cgtqmx8.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2018 congatec AG
  4. * Copyright (C) 2019 Oliver Graute <oliver.graute@kococonnector.com>
  5. */
  6. #include <common.h>
  7. #include <errno.h>
  8. #include <linux/libfdt.h>
  9. #include <fsl_esdhc.h>
  10. #include <init.h>
  11. #include <asm/io.h>
  12. #include <asm/gpio.h>
  13. #include <asm/arch/clock.h>
  14. #include <asm/arch/sci/sci.h>
  15. #include <asm/arch/imx8-pins.h>
  16. #include <usb.h>
  17. #include <asm/arch/iomux.h>
  18. #include <asm/arch/sys_proto.h>
  19. #include <linux/delay.h>
  20. #include <power-domain.h>
  21. DECLARE_GLOBAL_DATA_PTR;
  22. #define ESDHC_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \
  23. (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
  24. (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \
  25. (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
  26. #define ESDHC_CLK_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \
  27. (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
  28. (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \
  29. (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
  30. #define ENET_INPUT_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | \
  31. (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
  32. (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | \
  33. (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
  34. #define ENET_NORMAL_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \
  35. (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
  36. (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | \
  37. (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
  38. #define FSPI_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \
  39. (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
  40. (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \
  41. (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
  42. #define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \
  43. (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
  44. (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \
  45. (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
  46. #define I2C_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \
  47. (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
  48. (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \
  49. (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
  50. #define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \
  51. (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
  52. (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \
  53. (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
  54. static iomux_cfg_t uart0_pads[] = {
  55. SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
  56. SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
  57. };
  58. void board_late_mmc_env_init(void);
  59. void init_clk_usdhc(u32 index);
  60. int fsl_esdhc_initialize(struct bd_info *bis, struct fsl_esdhc_cfg *cfg);
  61. static void setup_iomux_uart(void)
  62. {
  63. imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads));
  64. }
  65. int board_early_init_f(void)
  66. {
  67. /* sc_ipc_t ipcHndl = 0; */
  68. sc_err_t scierr = 0;
  69. /* When start u-boot in XEN VM, directly return */
  70. /* if (IS_ENABLED(CONFIG_XEN)) */
  71. /* return 0; */
  72. /* ipcHndl = gd->arch.ipc_channel_handle; */
  73. /* Power up UART0, this is very early while power domain is not working */
  74. scierr = sc_pm_set_resource_power_mode(-1, SC_R_UART_0, SC_PM_PW_MODE_ON);
  75. if (scierr != SC_ERR_NONE)
  76. return 0;
  77. /* Set UART0 clock root to 80 MHz */
  78. sc_pm_clock_rate_t rate = 80000000;
  79. scierr = sc_pm_set_clock_rate(-1, SC_R_UART_0, 2, &rate);
  80. if (scierr != SC_ERR_NONE)
  81. return 0;
  82. /* Enable UART0 clock root */
  83. scierr = sc_pm_clock_enable(-1, SC_R_UART_0, 2, true, false);
  84. if (scierr != SC_ERR_NONE)
  85. return 0;
  86. setup_iomux_uart();
  87. return 0;
  88. }
  89. #if IS_ENABLED(CONFIG_FSL_ESDHC_IMX)
  90. #define USDHC1_CD_GPIO IMX_GPIO_NR(5, 22)
  91. #define USDHC2_CD_GPIO IMX_GPIO_NR(4, 12)
  92. static struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = {
  93. {USDHC1_BASE_ADDR, 0, 8},
  94. {USDHC2_BASE_ADDR, 0, 4},
  95. {USDHC3_BASE_ADDR, 0, 4},
  96. };
  97. static iomux_cfg_t emmc0[] = {
  98. SC_P_EMMC0_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL),
  99. SC_P_EMMC0_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  100. SC_P_EMMC0_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  101. SC_P_EMMC0_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  102. SC_P_EMMC0_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  103. SC_P_EMMC0_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  104. SC_P_EMMC0_DATA4 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  105. SC_P_EMMC0_DATA5 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  106. SC_P_EMMC0_DATA6 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  107. SC_P_EMMC0_DATA7 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  108. SC_P_EMMC0_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  109. SC_P_EMMC0_STROBE | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  110. };
  111. static iomux_cfg_t usdhc1_sd[] = {
  112. SC_P_USDHC1_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL),
  113. SC_P_USDHC1_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  114. SC_P_USDHC1_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  115. SC_P_USDHC1_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  116. SC_P_USDHC1_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  117. SC_P_USDHC1_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  118. SC_P_USDHC1_DATA6 | MUX_MODE_ALT(2) | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  119. SC_P_USDHC1_DATA7 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  120. SC_P_USDHC1_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  121. SC_P_USDHC1_VSELECT | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  122. };
  123. static iomux_cfg_t usdhc2_sd[] = {
  124. SC_P_USDHC2_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL),
  125. SC_P_USDHC2_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  126. SC_P_USDHC2_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  127. SC_P_USDHC2_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  128. SC_P_USDHC2_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  129. SC_P_USDHC2_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  130. SC_P_USDHC2_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  131. SC_P_USDHC2_VSELECT | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  132. SC_P_USDHC2_WP | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  133. SC_P_USDHC2_CD_B | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ESDHC_PAD_CTRL),
  134. };
  135. int board_mmc_init(struct bd_info *bis)
  136. {
  137. int i, ret;
  138. struct power_domain pd;
  139. /*
  140. * According to the board_mmc_init() the following map is done:
  141. * (U-Boot device node) (Physical Port)
  142. * mmc0 (onboard eMMC) USDHC1
  143. * mmc1 (external SD card) USDHC2
  144. * mmc2 (onboard µSD) USDHC3
  145. */
  146. for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
  147. switch (i) {
  148. case 0:
  149. /* onboard eMMC */
  150. if (!imx8_power_domain_lookup_name("conn_sdhc0", &pd))
  151. power_domain_on(&pd);
  152. imx8_iomux_setup_multiple_pads(emmc0, ARRAY_SIZE(emmc0));
  153. init_clk_usdhc(0);
  154. usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
  155. break;
  156. case 1:
  157. /* external SD card */
  158. if (!imx8_power_domain_lookup_name("conn_sdhc1", &pd))
  159. power_domain_on(&pd);
  160. imx8_iomux_setup_multiple_pads(usdhc1_sd, ARRAY_SIZE(usdhc1_sd));
  161. init_clk_usdhc(1);
  162. usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
  163. gpio_request(USDHC1_CD_GPIO, "sd1_cd");
  164. gpio_direction_input(USDHC1_CD_GPIO);
  165. break;
  166. case 2:
  167. /* onboard µSD */
  168. if (!imx8_power_domain_lookup_name("conn_sdhc2", &pd))
  169. power_domain_on(&pd);
  170. imx8_iomux_setup_multiple_pads(usdhc2_sd, ARRAY_SIZE(usdhc2_sd));
  171. init_clk_usdhc(2);
  172. usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
  173. gpio_request(USDHC2_CD_GPIO, "sd2_cd");
  174. gpio_direction_input(USDHC2_CD_GPIO);
  175. break;
  176. default:
  177. printf("Warning: you configured more USDHC controllers"
  178. "(%d) than supported by the board\n", i + 1);
  179. return 0;
  180. }
  181. ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
  182. if (ret) {
  183. printf("Warning: failed to initialize mmc dev %d\n", i);
  184. return ret;
  185. }
  186. }
  187. return 0;
  188. }
  189. int board_mmc_getcd(struct mmc *mmc)
  190. {
  191. struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
  192. int ret = 0;
  193. switch (cfg->esdhc_base) {
  194. case USDHC1_BASE_ADDR:
  195. ret = 1;
  196. break;
  197. case USDHC2_BASE_ADDR:
  198. ret = !gpio_get_value(USDHC1_CD_GPIO);
  199. break;
  200. case USDHC3_BASE_ADDR:
  201. ret = !gpio_get_value(USDHC2_CD_GPIO);
  202. break;
  203. }
  204. return ret;
  205. }
  206. #endif /* CONFIG_FSL_ESDHC_IMX */
  207. #if (IS_ENABLED(CONFIG_FEC_MXC))
  208. #include <miiphy.h>
  209. static iomux_cfg_t pad_enet0[] = {
  210. SC_P_ENET0_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
  211. SC_P_ENET0_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
  212. SC_P_ENET0_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
  213. SC_P_ENET0_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
  214. SC_P_ENET0_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
  215. SC_P_ENET0_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL),
  216. SC_P_ENET0_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
  217. SC_P_ENET0_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
  218. SC_P_ENET0_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
  219. SC_P_ENET0_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
  220. SC_P_ENET0_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
  221. SC_P_ENET0_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
  222. SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
  223. SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL),
  224. };
  225. static void setup_iomux_fec(void)
  226. {
  227. imx8_iomux_setup_multiple_pads(pad_enet0, ARRAY_SIZE(pad_enet0));
  228. }
  229. static void enet_device_phy_reset(void)
  230. {
  231. gpio_set_value(FEC0_RESET, 0);
  232. udelay(50);
  233. gpio_set_value(FEC0_RESET, 1);
  234. /* The board has a long delay for this reset to become stable */
  235. mdelay(200);
  236. }
  237. int board_eth_init(struct bd_info *bis)
  238. {
  239. setup_iomux_fec();
  240. return 0;
  241. }
  242. int board_phy_config(struct phy_device *phydev)
  243. {
  244. phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
  245. phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
  246. phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00);
  247. phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee);
  248. phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
  249. phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
  250. if (phydev->drv->config)
  251. phydev->drv->config(phydev);
  252. return 0;
  253. }
  254. static int setup_fec(void)
  255. {
  256. /* Reset ENET PHY */
  257. enet_device_phy_reset();
  258. return 0;
  259. }
  260. #endif
  261. #ifdef CONFIG_MXC_GPIO
  262. #define LVDS_ENABLE IMX_GPIO_NR(1, 6)
  263. #define BKL_ENABLE IMX_GPIO_NR(1, 7)
  264. static iomux_cfg_t board_gpios[] = {
  265. SC_P_LVDS0_I2C0_SCL | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL),
  266. SC_P_LVDS0_I2C0_SDA | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL),
  267. SC_P_ESAI1_FST | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL),
  268. };
  269. static void board_gpio_init(void)
  270. {
  271. imx8_iomux_setup_multiple_pads(board_gpios, ARRAY_SIZE(board_gpios));
  272. /* enable LVDS */
  273. gpio_request(LVDS_ENABLE, "lvds_enable");
  274. gpio_direction_output(LVDS_ENABLE, 1);
  275. /* enable backlight */
  276. gpio_request(BKL_ENABLE, "bkl_enable");
  277. gpio_direction_output(BKL_ENABLE, 1);
  278. /* ethernet reset */
  279. gpio_request(FEC0_RESET, "enet0_reset");
  280. gpio_direction_output(FEC0_RESET, 1);
  281. }
  282. #endif
  283. int checkboard(void)
  284. {
  285. puts("Board: conga-QMX8\n");
  286. build_info();
  287. print_bootinfo();
  288. return 0;
  289. }
  290. int board_init(void)
  291. {
  292. if (IS_ENABLED(CONFIG_XEN))
  293. return 0;
  294. #ifdef CONFIG_MXC_GPIO
  295. board_gpio_init();
  296. #endif
  297. #if (IS_ENABLED(CONFIG_FEC_MXC))
  298. setup_fec();
  299. #endif
  300. return 0;
  301. }
  302. void detail_board_ddr_info(void)
  303. {
  304. puts("\nDDR ");
  305. }
  306. /*
  307. * Board specific reset that is system reset.
  308. */
  309. void reset_cpu(ulong addr)
  310. {
  311. /* TODO */
  312. }
  313. #ifdef CONFIG_OF_BOARD_SETUP
  314. int ft_board_setup(void *blob, struct bd_info *bd)
  315. {
  316. return 0;
  317. }
  318. #endif
  319. int board_mmc_get_env_dev(int devno)
  320. {
  321. /* Use EMMC */
  322. if (IS_ENABLED(CONFIG_XEN))
  323. return 0;
  324. return devno;
  325. }
  326. int mmc_map_to_kernel_blk(int dev_no)
  327. {
  328. /* Use EMMC */
  329. if (IS_ENABLED(CONFIG_XEN))
  330. return 0;
  331. return dev_no;
  332. }
  333. extern u32 _end_ofs;
  334. int board_late_init(void)
  335. {
  336. #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
  337. env_set("board_name", "QMX8");
  338. env_set("board_rev", "iMX8QM");
  339. #endif
  340. env_set("sec_boot", "no");
  341. #ifdef CONFIG_AHAB_BOOT
  342. env_set("sec_boot", "yes");
  343. #endif
  344. #ifdef CONFIG_ENV_IS_IN_MMC
  345. board_late_mmc_env_init();
  346. #endif
  347. #ifdef IMX_LOAD_HDMI_FIMRWARE
  348. char *end_of_uboot;
  349. char command[256];
  350. end_of_uboot = (char *)(ulong)(CONFIG_SYS_TEXT_BASE + _end_ofs
  351. + fdt_totalsize(gd->fdt_blob));
  352. end_of_uboot += 9;
  353. /* load hdmitxfw.bin and hdmirxfw.bin*/
  354. memcpy(IMX_HDMI_FIRMWARE_LOAD_ADDR, end_of_uboot,
  355. IMX_HDMITX_FIRMWARE_SIZE + IMX_HDMIRX_FIRMWARE_SIZE);
  356. sprintf(command, "hdp load 0x%x", IMX_HDMI_FIRMWARE_LOAD_ADDR);
  357. run_command(command, 0);
  358. sprintf(command, "hdprx load 0x%x",
  359. IMX_HDMI_FIRMWARE_LOAD_ADDR + IMX_HDMITX_FIRMWARE_SIZE);
  360. run_command(command, 0);
  361. #endif
  362. return 0;
  363. }
  364. #ifdef CONFIG_FSL_FASTBOOT
  365. #ifdef CONFIG_ANDROID_RECOVERY
  366. int is_recovery_key_pressing(void)
  367. {
  368. return 0; /*TODO*/
  369. }
  370. #endif /*CONFIG_ANDROID_RECOVERY*/
  371. #endif /*CONFIG_FSL_FASTBOOT*/
  372. /* Only Enable USB3 resources currently */
  373. int board_usb_init(int index, enum usb_init_type init)
  374. {
  375. return 0;
  376. }