Merge samsung, imx, tegra into u-boot-arm/master
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / exynos / pinmux.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics.
3  * Abhilash Kesavan <a.kesavan@samsung.com>
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <asm/arch/gpio.h>
26 #include <asm/arch/pinmux.h>
27 #include <asm/arch/sromc.h>
28
29 static void exynos5_uart_config(int peripheral)
30 {
31         struct exynos5_gpio_part1 *gpio1 =
32                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
33         struct s5p_gpio_bank *bank;
34         int i, start, count;
35
36         switch (peripheral) {
37         case PERIPH_ID_UART0:
38                 bank = &gpio1->a0;
39                 start = 0;
40                 count = 4;
41                 break;
42         case PERIPH_ID_UART1:
43                 bank = &gpio1->d0;
44                 start = 0;
45                 count = 4;
46                 break;
47         case PERIPH_ID_UART2:
48                 bank = &gpio1->a1;
49                 start = 0;
50                 count = 4;
51                 break;
52         case PERIPH_ID_UART3:
53                 bank = &gpio1->a1;
54                 start = 4;
55                 count = 2;
56                 break;
57         }
58         for (i = start; i < start + count; i++) {
59                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
60                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
61         }
62 }
63
64 static int exynos5_mmc_config(int peripheral, int flags)
65 {
66         struct exynos5_gpio_part1 *gpio1 =
67                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
68         struct s5p_gpio_bank *bank, *bank_ext;
69         int i, start = 0, gpio_func = 0;
70
71         switch (peripheral) {
72         case PERIPH_ID_SDMMC0:
73                 bank = &gpio1->c0;
74                 bank_ext = &gpio1->c1;
75                 start = 0;
76                 gpio_func = GPIO_FUNC(0x2);
77                 break;
78         case PERIPH_ID_SDMMC1:
79                 bank = &gpio1->c2;
80                 bank_ext = NULL;
81                 break;
82         case PERIPH_ID_SDMMC2:
83                 bank = &gpio1->c3;
84                 bank_ext = &gpio1->c4;
85                 start = 3;
86                 gpio_func = GPIO_FUNC(0x3);
87                 break;
88         case PERIPH_ID_SDMMC3:
89                 bank = &gpio1->c4;
90                 bank_ext = NULL;
91                 break;
92         }
93         if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) {
94                 debug("SDMMC device %d does not support 8bit mode",
95                                 peripheral);
96                 return -1;
97         }
98         if (flags & PINMUX_FLAG_8BIT_MODE) {
99                 for (i = start; i <= (start + 3); i++) {
100                         s5p_gpio_cfg_pin(bank_ext, i, gpio_func);
101                         s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP);
102                         s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
103                 }
104         }
105         for (i = 0; i < 2; i++) {
106                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
107                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
108                 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
109         }
110         for (i = 3; i <= 6; i++) {
111                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
112                 s5p_gpio_set_pull(bank, i, GPIO_PULL_UP);
113                 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
114         }
115
116         return 0;
117 }
118
119 static void exynos5_sromc_config(int flags)
120 {
121         struct exynos5_gpio_part1 *gpio1 =
122                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
123         int i;
124
125         /*
126          * SROM:CS1 and EBI
127          *
128          * GPY0[0]      SROM_CSn[0]
129          * GPY0[1]      SROM_CSn[1](2)
130          * GPY0[2]      SROM_CSn[2]
131          * GPY0[3]      SROM_CSn[3]
132          * GPY0[4]      EBI_OEn(2)
133          * GPY0[5]      EBI_EEn(2)
134          *
135          * GPY1[0]      EBI_BEn[0](2)
136          * GPY1[1]      EBI_BEn[1](2)
137          * GPY1[2]      SROM_WAIT(2)
138          * GPY1[3]      EBI_DATA_RDn(2)
139          */
140         s5p_gpio_cfg_pin(&gpio1->y0, (flags & PINMUX_FLAG_BANK),
141                                 GPIO_FUNC(2));
142         s5p_gpio_cfg_pin(&gpio1->y0, 4, GPIO_FUNC(2));
143         s5p_gpio_cfg_pin(&gpio1->y0, 5, GPIO_FUNC(2));
144
145         for (i = 0; i < 4; i++)
146                 s5p_gpio_cfg_pin(&gpio1->y1, i, GPIO_FUNC(2));
147
148         /*
149          * EBI: 8 Addrss Lines
150          *
151          * GPY3[0]      EBI_ADDR[0](2)
152          * GPY3[1]      EBI_ADDR[1](2)
153          * GPY3[2]      EBI_ADDR[2](2)
154          * GPY3[3]      EBI_ADDR[3](2)
155          * GPY3[4]      EBI_ADDR[4](2)
156          * GPY3[5]      EBI_ADDR[5](2)
157          * GPY3[6]      EBI_ADDR[6](2)
158          * GPY3[7]      EBI_ADDR[7](2)
159          *
160          * EBI: 16 Data Lines
161          *
162          * GPY5[0]      EBI_DATA[0](2)
163          * GPY5[1]      EBI_DATA[1](2)
164          * GPY5[2]      EBI_DATA[2](2)
165          * GPY5[3]      EBI_DATA[3](2)
166          * GPY5[4]      EBI_DATA[4](2)
167          * GPY5[5]      EBI_DATA[5](2)
168          * GPY5[6]      EBI_DATA[6](2)
169          * GPY5[7]      EBI_DATA[7](2)
170          *
171          * GPY6[0]      EBI_DATA[8](2)
172          * GPY6[1]      EBI_DATA[9](2)
173          * GPY6[2]      EBI_DATA[10](2)
174          * GPY6[3]      EBI_DATA[11](2)
175          * GPY6[4]      EBI_DATA[12](2)
176          * GPY6[5]      EBI_DATA[13](2)
177          * GPY6[6]      EBI_DATA[14](2)
178          * GPY6[7]      EBI_DATA[15](2)
179          */
180         for (i = 0; i < 8; i++) {
181                 s5p_gpio_cfg_pin(&gpio1->y3, i, GPIO_FUNC(2));
182                 s5p_gpio_set_pull(&gpio1->y3, i, GPIO_PULL_UP);
183
184                 s5p_gpio_cfg_pin(&gpio1->y5, i, GPIO_FUNC(2));
185                 s5p_gpio_set_pull(&gpio1->y5, i, GPIO_PULL_UP);
186
187                 s5p_gpio_cfg_pin(&gpio1->y6, i, GPIO_FUNC(2));
188                 s5p_gpio_set_pull(&gpio1->y6, i, GPIO_PULL_UP);
189         }
190 }
191
192 static void exynos5_i2c_config(int peripheral, int flags)
193 {
194
195         struct exynos5_gpio_part1 *gpio1 =
196                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
197
198         switch (peripheral) {
199         case PERIPH_ID_I2C0:
200                 s5p_gpio_cfg_pin(&gpio1->b3, 0, GPIO_FUNC(0x2));
201                 s5p_gpio_cfg_pin(&gpio1->b3, 1, GPIO_FUNC(0x2));
202                 break;
203         case PERIPH_ID_I2C1:
204                 s5p_gpio_cfg_pin(&gpio1->b3, 2, GPIO_FUNC(0x2));
205                 s5p_gpio_cfg_pin(&gpio1->b3, 3, GPIO_FUNC(0x2));
206                 break;
207         case PERIPH_ID_I2C2:
208                 s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
209                 s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
210                 break;
211         case PERIPH_ID_I2C3:
212                 s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
213                 s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
214                 break;
215         case PERIPH_ID_I2C4:
216                 s5p_gpio_cfg_pin(&gpio1->a2, 0, GPIO_FUNC(0x3));
217                 s5p_gpio_cfg_pin(&gpio1->a2, 1, GPIO_FUNC(0x3));
218                 break;
219         case PERIPH_ID_I2C5:
220                 s5p_gpio_cfg_pin(&gpio1->a2, 2, GPIO_FUNC(0x3));
221                 s5p_gpio_cfg_pin(&gpio1->a2, 3, GPIO_FUNC(0x3));
222                 break;
223         case PERIPH_ID_I2C6:
224                 s5p_gpio_cfg_pin(&gpio1->b1, 3, GPIO_FUNC(0x4));
225                 s5p_gpio_cfg_pin(&gpio1->b1, 4, GPIO_FUNC(0x4));
226                 break;
227         case PERIPH_ID_I2C7:
228                 s5p_gpio_cfg_pin(&gpio1->b2, 2, GPIO_FUNC(0x3));
229                 s5p_gpio_cfg_pin(&gpio1->b2, 3, GPIO_FUNC(0x3));
230                 break;
231         }
232 }
233
234 static void exynos5_i2s_config(int peripheral)
235 {
236         int i;
237         struct exynos5_gpio_part1 *gpio1 =
238                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
239
240         for (i = 0; i < 5; i++)
241                 s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
242 }
243
244 void exynos5_spi_config(int peripheral)
245 {
246         int cfg = 0, pin = 0, i;
247         struct s5p_gpio_bank *bank = NULL;
248         struct exynos5_gpio_part1 *gpio1 =
249                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
250         struct exynos5_gpio_part2 *gpio2 =
251                 (struct exynos5_gpio_part2 *) samsung_get_base_gpio_part2();
252
253         switch (peripheral) {
254         case PERIPH_ID_SPI0:
255                 bank = &gpio1->a2;
256                 cfg = GPIO_FUNC(0x2);
257                 pin = 0;
258                 break;
259         case PERIPH_ID_SPI1:
260                 bank = &gpio1->a2;
261                 cfg = GPIO_FUNC(0x2);
262                 pin = 4;
263                 break;
264         case PERIPH_ID_SPI2:
265                 bank = &gpio1->b1;
266                 cfg = GPIO_FUNC(0x5);
267                 pin = 1;
268                 break;
269         case PERIPH_ID_SPI3:
270                 bank = &gpio2->f1;
271                 cfg = GPIO_FUNC(0x2);
272                 pin = 0;
273                 break;
274         case PERIPH_ID_SPI4:
275                 for (i = 0; i < 2; i++) {
276                         s5p_gpio_cfg_pin(&gpio2->f0, i + 2, GPIO_FUNC(0x4));
277                         s5p_gpio_cfg_pin(&gpio2->e0, i + 4, GPIO_FUNC(0x4));
278                 }
279                 break;
280         }
281         if (peripheral != PERIPH_ID_SPI4) {
282                 for (i = pin; i < pin + 4; i++)
283                         s5p_gpio_cfg_pin(bank, i, cfg);
284         }
285 }
286
287 static int exynos5_pinmux_config(int peripheral, int flags)
288 {
289         switch (peripheral) {
290         case PERIPH_ID_UART0:
291         case PERIPH_ID_UART1:
292         case PERIPH_ID_UART2:
293         case PERIPH_ID_UART3:
294                 exynos5_uart_config(peripheral);
295                 break;
296         case PERIPH_ID_SDMMC0:
297         case PERIPH_ID_SDMMC1:
298         case PERIPH_ID_SDMMC2:
299         case PERIPH_ID_SDMMC3:
300                 return exynos5_mmc_config(peripheral, flags);
301         case PERIPH_ID_SROMC:
302                 exynos5_sromc_config(flags);
303                 break;
304         case PERIPH_ID_I2C0:
305         case PERIPH_ID_I2C1:
306         case PERIPH_ID_I2C2:
307         case PERIPH_ID_I2C3:
308         case PERIPH_ID_I2C4:
309         case PERIPH_ID_I2C5:
310         case PERIPH_ID_I2C6:
311         case PERIPH_ID_I2C7:
312                 exynos5_i2c_config(peripheral, flags);
313                 break;
314         case PERIPH_ID_I2S1:
315                 exynos5_i2s_config(peripheral);
316                 break;
317         case PERIPH_ID_SPI0:
318         case PERIPH_ID_SPI1:
319         case PERIPH_ID_SPI2:
320         case PERIPH_ID_SPI3:
321         case PERIPH_ID_SPI4:
322                 exynos5_spi_config(peripheral);
323                 break;
324         default:
325                 debug("%s: invalid peripheral %d", __func__, peripheral);
326                 return -1;
327         }
328
329         return 0;
330 }
331
332 static void exynos4_i2c_config(int peripheral, int flags)
333 {
334         struct exynos4_gpio_part1 *gpio1 =
335                 (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1();
336
337         switch (peripheral) {
338         case PERIPH_ID_I2C0:
339                 s5p_gpio_cfg_pin(&gpio1->d1, 0, GPIO_FUNC(0x2));
340                 s5p_gpio_cfg_pin(&gpio1->d1, 1, GPIO_FUNC(0x2));
341                 break;
342         case PERIPH_ID_I2C1:
343                 s5p_gpio_cfg_pin(&gpio1->d1, 2, GPIO_FUNC(0x2));
344                 s5p_gpio_cfg_pin(&gpio1->d1, 3, GPIO_FUNC(0x2));
345                 break;
346         case PERIPH_ID_I2C2:
347                 s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
348                 s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
349                 break;
350         case PERIPH_ID_I2C3:
351                 s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
352                 s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
353                 break;
354         case PERIPH_ID_I2C4:
355                 s5p_gpio_cfg_pin(&gpio1->b, 2, GPIO_FUNC(0x3));
356                 s5p_gpio_cfg_pin(&gpio1->b, 3, GPIO_FUNC(0x3));
357                 break;
358         case PERIPH_ID_I2C5:
359                 s5p_gpio_cfg_pin(&gpio1->b, 6, GPIO_FUNC(0x3));
360                 s5p_gpio_cfg_pin(&gpio1->b, 7, GPIO_FUNC(0x3));
361                 break;
362         case PERIPH_ID_I2C6:
363                 s5p_gpio_cfg_pin(&gpio1->c1, 3, GPIO_FUNC(0x4));
364                 s5p_gpio_cfg_pin(&gpio1->c1, 4, GPIO_FUNC(0x4));
365                 break;
366         case PERIPH_ID_I2C7:
367                 s5p_gpio_cfg_pin(&gpio1->d0, 2, GPIO_FUNC(0x3));
368                 s5p_gpio_cfg_pin(&gpio1->d0, 3, GPIO_FUNC(0x3));
369                 break;
370         }
371 }
372
373 static int exynos4_pinmux_config(int peripheral, int flags)
374 {
375         switch (peripheral) {
376         case PERIPH_ID_I2C0:
377         case PERIPH_ID_I2C1:
378         case PERIPH_ID_I2C2:
379         case PERIPH_ID_I2C3:
380         case PERIPH_ID_I2C4:
381         case PERIPH_ID_I2C5:
382         case PERIPH_ID_I2C6:
383         case PERIPH_ID_I2C7:
384                 exynos4_i2c_config(peripheral, flags);
385                 break;
386         default:
387                 debug("%s: invalid peripheral %d", __func__, peripheral);
388                 return -1;
389         }
390
391         return 0;
392 }
393
394 int exynos_pinmux_config(int peripheral, int flags)
395 {
396         if (cpu_is_exynos5())
397                 return exynos5_pinmux_config(peripheral, flags);
398         else if (cpu_is_exynos4())
399                 return exynos4_pinmux_config(peripheral, flags);
400         else {
401                 debug("pinmux functionality not supported\n");
402                 return -1;
403         }
404 }