1 /* 2 * Copyright (C) 2015 Freescale Semiconductor, Inc. 3 * 4 * Author: Fabio Estevam <fabio.estevam@freescale.com> 5 * 6 * Copyright (C) 2013 Jon Nettleton <jon.nettleton@gmail.com> 7 * 8 * Based on SPL code from Solidrun tree, which is: 9 * Author: Tungyi Lin <tungyilin1127@gmail.com> 10 * 11 * Derived from EDM_CF_IMX6 code by TechNexion,Inc 12 * Ported to SolidRun microSOM by Rabeeh Khoury <rabeeh@solid-run.com> 13 * 14 * SPDX-License-Identifier: GPL-2.0+ 15 */ 16 17 #include <asm/arch/clock.h> 18 #include <asm/arch/imx-regs.h> 19 #include <asm/arch/iomux.h> 20 #include <asm/arch/mx6-pins.h> 21 #include <asm/arch/mxc_hdmi.h> 22 #include <asm/errno.h> 23 #include <asm/gpio.h> 24 #include <asm/imx-common/iomux-v3.h> 25 #include <asm/imx-common/video.h> 26 #include <mmc.h> 27 #include <fsl_esdhc.h> 28 #include <miiphy.h> 29 #include <netdev.h> 30 #include <asm/arch/crm_regs.h> 31 #include <asm/io.h> 32 #include <asm/arch/sys_proto.h> 33 #include <spl.h> 34 35 DECLARE_GLOBAL_DATA_PTR; 36 37 #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 38 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ 39 PAD_CTL_SRE_FAST | PAD_CTL_HYS) 40 41 #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ 42 PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ 43 PAD_CTL_SRE_FAST | PAD_CTL_HYS) 44 45 #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 46 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) 47 48 #define ENET_PAD_CTRL_PD (PAD_CTL_PUS_100K_DOWN | \ 49 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) 50 51 #define ENET_PAD_CTRL_CLK ((PAD_CTL_PUS_100K_UP & ~PAD_CTL_PKE) | \ 52 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) 53 54 #define ETH_PHY_RESET IMX_GPIO_NR(4, 15) 55 56 int dram_init(void) 57 { 58 gd->ram_size = imx_ddr_size(); 59 return 0; 60 } 61 62 static iomux_v3_cfg_t const uart1_pads[] = { 63 IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), 64 IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), 65 }; 66 67 static iomux_v3_cfg_t const usdhc2_pads[] = { 68 IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 69 IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 70 IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 71 IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 72 IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 73 IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 74 }; 75 76 static iomux_v3_cfg_t const hb_cbi_sense[] = { 77 /* These pins are for sensing if it is a CuBox-i or a HummingBoard */ 78 IOMUX_PADS(PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(UART_PAD_CTRL)), 79 IOMUX_PADS(PAD_EIM_DA4__GPIO3_IO04 | MUX_PAD_CTRL(UART_PAD_CTRL)), 80 }; 81 82 static void setup_iomux_uart(void) 83 { 84 SETUP_IOMUX_PADS(uart1_pads); 85 } 86 87 static struct fsl_esdhc_cfg usdhc_cfg[1] = { 88 {USDHC2_BASE_ADDR}, 89 }; 90 91 int board_mmc_getcd(struct mmc *mmc) 92 { 93 return 1; /* uSDHC2 is always present */ 94 } 95 96 int board_mmc_init(bd_t *bis) 97 { 98 SETUP_IOMUX_PADS(usdhc2_pads); 99 usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR; 100 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); 101 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; 102 103 return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); 104 } 105 106 static iomux_v3_cfg_t const enet_pads[] = { 107 IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)), 108 IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)), 109 /* AR8035 reset */ 110 IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)), 111 /* AR8035 interrupt */ 112 IOMUX_PADS(PAD_DI0_PIN2__GPIO4_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL)), 113 /* GPIO16 -> AR8035 25MHz */ 114 IOMUX_PADS(PAD_GPIO_16__ENET_REF_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)), 115 IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(NO_PAD_CTRL)), 116 IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 117 IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 118 IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 119 IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 120 IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)), 121 /* AR8035 CLK_25M --> ENET_REF_CLK (V22) */ 122 IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL_CLK)), 123 IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)), 124 IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)), 125 IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)), 126 IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 127 IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 128 IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL_PD)), 129 }; 130 131 static void setup_iomux_enet(void) 132 { 133 SETUP_IOMUX_PADS(enet_pads); 134 135 gpio_direction_output(ETH_PHY_RESET, 0); 136 mdelay(2); 137 gpio_set_value(ETH_PHY_RESET, 1); 138 } 139 140 int board_phy_config(struct phy_device *phydev) 141 { 142 if (phydev->drv->config) 143 phydev->drv->config(phydev); 144 145 return 0; 146 } 147 148 int board_eth_init(bd_t *bis) 149 { 150 struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; 151 152 int ret = enable_fec_anatop_clock(ENET_25MHZ); 153 if (ret) 154 return ret; 155 156 /* set gpr1[ENET_CLK_SEL] */ 157 setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK); 158 159 setup_iomux_enet(); 160 161 return cpu_eth_init(bis); 162 } 163 164 #ifdef CONFIG_VIDEO_IPUV3 165 static void do_enable_hdmi(struct display_info_t const *dev) 166 { 167 imx_enable_hdmi_phy(); 168 } 169 170 struct display_info_t const displays[] = { 171 { 172 .bus = -1, 173 .addr = 0, 174 .pixfmt = IPU_PIX_FMT_RGB24, 175 .detect = detect_hdmi, 176 .enable = do_enable_hdmi, 177 .mode = { 178 .name = "HDMI", 179 /* 1024x768@60Hz (VESA)*/ 180 .refresh = 60, 181 .xres = 1024, 182 .yres = 768, 183 .pixclock = 15384, 184 .left_margin = 160, 185 .right_margin = 24, 186 .upper_margin = 29, 187 .lower_margin = 3, 188 .hsync_len = 136, 189 .vsync_len = 6, 190 .sync = FB_SYNC_EXT, 191 .vmode = FB_VMODE_NONINTERLACED 192 } 193 } 194 }; 195 196 size_t display_count = ARRAY_SIZE(displays); 197 198 static int setup_display(void) 199 { 200 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 201 int reg; 202 int timeout = 100000; 203 204 enable_ipu_clock(); 205 imx_setup_hdmi(); 206 207 /* set video pll to 455MHz (24MHz * (37+11/12) / 2) */ 208 setbits_le32(&ccm->analog_pll_video, BM_ANADIG_PLL_VIDEO_POWERDOWN); 209 210 reg = readl(&ccm->analog_pll_video); 211 reg &= ~BM_ANADIG_PLL_VIDEO_DIV_SELECT; 212 reg |= BF_ANADIG_PLL_VIDEO_DIV_SELECT(37); 213 reg &= ~BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT; 214 reg |= BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(1); 215 writel(reg, &ccm->analog_pll_video); 216 217 writel(BF_ANADIG_PLL_VIDEO_NUM_A(11), &ccm->analog_pll_video_num); 218 writel(BF_ANADIG_PLL_VIDEO_DENOM_B(12), &ccm->analog_pll_video_denom); 219 220 reg &= ~BM_ANADIG_PLL_VIDEO_POWERDOWN; 221 writel(reg, &ccm->analog_pll_video); 222 223 while (timeout--) 224 if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK) 225 break; 226 if (timeout < 0) { 227 printf("Warning: video pll lock timeout!\n"); 228 return -ETIMEDOUT; 229 } 230 231 reg = readl(&ccm->analog_pll_video); 232 reg |= BM_ANADIG_PLL_VIDEO_ENABLE; 233 reg &= ~BM_ANADIG_PLL_VIDEO_BYPASS; 234 writel(reg, &ccm->analog_pll_video); 235 236 /* gate ipu1_di0_clk */ 237 clrbits_le32(&ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK); 238 239 /* select video_pll clock / 7 for ipu1_di0_clk -> 65MHz pixclock */ 240 reg = readl(&ccm->chsccdr); 241 reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK | 242 MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK | 243 MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK); 244 reg |= (2 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET) | 245 (6 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET) | 246 (0 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET); 247 writel(reg, &ccm->chsccdr); 248 249 /* enable ipu1_di0_clk */ 250 setbits_le32(&ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK); 251 252 return 0; 253 } 254 #endif /* CONFIG_VIDEO_IPUV3 */ 255 256 int board_early_init_f(void) 257 { 258 int ret = 0; 259 setup_iomux_uart(); 260 261 #ifdef CONFIG_VIDEO_IPUV3 262 ret = setup_display(); 263 #endif 264 return ret; 265 } 266 267 int board_init(void) 268 { 269 /* address of boot parameters */ 270 gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; 271 272 return 0; 273 } 274 275 static bool is_hummingboard(void) 276 { 277 int val1, val2; 278 279 SETUP_IOMUX_PADS(hb_cbi_sense); 280 281 gpio_direction_input(IMX_GPIO_NR(4, 9)); 282 gpio_direction_input(IMX_GPIO_NR(3, 4)); 283 284 val1 = gpio_get_value(IMX_GPIO_NR(4, 9)); 285 val2 = gpio_get_value(IMX_GPIO_NR(3, 4)); 286 287 /* 288 * Machine selection - 289 * Machine val1, val2 290 * ------------------------- 291 * HB rev 3.x x 0 292 * CBi 0 1 293 * HB 1 1 294 */ 295 296 if (val2 == 0) 297 return true; 298 else if (val1 == 0) 299 return false; 300 else 301 return true; 302 } 303 304 int checkboard(void) 305 { 306 if (is_hummingboard()) 307 puts("Board: MX6 Hummingboard\n"); 308 else 309 puts("Board: MX6 Cubox-i\n"); 310 311 return 0; 312 } 313 314 static bool is_mx6q(void) 315 { 316 if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) 317 return true; 318 else 319 return false; 320 } 321 322 int board_late_init(void) 323 { 324 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 325 if (is_hummingboard()) 326 setenv("board_name", "HUMMINGBOARD"); 327 else 328 setenv("board_name", "CUBOXI"); 329 330 if (is_mx6q()) 331 setenv("board_rev", "MX6Q"); 332 else 333 setenv("board_rev", "MX6DL"); 334 #endif 335 336 return 0; 337 } 338 339 #ifdef CONFIG_SPL_BUILD 340 #include <asm/arch/mx6-ddr.h> 341 static const struct mx6dq_iomux_ddr_regs mx6q_ddr_ioregs = { 342 .dram_sdclk_0 = 0x00020030, 343 .dram_sdclk_1 = 0x00020030, 344 .dram_cas = 0x00020030, 345 .dram_ras = 0x00020030, 346 .dram_reset = 0x00020030, 347 .dram_sdcke0 = 0x00003000, 348 .dram_sdcke1 = 0x00003000, 349 .dram_sdba2 = 0x00000000, 350 .dram_sdodt0 = 0x00003030, 351 .dram_sdodt1 = 0x00003030, 352 .dram_sdqs0 = 0x00000030, 353 .dram_sdqs1 = 0x00000030, 354 .dram_sdqs2 = 0x00000030, 355 .dram_sdqs3 = 0x00000030, 356 .dram_sdqs4 = 0x00000030, 357 .dram_sdqs5 = 0x00000030, 358 .dram_sdqs6 = 0x00000030, 359 .dram_sdqs7 = 0x00000030, 360 .dram_dqm0 = 0x00020030, 361 .dram_dqm1 = 0x00020030, 362 .dram_dqm2 = 0x00020030, 363 .dram_dqm3 = 0x00020030, 364 .dram_dqm4 = 0x00020030, 365 .dram_dqm5 = 0x00020030, 366 .dram_dqm6 = 0x00020030, 367 .dram_dqm7 = 0x00020030, 368 }; 369 370 static const struct mx6sdl_iomux_ddr_regs mx6dl_ddr_ioregs = { 371 .dram_sdclk_0 = 0x00000028, 372 .dram_sdclk_1 = 0x00000028, 373 .dram_cas = 0x00000028, 374 .dram_ras = 0x00000028, 375 .dram_reset = 0x000c0028, 376 .dram_sdcke0 = 0x00003000, 377 .dram_sdcke1 = 0x00003000, 378 .dram_sdba2 = 0x00000000, 379 .dram_sdodt0 = 0x00003030, 380 .dram_sdodt1 = 0x00003030, 381 .dram_sdqs0 = 0x00000028, 382 .dram_sdqs1 = 0x00000028, 383 .dram_sdqs2 = 0x00000028, 384 .dram_sdqs3 = 0x00000028, 385 .dram_sdqs4 = 0x00000028, 386 .dram_sdqs5 = 0x00000028, 387 .dram_sdqs6 = 0x00000028, 388 .dram_sdqs7 = 0x00000028, 389 .dram_dqm0 = 0x00000028, 390 .dram_dqm1 = 0x00000028, 391 .dram_dqm2 = 0x00000028, 392 .dram_dqm3 = 0x00000028, 393 .dram_dqm4 = 0x00000028, 394 .dram_dqm5 = 0x00000028, 395 .dram_dqm6 = 0x00000028, 396 .dram_dqm7 = 0x00000028, 397 }; 398 399 static const struct mx6dq_iomux_grp_regs mx6q_grp_ioregs = { 400 .grp_ddr_type = 0x000C0000, 401 .grp_ddrmode_ctl = 0x00020000, 402 .grp_ddrpke = 0x00000000, 403 .grp_addds = 0x00000030, 404 .grp_ctlds = 0x00000030, 405 .grp_ddrmode = 0x00020000, 406 .grp_b0ds = 0x00000030, 407 .grp_b1ds = 0x00000030, 408 .grp_b2ds = 0x00000030, 409 .grp_b3ds = 0x00000030, 410 .grp_b4ds = 0x00000030, 411 .grp_b5ds = 0x00000030, 412 .grp_b6ds = 0x00000030, 413 .grp_b7ds = 0x00000030, 414 }; 415 416 static const struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = { 417 .grp_ddr_type = 0x000c0000, 418 .grp_ddrmode_ctl = 0x00020000, 419 .grp_ddrpke = 0x00000000, 420 .grp_addds = 0x00000028, 421 .grp_ctlds = 0x00000028, 422 .grp_ddrmode = 0x00020000, 423 .grp_b0ds = 0x00000028, 424 .grp_b1ds = 0x00000028, 425 .grp_b2ds = 0x00000028, 426 .grp_b3ds = 0x00000028, 427 .grp_b4ds = 0x00000028, 428 .grp_b5ds = 0x00000028, 429 .grp_b6ds = 0x00000028, 430 .grp_b7ds = 0x00000028, 431 }; 432 433 /* microSOM with Dual processor and 1GB memory */ 434 static const struct mx6_mmdc_calibration mx6q_1g_mmcd_calib = { 435 .p0_mpwldectrl0 = 0x00000000, 436 .p0_mpwldectrl1 = 0x00000000, 437 .p1_mpwldectrl0 = 0x00000000, 438 .p1_mpwldectrl1 = 0x00000000, 439 .p0_mpdgctrl0 = 0x0314031c, 440 .p0_mpdgctrl1 = 0x023e0304, 441 .p1_mpdgctrl0 = 0x03240330, 442 .p1_mpdgctrl1 = 0x03180260, 443 .p0_mprddlctl = 0x3630323c, 444 .p1_mprddlctl = 0x3436283a, 445 .p0_mpwrdlctl = 0x36344038, 446 .p1_mpwrdlctl = 0x422a423c, 447 }; 448 449 /* microSOM with Quad processor and 2GB memory */ 450 static const struct mx6_mmdc_calibration mx6q_2g_mmcd_calib = { 451 .p0_mpwldectrl0 = 0x00000000, 452 .p0_mpwldectrl1 = 0x00000000, 453 .p1_mpwldectrl0 = 0x00000000, 454 .p1_mpwldectrl1 = 0x00000000, 455 .p0_mpdgctrl0 = 0x0314031c, 456 .p0_mpdgctrl1 = 0x023e0304, 457 .p1_mpdgctrl0 = 0x03240330, 458 .p1_mpdgctrl1 = 0x03180260, 459 .p0_mprddlctl = 0x3630323c, 460 .p1_mprddlctl = 0x3436283a, 461 .p0_mpwrdlctl = 0x36344038, 462 .p1_mpwrdlctl = 0x422a423c, 463 }; 464 465 /* microSOM with Solo processor and 512MB memory */ 466 static const struct mx6_mmdc_calibration mx6dl_512m_mmcd_calib = { 467 .p0_mpwldectrl0 = 0x0045004D, 468 .p0_mpwldectrl1 = 0x003A0047, 469 .p0_mpdgctrl0 = 0x023C0224, 470 .p0_mpdgctrl1 = 0x02000220, 471 .p0_mprddlctl = 0x44444846, 472 .p0_mpwrdlctl = 0x32343032, 473 }; 474 475 /* microSOM with Dual lite processor and 1GB memory */ 476 static const struct mx6_mmdc_calibration mx6dl_1g_mmcd_calib = { 477 .p0_mpwldectrl0 = 0x0045004D, 478 .p0_mpwldectrl1 = 0x003A0047, 479 .p1_mpwldectrl0 = 0x001F001F, 480 .p1_mpwldectrl1 = 0x00210035, 481 .p0_mpdgctrl0 = 0x023C0224, 482 .p0_mpdgctrl1 = 0x02000220, 483 .p1_mpdgctrl0 = 0x02200220, 484 .p1_mpdgctrl1 = 0x02000220, 485 .p0_mprddlctl = 0x44444846, 486 .p1_mprddlctl = 0x4042463C, 487 .p0_mpwrdlctl = 0x32343032, 488 .p1_mpwrdlctl = 0x36363430, 489 }; 490 491 static struct mx6_ddr3_cfg mem_ddr_2g = { 492 .mem_speed = 1600, 493 .density = 2, 494 .width = 16, 495 .banks = 8, 496 .rowaddr = 14, 497 .coladdr = 10, 498 .pagesz = 2, 499 .trcd = 1375, 500 .trcmin = 4875, 501 .trasmin = 3500, 502 .SRT = 1, 503 }; 504 505 static struct mx6_ddr3_cfg mem_ddr_4g = { 506 .mem_speed = 1600, 507 .density = 4, 508 .width = 16, 509 .banks = 8, 510 .rowaddr = 15, 511 .coladdr = 10, 512 .pagesz = 2, 513 .trcd = 1375, 514 .trcmin = 4875, 515 .trasmin = 3500, 516 }; 517 518 static void ccgr_init(void) 519 { 520 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 521 522 writel(0x00C03F3F, &ccm->CCGR0); 523 writel(0x0030FC03, &ccm->CCGR1); 524 writel(0x0FFFC000, &ccm->CCGR2); 525 writel(0x3FF00000, &ccm->CCGR3); 526 writel(0x00FFF300, &ccm->CCGR4); 527 writel(0x0F0000C3, &ccm->CCGR5); 528 writel(0x000003FF, &ccm->CCGR6); 529 } 530 531 static void gpr_init(void) 532 { 533 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 534 535 /* enable AXI cache for VDOA/VPU/IPU */ 536 writel(0xF00000CF, &iomux->gpr[4]); 537 /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ 538 writel(0x007F007F, &iomux->gpr[6]); 539 writel(0x007F007F, &iomux->gpr[7]); 540 } 541 542 /* 543 * This section requires the differentiation between Solidrun mx6 boards, but 544 * for now, it will configure only for the mx6dual hummingboard version. 545 */ 546 static void spl_dram_init(int width) 547 { 548 struct mx6_ddr_sysinfo sysinfo = { 549 /* width of data bus: 0=16, 1=32, 2=64 */ 550 .dsize = width / 32, 551 /* config for full 4GB range so that get_mem_size() works */ 552 .cs_density = 32, /* 32Gb per CS */ 553 .ncs = 1, /* single chip select */ 554 .cs1_mirror = 0, 555 .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */ 556 .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */ 557 .walat = 1, /* Write additional latency */ 558 .ralat = 5, /* Read additional latency */ 559 .mif3_mode = 3, /* Command prediction working mode */ 560 .bi_on = 1, /* Bank interleaving enabled */ 561 .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ 562 .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ 563 }; 564 565 if (is_cpu_type(MXC_CPU_MX6D) || is_cpu_type(MXC_CPU_MX6Q)) 566 mx6dq_dram_iocfg(width, &mx6q_ddr_ioregs, &mx6q_grp_ioregs); 567 else 568 mx6sdl_dram_iocfg(width, &mx6dl_ddr_ioregs, &mx6sdl_grp_ioregs); 569 570 if (is_cpu_type(MXC_CPU_MX6D)) 571 mx6_dram_cfg(&sysinfo, &mx6q_1g_mmcd_calib, &mem_ddr_2g); 572 else if (is_cpu_type(MXC_CPU_MX6Q)) 573 mx6_dram_cfg(&sysinfo, &mx6q_2g_mmcd_calib, &mem_ddr_4g); 574 else if (is_cpu_type(MXC_CPU_MX6DL)) 575 mx6_dram_cfg(&sysinfo, &mx6q_1g_mmcd_calib, &mem_ddr_2g); 576 else if (is_cpu_type(MXC_CPU_MX6SOLO)) 577 mx6_dram_cfg(&sysinfo, &mx6dl_512m_mmcd_calib, &mem_ddr_2g); 578 } 579 580 void board_init_f(ulong dummy) 581 { 582 /* setup AIPS and disable watchdog */ 583 arch_cpu_init(); 584 585 ccgr_init(); 586 gpr_init(); 587 588 /* iomux and setup of i2c */ 589 board_early_init_f(); 590 591 /* setup GP timer */ 592 timer_init(); 593 594 /* UART clocks enabled and gd valid - init serial console */ 595 preloader_console_init(); 596 597 /* DDR initialization */ 598 if (is_cpu_type(MXC_CPU_MX6SOLO)) 599 spl_dram_init(32); 600 else 601 spl_dram_init(64); 602 603 /* Clear the BSS. */ 604 memset(__bss_start, 0, __bss_end - __bss_start); 605 606 /* load/boot image from boot device */ 607 board_init_r(NULL, 0); 608 } 609 #endif 610