aristainetos.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2014
  4. * Heiko Schocher, DENX Software Engineering, hs@denx.de.
  5. *
  6. * Based on:
  7. * Copyright (C) 2012 Freescale Semiconductor, Inc.
  8. *
  9. * Author: Fabio Estevam <fabio.estevam@freescale.com>
  10. */
  11. #include <command.h>
  12. #include <image.h>
  13. #include <init.h>
  14. #include <asm/arch/clock.h>
  15. #include <asm/arch/imx-regs.h>
  16. #include <asm/arch/iomux.h>
  17. #include <asm/arch/mx6-pins.h>
  18. #include <linux/errno.h>
  19. #include <asm/gpio.h>
  20. #include <asm/mach-imx/iomux-v3.h>
  21. #include <asm/mach-imx/boot_mode.h>
  22. #include <asm/mach-imx/video.h>
  23. #include <asm/arch/crm_regs.h>
  24. #include <asm/io.h>
  25. #include <asm/arch/sys_proto.h>
  26. #include <bmp_logo.h>
  27. #include <dm/root.h>
  28. #include <env.h>
  29. #include <i2c_eeprom.h>
  30. #include <i2c.h>
  31. #include <micrel.h>
  32. #include <miiphy.h>
  33. #include <lcd.h>
  34. #include <led.h>
  35. #include <power/pmic.h>
  36. #include <power/regulator.h>
  37. #include <power/da9063_pmic.h>
  38. #include <splash.h>
  39. #include <video_fb.h>
  40. DECLARE_GLOBAL_DATA_PTR;
  41. enum {
  42. BOARD_TYPE_4 = 4,
  43. BOARD_TYPE_7 = 7,
  44. };
  45. #define ARI_BT_4 "aristainetos2_4@2"
  46. #define ARI_BT_7 "aristainetos2_7@1"
  47. int board_phy_config(struct phy_device *phydev)
  48. {
  49. /* control data pad skew - devaddr = 0x02, register = 0x04 */
  50. ksz9031_phy_extended_write(phydev, 0x02,
  51. MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
  52. MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
  53. /* rx data pad skew - devaddr = 0x02, register = 0x05 */
  54. ksz9031_phy_extended_write(phydev, 0x02,
  55. MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
  56. MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
  57. /* tx data pad skew - devaddr = 0x02, register = 0x06 */
  58. ksz9031_phy_extended_write(phydev, 0x02,
  59. MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
  60. MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
  61. /* gtx and rx clock pad skew - devaddr = 0x02, register = 0x08 */
  62. ksz9031_phy_extended_write(phydev, 0x02,
  63. MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
  64. MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x03FF);
  65. if (phydev->drv->config)
  66. phydev->drv->config(phydev);
  67. return 0;
  68. }
  69. static int rotate_logo_one(unsigned char *out, unsigned char *in)
  70. {
  71. int i, j;
  72. for (i = 0; i < BMP_LOGO_WIDTH; i++)
  73. for (j = 0; j < BMP_LOGO_HEIGHT; j++)
  74. out[j * BMP_LOGO_WIDTH + BMP_LOGO_HEIGHT - 1 - i] =
  75. in[i * BMP_LOGO_WIDTH + j];
  76. return 0;
  77. }
  78. /*
  79. * Rotate the BMP_LOGO (only)
  80. * Will only work, if the logo is square, as
  81. * BMP_LOGO_HEIGHT and BMP_LOGO_WIDTH are defines, not variables
  82. */
  83. void rotate_logo(int rotations)
  84. {
  85. unsigned char out_logo[BMP_LOGO_WIDTH * BMP_LOGO_HEIGHT];
  86. struct bmp_header *header;
  87. unsigned char *in_logo;
  88. int i, j;
  89. if (BMP_LOGO_WIDTH != BMP_LOGO_HEIGHT)
  90. return;
  91. header = (struct bmp_header *)bmp_logo_bitmap;
  92. in_logo = bmp_logo_bitmap + header->data_offset;
  93. /* one 90 degree rotation */
  94. if (rotations == 1 || rotations == 2 || rotations == 3)
  95. rotate_logo_one(out_logo, in_logo);
  96. /* second 90 degree rotation */
  97. if (rotations == 2 || rotations == 3)
  98. rotate_logo_one(in_logo, out_logo);
  99. /* third 90 degree rotation */
  100. if (rotations == 3)
  101. rotate_logo_one(out_logo, in_logo);
  102. /* copy result back to original array */
  103. if (rotations == 1 || rotations == 3)
  104. for (i = 0; i < BMP_LOGO_WIDTH; i++)
  105. for (j = 0; j < BMP_LOGO_HEIGHT; j++)
  106. in_logo[i * BMP_LOGO_WIDTH + j] =
  107. out_logo[i * BMP_LOGO_WIDTH + j];
  108. }
  109. static void enable_lvds(struct display_info_t const *dev)
  110. {
  111. struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
  112. struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  113. int reg;
  114. s32 timeout = 100000;
  115. /* set PLL5 clock */
  116. reg = readl(&ccm->analog_pll_video);
  117. reg |= BM_ANADIG_PLL_VIDEO_POWERDOWN;
  118. writel(reg, &ccm->analog_pll_video);
  119. /* set PLL5 to 232720000Hz */
  120. reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
  121. reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(0x26);
  122. reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
  123. reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0);
  124. writel(reg, &ccm->analog_pll_video);
  125. writel(BF_ANADIG_PLL_VIDEO_NUM_A(0xC0238),
  126. &ccm->analog_pll_video_num);
  127. writel(BF_ANADIG_PLL_VIDEO_DENOM_B(0xF4240),
  128. &ccm->analog_pll_video_denom);
  129. reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
  130. writel(reg, &ccm->analog_pll_video);
  131. while (timeout--)
  132. if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
  133. break;
  134. if (timeout < 0)
  135. printf("Warning: video pll lock timeout!\n");
  136. reg = readl(&ccm->analog_pll_video);
  137. reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
  138. reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
  139. writel(reg, &ccm->analog_pll_video);
  140. /* set LDB0, LDB1 clk select to 000/000 (PLL5 clock) */
  141. reg = readl(&ccm->cs2cdr);
  142. reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
  143. | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
  144. reg |= (0 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
  145. | (0 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
  146. writel(reg, &ccm->cs2cdr);
  147. reg = readl(&ccm->cscmr2);
  148. reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
  149. writel(reg, &ccm->cscmr2);
  150. reg = readl(&ccm->chsccdr);
  151. reg |= (CHSCCDR_CLK_SEL_LDB_DI0
  152. << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
  153. writel(reg, &ccm->chsccdr);
  154. reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
  155. | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
  156. | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH
  157. | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
  158. | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
  159. | IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
  160. | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
  161. writel(reg, &iomux->gpr[2]);
  162. reg = readl(&iomux->gpr[3]);
  163. reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
  164. | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
  165. << IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
  166. writel(reg, &iomux->gpr[3]);
  167. }
  168. static void enable_spi_display(struct display_info_t const *dev)
  169. {
  170. struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
  171. struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  172. int reg;
  173. s32 timeout = 100000;
  174. #if defined(CONFIG_VIDEO_BMP_LOGO)
  175. rotate_logo(3); /* portrait display in landscape mode */
  176. #endif
  177. reg = readl(&ccm->cs2cdr);
  178. /* select pll 5 clock */
  179. reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
  180. | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
  181. writel(reg, &ccm->cs2cdr);
  182. /* set PLL5 to 197994996Hz */
  183. reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
  184. reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(0x21);
  185. reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
  186. reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0);
  187. writel(reg, &ccm->analog_pll_video);
  188. writel(BF_ANADIG_PLL_VIDEO_NUM_A(0xfbf4),
  189. &ccm->analog_pll_video_num);
  190. writel(BF_ANADIG_PLL_VIDEO_DENOM_B(0xf4240),
  191. &ccm->analog_pll_video_denom);
  192. reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
  193. writel(reg, &ccm->analog_pll_video);
  194. while (timeout--)
  195. if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
  196. break;
  197. if (timeout < 0)
  198. printf("Warning: video pll lock timeout!\n");
  199. reg = readl(&ccm->analog_pll_video);
  200. reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
  201. reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
  202. writel(reg, &ccm->analog_pll_video);
  203. /* set LDB0, LDB1 clk select to 000/000 (PLL5 clock) */
  204. reg = readl(&ccm->cs2cdr);
  205. reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
  206. | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
  207. reg |= (0 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
  208. | (0 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
  209. writel(reg, &ccm->cs2cdr);
  210. reg = readl(&ccm->cscmr2);
  211. reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
  212. writel(reg, &ccm->cscmr2);
  213. reg = readl(&ccm->chsccdr);
  214. reg |= (CHSCCDR_CLK_SEL_LDB_DI0
  215. << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
  216. reg &= ~MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK;
  217. reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET);
  218. reg &= ~MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK;
  219. reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
  220. writel(reg, &ccm->chsccdr);
  221. reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
  222. | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
  223. | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH
  224. | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
  225. | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
  226. | IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
  227. | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
  228. writel(reg, &iomux->gpr[2]);
  229. reg = readl(&iomux->gpr[3]);
  230. reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
  231. | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
  232. << IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
  233. writel(reg, &iomux->gpr[3]);
  234. }
  235. static void setup_display(void)
  236. {
  237. enable_ipu_clock();
  238. }
  239. static void set_gpr_register(void)
  240. {
  241. struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
  242. writel(IOMUXC_GPR1_APP_CLK_REQ_N | IOMUXC_GPR1_PCIE_RDY_L23 |
  243. IOMUXC_GPR1_EXC_MON_SLVE |
  244. (2 << IOMUXC_GPR1_ADDRS0_OFFSET) |
  245. IOMUXC_GPR1_ACT_CS0,
  246. &iomuxc_regs->gpr[1]);
  247. writel(0x0, &iomuxc_regs->gpr[8]);
  248. writel(IOMUXC_GPR12_ARMP_IPG_CLK_EN | IOMUXC_GPR12_ARMP_AHB_CLK_EN |
  249. IOMUXC_GPR12_ARMP_ATB_CLK_EN | IOMUXC_GPR12_ARMP_APB_CLK_EN,
  250. &iomuxc_regs->gpr[12]);
  251. }
  252. extern char __bss_start[], __bss_end[];
  253. int board_early_init_f(void)
  254. {
  255. select_ldb_di_clock_source(MXC_PLL5_CLK);
  256. set_gpr_register();
  257. /*
  258. * clear bss here, so we can use spi driver
  259. * before relocation and read Environment
  260. * from spi flash.
  261. */
  262. memset(__bss_start, 0x00, __bss_end - __bss_start);
  263. return 0;
  264. }
  265. static void setup_one_led(char *label, int state)
  266. {
  267. struct udevice *dev;
  268. int ret;
  269. ret = led_get_by_label(label, &dev);
  270. if (ret == 0)
  271. led_set_state(dev, state);
  272. }
  273. static void setup_board_gpio(void)
  274. {
  275. setup_one_led("led_ena", LEDST_ON);
  276. /* switch off Status LEDs */
  277. setup_one_led("led_yellow", LEDST_OFF);
  278. setup_one_led("led_red", LEDST_OFF);
  279. setup_one_led("led_green", LEDST_OFF);
  280. setup_one_led("led_blue", LEDST_OFF);
  281. }
  282. #define ARI_RESC_FMT "setenv rescue_reason setenv bootargs \\${bootargs}" \
  283. " rescueReason=%d "
  284. static void aristainetos_run_rescue_command(int reason)
  285. {
  286. char rescue_reason_command[80];
  287. sprintf(rescue_reason_command, ARI_RESC_FMT, reason);
  288. run_command(rescue_reason_command, 0);
  289. }
  290. static int aristainetos_eeprom(void)
  291. {
  292. struct udevice *dev;
  293. int off;
  294. int ret;
  295. u8 data[0x10];
  296. u8 rescue_reason;
  297. off = fdt_path_offset(gd->fdt_blob, "eeprom0");
  298. if (off < 0) {
  299. printf("%s: No eeprom0 path offset\n", __func__);
  300. return off;
  301. }
  302. ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, off, &dev);
  303. if (ret) {
  304. printf("%s: Could not find EEPROM\n", __func__);
  305. return ret;
  306. }
  307. ret = i2c_set_chip_offset_len(dev, 2);
  308. if (ret)
  309. return ret;
  310. ret = i2c_eeprom_read(dev, 0x1ff0, (uint8_t *)data, 6);
  311. if (ret) {
  312. printf("%s: Could not read EEPROM\n", __func__);
  313. return ret;
  314. }
  315. if (strncmp((char *)&data[3], "ReScUe", 6) == 0) {
  316. rescue_reason = *(uint8_t *)&data[9];
  317. memset(&data[3], 0xff, 7);
  318. i2c_eeprom_write(dev, 0x1ff0, (uint8_t *)&data[3], 7);
  319. printf("\nBooting into Rescue System (EEPROM)\n");
  320. aristainetos_run_rescue_command(rescue_reason);
  321. run_command("run rescue_load_fit rescueboot", 0);
  322. } else if (strncmp((char *)data, "DeF", 3) == 0) {
  323. memset(data, 0xff, 3);
  324. i2c_eeprom_write(dev, 0x1ff0, (uint8_t *)data, 3);
  325. printf("\nClear u-boot environment (set back to defaults)\n");
  326. run_command("run default_env; saveenv; saveenv", 0);
  327. }
  328. return 0;
  329. };
  330. static void aristainetos_bootmode_settings(void)
  331. {
  332. struct gpio_desc *desc;
  333. struct src *psrc = (struct src *)SRC_BASE_ADDR;
  334. unsigned int sbmr1 = readl(&psrc->sbmr1);
  335. char *my_bootdelay;
  336. char bootmode = 0;
  337. int ret;
  338. /*
  339. * Check the boot-source. If booting from NOR Flash,
  340. * disable bootdelay
  341. */
  342. ret = gpio_hog_lookup_name("bootsel0", &desc);
  343. if (!ret)
  344. bootmode |= (dm_gpio_get_value(desc) ? 1 : 0) << 0;
  345. ret = gpio_hog_lookup_name("bootsel1", &desc);
  346. if (!ret)
  347. bootmode |= (dm_gpio_get_value(desc) ? 1 : 0) << 1;
  348. ret = gpio_hog_lookup_name("bootsel2", &desc);
  349. if (!ret)
  350. bootmode |= (dm_gpio_get_value(desc) ? 1 : 0) << 2;
  351. if (bootmode == 7) {
  352. my_bootdelay = env_get("nor_bootdelay");
  353. if (my_bootdelay)
  354. env_set("bootdelay", my_bootdelay);
  355. else
  356. env_set("bootdelay", "-2");
  357. }
  358. if (sbmr1 & 0x40) {
  359. env_set("bootmode", "1");
  360. printf("SD bootmode jumper set!\n");
  361. } else {
  362. env_set("bootmode", "0");
  363. }
  364. /* read out some jumper values*/
  365. ret = gpio_hog_lookup_name("env_reset", &desc);
  366. if (!ret) {
  367. if (dm_gpio_get_value(desc)) {
  368. printf("\nClear env (set back to defaults)\n");
  369. run_command("run default_env; saveenv; saveenv", 0);
  370. }
  371. }
  372. ret = gpio_hog_lookup_name("boot_rescue", &desc);
  373. if (!ret) {
  374. if (dm_gpio_get_value(desc)) {
  375. aristainetos_run_rescue_command(16);
  376. run_command("run rescue_xload_boot", 0);
  377. }
  378. }
  379. }
  380. #if defined(CONFIG_DM_PMIC_DA9063)
  381. /*
  382. * On the aristainetos2c boards the PMIC needs to be initialized,
  383. * because the Ethernet PHY uses a different regulator that is not
  384. * setup per hardware default. This does not influence the other versions
  385. * as this regulator isn't used there at all.
  386. *
  387. * Unfortunately we have not yet a interface to setup all
  388. * values we need.
  389. */
  390. static int setup_pmic_voltages(void)
  391. {
  392. struct udevice *dev;
  393. int off;
  394. int ret;
  395. off = fdt_path_offset(gd->fdt_blob, "pmic0");
  396. if (off < 0) {
  397. printf("%s: No pmic path offset\n", __func__);
  398. return off;
  399. }
  400. ret = uclass_get_device_by_of_offset(UCLASS_PMIC, off, &dev);
  401. if (ret) {
  402. printf("%s: Could not find PMIC\n", __func__);
  403. return ret;
  404. }
  405. pmic_reg_write(dev, DA9063_REG_PAGE_CON, 0x01);
  406. pmic_reg_write(dev, DA9063_REG_BPRO_CFG, 0xc1);
  407. ret = pmic_reg_read(dev, DA9063_REG_BUCK_ILIM_B);
  408. if (ret < 0) {
  409. printf("%s: error %d get register\n", __func__, ret);
  410. return ret;
  411. }
  412. ret &= 0xf0;
  413. ret |= 0x09;
  414. pmic_reg_write(dev, DA9063_REG_BUCK_ILIM_B, ret);
  415. pmic_reg_write(dev, DA9063_REG_VBPRO_A, 0x43);
  416. pmic_reg_write(dev, DA9063_REG_VBPRO_B, 0xc3);
  417. return 0;
  418. }
  419. #else
  420. static int setup_pmic_voltages(void)
  421. {
  422. return 0;
  423. }
  424. #endif
  425. int board_late_init(void)
  426. {
  427. int x, y;
  428. led_default_state();
  429. splash_get_pos(&x, &y);
  430. bmp_display((ulong)&bmp_logo_bitmap[0], x, y);
  431. aristainetos_bootmode_settings();
  432. /* eeprom work */
  433. aristainetos_eeprom();
  434. /* set board_type */
  435. if (gd->board_type == BOARD_TYPE_4)
  436. env_set("board_type", ARI_BT_4);
  437. else
  438. env_set("board_type", ARI_BT_7);
  439. if (setup_pmic_voltages())
  440. printf("Error setup PMIC\n");
  441. return 0;
  442. }
  443. int dram_init(void)
  444. {
  445. gd->ram_size = imx_ddr_size();
  446. return 0;
  447. }
  448. struct display_info_t const displays[] = {
  449. {
  450. .bus = -1,
  451. .addr = 0,
  452. .pixfmt = IPU_PIX_FMT_RGB24,
  453. .detect = NULL,
  454. .enable = enable_lvds,
  455. .mode = {
  456. .name = "lb07wv8",
  457. .refresh = 60,
  458. .xres = 800,
  459. .yres = 480,
  460. .pixclock = 30066,
  461. .left_margin = 88,
  462. .right_margin = 88,
  463. .upper_margin = 20,
  464. .lower_margin = 20,
  465. .hsync_len = 80,
  466. .vsync_len = 5,
  467. .sync = FB_SYNC_EXT,
  468. .vmode = FB_VMODE_NONINTERLACED
  469. }
  470. }
  471. #if ((CONFIG_SYS_BOARD_VERSION == 2) || \
  472. (CONFIG_SYS_BOARD_VERSION == 3) || \
  473. (CONFIG_SYS_BOARD_VERSION == 4) || \
  474. (CONFIG_SYS_BOARD_VERSION == 5))
  475. , {
  476. .bus = -1,
  477. .addr = 0,
  478. .pixfmt = IPU_PIX_FMT_RGB24,
  479. .detect = NULL,
  480. .enable = enable_spi_display,
  481. .mode = {
  482. .name = "lg4573",
  483. .refresh = 57,
  484. .xres = 480,
  485. .yres = 800,
  486. .pixclock = 37037,
  487. .left_margin = 59,
  488. .right_margin = 10,
  489. .upper_margin = 15,
  490. .lower_margin = 15,
  491. .hsync_len = 10,
  492. .vsync_len = 15,
  493. .sync = FB_SYNC_EXT | FB_SYNC_HOR_HIGH_ACT |
  494. FB_SYNC_VERT_HIGH_ACT,
  495. .vmode = FB_VMODE_NONINTERLACED
  496. }
  497. }
  498. #endif
  499. };
  500. size_t display_count = ARRAY_SIZE(displays);
  501. #if defined(CONFIG_MTD_RAW_NAND)
  502. iomux_v3_cfg_t nfc_pads[] = {
  503. MX6_PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NO_PAD_CTRL),
  504. MX6_PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NO_PAD_CTRL),
  505. MX6_PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(NO_PAD_CTRL),
  506. MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL),
  507. MX6_PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NO_PAD_CTRL),
  508. MX6_PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NO_PAD_CTRL),
  509. MX6_PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NO_PAD_CTRL),
  510. MX6_PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL),
  511. MX6_PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL),
  512. MX6_PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL),
  513. MX6_PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL),
  514. MX6_PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL),
  515. MX6_PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL),
  516. MX6_PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL),
  517. MX6_PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL),
  518. MX6_PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(NO_PAD_CTRL),
  519. };
  520. static void setup_gpmi_nand(void)
  521. {
  522. struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  523. /* config gpmi nand iomux */
  524. imx_iomux_v3_setup_multiple_pads(nfc_pads,
  525. ARRAY_SIZE(nfc_pads));
  526. /* gate ENFC_CLK_ROOT clock first,before clk source switch */
  527. clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
  528. /* config gpmi and bch clock to 100 MHz */
  529. clrsetbits_le32(&mxc_ccm->cs2cdr,
  530. MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
  531. MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
  532. MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
  533. MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
  534. MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
  535. MXC_CCM_CS2CDR_ENFC_CLK_SEL(3));
  536. /* enable ENFC_CLK_ROOT clock */
  537. setbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
  538. /* enable gpmi and bch clock gating */
  539. setbits_le32(&mxc_ccm->CCGR4,
  540. MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
  541. MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
  542. MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
  543. MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
  544. MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET);
  545. /* enable apbh clock gating */
  546. setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
  547. }
  548. #else
  549. static void setup_gpmi_nand(void)
  550. {
  551. }
  552. #endif
  553. int board_init(void)
  554. {
  555. struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
  556. /* address of boot parameters */
  557. gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  558. setup_board_gpio();
  559. setup_gpmi_nand();
  560. setup_display();
  561. /* GPIO_1 for USB_OTG_ID */
  562. clrsetbits_le32(&iomux->gpr[1], IOMUXC_GPR1_USB_OTG_ID_SEL_MASK, 0);
  563. return 0;
  564. }
  565. int board_fit_config_name_match(const char *name)
  566. {
  567. if (gd->board_type == BOARD_TYPE_4 &&
  568. strchr(name, 0x34))
  569. return 0;
  570. if (gd->board_type == BOARD_TYPE_7 &&
  571. strchr(name, 0x37))
  572. return 0;
  573. return -1;
  574. }
  575. static void do_board_detect(void)
  576. {
  577. int ret;
  578. char s[30];
  579. /* default use board type 7 */
  580. gd->board_type = BOARD_TYPE_7;
  581. if (env_init())
  582. return;
  583. ret = env_get_f("panel", s, sizeof(s));
  584. if (ret < 0)
  585. return;
  586. if (!strncmp("lg4573", s, 6))
  587. gd->board_type = BOARD_TYPE_4;
  588. }
  589. #ifdef CONFIG_DTB_RESELECT
  590. int embedded_dtb_select(void)
  591. {
  592. int rescan;
  593. do_board_detect();
  594. fdtdec_resetup(&rescan);
  595. return 0;
  596. }
  597. #endif