el6x.c 17 KB

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