aristainetos.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  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 <asm/global_data.h>
  19. #include <linux/errno.h>
  20. #include <asm/gpio.h>
  21. #include <asm/mach-imx/iomux-v3.h>
  22. #include <asm/mach-imx/boot_mode.h>
  23. #include <asm/mach-imx/video.h>
  24. #include <asm/arch/crm_regs.h>
  25. #include <asm/io.h>
  26. #include <asm/arch/sys_proto.h>
  27. #include <bmp_logo.h>
  28. #include <dm/root.h>
  29. #include <env.h>
  30. #include <env_internal.h>
  31. #include <i2c_eeprom.h>
  32. #include <i2c.h>
  33. #include <micrel.h>
  34. #include <miiphy.h>
  35. #include <lcd.h>
  36. #include <led.h>
  37. #include <power/pmic.h>
  38. #include <power/regulator.h>
  39. #include <power/da9063_pmic.h>
  40. #include <splash.h>
  41. #include <video_fb.h>
  42. DECLARE_GLOBAL_DATA_PTR;
  43. enum {
  44. BOARD_TYPE_4 = 4,
  45. BOARD_TYPE_7 = 7,
  46. };
  47. #define ARI_BT_4 "aristainetos2_4@2"
  48. #define ARI_BT_7 "aristainetos2_7@1"
  49. int board_phy_config(struct phy_device *phydev)
  50. {
  51. /* control data pad skew - devaddr = 0x02, register = 0x04 */
  52. ksz9031_phy_extended_write(phydev, 0x02,
  53. MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
  54. MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
  55. /* rx data pad skew - devaddr = 0x02, register = 0x05 */
  56. ksz9031_phy_extended_write(phydev, 0x02,
  57. MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
  58. MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
  59. /* tx data pad skew - devaddr = 0x02, register = 0x06 */
  60. ksz9031_phy_extended_write(phydev, 0x02,
  61. MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
  62. MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x0000);
  63. /* gtx and rx clock pad skew - devaddr = 0x02, register = 0x08 */
  64. ksz9031_phy_extended_write(phydev, 0x02,
  65. MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
  66. MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x03FF);
  67. if (phydev->drv->config)
  68. phydev->drv->config(phydev);
  69. return 0;
  70. }
  71. static int rotate_logo_one(unsigned char *out, unsigned char *in)
  72. {
  73. int i, j;
  74. for (i = 0; i < BMP_LOGO_WIDTH; i++)
  75. for (j = 0; j < BMP_LOGO_HEIGHT; j++)
  76. out[j * BMP_LOGO_WIDTH + BMP_LOGO_HEIGHT - 1 - i] =
  77. in[i * BMP_LOGO_WIDTH + j];
  78. return 0;
  79. }
  80. /*
  81. * Rotate the BMP_LOGO (only)
  82. * Will only work, if the logo is square, as
  83. * BMP_LOGO_HEIGHT and BMP_LOGO_WIDTH are defines, not variables
  84. */
  85. void rotate_logo(int rotations)
  86. {
  87. unsigned char out_logo[BMP_LOGO_WIDTH * BMP_LOGO_HEIGHT];
  88. struct bmp_header *header;
  89. unsigned char *in_logo;
  90. int i, j;
  91. if (BMP_LOGO_WIDTH != BMP_LOGO_HEIGHT)
  92. return;
  93. header = (struct bmp_header *)bmp_logo_bitmap;
  94. in_logo = bmp_logo_bitmap + header->data_offset;
  95. /* one 90 degree rotation */
  96. if (rotations == 1 || rotations == 2 || rotations == 3)
  97. rotate_logo_one(out_logo, in_logo);
  98. /* second 90 degree rotation */
  99. if (rotations == 2 || rotations == 3)
  100. rotate_logo_one(in_logo, out_logo);
  101. /* third 90 degree rotation */
  102. if (rotations == 3)
  103. rotate_logo_one(out_logo, in_logo);
  104. /* copy result back to original array */
  105. if (rotations == 1 || rotations == 3)
  106. for (i = 0; i < BMP_LOGO_WIDTH; i++)
  107. for (j = 0; j < BMP_LOGO_HEIGHT; j++)
  108. in_logo[i * BMP_LOGO_WIDTH + j] =
  109. out_logo[i * BMP_LOGO_WIDTH + j];
  110. }
  111. static void enable_lvds(struct display_info_t const *dev)
  112. {
  113. struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
  114. struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  115. int reg;
  116. s32 timeout = 100000;
  117. /* set PLL5 clock */
  118. reg = readl(&ccm->analog_pll_video);
  119. reg |= BM_ANADIG_PLL_VIDEO_POWERDOWN;
  120. writel(reg, &ccm->analog_pll_video);
  121. /* set PLL5 to 232720000Hz */
  122. reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT;
  123. reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(0x26);
  124. reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
  125. reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0);
  126. writel(reg, &ccm->analog_pll_video);
  127. writel(BF_ANADIG_PLL_VIDEO_NUM_A(0xC0238),
  128. &ccm->analog_pll_video_num);
  129. writel(BF_ANADIG_PLL_VIDEO_DENOM_B(0xF4240),
  130. &ccm->analog_pll_video_denom);
  131. reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN;
  132. writel(reg, &ccm->analog_pll_video);
  133. while (timeout--)
  134. if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
  135. break;
  136. if (timeout < 0)
  137. printf("Warning: video pll lock timeout!\n");
  138. reg = readl(&ccm->analog_pll_video);
  139. reg |= BM_ANADIG_PLL_VIDEO_ENABLE;
  140. reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS;
  141. writel(reg, &ccm->analog_pll_video);
  142. /* set LDB0, LDB1 clk select to 000/000 (PLL5 clock) */
  143. reg = readl(&ccm->cs2cdr);
  144. reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
  145. | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
  146. reg |= (0 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
  147. | (0 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
  148. writel(reg, &ccm->cs2cdr);
  149. reg = readl(&ccm->cscmr2);
  150. reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
  151. writel(reg, &ccm->cscmr2);
  152. reg = readl(&ccm->chsccdr);
  153. reg |= (CHSCCDR_CLK_SEL_LDB_DI0
  154. << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
  155. writel(reg, &ccm->chsccdr);
  156. reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
  157. | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
  158. | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH
  159. | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
  160. | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
  161. | IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
  162. | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
  163. writel(reg, &iomux->gpr[2]);
  164. reg = readl(&iomux->gpr[3]);
  165. reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
  166. | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
  167. << IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
  168. writel(reg, &iomux->gpr[3]);
  169. }
  170. static void setup_display(void)
  171. {
  172. enable_ipu_clock();
  173. }
  174. static void set_gpr_register(void)
  175. {
  176. struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
  177. writel(IOMUXC_GPR1_APP_CLK_REQ_N | IOMUXC_GPR1_PCIE_RDY_L23 |
  178. IOMUXC_GPR1_EXC_MON_SLVE |
  179. (2 << IOMUXC_GPR1_ADDRS0_OFFSET) |
  180. IOMUXC_GPR1_ACT_CS0,
  181. &iomuxc_regs->gpr[1]);
  182. writel(0x0, &iomuxc_regs->gpr[8]);
  183. writel(IOMUXC_GPR12_ARMP_IPG_CLK_EN | IOMUXC_GPR12_ARMP_AHB_CLK_EN |
  184. IOMUXC_GPR12_ARMP_ATB_CLK_EN | IOMUXC_GPR12_ARMP_APB_CLK_EN,
  185. &iomuxc_regs->gpr[12]);
  186. }
  187. extern char __bss_start[], __bss_end[];
  188. int board_early_init_f(void)
  189. {
  190. select_ldb_di_clock_source(MXC_PLL5_CLK);
  191. set_gpr_register();
  192. /*
  193. * clear bss here, so we can use spi driver
  194. * before relocation and read Environment
  195. * from spi flash.
  196. */
  197. memset(__bss_start, 0x00, __bss_end - __bss_start);
  198. return 0;
  199. }
  200. static void setup_one_led(char *label, int state)
  201. {
  202. struct udevice *dev;
  203. int ret;
  204. ret = led_get_by_label(label, &dev);
  205. if (ret == 0)
  206. led_set_state(dev, state);
  207. }
  208. static void setup_board_gpio(void)
  209. {
  210. setup_one_led("led_ena", LEDST_ON);
  211. /* switch off Status LEDs */
  212. setup_one_led("led_yellow", LEDST_OFF);
  213. setup_one_led("led_red", LEDST_OFF);
  214. setup_one_led("led_green", LEDST_OFF);
  215. setup_one_led("led_blue", LEDST_OFF);
  216. }
  217. static void aristainetos_run_rescue_command(int reason)
  218. {
  219. char rescue_reason_command[20];
  220. sprintf(rescue_reason_command, "setenv rreason %d", reason);
  221. run_command(rescue_reason_command, 0);
  222. }
  223. static int aristainetos_bootmode_settings(void)
  224. {
  225. struct gpio_desc *desc;
  226. struct src *psrc = (struct src *)SRC_BASE_ADDR;
  227. unsigned int sbmr1 = readl(&psrc->sbmr1);
  228. char *my_bootdelay;
  229. char bootmode = 0;
  230. int ret;
  231. struct udevice *dev;
  232. int off;
  233. u8 data[0x10];
  234. u8 rescue_reason;
  235. /* jumper controlled reset of the environment */
  236. ret = gpio_hog_lookup_name("env_reset", &desc);
  237. if (!ret) {
  238. if (dm_gpio_get_value(desc)) {
  239. printf("\nReset u-boot environment (jumper)\n");
  240. run_command("run default_env; saveenv; saveenv", 0);
  241. }
  242. }
  243. off = fdt_path_offset(gd->fdt_blob, "eeprom0");
  244. if (off < 0) {
  245. printf("%s: No eeprom0 path offset\n", __func__);
  246. return off;
  247. }
  248. ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, off, &dev);
  249. if (ret) {
  250. printf("%s: Could not find EEPROM\n", __func__);
  251. return ret;
  252. }
  253. ret = i2c_set_chip_offset_len(dev, 2);
  254. if (ret)
  255. return ret;
  256. ret = i2c_eeprom_read(dev, 0x1ff0, (uint8_t *)data, sizeof(data));
  257. if (ret) {
  258. printf("%s: Could not read EEPROM\n", __func__);
  259. return ret;
  260. }
  261. /* software controlled reset of the environment (EEPROM magic) */
  262. if (strncmp((char *)data, "DeF", 3) == 0) {
  263. memset(data, 0xff, 3);
  264. i2c_eeprom_write(dev, 0x1ff0, (uint8_t *)data, 3);
  265. printf("\nReset u-boot environment (EEPROM)\n");
  266. run_command("run default_env; saveenv; saveenv", 0);
  267. }
  268. if (sbmr1 & 0x40) {
  269. env_set("bootmode", "1");
  270. printf("SD bootmode jumper set!\n");
  271. } else {
  272. env_set("bootmode", "0");
  273. }
  274. /*
  275. * Check the boot-source. If booting from NOR Flash,
  276. * disable bootdelay
  277. */
  278. ret = gpio_hog_lookup_name("bootsel0", &desc);
  279. if (!ret)
  280. bootmode |= (dm_gpio_get_value(desc) ? 1 : 0) << 0;
  281. ret = gpio_hog_lookup_name("bootsel1", &desc);
  282. if (!ret)
  283. bootmode |= (dm_gpio_get_value(desc) ? 1 : 0) << 1;
  284. ret = gpio_hog_lookup_name("bootsel2", &desc);
  285. if (!ret)
  286. bootmode |= (dm_gpio_get_value(desc) ? 1 : 0) << 2;
  287. if (bootmode == 7) {
  288. my_bootdelay = env_get("nor_bootdelay");
  289. if (my_bootdelay)
  290. env_set("bootdelay", my_bootdelay);
  291. else
  292. env_set("bootdelay", "-2");
  293. }
  294. /* jumper controlled boot of the rescue system */
  295. ret = gpio_hog_lookup_name("boot_rescue", &desc);
  296. if (!ret) {
  297. if (dm_gpio_get_value(desc)) {
  298. printf("\nBooting into Rescue System (jumper)\n");
  299. aristainetos_run_rescue_command(16);
  300. run_command("run rescue_xload_boot", 0);
  301. }
  302. }
  303. /* software controlled boot of the rescue system (EEPROM magic) */
  304. if (strncmp((char *)&data[3], "ReScUe", 6) == 0) {
  305. rescue_reason = *(uint8_t *)&data[9];
  306. memset(&data[3], 0xff, 7);
  307. i2c_eeprom_write(dev, 0x1ff0, (uint8_t *)&data[3], 7);
  308. printf("\nBooting into Rescue System (EEPROM)\n");
  309. aristainetos_run_rescue_command(rescue_reason);
  310. run_command("run rescue_xload_boot", 0);
  311. }
  312. return 0;
  313. }
  314. #if defined(CONFIG_DM_PMIC_DA9063)
  315. /*
  316. * On the aristainetos2c boards the PMIC needs to be initialized,
  317. * because the Ethernet PHY uses a different regulator that is not
  318. * setup per hardware default. This does not influence the other versions
  319. * as this regulator isn't used there at all.
  320. *
  321. * Unfortunately we have not yet a interface to setup all
  322. * values we need.
  323. */
  324. static int setup_pmic_voltages(void)
  325. {
  326. struct udevice *dev;
  327. int off;
  328. int ret;
  329. off = fdt_path_offset(gd->fdt_blob, "pmic0");
  330. if (off < 0) {
  331. printf("%s: No pmic path offset\n", __func__);
  332. return off;
  333. }
  334. ret = uclass_get_device_by_of_offset(UCLASS_PMIC, off, &dev);
  335. if (ret) {
  336. printf("%s: Could not find PMIC\n", __func__);
  337. return ret;
  338. }
  339. pmic_reg_write(dev, DA9063_REG_PAGE_CON, 0x01);
  340. pmic_reg_write(dev, DA9063_REG_BPRO_CFG, 0xc1);
  341. ret = pmic_reg_read(dev, DA9063_REG_BUCK_ILIM_B);
  342. if (ret < 0) {
  343. printf("%s: error %d get register\n", __func__, ret);
  344. return ret;
  345. }
  346. ret &= 0xf0;
  347. ret |= 0x09;
  348. pmic_reg_write(dev, DA9063_REG_BUCK_ILIM_B, ret);
  349. pmic_reg_write(dev, DA9063_REG_VBPRO_A, 0x43);
  350. pmic_reg_write(dev, DA9063_REG_VBPRO_B, 0xc3);
  351. return 0;
  352. }
  353. #else
  354. static int setup_pmic_voltages(void)
  355. {
  356. return 0;
  357. }
  358. #endif
  359. int board_late_init(void)
  360. {
  361. int x, y;
  362. int ret;
  363. led_default_state();
  364. splash_get_pos(&x, &y);
  365. bmp_display((ulong)&bmp_logo_bitmap[0], x, y);
  366. ret = aristainetos_bootmode_settings();
  367. if (ret)
  368. return ret;
  369. /* set board_type */
  370. if (gd->board_type == BOARD_TYPE_4)
  371. env_set("board_type", ARI_BT_4);
  372. else
  373. env_set("board_type", ARI_BT_7);
  374. if (setup_pmic_voltages())
  375. printf("Error setup PMIC\n");
  376. return 0;
  377. }
  378. int dram_init(void)
  379. {
  380. gd->ram_size = imx_ddr_size();
  381. return 0;
  382. }
  383. struct display_info_t const displays[] = {
  384. {
  385. .bus = -1,
  386. .addr = 0,
  387. .pixfmt = IPU_PIX_FMT_RGB24,
  388. .detect = NULL,
  389. .enable = enable_lvds,
  390. .mode = {
  391. .name = "lb07wv8",
  392. .refresh = 60,
  393. .xres = 800,
  394. .yres = 480,
  395. .pixclock = 30066,
  396. .left_margin = 88,
  397. .right_margin = 88,
  398. .upper_margin = 20,
  399. .lower_margin = 20,
  400. .hsync_len = 80,
  401. .vsync_len = 5,
  402. .sync = FB_SYNC_EXT,
  403. .vmode = FB_VMODE_NONINTERLACED
  404. }
  405. }
  406. };
  407. size_t display_count = ARRAY_SIZE(displays);
  408. int board_init(void)
  409. {
  410. struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
  411. /* address of boot parameters */
  412. gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  413. setup_board_gpio();
  414. setup_display();
  415. /* GPIO_1 for USB_OTG_ID */
  416. clrsetbits_le32(&iomux->gpr[1], IOMUXC_GPR1_USB_OTG_ID_SEL_MASK, 0);
  417. return 0;
  418. }
  419. int board_fit_config_name_match(const char *name)
  420. {
  421. if (gd->board_type == BOARD_TYPE_4 &&
  422. strchr(name, 0x34))
  423. return 0;
  424. if (gd->board_type == BOARD_TYPE_7 &&
  425. strchr(name, 0x37))
  426. return 0;
  427. return -1;
  428. }
  429. static void do_board_detect(void)
  430. {
  431. int ret;
  432. char s[30];
  433. /* default use board type 7 */
  434. gd->board_type = BOARD_TYPE_7;
  435. if (env_init())
  436. return;
  437. ret = env_get_f("panel", s, sizeof(s));
  438. if (ret < 0)
  439. return;
  440. if (!strncmp("lg4573", s, 6))
  441. gd->board_type = BOARD_TYPE_4;
  442. }
  443. #ifdef CONFIG_DTB_RESELECT
  444. int embedded_dtb_select(void)
  445. {
  446. int rescan;
  447. do_board_detect();
  448. fdtdec_resetup(&rescan);
  449. return 0;
  450. }
  451. #endif
  452. enum env_location env_get_location(enum env_operation op, int prio)
  453. {
  454. if (op == ENVOP_SAVE || op == ENVOP_ERASE)
  455. return ENVL_SPI_FLASH;
  456. switch (prio) {
  457. case 0:
  458. return ENVL_NOWHERE;
  459. case 1:
  460. return ENVL_SPI_FLASH;
  461. default:
  462. return ENVL_UNKNOWN;
  463. }
  464. return ENVL_UNKNOWN;
  465. }