]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/ppc4xx/gpio.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[karo-tx-uboot.git] / arch / powerpc / cpu / ppc4xx / gpio.c
1 /*
2  * (C) Copyright 2007-2008
3  * Stefan Roese, DENX Software Engineering, sr@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <asm/processor.h>
10 #include <asm/io.h>
11 #include <asm/ppc4xx-gpio.h>
12
13 /* Only compile this file for boards with GPIO support */
14 #if defined(GPIO0_BASE)
15
16 #if defined(CONFIG_SYS_4xx_GPIO_TABLE)
17 gpio_param_s const gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CONFIG_SYS_4xx_GPIO_TABLE;
18 #endif
19
20 #if defined(GPIO0_OSRL)
21 /* Only some 4xx variants support alternate funtions on the GPIO's */
22 void gpio_config(int pin, int in_out, int gpio_alt, int out_val)
23 {
24         u32 mask;
25         u32 mask2;
26         u32 val;
27         u32 offs = 0;
28         u32 offs2 = 0;
29         int pin2 = pin << 1;
30
31         if (pin >= GPIO_MAX) {
32                 offs = 0x100;
33                 pin -= GPIO_MAX;
34         }
35
36         if (pin >= GPIO_MAX/2) {
37                 offs2 = 0x4;
38                 pin2 = (pin - GPIO_MAX/2) << 1;
39         }
40
41         mask = 0x80000000 >> pin;
42         mask2 = 0xc0000000 >> pin2;
43
44         /* first set TCR to 0 */
45         out_be32((void *)GPIO0_TCR + offs, in_be32((void *)GPIO0_TCR + offs) & ~mask);
46
47         if (in_out == GPIO_OUT) {
48                 val = in_be32((void *)GPIO0_OSRL + offs + offs2) & ~mask2;
49                 switch (gpio_alt) {
50                 case GPIO_ALT1:
51                         val |= GPIO_ALT1_SEL >> pin2;
52                         break;
53                 case GPIO_ALT2:
54                         val |= GPIO_ALT2_SEL >> pin2;
55                         break;
56                 case GPIO_ALT3:
57                         val |= GPIO_ALT3_SEL >> pin2;
58                         break;
59                 }
60                 out_be32((void *)GPIO0_OSRL + offs + offs2, val);
61
62                 /* setup requested output value */
63                 if (out_val == GPIO_OUT_0)
64                         out_be32((void *)GPIO0_OR + offs,
65                                  in_be32((void *)GPIO0_OR + offs) & ~mask);
66                 else if (out_val == GPIO_OUT_1)
67                         out_be32((void *)GPIO0_OR + offs,
68                                  in_be32((void *)GPIO0_OR + offs) | mask);
69
70                 /* now configure TCR to drive output if selected */
71                 out_be32((void *)GPIO0_TCR + offs,
72                          in_be32((void *)GPIO0_TCR + offs) | mask);
73         } else {
74                 val = in_be32((void *)GPIO0_ISR1L + offs + offs2) & ~mask2;
75                 val |= GPIO_IN_SEL >> pin2;
76                 out_be32((void *)GPIO0_ISR1L + offs + offs2, val);
77         }
78 }
79 #endif /* GPIO_OSRL */
80
81 void gpio_write_bit(int pin, int val)
82 {
83         u32 offs = 0;
84
85         if (pin >= GPIO_MAX) {
86                 offs = 0x100;
87                 pin -= GPIO_MAX;
88         }
89
90         if (val)
91                 out_be32((void *)GPIO0_OR + offs,
92                          in_be32((void *)GPIO0_OR + offs) | GPIO_VAL(pin));
93         else
94                 out_be32((void *)GPIO0_OR + offs,
95                          in_be32((void *)GPIO0_OR + offs) & ~GPIO_VAL(pin));
96 }
97
98 int gpio_read_out_bit(int pin)
99 {
100         u32 offs = 0;
101
102         if (pin >= GPIO_MAX) {
103                 offs = 0x100;
104                 pin -= GPIO_MAX;
105         }
106
107         return (in_be32((void *)GPIO0_OR + offs) & GPIO_VAL(pin) ? 1 : 0);
108 }
109
110 int gpio_read_in_bit(int pin)
111 {
112         u32 offs = 0;
113
114         if (pin >= GPIO_MAX) {
115                 offs = 0x100;
116                 pin -= GPIO_MAX;
117         }
118
119         return (in_be32((void *)GPIO0_IR + offs) & GPIO_VAL(pin) ? 1 : 0);
120 }
121
122 #if defined(CONFIG_SYS_4xx_GPIO_TABLE)
123 void gpio_set_chip_configuration(void)
124 {
125         unsigned char i=0, j=0, offs=0, gpio_core;
126         unsigned long reg, core_add;
127
128         for (gpio_core=0; gpio_core<GPIO_GROUP_MAX; gpio_core++) {
129                 j = 0;
130                 offs = 0;
131                 /* GPIO config of the GPIOs 0 to 31 */
132                 for (i=0; i<GPIO_MAX; i++, j++) {
133                         if (i == GPIO_MAX/2) {
134                                 offs = 4;
135                                 j = i-16;
136                         }
137
138                         core_add = gpio_tab[gpio_core][i].add;
139
140                         if ((gpio_tab[gpio_core][i].in_out == GPIO_IN) ||
141                             (gpio_tab[gpio_core][i].in_out == GPIO_BI)) {
142
143                                 switch (gpio_tab[gpio_core][i].alt_nb) {
144                                 case GPIO_SEL:
145                                         break;
146
147                                 case GPIO_ALT1:
148                                         reg = in_be32((void *)GPIO_IS1(core_add+offs))
149                                                 & ~(GPIO_MASK >> (j*2));
150                                         reg = reg | (GPIO_IN_SEL >> (j*2));
151                                         out_be32((void *)GPIO_IS1(core_add+offs), reg);
152                                         break;
153
154                                 case GPIO_ALT2:
155                                         reg = in_be32((void *)GPIO_IS2(core_add+offs))
156                                                 & ~(GPIO_MASK >> (j*2));
157                                         reg = reg | (GPIO_IN_SEL >> (j*2));
158                                         out_be32((void *)GPIO_IS2(core_add+offs), reg);
159                                         break;
160
161                                 case GPIO_ALT3:
162                                         reg = in_be32((void *)GPIO_IS3(core_add+offs))
163                                                 & ~(GPIO_MASK >> (j*2));
164                                         reg = reg | (GPIO_IN_SEL >> (j*2));
165                                         out_be32((void *)GPIO_IS3(core_add+offs), reg);
166                                         break;
167                                 }
168                         }
169
170                         if ((gpio_tab[gpio_core][i].in_out == GPIO_OUT) ||
171                             (gpio_tab[gpio_core][i].in_out == GPIO_BI)) {
172
173                                 u32 gpio_alt_sel = 0;
174
175                                 switch (gpio_tab[gpio_core][i].alt_nb) {
176                                 case GPIO_SEL:
177                                         /*
178                                          * Setup output value
179                                          * 1 -> high level
180                                          * 0 -> low level
181                                          * else -> don't touch
182                                          */
183                                         reg = in_be32((void *)GPIO_OR(core_add));
184                                         if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1)
185                                                 reg |= (0x80000000 >> (i));
186                                         else if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_0)
187                                                 reg &= ~(0x80000000 >> (i));
188                                         out_be32((void *)GPIO_OR(core_add), reg);
189
190                                         reg = in_be32((void *)GPIO_TCR(core_add)) |
191                                                 (0x80000000 >> (i));
192                                         out_be32((void *)GPIO_TCR(core_add), reg);
193
194                                         reg = in_be32((void *)GPIO_OS(core_add+offs))
195                                                 & ~(GPIO_MASK >> (j*2));
196                                         out_be32((void *)GPIO_OS(core_add+offs), reg);
197                                         reg = in_be32((void *)GPIO_TS(core_add+offs))
198                                                 & ~(GPIO_MASK >> (j*2));
199                                         out_be32((void *)GPIO_TS(core_add+offs), reg);
200                                         break;
201
202                                 case GPIO_ALT1:
203                                         gpio_alt_sel = GPIO_ALT1_SEL;
204                                         break;
205
206                                 case GPIO_ALT2:
207                                         gpio_alt_sel = GPIO_ALT2_SEL;
208                                         break;
209
210                                 case GPIO_ALT3:
211                                         gpio_alt_sel = GPIO_ALT3_SEL;
212                                         break;
213                                 }
214
215                                 if (0 != gpio_alt_sel) {
216                                         reg = in_be32((void *)GPIO_OS(core_add+offs))
217                                                 & ~(GPIO_MASK >> (j*2));
218                                         reg = reg | (gpio_alt_sel >> (j*2));
219                                         out_be32((void *)GPIO_OS(core_add+offs), reg);
220
221                                         if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1) {
222                                                 reg = in_be32((void *)GPIO_TCR(core_add))
223                                                         | (0x80000000 >> (i));
224                                                 out_be32((void *)GPIO_TCR(core_add), reg);
225                                                 reg = in_be32((void *)GPIO_TS(core_add+offs))
226                                                         & ~(GPIO_MASK >> (j*2));
227                                                 out_be32((void *)GPIO_TS(core_add+offs), reg);
228                                         } else {
229                                                 reg = in_be32((void *)GPIO_TCR(core_add))
230                                                         & ~(0x80000000 >> (i));
231                                                 out_be32((void *)GPIO_TCR(core_add), reg);
232                                                 reg = in_be32((void *)GPIO_TS(core_add+offs))
233                                                         & ~(GPIO_MASK >> (j*2));
234                                                 reg = reg | (gpio_alt_sel >> (j*2));
235                                                 out_be32((void *)GPIO_TS(core_add+offs), reg);
236                                         }
237                                 }
238                         }
239                 }
240         }
241 }
242
243 #endif /* GPIO0_BASE */
244 #endif /* CONFIG_SYS_4xx_GPIO_TABLE */