mx6ul_14x14_evk.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2015 Freescale Semiconductor, Inc.
  4. */
  5. #include <init.h>
  6. #include <net.h>
  7. #include <asm/arch/clock.h>
  8. #include <asm/arch/iomux.h>
  9. #include <asm/arch/imx-regs.h>
  10. #include <asm/arch/crm_regs.h>
  11. #include <asm/arch/mx6ul_pins.h>
  12. #include <asm/arch/mx6-pins.h>
  13. #include <asm/arch/sys_proto.h>
  14. #include <asm/gpio.h>
  15. #include <asm/mach-imx/iomux-v3.h>
  16. #include <asm/mach-imx/boot_mode.h>
  17. #include <asm/mach-imx/mxc_i2c.h>
  18. #include <asm/io.h>
  19. #include <common.h>
  20. #include <env.h>
  21. #include <fsl_esdhc_imx.h>
  22. #include <i2c.h>
  23. #include <miiphy.h>
  24. #include <linux/delay.h>
  25. #include <linux/sizes.h>
  26. #include <mmc.h>
  27. #include <netdev.h>
  28. #include <power/pmic.h>
  29. #include <power/pfuze3000_pmic.h>
  30. #include "../common/pfuze.h"
  31. #include <usb.h>
  32. #include <usb/ehci-ci.h>
  33. DECLARE_GLOBAL_DATA_PTR;
  34. #define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  35. PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
  36. PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  37. #define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  38. PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
  39. PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
  40. PAD_CTL_ODE)
  41. #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \
  42. PAD_CTL_SPEED_HIGH | \
  43. PAD_CTL_DSE_48ohm | PAD_CTL_SRE_FAST)
  44. #define LCD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \
  45. PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm)
  46. #define MDIO_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \
  47. PAD_CTL_DSE_48ohm | PAD_CTL_SRE_FAST | PAD_CTL_ODE)
  48. #define ENET_CLK_PAD_CTRL (PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
  49. #define OTG_ID_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  50. PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
  51. PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  52. #ifdef CONFIG_DM_PMIC
  53. int power_init_board(void)
  54. {
  55. struct udevice *dev;
  56. int ret, dev_id, rev_id;
  57. unsigned int reg;
  58. ret = pmic_get("pfuze3000", &dev);
  59. if (ret == -ENODEV)
  60. return 0;
  61. if (ret != 0)
  62. return ret;
  63. dev_id = pmic_reg_read(dev, PFUZE3000_DEVICEID);
  64. rev_id = pmic_reg_read(dev, PFUZE3000_REVID);
  65. printf("PMIC: PFUZE3000 DEV_ID=0x%x REV_ID=0x%x\n", dev_id, rev_id);
  66. /* disable Low Power Mode during standby mode */
  67. reg = pmic_reg_read(dev, PFUZE3000_LDOGCTL);
  68. reg |= 0x1;
  69. pmic_reg_write(dev, PFUZE3000_LDOGCTL, reg);
  70. /* SW1B step ramp up time from 2us to 4us/25mV */
  71. pmic_reg_write(dev, PFUZE3000_SW1BCONF, 0x40);
  72. /* SW1B mode to APS/PFM */
  73. pmic_reg_write(dev, PFUZE3000_SW1BMODE, 0xc);
  74. /* SW1B standby voltage set to 0.975V */
  75. pmic_reg_write(dev, PFUZE3000_SW1BSTBY, 0xb);
  76. return 0;
  77. }
  78. #endif
  79. int dram_init(void)
  80. {
  81. gd->ram_size = imx_ddr_size();
  82. return 0;
  83. }
  84. static iomux_v3_cfg_t const uart1_pads[] = {
  85. MX6_PAD_UART1_TX_DATA__UART1_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
  86. MX6_PAD_UART1_RX_DATA__UART1_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
  87. };
  88. static void setup_iomux_uart(void)
  89. {
  90. imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
  91. }
  92. #ifdef CONFIG_FSL_QSPI
  93. static int board_qspi_init(void)
  94. {
  95. /* Set the clock */
  96. enable_qspi_clk(0);
  97. return 0;
  98. }
  99. #endif
  100. #ifdef CONFIG_SPL_BUILD
  101. #define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
  102. PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \
  103. PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  104. static iomux_v3_cfg_t const usdhc2_pads[] = {
  105. MX6_PAD_NAND_RE_B__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  106. MX6_PAD_NAND_WE_B__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  107. MX6_PAD_NAND_DATA00__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  108. MX6_PAD_NAND_DATA01__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  109. MX6_PAD_NAND_DATA02__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  110. MX6_PAD_NAND_DATA03__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  111. };
  112. static struct fsl_esdhc_cfg usdhc_cfg[1] = {
  113. {USDHC2_BASE_ADDR, 0, 4},
  114. };
  115. int board_mmc_getcd(struct mmc *mmc)
  116. {
  117. return 1;
  118. }
  119. int board_mmc_init(struct bd_info *bis)
  120. {
  121. imx_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
  122. usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
  123. return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
  124. }
  125. #endif
  126. #ifdef CONFIG_USB_EHCI_MX6
  127. #ifndef CONFIG_DM_USB
  128. #define USB_OTHERREGS_OFFSET 0x800
  129. #define UCTRL_PWR_POL (1 << 9)
  130. static iomux_v3_cfg_t const usb_otg_pads[] = {
  131. MX6_PAD_GPIO1_IO00__ANATOP_OTG1_ID | MUX_PAD_CTRL(OTG_ID_PAD_CTRL),
  132. };
  133. /* At default the 3v3 enables the MIC2026 for VBUS power */
  134. static void setup_usb(void)
  135. {
  136. imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
  137. ARRAY_SIZE(usb_otg_pads));
  138. }
  139. int board_usb_phy_mode(int port)
  140. {
  141. if (port == 1)
  142. return USB_INIT_HOST;
  143. else
  144. return usb_phy_mode(port);
  145. }
  146. int board_ehci_hcd_init(int port)
  147. {
  148. u32 *usbnc_usb_ctrl;
  149. if (port > 1)
  150. return -EINVAL;
  151. usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET +
  152. port * 4);
  153. /* Set Power polarity */
  154. setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL);
  155. return 0;
  156. }
  157. #endif
  158. #endif
  159. #ifdef CONFIG_FEC_MXC
  160. static int setup_fec(int fec_id)
  161. {
  162. struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
  163. int ret;
  164. if (fec_id == 0) {
  165. /*
  166. * Use 50M anatop loopback REF_CLK1 for ENET1,
  167. * clear gpr1[13], set gpr1[17].
  168. */
  169. clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK,
  170. IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK);
  171. } else {
  172. /*
  173. * Use 50M anatop loopback REF_CLK2 for ENET2,
  174. * clear gpr1[14], set gpr1[18].
  175. */
  176. clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC2_MASK,
  177. IOMUX_GPR1_FEC2_CLOCK_MUX1_SEL_MASK);
  178. }
  179. ret = enable_fec_anatop_clock(fec_id, ENET_50MHZ);
  180. if (ret)
  181. return ret;
  182. enable_enet_clk(1);
  183. return 0;
  184. }
  185. int board_phy_config(struct phy_device *phydev)
  186. {
  187. phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x8190);
  188. if (phydev->drv->config)
  189. phydev->drv->config(phydev);
  190. return 0;
  191. }
  192. #endif
  193. #ifdef CONFIG_DM_VIDEO
  194. static iomux_v3_cfg_t const lcd_pads[] = {
  195. /* Use GPIO for Brightness adjustment, duty cycle = period. */
  196. MX6_PAD_GPIO1_IO08__GPIO1_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
  197. };
  198. static int setup_lcd(void)
  199. {
  200. enable_lcdif_clock(LCDIF1_BASE_ADDR, 1);
  201. imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads));
  202. /* Reset the LCD */
  203. gpio_request(IMX_GPIO_NR(5, 9), "lcd reset");
  204. gpio_direction_output(IMX_GPIO_NR(5, 9) , 0);
  205. udelay(500);
  206. gpio_direction_output(IMX_GPIO_NR(5, 9) , 1);
  207. /* Set Brightness to high */
  208. gpio_request(IMX_GPIO_NR(1, 8), "backlight");
  209. gpio_direction_output(IMX_GPIO_NR(1, 8) , 1);
  210. return 0;
  211. }
  212. #else
  213. static inline int setup_lcd(void) { return 0; }
  214. #endif
  215. int board_early_init_f(void)
  216. {
  217. setup_iomux_uart();
  218. return 0;
  219. }
  220. int board_init(void)
  221. {
  222. /* Address of boot parameters */
  223. gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  224. #ifdef CONFIG_FEC_MXC
  225. setup_fec(CONFIG_FEC_ENET_DEV);
  226. #endif
  227. #ifdef CONFIG_USB_EHCI_MX6
  228. #ifndef CONFIG_DM_USB
  229. setup_usb();
  230. #endif
  231. #endif
  232. #ifdef CONFIG_FSL_QSPI
  233. board_qspi_init();
  234. #endif
  235. return 0;
  236. }
  237. #ifdef CONFIG_CMD_BMODE
  238. static const struct boot_mode board_boot_modes[] = {
  239. /* 4 bit bus width */
  240. {"sd1", MAKE_CFGVAL(0x42, 0x20, 0x00, 0x00)},
  241. {"sd2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
  242. {"qspi1", MAKE_CFGVAL(0x10, 0x00, 0x00, 0x00)},
  243. {NULL, 0},
  244. };
  245. #endif
  246. int board_late_init(void)
  247. {
  248. #ifdef CONFIG_CMD_BMODE
  249. add_board_boot_modes(board_boot_modes);
  250. #endif
  251. #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
  252. env_set("board_name", "EVK");
  253. if (is_mx6ul_9x9_evk())
  254. env_set("board_rev", "9X9");
  255. else
  256. env_set("board_rev", "14X14");
  257. #endif
  258. setup_lcd();
  259. return 0;
  260. }
  261. int checkboard(void)
  262. {
  263. if (is_mx6ul_9x9_evk())
  264. puts("Board: MX6UL 9x9 EVK\n");
  265. else
  266. puts("Board: MX6UL 14x14 EVK\n");
  267. return 0;
  268. }
  269. /*
  270. * Backlight off and reset LCD before OS handover
  271. */
  272. void board_preboot_os(void)
  273. {
  274. gpio_set_value(IMX_GPIO_NR(1, 8), 0);
  275. gpio_set_value(IMX_GPIO_NR(5, 9), 0);
  276. }
  277. #ifdef CONFIG_SPL_BUILD
  278. #include <linux/libfdt.h>
  279. #include <spl.h>
  280. #include <asm/arch/mx6-ddr.h>
  281. static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = {
  282. .grp_addds = 0x00000030,
  283. .grp_ddrmode_ctl = 0x00020000,
  284. .grp_b0ds = 0x00000030,
  285. .grp_ctlds = 0x00000030,
  286. .grp_b1ds = 0x00000030,
  287. .grp_ddrpke = 0x00000000,
  288. .grp_ddrmode = 0x00020000,
  289. #ifdef CONFIG_TARGET_MX6UL_9X9_EVK
  290. .grp_ddr_type = 0x00080000,
  291. #else
  292. .grp_ddr_type = 0x000c0000,
  293. #endif
  294. };
  295. #ifdef CONFIG_TARGET_MX6UL_9X9_EVK
  296. static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = {
  297. .dram_dqm0 = 0x00000030,
  298. .dram_dqm1 = 0x00000030,
  299. .dram_ras = 0x00000030,
  300. .dram_cas = 0x00000030,
  301. .dram_odt0 = 0x00000000,
  302. .dram_odt1 = 0x00000000,
  303. .dram_sdba2 = 0x00000000,
  304. .dram_sdclk_0 = 0x00000030,
  305. .dram_sdqs0 = 0x00003030,
  306. .dram_sdqs1 = 0x00003030,
  307. .dram_reset = 0x00000030,
  308. };
  309. static struct mx6_mmdc_calibration mx6_mmcd_calib = {
  310. .p0_mpwldectrl0 = 0x00000000,
  311. .p0_mpdgctrl0 = 0x20000000,
  312. .p0_mprddlctl = 0x4040484f,
  313. .p0_mpwrdlctl = 0x40405247,
  314. .mpzqlp2ctl = 0x1b4700c7,
  315. };
  316. static struct mx6_lpddr2_cfg mem_ddr = {
  317. .mem_speed = 800,
  318. .density = 2,
  319. .width = 16,
  320. .banks = 4,
  321. .rowaddr = 14,
  322. .coladdr = 10,
  323. .trcd_lp = 1500,
  324. .trppb_lp = 1500,
  325. .trpab_lp = 2000,
  326. .trasmin = 4250,
  327. };
  328. struct mx6_ddr_sysinfo ddr_sysinfo = {
  329. .dsize = 0,
  330. .cs_density = 18,
  331. .ncs = 1,
  332. .cs1_mirror = 0,
  333. .walat = 0,
  334. .ralat = 5,
  335. .mif3_mode = 3,
  336. .bi_on = 1,
  337. .rtt_wr = 0, /* LPDDR2 does not need rtt_wr rtt_nom */
  338. .rtt_nom = 0,
  339. .sde_to_rst = 0, /* LPDDR2 does not need this field */
  340. .rst_to_cke = 0x10, /* JEDEC value for LPDDR2: 200us */
  341. .ddr_type = DDR_TYPE_LPDDR2,
  342. .refsel = 0, /* Refresh cycles at 64KHz */
  343. .refr = 3, /* 4 refresh commands per refresh cycle */
  344. };
  345. #else
  346. static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = {
  347. .dram_dqm0 = 0x00000030,
  348. .dram_dqm1 = 0x00000030,
  349. .dram_ras = 0x00000030,
  350. .dram_cas = 0x00000030,
  351. .dram_odt0 = 0x00000030,
  352. .dram_odt1 = 0x00000030,
  353. .dram_sdba2 = 0x00000000,
  354. .dram_sdclk_0 = 0x00000030,
  355. .dram_sdqs0 = 0x00000030,
  356. .dram_sdqs1 = 0x00000030,
  357. .dram_reset = 0x00000030,
  358. };
  359. static struct mx6_mmdc_calibration mx6_mmcd_calib = {
  360. .p0_mpwldectrl0 = 0x00000000,
  361. .p0_mpdgctrl0 = 0x41570155,
  362. .p0_mprddlctl = 0x4040474A,
  363. .p0_mpwrdlctl = 0x40405550,
  364. };
  365. struct mx6_ddr_sysinfo ddr_sysinfo = {
  366. .dsize = 0,
  367. .cs_density = 20,
  368. .ncs = 1,
  369. .cs1_mirror = 0,
  370. .rtt_wr = 2,
  371. .rtt_nom = 1, /* RTT_Nom = RZQ/2 */
  372. .walat = 0, /* Write additional latency */
  373. .ralat = 5, /* Read additional latency */
  374. .mif3_mode = 3, /* Command prediction working mode */
  375. .bi_on = 1, /* Bank interleaving enabled */
  376. .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */
  377. .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */
  378. .ddr_type = DDR_TYPE_DDR3,
  379. .refsel = 0, /* Refresh cycles at 64KHz */
  380. .refr = 1, /* 2 refresh commands per refresh cycle */
  381. };
  382. static struct mx6_ddr3_cfg mem_ddr = {
  383. .mem_speed = 800,
  384. .density = 4,
  385. .width = 16,
  386. .banks = 8,
  387. .rowaddr = 15,
  388. .coladdr = 10,
  389. .pagesz = 2,
  390. .trcd = 1375,
  391. .trcmin = 4875,
  392. .trasmin = 3500,
  393. };
  394. #endif
  395. static void ccgr_init(void)
  396. {
  397. struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  398. writel(0xFFFFFFFF, &ccm->CCGR0);
  399. writel(0xFFFFFFFF, &ccm->CCGR1);
  400. writel(0xFFFFFFFF, &ccm->CCGR2);
  401. writel(0xFFFFFFFF, &ccm->CCGR3);
  402. writel(0xFFFFFFFF, &ccm->CCGR4);
  403. writel(0xFFFFFFFF, &ccm->CCGR5);
  404. writel(0xFFFFFFFF, &ccm->CCGR6);
  405. writel(0xFFFFFFFF, &ccm->CCGR7);
  406. }
  407. static void spl_dram_init(void)
  408. {
  409. mx6ul_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
  410. mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr);
  411. }
  412. void board_init_f(ulong dummy)
  413. {
  414. ccgr_init();
  415. /* setup AIPS and disable watchdog */
  416. arch_cpu_init();
  417. /* iomux and setup of i2c */
  418. board_early_init_f();
  419. /* setup GP timer */
  420. timer_init();
  421. /* UART clocks enabled and gd valid - init serial console */
  422. preloader_console_init();
  423. /* DDR initialization */
  424. spl_dram_init();
  425. /* Clear the BSS. */
  426. memset(__bss_start, 0, __bss_end - __bss_start);
  427. /* load/boot image from boot device */
  428. board_init_r(NULL, 0);
  429. }
  430. #endif