Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / board / st-ericsson / u8500 / gpio.c
1 /*
2  * Copyright (C) ST-Ericsson SA 2009
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <asm/arch/gpio.h>
9
10 static struct gpio_register *addr_gpio_register[] = {
11         (void *)U8500_GPIO_0_BASE,
12         (void *)U8500_GPIO_1_BASE,
13         (void *)U8500_GPIO_2_BASE,
14         (void *)U8500_GPIO_3_BASE,
15         (void *)U8500_GPIO_4_BASE,
16         (void *)U8500_GPIO_5_BASE,
17         (void *)U8500_GPIO_6_BASE,
18         (void *)U8500_GPIO_7_BASE,
19         (void *)U8500_GPIO_8_BASE,
20 };
21
22 struct gpio_altfun_data altfun_table[] = {
23         {
24                 .altfun = GPIO_ALT_I2C_0,
25                 .start = 147,
26                 .end = 148,
27                 .cont = 0,
28                 .type = GPIO_ALTF_A,
29         },
30         {
31                 .altfun = GPIO_ALT_I2C_1,
32                 .start = 16,
33                 .end = 17,
34                 .cont = 0,
35                 .type = GPIO_ALTF_B,
36         },
37         {
38                 .altfun = GPIO_ALT_I2C_2,
39                 .start = 10,
40                 .end = 11,
41                 .cont = 0,
42                 .type = GPIO_ALTF_B,
43         },
44         {
45                 .altfun = GPIO_ALT_I2C_3,
46                 .start = 229,
47                 .end = 230,
48                 .cont = 0,
49                 .type = GPIO_ALTF_C,
50         },
51         {
52                 .altfun = GPIO_ALT_UART_0_MODEM,
53                 .start = 0,
54                 .end = 3,
55                 .cont = 1,
56                 .type = GPIO_ALTF_A,
57         },
58         {
59                 .altfun = GPIO_ALT_UART_0_MODEM,
60                 .start = 33,
61                 .end = 36,
62                 .cont = 0,
63                 .type = GPIO_ALTF_C,
64         },
65         {
66                 .altfun = GPIO_ALT_UART_1,
67                 .start = 4,
68                 .end = 7,
69                 .cont = 0,
70                 .type =
71                         GPIO_ALTF_A,
72         },
73         {
74                 .altfun = GPIO_ALT_UART_2,
75                 .start = 18,
76                 .end = 19,
77                 .cont = 1,
78                 .type = GPIO_ALTF_B,
79         },
80         {
81                 .altfun = GPIO_ALT_UART_2,
82                 .start = 29,
83                 .end = 32,
84                 .cont = 0,
85                 .type = GPIO_ALTF_C,
86         },
87         {
88                 .altfun = GPIO_ALT_MSP_0,
89                 .start = 12,
90                 .end = 17,
91                 .cont = 1,
92                 .type = GPIO_ALTF_A,
93         },
94         {
95                 .altfun = GPIO_ALT_MSP_0,
96                 .start = 21,
97                 .end = 21,
98                 .cont = 0,
99                 .type = GPIO_ALTF_B,
100         },
101         {
102                 .altfun = GPIO_ALT_MSP_1,
103                 .start = 33,
104                 .end = 36,
105                 .cont = 0,
106                 .type = GPIO_ALTF_A,
107         },
108         {
109                 .altfun = GPIO_ALT_MSP_2,
110                 .start = 192,
111                 .end = 196,
112                 .cont = 0,
113                 .type = GPIO_ALTF_A,
114         },
115         {
116                 .altfun = GPIO_ALT_LCD_PANEL,
117                 .start = 64,
118                 .end = 93,
119                 .cont = 1,
120                 .type = GPIO_ALTF_A,
121         },
122         {
123                 .altfun = GPIO_ALT_LCD_PANEL,
124                 .start = 150,
125                 .end = 171,
126                 .cont = 0,
127                 .type = GPIO_ALTF_B,
128         },
129         {
130                 .altfun = GPIO_ALT_SD_CARD0,
131                 .start = 18,
132                 .end = 28,
133                 .cont = 0,
134                 .type = GPIO_ALTF_A,
135         },
136         {
137                 .altfun = GPIO_ALT_MM_CARD0,
138                 .start = 18,
139                 .end = 32,
140                 .cont = 0,
141                 .type = GPIO_ALTF_A,
142         },
143         {
144                 .altfun = GPIO_ALT_USB_OTG,
145                 .start = 256,
146                 .end = 267,
147                 .cont = 0,
148                 .type = GPIO_ALTF_A,
149         },
150         {
151                 .altfun = GPIO_ALT_EMMC,
152                 .start = 197,
153                 .end = 207,
154                 .cont = 0,
155                 .type = GPIO_ALTF_A,
156         },
157         {
158                 .altfun = GPIO_ALT_POP_EMMC,
159                 .start = 128,
160                 .end = 138,
161                 .cont = 0,
162                 .type = GPIO_ALTF_A,
163         },
164 };
165
166 /*
167  * Static Function declarations
168  */
169 enum gpio_error gpio_setpinconfig(int pin_id, struct gpio_config *config)
170 {
171         struct gpio_register *p_gpio_register =
172             addr_gpio_register[GPIO_BLOCK(pin_id)];
173         u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
174         enum gpio_error error = GPIO_OK;
175         u32 temp_reg;
176
177         switch (config->mode) {
178         case GPIO_ALTF_A:
179                 temp_reg = readl(&p_gpio_register->gpio_afsa);
180                 temp_reg |= mask;
181                 writel(temp_reg, &p_gpio_register->gpio_afsa);
182                 temp_reg = readl(&p_gpio_register->gpio_afsb);
183                 temp_reg &= ~mask;
184                 writel(temp_reg, &p_gpio_register->gpio_afsb);
185                 break;
186         case GPIO_ALTF_B:
187                 temp_reg = readl(&p_gpio_register->gpio_afsa);
188                 temp_reg &= ~mask;
189                 writel(temp_reg, &p_gpio_register->gpio_afsa);
190                 temp_reg = readl(&p_gpio_register->gpio_afsb);
191                 temp_reg |= mask;
192                 writel(temp_reg, &p_gpio_register->gpio_afsb);
193                 break;
194         case GPIO_ALTF_C:
195                 temp_reg = readl(&p_gpio_register->gpio_afsa);
196                 temp_reg |= mask;
197                 writel(temp_reg, &p_gpio_register->gpio_afsa);
198                 temp_reg = readl(&p_gpio_register->gpio_afsb);
199                 temp_reg |= mask;
200                 writel(temp_reg, &p_gpio_register->gpio_afsb);
201                 break;
202         case GPIO_MODE_SOFTWARE:
203                 temp_reg = readl(&p_gpio_register->gpio_afsa);
204                 temp_reg &= ~mask;
205                 writel(temp_reg, &p_gpio_register->gpio_afsa);
206                 temp_reg = readl(&p_gpio_register->gpio_afsb);
207                 temp_reg &= ~mask;
208                 writel(temp_reg, &p_gpio_register->gpio_afsb);
209
210                 switch (config->direction) {
211                 case GPIO_DIR_INPUT:
212                         writel(mask, &p_gpio_register->gpio_dirc);
213                         break;
214                 case GPIO_DIR_OUTPUT:
215                         writel(mask, &p_gpio_register->gpio_dirs);
216                         break;
217                 case GPIO_DIR_LEAVE_UNCHANGED:
218                         break;
219                 default:
220                         return GPIO_INVALID_PARAMETER;
221                 }
222
223                 break;
224         case GPIO_MODE_LEAVE_UNCHANGED:
225                 break;
226         default:
227                 return GPIO_INVALID_PARAMETER;
228         }
229         return error;
230 }
231
232 enum gpio_error gpio_resetgpiopin(int pin_id, char *dev_name)
233 {
234         struct gpio_register *p_gpio_register =
235             addr_gpio_register[GPIO_BLOCK(pin_id)];
236         u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
237         enum gpio_error error = GPIO_OK;
238         u32 temp_reg;
239
240         temp_reg = readl(&p_gpio_register->gpio_afsa);
241         temp_reg &= ~mask;
242         writel(temp_reg, &p_gpio_register->gpio_afsa);
243         temp_reg = readl(&p_gpio_register->gpio_afsb);
244         temp_reg &= ~mask;
245         writel(temp_reg, &p_gpio_register->gpio_afsb);
246         writel(mask, &p_gpio_register->gpio_dirc);
247
248         return error;
249 }
250
251 struct gpio_config altfun_pinconfig;
252 enum gpio_error gpio_altfunction(enum gpio_alt_function alt_func,
253                             int which_altfunc, char *dev_name)
254 {
255         int i, j, start, end;
256         enum gpio_error error = -1;
257
258         for (i = 0; i < ARRAY_SIZE(altfun_table); i++) {
259                 if (altfun_table[i].altfun != alt_func)
260                         continue;
261
262                 start = altfun_table[i].start;
263                 end = altfun_table[i].end;
264                 for (j = start; j <= end; j++) {
265                         if (which_altfunc == GPIO_ALTF_FIND)
266                                 altfun_pinconfig.mode = altfun_table[i].type;
267                         else
268                                 altfun_pinconfig.mode = which_altfunc;
269                         altfun_pinconfig.direction = GPIO_DIR_OUTPUT;
270                         altfun_pinconfig.dev_name = dev_name;
271
272                         if (which_altfunc != GPIO_ALTF_DISABLE)
273                                 error = gpio_setpinconfig(j, &altfun_pinconfig);
274                         else
275                                 error = gpio_resetgpiopin(j, dev_name);
276                         if (!error)
277                                 continue;
278                         printf("GPIO %d configuration failure (nmdk_error:%d)",
279                                 j, error);
280                         error = GPIO_INVALID_PARAMETER;
281                         return error;
282                 }
283
284                 if (!altfun_table[i].cont)
285                         break;
286         }
287         return error;
288 }
289
290 int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name)
291 {
292         struct gpio_register *p_gpio_register =
293             addr_gpio_register[GPIO_BLOCK(pin_id)];
294         u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
295
296         switch (value) {
297         case GPIO_DATA_HIGH:
298                 writel(mask, &p_gpio_register->gpio_dats);
299                 break;
300         case GPIO_DATA_LOW:
301                 writel(mask, &p_gpio_register->gpio_datc);
302                 break;
303         default:
304                 printf("Invalid value passed in %s", __FUNCTION__);
305                 return GPIO_INVALID_PARAMETER;
306         }
307         return GPIO_OK;
308 }
309
310 int gpio_readpin(int pin_id, enum gpio_data *rv)
311 {
312         struct gpio_register *p_gpio_register =
313             addr_gpio_register[GPIO_BLOCK(pin_id)];
314         u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
315
316         if ((readl(&p_gpio_register->gpio_dat) & mask) != 0)
317                 *rv = GPIO_DATA_HIGH;
318         else
319                 *rv = GPIO_DATA_LOW;
320         return GPIO_OK;
321 }
322
323 int gpio_altfuncenable(enum gpio_alt_function altfunc, char *dev_name)
324 {
325         return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name);
326 }
327
328 int gpio_altfuncdisable(enum gpio_alt_function altfunc, char *dev_name)
329 {
330         return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name);
331 }