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 */