mx6sxsabreauto.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. /*
  2. * Copyright (C) 2014 Freescale Semiconductor, Inc.
  3. *
  4. * Author: Ye Li <ye.li@nxp.com>
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <asm/arch/clock.h>
  9. #include <asm/arch/crm_regs.h>
  10. #include <asm/arch/iomux.h>
  11. #include <asm/arch/imx-regs.h>
  12. #include <asm/arch/mx6-pins.h>
  13. #include <asm/arch/sys_proto.h>
  14. #include <asm/gpio.h>
  15. #include <asm/imx-common/iomux-v3.h>
  16. #include <asm/imx-common/boot_mode.h>
  17. #include <asm/io.h>
  18. #include <asm/imx-common/mxc_i2c.h>
  19. #include <linux/sizes.h>
  20. #include <common.h>
  21. #include <fsl_esdhc.h>
  22. #include <mmc.h>
  23. #include <i2c.h>
  24. #include <miiphy.h>
  25. #include <netdev.h>
  26. #include <power/pmic.h>
  27. #include <power/pfuze100_pmic.h>
  28. #include "../common/pfuze.h"
  29. #include <usb.h>
  30. #include <usb/ehci-ci.h>
  31. #include <pca953x.h>
  32. DECLARE_GLOBAL_DATA_PTR;
  33. #define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  34. 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_PKE | PAD_CTL_PUE | \
  37. PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \
  38. PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  39. #define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  40. PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
  41. PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
  42. PAD_CTL_ODE)
  43. #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \
  44. PAD_CTL_SPEED_HIGH | \
  45. PAD_CTL_DSE_48ohm | PAD_CTL_SRE_FAST)
  46. #define ENET_CLK_PAD_CTRL (PAD_CTL_SPEED_MED | \
  47. PAD_CTL_DSE_120ohm | PAD_CTL_SRE_FAST)
  48. #define ENET_RX_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  49. PAD_CTL_SPEED_HIGH | PAD_CTL_SRE_FAST)
  50. #define I2C_PMIC 1
  51. #define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
  52. #define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
  53. PAD_CTL_SRE_FAST)
  54. #define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
  55. /*Define for building port exp gpio, pin starts from 0*/
  56. #define PORTEXP_IO_NR(chip, pin) \
  57. ((chip << 5) + pin)
  58. /*Get the chip addr from a ioexp gpio*/
  59. #define PORTEXP_IO_TO_CHIP(gpio_nr) \
  60. (gpio_nr >> 5)
  61. /*Get the pin number from a ioexp gpio*/
  62. #define PORTEXP_IO_TO_PIN(gpio_nr) \
  63. (gpio_nr & 0x1f)
  64. #define CPU_PER_RST_B PORTEXP_IO_NR(0x30, 4)
  65. #define STEER_ENET PORTEXP_IO_NR(0x32, 2)
  66. static int port_exp_direction_output(unsigned gpio, int value)
  67. {
  68. int ret;
  69. i2c_set_bus_num(2);
  70. ret = i2c_probe(PORTEXP_IO_TO_CHIP(gpio));
  71. if (ret)
  72. return ret;
  73. ret = pca953x_set_dir(PORTEXP_IO_TO_CHIP(gpio),
  74. (1 << PORTEXP_IO_TO_PIN(gpio)),
  75. (PCA953X_DIR_OUT << PORTEXP_IO_TO_PIN(gpio)));
  76. if (ret)
  77. return ret;
  78. ret = pca953x_set_val(PORTEXP_IO_TO_CHIP(gpio),
  79. (1 << PORTEXP_IO_TO_PIN(gpio)),
  80. (value << PORTEXP_IO_TO_PIN(gpio)));
  81. if (ret)
  82. return ret;
  83. return 0;
  84. }
  85. int dram_init(void)
  86. {
  87. gd->ram_size = imx_ddr_size();
  88. return 0;
  89. }
  90. static iomux_v3_cfg_t const uart1_pads[] = {
  91. MX6_PAD_GPIO1_IO04__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
  92. MX6_PAD_GPIO1_IO05__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
  93. };
  94. static iomux_v3_cfg_t const usdhc3_pads[] = {
  95. MX6_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  96. MX6_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  97. MX6_PAD_SD3_DATA0__USDHC3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  98. MX6_PAD_SD3_DATA1__USDHC3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  99. MX6_PAD_SD3_DATA2__USDHC3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  100. MX6_PAD_SD3_DATA3__USDHC3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  101. MX6_PAD_SD3_DATA4__USDHC3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  102. MX6_PAD_SD3_DATA5__USDHC3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  103. MX6_PAD_SD3_DATA6__USDHC3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  104. MX6_PAD_SD3_DATA7__USDHC3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  105. /* CD pin */
  106. MX6_PAD_USB_H_DATA__GPIO7_IO_10 | MUX_PAD_CTRL(NO_PAD_CTRL),
  107. /* RST_B, used for power reset cycle */
  108. MX6_PAD_KEY_COL1__GPIO2_IO_11 | MUX_PAD_CTRL(NO_PAD_CTRL),
  109. };
  110. static iomux_v3_cfg_t const usdhc4_pads[] = {
  111. MX6_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  112. MX6_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  113. MX6_PAD_SD4_DATA0__USDHC4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  114. MX6_PAD_SD4_DATA1__USDHC4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  115. MX6_PAD_SD4_DATA2__USDHC4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  116. MX6_PAD_SD4_DATA3__USDHC4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  117. MX6_PAD_SD4_DATA4__USDHC4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  118. MX6_PAD_SD4_DATA5__USDHC4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  119. MX6_PAD_SD4_DATA6__USDHC4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  120. MX6_PAD_SD4_DATA7__USDHC4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  121. /* CD pin */
  122. MX6_PAD_USB_H_STROBE__GPIO7_IO_11 | MUX_PAD_CTRL(NO_PAD_CTRL),
  123. };
  124. static iomux_v3_cfg_t const fec2_pads[] = {
  125. MX6_PAD_ENET1_MDC__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  126. MX6_PAD_ENET1_MDIO__ENET2_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
  127. MX6_PAD_RGMII2_RX_CTL__ENET2_RX_EN | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  128. MX6_PAD_RGMII2_RD0__ENET2_RX_DATA_0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  129. MX6_PAD_RGMII2_RD1__ENET2_RX_DATA_1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  130. MX6_PAD_RGMII2_RD2__ENET2_RX_DATA_2 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  131. MX6_PAD_RGMII2_RD3__ENET2_RX_DATA_3 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  132. MX6_PAD_RGMII2_RXC__ENET2_RX_CLK | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  133. MX6_PAD_RGMII2_TX_CTL__ENET2_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
  134. MX6_PAD_RGMII2_TD0__ENET2_TX_DATA_0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  135. MX6_PAD_RGMII2_TD1__ENET2_TX_DATA_1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  136. MX6_PAD_RGMII2_TD2__ENET2_TX_DATA_2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  137. MX6_PAD_RGMII2_TD3__ENET2_TX_DATA_3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  138. MX6_PAD_RGMII2_TXC__ENET2_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  139. };
  140. static void setup_iomux_uart(void)
  141. {
  142. imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
  143. }
  144. static int setup_fec(void)
  145. {
  146. struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
  147. /* Use 125MHz anatop loopback REF_CLK1 for ENET2 */
  148. clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC2_MASK, 0);
  149. return enable_fec_anatop_clock(1, ENET_125MHZ);
  150. }
  151. int board_eth_init(bd_t *bis)
  152. {
  153. int ret;
  154. imx_iomux_v3_setup_multiple_pads(fec2_pads, ARRAY_SIZE(fec2_pads));
  155. setup_fec();
  156. ret = fecmxc_initialize_multi(bis, 1,
  157. CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
  158. if (ret)
  159. printf("FEC%d MXC: %s:failed\n", 1, __func__);
  160. return ret;
  161. }
  162. int board_phy_config(struct phy_device *phydev)
  163. {
  164. /*
  165. * Enable 1.8V(SEL_1P5_1P8_POS_REG) on
  166. * Phy control debug reg 0
  167. */
  168. phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
  169. phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
  170. /* rgmii tx clock delay enable */
  171. phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
  172. phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
  173. if (phydev->drv->config)
  174. phydev->drv->config(phydev);
  175. return 0;
  176. }
  177. #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
  178. /* I2C2 for PMIC */
  179. struct i2c_pads_info i2c_pad_info2 = {
  180. .scl = {
  181. .i2c_mode = MX6_PAD_GPIO1_IO02__I2C2_SCL | PC,
  182. .gpio_mode = MX6_PAD_GPIO1_IO02__GPIO1_IO_2 | PC,
  183. .gp = IMX_GPIO_NR(1, 2),
  184. },
  185. .sda = {
  186. .i2c_mode = MX6_PAD_GPIO1_IO03__I2C2_SDA | PC,
  187. .gpio_mode = MX6_PAD_GPIO1_IO03__GPIO1_IO_3 | PC,
  188. .gp = IMX_GPIO_NR(1, 3),
  189. },
  190. };
  191. /* I2C3 for IO Expander */
  192. struct i2c_pads_info i2c_pad_info3 = {
  193. .scl = {
  194. .i2c_mode = MX6_PAD_KEY_COL4__I2C3_SCL | PC,
  195. .gpio_mode = MX6_PAD_KEY_COL4__GPIO2_IO_14 | PC,
  196. .gp = IMX_GPIO_NR(2, 14),
  197. },
  198. .sda = {
  199. .i2c_mode = MX6_PAD_KEY_ROW4__I2C3_SDA | PC,
  200. .gpio_mode = MX6_PAD_KEY_ROW4__GPIO2_IO_19 | PC,
  201. .gp = IMX_GPIO_NR(2, 19),
  202. },
  203. };
  204. int power_init_board(void)
  205. {
  206. struct pmic *p;
  207. p = pfuze_common_init(I2C_PMIC);
  208. if (!p)
  209. return -ENODEV;
  210. return 0;
  211. }
  212. #ifdef CONFIG_USB_EHCI_MX6
  213. #define USB_OTHERREGS_OFFSET 0x800
  214. #define UCTRL_PWR_POL (1 << 9)
  215. static iomux_v3_cfg_t const usb_otg_pads[] = {
  216. /* OGT1 */
  217. MX6_PAD_GPIO1_IO09__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
  218. MX6_PAD_GPIO1_IO10__ANATOP_OTG1_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
  219. /* OTG2 */
  220. MX6_PAD_GPIO1_IO12__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL)
  221. };
  222. static void setup_usb(void)
  223. {
  224. imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
  225. ARRAY_SIZE(usb_otg_pads));
  226. }
  227. int board_usb_phy_mode(int port)
  228. {
  229. if (port == 1)
  230. return USB_INIT_HOST;
  231. else
  232. return usb_phy_mode(port);
  233. }
  234. int board_ehci_hcd_init(int port)
  235. {
  236. u32 *usbnc_usb_ctrl;
  237. if (port > 1)
  238. return -EINVAL;
  239. usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET +
  240. port * 4);
  241. /* Set Power polarity */
  242. setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL);
  243. return 0;
  244. }
  245. #endif
  246. int board_early_init_f(void)
  247. {
  248. setup_iomux_uart();
  249. return 0;
  250. }
  251. static struct fsl_esdhc_cfg usdhc_cfg[3] = {
  252. {USDHC3_BASE_ADDR},
  253. {USDHC4_BASE_ADDR},
  254. };
  255. #define USDHC3_CD_GPIO IMX_GPIO_NR(7, 10)
  256. #define USDHC3_RST_GPIO IMX_GPIO_NR(2, 11)
  257. #define USDHC4_CD_GPIO IMX_GPIO_NR(7, 11)
  258. int board_mmc_getcd(struct mmc *mmc)
  259. {
  260. struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
  261. int ret = 0;
  262. switch (cfg->esdhc_base) {
  263. case USDHC3_BASE_ADDR:
  264. ret = !gpio_get_value(USDHC3_CD_GPIO);
  265. break;
  266. case USDHC4_BASE_ADDR:
  267. ret = !gpio_get_value(USDHC4_CD_GPIO);
  268. break;
  269. }
  270. return ret;
  271. }
  272. int board_mmc_init(bd_t *bis)
  273. {
  274. int i, ret;
  275. /*
  276. * According to the board_mmc_init() the following map is done:
  277. * (U-Boot device node) (Physical Port)
  278. * mmc0 USDHC3
  279. * mmc1 USDHC4
  280. */
  281. for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
  282. switch (i) {
  283. case 0:
  284. imx_iomux_v3_setup_multiple_pads(
  285. usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
  286. gpio_direction_input(USDHC3_CD_GPIO);
  287. /* This starts a power cycle for UHS-I. Need to set steer to B0 to A*/
  288. gpio_direction_output(USDHC3_RST_GPIO, 0);
  289. udelay(1000); /* need 1ms at least */
  290. gpio_direction_output(USDHC3_RST_GPIO, 1);
  291. usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
  292. break;
  293. case 1:
  294. imx_iomux_v3_setup_multiple_pads(
  295. usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
  296. gpio_direction_input(USDHC4_CD_GPIO);
  297. usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
  298. break;
  299. default:
  300. printf("Warning: you configured more USDHC controllers"
  301. "(%d) than supported by the board\n", i + 1);
  302. return -EINVAL;
  303. }
  304. ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
  305. if (ret) {
  306. printf("Warning: failed to initialize mmc dev %d\n", i);
  307. return ret;
  308. }
  309. }
  310. return 0;
  311. }
  312. #ifdef CONFIG_FSL_QSPI
  313. #define QSPI_PAD_CTRL1 \
  314. (PAD_CTL_SRE_FAST | PAD_CTL_SPEED_HIGH | \
  315. PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_40ohm)
  316. static iomux_v3_cfg_t const quadspi_pads[] = {
  317. MX6_PAD_QSPI1A_SS0_B__QSPI1_A_SS0_B | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
  318. MX6_PAD_QSPI1A_SCLK__QSPI1_A_SCLK | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
  319. MX6_PAD_QSPI1A_DATA0__QSPI1_A_DATA_0 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
  320. MX6_PAD_QSPI1A_DATA1__QSPI1_A_DATA_1 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
  321. MX6_PAD_QSPI1A_DATA2__QSPI1_A_DATA_2 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
  322. MX6_PAD_QSPI1A_DATA3__QSPI1_A_DATA_3 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
  323. MX6_PAD_QSPI1B_SS0_B__QSPI1_B_SS0_B | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
  324. MX6_PAD_QSPI1B_SCLK__QSPI1_B_SCLK | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
  325. MX6_PAD_QSPI1B_DATA0__QSPI1_B_DATA_0 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
  326. MX6_PAD_QSPI1B_DATA1__QSPI1_B_DATA_1 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
  327. MX6_PAD_QSPI1B_DATA2__QSPI1_B_DATA_2 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
  328. MX6_PAD_QSPI1B_DATA3__QSPI1_B_DATA_3 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
  329. };
  330. int board_qspi_init(void)
  331. {
  332. /* Set the iomux */
  333. imx_iomux_v3_setup_multiple_pads(quadspi_pads,
  334. ARRAY_SIZE(quadspi_pads));
  335. /* Set the clock */
  336. enable_qspi_clk(0);
  337. return 0;
  338. }
  339. #endif
  340. #ifdef CONFIG_NAND_MXS
  341. iomux_v3_cfg_t gpmi_pads[] = {
  342. MX6_PAD_NAND_CLE__RAWNAND_CLE | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  343. MX6_PAD_NAND_ALE__RAWNAND_ALE | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  344. MX6_PAD_NAND_WP_B__RAWNAND_WP_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  345. MX6_PAD_NAND_READY_B__RAWNAND_READY_B | MUX_PAD_CTRL(GPMI_PAD_CTRL0),
  346. MX6_PAD_NAND_CE0_B__RAWNAND_CE0_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  347. MX6_PAD_NAND_RE_B__RAWNAND_RE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  348. MX6_PAD_NAND_WE_B__RAWNAND_WE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  349. MX6_PAD_NAND_DATA00__RAWNAND_DATA00 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  350. MX6_PAD_NAND_DATA01__RAWNAND_DATA01 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  351. MX6_PAD_NAND_DATA02__RAWNAND_DATA02 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  352. MX6_PAD_NAND_DATA03__RAWNAND_DATA03 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  353. MX6_PAD_NAND_DATA04__RAWNAND_DATA04 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  354. MX6_PAD_NAND_DATA05__RAWNAND_DATA05 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  355. MX6_PAD_NAND_DATA06__RAWNAND_DATA06 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  356. MX6_PAD_NAND_DATA07__RAWNAND_DATA07 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
  357. };
  358. static void setup_gpmi_nand(void)
  359. {
  360. struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  361. /* config gpmi nand iomux */
  362. imx_iomux_v3_setup_multiple_pads(gpmi_pads, ARRAY_SIZE(gpmi_pads));
  363. setup_gpmi_io_clk((MXC_CCM_CS2CDR_QSPI2_CLK_PODF(0) |
  364. MXC_CCM_CS2CDR_QSPI2_CLK_PRED(3) |
  365. MXC_CCM_CS2CDR_QSPI2_CLK_SEL(3)));
  366. /* enable apbh clock gating */
  367. setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
  368. }
  369. #endif
  370. int board_init(void)
  371. {
  372. /* Address of boot parameters */
  373. gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  374. #ifdef CONFIG_SYS_I2C_MXC
  375. setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
  376. setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info3);
  377. #endif
  378. /* Reset CPU_PER_RST_B signal for enet phy and PCIE */
  379. port_exp_direction_output(CPU_PER_RST_B, 0);
  380. udelay(500);
  381. port_exp_direction_output(CPU_PER_RST_B, 1);
  382. /* Set steering signal to L for selecting B0 */
  383. port_exp_direction_output(STEER_ENET, 0);
  384. #ifdef CONFIG_USB_EHCI_MX6
  385. setup_usb();
  386. #endif
  387. #ifdef CONFIG_FSL_QSPI
  388. board_qspi_init();
  389. #endif
  390. #ifdef CONFIG_NAND_MXS
  391. setup_gpmi_nand();
  392. #endif
  393. return 0;
  394. }
  395. #ifdef CONFIG_CMD_BMODE
  396. static const struct boot_mode board_boot_modes[] = {
  397. {"sda", MAKE_CFGVAL(0x42, 0x30, 0x00, 0x00)},
  398. {"sdb", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
  399. {"qspi1", MAKE_CFGVAL(0x10, 0x00, 0x00, 0x00)},
  400. {"nand", MAKE_CFGVAL(0x82, 0x00, 0x00, 0x00)},
  401. {NULL, 0},
  402. };
  403. #endif
  404. int board_late_init(void)
  405. {
  406. #ifdef CONFIG_CMD_BMODE
  407. add_board_boot_modes(board_boot_modes);
  408. #endif
  409. return 0;
  410. }
  411. int checkboard(void)
  412. {
  413. puts("Board: MX6SX SABRE AUTO\n");
  414. return 0;
  415. }