board.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2016 Amarula Solutions B.V.
  4. * Copyright (C) 2016 Engicam S.r.l.
  5. * Author: Jagan Teki <jagan@amarulasolutions.com>
  6. */
  7. #include <common.h>
  8. #include <command.h>
  9. #include <env.h>
  10. #include <hang.h>
  11. #include <init.h>
  12. #include <log.h>
  13. #include <mmc.h>
  14. #include <asm/arch/clock.h>
  15. #include <asm/arch/imx-regs.h>
  16. #include <asm/arch/sys_proto.h>
  17. #include <watchdog.h>
  18. #include "board.h"
  19. DECLARE_GLOBAL_DATA_PTR;
  20. #ifdef CONFIG_ENV_IS_IN_MMC
  21. static void mmc_late_init(void)
  22. {
  23. char cmd[32];
  24. char mmcblk[32];
  25. u32 dev_no = mmc_get_env_dev();
  26. env_set_ulong("mmcdev", dev_no);
  27. /* Set mmcblk env */
  28. sprintf(mmcblk, "/dev/mmcblk%dp2 rootwait rw", dev_no);
  29. env_set("mmcroot", mmcblk);
  30. sprintf(cmd, "mmc dev %d", dev_no);
  31. run_command(cmd, 0);
  32. }
  33. #endif
  34. enum engicam_boards {
  35. IMX6Q_ICORE,
  36. IMX6DL_ICORE,
  37. IMX6Q_ICORE_MIPI,
  38. IMX6DL_ICORE_MIPI,
  39. IMX6Q_ICORE_RQS,
  40. IMX6DL_ICORE_RQS,
  41. IMX6UL_GEAM,
  42. IMX6UL_ISIOT_EMMC,
  43. IMX6UL_ISIOT_NAND,
  44. ENGICAM_BOARDS,
  45. };
  46. static const char * const board_fdt_file[ENGICAM_BOARDS] = {
  47. [IMX6Q_ICORE] = "imx6q-icore.dtb",
  48. [IMX6DL_ICORE] = "imx6dl-icore.dtb",
  49. [IMX6Q_ICORE_MIPI] = "imx6q-icore-mipi.dtb",
  50. [IMX6DL_ICORE_MIPI] = "imx6dl-icore-mipi.dtb",
  51. [IMX6Q_ICORE_RQS] = "imx6q-icore-rqs.dtb",
  52. [IMX6DL_ICORE_RQS] = "imx6dl-icore-rqs.dtb",
  53. [IMX6UL_GEAM] = "imx6ul-geam.dtb",
  54. [IMX6UL_ISIOT_EMMC] = "imx6ul-isiot-emmc.dtb",
  55. [IMX6UL_ISIOT_NAND] = "imx6ul-isiot-nand.dtb",
  56. };
  57. static int setenv_fdt_file(int board_detected)
  58. {
  59. if (board_detected < 0 || board_detected >= ENGICAM_BOARDS)
  60. return -EINVAL;
  61. if (!board_fdt_file[board_detected])
  62. return -ENODEV;
  63. env_set("fdt_file", board_fdt_file[board_detected]);
  64. return 0;
  65. }
  66. static enum engicam_boards engicam_board_detect(void)
  67. {
  68. const char *cmp_dtb = CONFIG_DEFAULT_DEVICE_TREE;
  69. if (!strcmp(cmp_dtb, "imx6q-icore")) {
  70. if (is_mx6dq())
  71. return IMX6Q_ICORE;
  72. else if (is_mx6dl() || is_mx6solo())
  73. return IMX6DL_ICORE;
  74. } else if (!strcmp(cmp_dtb, "imx6q-icore-mipi")) {
  75. if (is_mx6dq())
  76. return IMX6Q_ICORE_MIPI;
  77. else if (is_mx6dl() || is_mx6solo())
  78. return IMX6DL_ICORE_MIPI;
  79. } else if (!strcmp(cmp_dtb, "imx6q-icore-rqs")) {
  80. if (is_mx6dq())
  81. return IMX6Q_ICORE_RQS;
  82. else if (is_mx6dl() || is_mx6solo())
  83. return IMX6DL_ICORE_RQS;
  84. } else if (!strcmp(cmp_dtb, "imx6ul-geam"))
  85. return IMX6UL_GEAM;
  86. else if (!strcmp(cmp_dtb, "imx6ul-isiot-emmc"))
  87. return IMX6UL_ISIOT_EMMC;
  88. else if (!strcmp(cmp_dtb, "imx6ul-isiot-nand"))
  89. return IMX6UL_ISIOT_NAND;
  90. return -EINVAL;
  91. }
  92. static int fixup_enet_clock(enum engicam_boards board_detected)
  93. {
  94. struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
  95. int clk_internal = 0;
  96. switch (board_detected) {
  97. case IMX6Q_ICORE_MIPI:
  98. case IMX6DL_ICORE_MIPI:
  99. clk_internal = 1;
  100. break;
  101. default:
  102. break;
  103. }
  104. /* set gpr1[21] to select anatop clock */
  105. debug("fixup_enet_clock %d\n", clk_internal);
  106. clrsetbits_le32(&iomuxc_regs->gpr[1], 0x1 << 21, clk_internal << 21);
  107. if (!clk_internal) {
  108. /* clock is external */
  109. return 0;
  110. }
  111. return enable_fec_anatop_clock(0, ENET_50MHZ);
  112. }
  113. int board_late_init(void)
  114. {
  115. enum engicam_boards board_detected = IMX6Q_ICORE;
  116. switch ((imx6_src_get_boot_mode() & IMX6_BMODE_MASK) >>
  117. IMX6_BMODE_SHIFT) {
  118. case IMX6_BMODE_SD:
  119. case IMX6_BMODE_ESD:
  120. case IMX6_BMODE_MMC:
  121. case IMX6_BMODE_EMMC:
  122. #ifdef CONFIG_ENV_IS_IN_MMC
  123. mmc_late_init();
  124. #endif
  125. env_set("modeboot", "mmcboot");
  126. break;
  127. case IMX6_BMODE_NAND_MIN ... IMX6_BMODE_NAND_MAX:
  128. env_set("modeboot", "nandboot");
  129. break;
  130. default:
  131. env_set("modeboot", "");
  132. break;
  133. }
  134. if (is_mx6ul())
  135. env_set("console", "ttymxc0");
  136. else
  137. env_set("console", "ttymxc3");
  138. board_detected = engicam_board_detect();
  139. if (board_detected < 0)
  140. hang();
  141. fixup_enet_clock(board_detected);
  142. setenv_fdt_file(board_detected);
  143. #ifdef CONFIG_HW_WATCHDOG
  144. hw_watchdog_init();
  145. #endif
  146. return 0;
  147. }
  148. int board_init(void)
  149. {
  150. /* Address of boot parameters */
  151. gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  152. #ifdef CONFIG_NAND_MXS
  153. setup_gpmi_nand();
  154. #endif
  155. #ifdef CONFIG_VIDEO_IPUV3
  156. setup_display();
  157. #endif
  158. return 0;
  159. }
  160. int dram_init(void)
  161. {
  162. gd->ram_size = imx_ddr_size();
  163. return 0;
  164. }