2 * Copyright (C) 2006, 2008 Atmel Corporation
4 * See file CREDITS for list of people who contributed to this
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 #include <asm/arch/chip-features.h>
27 #include <asm/arch/memory-map.h>
28 #include <asm/arch/portmux.h>
31 * Lots of small functions here. We depend on --gc-sections getting
32 * rid of the ones we don't need.
34 void portmux_enable_ebi(unsigned int bus_width, unsigned int addr_width,
35 unsigned long flags, unsigned long drive_strength)
37 unsigned long porte_mask = 0;
40 portmux_select_peripheral(PORTMUX_PORT_E, 0xffff,
41 PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
43 porte_mask |= (((1 << (addr_width - 23)) - 1) & 7) << 16;
44 if (flags & PORTMUX_EBI_CS(2))
45 porte_mask |= 1 << 25;
46 if (flags & PORTMUX_EBI_CS(4))
47 porte_mask |= 1 << 21;
48 if (flags & PORTMUX_EBI_CS(5))
49 porte_mask |= 1 << 22;
50 if (flags & (PORTMUX_EBI_CF(0) | PORTMUX_EBI_CF(1)))
51 porte_mask |= (1 << 19) | (1 << 20) | (1 << 23);
53 portmux_select_peripheral(PORTMUX_PORT_E, porte_mask,
56 if (flags & PORTMUX_EBI_NWAIT)
57 portmux_select_peripheral(PORTMUX_PORT_E, 1 << 24,
58 PORTMUX_FUNC_A, PORTMUX_PULL_UP);
61 #ifdef AT32AP700x_CHIP_HAS_MACB
62 void portmux_enable_macb0(unsigned long flags, unsigned long drive_strength)
64 unsigned long portc_mask;
66 portc_mask = (1 << 3) /* TXD0 */
71 | (1 << 10) /* RXD1 */
72 | (1 << 13) /* RXER */
73 | (1 << 15) /* RXDV */
75 | (1 << 17); /* MDIO */
77 if (flags & PORTMUX_MACB_MII)
78 portc_mask |= (1 << 0) /* COL */
83 | (1 << 11) /* RXD2 */
84 | (1 << 12) /* RXD3 */
85 | (1 << 14); /* RXCK */
87 if (flags & PORTMUX_MACB_SPEED)
88 portc_mask |= (1 << 18);/* SPD */
90 /* REVISIT: Some pins are probably pure outputs */
91 portmux_select_peripheral(PORTMUX_PORT_C, portc_mask,
92 PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
95 void portmux_enable_macb1(unsigned long flags, unsigned long drive_strength)
97 unsigned long portc_mask = 0;
98 unsigned long portd_mask;
100 portd_mask = (1 << 13) /* TXD0 */
101 | (1 << 14) /* TXD1 */
102 | (1 << 11) /* TXEN */
103 | (1 << 12) /* TXCK */
104 | (1 << 10) /* RXD0 */
105 | (1 << 6) /* RXD1 */
106 | (1 << 5) /* RXER */
107 | (1 << 4) /* RXDV */
109 | (1 << 2); /* MDIO */
111 if (flags & PORTMUX_MACB_MII)
112 portc_mask = (1 << 19) /* COL */
113 | (1 << 23) /* CRS */
114 | (1 << 26) /* TXER */
115 | (1 << 27) /* TXD2 */
116 | (1 << 28) /* TXD3 */
117 | (1 << 29) /* RXD2 */
118 | (1 << 30) /* RXD3 */
119 | (1 << 24); /* RXCK */
121 if (flags & PORTMUX_MACB_SPEED)
122 portd_mask |= (1 << 15);/* SPD */
124 /* REVISIT: Some pins are probably pure outputs */
125 portmux_select_peripheral(PORTMUX_PORT_D, portc_mask,
126 PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
127 portmux_select_peripheral(PORTMUX_PORT_C, portc_mask,
128 PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
132 #ifdef AT32AP700x_CHIP_HAS_MMCI
133 void portmux_enable_mmci(unsigned int slot, unsigned long flags,
134 unsigned long drive_strength)
137 unsigned long portmux_flags = PORTMUX_PULL_UP;
139 /* First, the common CLK signal. It doesn't need a pull-up */
140 portmux_select_peripheral(PORTMUX_PORT_A, 1 << 10,
143 if (flags & PORTMUX_MMCI_EXT_PULLUP)
146 /* Then, the per-slot signals */
149 mask = (1 << 11) | (1 << 12); /* CMD and DATA0 */
150 if (flags & PORTMUX_MMCI_4BIT)
152 mask |= (1 << 13) | (1 << 14) | (1 << 15);
153 portmux_select_peripheral(PORTMUX_PORT_A, mask,
154 PORTMUX_FUNC_A, portmux_flags);
157 mask = (1 << 6) | (1 << 7); /* CMD and DATA0 */
158 if (flags & PORTMUX_MMCI_4BIT)
160 mask |= (1 << 8) | (1 << 9) | (1 << 10);
161 portmux_select_peripheral(PORTMUX_PORT_B, mask,
162 PORTMUX_FUNC_B, portmux_flags);
168 #ifdef AT32AP700x_CHIP_HAS_SPI
169 void portmux_enable_spi0(unsigned long cs_mask, unsigned long drive_strength)
171 unsigned long pin_mask;
174 portmux_select_peripheral(PORTMUX_PORT_A, (1 << 1) | (1 << 2),
177 portmux_select_peripheral(PORTMUX_PORT_A, 1 << 0,
178 PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
180 /* Set up NPCSx as GPIO outputs, initially high */
181 pin_mask = (cs_mask & 7) << 3;
182 if (cs_mask & (1 << 3))
185 portmux_select_gpio(PORTMUX_PORT_A, pin_mask,
186 PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH);
189 void portmux_enable_spi1(unsigned long cs_mask, unsigned long drive_strength)
192 portmux_select_peripheral(PORTMUX_PORT_B, (1 << 1) | (1 << 5),
195 portmux_select_peripheral(PORTMUX_PORT_B, 1 << 0,
196 PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);
198 /* Set up NPCSx as GPIO outputs, initially high */
199 portmux_select_gpio(PORTMUX_PORT_B, (cs_mask & 7) << 2,
200 PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH);
201 portmux_select_gpio(PORTMUX_PORT_A, (cs_mask & 8) << (27 - 3),
202 PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH);
206 #ifdef AT32AP700x_CHIP_HAS_LCDC
207 void portmux_enable_lcdc(int pin_config)
209 unsigned long portc_mask = 0;
210 unsigned long portd_mask = 0;
211 unsigned long porte_mask = 0;
213 switch (pin_config) {
215 portc_mask = (1 << 19) /* CC */
216 | (1 << 20) /* HSYNC */
217 | (1 << 21) /* PCLK */
218 | (1 << 22) /* VSYNC */
219 | (1 << 23) /* DVAL */
220 | (1 << 24) /* MODE */
221 | (1 << 25) /* PWR */
222 | (1 << 26) /* DATA0 */
223 | (1 << 27) /* DATA1 */
224 | (1 << 28) /* DATA2 */
225 | (1 << 29) /* DATA3 */
226 | (1 << 30) /* DATA4 */
227 | (1 << 31); /* DATA5 */
229 portd_mask = (1 << 0) /* DATA6 */
230 | (1 << 1) /* DATA7 */
231 | (1 << 2) /* DATA8 */
232 | (1 << 3) /* DATA9 */
233 | (1 << 4) /* DATA10 */
234 | (1 << 5) /* DATA11 */
235 | (1 << 6) /* DATA12 */
236 | (1 << 7) /* DATA13 */
237 | (1 << 8) /* DATA14 */
238 | (1 << 9) /* DATA15 */
239 | (1 << 10) /* DATA16 */
240 | (1 << 11) /* DATA17 */
241 | (1 << 12) /* DATA18 */
242 | (1 << 13) /* DATA19 */
243 | (1 << 14) /* DATA20 */
244 | (1 << 15) /* DATA21 */
245 | (1 << 16) /* DATA22 */
246 | (1 << 17); /* DATA23 */
250 portc_mask = (1 << 20) /* HSYNC */
251 | (1 << 21) /* PCLK */
252 | (1 << 22) /* VSYNC */
253 | (1 << 25) /* PWR */
254 | (1 << 31); /* DATA5 */
256 portd_mask = (1 << 0) /* DATA6 */
257 | (1 << 1) /* DATA7 */
258 | (1 << 7) /* DATA13 */
259 | (1 << 8) /* DATA14 */
260 | (1 << 9) /* DATA15 */
261 | (1 << 16) /* DATA22 */
262 | (1 << 17); /* DATA23 */
264 porte_mask = (1 << 0) /* CC */
265 | (1 << 1) /* DVAL */
266 | (1 << 2) /* MODE */
267 | (1 << 3) /* DATA0 */
268 | (1 << 4) /* DATA1 */
269 | (1 << 5) /* DATA2 */
270 | (1 << 6) /* DATA3 */
271 | (1 << 7) /* DATA4 */
272 | (1 << 8) /* DATA8 */
273 | (1 << 9) /* DATA9 */
274 | (1 << 10) /* DATA10 */
275 | (1 << 11) /* DATA11 */
276 | (1 << 12) /* DATA12 */
277 | (1 << 13) /* DATA16 */
278 | (1 << 14) /* DATA17 */
279 | (1 << 15) /* DATA18 */
280 | (1 << 16) /* DATA19 */
281 | (1 << 17) /* DATA20 */
282 | (1 << 18); /* DATA21 */
286 /* REVISIT: Some pins are probably pure outputs */
287 portmux_select_peripheral(PORTMUX_PORT_C, portc_mask,
288 PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
289 portmux_select_peripheral(PORTMUX_PORT_D, portd_mask,
290 PORTMUX_FUNC_A, PORTMUX_BUSKEEPER);
291 portmux_select_peripheral(PORTMUX_PORT_E, porte_mask,
292 PORTMUX_FUNC_B, PORTMUX_BUSKEEPER);