vining_2000.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2016 samtec automotive software & electronics gmbh
  4. * Copyright (C) 2017-2019 softing automotive electronics gmbH
  5. *
  6. * Author: Christoph Fritz <chf.fritz@googlemail.com>
  7. */
  8. #include <init.h>
  9. #include <net.h>
  10. #include <asm/arch/clock.h>
  11. #include <asm/arch/crm_regs.h>
  12. #include <asm/arch/iomux.h>
  13. #include <asm/arch/imx-regs.h>
  14. #include <asm/arch/mx6-pins.h>
  15. #include <asm/arch/sys_proto.h>
  16. #include <asm/global_data.h>
  17. #include <asm/gpio.h>
  18. #include <asm/mach-imx/iomux-v3.h>
  19. #include <asm/io.h>
  20. #include <asm/mach-imx/mxc_i2c.h>
  21. #include <env.h>
  22. #include <linux/bitops.h>
  23. #include <linux/delay.h>
  24. #include <linux/sizes.h>
  25. #include <common.h>
  26. #include <fsl_esdhc_imx.h>
  27. #include <mmc.h>
  28. #include <i2c.h>
  29. #include <miiphy.h>
  30. #include <netdev.h>
  31. #include <power/pmic.h>
  32. #include <power/pfuze100_pmic.h>
  33. #include <usb.h>
  34. #include <usb/ehci-ci.h>
  35. #include <pwm.h>
  36. #include <wait_bit.h>
  37. DECLARE_GLOBAL_DATA_PTR;
  38. #define UART_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \
  39. PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
  40. PAD_CTL_SRE_FAST)
  41. #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_PKE | \
  42. PAD_CTL_SPEED_HIGH | PAD_CTL_DSE_48ohm | \
  43. PAD_CTL_SRE_FAST)
  44. #define ENET_CLK_PAD_CTRL PAD_CTL_DSE_34ohm
  45. #define ENET_RX_PAD_CTRL (PAD_CTL_PKE | \
  46. PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_HIGH | \
  47. PAD_CTL_SRE_FAST)
  48. #define I2C_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \
  49. PAD_CTL_PKE | PAD_CTL_ODE | PAD_CTL_SPEED_MED | \
  50. PAD_CTL_DSE_40ohm)
  51. #define USDHC_CLK_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
  52. PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST)
  53. #define USDHC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | \
  54. PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_80ohm | \
  55. PAD_CTL_SRE_FAST)
  56. #define USDHC_RESET_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | \
  57. PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_80ohm)
  58. #define GPIO_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \
  59. PAD_CTL_PKE)
  60. int dram_init(void)
  61. {
  62. gd->ram_size = imx_ddr_size();
  63. return 0;
  64. }
  65. static iomux_v3_cfg_t const pwm_led_pads[] = {
  66. MX6_PAD_RGMII2_RD2__PWM2_OUT | MUX_PAD_CTRL(NO_PAD_CTRL), /* green */
  67. MX6_PAD_RGMII2_TD2__PWM6_OUT | MUX_PAD_CTRL(NO_PAD_CTRL), /* red */
  68. MX6_PAD_RGMII2_RD3__PWM1_OUT | MUX_PAD_CTRL(NO_PAD_CTRL), /* blue */
  69. };
  70. static int board_net_init(void)
  71. {
  72. struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
  73. unsigned char eth1addr[6];
  74. int ret;
  75. /* just to get second mac address */
  76. imx_get_mac_from_fuse(1, eth1addr);
  77. if (!env_get("eth1addr") && is_valid_ethaddr(eth1addr))
  78. eth_env_set_enetaddr("eth1addr", eth1addr);
  79. /*
  80. * Generate phy reference clock via pin IOMUX ENET_REF_CLK1/2 by erasing
  81. * ENET1/2_TX_CLK_DIR gpr1[14:13], so that reference clock is driven by
  82. * ref_enetpll0/1 and enable ENET1/2_TX_CLK output driver.
  83. */
  84. clrsetbits_le32(&iomuxc_regs->gpr[1],
  85. IOMUX_GPR1_FEC1_CLOCK_MUX2_SEL_MASK |
  86. IOMUX_GPR1_FEC2_CLOCK_MUX2_SEL_MASK,
  87. IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK |
  88. IOMUX_GPR1_FEC2_CLOCK_MUX1_SEL_MASK);
  89. ret = enable_fec_anatop_clock(0, ENET_50MHZ);
  90. if (ret)
  91. goto eth_fail;
  92. ret = enable_fec_anatop_clock(1, ENET_50MHZ);
  93. if (ret)
  94. goto eth_fail;
  95. return ret;
  96. eth_fail:
  97. printf("FEC MXC: %s:failed (%i)\n", __func__, ret);
  98. return ret;
  99. }
  100. #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
  101. /* I2C1 for PMIC */
  102. static struct i2c_pads_info i2c_pad_info1 = {
  103. .scl = {
  104. .i2c_mode = MX6_PAD_GPIO1_IO00__I2C1_SCL | PC,
  105. .gpio_mode = MX6_PAD_GPIO1_IO00__GPIO1_IO_0 | PC,
  106. .gp = IMX_GPIO_NR(1, 0),
  107. },
  108. .sda = {
  109. .i2c_mode = MX6_PAD_GPIO1_IO01__I2C1_SDA | PC,
  110. .gpio_mode = MX6_PAD_GPIO1_IO01__GPIO1_IO_1 | PC,
  111. .gp = IMX_GPIO_NR(1, 1),
  112. },
  113. };
  114. static struct pmic *pfuze_init(unsigned char i2cbus)
  115. {
  116. struct pmic *p;
  117. int ret;
  118. u32 reg;
  119. ret = power_pfuze100_init(i2cbus);
  120. if (ret)
  121. return NULL;
  122. p = pmic_get("PFUZE100");
  123. ret = pmic_probe(p);
  124. if (ret)
  125. return NULL;
  126. pmic_reg_read(p, PFUZE100_DEVICEID, &reg);
  127. printf("PMIC: PFUZE%i00 ID=0x%02x\n", (reg & 1) ? 2 : 1, reg);
  128. /* Set SW1AB stanby volage to 0.975V */
  129. pmic_reg_read(p, PFUZE100_SW1ABSTBY, &reg);
  130. reg &= ~SW1x_STBY_MASK;
  131. reg |= SW1x_0_975V;
  132. pmic_reg_write(p, PFUZE100_SW1ABSTBY, reg);
  133. /* Set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */
  134. pmic_reg_read(p, PFUZE100_SW1ABCONF, &reg);
  135. reg &= ~SW1xCONF_DVSSPEED_MASK;
  136. reg |= SW1xCONF_DVSSPEED_4US;
  137. pmic_reg_write(p, PFUZE100_SW1ABCONF, reg);
  138. /* Set SW1C standby voltage to 0.975V */
  139. pmic_reg_read(p, PFUZE100_SW1CSTBY, &reg);
  140. reg &= ~SW1x_STBY_MASK;
  141. reg |= SW1x_0_975V;
  142. pmic_reg_write(p, PFUZE100_SW1CSTBY, reg);
  143. /* Set SW1C/VDDSOC step ramp up time from 16us to 4us/25mV */
  144. pmic_reg_read(p, PFUZE100_SW1CCONF, &reg);
  145. reg &= ~SW1xCONF_DVSSPEED_MASK;
  146. reg |= SW1xCONF_DVSSPEED_4US;
  147. pmic_reg_write(p, PFUZE100_SW1CCONF, reg);
  148. return p;
  149. }
  150. static int pfuze_mode_init(struct pmic *p, u32 mode)
  151. {
  152. unsigned char offset, i, switch_num;
  153. u32 id;
  154. int ret;
  155. pmic_reg_read(p, PFUZE100_DEVICEID, &id);
  156. id = id & 0xf;
  157. if (id == 0) {
  158. switch_num = 6;
  159. offset = PFUZE100_SW1CMODE;
  160. } else if (id == 1) {
  161. switch_num = 4;
  162. offset = PFUZE100_SW2MODE;
  163. } else {
  164. printf("Not supported, id=%d\n", id);
  165. return -EINVAL;
  166. }
  167. ret = pmic_reg_write(p, PFUZE100_SW1ABMODE, mode);
  168. if (ret < 0) {
  169. printf("Set SW1AB mode error!\n");
  170. return ret;
  171. }
  172. for (i = 0; i < switch_num - 1; i++) {
  173. ret = pmic_reg_write(p, offset + i * SWITCH_SIZE, mode);
  174. if (ret < 0) {
  175. printf("Set switch 0x%x mode error!\n",
  176. offset + i * SWITCH_SIZE);
  177. return ret;
  178. }
  179. }
  180. return ret;
  181. }
  182. int power_init_board(void)
  183. {
  184. struct pmic *p;
  185. int ret;
  186. p = pfuze_init(I2C_PMIC);
  187. if (!p)
  188. return -ENODEV;
  189. ret = pfuze_mode_init(p, APS_PFM);
  190. if (ret < 0)
  191. return ret;
  192. set_ldo_voltage(LDO_ARM, 1175); /* Set VDDARM to 1.175V */
  193. set_ldo_voltage(LDO_SOC, 1175); /* Set VDDSOC to 1.175V */
  194. return 0;
  195. }
  196. #ifdef CONFIG_USB_EHCI_MX6
  197. static iomux_v3_cfg_t const usb_otg_pads[] = {
  198. /* OGT1 */
  199. MX6_PAD_GPIO1_IO09__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
  200. MX6_PAD_GPIO1_IO10__ANATOP_OTG1_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
  201. /* OTG2 */
  202. MX6_PAD_GPIO1_IO12__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL)
  203. };
  204. static void setup_iomux_usb(void)
  205. {
  206. imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
  207. ARRAY_SIZE(usb_otg_pads));
  208. }
  209. int board_usb_phy_mode(int port)
  210. {
  211. if (port == 1)
  212. return USB_INIT_HOST;
  213. else
  214. return usb_phy_mode(port);
  215. }
  216. #endif
  217. #ifdef CONFIG_PWM_IMX
  218. static int set_pwm_leds(void)
  219. {
  220. int ret;
  221. imx_iomux_v3_setup_multiple_pads(pwm_led_pads,
  222. ARRAY_SIZE(pwm_led_pads));
  223. /* enable backlight PWM 2, green LED */
  224. ret = pwm_init(1, 0, 0);
  225. if (ret)
  226. goto error;
  227. /* duty cycle 200ns, period: 8000ns */
  228. ret = pwm_config(1, 200, 8000);
  229. if (ret)
  230. goto error;
  231. ret = pwm_enable(1);
  232. if (ret)
  233. goto error;
  234. /* enable backlight PWM 1, blue LED */
  235. ret = pwm_init(0, 0, 0);
  236. if (ret)
  237. goto error;
  238. /* duty cycle 200ns, period: 8000ns */
  239. ret = pwm_config(0, 200, 8000);
  240. if (ret)
  241. goto error;
  242. ret = pwm_enable(0);
  243. if (ret)
  244. goto error;
  245. /* enable backlight PWM 6, red LED */
  246. ret = pwm_init(5, 0, 0);
  247. if (ret)
  248. goto error;
  249. /* duty cycle 200ns, period: 8000ns */
  250. ret = pwm_config(5, 200, 8000);
  251. if (ret)
  252. goto error;
  253. ret = pwm_enable(5);
  254. error:
  255. return ret;
  256. }
  257. #else
  258. static int set_pwm_leds(void)
  259. {
  260. return 0;
  261. }
  262. #endif
  263. #define ADCx_HC0 0x00
  264. #define ADCx_HS 0x08
  265. #define ADCx_HS_C0 BIT(0)
  266. #define ADCx_R0 0x0c
  267. #define ADCx_CFG 0x14
  268. #define ADCx_CFG_SWMODE 0x308
  269. #define ADCx_GC 0x18
  270. #define ADCx_GC_CAL BIT(7)
  271. static int read_adc(u32 *val)
  272. {
  273. int ret;
  274. void __iomem *b = map_physmem(ADC1_BASE_ADDR, 0x100, MAP_NOCACHE);
  275. /* use software mode */
  276. writel(ADCx_CFG_SWMODE, b + ADCx_CFG);
  277. /* start auto calibration */
  278. setbits_le32(b + ADCx_GC, ADCx_GC_CAL);
  279. ret = wait_for_bit_le32(b + ADCx_GC, ADCx_GC_CAL, ADCx_GC_CAL, 10, 0);
  280. if (ret)
  281. goto adc_exit;
  282. /* start conversion */
  283. writel(0, b + ADCx_HC0);
  284. /* wait for conversion */
  285. ret = wait_for_bit_le32(b + ADCx_HS, ADCx_HS_C0, ADCx_HS_C0, 10, 0);
  286. if (ret)
  287. goto adc_exit;
  288. /* read result */
  289. *val = readl(b + ADCx_R0);
  290. adc_exit:
  291. if (ret)
  292. printf("ADC failure (ret=%i)\n", ret);
  293. unmap_physmem(b, MAP_NOCACHE);
  294. return ret;
  295. }
  296. #define VAL_UPPER 2498
  297. #define VAL_LOWER 1550
  298. static int set_pin_state(void)
  299. {
  300. u32 val;
  301. int ret;
  302. ret = read_adc(&val);
  303. if (ret)
  304. return ret;
  305. if (val >= VAL_UPPER)
  306. env_set("pin_state", "connected");
  307. else if (val < VAL_UPPER && val > VAL_LOWER)
  308. env_set("pin_state", "open");
  309. else
  310. env_set("pin_state", "button");
  311. return ret;
  312. }
  313. int board_late_init(void)
  314. {
  315. int ret;
  316. ret = set_pwm_leds();
  317. if (ret)
  318. return ret;
  319. ret = set_pin_state();
  320. return ret;
  321. }
  322. int board_early_init_f(void)
  323. {
  324. setup_iomux_usb();
  325. return 0;
  326. }
  327. int board_init(void)
  328. {
  329. /* Address of boot parameters */
  330. gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  331. #ifdef CONFIG_SYS_I2C_MXC
  332. setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
  333. #endif
  334. return board_net_init();
  335. }
  336. int checkboard(void)
  337. {
  338. puts("Board: VIN|ING 2000\n");
  339. return 0;
  340. }
  341. #define PCIE_PHY_PUP_REQ BIT(7)
  342. void board_preboot_os(void)
  343. {
  344. struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
  345. struct gpc *gpc_regs = (struct gpc *)GPC_BASE_ADDR;
  346. /* Bring the PCI power domain up, so that old vendorkernel works. */
  347. setbits_le32(&iomuxc_regs->gpr[12], IOMUXC_GPR12_TEST_POWERDOWN);
  348. setbits_le32(&iomuxc_regs->gpr[5], IOMUXC_GPR5_PCIE_BTNRST);
  349. setbits_le32(&gpc_regs->cntr, PCIE_PHY_PUP_REQ);
  350. }
  351. #ifdef CONFIG_SPL_BUILD
  352. #include <linux/libfdt.h>
  353. #include <spl.h>
  354. #include <asm/arch/mx6-ddr.h>
  355. static iomux_v3_cfg_t const pcie_pads[] = {
  356. MX6_PAD_NAND_DATA02__GPIO4_IO_6 | MUX_PAD_CTRL(GPIO_PAD_CTRL),
  357. };
  358. static iomux_v3_cfg_t const uart_pads[] = {
  359. MX6_PAD_GPIO1_IO04__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
  360. MX6_PAD_GPIO1_IO05__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
  361. };
  362. static iomux_v3_cfg_t const usdhc4_pads[] = {
  363. MX6_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  364. MX6_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  365. MX6_PAD_SD4_DATA0__USDHC4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  366. MX6_PAD_SD4_DATA1__USDHC4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  367. MX6_PAD_SD4_DATA2__USDHC4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  368. MX6_PAD_SD4_DATA3__USDHC4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  369. MX6_PAD_SD4_DATA4__USDHC4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  370. MX6_PAD_SD4_DATA5__USDHC4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  371. MX6_PAD_SD4_DATA6__USDHC4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  372. MX6_PAD_SD4_DATA7__USDHC4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  373. };
  374. static void vining2000_spl_setup_iomux_pcie(void)
  375. {
  376. imx_iomux_v3_setup_multiple_pads(pcie_pads, ARRAY_SIZE(pcie_pads));
  377. }
  378. static void vining2000_spl_setup_iomux_uart(void)
  379. {
  380. imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
  381. }
  382. static struct fsl_esdhc_cfg usdhc_cfg = { USDHC4_BASE_ADDR };
  383. int board_mmc_init(struct bd_info *bis)
  384. {
  385. imx_iomux_v3_setup_multiple_pads(usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
  386. usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
  387. gd->arch.sdhc_clk = usdhc_cfg.sdhc_clk;
  388. return fsl_esdhc_initialize(bis, &usdhc_cfg);
  389. }
  390. int board_mmc_getcd(struct mmc *mmc)
  391. {
  392. return 1;
  393. }
  394. const struct mx6sx_iomux_ddr_regs mx6_ddr_ioregs = {
  395. .dram_dqm0 = 0x00000028,
  396. .dram_dqm1 = 0x00000028,
  397. .dram_dqm2 = 0x00000028,
  398. .dram_dqm3 = 0x00000028,
  399. .dram_ras = 0x00000028,
  400. .dram_cas = 0x00000028,
  401. .dram_odt0 = 0x00000028,
  402. .dram_odt1 = 0x00000028,
  403. .dram_sdba2 = 0x00000000,
  404. .dram_sdcke0 = 0x00003000,
  405. .dram_sdcke1 = 0x00003000,
  406. .dram_sdclk_0 = 0x00000030,
  407. .dram_sdqs0 = 0x00000028,
  408. .dram_sdqs1 = 0x00000028,
  409. .dram_sdqs2 = 0x00000028,
  410. .dram_sdqs3 = 0x00000028,
  411. .dram_reset = 0x00000028,
  412. };
  413. const struct mx6sx_iomux_grp_regs mx6_grp_ioregs = {
  414. .grp_addds = 0x00000028,
  415. .grp_b0ds = 0x00000028,
  416. .grp_b1ds = 0x00000028,
  417. .grp_b2ds = 0x00000028,
  418. .grp_b3ds = 0x00000028,
  419. .grp_ctlds = 0x00000028,
  420. .grp_ddr_type = 0x000c0000,
  421. .grp_ddrmode = 0x00020000,
  422. .grp_ddrmode_ctl = 0x00020000,
  423. .grp_ddrpke = 0x00000000,
  424. };
  425. const struct mx6_mmdc_calibration mx6_mmcd_calib = {
  426. .p0_mpwldectrl0 = 0x0022001C,
  427. .p0_mpwldectrl1 = 0x001F001A,
  428. .p0_mpdgctrl0 = 0x01380134,
  429. .p0_mpdgctrl1 = 0x0124011C,
  430. .p0_mprddlctl = 0x42404444,
  431. .p0_mpwrdlctl = 0x36383C38,
  432. };
  433. static struct mx6_ddr3_cfg mem_ddr = {
  434. .mem_speed = 1600,
  435. .density = 4,
  436. .width = 32,
  437. .banks = 8,
  438. .rowaddr = 15,
  439. .coladdr = 10,
  440. .pagesz = 2,
  441. .trcd = 1391,
  442. .trcmin = 4875,
  443. .trasmin = 3500,
  444. };
  445. static void ccgr_init(void)
  446. {
  447. struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  448. writel(0xF000000F, &ccm->CCGR0); /* AIPS_TZ{1,2,3} */
  449. writel(0x303C0000, &ccm->CCGR1); /* GPT, OCRAM */
  450. writel(0x00FFFCC0, &ccm->CCGR2); /* IPMUX, I2C1, I2C3 */
  451. writel(0x3F300030, &ccm->CCGR3); /* OCRAM, MMDC, ENET */
  452. writel(0x0000C003, &ccm->CCGR4); /* PCI, PL301 */
  453. writel(0x0F0330C3, &ccm->CCGR5); /* UART, ROM */
  454. writel(0x00000F00, &ccm->CCGR6); /* SDHI4, EIM */
  455. }
  456. static void vining2000_spl_dram_init(void)
  457. {
  458. struct mx6_ddr_sysinfo sysinfo = {
  459. .dsize = mem_ddr.width / 32,
  460. .cs_density = 24,
  461. .ncs = 1,
  462. .cs1_mirror = 0,
  463. .rtt_wr = 1, /* RTT_wr = RZQ/4 */
  464. .rtt_nom = 1, /* RTT_Nom = RZQ/4 */
  465. .walat = 1, /* Write additional latency */
  466. .ralat = 5, /* Read additional latency */
  467. .mif3_mode = 3, /* Command prediction working mode */
  468. .bi_on = 1, /* Bank interleaving enabled */
  469. .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */
  470. .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */
  471. .ddr_type = DDR_TYPE_DDR3,
  472. .refsel = 1, /* Refresh cycles at 32KHz */
  473. .refr = 7, /* 8 refresh commands per refresh cycle */
  474. };
  475. mx6sx_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
  476. mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr);
  477. /* Perform DDR DRAM calibration */
  478. udelay(100);
  479. mmdc_do_write_level_calibration(&sysinfo);
  480. mmdc_do_dqs_calibration(&sysinfo);
  481. }
  482. void board_init_f(ulong dummy)
  483. {
  484. /* setup AIPS and disable watchdog */
  485. arch_cpu_init();
  486. ccgr_init();
  487. /* iomux setup */
  488. vining2000_spl_setup_iomux_pcie();
  489. vining2000_spl_setup_iomux_uart();
  490. /* setup GP timer */
  491. timer_init();
  492. /* reset the PCIe device */
  493. gpio_set_value(IMX_GPIO_NR(4, 6), 1);
  494. udelay(50);
  495. gpio_set_value(IMX_GPIO_NR(4, 6), 0);
  496. /* UART clocks enabled and gd valid - init serial console */
  497. preloader_console_init();
  498. /* DDR initialization */
  499. vining2000_spl_dram_init();
  500. /* Clear the BSS. */
  501. memset(__bss_start, 0, __bss_end - __bss_start);
  502. /* load/boot image from boot device */
  503. board_init_r(NULL, 0);
  504. }
  505. #endif