]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/avr32/cpu/at32ap700x/portmux.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[karo-tx-uboot.git] / arch / avr32 / cpu / at32ap700x / portmux.c
1 /*
2  * Copyright (C) 2006, 2008 Atmel Corporation
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 #include <common.h>
7
8 #include <asm/io.h>
9
10 #include <asm/arch/chip-features.h>
11 #include <asm/arch/hardware.h>
12 #include <asm/arch/portmux.h>
13
14 /*
15  * Lots of small functions here. We depend on --gc-sections getting
16  * rid of the ones we don't need.
17  */
18 void portmux_enable_ebi(unsigned int bus_width, unsigned int addr_width,
19                 unsigned long flags, unsigned long drive_strength)
20 {
21         unsigned long porte_mask = 0;
22
23         if (bus_width > 16)
24                 portmux_select_peripheral(PORTMUX_PORT_E, 0xffff,
25                                 PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
26         if (addr_width > 23)
27                 porte_mask |= (((1 << (addr_width - 23)) - 1) & 7) << 16;
28         if (flags & PORTMUX_EBI_CS(2))
29                 porte_mask |= 1 << 25;
30         if (flags & PORTMUX_EBI_CS(4))
31                 porte_mask |= 1 << 21;
32         if (flags & PORTMUX_EBI_CS(5))
33                 porte_mask |= 1 << 22;
34         if (flags & (PORTMUX_EBI_CF(0) | PORTMUX_EBI_CF(1)))
35                 porte_mask |= (1 << 19) | (1 << 20) | (1 << 23);
36
37         portmux_select_peripheral(PORTMUX_PORT_E, porte_mask,
38                         PORTMUX_FUNC_A, 0);
39
40         if (flags & PORTMUX_EBI_NWAIT)
41                 portmux_select_peripheral(PORTMUX_PORT_E, 1 << 24,
42                                 PORTMUX_FUNC_A, PORTMUX_PULL_UP);
43 }
44
45 #ifdef AT32AP700x_CHIP_HAS_MACB
46 void portmux_enable_macb0(unsigned long flags, unsigned long drive_strength)
47 {
48         unsigned long portc_mask;
49
50         portc_mask = (1 << 3)   /* TXD0 */
51                 | (1 << 4)      /* TXD1 */
52                 | (1 << 7)      /* TXEN */
53                 | (1 << 8)      /* TXCK */
54                 | (1 << 9)      /* RXD0 */
55                 | (1 << 10)     /* RXD1 */
56                 | (1 << 13)     /* RXER */
57                 | (1 << 15)     /* RXDV */
58                 | (1 << 16)     /* MDC  */
59                 | (1 << 17);    /* MDIO */
60
61         if (flags & PORTMUX_MACB_MII)
62                 portc_mask |= (1 << 0)  /* COL  */
63                         | (1 << 1)      /* CRS  */
64                         | (1 << 2)      /* TXER */
65                         | (1 << 5)      /* TXD2 */
66                         | (1 << 6)      /* TXD3 */
67                         | (1 << 11)     /* RXD2 */
68                         | (1 << 12)     /* RXD3 */
69                         | (1 << 14);    /* RXCK */
70
71         if (flags & PORTMUX_MACB_SPEED)
72                 portc_mask |= (1 << 18);/* SPD  */
73
74         /* REVISIT: Some pins are probably pure outputs */
75         portmux_select_peripheral(PORTMUX_PORT_C, portc_mask,
76                         PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
77 }
78
79 void portmux_enable_macb1(unsigned long flags, unsigned long drive_strength)
80 {
81         unsigned long portc_mask = 0;
82         unsigned long portd_mask;
83
84         portd_mask = (1 << 13)  /* TXD0 */
85                 | (1 << 14)     /* TXD1 */
86                 | (1 << 11)     /* TXEN */
87                 | (1 << 12)     /* TXCK */
88                 | (1 << 10)     /* RXD0 */
89                 | (1 << 6)      /* RXD1 */
90                 | (1 << 5)      /* RXER */
91                 | (1 << 4)      /* RXDV */
92                 | (1 << 3)      /* MDC  */
93                 | (1 << 2);     /* MDIO */
94
95         if (flags & PORTMUX_MACB_MII)
96                 portc_mask = (1 << 19)  /* COL  */
97                         | (1 << 23)     /* CRS  */
98                         | (1 << 26)     /* TXER */
99                         | (1 << 27)     /* TXD2 */
100                         | (1 << 28)     /* TXD3 */
101                         | (1 << 29)     /* RXD2 */
102                         | (1 << 30)     /* RXD3 */
103                         | (1 << 24);    /* RXCK */
104
105         if (flags & PORTMUX_MACB_SPEED)
106                 portd_mask |= (1 << 15);/* SPD  */
107
108         /* REVISIT: Some pins are probably pure outputs */
109         portmux_select_peripheral(PORTMUX_PORT_D, portd_mask,
110                         PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
111         portmux_select_peripheral(PORTMUX_PORT_C, portc_mask,
112                         PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
113 }
114 #endif
115
116 #ifdef AT32AP700x_CHIP_HAS_MMCI
117 void portmux_enable_mmci(unsigned int slot, unsigned long flags,
118                 unsigned long drive_strength)
119 {
120         unsigned long mask;
121         unsigned long portmux_flags = PORTMUX_PULL_UP;
122
123         /* First, the common CLK signal. It doesn't need a pull-up */
124         portmux_select_peripheral(PORTMUX_PORT_A, 1 << 10,
125                         PORTMUX_FUNC_A, 0);
126
127         if (flags & PORTMUX_MMCI_EXT_PULLUP)
128                 portmux_flags = 0;
129
130         /* Then, the per-slot signals */
131         switch (slot) {
132         case 0:
133                 mask = (1 << 11) | (1 << 12);   /* CMD and DATA0 */
134                 if (flags & PORTMUX_MMCI_4BIT)
135                         /* DATA1..DATA3 */
136                         mask |= (1 << 13) | (1 << 14) | (1 << 15);
137                 portmux_select_peripheral(PORTMUX_PORT_A, mask,
138                                 PORTMUX_FUNC_A, portmux_flags);
139                 break;
140         case 1:
141                 mask = (1 << 6) | (1 << 7);     /* CMD and DATA0 */
142                 if (flags & PORTMUX_MMCI_4BIT)
143                         /* DATA1..DATA3 */
144                         mask |= (1 << 8) | (1 << 9) | (1 << 10);
145                 portmux_select_peripheral(PORTMUX_PORT_B, mask,
146                                 PORTMUX_FUNC_B, portmux_flags);
147                 break;
148         }
149 }
150 #endif
151
152 #ifdef AT32AP700x_CHIP_HAS_SPI
153 void portmux_enable_spi0(unsigned long cs_mask, unsigned long drive_strength)
154 {
155         unsigned long pin_mask;
156
157         /* MOSI and SCK */
158         portmux_select_peripheral(PORTMUX_PORT_A, (1 << 1) | (1 << 2),
159                         PORTMUX_FUNC_A, 0);
160         /* MISO may float */
161         portmux_select_peripheral(PORTMUX_PORT_A, 1 << 0,
162                         PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
163
164         /* Set up NPCSx as GPIO outputs, initially high */
165         pin_mask = (cs_mask & 7) << 3;
166         if (cs_mask & (1 << 3))
167                 pin_mask |= 1 << 20;
168
169         portmux_select_gpio(PORTMUX_PORT_A, pin_mask,
170                         PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH);
171 }
172
173 void portmux_enable_spi1(unsigned long cs_mask, unsigned long drive_strength)
174 {
175         /* MOSI and SCK */
176         portmux_select_peripheral(PORTMUX_PORT_B, (1 << 1) | (1 << 5),
177                         PORTMUX_FUNC_B, 0);
178         /* MISO may float */
179         portmux_select_peripheral(PORTMUX_PORT_B, 1 << 0,
180                         PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
181
182         /* Set up NPCSx as GPIO outputs, initially high */
183         portmux_select_gpio(PORTMUX_PORT_B, (cs_mask & 7) << 2,
184                         PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH);
185         portmux_select_gpio(PORTMUX_PORT_A, (cs_mask & 8) << (27 - 3),
186                         PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH);
187 }
188 #endif
189
190 #ifdef AT32AP700x_CHIP_HAS_LCDC
191 void portmux_enable_lcdc(int pin_config)
192 {
193         unsigned long portc_mask = 0;
194         unsigned long portd_mask = 0;
195         unsigned long porte_mask = 0;
196
197         switch (pin_config) {
198         case 0:
199                 portc_mask = (1 << 19)  /* CC     */
200                         | (1 << 20)     /* HSYNC  */
201                         | (1 << 21)     /* PCLK   */
202                         | (1 << 22)     /* VSYNC  */
203                         | (1 << 23)     /* DVAL   */
204                         | (1 << 24)     /* MODE   */
205                         | (1 << 25)     /* PWR    */
206                         | (1 << 26)     /* DATA0  */
207                         | (1 << 27)     /* DATA1  */
208                         | (1 << 28)     /* DATA2  */
209                         | (1 << 29)     /* DATA3  */
210                         | (1 << 30)     /* DATA4  */
211                         | (1 << 31);    /* DATA5  */
212
213                 portd_mask = (1 << 0)   /* DATA6  */
214                         | (1 << 1)      /* DATA7  */
215                         | (1 << 2)      /* DATA8  */
216                         | (1 << 3)      /* DATA9  */
217                         | (1 << 4)      /* DATA10 */
218                         | (1 << 5)      /* DATA11 */
219                         | (1 << 6)      /* DATA12 */
220                         | (1 << 7)      /* DATA13 */
221                         | (1 << 8)      /* DATA14 */
222                         | (1 << 9)      /* DATA15 */
223                         | (1 << 10)     /* DATA16 */
224                         | (1 << 11)     /* DATA17 */
225                         | (1 << 12)     /* DATA18 */
226                         | (1 << 13)     /* DATA19 */
227                         | (1 << 14)     /* DATA20 */
228                         | (1 << 15)     /* DATA21 */
229                         | (1 << 16)     /* DATA22 */
230                         | (1 << 17);    /* DATA23 */
231                 break;
232
233         case 1:
234                 portc_mask = (1 << 20)  /* HSYNC  */
235                         | (1 << 21)     /* PCLK   */
236                         | (1 << 22)     /* VSYNC  */
237                         | (1 << 25)     /* PWR    */
238                         | (1 << 31);    /* DATA5  */
239
240                 portd_mask = (1 << 0)   /* DATA6  */
241                         | (1 << 1)      /* DATA7  */
242                         | (1 << 7)      /* DATA13 */
243                         | (1 << 8)      /* DATA14 */
244                         | (1 << 9)      /* DATA15 */
245                         | (1 << 16)     /* DATA22 */
246                         | (1 << 17);    /* DATA23 */
247
248                 porte_mask = (1 << 0)   /* CC     */
249                         | (1 << 1)      /* DVAL   */
250                         | (1 << 2)      /* MODE   */
251                         | (1 << 3)      /* DATA0  */
252                         | (1 << 4)      /* DATA1  */
253                         | (1 << 5)      /* DATA2  */
254                         | (1 << 6)      /* DATA3  */
255                         | (1 << 7)      /* DATA4  */
256                         | (1 << 8)      /* DATA8  */
257                         | (1 << 9)      /* DATA9  */
258                         | (1 << 10)     /* DATA10 */
259                         | (1 << 11)     /* DATA11 */
260                         | (1 << 12)     /* DATA12 */
261                         | (1 << 13)     /* DATA16 */
262                         | (1 << 14)     /* DATA17 */
263                         | (1 << 15)     /* DATA18 */
264                         | (1 << 16)     /* DATA19 */
265                         | (1 << 17)     /* DATA20 */
266                         | (1 << 18);    /* DATA21 */
267                 break;
268         }
269
270         /* REVISIT: Some pins are probably pure outputs */
271         portmux_select_peripheral(PORTMUX_PORT_C, portc_mask,
272                         PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
273         portmux_select_peripheral(PORTMUX_PORT_D, portd_mask,
274                         PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
275         portmux_select_peripheral(PORTMUX_PORT_E, porte_mask,
276                         PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
277 }
278 #endif