el6x.c 17 KB

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