cgtqmx6eval.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. /*
  2. * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
  3. * Based on mx6qsabrelite.c file
  4. * Copyright (C) 2013, Adeneo Embedded <www.adeneo-embedded.com>
  5. * Leo Sartre, <lsartre@adeneo-embedded.com>
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. #include <common.h>
  10. #include <asm/io.h>
  11. #include <asm/arch/clock.h>
  12. #include <asm/arch/imx-regs.h>
  13. #include <asm/arch/iomux.h>
  14. #include <asm/arch/mx6-pins.h>
  15. #include <asm/gpio.h>
  16. #include <asm/imx-common/iomux-v3.h>
  17. #include <asm/imx-common/sata.h>
  18. #include <asm/imx-common/boot_mode.h>
  19. #include <asm/imx-common/mxc_i2c.h>
  20. #include <asm/arch/mxc_hdmi.h>
  21. #include <asm/arch/crm_regs.h>
  22. #include <mmc.h>
  23. #include <fsl_esdhc.h>
  24. #include <i2c.h>
  25. #include <power/pmic.h>
  26. #include <power/pfuze100_pmic.h>
  27. #include <linux/fb.h>
  28. #include <ipu_pixfmt.h>
  29. #include <malloc.h>
  30. #include <miiphy.h>
  31. #include <netdev.h>
  32. #include <micrel.h>
  33. DECLARE_GLOBAL_DATA_PTR;
  34. #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |\
  35. PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  36. #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW |\
  37. PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  38. #define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  39. PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
  40. PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
  41. PAD_CTL_ODE | PAD_CTL_SRE_FAST)
  42. #define MX6Q_QMX6_PFUZE_MUX IMX_GPIO_NR(6, 9)
  43. #define ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  44. PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
  45. PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
  46. int dram_init(void)
  47. {
  48. gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
  49. return 0;
  50. }
  51. static iomux_v3_cfg_t const uart2_pads[] = {
  52. MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  53. MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  54. };
  55. static iomux_v3_cfg_t const usdhc2_pads[] = {
  56. MX6_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  57. MX6_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  58. MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  59. MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  60. MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  61. MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  62. MX6_PAD_GPIO_4__GPIO1_IO04 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  63. };
  64. static iomux_v3_cfg_t const usdhc3_pads[] = {
  65. MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  66. MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  67. MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  68. MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  69. MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  70. MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  71. MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  72. MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  73. MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  74. MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  75. MX6_PAD_SD3_RST__SD3_RESET | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  76. };
  77. static iomux_v3_cfg_t const usdhc4_pads[] = {
  78. MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  79. MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  80. MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  81. MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  82. MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  83. MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  84. MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  85. MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  86. MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  87. MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  88. MX6_PAD_NANDF_D6__GPIO2_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
  89. };
  90. static iomux_v3_cfg_t const usb_otg_pads[] = {
  91. MX6_PAD_EIM_D22__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
  92. MX6_PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
  93. };
  94. static iomux_v3_cfg_t enet_pads_ksz9031[] = {
  95. MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
  96. MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  97. MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  98. MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  99. MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  100. MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  101. MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  102. MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
  103. MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
  104. MX6_PAD_RGMII_RXC__GPIO6_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL),
  105. MX6_PAD_RGMII_RD0__GPIO6_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL),
  106. MX6_PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
  107. MX6_PAD_RGMII_RD2__GPIO6_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL),
  108. MX6_PAD_RGMII_RD3__GPIO6_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
  109. MX6_PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL),
  110. };
  111. static iomux_v3_cfg_t enet_pads_final_ksz9031[] = {
  112. MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  113. MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  114. MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  115. MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  116. MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  117. MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
  118. };
  119. static iomux_v3_cfg_t enet_pads_ar8035[] = {
  120. MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
  121. MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  122. MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  123. MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  124. MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  125. MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  126. MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  127. MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
  128. MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
  129. MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  130. MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  131. MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  132. MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  133. MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  134. MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
  135. };
  136. #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
  137. struct i2c_pads_info i2c_pad_info1 = {
  138. .scl = {
  139. .i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | PC,
  140. .gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12 | PC,
  141. .gp = IMX_GPIO_NR(4, 12)
  142. },
  143. .sda = {
  144. .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC,
  145. .gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | PC,
  146. .gp = IMX_GPIO_NR(4, 13)
  147. }
  148. };
  149. #define I2C_PMIC 1 /* I2C2 port is used to connect to the PMIC */
  150. struct interface_level {
  151. char *name;
  152. uchar value;
  153. };
  154. static struct interface_level mipi_levels[] = {
  155. {"0V0", 0x00},
  156. {"2V5", 0x17},
  157. };
  158. /* setup board specific PMIC */
  159. int power_init_board(void)
  160. {
  161. struct pmic *p;
  162. u32 id1, id2, i;
  163. int ret;
  164. char const *lv_mipi;
  165. /* configure I2C multiplexer */
  166. gpio_direction_output(MX6Q_QMX6_PFUZE_MUX, 1);
  167. power_pfuze100_init(I2C_PMIC);
  168. p = pmic_get("PFUZE100");
  169. if (!p)
  170. return -EINVAL;
  171. ret = pmic_probe(p);
  172. if (ret)
  173. return ret;
  174. pmic_reg_read(p, PFUZE100_DEVICEID, &id1);
  175. pmic_reg_read(p, PFUZE100_REVID, &id2);
  176. printf("PFUZE100 Rev. [%02x/%02x] detected\n", id1, id2);
  177. if (id2 >= 0x20)
  178. return 0;
  179. /* set level of MIPI if specified */
  180. lv_mipi = getenv("lv_mipi");
  181. if (lv_mipi)
  182. return 0;
  183. for (i = 0; i < ARRAY_SIZE(mipi_levels); i++) {
  184. if (!strcmp(mipi_levels[i].name, lv_mipi)) {
  185. printf("set MIPI level %s\n", mipi_levels[i].name);
  186. ret = pmic_reg_write(p, PFUZE100_VGEN4VOL,
  187. mipi_levels[i].value);
  188. if (ret)
  189. return ret;
  190. }
  191. }
  192. return 0;
  193. }
  194. int board_eth_init(bd_t *bis)
  195. {
  196. struct phy_device *phydev;
  197. struct mii_dev *bus;
  198. unsigned short id1, id2;
  199. int ret;
  200. iomux_v3_cfg_t enet_reset = MX6_PAD_EIM_D23__GPIO3_IO23 |
  201. MUX_PAD_CTRL(NO_PAD_CTRL);
  202. /* check whether KSZ9031 or AR8035 has to be configured */
  203. imx_iomux_v3_setup_multiple_pads(enet_pads_ar8035,
  204. ARRAY_SIZE(enet_pads_ar8035));
  205. imx_iomux_v3_setup_pad(enet_reset);
  206. /* phy reset */
  207. gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
  208. udelay(2000);
  209. gpio_set_value(IMX_GPIO_NR(3, 23), 1);
  210. udelay(500);
  211. bus = fec_get_miibus(IMX_FEC_BASE, -1);
  212. if (!bus)
  213. return -EINVAL;
  214. phydev = phy_find_by_mask(bus, (0xf << 4), PHY_INTERFACE_MODE_RGMII);
  215. if (!phydev) {
  216. printf("Error: phy device not found.\n");
  217. ret = -ENODEV;
  218. goto free_bus;
  219. }
  220. /* get the PHY id */
  221. id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
  222. id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
  223. if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
  224. /* re-configure for Micrel KSZ9031 */
  225. printf("configure Micrel KSZ9031 Ethernet Phy at address %d\n",
  226. phydev->addr);
  227. /* phy reset: gpio3-23 */
  228. gpio_set_value(IMX_GPIO_NR(3, 23), 0);
  229. gpio_set_value(IMX_GPIO_NR(6, 30), (phydev->addr >> 2));
  230. gpio_set_value(IMX_GPIO_NR(6, 25), 1);
  231. gpio_set_value(IMX_GPIO_NR(6, 27), 1);
  232. gpio_set_value(IMX_GPIO_NR(6, 28), 1);
  233. gpio_set_value(IMX_GPIO_NR(6, 29), 1);
  234. imx_iomux_v3_setup_multiple_pads(enet_pads_ksz9031,
  235. ARRAY_SIZE(enet_pads_ksz9031));
  236. gpio_set_value(IMX_GPIO_NR(6, 24), 1);
  237. udelay(500);
  238. gpio_set_value(IMX_GPIO_NR(3, 23), 1);
  239. imx_iomux_v3_setup_multiple_pads(enet_pads_final_ksz9031,
  240. ARRAY_SIZE(enet_pads_final_ksz9031));
  241. } else if ((id1 == 0x004d) && (id2 == 0xd072)) {
  242. /* configure Atheros AR8035 - actually nothing to do */
  243. printf("configure Atheros AR8035 Ethernet Phy at address %d\n",
  244. phydev->addr);
  245. } else {
  246. printf("Unknown Ethernet-Phy: 0x%04x 0x%04x\n", id1, id2);
  247. ret = -EINVAL;
  248. goto free_phydev;
  249. }
  250. ret = fec_probe(bis, -1, IMX_FEC_BASE, bus, phydev);
  251. if (ret)
  252. goto free_phydev;
  253. return 0;
  254. free_phydev:
  255. free(phydev);
  256. free_bus:
  257. free(bus);
  258. return ret;
  259. }
  260. int mx6_rgmii_rework(struct phy_device *phydev)
  261. {
  262. unsigned short id1, id2;
  263. unsigned short val;
  264. /* check whether KSZ9031 or AR8035 has to be configured */
  265. id1 = phy_read(phydev, MDIO_DEVAD_NONE, 2);
  266. id2 = phy_read(phydev, MDIO_DEVAD_NONE, 3);
  267. if ((id1 == 0x22) && ((id2 & 0xFFF0) == 0x1620)) {
  268. /* finalize phy configuration for Micrel KSZ9031 */
  269. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
  270. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 4);
  271. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
  272. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x0000);
  273. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
  274. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 5);
  275. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
  276. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, MII_KSZ9031_MOD_REG);
  277. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
  278. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 6);
  279. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
  280. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0xFFFF);
  281. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 2);
  282. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 8);
  283. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_POST_INC_W | 0x2);
  284. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x3FFF);
  285. /* fix KSZ9031 link up issue */
  286. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 0x0);
  287. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x4);
  288. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC);
  289. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x6);
  290. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_REG);
  291. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x3);
  292. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC);
  293. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, 0x1A80);
  294. }
  295. if ((id1 == 0x004d) && (id2 == 0xd072)) {
  296. /* enable AR8035 ouput a 125MHz clk from CLK_25M */
  297. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, 0x7);
  298. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, MII_KSZ9031_MOD_DATA_POST_INC_RW | 0x16);
  299. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_CONTROL, MII_KSZ9031_MOD_DATA_NO_POST_INC | 0x7);
  300. val = phy_read(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA);
  301. val &= 0xfe63;
  302. val |= 0x18;
  303. phy_write(phydev, MDIO_DEVAD_NONE, MMD_ACCESS_REG_DATA, val);
  304. /* introduce tx clock delay */
  305. phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
  306. val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
  307. val |= 0x0100;
  308. phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
  309. /* disable hibernation */
  310. phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0xb);
  311. val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
  312. phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3c40);
  313. }
  314. return 0;
  315. }
  316. int board_phy_config(struct phy_device *phydev)
  317. {
  318. mx6_rgmii_rework(phydev);
  319. if (phydev->drv->config)
  320. phydev->drv->config(phydev);
  321. return 0;
  322. }
  323. static void setup_iomux_uart(void)
  324. {
  325. imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
  326. }
  327. #ifdef CONFIG_FSL_ESDHC
  328. static struct fsl_esdhc_cfg usdhc_cfg[] = {
  329. {USDHC2_BASE_ADDR},
  330. {USDHC3_BASE_ADDR},
  331. {USDHC4_BASE_ADDR},
  332. };
  333. int board_mmc_getcd(struct mmc *mmc)
  334. {
  335. struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
  336. int ret = 0;
  337. switch (cfg->esdhc_base) {
  338. case USDHC2_BASE_ADDR:
  339. gpio_direction_input(IMX_GPIO_NR(1, 4));
  340. ret = !gpio_get_value(IMX_GPIO_NR(1, 4));
  341. break;
  342. case USDHC3_BASE_ADDR:
  343. ret = 1; /* eMMC is always present */
  344. break;
  345. case USDHC4_BASE_ADDR:
  346. gpio_direction_input(IMX_GPIO_NR(2, 6));
  347. ret = !gpio_get_value(IMX_GPIO_NR(2, 6));
  348. break;
  349. default:
  350. printf("Bad USDHC interface\n");
  351. }
  352. return ret;
  353. }
  354. int board_mmc_init(bd_t *bis)
  355. {
  356. s32 status = 0;
  357. int i;
  358. usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
  359. usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
  360. usdhc_cfg[2].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
  361. imx_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
  362. imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
  363. imx_iomux_v3_setup_multiple_pads(usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
  364. for (i = 0; i < ARRAY_SIZE(usdhc_cfg); i++) {
  365. status = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
  366. if (status)
  367. return status;
  368. }
  369. return 0;
  370. }
  371. #endif
  372. int board_ehci_hcd_init(int port)
  373. {
  374. switch (port) {
  375. case 0:
  376. imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
  377. ARRAY_SIZE(usb_otg_pads));
  378. /*
  379. * set daisy chain for otg_pin_id on 6q.
  380. * for 6dl, this bit is reserved
  381. */
  382. imx_iomux_set_gpr_register(1, 13, 1, 1);
  383. break;
  384. case 1:
  385. /* nothing to do */
  386. break;
  387. default:
  388. printf("Invalid USB port: %d\n", port);
  389. return -EINVAL;
  390. }
  391. return 0;
  392. }
  393. int board_ehci_power(int port, int on)
  394. {
  395. switch (port) {
  396. case 0:
  397. break;
  398. case 1:
  399. gpio_direction_output(IMX_GPIO_NR(5, 5), on);
  400. break;
  401. default:
  402. printf("Invalid USB port: %d\n", port);
  403. return -EINVAL;
  404. }
  405. return 0;
  406. }
  407. struct display_info_t {
  408. int bus;
  409. int addr;
  410. int pixfmt;
  411. int (*detect)(struct display_info_t const *dev);
  412. void (*enable)(struct display_info_t const *dev);
  413. struct fb_videomode mode;
  414. };
  415. static void disable_lvds(struct display_info_t const *dev)
  416. {
  417. struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
  418. clrbits_le32(&iomux->gpr[2], IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
  419. IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
  420. }
  421. static void do_enable_hdmi(struct display_info_t const *dev)
  422. {
  423. disable_lvds(dev);
  424. imx_enable_hdmi_phy();
  425. }
  426. static struct display_info_t const displays[] = {
  427. {
  428. .bus = -1,
  429. .addr = 0,
  430. .pixfmt = IPU_PIX_FMT_RGB666,
  431. .detect = NULL,
  432. .enable = NULL,
  433. .mode = {
  434. .name =
  435. "Hannstar-XGA",
  436. .refresh = 60,
  437. .xres = 1024,
  438. .yres = 768,
  439. .pixclock = 15385,
  440. .left_margin = 220,
  441. .right_margin = 40,
  442. .upper_margin = 21,
  443. .lower_margin = 7,
  444. .hsync_len = 60,
  445. .vsync_len = 10,
  446. .sync = FB_SYNC_EXT,
  447. .vmode = FB_VMODE_NONINTERLACED } },
  448. {
  449. .bus = -1,
  450. .addr = 0,
  451. .pixfmt = IPU_PIX_FMT_RGB24,
  452. .detect = NULL,
  453. .enable = do_enable_hdmi,
  454. .mode = {
  455. .name = "HDMI",
  456. .refresh = 60,
  457. .xres = 1024,
  458. .yres = 768,
  459. .pixclock = 15385,
  460. .left_margin = 220,
  461. .right_margin = 40,
  462. .upper_margin = 21,
  463. .lower_margin = 7,
  464. .hsync_len = 60,
  465. .vsync_len = 10,
  466. .sync = FB_SYNC_EXT,
  467. .vmode = FB_VMODE_NONINTERLACED } }
  468. };
  469. int board_video_skip(void)
  470. {
  471. int i;
  472. int ret;
  473. char const *panel = getenv("panel");
  474. if (!panel) {
  475. for (i = 0; i < ARRAY_SIZE(displays); i++) {
  476. struct display_info_t const *dev = displays + i;
  477. if (dev->detect && dev->detect(dev)) {
  478. panel = dev->mode.name;
  479. printf("auto-detected panel %s\n", panel);
  480. break;
  481. }
  482. }
  483. if (!panel) {
  484. panel = displays[0].mode.name;
  485. printf("No panel detected: default to %s\n", panel);
  486. i = 0;
  487. }
  488. } else {
  489. for (i = 0; i < ARRAY_SIZE(displays); i++) {
  490. if (!strcmp(panel, displays[i].mode.name))
  491. break;
  492. }
  493. }
  494. if (i < ARRAY_SIZE(displays)) {
  495. ret = ipuv3_fb_init(&displays[i].mode, 0, displays[i].pixfmt);
  496. if (!ret) {
  497. if (displays[i].enable)
  498. displays[i].enable(displays + i);
  499. printf("Display: %s (%ux%u)\n",
  500. displays[i].mode.name, displays[i].mode.xres,
  501. displays[i].mode.yres);
  502. } else
  503. printf("LCD %s cannot be configured: %d\n",
  504. displays[i].mode.name, ret);
  505. } else {
  506. printf("unsupported panel %s\n", panel);
  507. return -EINVAL;
  508. }
  509. return 0;
  510. }
  511. static void setup_display(void)
  512. {
  513. struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  514. struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
  515. int reg;
  516. enable_ipu_clock();
  517. imx_setup_hdmi();
  518. /* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
  519. setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK |
  520. MXC_CCM_CCGR3_LDB_DI1_MASK);
  521. /* set LDB0, LDB1 clk select to 011/011 */
  522. reg = readl(&mxc_ccm->cs2cdr);
  523. reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
  524. MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
  525. reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
  526. (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
  527. writel(reg, &mxc_ccm->cs2cdr);
  528. setbits_le32(&mxc_ccm->cscmr2, MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV |
  529. MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV);
  530. setbits_le32(&mxc_ccm->chsccdr, CHSCCDR_CLK_SEL_LDB_DI0 <<
  531. MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET |
  532. CHSCCDR_CLK_SEL_LDB_DI0 <<
  533. MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
  534. reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
  535. | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
  536. | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
  537. | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
  538. | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
  539. | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
  540. | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
  541. | IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED
  542. | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
  543. writel(reg, &iomux->gpr[2]);
  544. reg = readl(&iomux->gpr[3]);
  545. reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK |
  546. IOMUXC_GPR3_HDMI_MUX_CTL_MASK)) |
  547. (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
  548. IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
  549. writel(reg, &iomux->gpr[3]);
  550. }
  551. /*
  552. * Do not overwrite the console
  553. * Use always serial for U-Boot console
  554. */
  555. int overwrite_console(void)
  556. {
  557. return 1;
  558. }
  559. int board_early_init_f(void)
  560. {
  561. setup_iomux_uart();
  562. setup_display();
  563. return 0;
  564. }
  565. int board_init(void)
  566. {
  567. /* address of boot parameters */
  568. gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  569. setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
  570. #ifdef CONFIG_CMD_SATA
  571. setup_sata();
  572. #endif
  573. return 0;
  574. }
  575. int checkboard(void)
  576. {
  577. puts("Board: Conga-QEVAL QMX6 Quad\n");
  578. return 0;
  579. }
  580. #ifdef CONFIG_CMD_BMODE
  581. static const struct boot_mode board_boot_modes[] = {
  582. /* 4 bit bus width */
  583. {"mmc0", MAKE_CFGVAL(0x50, 0x20, 0x00, 0x00)},
  584. {"mmc1", MAKE_CFGVAL(0x50, 0x38, 0x00, 0x00)},
  585. {NULL, 0},
  586. };
  587. #endif
  588. int misc_init_r(void)
  589. {
  590. #ifdef CONFIG_CMD_BMODE
  591. add_board_boot_modes(board_boot_modes);
  592. #endif
  593. return 0;
  594. }