2 * (C) Copyright 2007-2008
3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
5 * SPDX-License-Identifier: GPL-2.0+
9 #include <asm/processor.h>
11 #include <asm/ppc4xx-gpio.h>
13 /* Only compile this file for boards with GPIO support */
14 #if defined(GPIO0_BASE)
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
;
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
)
31 if (pin
>= GPIO_MAX
) {
36 if (pin
>= GPIO_MAX
/2) {
38 pin2
= (pin
- GPIO_MAX
/2) << 1;
41 mask
= 0x80000000 >> pin
;
42 mask2
= 0xc0000000 >> pin2
;
44 /* first set TCR to 0 */
45 out_be32((void *)GPIO0_TCR
+ offs
, in_be32((void *)GPIO0_TCR
+ offs
) & ~mask
);
47 if (in_out
== GPIO_OUT
) {
48 val
= in_be32((void *)GPIO0_OSRL
+ offs
+ offs2
) & ~mask2
;
51 val
|= GPIO_ALT1_SEL
>> pin2
;
54 val
|= GPIO_ALT2_SEL
>> pin2
;
57 val
|= GPIO_ALT3_SEL
>> pin2
;
60 out_be32((void *)GPIO0_OSRL
+ offs
+ offs2
, val
);
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
);
70 /* now configure TCR to drive output if selected */
71 out_be32((void *)GPIO0_TCR
+ offs
,
72 in_be32((void *)GPIO0_TCR
+ offs
) | mask
);
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
);
79 #endif /* GPIO_OSRL */
81 void gpio_write_bit(int pin
, int val
)
85 if (pin
>= GPIO_MAX
) {
91 out_be32((void *)GPIO0_OR
+ offs
,
92 in_be32((void *)GPIO0_OR
+ offs
) | GPIO_VAL(pin
));
94 out_be32((void *)GPIO0_OR
+ offs
,
95 in_be32((void *)GPIO0_OR
+ offs
) & ~GPIO_VAL(pin
));
98 int gpio_read_out_bit(int pin
)
102 if (pin
>= GPIO_MAX
) {
107 return (in_be32((void *)GPIO0_OR
+ offs
) & GPIO_VAL(pin
) ? 1 : 0);
110 int gpio_read_in_bit(int pin
)
114 if (pin
>= GPIO_MAX
) {
119 return (in_be32((void *)GPIO0_IR
+ offs
) & GPIO_VAL(pin
) ? 1 : 0);
122 #if defined(CONFIG_SYS_4xx_GPIO_TABLE)
123 void gpio_set_chip_configuration(void)
125 unsigned char i
=0, j
=0, offs
=0, gpio_core
;
126 unsigned long reg
, core_add
;
128 for (gpio_core
=0; gpio_core
<GPIO_GROUP_MAX
; gpio_core
++) {
131 /* GPIO config of the GPIOs 0 to 31 */
132 for (i
=0; i
<GPIO_MAX
; i
++, j
++) {
133 if (i
== GPIO_MAX
/2) {
138 core_add
= gpio_tab
[gpio_core
][i
].add
;
140 if ((gpio_tab
[gpio_core
][i
].in_out
== GPIO_IN
) ||
141 (gpio_tab
[gpio_core
][i
].in_out
== GPIO_BI
)) {
143 switch (gpio_tab
[gpio_core
][i
].alt_nb
) {
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
);
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
);
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
);
170 if ((gpio_tab
[gpio_core
][i
].in_out
== GPIO_OUT
) ||
171 (gpio_tab
[gpio_core
][i
].in_out
== GPIO_BI
)) {
173 u32 gpio_alt_sel
= 0;
175 switch (gpio_tab
[gpio_core
][i
].alt_nb
) {
181 * else -> don't touch
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
);
190 reg
= in_be32((void *)GPIO_TCR(core_add
)) |
192 out_be32((void *)GPIO_TCR(core_add
), reg
);
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
);
203 gpio_alt_sel
= GPIO_ALT1_SEL
;
207 gpio_alt_sel
= GPIO_ALT2_SEL
;
211 gpio_alt_sel
= GPIO_ALT3_SEL
;
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
);
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
);
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
);
243 #endif /* GPIO0_BASE */
244 #endif /* CONFIG_SYS_4xx_GPIO_TABLE */