el6x.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. /*
  2. * Copyright (C) Stefano Babic <sbabic@denx.de>
  3. *
  4. * Based on other i.MX6 boards
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <asm/arch/clock.h>
  9. #include <asm/arch/imx-regs.h>
  10. #include <asm/arch/iomux.h>
  11. #include <asm/arch/mx6-pins.h>
  12. #include <linux/errno.h>
  13. #include <asm/gpio.h>
  14. #include <asm/imx-common/mxc_i2c.h>
  15. #include <asm/imx-common/iomux-v3.h>
  16. #include <asm/imx-common/boot_mode.h>
  17. #include <asm/imx-common/video.h>
  18. #include <mmc.h>
  19. #include <fsl_esdhc.h>
  20. #include <miiphy.h>
  21. #include <netdev.h>
  22. #include <asm/arch/mxc_hdmi.h>
  23. #include <asm/arch/crm_regs.h>
  24. #include <asm/io.h>
  25. #include <asm/arch/sys_proto.h>
  26. #include <i2c.h>
  27. #include <power/pmic.h>
  28. #include <power/pfuze100_pmic.h>
  29. #include <asm/arch/mx6-ddr.h>
  30. DECLARE_GLOBAL_DATA_PTR;
  31. #define OPEN_PAD_CTRL (PAD_CTL_ODE | PAD_CTL_DSE_DISABLE | (0 << 12))
  32. #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
  33. PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
  34. PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  35. #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \
  36. PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
  37. PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  38. #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
  39. PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
  40. #define ENET_PAD_CTRL_PD (PAD_CTL_PUS_100K_DOWN | \
  41. PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
  42. #define ENET_PAD_CTRL_CLK ((PAD_CTL_PUS_100K_UP & ~PAD_CTL_PKE) | \
  43. PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
  44. #define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
  45. PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
  46. #define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
  47. PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
  48. PAD_CTL_ODE | PAD_CTL_SRE_FAST)
  49. #define I2C_PMIC 1
  50. #define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL)
  51. #define ETH_PHY_RESET IMX_GPIO_NR(2, 4)
  52. int dram_init(void)
  53. {
  54. gd->ram_size = imx_ddr_size();
  55. return 0;
  56. }
  57. iomux_v3_cfg_t const uart2_pads[] = {
  58. MX6_PAD_SD3_DAT5__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  59. MX6_PAD_SD3_DAT4__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  60. };
  61. static void setup_iomux_uart(void)
  62. {
  63. imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
  64. }
  65. #ifdef CONFIG_TARGET_ZC5202
  66. iomux_v3_cfg_t const enet_pads[] = {
  67. MX6_PAD_GPIO_18__ENET_RX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
  68. MX6_PAD_ENET_RXD0__ENET_RX_DATA0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  69. MX6_PAD_ENET_RXD1__ENET_RX_DATA1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  70. MX6_PAD_KEY_COL2__ENET_RX_DATA2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  71. MX6_PAD_KEY_COL0__ENET_RX_DATA3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  72. MX6_PAD_ENET_CRS_DV__ENET_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
  73. MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL_CLK),
  74. MX6_PAD_ENET_TXD0__ENET_TX_DATA0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  75. MX6_PAD_ENET_TXD1__ENET_TX_DATA1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  76. MX6_PAD_GPIO_19__ENET_TX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
  77. MX6_PAD_KEY_ROW2__ENET_TX_DATA2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  78. MX6_PAD_KEY_ROW0__ENET_TX_DATA3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  79. MX6_PAD_ENET_TX_EN__ENET_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
  80. MX6_PAD_ENET_RX_ER__ENET_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
  81. /* Switch Reset */
  82. MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD),
  83. /* Switch Interrupt */
  84. MX6_PAD_NANDF_D5__GPIO2_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
  85. /* use CRS and COL pads as GPIOs */
  86. MX6_PAD_KEY_COL3__GPIO4_IO12 | MUX_PAD_CTRL(OPEN_PAD_CTRL),
  87. MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(OPEN_PAD_CTRL),
  88. };
  89. #define BOARD_NAME "EL6x-ZC5202"
  90. #else
  91. iomux_v3_cfg_t const enet_pads[] = {
  92. MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
  93. MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  94. MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  95. MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  96. MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  97. MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  98. MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  99. MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
  100. MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL_CLK),
  101. MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  102. MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  103. MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  104. MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  105. MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  106. MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
  107. MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL),
  108. MX6_PAD_NANDF_D5__GPIO2_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
  109. };
  110. #define BOARD_NAME "EL6x-ZC5601"
  111. #endif
  112. static void setup_iomux_enet(void)
  113. {
  114. imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
  115. #ifdef CONFIG_TARGET_ZC5202
  116. /* set CRS and COL to input */
  117. gpio_direction_input(IMX_GPIO_NR(4, 9));
  118. gpio_direction_input(IMX_GPIO_NR(4, 12));
  119. /* Reset Switch */
  120. gpio_direction_output(ETH_PHY_RESET , 0);
  121. mdelay(2);
  122. gpio_set_value(ETH_PHY_RESET, 1);
  123. #endif
  124. }
  125. int board_phy_config(struct phy_device *phydev)
  126. {
  127. if (phydev->drv->config)
  128. phydev->drv->config(phydev);
  129. return 0;
  130. }
  131. #ifdef CONFIG_MXC_SPI
  132. #ifdef CONFIG_TARGET_ZC5202
  133. iomux_v3_cfg_t const ecspi1_pads[] = {
  134. MX6_PAD_DISP0_DAT20__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
  135. MX6_PAD_DISP0_DAT21__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
  136. MX6_PAD_DISP0_DAT22__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
  137. MX6_PAD_DISP0_DAT23__GPIO5_IO17 | MUX_PAD_CTRL(NO_PAD_CTRL),
  138. MX6_PAD_DISP0_DAT15__GPIO5_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
  139. };
  140. iomux_v3_cfg_t const ecspi3_pads[] = {
  141. MX6_PAD_DISP0_DAT0__ECSPI3_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
  142. MX6_PAD_DISP0_DAT2__ECSPI3_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
  143. MX6_PAD_DISP0_DAT1__ECSPI3_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
  144. MX6_PAD_DISP0_DAT7__GPIO4_IO28 | MUX_PAD_CTRL(SPI_PAD_CTRL),
  145. MX6_PAD_DISP0_DAT8__GPIO4_IO29 | MUX_PAD_CTRL(SPI_PAD_CTRL),
  146. MX6_PAD_DISP0_DAT9__GPIO4_IO30 | MUX_PAD_CTRL(SPI_PAD_CTRL),
  147. MX6_PAD_DISP0_DAT10__GPIO4_IO31 | MUX_PAD_CTRL(SPI_PAD_CTRL),
  148. };
  149. #endif
  150. iomux_v3_cfg_t const ecspi4_pads[] = {
  151. MX6_PAD_EIM_D21__ECSPI4_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
  152. MX6_PAD_EIM_D28__ECSPI4_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
  153. MX6_PAD_EIM_D22__ECSPI4_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
  154. MX6_PAD_EIM_D20__GPIO3_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
  155. };
  156. int board_spi_cs_gpio(unsigned bus, unsigned cs)
  157. {
  158. return (bus == CONFIG_SF_DEFAULT_BUS && cs == CONFIG_SF_DEFAULT_CS)
  159. ? (IMX_GPIO_NR(3, 20)) : -1;
  160. }
  161. static void setup_spi(void)
  162. {
  163. #ifdef CONFIG_TARGET_ZC5202
  164. gpio_request(IMX_GPIO_NR(5, 17), "spi_cs0");
  165. gpio_request(IMX_GPIO_NR(5, 9), "spi_cs1");
  166. gpio_direction_output(IMX_GPIO_NR(5, 17), 1);
  167. gpio_direction_output(IMX_GPIO_NR(5, 9), 1);
  168. imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
  169. #endif
  170. gpio_request(IMX_GPIO_NR(3, 20), "spi4_cs0");
  171. gpio_direction_output(IMX_GPIO_NR(3, 20), 1);
  172. imx_iomux_v3_setup_multiple_pads(ecspi4_pads, ARRAY_SIZE(ecspi4_pads));
  173. enable_spi_clk(true, 3);
  174. }
  175. #endif
  176. static struct i2c_pads_info i2c_pad_info1 = {
  177. .scl = {
  178. .i2c_mode = MX6_PAD_EIM_EB2__I2C2_SCL | I2C_PAD,
  179. .gpio_mode = MX6_PAD_EIM_EB2__GPIO2_IO30 | I2C_PAD,
  180. .gp = IMX_GPIO_NR(2, 30)
  181. },
  182. .sda = {
  183. .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | I2C_PAD,
  184. .gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | I2C_PAD,
  185. .gp = IMX_GPIO_NR(4, 13)
  186. }
  187. };
  188. static struct i2c_pads_info i2c_pad_info2 = {
  189. .scl = {
  190. .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | I2C_PAD,
  191. .gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | I2C_PAD,
  192. .gp = IMX_GPIO_NR(1, 5)
  193. },
  194. .sda = {
  195. .i2c_mode = MX6_PAD_GPIO_16__I2C3_SDA | I2C_PAD,
  196. .gpio_mode = MX6_PAD_GPIO_16__GPIO7_IO11 | I2C_PAD,
  197. .gp = IMX_GPIO_NR(7, 11)
  198. }
  199. };
  200. iomux_v3_cfg_t const usdhc2_pads[] = {
  201. MX6_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  202. MX6_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  203. MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  204. MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  205. MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  206. MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  207. MX6_PAD_GPIO_4__SD2_CD_B | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
  208. };
  209. iomux_v3_cfg_t const usdhc4_pads[] = {
  210. MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  211. MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  212. MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  213. MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  214. MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  215. MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  216. MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  217. MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  218. MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  219. MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  220. };
  221. #ifdef CONFIG_FSL_ESDHC
  222. struct fsl_esdhc_cfg usdhc_cfg[2] = {
  223. {USDHC2_BASE_ADDR},
  224. {USDHC4_BASE_ADDR},
  225. };
  226. #define USDHC2_CD_GPIO IMX_GPIO_NR(1, 4)
  227. int board_mmc_getcd(struct mmc *mmc)
  228. {
  229. struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
  230. int ret = 0;
  231. switch (cfg->esdhc_base) {
  232. case USDHC2_BASE_ADDR:
  233. ret = !gpio_get_value(USDHC2_CD_GPIO);
  234. break;
  235. case USDHC4_BASE_ADDR:
  236. ret = 1; /* eMMC/uSDHC4 is always present */
  237. break;
  238. }
  239. return ret;
  240. }
  241. int board_mmc_init(bd_t *bis)
  242. {
  243. #ifndef CONFIG_SPL_BUILD
  244. int ret;
  245. int i;
  246. /*
  247. * According to the board_mmc_init() the following map is done:
  248. * (U-boot device node) (Physical Port)
  249. * mmc0 SD2
  250. * mmc1 SD3
  251. * mmc2 eMMC
  252. */
  253. for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
  254. switch (i) {
  255. case 0:
  256. imx_iomux_v3_setup_multiple_pads(
  257. usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
  258. gpio_direction_input(USDHC2_CD_GPIO);
  259. usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
  260. break;
  261. case 1:
  262. imx_iomux_v3_setup_multiple_pads(
  263. usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
  264. usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
  265. break;
  266. default:
  267. printf("Warning: you configured more USDHC controllers"
  268. "(%d) then supported by the board (%d)\n",
  269. i + 1, CONFIG_SYS_FSL_USDHC_NUM);
  270. return -EINVAL;
  271. }
  272. ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
  273. if (ret)
  274. return ret;
  275. }
  276. return 0;
  277. #else
  278. struct src *psrc = (struct src *)SRC_BASE_ADDR;
  279. unsigned reg = readl(&psrc->sbmr1) >> 11;
  280. /*
  281. * Upon reading BOOT_CFG register the following map is done:
  282. * Bit 11 and 12 of BOOT_CFG register can determine the current
  283. * mmc port
  284. * 0x1 SD1
  285. * 0x2 SD2
  286. * 0x3 SD4
  287. */
  288. switch (reg & 0x3) {
  289. case 0x1:
  290. imx_iomux_v3_setup_multiple_pads(
  291. usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
  292. usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
  293. usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
  294. gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
  295. break;
  296. case 0x3:
  297. imx_iomux_v3_setup_multiple_pads(
  298. usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
  299. usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
  300. usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
  301. gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
  302. break;
  303. }
  304. return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
  305. #endif
  306. }
  307. #endif
  308. /*
  309. * Do not overwrite the console
  310. * Use always serial for U-Boot console
  311. */
  312. int overwrite_console(void)
  313. {
  314. return 1;
  315. }
  316. int board_eth_init(bd_t *bis)
  317. {
  318. setup_iomux_enet();
  319. enable_enet_clk(1);
  320. return cpu_eth_init(bis);
  321. }
  322. int board_early_init_f(void)
  323. {
  324. setup_iomux_uart();
  325. setup_spi();
  326. return 0;
  327. }
  328. int board_init(void)
  329. {
  330. /* address of boot parameters */
  331. gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  332. setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
  333. setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
  334. return 0;
  335. }
  336. int power_init_board(void)
  337. {
  338. struct pmic *p;
  339. int ret;
  340. unsigned int reg;
  341. ret = power_pfuze100_init(I2C_PMIC);
  342. if (ret)
  343. return ret;
  344. p = pmic_get("PFUZE100");
  345. ret = pmic_probe(p);
  346. if (ret)
  347. return ret;
  348. pmic_reg_read(p, PFUZE100_DEVICEID, &reg);
  349. printf("PMIC: PFUZE100 ID=0x%02x\n", reg);
  350. /* Increase VGEN3 from 2.5 to 2.8V */
  351. pmic_reg_read(p, PFUZE100_VGEN3VOL, &reg);
  352. reg &= ~LDO_VOL_MASK;
  353. reg |= LDOB_2_80V;
  354. pmic_reg_write(p, PFUZE100_VGEN3VOL, reg);
  355. /* Increase VGEN5 from 2.8 to 3V */
  356. pmic_reg_read(p, PFUZE100_VGEN5VOL, &reg);
  357. reg &= ~LDO_VOL_MASK;
  358. reg |= LDOB_3_00V;
  359. pmic_reg_write(p, PFUZE100_VGEN5VOL, reg);
  360. /* Set SW1AB stanby volage to 0.975V */
  361. pmic_reg_read(p, PFUZE100_SW1ABSTBY, &reg);
  362. reg &= ~SW1x_STBY_MASK;
  363. reg |= SW1x_0_975V;
  364. pmic_reg_write(p, PFUZE100_SW1ABSTBY, reg);
  365. /* Set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */
  366. pmic_reg_read(p, PFUZE100_SW1ABCONF, &reg);
  367. reg &= ~SW1xCONF_DVSSPEED_MASK;
  368. reg |= SW1xCONF_DVSSPEED_4US;
  369. pmic_reg_write(p, PFUZE100_SW1ABCONF, reg);
  370. /* Set SW1C standby voltage to 0.975V */
  371. pmic_reg_read(p, PFUZE100_SW1CSTBY, &reg);
  372. reg &= ~SW1x_STBY_MASK;
  373. reg |= SW1x_0_975V;
  374. pmic_reg_write(p, PFUZE100_SW1CSTBY, reg);
  375. /* Set SW1C/VDDSOC step ramp up time from 16us to 4us/25mV */
  376. pmic_reg_read(p, PFUZE100_SW1CCONF, &reg);
  377. reg &= ~SW1xCONF_DVSSPEED_MASK;
  378. reg |= SW1xCONF_DVSSPEED_4US;
  379. pmic_reg_write(p, PFUZE100_SW1CCONF, reg);
  380. return 0;
  381. }
  382. #ifdef CONFIG_CMD_BMODE
  383. static const struct boot_mode board_boot_modes[] = {
  384. /* 4 bit bus width */
  385. {"sd2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
  386. /* 8 bit bus width */
  387. {"emmc", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
  388. {NULL, 0},
  389. };
  390. #endif
  391. int board_late_init(void)
  392. {
  393. #ifdef CONFIG_CMD_BMODE
  394. add_board_boot_modes(board_boot_modes);
  395. #endif
  396. setenv("board_name", BOARD_NAME);
  397. return 0;
  398. }
  399. int checkboard(void)
  400. {
  401. puts("Board: ");
  402. puts(BOARD_NAME "\n");
  403. return 0;
  404. }
  405. #ifdef CONFIG_SPL_BUILD
  406. #include <spl.h>
  407. #include <libfdt.h>
  408. const struct mx6dq_iomux_ddr_regs mx6_ddr_ioregs = {
  409. .dram_sdclk_0 = 0x00020030,
  410. .dram_sdclk_1 = 0x00020030,
  411. .dram_cas = 0x00020030,
  412. .dram_ras = 0x00020030,
  413. .dram_reset = 0x00020030,
  414. .dram_sdcke0 = 0x00003000,
  415. .dram_sdcke1 = 0x00003000,
  416. .dram_sdba2 = 0x00000000,
  417. .dram_sdodt0 = 0x00003030,
  418. .dram_sdodt1 = 0x00003030,
  419. .dram_sdqs0 = 0x00000030,
  420. .dram_sdqs1 = 0x00000030,
  421. .dram_sdqs2 = 0x00000030,
  422. .dram_sdqs3 = 0x00000030,
  423. .dram_sdqs4 = 0x00000030,
  424. .dram_sdqs5 = 0x00000030,
  425. .dram_sdqs6 = 0x00000030,
  426. .dram_sdqs7 = 0x00000030,
  427. .dram_dqm0 = 0x00020030,
  428. .dram_dqm1 = 0x00020030,
  429. .dram_dqm2 = 0x00020030,
  430. .dram_dqm3 = 0x00020030,
  431. .dram_dqm4 = 0x00020030,
  432. .dram_dqm5 = 0x00020030,
  433. .dram_dqm6 = 0x00020030,
  434. .dram_dqm7 = 0x00020030,
  435. };
  436. const struct mx6dq_iomux_grp_regs mx6_grp_ioregs = {
  437. .grp_ddr_type = 0x000C0000,
  438. .grp_ddrmode_ctl = 0x00020000,
  439. .grp_ddrpke = 0x00000000,
  440. .grp_addds = 0x00000030,
  441. .grp_ctlds = 0x00000030,
  442. .grp_ddrmode = 0x00020000,
  443. .grp_b0ds = 0x00000030,
  444. .grp_b1ds = 0x00000030,
  445. .grp_b2ds = 0x00000030,
  446. .grp_b3ds = 0x00000030,
  447. .grp_b4ds = 0x00000030,
  448. .grp_b5ds = 0x00000030,
  449. .grp_b6ds = 0x00000030,
  450. .grp_b7ds = 0x00000030,
  451. };
  452. const struct mx6_mmdc_calibration mx6_mmcd_calib = {
  453. .p0_mpwldectrl0 = 0x001F001F,
  454. .p0_mpwldectrl1 = 0x001F001F,
  455. .p1_mpwldectrl0 = 0x00440044,
  456. .p1_mpwldectrl1 = 0x00440044,
  457. .p0_mpdgctrl0 = 0x434B0350,
  458. .p0_mpdgctrl1 = 0x034C0359,
  459. .p1_mpdgctrl0 = 0x434B0350,
  460. .p1_mpdgctrl1 = 0x03650348,
  461. .p0_mprddlctl = 0x4436383B,
  462. .p1_mprddlctl = 0x39393341,
  463. .p0_mpwrdlctl = 0x35373933,
  464. .p1_mpwrdlctl = 0x48254A36,
  465. };
  466. /* MT41K128M16JT-125 */
  467. static struct mx6_ddr3_cfg mem_ddr = {
  468. .mem_speed = 1600,
  469. .density = 2,
  470. .width = 16,
  471. .banks = 8,
  472. .rowaddr = 14,
  473. .coladdr = 10,
  474. .pagesz = 2,
  475. .trcd = 1375,
  476. .trcmin = 4875,
  477. .trasmin = 3500,
  478. };
  479. static void ccgr_init(void)
  480. {
  481. struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  482. writel(0x00C03F3F, &ccm->CCGR0);
  483. writel(0x0030FC03, &ccm->CCGR1);
  484. writel(0x0FFFC000, &ccm->CCGR2);
  485. writel(0x3FF00000, &ccm->CCGR3);
  486. writel(0x00FFF300, &ccm->CCGR4);
  487. writel(0x0F0000C3, &ccm->CCGR5);
  488. writel(0x000003FF, &ccm->CCGR6);
  489. }
  490. static void gpr_init(void)
  491. {
  492. struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
  493. /* enable AXI cache for VDOA/VPU/IPU */
  494. writel(0xF00000CF, &iomux->gpr[4]);
  495. /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
  496. writel(0x007F007F, &iomux->gpr[6]);
  497. writel(0x007F007F, &iomux->gpr[7]);
  498. }
  499. /*
  500. * This section requires the differentiation between iMX6 Sabre boards, but
  501. * for now, it will configure only for the mx6q variant.
  502. */
  503. static void spl_dram_init(void)
  504. {
  505. struct mx6_ddr_sysinfo sysinfo = {
  506. /* width of data bus:0=16,1=32,2=64 */
  507. .dsize = 2,
  508. /* config for full 4GB range so that get_mem_size() works */
  509. .cs_density = 32, /* 32Gb per CS */
  510. /* single chip select */
  511. .ncs = 1,
  512. .cs1_mirror = 0,
  513. .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */
  514. .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */
  515. .walat = 1, /* Write additional latency */
  516. .ralat = 5, /* Read additional latency */
  517. .mif3_mode = 3, /* Command prediction working mode */
  518. .bi_on = 1, /* Bank interleaving enabled */
  519. .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */
  520. .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */
  521. .ddr_type = DDR_TYPE_DDR3,
  522. .refsel = 1, /* Refresh cycles at 32KHz */
  523. .refr = 7, /* 8 refresh commands per refresh cycle */
  524. };
  525. mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs);
  526. mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr);
  527. }
  528. void board_init_f(ulong dummy)
  529. {
  530. /* setup AIPS and disable watchdog */
  531. arch_cpu_init();
  532. ccgr_init();
  533. gpr_init();
  534. /* iomux and setup of i2c */
  535. board_early_init_f();
  536. /* setup GP timer */
  537. timer_init();
  538. /* UART clocks enabled and gd valid - init serial console */
  539. preloader_console_init();
  540. /* DDR initialization */
  541. spl_dram_init();
  542. /* Clear the BSS. */
  543. memset(__bss_start, 0, __bss_end - __bss_start);
  544. /* load/boot image from boot device */
  545. board_init_r(NULL, 0);
  546. }
  547. #endif