]>
Commit | Line | Data |
---|---|---|
5289e83a CN |
1 | /* |
2 | * mux.c | |
3 | * | |
4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public License as | |
8 | * published by the Free Software Foundation version 2. | |
9 | * | |
10 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | |
11 | * kind, whether express or implied; without even the implied warranty | |
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | */ | |
15 | ||
db7dd810 TR |
16 | #include <common.h> |
17 | #include <asm/arch/sys_proto.h> | |
5289e83a CN |
18 | #include <asm/arch/hardware.h> |
19 | #include <asm/io.h> | |
036fd65a | 20 | #include <i2c.h> |
5289e83a CN |
21 | |
22 | #define MUX_CFG(value, offset) \ | |
23 | __raw_writel(value, (CTRL_BASE + offset)); | |
24 | ||
25 | /* PAD Control Fields */ | |
26 | #define SLEWCTRL (0x1 << 6) | |
27 | #define RXACTIVE (0x1 << 5) | |
28 | #define PULLUP_EN (0x1 << 4) /* Pull UP Selection */ | |
29 | #define PULLUDEN (0x0 << 3) /* Pull up enabled */ | |
30 | #define PULLUDDIS (0x1 << 3) /* Pull up disabled */ | |
31 | #define MODE(val) val /* used for Readability */ | |
32 | ||
33 | /* | |
34 | * PAD CONTROL OFFSETS | |
35 | * Field names corresponds to the pad signal name | |
36 | */ | |
37 | struct pad_signals { | |
38 | int gpmc_ad0; | |
39 | int gpmc_ad1; | |
40 | int gpmc_ad2; | |
41 | int gpmc_ad3; | |
42 | int gpmc_ad4; | |
43 | int gpmc_ad5; | |
44 | int gpmc_ad6; | |
45 | int gpmc_ad7; | |
46 | int gpmc_ad8; | |
47 | int gpmc_ad9; | |
48 | int gpmc_ad10; | |
49 | int gpmc_ad11; | |
50 | int gpmc_ad12; | |
51 | int gpmc_ad13; | |
52 | int gpmc_ad14; | |
53 | int gpmc_ad15; | |
54 | int gpmc_a0; | |
55 | int gpmc_a1; | |
56 | int gpmc_a2; | |
57 | int gpmc_a3; | |
58 | int gpmc_a4; | |
59 | int gpmc_a5; | |
60 | int gpmc_a6; | |
61 | int gpmc_a7; | |
62 | int gpmc_a8; | |
63 | int gpmc_a9; | |
64 | int gpmc_a10; | |
65 | int gpmc_a11; | |
66 | int gpmc_wait0; | |
67 | int gpmc_wpn; | |
68 | int gpmc_be1n; | |
69 | int gpmc_csn0; | |
70 | int gpmc_csn1; | |
71 | int gpmc_csn2; | |
72 | int gpmc_csn3; | |
73 | int gpmc_clk; | |
74 | int gpmc_advn_ale; | |
75 | int gpmc_oen_ren; | |
76 | int gpmc_wen; | |
77 | int gpmc_be0n_cle; | |
78 | int lcd_data0; | |
79 | int lcd_data1; | |
80 | int lcd_data2; | |
81 | int lcd_data3; | |
82 | int lcd_data4; | |
83 | int lcd_data5; | |
84 | int lcd_data6; | |
85 | int lcd_data7; | |
86 | int lcd_data8; | |
87 | int lcd_data9; | |
88 | int lcd_data10; | |
89 | int lcd_data11; | |
90 | int lcd_data12; | |
91 | int lcd_data13; | |
92 | int lcd_data14; | |
93 | int lcd_data15; | |
94 | int lcd_vsync; | |
95 | int lcd_hsync; | |
96 | int lcd_pclk; | |
97 | int lcd_ac_bias_en; | |
98 | int mmc0_dat3; | |
99 | int mmc0_dat2; | |
100 | int mmc0_dat1; | |
101 | int mmc0_dat0; | |
102 | int mmc0_clk; | |
103 | int mmc0_cmd; | |
104 | int mii1_col; | |
105 | int mii1_crs; | |
106 | int mii1_rxerr; | |
107 | int mii1_txen; | |
108 | int mii1_rxdv; | |
109 | int mii1_txd3; | |
110 | int mii1_txd2; | |
111 | int mii1_txd1; | |
112 | int mii1_txd0; | |
113 | int mii1_txclk; | |
114 | int mii1_rxclk; | |
115 | int mii1_rxd3; | |
116 | int mii1_rxd2; | |
117 | int mii1_rxd1; | |
118 | int mii1_rxd0; | |
119 | int rmii1_refclk; | |
120 | int mdio_data; | |
121 | int mdio_clk; | |
122 | int spi0_sclk; | |
123 | int spi0_d0; | |
124 | int spi0_d1; | |
125 | int spi0_cs0; | |
126 | int spi0_cs1; | |
127 | int ecap0_in_pwm0_out; | |
128 | int uart0_ctsn; | |
129 | int uart0_rtsn; | |
130 | int uart0_rxd; | |
131 | int uart0_txd; | |
132 | int uart1_ctsn; | |
133 | int uart1_rtsn; | |
134 | int uart1_rxd; | |
135 | int uart1_txd; | |
136 | int i2c0_sda; | |
137 | int i2c0_scl; | |
138 | int mcasp0_aclkx; | |
139 | int mcasp0_fsx; | |
140 | int mcasp0_axr0; | |
141 | int mcasp0_ahclkr; | |
142 | int mcasp0_aclkr; | |
143 | int mcasp0_fsr; | |
144 | int mcasp0_axr1; | |
145 | int mcasp0_ahclkx; | |
146 | int xdma_event_intr0; | |
147 | int xdma_event_intr1; | |
148 | int nresetin_out; | |
149 | int porz; | |
150 | int nnmi; | |
151 | int osc0_in; | |
152 | int osc0_out; | |
153 | int rsvd1; | |
154 | int tms; | |
155 | int tdi; | |
156 | int tdo; | |
157 | int tck; | |
158 | int ntrst; | |
159 | int emu0; | |
160 | int emu1; | |
161 | int osc1_in; | |
162 | int osc1_out; | |
163 | int pmic_power_en; | |
164 | int rtc_porz; | |
165 | int rsvd2; | |
166 | int ext_wakeup; | |
167 | int enz_kaldo_1p8v; | |
168 | int usb0_dm; | |
169 | int usb0_dp; | |
170 | int usb0_ce; | |
171 | int usb0_id; | |
172 | int usb0_vbus; | |
173 | int usb0_drvvbus; | |
174 | int usb1_dm; | |
175 | int usb1_dp; | |
176 | int usb1_ce; | |
177 | int usb1_id; | |
178 | int usb1_vbus; | |
179 | int usb1_drvvbus; | |
180 | int ddr_resetn; | |
181 | int ddr_csn0; | |
182 | int ddr_cke; | |
183 | int ddr_ck; | |
184 | int ddr_nck; | |
185 | int ddr_casn; | |
186 | int ddr_rasn; | |
187 | int ddr_wen; | |
188 | int ddr_ba0; | |
189 | int ddr_ba1; | |
190 | int ddr_ba2; | |
191 | int ddr_a0; | |
192 | int ddr_a1; | |
193 | int ddr_a2; | |
194 | int ddr_a3; | |
195 | int ddr_a4; | |
196 | int ddr_a5; | |
197 | int ddr_a6; | |
198 | int ddr_a7; | |
199 | int ddr_a8; | |
200 | int ddr_a9; | |
201 | int ddr_a10; | |
202 | int ddr_a11; | |
203 | int ddr_a12; | |
204 | int ddr_a13; | |
205 | int ddr_a14; | |
206 | int ddr_a15; | |
207 | int ddr_odt; | |
208 | int ddr_d0; | |
209 | int ddr_d1; | |
210 | int ddr_d2; | |
211 | int ddr_d3; | |
212 | int ddr_d4; | |
213 | int ddr_d5; | |
214 | int ddr_d6; | |
215 | int ddr_d7; | |
216 | int ddr_d8; | |
217 | int ddr_d9; | |
218 | int ddr_d10; | |
219 | int ddr_d11; | |
220 | int ddr_d12; | |
221 | int ddr_d13; | |
222 | int ddr_d14; | |
223 | int ddr_d15; | |
224 | int ddr_dqm0; | |
225 | int ddr_dqm1; | |
226 | int ddr_dqs0; | |
227 | int ddr_dqsn0; | |
228 | int ddr_dqs1; | |
229 | int ddr_dqsn1; | |
230 | int ddr_vref; | |
231 | int ddr_vtp; | |
232 | int ddr_strben0; | |
233 | int ddr_strben1; | |
234 | int ain7; | |
235 | int ain6; | |
236 | int ain5; | |
237 | int ain4; | |
238 | int ain3; | |
239 | int ain2; | |
240 | int ain1; | |
241 | int ain0; | |
242 | int vrefp; | |
243 | int vrefn; | |
244 | }; | |
245 | ||
246 | struct module_pin_mux { | |
247 | short reg_offset; | |
248 | unsigned char val; | |
249 | }; | |
250 | ||
251 | /* Pad control register offset */ | |
252 | #define PAD_CTRL_BASE 0x800 | |
253 | #define OFFSET(x) (unsigned int) (&((struct pad_signals *) \ | |
254 | (PAD_CTRL_BASE))->x) | |
255 | ||
256 | static struct module_pin_mux uart0_pin_mux[] = { | |
257 | {OFFSET(uart0_rxd), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* UART0_RXD */ | |
258 | {OFFSET(uart0_txd), (MODE(0) | PULLUDEN)}, /* UART0_TXD */ | |
259 | {-1}, | |
260 | }; | |
261 | ||
876bdd6d CN |
262 | static struct module_pin_mux mmc0_pin_mux[] = { |
263 | {OFFSET(mmc0_dat3), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT3 */ | |
264 | {OFFSET(mmc0_dat2), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT2 */ | |
265 | {OFFSET(mmc0_dat1), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT1 */ | |
266 | {OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT0 */ | |
267 | {OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CLK */ | |
268 | {OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CMD */ | |
269 | {OFFSET(mcasp0_aclkr), (MODE(4) | RXACTIVE)}, /* MMC0_WP */ | |
270 | {OFFSET(spi0_cs1), (MODE(5) | RXACTIVE | PULLUP_EN)}, /* MMC0_CD */ | |
271 | {-1}, | |
272 | }; | |
db7dd810 TR |
273 | |
274 | static struct module_pin_mux mmc0_pin_mux_sk_evm[] = { | |
275 | {OFFSET(mmc0_dat3), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT3 */ | |
276 | {OFFSET(mmc0_dat2), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT2 */ | |
277 | {OFFSET(mmc0_dat1), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT1 */ | |
278 | {OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT0 */ | |
279 | {OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CLK */ | |
280 | {OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CMD */ | |
281 | {OFFSET(spi0_cs1), (MODE(5) | RXACTIVE | PULLUP_EN)}, /* MMC0_CD */ | |
282 | {-1}, | |
283 | }; | |
876bdd6d | 284 | |
6bfca503 TR |
285 | static struct module_pin_mux mmc1_pin_mux[] = { |
286 | {OFFSET(gpmc_ad3), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT3 */ | |
287 | {OFFSET(gpmc_ad2), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT2 */ | |
288 | {OFFSET(gpmc_ad1), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT1 */ | |
289 | {OFFSET(gpmc_ad0), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT0 */ | |
290 | {OFFSET(gpmc_csn1), (MODE(2) | RXACTIVE | PULLUP_EN)}, /* MMC1_CLK */ | |
291 | {OFFSET(gpmc_csn2), (MODE(2) | RXACTIVE | PULLUP_EN)}, /* MMC1_CMD */ | |
292 | {OFFSET(gpmc_csn0), (MODE(7) | RXACTIVE | PULLUP_EN)}, /* MMC1_WP */ | |
293 | {OFFSET(gpmc_advn_ale), (MODE(7) | RXACTIVE | PULLUP_EN)}, /* MMC1_CD */ | |
294 | {-1}, | |
295 | }; | |
296 | ||
b4116ede PR |
297 | static struct module_pin_mux i2c0_pin_mux[] = { |
298 | {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | | |
299 | PULLUDEN | SLEWCTRL)}, /* I2C_DATA */ | |
300 | {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE | | |
301 | PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */ | |
302 | {-1}, | |
303 | }; | |
304 | ||
d3decdeb SS |
305 | static struct module_pin_mux i2c1_pin_mux[] = { |
306 | {OFFSET(spi0_d1), (MODE(2) | RXACTIVE | | |
307 | PULLUDEN | SLEWCTRL)}, /* I2C_DATA */ | |
308 | {OFFSET(spi0_cs0), (MODE(2) | RXACTIVE | | |
309 | PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */ | |
310 | {-1}, | |
311 | }; | |
312 | ||
a4a99fff TR |
313 | static struct module_pin_mux spi0_pin_mux[] = { |
314 | {OFFSET(spi0_sclk), (MODE(0) | RXACTIVE | PULLUDEN)}, /* SPI0_SCLK */ | |
315 | {OFFSET(spi0_d0), (MODE(0) | RXACTIVE | | |
316 | PULLUDEN | PULLUP_EN)}, /* SPI0_D0 */ | |
317 | {OFFSET(spi0_d1), (MODE(0) | RXACTIVE | PULLUDEN)}, /* SPI0_D1 */ | |
318 | {OFFSET(spi0_cs0), (MODE(0) | RXACTIVE | | |
319 | PULLUDEN | PULLUP_EN)}, /* SPI0_CS0 */ | |
320 | {-1}, | |
321 | }; | |
322 | ||
65d750be TR |
323 | static struct module_pin_mux gpio0_7_pin_mux[] = { |
324 | {OFFSET(ecap0_in_pwm0_out), (MODE(7) | PULLUDEN)}, /* GPIO0_7 */ | |
325 | {-1}, | |
326 | }; | |
327 | ||
89017e15 CN |
328 | static struct module_pin_mux rgmii1_pin_mux[] = { |
329 | {OFFSET(mii1_txen), MODE(2)}, /* RGMII1_TCTL */ | |
330 | {OFFSET(mii1_rxdv), MODE(2) | RXACTIVE}, /* RGMII1_RCTL */ | |
331 | {OFFSET(mii1_txd3), MODE(2)}, /* RGMII1_TD3 */ | |
332 | {OFFSET(mii1_txd2), MODE(2)}, /* RGMII1_TD2 */ | |
333 | {OFFSET(mii1_txd1), MODE(2)}, /* RGMII1_TD1 */ | |
334 | {OFFSET(mii1_txd0), MODE(2)}, /* RGMII1_TD0 */ | |
335 | {OFFSET(mii1_txclk), MODE(2)}, /* RGMII1_TCLK */ | |
336 | {OFFSET(mii1_rxclk), MODE(2) | RXACTIVE}, /* RGMII1_RCLK */ | |
337 | {OFFSET(mii1_rxd3), MODE(2) | RXACTIVE}, /* RGMII1_RD3 */ | |
338 | {OFFSET(mii1_rxd2), MODE(2) | RXACTIVE}, /* RGMII1_RD2 */ | |
339 | {OFFSET(mii1_rxd1), MODE(2) | RXACTIVE}, /* RGMII1_RD1 */ | |
340 | {OFFSET(mii1_rxd0), MODE(2) | RXACTIVE}, /* RGMII1_RD0 */ | |
341 | {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN},/* MDIO_DATA */ | |
342 | {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */ | |
343 | {-1}, | |
344 | }; | |
345 | ||
346 | static struct module_pin_mux mii1_pin_mux[] = { | |
347 | {OFFSET(mii1_rxerr), MODE(0) | RXACTIVE}, /* MII1_RXERR */ | |
348 | {OFFSET(mii1_txen), MODE(0)}, /* MII1_TXEN */ | |
349 | {OFFSET(mii1_rxdv), MODE(0) | RXACTIVE}, /* MII1_RXDV */ | |
350 | {OFFSET(mii1_txd3), MODE(0)}, /* MII1_TXD3 */ | |
351 | {OFFSET(mii1_txd2), MODE(0)}, /* MII1_TXD2 */ | |
352 | {OFFSET(mii1_txd1), MODE(0)}, /* MII1_TXD1 */ | |
353 | {OFFSET(mii1_txd0), MODE(0)}, /* MII1_TXD0 */ | |
354 | {OFFSET(mii1_txclk), MODE(0) | RXACTIVE}, /* MII1_TXCLK */ | |
355 | {OFFSET(mii1_rxclk), MODE(0) | RXACTIVE}, /* MII1_RXCLK */ | |
356 | {OFFSET(mii1_rxd3), MODE(0) | RXACTIVE}, /* MII1_RXD3 */ | |
357 | {OFFSET(mii1_rxd2), MODE(0) | RXACTIVE}, /* MII1_RXD2 */ | |
358 | {OFFSET(mii1_rxd1), MODE(0) | RXACTIVE}, /* MII1_RXD1 */ | |
359 | {OFFSET(mii1_rxd0), MODE(0) | RXACTIVE}, /* MII1_RXD0 */ | |
360 | {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */ | |
361 | {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */ | |
362 | {-1}, | |
363 | }; | |
364 | ||
5289e83a CN |
365 | /* |
366 | * Configure the pin mux for the module | |
367 | */ | |
368 | static void configure_module_pin_mux(struct module_pin_mux *mod_pin_mux) | |
369 | { | |
370 | int i; | |
371 | ||
372 | if (!mod_pin_mux) | |
373 | return; | |
374 | ||
375 | for (i = 0; mod_pin_mux[i].reg_offset != -1; i++) | |
376 | MUX_CFG(mod_pin_mux[i].val, mod_pin_mux[i].reg_offset); | |
377 | } | |
378 | ||
379 | void enable_uart0_pin_mux(void) | |
380 | { | |
381 | configure_module_pin_mux(uart0_pin_mux); | |
382 | } | |
876bdd6d | 383 | |
b4116ede PR |
384 | |
385 | void enable_i2c0_pin_mux(void) | |
386 | { | |
387 | configure_module_pin_mux(i2c0_pin_mux); | |
388 | } | |
d3decdeb | 389 | |
036fd65a TR |
390 | /* |
391 | * The AM335x GP EVM, if daughter card(s) are connected, can have 8 | |
392 | * different profiles. These profiles determine what peripherals are | |
393 | * valid and need pinmux to be configured. | |
394 | */ | |
395 | #define PROFILE_NONE 0x0 | |
396 | #define PROFILE_0 (1 << 0) | |
397 | #define PROFILE_1 (1 << 1) | |
398 | #define PROFILE_2 (1 << 2) | |
399 | #define PROFILE_3 (1 << 3) | |
400 | #define PROFILE_4 (1 << 4) | |
401 | #define PROFILE_5 (1 << 5) | |
402 | #define PROFILE_6 (1 << 6) | |
403 | #define PROFILE_7 (1 << 7) | |
404 | #define PROFILE_MASK 0x7 | |
405 | #define PROFILE_ALL 0xFF | |
406 | ||
407 | /* CPLD registers */ | |
408 | #define I2C_CPLD_ADDR 0x35 | |
409 | #define CFG_REG 0x10 | |
410 | ||
411 | static unsigned short detect_daughter_board_profile(void) | |
d3decdeb | 412 | { |
036fd65a TR |
413 | unsigned short val; |
414 | ||
415 | if (i2c_probe(I2C_CPLD_ADDR)) | |
416 | return PROFILE_NONE; | |
89017e15 | 417 | |
036fd65a TR |
418 | if (i2c_read(I2C_CPLD_ADDR, CFG_REG, 1, (unsigned char *)(&val), 2)) |
419 | return PROFILE_NONE; | |
420 | ||
421 | return (1 << (val & PROFILE_MASK)); | |
422 | } | |
423 | ||
424 | void enable_board_pin_mux(struct am335x_baseboard_id *header) | |
425 | { | |
426 | /* Do board-specific muxes. */ | |
db7dd810 TR |
427 | if (!strncmp(header->name, "A335BONE", HDR_NAME_LEN)) { |
428 | /* Beaglebone pinmux */ | |
036fd65a | 429 | configure_module_pin_mux(i2c1_pin_mux); |
db7dd810 TR |
430 | configure_module_pin_mux(mii1_pin_mux); |
431 | configure_module_pin_mux(mmc0_pin_mux); | |
6bfca503 | 432 | configure_module_pin_mux(mmc1_pin_mux); |
db7dd810 TR |
433 | } else if (!strncmp(header->config, "SKU#01", 6)) { |
434 | /* General Purpose EVM */ | |
036fd65a | 435 | unsigned short profile = detect_daughter_board_profile(); |
db7dd810 TR |
436 | configure_module_pin_mux(rgmii1_pin_mux); |
437 | configure_module_pin_mux(mmc0_pin_mux); | |
036fd65a TR |
438 | /* In profile #2 i2c1 and spi0 conflict. */ |
439 | if (profile & ~PROFILE_2) | |
440 | configure_module_pin_mux(i2c1_pin_mux); | |
6bfca503 TR |
441 | else if (profile == PROFILE_2) { |
442 | configure_module_pin_mux(mmc1_pin_mux); | |
a4a99fff | 443 | configure_module_pin_mux(spi0_pin_mux); |
6bfca503 | 444 | } |
db7dd810 TR |
445 | } else if (!strncmp(header->name, "A335X_SK", HDR_NAME_LEN)) { |
446 | /* Starter Kit EVM */ | |
036fd65a | 447 | configure_module_pin_mux(i2c1_pin_mux); |
db7dd810 TR |
448 | configure_module_pin_mux(gpio0_7_pin_mux); |
449 | configure_module_pin_mux(rgmii1_pin_mux); | |
450 | configure_module_pin_mux(mmc0_pin_mux_sk_evm); | |
451 | } else { | |
452 | puts("Unknown board, cannot configure pinmux."); | |
453 | hang(); | |
454 | } | |
65d750be | 455 | } |