]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/exynos/pinmux.c
arm:exynos4:pinmux: Modify the gpio function for mmc
[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         return 0;
116 }
117
118 static void exynos5_sromc_config(int flags)
119 {
120         struct exynos5_gpio_part1 *gpio1 =
121                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
122         int i;
123
124         /*
125          * SROM:CS1 and EBI
126          *
127          * GPY0[0]      SROM_CSn[0]
128          * GPY0[1]      SROM_CSn[1](2)
129          * GPY0[2]      SROM_CSn[2]
130          * GPY0[3]      SROM_CSn[3]
131          * GPY0[4]      EBI_OEn(2)
132          * GPY0[5]      EBI_EEn(2)
133          *
134          * GPY1[0]      EBI_BEn[0](2)
135          * GPY1[1]      EBI_BEn[1](2)
136          * GPY1[2]      SROM_WAIT(2)
137          * GPY1[3]      EBI_DATA_RDn(2)
138          */
139         s5p_gpio_cfg_pin(&gpio1->y0, (flags & PINMUX_FLAG_BANK),
140                                 GPIO_FUNC(2));
141         s5p_gpio_cfg_pin(&gpio1->y0, 4, GPIO_FUNC(2));
142         s5p_gpio_cfg_pin(&gpio1->y0, 5, GPIO_FUNC(2));
143
144         for (i = 0; i < 4; i++)
145                 s5p_gpio_cfg_pin(&gpio1->y1, i, GPIO_FUNC(2));
146
147         /*
148          * EBI: 8 Addrss Lines
149          *
150          * GPY3[0]      EBI_ADDR[0](2)
151          * GPY3[1]      EBI_ADDR[1](2)
152          * GPY3[2]      EBI_ADDR[2](2)
153          * GPY3[3]      EBI_ADDR[3](2)
154          * GPY3[4]      EBI_ADDR[4](2)
155          * GPY3[5]      EBI_ADDR[5](2)
156          * GPY3[6]      EBI_ADDR[6](2)
157          * GPY3[7]      EBI_ADDR[7](2)
158          *
159          * EBI: 16 Data Lines
160          *
161          * GPY5[0]      EBI_DATA[0](2)
162          * GPY5[1]      EBI_DATA[1](2)
163          * GPY5[2]      EBI_DATA[2](2)
164          * GPY5[3]      EBI_DATA[3](2)
165          * GPY5[4]      EBI_DATA[4](2)
166          * GPY5[5]      EBI_DATA[5](2)
167          * GPY5[6]      EBI_DATA[6](2)
168          * GPY5[7]      EBI_DATA[7](2)
169          *
170          * GPY6[0]      EBI_DATA[8](2)
171          * GPY6[1]      EBI_DATA[9](2)
172          * GPY6[2]      EBI_DATA[10](2)
173          * GPY6[3]      EBI_DATA[11](2)
174          * GPY6[4]      EBI_DATA[12](2)
175          * GPY6[5]      EBI_DATA[13](2)
176          * GPY6[6]      EBI_DATA[14](2)
177          * GPY6[7]      EBI_DATA[15](2)
178          */
179         for (i = 0; i < 8; i++) {
180                 s5p_gpio_cfg_pin(&gpio1->y3, i, GPIO_FUNC(2));
181                 s5p_gpio_set_pull(&gpio1->y3, i, GPIO_PULL_UP);
182
183                 s5p_gpio_cfg_pin(&gpio1->y5, i, GPIO_FUNC(2));
184                 s5p_gpio_set_pull(&gpio1->y5, i, GPIO_PULL_UP);
185
186                 s5p_gpio_cfg_pin(&gpio1->y6, i, GPIO_FUNC(2));
187                 s5p_gpio_set_pull(&gpio1->y6, i, GPIO_PULL_UP);
188         }
189 }
190
191 static void exynos5_i2c_config(int peripheral, int flags)
192 {
193
194         struct exynos5_gpio_part1 *gpio1 =
195                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
196
197         switch (peripheral) {
198         case PERIPH_ID_I2C0:
199                 s5p_gpio_cfg_pin(&gpio1->b3, 0, GPIO_FUNC(0x2));
200                 s5p_gpio_cfg_pin(&gpio1->b3, 1, GPIO_FUNC(0x2));
201                 break;
202         case PERIPH_ID_I2C1:
203                 s5p_gpio_cfg_pin(&gpio1->b3, 2, GPIO_FUNC(0x2));
204                 s5p_gpio_cfg_pin(&gpio1->b3, 3, GPIO_FUNC(0x2));
205                 break;
206         case PERIPH_ID_I2C2:
207                 s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
208                 s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
209                 break;
210         case PERIPH_ID_I2C3:
211                 s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
212                 s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
213                 break;
214         case PERIPH_ID_I2C4:
215                 s5p_gpio_cfg_pin(&gpio1->a2, 0, GPIO_FUNC(0x3));
216                 s5p_gpio_cfg_pin(&gpio1->a2, 1, GPIO_FUNC(0x3));
217                 break;
218         case PERIPH_ID_I2C5:
219                 s5p_gpio_cfg_pin(&gpio1->a2, 2, GPIO_FUNC(0x3));
220                 s5p_gpio_cfg_pin(&gpio1->a2, 3, GPIO_FUNC(0x3));
221                 break;
222         case PERIPH_ID_I2C6:
223                 s5p_gpio_cfg_pin(&gpio1->b1, 3, GPIO_FUNC(0x4));
224                 s5p_gpio_cfg_pin(&gpio1->b1, 4, GPIO_FUNC(0x4));
225                 break;
226         case PERIPH_ID_I2C7:
227                 s5p_gpio_cfg_pin(&gpio1->b2, 2, GPIO_FUNC(0x3));
228                 s5p_gpio_cfg_pin(&gpio1->b2, 3, GPIO_FUNC(0x3));
229                 break;
230         }
231 }
232
233 static int exynos5_pinmux_config(int peripheral, int flags)
234 {
235         switch (peripheral) {
236         case PERIPH_ID_UART0:
237         case PERIPH_ID_UART1:
238         case PERIPH_ID_UART2:
239         case PERIPH_ID_UART3:
240                 exynos5_uart_config(peripheral);
241                 break;
242         case PERIPH_ID_SDMMC0:
243         case PERIPH_ID_SDMMC1:
244         case PERIPH_ID_SDMMC2:
245         case PERIPH_ID_SDMMC3:
246                 return exynos5_mmc_config(peripheral, flags);
247         case PERIPH_ID_SROMC:
248                 exynos5_sromc_config(flags);
249                 break;
250         case PERIPH_ID_I2C0:
251         case PERIPH_ID_I2C1:
252         case PERIPH_ID_I2C2:
253         case PERIPH_ID_I2C3:
254         case PERIPH_ID_I2C4:
255         case PERIPH_ID_I2C5:
256         case PERIPH_ID_I2C6:
257         case PERIPH_ID_I2C7:
258                 exynos5_i2c_config(peripheral, flags);
259                 break;
260         default:
261                 debug("%s: invalid peripheral %d", __func__, peripheral);
262                 return -1;
263         }
264
265         return 0;
266 }
267
268 static int exynos4_mmc_config(int peripheral, int flags)
269 {
270         struct exynos4_gpio_part2 *gpio2 =
271                 (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
272         struct s5p_gpio_bank *bank, *bank_ext;
273         int i;
274
275         switch (peripheral) {
276         case PERIPH_ID_SDMMC0:
277                 bank = &gpio2->k0;
278                 bank_ext = &gpio2->k1;
279                 break;
280         case PERIPH_ID_SDMMC2:
281                 bank = &gpio2->k2;
282                 bank_ext = &gpio2->k3;
283                 break;
284         default:
285                 return -1;
286         }
287         for (i = 0; i < 7; i++) {
288                 if (i == 2)
289                         continue;
290                 s5p_gpio_cfg_pin(bank, i,  GPIO_FUNC(0x2));
291                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
292                 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
293         }
294         if (flags & PINMUX_FLAG_8BIT_MODE) {
295                 for (i = 3; i < 7; i++) {
296                         s5p_gpio_cfg_pin(bank_ext, i,  GPIO_FUNC(0x3));
297                         s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_NONE);
298                         s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
299                 }
300         }
301
302         return 0;
303 }
304
305 static int exynos4_pinmux_config(int peripheral, int flags)
306 {
307         switch (peripheral) {
308         case PERIPH_ID_SDMMC0:
309         case PERIPH_ID_SDMMC2:
310                 return exynos4_mmc_config(peripheral, flags);
311         case PERIPH_ID_SDMMC1:
312         case PERIPH_ID_SDMMC3:
313         case PERIPH_ID_SDMMC4:
314                 printf("SDMMC device %d not implemented\n", peripheral);
315                 return -1;
316         default:
317                 debug("%s: invalid peripheral %d", __func__, peripheral);
318                 return -1;
319         }
320
321         return 0;
322 }
323
324 int exynos_pinmux_config(int peripheral, int flags)
325 {
326         if (cpu_is_exynos5())
327                 return exynos5_pinmux_config(peripheral, flags);
328         else if (cpu_is_exynos4())
329                 return exynos4_pinmux_config(peripheral, flags);
330         else {
331                 debug("pinmux functionality not supported\n");
332                 return -1;
333         }
334 }