mx6qsabreauto.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. /*
  2. * Copyright (C) 2012 Freescale Semiconductor, Inc.
  3. *
  4. * Author: Fabio Estevam <fabio.estevam@freescale.com>
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <common.h>
  9. #include <asm/io.h>
  10. #include <asm/arch/clock.h>
  11. #include <asm/arch/imx-regs.h>
  12. #include <asm/arch/iomux.h>
  13. #include <asm/arch/mx6-pins.h>
  14. #include <linux/errno.h>
  15. #include <asm/gpio.h>
  16. #include <asm/imx-common/iomux-v3.h>
  17. #include <asm/imx-common/mxc_i2c.h>
  18. #include <asm/imx-common/boot_mode.h>
  19. #include <asm/imx-common/spi.h>
  20. #include <mmc.h>
  21. #include <fsl_esdhc.h>
  22. #include <miiphy.h>
  23. #include <netdev.h>
  24. #include <asm/arch/sys_proto.h>
  25. #include <i2c.h>
  26. #include <asm/arch/mxc_hdmi.h>
  27. #include <asm/imx-common/video.h>
  28. #include <asm/arch/crm_regs.h>
  29. #include <pca953x.h>
  30. #include <power/pmic.h>
  31. #include <power/pfuze100_pmic.h>
  32. #include "../common/pfuze.h"
  33. DECLARE_GLOBAL_DATA_PTR;
  34. #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
  35. PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
  36. PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  37. #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \
  38. PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
  39. PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  40. #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
  41. PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
  42. #define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
  43. PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
  44. PAD_CTL_ODE | PAD_CTL_SRE_FAST)
  45. #define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
  46. #define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
  47. PAD_CTL_SRE_FAST)
  48. #define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
  49. #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
  50. #define WEIM_NOR_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  51. PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
  52. PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
  53. #define I2C_PMIC 1
  54. int dram_init(void)
  55. {
  56. gd->ram_size = imx_ddr_size();
  57. return 0;
  58. }
  59. static iomux_v3_cfg_t const uart4_pads[] = {
  60. MX6_PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  61. MX6_PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  62. };
  63. static iomux_v3_cfg_t const enet_pads[] = {
  64. MX6_PAD_KEY_COL1__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
  65. MX6_PAD_KEY_COL2__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  66. MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  67. MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  68. MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  69. MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  70. MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  71. MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
  72. MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
  73. MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  74. MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  75. MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  76. MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  77. MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  78. MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
  79. };
  80. /* I2C2 PMIC, iPod, Tuner, Codec, Touch, HDMI EDID, MIPI CSI2 card */
  81. static struct i2c_pads_info i2c_pad_info1 = {
  82. .scl = {
  83. .i2c_mode = MX6_PAD_EIM_EB2__I2C2_SCL | PC,
  84. .gpio_mode = MX6_PAD_EIM_EB2__GPIO2_IO30 | PC,
  85. .gp = IMX_GPIO_NR(2, 30)
  86. },
  87. .sda = {
  88. .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC,
  89. .gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | PC,
  90. .gp = IMX_GPIO_NR(4, 13)
  91. }
  92. };
  93. #ifndef CONFIG_SYS_FLASH_CFI
  94. /*
  95. * I2C3 MLB, Port Expanders (A, B, C), Video ADC, Light Sensor,
  96. * Compass Sensor, Accelerometer, Res Touch
  97. */
  98. static struct i2c_pads_info i2c_pad_info2 = {
  99. .scl = {
  100. .i2c_mode = MX6_PAD_GPIO_3__I2C3_SCL | PC,
  101. .gpio_mode = MX6_PAD_GPIO_3__GPIO1_IO03 | PC,
  102. .gp = IMX_GPIO_NR(1, 3)
  103. },
  104. .sda = {
  105. .i2c_mode = MX6_PAD_EIM_D18__I2C3_SDA | PC,
  106. .gpio_mode = MX6_PAD_EIM_D18__GPIO3_IO18 | PC,
  107. .gp = IMX_GPIO_NR(3, 18)
  108. }
  109. };
  110. #endif
  111. static iomux_v3_cfg_t const i2c3_pads[] = {
  112. MX6_PAD_EIM_A24__GPIO5_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL),
  113. };
  114. static iomux_v3_cfg_t const port_exp[] = {
  115. MX6_PAD_SD2_DAT0__GPIO1_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
  116. };
  117. /*Define for building port exp gpio, pin starts from 0*/
  118. #define PORTEXP_IO_NR(chip, pin) \
  119. ((chip << 5) + pin)
  120. /*Get the chip addr from a ioexp gpio*/
  121. #define PORTEXP_IO_TO_CHIP(gpio_nr) \
  122. (gpio_nr >> 5)
  123. /*Get the pin number from a ioexp gpio*/
  124. #define PORTEXP_IO_TO_PIN(gpio_nr) \
  125. (gpio_nr & 0x1f)
  126. static int port_exp_direction_output(unsigned gpio, int value)
  127. {
  128. int ret;
  129. i2c_set_bus_num(2);
  130. ret = i2c_probe(PORTEXP_IO_TO_CHIP(gpio));
  131. if (ret)
  132. return ret;
  133. ret = pca953x_set_dir(PORTEXP_IO_TO_CHIP(gpio),
  134. (1 << PORTEXP_IO_TO_PIN(gpio)),
  135. (PCA953X_DIR_OUT << PORTEXP_IO_TO_PIN(gpio)));
  136. if (ret)
  137. return ret;
  138. ret = pca953x_set_val(PORTEXP_IO_TO_CHIP(gpio),
  139. (1 << PORTEXP_IO_TO_PIN(gpio)),
  140. (value << PORTEXP_IO_TO_PIN(gpio)));
  141. if (ret)
  142. return ret;
  143. return 0;
  144. }
  145. static iomux_v3_cfg_t const eimnor_pads[] = {
  146. MX6_PAD_EIM_D16__EIM_DATA16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  147. MX6_PAD_EIM_D17__EIM_DATA17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  148. MX6_PAD_EIM_D18__EIM_DATA18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  149. MX6_PAD_EIM_D19__EIM_DATA19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  150. MX6_PAD_EIM_D20__EIM_DATA20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  151. MX6_PAD_EIM_D21__EIM_DATA21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  152. MX6_PAD_EIM_D22__EIM_DATA22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  153. MX6_PAD_EIM_D23__EIM_DATA23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  154. MX6_PAD_EIM_D24__EIM_DATA24 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  155. MX6_PAD_EIM_D25__EIM_DATA25 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  156. MX6_PAD_EIM_D26__EIM_DATA26 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  157. MX6_PAD_EIM_D27__EIM_DATA27 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  158. MX6_PAD_EIM_D28__EIM_DATA28 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  159. MX6_PAD_EIM_D29__EIM_DATA29 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  160. MX6_PAD_EIM_D30__EIM_DATA30 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  161. MX6_PAD_EIM_D31__EIM_DATA31 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  162. MX6_PAD_EIM_DA0__EIM_AD00 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  163. MX6_PAD_EIM_DA1__EIM_AD01 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  164. MX6_PAD_EIM_DA2__EIM_AD02 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  165. MX6_PAD_EIM_DA3__EIM_AD03 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  166. MX6_PAD_EIM_DA4__EIM_AD04 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  167. MX6_PAD_EIM_DA5__EIM_AD05 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  168. MX6_PAD_EIM_DA6__EIM_AD06 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  169. MX6_PAD_EIM_DA7__EIM_AD07 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  170. MX6_PAD_EIM_DA8__EIM_AD08 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  171. MX6_PAD_EIM_DA9__EIM_AD09 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  172. MX6_PAD_EIM_DA10__EIM_AD10 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  173. MX6_PAD_EIM_DA11__EIM_AD11 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL) ,
  174. MX6_PAD_EIM_DA12__EIM_AD12 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  175. MX6_PAD_EIM_DA13__EIM_AD13 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  176. MX6_PAD_EIM_DA14__EIM_AD14 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  177. MX6_PAD_EIM_DA15__EIM_AD15 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  178. MX6_PAD_EIM_A16__EIM_ADDR16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  179. MX6_PAD_EIM_A17__EIM_ADDR17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  180. MX6_PAD_EIM_A18__EIM_ADDR18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  181. MX6_PAD_EIM_A19__EIM_ADDR19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  182. MX6_PAD_EIM_A20__EIM_ADDR20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  183. MX6_PAD_EIM_A21__EIM_ADDR21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  184. MX6_PAD_EIM_A22__EIM_ADDR22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  185. MX6_PAD_EIM_A23__EIM_ADDR23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
  186. MX6_PAD_EIM_OE__EIM_OE_B | MUX_PAD_CTRL(NO_PAD_CTRL),
  187. MX6_PAD_EIM_RW__EIM_RW | MUX_PAD_CTRL(NO_PAD_CTRL),
  188. MX6_PAD_EIM_CS0__EIM_CS0_B | MUX_PAD_CTRL(NO_PAD_CTRL),
  189. };
  190. static void eimnor_cs_setup(void)
  191. {
  192. struct weim *weim_regs = (struct weim *)WEIM_BASE_ADDR;
  193. writel(0x00020181, &weim_regs->cs0gcr1);
  194. writel(0x00000001, &weim_regs->cs0gcr2);
  195. writel(0x0a020000, &weim_regs->cs0rcr1);
  196. writel(0x0000c000, &weim_regs->cs0rcr2);
  197. writel(0x0804a240, &weim_regs->cs0wcr1);
  198. writel(0x00000120, &weim_regs->wcr);
  199. set_chipselect_size(CS0_128);
  200. }
  201. static void eim_clk_setup(void)
  202. {
  203. struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  204. int cscmr1, ccgr6;
  205. /* Turn off EIM clock */
  206. ccgr6 = readl(&imx_ccm->CCGR6);
  207. ccgr6 &= ~(0x3 << 10);
  208. writel(ccgr6, &imx_ccm->CCGR6);
  209. /*
  210. * Configure clk_eim_slow_sel = 00 --> derive clock from AXI clk root
  211. * and aclk_eim_slow_podf = 01 --> divide by 2
  212. * so that we can have EIM at the maximum clock of 132MHz
  213. */
  214. cscmr1 = readl(&imx_ccm->cscmr1);
  215. cscmr1 &= ~(MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK |
  216. MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK);
  217. cscmr1 |= (1 << MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET);
  218. writel(cscmr1, &imx_ccm->cscmr1);
  219. /* Turn on EIM clock */
  220. ccgr6 |= (0x3 << 10);
  221. writel(ccgr6, &imx_ccm->CCGR6);
  222. }
  223. static void setup_iomux_eimnor(void)
  224. {
  225. imx_iomux_v3_setup_multiple_pads(eimnor_pads, ARRAY_SIZE(eimnor_pads));
  226. gpio_direction_output(IMX_GPIO_NR(5, 4), 0);
  227. eimnor_cs_setup();
  228. }
  229. static void setup_iomux_enet(void)
  230. {
  231. imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
  232. }
  233. static iomux_v3_cfg_t const usdhc3_pads[] = {
  234. MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  235. MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  236. MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  237. MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  238. MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  239. MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  240. MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  241. MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  242. MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  243. MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  244. MX6_PAD_GPIO_18__SD3_VSELECT | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  245. MX6_PAD_NANDF_CS2__GPIO6_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
  246. };
  247. static void setup_iomux_uart(void)
  248. {
  249. imx_iomux_v3_setup_multiple_pads(uart4_pads, ARRAY_SIZE(uart4_pads));
  250. }
  251. #ifdef CONFIG_FSL_ESDHC
  252. static struct fsl_esdhc_cfg usdhc_cfg[1] = {
  253. {USDHC3_BASE_ADDR},
  254. };
  255. int board_mmc_getcd(struct mmc *mmc)
  256. {
  257. gpio_direction_input(IMX_GPIO_NR(6, 15));
  258. return !gpio_get_value(IMX_GPIO_NR(6, 15));
  259. }
  260. int board_mmc_init(bd_t *bis)
  261. {
  262. imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
  263. usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
  264. return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
  265. }
  266. #endif
  267. #ifdef CONFIG_NAND_MXS
  268. static iomux_v3_cfg_t gpmi_pads[] = {
  269. MX6_PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  270. MX6_PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  271. MX6_PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  272. MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(GPMI_PAD_CTRL0),
  273. MX6_PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  274. MX6_PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  275. MX6_PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  276. MX6_PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  277. MX6_PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  278. MX6_PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  279. MX6_PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  280. MX6_PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  281. MX6_PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  282. MX6_PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  283. MX6_PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  284. MX6_PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(GPMI_PAD_CTRL1),
  285. };
  286. static void setup_gpmi_nand(void)
  287. {
  288. struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  289. /* config gpmi nand iomux */
  290. imx_iomux_v3_setup_multiple_pads(gpmi_pads, ARRAY_SIZE(gpmi_pads));
  291. setup_gpmi_io_clk((MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
  292. MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
  293. MXC_CCM_CS2CDR_ENFC_CLK_SEL(3)));
  294. /* enable apbh clock gating */
  295. setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
  296. }
  297. #endif
  298. static void setup_fec(void)
  299. {
  300. if (is_mx6dqp()) {
  301. /*
  302. * select ENET MAC0 TX clock from PLL
  303. */
  304. imx_iomux_set_gpr_register(5, 9, 1, 1);
  305. enable_fec_anatop_clock(0, ENET_125MHZ);
  306. }
  307. setup_iomux_enet();
  308. }
  309. int board_eth_init(bd_t *bis)
  310. {
  311. setup_fec();
  312. return cpu_eth_init(bis);
  313. }
  314. #define BOARD_REV_B 0x200
  315. #define BOARD_REV_A 0x100
  316. static int mx6sabre_rev(void)
  317. {
  318. /*
  319. * Get Board ID information from OCOTP_GP1[15:8]
  320. * i.MX6Q ARD RevA: 0x01
  321. * i.MX6Q ARD RevB: 0x02
  322. */
  323. struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  324. struct fuse_bank *bank = &ocotp->bank[4];
  325. struct fuse_bank4_regs *fuse =
  326. (struct fuse_bank4_regs *)bank->fuse_regs;
  327. int reg = readl(&fuse->gp1);
  328. int ret;
  329. switch (reg >> 8 & 0x0F) {
  330. case 0x02:
  331. ret = BOARD_REV_B;
  332. break;
  333. case 0x01:
  334. default:
  335. ret = BOARD_REV_A;
  336. break;
  337. }
  338. return ret;
  339. }
  340. u32 get_board_rev(void)
  341. {
  342. int rev = mx6sabre_rev();
  343. return (get_cpu_rev() & ~(0xF << 8)) | rev;
  344. }
  345. #if defined(CONFIG_VIDEO_IPUV3)
  346. static void disable_lvds(struct display_info_t const *dev)
  347. {
  348. struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
  349. clrbits_le32(&iomux->gpr[2],
  350. IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
  351. IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
  352. }
  353. static void do_enable_hdmi(struct display_info_t const *dev)
  354. {
  355. disable_lvds(dev);
  356. imx_enable_hdmi_phy();
  357. }
  358. struct display_info_t const displays[] = {{
  359. .bus = -1,
  360. .addr = 0,
  361. .pixfmt = IPU_PIX_FMT_RGB666,
  362. .detect = NULL,
  363. .enable = NULL,
  364. .mode = {
  365. .name = "Hannstar-XGA",
  366. .refresh = 60,
  367. .xres = 1024,
  368. .yres = 768,
  369. .pixclock = 15385,
  370. .left_margin = 220,
  371. .right_margin = 40,
  372. .upper_margin = 21,
  373. .lower_margin = 7,
  374. .hsync_len = 60,
  375. .vsync_len = 10,
  376. .sync = FB_SYNC_EXT,
  377. .vmode = FB_VMODE_NONINTERLACED
  378. } }, {
  379. .bus = -1,
  380. .addr = 0,
  381. .pixfmt = IPU_PIX_FMT_RGB24,
  382. .detect = detect_hdmi,
  383. .enable = do_enable_hdmi,
  384. .mode = {
  385. .name = "HDMI",
  386. .refresh = 60,
  387. .xres = 1024,
  388. .yres = 768,
  389. .pixclock = 15385,
  390. .left_margin = 220,
  391. .right_margin = 40,
  392. .upper_margin = 21,
  393. .lower_margin = 7,
  394. .hsync_len = 60,
  395. .vsync_len = 10,
  396. .sync = FB_SYNC_EXT,
  397. .vmode = FB_VMODE_NONINTERLACED,
  398. } } };
  399. size_t display_count = ARRAY_SIZE(displays);
  400. iomux_v3_cfg_t const backlight_pads[] = {
  401. MX6_PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  402. };
  403. static void setup_iomux_backlight(void)
  404. {
  405. gpio_direction_output(IMX_GPIO_NR(2, 9), 1);
  406. imx_iomux_v3_setup_multiple_pads(backlight_pads,
  407. ARRAY_SIZE(backlight_pads));
  408. }
  409. static void setup_display(void)
  410. {
  411. struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  412. struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
  413. int reg;
  414. setup_iomux_backlight();
  415. enable_ipu_clock();
  416. imx_setup_hdmi();
  417. /* Turn on LDB_DI0 and LDB_DI1 clocks */
  418. reg = readl(&mxc_ccm->CCGR3);
  419. reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
  420. writel(reg, &mxc_ccm->CCGR3);
  421. /* Set LDB_DI0 and LDB_DI1 clk select to 3b'011 */
  422. reg = readl(&mxc_ccm->cs2cdr);
  423. reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
  424. MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
  425. reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
  426. (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
  427. writel(reg, &mxc_ccm->cs2cdr);
  428. reg = readl(&mxc_ccm->cscmr2);
  429. reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
  430. writel(reg, &mxc_ccm->cscmr2);
  431. reg = readl(&mxc_ccm->chsccdr);
  432. reg |= (CHSCCDR_CLK_SEL_LDB_DI0
  433. << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
  434. reg |= (CHSCCDR_CLK_SEL_LDB_DI0 <<
  435. MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
  436. writel(reg, &mxc_ccm->chsccdr);
  437. reg = IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW |
  438. IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW |
  439. IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG |
  440. IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT |
  441. IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG |
  442. IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT |
  443. IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0 |
  444. IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED;
  445. writel(reg, &iomux->gpr[2]);
  446. reg = readl(&iomux->gpr[3]);
  447. reg &= ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK |
  448. IOMUXC_GPR3_HDMI_MUX_CTL_MASK);
  449. reg |= (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
  450. IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET) |
  451. (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
  452. IOMUXC_GPR3_HDMI_MUX_CTL_OFFSET);
  453. writel(reg, &iomux->gpr[3]);
  454. }
  455. #endif /* CONFIG_VIDEO_IPUV3 */
  456. /*
  457. * Do not overwrite the console
  458. * Use always serial for U-Boot console
  459. */
  460. int overwrite_console(void)
  461. {
  462. return 1;
  463. }
  464. int board_early_init_f(void)
  465. {
  466. setup_iomux_uart();
  467. #ifdef CONFIG_NAND_MXS
  468. setup_gpmi_nand();
  469. #endif
  470. eim_clk_setup();
  471. return 0;
  472. }
  473. int board_init(void)
  474. {
  475. /* address of boot parameters */
  476. gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  477. /* I2C 2 and 3 setup - I2C 3 hw mux with EIM */
  478. setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
  479. /* I2C 3 Steer */
  480. gpio_direction_output(IMX_GPIO_NR(5, 4), 1);
  481. imx_iomux_v3_setup_multiple_pads(i2c3_pads, ARRAY_SIZE(i2c3_pads));
  482. #ifndef CONFIG_SYS_FLASH_CFI
  483. setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
  484. #endif
  485. gpio_direction_output(IMX_GPIO_NR(1, 15), 1);
  486. imx_iomux_v3_setup_multiple_pads(port_exp, ARRAY_SIZE(port_exp));
  487. #ifdef CONFIG_VIDEO_IPUV3
  488. setup_display();
  489. #endif
  490. setup_iomux_eimnor();
  491. return 0;
  492. }
  493. #ifdef CONFIG_MXC_SPI
  494. int board_spi_cs_gpio(unsigned bus, unsigned cs)
  495. {
  496. return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1;
  497. }
  498. #endif
  499. int power_init_board(void)
  500. {
  501. struct pmic *p;
  502. unsigned int value;
  503. p = pfuze_common_init(I2C_PMIC);
  504. if (!p)
  505. return -ENODEV;
  506. if (is_mx6dqp()) {
  507. /* set SW2 staby volatage 0.975V*/
  508. pmic_reg_read(p, PFUZE100_SW2STBY, &value);
  509. value &= ~0x3f;
  510. value |= 0x17;
  511. pmic_reg_write(p, PFUZE100_SW2STBY, value);
  512. }
  513. return pfuze_mode_init(p, APS_PFM);
  514. }
  515. #ifdef CONFIG_CMD_BMODE
  516. static const struct boot_mode board_boot_modes[] = {
  517. /* 4 bit bus width */
  518. {"mmc0", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
  519. {NULL, 0},
  520. };
  521. #endif
  522. int board_late_init(void)
  523. {
  524. #ifdef CONFIG_CMD_BMODE
  525. add_board_boot_modes(board_boot_modes);
  526. #endif
  527. #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
  528. setenv("board_name", "SABREAUTO");
  529. if (is_mx6dqp())
  530. setenv("board_rev", "MX6QP");
  531. else if (is_mx6dq())
  532. setenv("board_rev", "MX6Q");
  533. else if (is_mx6sdl())
  534. setenv("board_rev", "MX6DL");
  535. #endif
  536. return 0;
  537. }
  538. int checkboard(void)
  539. {
  540. int rev = mx6sabre_rev();
  541. char *revname;
  542. switch (rev) {
  543. case BOARD_REV_B:
  544. revname = "B";
  545. break;
  546. case BOARD_REV_A:
  547. default:
  548. revname = "A";
  549. break;
  550. }
  551. printf("Board: MX6Q-Sabreauto rev%s\n", revname);
  552. return 0;
  553. }
  554. #ifdef CONFIG_USB_EHCI_MX6
  555. #define USB_HOST1_PWR PORTEXP_IO_NR(0x32, 7)
  556. #define USB_OTG_PWR PORTEXP_IO_NR(0x34, 1)
  557. iomux_v3_cfg_t const usb_otg_pads[] = {
  558. MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
  559. };
  560. int board_ehci_hcd_init(int port)
  561. {
  562. switch (port) {
  563. case 0:
  564. imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
  565. ARRAY_SIZE(usb_otg_pads));
  566. /*
  567. * Set daisy chain for otg_pin_id on 6q.
  568. * For 6dl, this bit is reserved.
  569. */
  570. imx_iomux_set_gpr_register(1, 13, 1, 0);
  571. break;
  572. case 1:
  573. break;
  574. default:
  575. printf("MXC USB port %d not yet supported\n", port);
  576. return -EINVAL;
  577. }
  578. return 0;
  579. }
  580. int board_ehci_power(int port, int on)
  581. {
  582. switch (port) {
  583. case 0:
  584. if (on)
  585. port_exp_direction_output(USB_OTG_PWR, 1);
  586. else
  587. port_exp_direction_output(USB_OTG_PWR, 0);
  588. break;
  589. case 1:
  590. if (on)
  591. port_exp_direction_output(USB_HOST1_PWR, 1);
  592. else
  593. port_exp_direction_output(USB_HOST1_PWR, 0);
  594. break;
  595. default:
  596. printf("MXC USB port %d not yet supported\n", port);
  597. return -EINVAL;
  598. }
  599. return 0;
  600. }
  601. #endif