blob: 58327bac87ae48cc9b5e6ce02d55d51a8052d8dd [file] [log] [blame]
Haavard Skinnemoen610b3622008-08-29 21:09:49 +02001/*
2 * Copyright (C) 2006, 2008 Atmel Corporation
3 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02004 * SPDX-License-Identifier: GPL-2.0+
Haavard Skinnemoen610b3622008-08-29 21:09:49 +02005 */
6#include <common.h>
7
8#include <asm/io.h>
9
10#include <asm/arch/chip-features.h>
Andreas Bießmann94156fa2010-11-04 23:15:30 +000011#include <asm/arch/hardware.h>
Haavard Skinnemoen610b3622008-08-29 21:09:49 +020012#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 */
18void 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
46void 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
79void 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 */
Andreas Bießmann25715432012-08-16 02:19:19 +0000109 portmux_select_peripheral(PORTMUX_PORT_D, portd_mask,
Haavard Skinnemoen610b3622008-08-29 21:09:49 +0200110 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
117void 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
153void 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
173void 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
Mark Jacksonc563e482009-07-21 11:11:37 +0100189
190#ifdef AT32AP700x_CHIP_HAS_LCDC
191void 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