mux.c 11 KB

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