neo.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. /*
  2. * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
  3. * Copyright (C) Jasbir Matharu
  4. * Copyright (C) UDOO Team
  5. *
  6. * Author: Breno Lima <breno.lima@nxp.com>
  7. * Author: Francesco Montefoschi <francesco.monte@gmail.com>
  8. *
  9. * SPDX-License-Identifier: GPL-2.0+
  10. */
  11. #include <asm/arch/clock.h>
  12. #include <asm/arch/crm_regs.h>
  13. #include <asm/arch/imx-regs.h>
  14. #include <asm/arch/iomux.h>
  15. #include <asm/arch/mx6-pins.h>
  16. #include <asm/gpio.h>
  17. #include <asm/imx-common/iomux-v3.h>
  18. #include <mmc.h>
  19. #include <fsl_esdhc.h>
  20. #include <asm/arch/crm_regs.h>
  21. #include <asm/io.h>
  22. #include <asm/imx-common/mxc_i2c.h>
  23. #include <asm/arch/sys_proto.h>
  24. #include <spl.h>
  25. #include <linux/sizes.h>
  26. #include <common.h>
  27. #include <i2c.h>
  28. #include <miiphy.h>
  29. #include <netdev.h>
  30. #include <power/pmic.h>
  31. #include <power/pfuze3000_pmic.h>
  32. #include <malloc.h>
  33. DECLARE_GLOBAL_DATA_PTR;
  34. enum {
  35. UDOO_NEO_TYPE_BASIC,
  36. UDOO_NEO_TYPE_BASIC_KS,
  37. UDOO_NEO_TYPE_FULL,
  38. UDOO_NEO_TYPE_EXTENDED,
  39. };
  40. #define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  41. PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
  42. PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  43. #define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  44. PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \
  45. PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  46. #define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  47. PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
  48. PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
  49. PAD_CTL_ODE)
  50. #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \
  51. PAD_CTL_SPEED_MED | \
  52. PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
  53. #define ENET_CLK_PAD_CTRL (PAD_CTL_SPEED_MED | \
  54. PAD_CTL_DSE_120ohm | PAD_CTL_SRE_FAST)
  55. #define ENET_RX_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  56. PAD_CTL_SPEED_MED | PAD_CTL_SRE_FAST)
  57. #define WDOG_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_SPEED_MED | \
  58. PAD_CTL_DSE_40ohm)
  59. #define BOARD_DETECT_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  60. PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
  61. PAD_CTL_DSE_34ohm | PAD_CTL_HYS | PAD_CTL_SRE_FAST)
  62. #define BOARD_DETECT_PAD_CFG (MUX_PAD_CTRL(BOARD_DETECT_PAD_CTRL) | \
  63. MUX_MODE_SION)
  64. int dram_init(void)
  65. {
  66. gd->ram_size = imx_ddr_size();
  67. return 0;
  68. }
  69. #ifdef CONFIG_SYS_I2C_MXC
  70. #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
  71. /* I2C1 for PMIC */
  72. static struct i2c_pads_info i2c_pad_info1 = {
  73. .scl = {
  74. .i2c_mode = MX6_PAD_GPIO1_IO00__I2C1_SCL | PC,
  75. .gpio_mode = MX6_PAD_GPIO1_IO00__GPIO1_IO_0 | PC,
  76. .gp = IMX_GPIO_NR(1, 0),
  77. },
  78. .sda = {
  79. .i2c_mode = MX6_PAD_GPIO1_IO01__I2C1_SDA | PC,
  80. .gpio_mode = MX6_PAD_GPIO1_IO01__GPIO1_IO_1 | PC,
  81. .gp = IMX_GPIO_NR(1, 1),
  82. },
  83. };
  84. #endif
  85. #ifdef CONFIG_POWER
  86. int power_init_board(void)
  87. {
  88. struct pmic *p;
  89. int ret;
  90. unsigned int reg, rev_id;
  91. ret = power_pfuze3000_init(PFUZE3000_I2C_BUS);
  92. if (ret)
  93. return ret;
  94. p = pmic_get("PFUZE3000");
  95. ret = pmic_probe(p);
  96. if (ret)
  97. return ret;
  98. pmic_reg_read(p, PFUZE3000_DEVICEID, &reg);
  99. pmic_reg_read(p, PFUZE3000_REVID, &rev_id);
  100. printf("PMIC: PFUZE3000 DEV_ID=0x%x REV_ID=0x%x\n", reg, rev_id);
  101. /* disable Low Power Mode during standby mode */
  102. pmic_reg_read(p, PFUZE3000_LDOGCTL, &reg);
  103. reg |= 0x1;
  104. ret = pmic_reg_write(p, PFUZE3000_LDOGCTL, reg);
  105. if (ret)
  106. return ret;
  107. ret = pmic_reg_write(p, PFUZE3000_SW1AMODE, 0xc);
  108. if (ret)
  109. return ret;
  110. ret = pmic_reg_write(p, PFUZE3000_SW1BMODE, 0xc);
  111. if (ret)
  112. return ret;
  113. ret = pmic_reg_write(p, PFUZE3000_SW2MODE, 0xc);
  114. if (ret)
  115. return ret;
  116. ret = pmic_reg_write(p, PFUZE3000_SW3MODE, 0xc);
  117. if (ret)
  118. return ret;
  119. /* set SW1A standby voltage 0.975V */
  120. pmic_reg_read(p, PFUZE3000_SW1ASTBY, &reg);
  121. reg &= ~0x3f;
  122. reg |= PFUZE3000_SW1AB_SETP(9750);
  123. ret = pmic_reg_write(p, PFUZE3000_SW1ASTBY, reg);
  124. if (ret)
  125. return ret;
  126. /* set SW1B standby voltage 0.975V */
  127. pmic_reg_read(p, PFUZE3000_SW1BSTBY, &reg);
  128. reg &= ~0x3f;
  129. reg |= PFUZE3000_SW1AB_SETP(9750);
  130. ret = pmic_reg_write(p, PFUZE3000_SW1BSTBY, reg);
  131. if (ret)
  132. return ret;
  133. /* set SW1A/VDD_ARM_IN step ramp up time from 16us to 4us/25mV */
  134. pmic_reg_read(p, PFUZE3000_SW1ACONF, &reg);
  135. reg &= ~0xc0;
  136. reg |= 0x40;
  137. ret = pmic_reg_write(p, PFUZE3000_SW1ACONF, reg);
  138. if (ret)
  139. return ret;
  140. /* set SW1B/VDD_SOC_IN step ramp up time from 16us to 4us/25mV */
  141. pmic_reg_read(p, PFUZE3000_SW1BCONF, &reg);
  142. reg &= ~0xc0;
  143. reg |= 0x40;
  144. ret = pmic_reg_write(p, PFUZE3000_SW1BCONF, reg);
  145. if (ret)
  146. return ret;
  147. /* set VDD_ARM_IN to 1.350V */
  148. pmic_reg_read(p, PFUZE3000_SW1AVOLT, &reg);
  149. reg &= ~0x3f;
  150. reg |= PFUZE3000_SW1AB_SETP(13500);
  151. ret = pmic_reg_write(p, PFUZE3000_SW1AVOLT, reg);
  152. if (ret)
  153. return ret;
  154. /* set VDD_SOC_IN to 1.350V */
  155. pmic_reg_read(p, PFUZE3000_SW1BVOLT, &reg);
  156. reg &= ~0x3f;
  157. reg |= PFUZE3000_SW1AB_SETP(13500);
  158. ret = pmic_reg_write(p, PFUZE3000_SW1BVOLT, reg);
  159. if (ret)
  160. return ret;
  161. /* set DDR_1_5V to 1.350V */
  162. pmic_reg_read(p, PFUZE3000_SW3VOLT, &reg);
  163. reg &= ~0x0f;
  164. reg |= PFUZE3000_SW3_SETP(13500);
  165. ret = pmic_reg_write(p, PFUZE3000_SW3VOLT, reg);
  166. if (ret)
  167. return ret;
  168. /* set VGEN2_1V5 to 1.5V */
  169. pmic_reg_read(p, PFUZE3000_VLDO2CTL, &reg);
  170. reg &= ~0x0f;
  171. reg |= PFUZE3000_VLDO_SETP(15000);
  172. /* enable */
  173. reg |= 0x10;
  174. ret = pmic_reg_write(p, PFUZE3000_VLDO2CTL, reg);
  175. if (ret)
  176. return ret;
  177. return 0;
  178. }
  179. #endif
  180. static iomux_v3_cfg_t const uart1_pads[] = {
  181. MX6_PAD_GPIO1_IO04__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
  182. MX6_PAD_GPIO1_IO05__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
  183. };
  184. static iomux_v3_cfg_t const usdhc2_pads[] = {
  185. MX6_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  186. MX6_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  187. MX6_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  188. MX6_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  189. MX6_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  190. MX6_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  191. /* CD pin */
  192. MX6_PAD_SD1_DATA0__GPIO6_IO_2 | MUX_PAD_CTRL(NO_PAD_CTRL),
  193. /* Power */
  194. MX6_PAD_SD1_CMD__GPIO6_IO_1 | MUX_PAD_CTRL(NO_PAD_CTRL),
  195. };
  196. static iomux_v3_cfg_t const fec1_pads[] = {
  197. MX6_PAD_ENET1_MDC__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  198. MX6_PAD_ENET1_MDIO__ENET1_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
  199. MX6_PAD_RGMII1_RX_CTL__ENET1_RX_EN | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  200. MX6_PAD_RGMII1_RD0__ENET1_RX_DATA_0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  201. MX6_PAD_RGMII1_RD1__ENET1_RX_DATA_1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  202. MX6_PAD_RGMII1_TX_CTL__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
  203. MX6_PAD_RGMII1_RXC__ENET1_RX_ER | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  204. MX6_PAD_RGMII1_TD0__ENET1_TX_DATA_0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  205. MX6_PAD_RGMII1_TD1__ENET1_TX_DATA_1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  206. MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  207. MX6_PAD_ENET2_TX_CLK__GPIO2_IO_9 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
  208. MX6_PAD_ENET1_CRS__GPIO2_IO_1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  209. };
  210. static iomux_v3_cfg_t const phy_control_pads[] = {
  211. /* 25MHz Ethernet PHY Clock */
  212. MX6_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M |
  213. MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),
  214. };
  215. static iomux_v3_cfg_t const board_recognition_pads[] = {
  216. /*Connected to R184*/
  217. MX6_PAD_NAND_READY_B__GPIO4_IO_13 | BOARD_DETECT_PAD_CFG,
  218. /*Connected to R185*/
  219. MX6_PAD_NAND_ALE__GPIO4_IO_0 | BOARD_DETECT_PAD_CFG,
  220. };
  221. static iomux_v3_cfg_t const wdog_b_pad = {
  222. MX6_PAD_GPIO1_IO13__GPIO1_IO_13 | MUX_PAD_CTRL(WDOG_PAD_CTRL),
  223. };
  224. static iomux_v3_cfg_t const peri_3v3_pads[] = {
  225. MX6_PAD_QSPI1A_DATA0__GPIO4_IO_16 | MUX_PAD_CTRL(NO_PAD_CTRL),
  226. };
  227. static void setup_iomux_uart(void)
  228. {
  229. imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
  230. }
  231. static int setup_fec(int fec_id)
  232. {
  233. struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
  234. int reg;
  235. imx_iomux_v3_setup_multiple_pads(phy_control_pads,
  236. ARRAY_SIZE(phy_control_pads));
  237. /* Reset PHY */
  238. gpio_direction_output(IMX_GPIO_NR(2, 1) , 0);
  239. udelay(10000);
  240. gpio_set_value(IMX_GPIO_NR(2, 1), 1);
  241. udelay(100);
  242. reg = readl(&anatop->pll_enet);
  243. reg |= BM_ANADIG_PLL_ENET_REF_25M_ENABLE;
  244. writel(reg, &anatop->pll_enet);
  245. return enable_fec_anatop_clock(fec_id, ENET_25MHZ);
  246. }
  247. int board_eth_init(bd_t *bis)
  248. {
  249. uint32_t base = IMX_FEC_BASE;
  250. struct mii_dev *bus = NULL;
  251. struct phy_device *phydev = NULL;
  252. int ret;
  253. imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads));
  254. setup_fec(CONFIG_FEC_ENET_DEV);
  255. bus = fec_get_miibus(base, CONFIG_FEC_ENET_DEV);
  256. if (!bus)
  257. return -EINVAL;
  258. phydev = phy_find_by_mask(bus, (0x1 << CONFIG_FEC_MXC_PHYADDR),
  259. PHY_INTERFACE_MODE_RMII);
  260. if (!phydev) {
  261. free(bus);
  262. return -EINVAL;
  263. }
  264. ret = fec_probe(bis, CONFIG_FEC_ENET_DEV, base, bus, phydev);
  265. if (ret) {
  266. free(bus);
  267. free(phydev);
  268. return ret;
  269. }
  270. return 0;
  271. }
  272. int board_phy_config(struct phy_device *phydev)
  273. {
  274. if (phydev->drv->config)
  275. phydev->drv->config(phydev);
  276. return 0;
  277. }
  278. int board_init(void)
  279. {
  280. /* Address of boot parameters */
  281. gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  282. /*
  283. * Because kernel set WDOG_B mux before pad with the commone pinctrl
  284. * framwork now and wdog reset will be triggered once set WDOG_B mux
  285. * with default pad setting, we set pad setting here to workaround this.
  286. * Since imx_iomux_v3_setup_pad also set mux before pad setting, we set
  287. * as GPIO mux firstly here to workaround it.
  288. */
  289. imx_iomux_v3_setup_pad(wdog_b_pad);
  290. /* Enable PERI_3V3, which is used by SD2, ENET, LVDS, BT */
  291. imx_iomux_v3_setup_multiple_pads(peri_3v3_pads,
  292. ARRAY_SIZE(peri_3v3_pads));
  293. /* Active high for ncp692 */
  294. gpio_direction_output(IMX_GPIO_NR(4, 16) , 1);
  295. #ifdef CONFIG_SYS_I2C_MXC
  296. setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
  297. #endif
  298. return 0;
  299. }
  300. static int get_board_value(void)
  301. {
  302. int r184, r185;
  303. imx_iomux_v3_setup_multiple_pads(board_recognition_pads,
  304. ARRAY_SIZE(board_recognition_pads));
  305. gpio_direction_input(IMX_GPIO_NR(4, 13));
  306. gpio_direction_input(IMX_GPIO_NR(4, 0));
  307. r184 = gpio_get_value(IMX_GPIO_NR(4, 13));
  308. r185 = gpio_get_value(IMX_GPIO_NR(4, 0));
  309. /*
  310. * Machine selection -
  311. * Machine r184, r185
  312. * ---------------------------------
  313. * Basic 0 0
  314. * Basic Ks 0 1
  315. * Full 1 0
  316. * Extended 1 1
  317. */
  318. return (r184 << 1) + r185;
  319. }
  320. int board_early_init_f(void)
  321. {
  322. setup_iomux_uart();
  323. return 0;
  324. }
  325. static struct fsl_esdhc_cfg usdhc_cfg[1] = {
  326. {USDHC2_BASE_ADDR, 0, 4},
  327. };
  328. #define USDHC2_PWR_GPIO IMX_GPIO_NR(6, 1)
  329. #define USDHC2_CD_GPIO IMX_GPIO_NR(6, 2)
  330. int board_mmc_getcd(struct mmc *mmc)
  331. {
  332. return !gpio_get_value(USDHC2_CD_GPIO);
  333. }
  334. int board_mmc_init(bd_t *bis)
  335. {
  336. imx_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
  337. usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
  338. usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
  339. gpio_direction_input(USDHC2_CD_GPIO);
  340. gpio_direction_output(USDHC2_PWR_GPIO, 1);
  341. gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
  342. return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
  343. }
  344. static char *board_string(void)
  345. {
  346. switch (get_board_value()) {
  347. case UDOO_NEO_TYPE_BASIC:
  348. return "BASIC";
  349. case UDOO_NEO_TYPE_BASIC_KS:
  350. return "BASICKS";
  351. case UDOO_NEO_TYPE_FULL:
  352. return "FULL";
  353. case UDOO_NEO_TYPE_EXTENDED:
  354. return "EXTENDED";
  355. }
  356. return "UNDEFINED";
  357. }
  358. int checkboard(void)
  359. {
  360. printf("Board: UDOO Neo %s\n", board_string());
  361. return 0;
  362. }
  363. int board_late_init(void)
  364. {
  365. #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
  366. setenv("board_name", board_string());
  367. #endif
  368. return 0;
  369. }
  370. #ifdef CONFIG_SPL_BUILD
  371. #include <libfdt.h>
  372. #include <asm/arch/mx6-ddr.h>
  373. static const struct mx6sx_iomux_ddr_regs mx6_ddr_ioregs = {
  374. .dram_dqm0 = 0x00000028,
  375. .dram_dqm1 = 0x00000028,
  376. .dram_dqm2 = 0x00000028,
  377. .dram_dqm3 = 0x00000028,
  378. .dram_ras = 0x00000020,
  379. .dram_cas = 0x00000020,
  380. .dram_odt0 = 0x00000020,
  381. .dram_odt1 = 0x00000020,
  382. .dram_sdba2 = 0x00000000,
  383. .dram_sdcke0 = 0x00003000,
  384. .dram_sdcke1 = 0x00003000,
  385. .dram_sdclk_0 = 0x00000030,
  386. .dram_sdqs0 = 0x00000028,
  387. .dram_sdqs1 = 0x00000028,
  388. .dram_sdqs2 = 0x00000028,
  389. .dram_sdqs3 = 0x00000028,
  390. .dram_reset = 0x00000020,
  391. };
  392. static const struct mx6sx_iomux_grp_regs mx6_grp_ioregs = {
  393. .grp_addds = 0x00000020,
  394. .grp_ddrmode_ctl = 0x00020000,
  395. .grp_ddrpke = 0x00000000,
  396. .grp_ddrmode = 0x00020000,
  397. .grp_b0ds = 0x00000028,
  398. .grp_b1ds = 0x00000028,
  399. .grp_ctlds = 0x00000020,
  400. .grp_ddr_type = 0x000c0000,
  401. .grp_b2ds = 0x00000028,
  402. .grp_b3ds = 0x00000028,
  403. };
  404. static const struct mx6_mmdc_calibration neo_mmcd_calib = {
  405. .p0_mpwldectrl0 = 0x000E000B,
  406. .p0_mpwldectrl1 = 0x000E0010,
  407. .p0_mpdgctrl0 = 0x41600158,
  408. .p0_mpdgctrl1 = 0x01500140,
  409. .p0_mprddlctl = 0x3A383E3E,
  410. .p0_mpwrdlctl = 0x3A383C38,
  411. };
  412. static const struct mx6_mmdc_calibration neo_basic_mmcd_calib = {
  413. .p0_mpwldectrl0 = 0x001E0022,
  414. .p0_mpwldectrl1 = 0x001C0019,
  415. .p0_mpdgctrl0 = 0x41540150,
  416. .p0_mpdgctrl1 = 0x01440138,
  417. .p0_mprddlctl = 0x403E4644,
  418. .p0_mpwrdlctl = 0x3C3A4038,
  419. };
  420. /* MT41K256M16 */
  421. static struct mx6_ddr3_cfg neo_mem_ddr = {
  422. .mem_speed = 1600,
  423. .density = 4,
  424. .width = 16,
  425. .banks = 8,
  426. .rowaddr = 15,
  427. .coladdr = 10,
  428. .pagesz = 2,
  429. .trcd = 1375,
  430. .trcmin = 4875,
  431. .trasmin = 3500,
  432. };
  433. /* MT41K128M16 */
  434. static struct mx6_ddr3_cfg neo_basic_mem_ddr = {
  435. .mem_speed = 1600,
  436. .density = 2,
  437. .width = 16,
  438. .banks = 8,
  439. .rowaddr = 14,
  440. .coladdr = 10,
  441. .pagesz = 2,
  442. .trcd = 1375,
  443. .trcmin = 4875,
  444. .trasmin = 3500,
  445. };
  446. static void ccgr_init(void)
  447. {
  448. struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  449. writel(0xFFFFFFFF, &ccm->CCGR0);
  450. writel(0xFFFFFFFF, &ccm->CCGR1);
  451. writel(0xFFFFFFFF, &ccm->CCGR2);
  452. writel(0xFFFFFFFF, &ccm->CCGR3);
  453. writel(0xFFFFFFFF, &ccm->CCGR4);
  454. writel(0xFFFFFFFF, &ccm->CCGR5);
  455. writel(0xFFFFFFFF, &ccm->CCGR6);
  456. writel(0xFFFFFFFF, &ccm->CCGR7);
  457. }
  458. static void spl_dram_init(void)
  459. {
  460. int board = get_board_value();
  461. struct mx6_ddr_sysinfo sysinfo = {
  462. .dsize = 1, /* width of data bus: 1 = 32 bits */
  463. .cs_density = 24,
  464. .ncs = 1,
  465. .cs1_mirror = 0,
  466. .rtt_wr = 2,
  467. .rtt_nom = 2, /* RTT_Nom = RZQ/2 */
  468. .walat = 1, /* Write additional latency */
  469. .ralat = 5, /* Read additional latency */
  470. .mif3_mode = 3, /* Command prediction working mode */
  471. .bi_on = 1, /* Bank interleaving enabled */
  472. .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */
  473. .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */
  474. };
  475. mx6sx_dram_iocfg(32, &mx6_ddr_ioregs, &mx6_grp_ioregs);
  476. if (board == UDOO_NEO_TYPE_BASIC || board == UDOO_NEO_TYPE_BASIC_KS)
  477. mx6_dram_cfg(&sysinfo, &neo_basic_mmcd_calib,
  478. &neo_basic_mem_ddr);
  479. else
  480. mx6_dram_cfg(&sysinfo, &neo_mmcd_calib, &neo_mem_ddr);
  481. }
  482. void board_init_f(ulong dummy)
  483. {
  484. ccgr_init();
  485. /* setup AIPS and disable watchdog */
  486. arch_cpu_init();
  487. board_early_init_f();
  488. /* setup GP timer */
  489. timer_init();
  490. /* UART clocks enabled and gd valid - init serial console */
  491. preloader_console_init();
  492. /* DDR initialization */
  493. spl_dram_init();
  494. /* Clear the BSS. */
  495. memset(__bss_start, 0, __bss_end - __bss_start);
  496. /* load/boot image from boot device */
  497. board_init_r(NULL, 0);
  498. }
  499. #endif