apalis_imx6.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
  4. * Copyright (C) 2013, Boundary Devices <info@boundarydevices.com>
  5. * Copyright (C) 2014-2019, Toradex AG
  6. * copied from nitrogen6x
  7. */
  8. #include <common.h>
  9. #include <cpu_func.h>
  10. #include <dm.h>
  11. #include <image.h>
  12. #include <init.h>
  13. #include <net.h>
  14. #include <linux/bitops.h>
  15. #include <linux/delay.h>
  16. #include <ahci.h>
  17. #include <asm/arch/clock.h>
  18. #include <asm/arch/crm_regs.h>
  19. #include <asm/arch/imx-regs.h>
  20. #include <asm/arch/mx6-ddr.h>
  21. #include <asm/arch/mx6-pins.h>
  22. #include <asm/arch/mxc_hdmi.h>
  23. #include <asm/arch/sys_proto.h>
  24. #include <asm/bootm.h>
  25. #include <asm/gpio.h>
  26. #include <asm/mach-imx/boot_mode.h>
  27. #include <asm/mach-imx/iomux-v3.h>
  28. #include <asm/mach-imx/sata.h>
  29. #include <asm/mach-imx/video.h>
  30. #include <dm/device-internal.h>
  31. #include <dm/platform_data/serial_mxc.h>
  32. #include <dwc_ahsata.h>
  33. #include <env.h>
  34. #include <fsl_esdhc_imx.h>
  35. #include <imx_thermal.h>
  36. #include <micrel.h>
  37. #include <miiphy.h>
  38. #include <netdev.h>
  39. #include "../common/tdx-cfg-block.h"
  40. #ifdef CONFIG_TDX_CMD_IMX_MFGR
  41. #include "pf0100.h"
  42. #endif
  43. DECLARE_GLOBAL_DATA_PTR;
  44. #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
  45. PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
  46. PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  47. #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \
  48. PAD_CTL_SPEED_LOW | PAD_CTL_DSE_40ohm | \
  49. PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  50. #define USDHC_EMMC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \
  51. PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
  52. PAD_CTL_SRE_FAST | PAD_CTL_HYS)
  53. #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
  54. PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
  55. #define WEAK_PULLUP (PAD_CTL_PUS_100K_UP | \
  56. PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
  57. PAD_CTL_SRE_SLOW)
  58. #define WEAK_PULLDOWN (PAD_CTL_PUS_100K_DOWN | \
  59. PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
  60. PAD_CTL_HYS | PAD_CTL_SRE_SLOW)
  61. #define TRISTATE (PAD_CTL_HYS | PAD_CTL_SPEED_MED)
  62. #define OUTPUT_RGB (PAD_CTL_SPEED_MED|PAD_CTL_DSE_60ohm|PAD_CTL_SRE_FAST)
  63. #define APALIS_IMX6_SATA_INIT_RETRIES 10
  64. int dram_init(void)
  65. {
  66. /* use the DDR controllers configured size */
  67. gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
  68. (ulong)imx_ddr_size());
  69. return 0;
  70. }
  71. /* Apalis UART1 */
  72. iomux_v3_cfg_t const uart1_pads_dce[] = {
  73. MX6_PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  74. MX6_PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  75. };
  76. iomux_v3_cfg_t const uart1_pads_dte[] = {
  77. MX6_PAD_CSI0_DAT10__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  78. MX6_PAD_CSI0_DAT11__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
  79. };
  80. #if defined(CONFIG_FSL_ESDHC_IMX) && defined(CONFIG_SPL_BUILD)
  81. /* Apalis MMC1 */
  82. iomux_v3_cfg_t const usdhc1_pads[] = {
  83. MX6_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  84. MX6_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  85. MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  86. MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  87. MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  88. MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  89. MX6_PAD_NANDF_D0__SD1_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  90. MX6_PAD_NANDF_D1__SD1_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  91. MX6_PAD_NANDF_D2__SD1_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  92. MX6_PAD_NANDF_D3__SD1_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  93. MX6_PAD_DI0_PIN4__GPIO4_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
  94. # define GPIO_MMC_CD IMX_GPIO_NR(4, 20)
  95. };
  96. /* Apalis SD1 */
  97. iomux_v3_cfg_t const usdhc2_pads[] = {
  98. MX6_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  99. MX6_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  100. MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  101. MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  102. MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  103. MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
  104. MX6_PAD_NANDF_CS1__GPIO6_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
  105. # define GPIO_SD_CD IMX_GPIO_NR(6, 14)
  106. };
  107. /* eMMC */
  108. iomux_v3_cfg_t const usdhc3_pads[] = {
  109. MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
  110. MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
  111. MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
  112. MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
  113. MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
  114. MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
  115. MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
  116. MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
  117. MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
  118. MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL),
  119. MX6_PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(WEAK_PULLUP) | MUX_MODE_SION,
  120. };
  121. #endif /* CONFIG_FSL_ESDHC_IMX & CONFIG_SPL_BUILD */
  122. int mx6_rgmii_rework(struct phy_device *phydev)
  123. {
  124. int tmp;
  125. switch (ksz9xx1_phy_get_id(phydev) & MII_KSZ9x31_SILICON_REV_MASK) {
  126. case PHY_ID_KSZ9131:
  127. /* read rxc dll control - devaddr = 0x02, register = 0x4c */
  128. tmp = ksz9031_phy_extended_read(phydev, 0x02,
  129. MII_KSZ9131_EXT_RGMII_2NS_SKEW_RXDLL,
  130. MII_KSZ9031_MOD_DATA_NO_POST_INC);
  131. /* disable rxdll bypass (enable 2ns skew delay on RXC) */
  132. tmp &= ~MII_KSZ9131_RXTXDLL_BYPASS;
  133. /* rxc data pad skew 2ns - devaddr = 0x02, register = 0x4c */
  134. ksz9031_phy_extended_write(phydev, 0x02,
  135. MII_KSZ9131_EXT_RGMII_2NS_SKEW_RXDLL,
  136. MII_KSZ9031_MOD_DATA_NO_POST_INC,
  137. tmp);
  138. /* read txc dll control - devaddr = 0x02, register = 0x4d */
  139. tmp = ksz9031_phy_extended_read(phydev, 0x02,
  140. MII_KSZ9131_EXT_RGMII_2NS_SKEW_TXDLL,
  141. MII_KSZ9031_MOD_DATA_NO_POST_INC);
  142. /* disable rxdll bypass (enable 2ns skew delay on TXC) */
  143. tmp &= ~MII_KSZ9131_RXTXDLL_BYPASS;
  144. /* txc data pad skew 2ns - devaddr = 0x02, register = 0x4d */
  145. ksz9031_phy_extended_write(phydev, 0x02,
  146. MII_KSZ9131_EXT_RGMII_2NS_SKEW_TXDLL,
  147. MII_KSZ9031_MOD_DATA_NO_POST_INC,
  148. tmp);
  149. /* control data pad skew - devaddr = 0x02, register = 0x04 */
  150. ksz9031_phy_extended_write(phydev, 0x02,
  151. MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
  152. MII_KSZ9031_MOD_DATA_NO_POST_INC,
  153. 0x007d);
  154. /* rx data pad skew - devaddr = 0x02, register = 0x05 */
  155. ksz9031_phy_extended_write(phydev, 0x02,
  156. MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
  157. MII_KSZ9031_MOD_DATA_NO_POST_INC,
  158. 0x7777);
  159. /* tx data pad skew - devaddr = 0x02, register = 0x05 */
  160. ksz9031_phy_extended_write(phydev, 0x02,
  161. MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
  162. MII_KSZ9031_MOD_DATA_NO_POST_INC,
  163. 0xdddd);
  164. /* gtx and rx clock pad skew - devaddr = 0x02,register = 0x08 */
  165. ksz9031_phy_extended_write(phydev, 0x02,
  166. MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
  167. MII_KSZ9031_MOD_DATA_NO_POST_INC,
  168. 0x0007);
  169. break;
  170. case PHY_ID_KSZ9031:
  171. default:
  172. /* control data pad skew - devaddr = 0x02, register = 0x04 */
  173. ksz9031_phy_extended_write(phydev, 0x02,
  174. MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
  175. MII_KSZ9031_MOD_DATA_NO_POST_INC,
  176. 0x0000);
  177. /* rx data pad skew - devaddr = 0x02, register = 0x05 */
  178. ksz9031_phy_extended_write(phydev, 0x02,
  179. MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
  180. MII_KSZ9031_MOD_DATA_NO_POST_INC,
  181. 0x0000);
  182. /* tx data pad skew - devaddr = 0x02, register = 0x05 */
  183. ksz9031_phy_extended_write(phydev, 0x02,
  184. MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
  185. MII_KSZ9031_MOD_DATA_NO_POST_INC,
  186. 0x0000);
  187. /* gtx and rx clock pad skew - devaddr = 0x02,register = 0x08 */
  188. ksz9031_phy_extended_write(phydev, 0x02,
  189. MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
  190. MII_KSZ9031_MOD_DATA_NO_POST_INC,
  191. 0x03FF);
  192. break;
  193. }
  194. return 0;
  195. }
  196. iomux_v3_cfg_t const enet_pads[] = {
  197. MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
  198. MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  199. MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  200. MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  201. MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  202. MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  203. MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  204. MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
  205. MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
  206. MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  207. MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  208. MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  209. MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  210. MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
  211. MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
  212. /* KSZ9031 PHY Reset */
  213. MX6_PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL) |
  214. MUX_MODE_SION,
  215. # define GPIO_ENET_PHY_RESET IMX_GPIO_NR(1, 25)
  216. };
  217. /* mux the Apalis GPIO pins, so they can be used from the U-Boot cmdline */
  218. iomux_v3_cfg_t const gpio_pads[] = {
  219. /* Apalis GPIO1 - GPIO8 */
  220. MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(WEAK_PULLUP) |
  221. MUX_MODE_SION,
  222. MX6_PAD_NANDF_D5__GPIO2_IO05 | MUX_PAD_CTRL(WEAK_PULLUP) |
  223. MUX_MODE_SION,
  224. MX6_PAD_NANDF_D6__GPIO2_IO06 | MUX_PAD_CTRL(WEAK_PULLUP) |
  225. MUX_MODE_SION,
  226. MX6_PAD_NANDF_D7__GPIO2_IO07 | MUX_PAD_CTRL(WEAK_PULLUP) |
  227. MUX_MODE_SION,
  228. MX6_PAD_NANDF_RB0__GPIO6_IO10 | MUX_PAD_CTRL(WEAK_PULLUP) |
  229. MUX_MODE_SION,
  230. MX6_PAD_NANDF_WP_B__GPIO6_IO09 | MUX_PAD_CTRL(WEAK_PULLUP) |
  231. MUX_MODE_SION,
  232. MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(WEAK_PULLDOWN) |
  233. MUX_MODE_SION,
  234. MX6_PAD_GPIO_6__GPIO1_IO06 | MUX_PAD_CTRL(WEAK_PULLUP) |
  235. MUX_MODE_SION,
  236. MX6_PAD_GPIO_4__GPIO1_IO04 | MUX_PAD_CTRL(WEAK_PULLUP) |
  237. MUX_MODE_SION,
  238. };
  239. static void setup_iomux_gpio(void)
  240. {
  241. imx_iomux_v3_setup_multiple_pads(gpio_pads, ARRAY_SIZE(gpio_pads));
  242. }
  243. iomux_v3_cfg_t const usb_pads[] = {
  244. /* USBH_EN */
  245. MX6_PAD_GPIO_0__GPIO1_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL) | MUX_MODE_SION,
  246. # define GPIO_USBH_EN IMX_GPIO_NR(1, 0)
  247. /* USB_VBUS_DET */
  248. MX6_PAD_EIM_D28__GPIO3_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL),
  249. # define GPIO_USB_VBUS_DET IMX_GPIO_NR(3, 28)
  250. /* USBO1_ID */
  251. MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(WEAK_PULLUP),
  252. /* USBO1_EN */
  253. MX6_PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL) | MUX_MODE_SION,
  254. # define GPIO_USBO_EN IMX_GPIO_NR(3, 22)
  255. };
  256. /*
  257. * UARTs are used in DTE mode, switch the mode on all UARTs before
  258. * any pinmuxing connects a (DCE) output to a transceiver output.
  259. */
  260. #define UCR3 0x88 /* FIFO Control Register */
  261. #define UCR3_RI BIT(8) /* RIDELT DTE mode */
  262. #define UCR3_DCD BIT(9) /* DCDDELT DTE mode */
  263. #define UFCR 0x90 /* FIFO Control Register */
  264. #define UFCR_DCEDTE BIT(6) /* DCE=0 */
  265. static void setup_dtemode_uart(void)
  266. {
  267. setbits_le32((u32 *)(UART1_BASE + UFCR), UFCR_DCEDTE);
  268. setbits_le32((u32 *)(UART2_BASE + UFCR), UFCR_DCEDTE);
  269. setbits_le32((u32 *)(UART4_BASE + UFCR), UFCR_DCEDTE);
  270. setbits_le32((u32 *)(UART5_BASE + UFCR), UFCR_DCEDTE);
  271. clrbits_le32((u32 *)(UART1_BASE + UCR3), UCR3_DCD | UCR3_RI);
  272. clrbits_le32((u32 *)(UART2_BASE + UCR3), UCR3_DCD | UCR3_RI);
  273. clrbits_le32((u32 *)(UART4_BASE + UCR3), UCR3_DCD | UCR3_RI);
  274. clrbits_le32((u32 *)(UART5_BASE + UCR3), UCR3_DCD | UCR3_RI);
  275. }
  276. static void setup_dcemode_uart(void)
  277. {
  278. clrbits_le32((u32 *)(UART1_BASE + UFCR), UFCR_DCEDTE);
  279. clrbits_le32((u32 *)(UART2_BASE + UFCR), UFCR_DCEDTE);
  280. clrbits_le32((u32 *)(UART4_BASE + UFCR), UFCR_DCEDTE);
  281. clrbits_le32((u32 *)(UART5_BASE + UFCR), UFCR_DCEDTE);
  282. }
  283. static void setup_iomux_dte_uart(void)
  284. {
  285. setup_dtemode_uart();
  286. imx_iomux_v3_setup_multiple_pads(uart1_pads_dte,
  287. ARRAY_SIZE(uart1_pads_dte));
  288. }
  289. static void setup_iomux_dce_uart(void)
  290. {
  291. setup_dcemode_uart();
  292. imx_iomux_v3_setup_multiple_pads(uart1_pads_dce,
  293. ARRAY_SIZE(uart1_pads_dce));
  294. }
  295. #ifdef CONFIG_USB_EHCI_MX6
  296. int board_ehci_hcd_init(int port)
  297. {
  298. imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
  299. return 0;
  300. }
  301. #endif
  302. #if defined(CONFIG_FSL_ESDHC_IMX) && defined(CONFIG_SPL_BUILD)
  303. /* use the following sequence: eMMC, MMC1, SD1 */
  304. struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = {
  305. {USDHC3_BASE_ADDR},
  306. {USDHC1_BASE_ADDR},
  307. {USDHC2_BASE_ADDR},
  308. };
  309. int board_mmc_getcd(struct mmc *mmc)
  310. {
  311. struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
  312. int ret = true; /* default: assume inserted */
  313. switch (cfg->esdhc_base) {
  314. case USDHC1_BASE_ADDR:
  315. gpio_request(GPIO_MMC_CD, "MMC_CD");
  316. gpio_direction_input(GPIO_MMC_CD);
  317. ret = !gpio_get_value(GPIO_MMC_CD);
  318. break;
  319. case USDHC2_BASE_ADDR:
  320. gpio_request(GPIO_MMC_CD, "SD_CD");
  321. gpio_direction_input(GPIO_SD_CD);
  322. ret = !gpio_get_value(GPIO_SD_CD);
  323. break;
  324. }
  325. return ret;
  326. }
  327. int board_mmc_init(struct bd_info *bis)
  328. {
  329. struct src *psrc = (struct src *)SRC_BASE_ADDR;
  330. unsigned reg = readl(&psrc->sbmr1) >> 11;
  331. /*
  332. * Upon reading BOOT_CFG register the following map is done:
  333. * Bit 11 and 12 of BOOT_CFG register can determine the current
  334. * mmc port
  335. * 0x1 SD1
  336. * 0x2 SD2
  337. * 0x3 SD4
  338. */
  339. switch (reg & 0x3) {
  340. case 0x0:
  341. imx_iomux_v3_setup_multiple_pads(
  342. usdhc1_pads, ARRAY_SIZE(usdhc1_pads));
  343. usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR;
  344. usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
  345. gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
  346. break;
  347. case 0x1:
  348. imx_iomux_v3_setup_multiple_pads(
  349. usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
  350. usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
  351. usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
  352. gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
  353. break;
  354. case 0x2:
  355. imx_iomux_v3_setup_multiple_pads(
  356. usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
  357. usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
  358. usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
  359. gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
  360. break;
  361. default:
  362. puts("MMC boot device not available");
  363. }
  364. return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
  365. }
  366. #endif /* CONFIG_FSL_ESDHC_IMX & CONFIG_SPL_BUILD */
  367. int board_phy_config(struct phy_device *phydev)
  368. {
  369. mx6_rgmii_rework(phydev);
  370. if (phydev->drv->config)
  371. phydev->drv->config(phydev);
  372. return 0;
  373. }
  374. static iomux_v3_cfg_t const pwr_intb_pads[] = {
  375. /*
  376. * the bootrom sets the iomux to vselect, potentially connecting
  377. * two outputs. Set this back to GPIO
  378. */
  379. MX6_PAD_GPIO_18__GPIO7_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL)
  380. };
  381. #if defined(CONFIG_VIDEO_IPUV3)
  382. static iomux_v3_cfg_t const backlight_pads[] = {
  383. /* Backlight on RGB connector: J15 */
  384. MX6_PAD_EIM_DA13__GPIO3_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL) |
  385. MUX_MODE_SION,
  386. #define RGB_BACKLIGHT_GP IMX_GPIO_NR(3, 13)
  387. /* additional CPU pin on BKL_PWM, keep in tristate */
  388. MX6_PAD_EIM_DA14__GPIO3_IO14 | MUX_PAD_CTRL(TRISTATE),
  389. /* Backlight PWM, used as GPIO in U-Boot */
  390. MX6_PAD_SD4_DAT2__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL) |
  391. MUX_MODE_SION,
  392. #define RGB_BACKLIGHTPWM_GP IMX_GPIO_NR(2, 10)
  393. /* buffer output enable 0: buffer enabled */
  394. MX6_PAD_EIM_A25__GPIO5_IO02 | MUX_PAD_CTRL(WEAK_PULLUP) | MUX_MODE_SION,
  395. #define RGB_BACKLIGHTPWM_OE IMX_GPIO_NR(5, 2)
  396. /* PSAVE# integrated VDAC */
  397. MX6_PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL) |
  398. MUX_MODE_SION,
  399. #define VGA_PSAVE_NOT_GP IMX_GPIO_NR(6, 31)
  400. };
  401. static iomux_v3_cfg_t const rgb_pads[] = {
  402. MX6_PAD_EIM_A16__IPU1_DI1_DISP_CLK | MUX_PAD_CTRL(OUTPUT_RGB),
  403. MX6_PAD_EIM_DA10__IPU1_DI1_PIN15 | MUX_PAD_CTRL(OUTPUT_RGB),
  404. MX6_PAD_EIM_DA11__IPU1_DI1_PIN02 | MUX_PAD_CTRL(OUTPUT_RGB),
  405. MX6_PAD_EIM_DA12__IPU1_DI1_PIN03 | MUX_PAD_CTRL(OUTPUT_RGB),
  406. MX6_PAD_EIM_DA9__IPU1_DISP1_DATA00 | MUX_PAD_CTRL(OUTPUT_RGB),
  407. MX6_PAD_EIM_DA8__IPU1_DISP1_DATA01 | MUX_PAD_CTRL(OUTPUT_RGB),
  408. MX6_PAD_EIM_DA7__IPU1_DISP1_DATA02 | MUX_PAD_CTRL(OUTPUT_RGB),
  409. MX6_PAD_EIM_DA6__IPU1_DISP1_DATA03 | MUX_PAD_CTRL(OUTPUT_RGB),
  410. MX6_PAD_EIM_DA5__IPU1_DISP1_DATA04 | MUX_PAD_CTRL(OUTPUT_RGB),
  411. MX6_PAD_EIM_DA4__IPU1_DISP1_DATA05 | MUX_PAD_CTRL(OUTPUT_RGB),
  412. MX6_PAD_EIM_DA3__IPU1_DISP1_DATA06 | MUX_PAD_CTRL(OUTPUT_RGB),
  413. MX6_PAD_EIM_DA2__IPU1_DISP1_DATA07 | MUX_PAD_CTRL(OUTPUT_RGB),
  414. MX6_PAD_EIM_DA1__IPU1_DISP1_DATA08 | MUX_PAD_CTRL(OUTPUT_RGB),
  415. MX6_PAD_EIM_DA0__IPU1_DISP1_DATA09 | MUX_PAD_CTRL(OUTPUT_RGB),
  416. MX6_PAD_EIM_EB1__IPU1_DISP1_DATA10 | MUX_PAD_CTRL(OUTPUT_RGB),
  417. MX6_PAD_EIM_EB0__IPU1_DISP1_DATA11 | MUX_PAD_CTRL(OUTPUT_RGB),
  418. MX6_PAD_EIM_A17__IPU1_DISP1_DATA12 | MUX_PAD_CTRL(OUTPUT_RGB),
  419. MX6_PAD_EIM_A18__IPU1_DISP1_DATA13 | MUX_PAD_CTRL(OUTPUT_RGB),
  420. MX6_PAD_EIM_A19__IPU1_DISP1_DATA14 | MUX_PAD_CTRL(OUTPUT_RGB),
  421. MX6_PAD_EIM_A20__IPU1_DISP1_DATA15 | MUX_PAD_CTRL(OUTPUT_RGB),
  422. MX6_PAD_EIM_A21__IPU1_DISP1_DATA16 | MUX_PAD_CTRL(OUTPUT_RGB),
  423. MX6_PAD_EIM_A22__IPU1_DISP1_DATA17 | MUX_PAD_CTRL(OUTPUT_RGB),
  424. MX6_PAD_EIM_A23__IPU1_DISP1_DATA18 | MUX_PAD_CTRL(OUTPUT_RGB),
  425. MX6_PAD_EIM_A24__IPU1_DISP1_DATA19 | MUX_PAD_CTRL(OUTPUT_RGB),
  426. MX6_PAD_EIM_D26__IPU1_DISP1_DATA22 | MUX_PAD_CTRL(OUTPUT_RGB),
  427. MX6_PAD_EIM_D27__IPU1_DISP1_DATA23 | MUX_PAD_CTRL(OUTPUT_RGB),
  428. MX6_PAD_EIM_D30__IPU1_DISP1_DATA21 | MUX_PAD_CTRL(OUTPUT_RGB),
  429. MX6_PAD_EIM_D31__IPU1_DISP1_DATA20 | MUX_PAD_CTRL(OUTPUT_RGB),
  430. };
  431. static void do_enable_hdmi(struct display_info_t const *dev)
  432. {
  433. imx_enable_hdmi_phy();
  434. }
  435. static void enable_lvds(struct display_info_t const *dev)
  436. {
  437. struct iomuxc *iomux = (struct iomuxc *)
  438. IOMUXC_BASE_ADDR;
  439. u32 reg = readl(&iomux->gpr[2]);
  440. reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT;
  441. writel(reg, &iomux->gpr[2]);
  442. gpio_direction_output(RGB_BACKLIGHT_GP, 1);
  443. gpio_direction_output(RGB_BACKLIGHTPWM_GP, 0);
  444. gpio_direction_output(RGB_BACKLIGHTPWM_OE, 0);
  445. }
  446. static void enable_rgb(struct display_info_t const *dev)
  447. {
  448. imx_iomux_v3_setup_multiple_pads(
  449. rgb_pads,
  450. ARRAY_SIZE(rgb_pads));
  451. gpio_direction_output(RGB_BACKLIGHT_GP, 1);
  452. gpio_direction_output(RGB_BACKLIGHTPWM_GP, 0);
  453. gpio_direction_output(RGB_BACKLIGHTPWM_OE, 0);
  454. }
  455. static int detect_default(struct display_info_t const *dev)
  456. {
  457. (void) dev;
  458. return 1;
  459. }
  460. struct display_info_t const displays[] = {{
  461. .bus = -1,
  462. .addr = 0,
  463. .pixfmt = IPU_PIX_FMT_RGB24,
  464. .detect = detect_hdmi,
  465. .enable = do_enable_hdmi,
  466. .mode = {
  467. .name = "HDMI",
  468. .refresh = 60,
  469. .xres = 1024,
  470. .yres = 768,
  471. .pixclock = 15385,
  472. .left_margin = 220,
  473. .right_margin = 40,
  474. .upper_margin = 21,
  475. .lower_margin = 7,
  476. .hsync_len = 60,
  477. .vsync_len = 10,
  478. .sync = FB_SYNC_EXT,
  479. .vmode = FB_VMODE_NONINTERLACED
  480. } }, {
  481. .bus = -1,
  482. .addr = 0,
  483. .di = 1,
  484. .pixfmt = IPU_PIX_FMT_RGB24,
  485. .detect = detect_default,
  486. .enable = enable_rgb,
  487. .mode = {
  488. .name = "vga-rgb",
  489. .refresh = 60,
  490. .xres = 640,
  491. .yres = 480,
  492. .pixclock = 33000,
  493. .left_margin = 48,
  494. .right_margin = 16,
  495. .upper_margin = 31,
  496. .lower_margin = 11,
  497. .hsync_len = 96,
  498. .vsync_len = 2,
  499. .sync = 0,
  500. .vmode = FB_VMODE_NONINTERLACED
  501. } }, {
  502. .bus = -1,
  503. .addr = 0,
  504. .di = 1,
  505. .pixfmt = IPU_PIX_FMT_RGB24,
  506. .enable = enable_rgb,
  507. .mode = {
  508. .name = "wvga-rgb",
  509. .refresh = 60,
  510. .xres = 800,
  511. .yres = 480,
  512. .pixclock = 25000,
  513. .left_margin = 40,
  514. .right_margin = 88,
  515. .upper_margin = 33,
  516. .lower_margin = 10,
  517. .hsync_len = 128,
  518. .vsync_len = 2,
  519. .sync = 0,
  520. .vmode = FB_VMODE_NONINTERLACED
  521. } }, {
  522. .bus = -1,
  523. .addr = 0,
  524. .pixfmt = IPU_PIX_FMT_LVDS666,
  525. .enable = enable_lvds,
  526. .mode = {
  527. .name = "wsvga-lvds",
  528. .refresh = 60,
  529. .xres = 1024,
  530. .yres = 600,
  531. .pixclock = 15385,
  532. .left_margin = 220,
  533. .right_margin = 40,
  534. .upper_margin = 21,
  535. .lower_margin = 7,
  536. .hsync_len = 60,
  537. .vsync_len = 10,
  538. .sync = FB_SYNC_EXT,
  539. .vmode = FB_VMODE_NONINTERLACED
  540. } } };
  541. size_t display_count = ARRAY_SIZE(displays);
  542. static void setup_display(void)
  543. {
  544. struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  545. struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
  546. int reg;
  547. enable_ipu_clock();
  548. imx_setup_hdmi();
  549. /* Turn on LDB0,IPU,IPU DI0 clocks */
  550. reg = __raw_readl(&mxc_ccm->CCGR3);
  551. reg |= MXC_CCM_CCGR3_LDB_DI0_MASK;
  552. writel(reg, &mxc_ccm->CCGR3);
  553. /* set LDB0, LDB1 clk select to 011/011 */
  554. reg = readl(&mxc_ccm->cs2cdr);
  555. reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
  556. |MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
  557. reg |= (3<<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
  558. |(3<<MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
  559. writel(reg, &mxc_ccm->cs2cdr);
  560. reg = readl(&mxc_ccm->cscmr2);
  561. reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
  562. writel(reg, &mxc_ccm->cscmr2);
  563. reg = readl(&mxc_ccm->chsccdr);
  564. reg |= (CHSCCDR_CLK_SEL_LDB_DI0
  565. <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
  566. writel(reg, &mxc_ccm->chsccdr);
  567. reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
  568. |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
  569. |IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
  570. |IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
  571. |IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
  572. |IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
  573. |IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
  574. |IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
  575. |IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
  576. writel(reg, &iomux->gpr[2]);
  577. reg = readl(&iomux->gpr[3]);
  578. reg = (reg & ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK
  579. |IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
  580. | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
  581. <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
  582. writel(reg, &iomux->gpr[3]);
  583. /* backlight unconditionally on for now */
  584. imx_iomux_v3_setup_multiple_pads(backlight_pads,
  585. ARRAY_SIZE(backlight_pads));
  586. /* use 0 for EDT 7", use 1 for LG fullHD panel */
  587. gpio_request(RGB_BACKLIGHTPWM_GP, "BKL1_PWM");
  588. gpio_request(RGB_BACKLIGHTPWM_OE, "BKL1_PWM_EN");
  589. gpio_request(RGB_BACKLIGHT_GP, "BKL1_ON");
  590. gpio_direction_output(RGB_BACKLIGHTPWM_GP, 0);
  591. gpio_direction_output(RGB_BACKLIGHTPWM_OE, 0);
  592. gpio_direction_output(RGB_BACKLIGHT_GP, 1);
  593. }
  594. /*
  595. * Backlight off before OS handover
  596. */
  597. void board_preboot_os(void)
  598. {
  599. gpio_direction_output(RGB_BACKLIGHTPWM_GP, 1);
  600. gpio_direction_output(RGB_BACKLIGHT_GP, 0);
  601. }
  602. #endif /* defined(CONFIG_VIDEO_IPUV3) */
  603. int board_early_init_f(void)
  604. {
  605. imx_iomux_v3_setup_multiple_pads(pwr_intb_pads,
  606. ARRAY_SIZE(pwr_intb_pads));
  607. #ifndef CONFIG_TDX_APALIS_IMX6_V1_0
  608. setup_iomux_dte_uart();
  609. #else
  610. setup_iomux_dce_uart();
  611. #endif
  612. return 0;
  613. }
  614. /*
  615. * Do not overwrite the console
  616. * Use always serial for U-Boot console
  617. */
  618. int overwrite_console(void)
  619. {
  620. return 1;
  621. }
  622. int board_init(void)
  623. {
  624. /* address of boot parameters */
  625. gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
  626. #if defined(CONFIG_VIDEO_IPUV3)
  627. setup_display();
  628. #endif
  629. #ifdef CONFIG_TDX_CMD_IMX_MFGR
  630. (void) pmic_init();
  631. #endif
  632. #ifdef CONFIG_SATA
  633. setup_sata();
  634. #endif
  635. setup_iomux_gpio();
  636. return 0;
  637. }
  638. #ifdef CONFIG_BOARD_LATE_INIT
  639. int board_late_init(void)
  640. {
  641. #if defined(CONFIG_REVISION_TAG) && \
  642. defined(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)
  643. char env_str[256];
  644. u32 rev;
  645. rev = get_board_rev();
  646. snprintf(env_str, ARRAY_SIZE(env_str), "%.4x", rev);
  647. env_set("board_rev", env_str);
  648. #ifndef CONFIG_TDX_APALIS_IMX6_V1_0
  649. if ((rev & 0xfff0) == 0x0100) {
  650. char *fdt_env;
  651. /* reconfigure the UART to DCE mode dynamically if on V1.0 HW */
  652. setup_iomux_dce_uart();
  653. /* if using the default device tree, use version for V1.0 HW */
  654. fdt_env = env_get("fdt_file");
  655. if ((fdt_env != NULL) && (strcmp(FDT_FILE, fdt_env) == 0)) {
  656. env_set("fdt_file", FDT_FILE_V1_0);
  657. printf("patching fdt_file to " FDT_FILE_V1_0 "\n");
  658. #ifndef CONFIG_ENV_IS_NOWHERE
  659. env_save();
  660. #endif
  661. }
  662. }
  663. #endif /* CONFIG_TDX_APALIS_IMX6_V1_0 */
  664. #endif /* CONFIG_REVISION_TAG */
  665. #ifdef CONFIG_CMD_USB_SDP
  666. if (is_boot_from_usb()) {
  667. printf("Serial Downloader recovery mode, using sdp command\n");
  668. env_set("bootdelay", "0");
  669. env_set("bootcmd", "sdp 0");
  670. }
  671. #endif /* CONFIG_CMD_USB_SDP */
  672. return 0;
  673. }
  674. #endif /* CONFIG_BOARD_LATE_INIT */
  675. int checkboard(void)
  676. {
  677. char it[] = " IT";
  678. int minc, maxc;
  679. switch (get_cpu_temp_grade(&minc, &maxc)) {
  680. case TEMP_AUTOMOTIVE:
  681. case TEMP_INDUSTRIAL:
  682. break;
  683. case TEMP_EXTCOMMERCIAL:
  684. default:
  685. it[0] = 0;
  686. };
  687. printf("Model: Toradex Apalis iMX6 %s %s%s\n",
  688. is_cpu_type(MXC_CPU_MX6D) ? "Dual" : "Quad",
  689. (gd->ram_size == 0x80000000) ? "2GB" :
  690. (gd->ram_size == 0x40000000) ? "1GB" : "512MB", it);
  691. return 0;
  692. }
  693. #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
  694. int ft_board_setup(void *blob, struct bd_info *bd)
  695. {
  696. return ft_common_board_setup(blob, bd);
  697. }
  698. #endif
  699. #ifdef CONFIG_CMD_BMODE
  700. static const struct boot_mode board_boot_modes[] = {
  701. /* 4-bit bus width */
  702. {"mmc", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
  703. {"sd", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
  704. {NULL, 0},
  705. };
  706. #endif
  707. int misc_init_r(void)
  708. {
  709. #ifdef CONFIG_CMD_BMODE
  710. add_board_boot_modes(board_boot_modes);
  711. #endif
  712. return 0;
  713. }
  714. #ifdef CONFIG_LDO_BYPASS_CHECK
  715. /* TODO, use external pmic, for now always ldo_enable */
  716. void ldo_mode_set(int ldo_bypass)
  717. {
  718. return;
  719. }
  720. #endif
  721. #ifdef CONFIG_SPL_BUILD
  722. #include <spl.h>
  723. #include <linux/libfdt.h>
  724. #include "asm/arch/mx6q-ddr.h"
  725. #include "asm/arch/iomux.h"
  726. #include "asm/arch/crm_regs.h"
  727. static int mx6_com_dcd_table[] = {
  728. /* ddr-setup.cfg */
  729. MX6_IOM_DRAM_SDQS0, 0x00000030,
  730. MX6_IOM_DRAM_SDQS1, 0x00000030,
  731. MX6_IOM_DRAM_SDQS2, 0x00000030,
  732. MX6_IOM_DRAM_SDQS3, 0x00000030,
  733. MX6_IOM_DRAM_SDQS4, 0x00000030,
  734. MX6_IOM_DRAM_SDQS5, 0x00000030,
  735. MX6_IOM_DRAM_SDQS6, 0x00000030,
  736. MX6_IOM_DRAM_SDQS7, 0x00000030,
  737. MX6_IOM_GRP_B0DS, 0x00000030,
  738. MX6_IOM_GRP_B1DS, 0x00000030,
  739. MX6_IOM_GRP_B2DS, 0x00000030,
  740. MX6_IOM_GRP_B3DS, 0x00000030,
  741. MX6_IOM_GRP_B4DS, 0x00000030,
  742. MX6_IOM_GRP_B5DS, 0x00000030,
  743. MX6_IOM_GRP_B6DS, 0x00000030,
  744. MX6_IOM_GRP_B7DS, 0x00000030,
  745. MX6_IOM_GRP_ADDDS, 0x00000030,
  746. /* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */
  747. MX6_IOM_GRP_CTLDS, 0x00000030,
  748. MX6_IOM_DRAM_DQM0, 0x00020030,
  749. MX6_IOM_DRAM_DQM1, 0x00020030,
  750. MX6_IOM_DRAM_DQM2, 0x00020030,
  751. MX6_IOM_DRAM_DQM3, 0x00020030,
  752. MX6_IOM_DRAM_DQM4, 0x00020030,
  753. MX6_IOM_DRAM_DQM5, 0x00020030,
  754. MX6_IOM_DRAM_DQM6, 0x00020030,
  755. MX6_IOM_DRAM_DQM7, 0x00020030,
  756. MX6_IOM_DRAM_CAS, 0x00020030,
  757. MX6_IOM_DRAM_RAS, 0x00020030,
  758. MX6_IOM_DRAM_SDCLK_0, 0x00020030,
  759. MX6_IOM_DRAM_SDCLK_1, 0x00020030,
  760. MX6_IOM_DRAM_RESET, 0x00020030,
  761. MX6_IOM_DRAM_SDCKE0, 0x00003000,
  762. MX6_IOM_DRAM_SDCKE1, 0x00003000,
  763. MX6_IOM_DRAM_SDODT0, 0x00003030,
  764. MX6_IOM_DRAM_SDODT1, 0x00003030,
  765. /* (differential input) */
  766. MX6_IOM_DDRMODE_CTL, 0x00020000,
  767. /* (differential input) */
  768. MX6_IOM_GRP_DDRMODE, 0x00020000,
  769. /* disable ddr pullups */
  770. MX6_IOM_GRP_DDRPKE, 0x00000000,
  771. MX6_IOM_DRAM_SDBA2, 0x00000000,
  772. /* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */
  773. MX6_IOM_GRP_DDR_TYPE, 0x000C0000,
  774. /* Read data DQ Byte0-3 delay */
  775. MX6_MMDC_P0_MPRDDQBY0DL, 0x33333333,
  776. MX6_MMDC_P0_MPRDDQBY1DL, 0x33333333,
  777. MX6_MMDC_P0_MPRDDQBY2DL, 0x33333333,
  778. MX6_MMDC_P0_MPRDDQBY3DL, 0x33333333,
  779. MX6_MMDC_P1_MPRDDQBY0DL, 0x33333333,
  780. MX6_MMDC_P1_MPRDDQBY1DL, 0x33333333,
  781. MX6_MMDC_P1_MPRDDQBY2DL, 0x33333333,
  782. MX6_MMDC_P1_MPRDDQBY3DL, 0x33333333,
  783. /*
  784. * MDMISC mirroring interleaved (row/bank/col)
  785. */
  786. MX6_MMDC_P0_MDMISC, 0x00081740,
  787. /*
  788. * MDSCR con_req
  789. */
  790. MX6_MMDC_P0_MDSCR, 0x00008000,
  791. /* 1066mhz_4x128mx16.cfg */
  792. MX6_MMDC_P0_MDPDC, 0x00020036,
  793. MX6_MMDC_P0_MDCFG0, 0x555A7954,
  794. MX6_MMDC_P0_MDCFG1, 0xDB328F64,
  795. MX6_MMDC_P0_MDCFG2, 0x01FF00DB,
  796. MX6_MMDC_P0_MDRWD, 0x000026D2,
  797. MX6_MMDC_P0_MDOR, 0x005A1023,
  798. MX6_MMDC_P0_MDOTC, 0x09555050,
  799. MX6_MMDC_P0_MDPDC, 0x00025576,
  800. MX6_MMDC_P0_MDASP, 0x00000027,
  801. MX6_MMDC_P0_MDCTL, 0x831A0000,
  802. MX6_MMDC_P0_MDSCR, 0x04088032,
  803. MX6_MMDC_P0_MDSCR, 0x00008033,
  804. MX6_MMDC_P0_MDSCR, 0x00428031,
  805. MX6_MMDC_P0_MDSCR, 0x19308030,
  806. MX6_MMDC_P0_MDSCR, 0x04008040,
  807. MX6_MMDC_P0_MPZQHWCTRL, 0xA1390003,
  808. MX6_MMDC_P1_MPZQHWCTRL, 0xA1390003,
  809. MX6_MMDC_P0_MDREF, 0x00005800,
  810. MX6_MMDC_P0_MPODTCTRL, 0x00000000,
  811. MX6_MMDC_P1_MPODTCTRL, 0x00000000,
  812. MX6_MMDC_P0_MPDGCTRL0, 0x432A0338,
  813. MX6_MMDC_P0_MPDGCTRL1, 0x03260324,
  814. MX6_MMDC_P1_MPDGCTRL0, 0x43340344,
  815. MX6_MMDC_P1_MPDGCTRL1, 0x031E027C,
  816. MX6_MMDC_P0_MPRDDLCTL, 0x33272D2E,
  817. MX6_MMDC_P1_MPRDDLCTL, 0x2F312B37,
  818. MX6_MMDC_P0_MPWRDLCTL, 0x3A35433C,
  819. MX6_MMDC_P1_MPWRDLCTL, 0x4336453F,
  820. MX6_MMDC_P0_MPWLDECTRL0, 0x0009000E,
  821. MX6_MMDC_P0_MPWLDECTRL1, 0x0018000B,
  822. MX6_MMDC_P1_MPWLDECTRL0, 0x00060015,
  823. MX6_MMDC_P1_MPWLDECTRL1, 0x0006000E,
  824. MX6_MMDC_P0_MPMUR0, 0x00000800,
  825. MX6_MMDC_P1_MPMUR0, 0x00000800,
  826. MX6_MMDC_P0_MDSCR, 0x00000000,
  827. MX6_MMDC_P0_MAPSR, 0x00011006,
  828. };
  829. static int mx6_it_dcd_table[] = {
  830. /* ddr-setup.cfg */
  831. MX6_IOM_DRAM_SDQS0, 0x00000030,
  832. MX6_IOM_DRAM_SDQS1, 0x00000030,
  833. MX6_IOM_DRAM_SDQS2, 0x00000030,
  834. MX6_IOM_DRAM_SDQS3, 0x00000030,
  835. MX6_IOM_DRAM_SDQS4, 0x00000030,
  836. MX6_IOM_DRAM_SDQS5, 0x00000030,
  837. MX6_IOM_DRAM_SDQS6, 0x00000030,
  838. MX6_IOM_DRAM_SDQS7, 0x00000030,
  839. MX6_IOM_GRP_B0DS, 0x00000030,
  840. MX6_IOM_GRP_B1DS, 0x00000030,
  841. MX6_IOM_GRP_B2DS, 0x00000030,
  842. MX6_IOM_GRP_B3DS, 0x00000030,
  843. MX6_IOM_GRP_B4DS, 0x00000030,
  844. MX6_IOM_GRP_B5DS, 0x00000030,
  845. MX6_IOM_GRP_B6DS, 0x00000030,
  846. MX6_IOM_GRP_B7DS, 0x00000030,
  847. MX6_IOM_GRP_ADDDS, 0x00000030,
  848. /* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */
  849. MX6_IOM_GRP_CTLDS, 0x00000030,
  850. MX6_IOM_DRAM_DQM0, 0x00020030,
  851. MX6_IOM_DRAM_DQM1, 0x00020030,
  852. MX6_IOM_DRAM_DQM2, 0x00020030,
  853. MX6_IOM_DRAM_DQM3, 0x00020030,
  854. MX6_IOM_DRAM_DQM4, 0x00020030,
  855. MX6_IOM_DRAM_DQM5, 0x00020030,
  856. MX6_IOM_DRAM_DQM6, 0x00020030,
  857. MX6_IOM_DRAM_DQM7, 0x00020030,
  858. MX6_IOM_DRAM_CAS, 0x00020030,
  859. MX6_IOM_DRAM_RAS, 0x00020030,
  860. MX6_IOM_DRAM_SDCLK_0, 0x00020030,
  861. MX6_IOM_DRAM_SDCLK_1, 0x00020030,
  862. MX6_IOM_DRAM_RESET, 0x00020030,
  863. MX6_IOM_DRAM_SDCKE0, 0x00003000,
  864. MX6_IOM_DRAM_SDCKE1, 0x00003000,
  865. MX6_IOM_DRAM_SDODT0, 0x00003030,
  866. MX6_IOM_DRAM_SDODT1, 0x00003030,
  867. /* (differential input) */
  868. MX6_IOM_DDRMODE_CTL, 0x00020000,
  869. /* (differential input) */
  870. MX6_IOM_GRP_DDRMODE, 0x00020000,
  871. /* disable ddr pullups */
  872. MX6_IOM_GRP_DDRPKE, 0x00000000,
  873. MX6_IOM_DRAM_SDBA2, 0x00000000,
  874. /* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */
  875. MX6_IOM_GRP_DDR_TYPE, 0x000C0000,
  876. /* Read data DQ Byte0-3 delay */
  877. MX6_MMDC_P0_MPRDDQBY0DL, 0x33333333,
  878. MX6_MMDC_P0_MPRDDQBY1DL, 0x33333333,
  879. MX6_MMDC_P0_MPRDDQBY2DL, 0x33333333,
  880. MX6_MMDC_P0_MPRDDQBY3DL, 0x33333333,
  881. MX6_MMDC_P1_MPRDDQBY0DL, 0x33333333,
  882. MX6_MMDC_P1_MPRDDQBY1DL, 0x33333333,
  883. MX6_MMDC_P1_MPRDDQBY2DL, 0x33333333,
  884. MX6_MMDC_P1_MPRDDQBY3DL, 0x33333333,
  885. /*
  886. * MDMISC mirroring interleaved (row/bank/col)
  887. */
  888. MX6_MMDC_P0_MDMISC, 0x00081740,
  889. /*
  890. * MDSCR con_req
  891. */
  892. MX6_MMDC_P0_MDSCR, 0x00008000,
  893. /* 1066mhz_4x256mx16.cfg */
  894. MX6_MMDC_P0_MDPDC, 0x00020036,
  895. MX6_MMDC_P0_MDCFG0, 0x898E78f5,
  896. MX6_MMDC_P0_MDCFG1, 0xff328f64,
  897. MX6_MMDC_P0_MDCFG2, 0x01FF00DB,
  898. MX6_MMDC_P0_MDRWD, 0x000026D2,
  899. MX6_MMDC_P0_MDOR, 0x008E1023,
  900. MX6_MMDC_P0_MDOTC, 0x09444040,
  901. MX6_MMDC_P0_MDPDC, 0x00025576,
  902. MX6_MMDC_P0_MDASP, 0x00000047,
  903. MX6_MMDC_P0_MDCTL, 0x841A0000,
  904. MX6_MMDC_P0_MDSCR, 0x02888032,
  905. MX6_MMDC_P0_MDSCR, 0x00008033,
  906. MX6_MMDC_P0_MDSCR, 0x00048031,
  907. MX6_MMDC_P0_MDSCR, 0x19408030,
  908. MX6_MMDC_P0_MDSCR, 0x04008040,
  909. MX6_MMDC_P0_MPZQHWCTRL, 0xA1390003,
  910. MX6_MMDC_P1_MPZQHWCTRL, 0xA1390003,
  911. MX6_MMDC_P0_MDREF, 0x00007800,
  912. MX6_MMDC_P0_MPODTCTRL, 0x00022227,
  913. MX6_MMDC_P1_MPODTCTRL, 0x00022227,
  914. MX6_MMDC_P0_MPDGCTRL0, 0x03300338,
  915. MX6_MMDC_P0_MPDGCTRL1, 0x03240324,
  916. MX6_MMDC_P1_MPDGCTRL0, 0x03440350,
  917. MX6_MMDC_P1_MPDGCTRL1, 0x032C0308,
  918. MX6_MMDC_P0_MPRDDLCTL, 0x40363C3E,
  919. MX6_MMDC_P1_MPRDDLCTL, 0x3C3E3C46,
  920. MX6_MMDC_P0_MPWRDLCTL, 0x403E463E,
  921. MX6_MMDC_P1_MPWRDLCTL, 0x4A384C46,
  922. MX6_MMDC_P0_MPWLDECTRL0, 0x0009000E,
  923. MX6_MMDC_P0_MPWLDECTRL1, 0x0018000B,
  924. MX6_MMDC_P1_MPWLDECTRL0, 0x00060015,
  925. MX6_MMDC_P1_MPWLDECTRL1, 0x0006000E,
  926. MX6_MMDC_P0_MPMUR0, 0x00000800,
  927. MX6_MMDC_P1_MPMUR0, 0x00000800,
  928. MX6_MMDC_P0_MDSCR, 0x00000000,
  929. MX6_MMDC_P0_MAPSR, 0x00011006,
  930. };
  931. static void ccgr_init(void)
  932. {
  933. struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  934. writel(0x00C03F3F, &ccm->CCGR0);
  935. writel(0x0030FC03, &ccm->CCGR1);
  936. writel(0x0FFFFFF3, &ccm->CCGR2);
  937. writel(0x3FF0300F, &ccm->CCGR3);
  938. writel(0x00FFF300, &ccm->CCGR4);
  939. writel(0x0F0000F3, &ccm->CCGR5);
  940. writel(0x000003FF, &ccm->CCGR6);
  941. /*
  942. * Setup CCM_CCOSR register as follows:
  943. *
  944. * cko1_en = 1 --> CKO1 enabled
  945. * cko1_div = 111 --> divide by 8
  946. * cko1_sel = 1011 --> ahb_clk_root
  947. *
  948. * This sets CKO1 at ahb_clk_root/8 = 132/8 = 16.5 MHz
  949. */
  950. writel(0x000000FB, &ccm->ccosr);
  951. }
  952. static void ddr_init(int *table, int size)
  953. {
  954. int i;
  955. for (i = 0; i < size / 2 ; i++)
  956. writel(table[2 * i + 1], table[2 * i]);
  957. }
  958. static void spl_dram_init(void)
  959. {
  960. int minc, maxc;
  961. switch (get_cpu_temp_grade(&minc, &maxc)) {
  962. case TEMP_COMMERCIAL:
  963. case TEMP_EXTCOMMERCIAL:
  964. puts("Commercial temperature grade DDR3 timings.\n");
  965. ddr_init(mx6_com_dcd_table, ARRAY_SIZE(mx6_com_dcd_table));
  966. break;
  967. case TEMP_INDUSTRIAL:
  968. case TEMP_AUTOMOTIVE:
  969. default:
  970. puts("Industrial temperature grade DDR3 timings.\n");
  971. ddr_init(mx6_it_dcd_table, ARRAY_SIZE(mx6_it_dcd_table));
  972. break;
  973. };
  974. udelay(100);
  975. }
  976. void board_init_f(ulong dummy)
  977. {
  978. /* setup AIPS and disable watchdog */
  979. arch_cpu_init();
  980. ccgr_init();
  981. gpr_init();
  982. /* iomux */
  983. board_early_init_f();
  984. /* setup GP timer */
  985. timer_init();
  986. /* UART clocks enabled and gd valid - init serial console */
  987. preloader_console_init();
  988. #ifndef CONFIG_TDX_APALIS_IMX6_V1_0
  989. /* Make sure we use dte mode */
  990. setup_dtemode_uart();
  991. #endif
  992. /* DDR initialization */
  993. spl_dram_init();
  994. /* Clear the BSS. */
  995. memset(__bss_start, 0, __bss_end - __bss_start);
  996. /* load/boot image from boot device */
  997. board_init_r(NULL, 0);
  998. }
  999. #ifdef CONFIG_SPL_LOAD_FIT
  1000. int board_fit_config_name_match(const char *name)
  1001. {
  1002. if (!strcmp(name, "imx6-apalis"))
  1003. return 0;
  1004. return -1;
  1005. }
  1006. #endif
  1007. void reset_cpu(ulong addr)
  1008. {
  1009. }
  1010. #endif /* CONFIG_SPL_BUILD */
  1011. static struct mxc_serial_platdata mxc_serial_plat = {
  1012. .reg = (struct mxc_uart *)UART1_BASE,
  1013. .use_dte = true,
  1014. };
  1015. U_BOOT_DEVICE(mxc_serial) = {
  1016. .name = "serial_mxc",
  1017. .plat = &mxc_serial_plat,
  1018. };