]>
Commit | Line | Data |
---|---|---|
ab0df36f HS |
1 | /* |
2 | * Copyright (C) 2006, 2008 Atmel Corporation | |
3 | * | |
1a459660 | 4 | * SPDX-License-Identifier: GPL-2.0+ |
ab0df36f HS |
5 | */ |
6 | #include <common.h> | |
7 | ||
8 | #include <asm/io.h> | |
9 | ||
10 | #include <asm/arch/chip-features.h> | |
5d73bc7a | 11 | #include <asm/arch/hardware.h> |
ab0df36f HS |
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 */ | |
6314c84d | 109 | portmux_select_peripheral(PORTMUX_PORT_D, portd_mask, |
ab0df36f HS |
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 | |
716ece1d MJ |
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 |