1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2016 Nelson Integration, LLC 4 * Author: Eric Nelson <eric@nelint.com> 5 */ 6 7#include <common.h> 8#include <cpu_func.h> 9#include <init.h> 10#include <asm/global_data.h> 11#include <asm/io.h> 12#include <asm/arch/iomux.h> 13#include <asm/arch/clock.h> 14#include <asm/arch/crm_regs.h> 15#include <asm/arch/mx6-ddr.h> 16#include <asm/arch/mx6-pins.h> 17#include <asm/arch/sys_proto.h> 18#include <spl.h> 19 20DECLARE_GLOBAL_DATA_PTR; 21 22#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 23 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ 24 PAD_CTL_SRE_FAST | PAD_CTL_HYS) 25 26static iomux_v3_cfg_t const uart_pads[] = { 27#ifdef CONFIG_UART2_EIM_D26_27 28 IOMUX_PADS(PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), 29 IOMUX_PADS(PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), 30#elif defined(CONFIG_UART1_CSI0_DAT10_11) 31 IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), 32 IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), 33#elif defined(CONFIG_UART1_SD3_DAT6_7) 34 IOMUX_PADS(PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), 35 IOMUX_PADS(PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), 36#elif defined(CONFIG_UART1_UART1) 37 MX6_PAD_UART1_TXD__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL), 38 MX6_PAD_UART1_RXD__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL), 39#else 40#error select UART console pads 41#endif 42}; 43 44#ifdef CONFIG_DDR3 45#define GRP_DDRTYPE 0x000C0000 46#else 47#define GRP_DDRTYPE 0x00080000 48#endif 49 50/* all existing designs have this disabled */ 51#define DDR_PKE 0 52 53/* use Kconfig for ODT and DRIVE_STRENGTH */ 54#define DDR_ODT \ 55 (CONFIG_DDR_ODT << 8) 56#define DRAM_DRIVE_STRENGTH \ 57 (CONFIG_DRAM_DRIVE_STRENGTH << 3) 58 59/* configure MX6Q/DUAL mmdc DDR io registers */ 60static struct mx6dq_iomux_ddr_regs const mx6dq_ddr_ioregs = { 61 /* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */ 62 .dram_sdclk_0 = DDR_ODT + DRAM_DRIVE_STRENGTH, 63 .dram_sdclk_1 = DDR_ODT + DRAM_DRIVE_STRENGTH, 64 .dram_cas = DDR_ODT + DRAM_DRIVE_STRENGTH, 65 .dram_ras = DDR_ODT + DRAM_DRIVE_STRENGTH, 66 .dram_reset = DDR_ODT + DRAM_DRIVE_STRENGTH, 67 /* SDCKE[0:1]: 100k pull-up */ 68 .dram_sdcke0 = 0x00003000, 69 .dram_sdcke1 = 0x00003000, 70 /* SDBA2: pull-up disabled */ 71 .dram_sdba2 = 0x00000000, 72 /* SDODT[0:1]: 100k pull-up, 40 ohm */ 73 .dram_sdodt0 = 0x00003000 + DRAM_DRIVE_STRENGTH, 74 .dram_sdodt1 = 0x00003000 + DRAM_DRIVE_STRENGTH, 75 /* SDQS[0:7]: Differential input, 40 ohm */ 76 .dram_sdqs0 = DRAM_DRIVE_STRENGTH, 77 .dram_sdqs1 = DRAM_DRIVE_STRENGTH, 78 .dram_sdqs2 = DRAM_DRIVE_STRENGTH, 79 .dram_sdqs3 = DRAM_DRIVE_STRENGTH, 80 .dram_sdqs4 = DRAM_DRIVE_STRENGTH, 81 .dram_sdqs5 = DRAM_DRIVE_STRENGTH, 82 .dram_sdqs6 = DRAM_DRIVE_STRENGTH, 83 .dram_sdqs7 = DRAM_DRIVE_STRENGTH, 84 85 /* DQM[0:7]: Differential input, 40 ohm */ 86 .dram_dqm0 = DDR_ODT + DRAM_DRIVE_STRENGTH, 87 .dram_dqm1 = DDR_ODT + DRAM_DRIVE_STRENGTH, 88 .dram_dqm2 = DDR_ODT + DRAM_DRIVE_STRENGTH, 89 .dram_dqm3 = DDR_ODT + DRAM_DRIVE_STRENGTH, 90 .dram_dqm4 = DDR_ODT + DRAM_DRIVE_STRENGTH, 91 .dram_dqm5 = DDR_ODT + DRAM_DRIVE_STRENGTH, 92 .dram_dqm6 = DDR_ODT + DRAM_DRIVE_STRENGTH, 93 .dram_dqm7 = DDR_ODT + DRAM_DRIVE_STRENGTH, 94}; 95 96/* configure MX6Q/DUAL mmdc GRP io registers */ 97static struct mx6dq_iomux_grp_regs const mx6dq_grp_ioregs = { 98 /* DDR3 */ 99 .grp_ddr_type = GRP_DDRTYPE, 100 .grp_ddrmode_ctl = DDR_ODT, 101 /* disable DDR pullups */ 102 .grp_ddrpke = DDR_PKE, 103 /* ADDR[00:16], SDBA[0:1]: 40 ohm */ 104 .grp_addds = DRAM_DRIVE_STRENGTH, 105 /* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */ 106 .grp_ctlds = DRAM_DRIVE_STRENGTH, 107 /* DATA[00:63]: Differential input, 40 ohm */ 108 .grp_ddrmode = DDR_ODT, 109 .grp_b0ds = DRAM_DRIVE_STRENGTH, 110 .grp_b1ds = DRAM_DRIVE_STRENGTH, 111 .grp_b2ds = DRAM_DRIVE_STRENGTH, 112 .grp_b3ds = DRAM_DRIVE_STRENGTH, 113 .grp_b4ds = DRAM_DRIVE_STRENGTH, 114 .grp_b5ds = DRAM_DRIVE_STRENGTH, 115 .grp_b6ds = DRAM_DRIVE_STRENGTH, 116 .grp_b7ds = DRAM_DRIVE_STRENGTH, 117}; 118 119static struct mx6sdl_iomux_ddr_regs const mx6sdl_ddr_ioregs = { 120 /* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */ 121 .dram_sdclk_0 = DDR_ODT + DRAM_DRIVE_STRENGTH, 122 .dram_sdclk_1 = DDR_ODT + DRAM_DRIVE_STRENGTH, 123 .dram_cas = DDR_ODT + DRAM_DRIVE_STRENGTH, 124 .dram_ras = DDR_ODT + DRAM_DRIVE_STRENGTH, 125 .dram_reset = DDR_ODT + DRAM_DRIVE_STRENGTH, 126 /* SDCKE[0:1]: 100k pull-up */ 127 .dram_sdcke0 = 0x00003000, 128 .dram_sdcke1 = 0x00003000, 129 /* SDBA2: pull-up disabled */ 130 .dram_sdba2 = 0x00000000, 131 /* SDODT[0:1]: 100k pull-up, 40 ohm */ 132 .dram_sdodt0 = 0x00003000 + DRAM_DRIVE_STRENGTH, 133 .dram_sdodt1 = 0x00003000 + DRAM_DRIVE_STRENGTH, 134 /* SDQS[0:7]: Differential input, 40 ohm */ 135 .dram_sdqs0 = DRAM_DRIVE_STRENGTH, 136 .dram_sdqs1 = DRAM_DRIVE_STRENGTH, 137 .dram_sdqs2 = DRAM_DRIVE_STRENGTH, 138 .dram_sdqs3 = DRAM_DRIVE_STRENGTH, 139 .dram_sdqs4 = DRAM_DRIVE_STRENGTH, 140 .dram_sdqs5 = DRAM_DRIVE_STRENGTH, 141 .dram_sdqs6 = DRAM_DRIVE_STRENGTH, 142 .dram_sdqs7 = DRAM_DRIVE_STRENGTH, 143 144 /* DQM[0:7]: Differential input, 40 ohm */ 145 .dram_dqm0 = DDR_ODT + DRAM_DRIVE_STRENGTH, 146 .dram_dqm1 = DDR_ODT + DRAM_DRIVE_STRENGTH, 147 .dram_dqm2 = DDR_ODT + DRAM_DRIVE_STRENGTH, 148 .dram_dqm3 = DDR_ODT + DRAM_DRIVE_STRENGTH, 149 .dram_dqm4 = DDR_ODT + DRAM_DRIVE_STRENGTH, 150 .dram_dqm5 = DDR_ODT + DRAM_DRIVE_STRENGTH, 151 .dram_dqm6 = DDR_ODT + DRAM_DRIVE_STRENGTH, 152 .dram_dqm7 = DDR_ODT + DRAM_DRIVE_STRENGTH, 153}; 154 155/* configure MX6SOLO/DUALLITE mmdc GRP io registers */ 156static struct mx6sdl_iomux_grp_regs const mx6sdl_grp_ioregs = { 157 /* DDR3 */ 158 .grp_ddr_type = GRP_DDRTYPE, 159 /* SDQS[0:7]: Differential input, 40 ohm */ 160 .grp_ddrmode_ctl = DDR_ODT, 161 /* disable DDR pullups */ 162 .grp_ddrpke = DDR_PKE, 163 /* ADDR[00:16], SDBA[0:1]: 40 ohm */ 164 .grp_addds = DRAM_DRIVE_STRENGTH, 165 /* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */ 166 .grp_ctlds = DRAM_DRIVE_STRENGTH, 167 /* DATA[00:63]: Differential input, 40 ohm */ 168 .grp_ddrmode = DDR_ODT, 169 .grp_b0ds = DRAM_DRIVE_STRENGTH, 170 .grp_b1ds = DRAM_DRIVE_STRENGTH, 171 .grp_b2ds = DRAM_DRIVE_STRENGTH, 172 .grp_b3ds = DRAM_DRIVE_STRENGTH, 173 .grp_b4ds = DRAM_DRIVE_STRENGTH, 174 .grp_b5ds = DRAM_DRIVE_STRENGTH, 175 .grp_b6ds = DRAM_DRIVE_STRENGTH, 176 .grp_b7ds = DRAM_DRIVE_STRENGTH, 177}; 178 179const struct mx6sl_iomux_ddr_regs mx6sl_ddr_ioregs = { 180 .dram_sdqs0 = DRAM_DRIVE_STRENGTH, 181 .dram_sdqs1 = DRAM_DRIVE_STRENGTH, 182 .dram_sdqs2 = DRAM_DRIVE_STRENGTH, 183 .dram_sdqs3 = DRAM_DRIVE_STRENGTH, 184 .dram_dqm0 = DRAM_DRIVE_STRENGTH, 185 .dram_dqm1 = DRAM_DRIVE_STRENGTH, 186 .dram_dqm2 = DRAM_DRIVE_STRENGTH, 187 .dram_dqm3 = DRAM_DRIVE_STRENGTH, 188 .dram_cas = DRAM_DRIVE_STRENGTH, 189 .dram_ras = DRAM_DRIVE_STRENGTH, 190 .dram_sdclk_0 = DRAM_DRIVE_STRENGTH, 191 .dram_reset = DRAM_DRIVE_STRENGTH, 192 .dram_sdba2 = 0x00020000, 193 .dram_odt0 = 0x00030000 + DRAM_DRIVE_STRENGTH, 194 .dram_odt1 = 0x00030000 + DRAM_DRIVE_STRENGTH, 195}; 196 197const struct mx6sl_iomux_grp_regs mx6sl_grp_ioregs = { 198 .grp_b0ds = DRAM_DRIVE_STRENGTH, 199 .grp_b1ds = DRAM_DRIVE_STRENGTH, 200 .grp_b2ds = DRAM_DRIVE_STRENGTH, 201 .grp_b3ds = DRAM_DRIVE_STRENGTH, 202 .grp_addds = DRAM_DRIVE_STRENGTH, 203 .grp_ctlds = DRAM_DRIVE_STRENGTH, 204 .grp_ddrmode_ctl = DDR_ODT, 205 .grp_ddrpke = DDR_PKE, 206 .grp_ddrmode = DDR_ODT, 207 .grp_ddr_type = GRP_DDRTYPE, 208}; 209 210static struct mx6_ddr_sysinfo const sysinfo = { 211 /* width of data bus:0=16,1=32,2=64 */ 212#if CONFIG_DDRWIDTH == 32 213 .dsize = 1, 214#elif CONFIG_DDRWIDTH == 64 215 .dsize = 2, 216#else 217#error missing CONFIG_DDRWIDTH 218#endif 219 /* config for full 4GB range so that get_mem_size() works */ 220 .cs_density = 32, /* 32Gb per CS */ 221 222 /* # of chip selects */ 223 .ncs = CONFIG_DDRCS, 224 .cs1_mirror = 0, 225 .bi_on = 1, /* Bank interleaving enabled */ 226 .rtt_nom = CONFIG_RTT_NOM, 227 .rtt_wr = CONFIG_RTT_WR, 228 .ralat = CONFIG_RALAT, /* Read additional latency */ 229 .walat = CONFIG_WALAT, /* Write additional latency */ 230 .mif3_mode = 3, /* Command prediction working mode */ 231#ifdef CONFIG_DDR3 232 .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ 233 .sde_to_rst = 0x10, /* JEDEC value for LPDDR2 - 200us */ 234 .pd_fast_exit = 0, /* immaterial for calibration */ 235 .ddr_type = DDR_TYPE_DDR3, 236#else 237 .rst_to_cke = 0x10, /* JEDEC value for LPDDR2: 200us */ 238 .sde_to_rst = 0, /* LPDDR2 does not need this field */ 239 .pd_fast_exit = 0, /* immaterial for calibration */ 240 .ddr_type = DDR_TYPE_LPDDR2, 241#endif 242 .refsel = CONFIG_REFSEL, 243 .refr = CONFIG_REFR, 244}; 245 246#ifdef CONFIG_MT41K512M16TNA 247/* Micron MT41K512M16TNA-125 */ 248static struct mx6_ddr3_cfg const ddrtype = { 249 .mem_speed = 1600, 250 .density = 8, 251 .width = 16, 252 .banks = 8, 253 .rowaddr = 15, 254 .coladdr = 10, 255 .pagesz = 1, 256 .trcd = 1375, 257 .trcmin = 5062, 258 .trasmin = 3750, 259}; 260#elif defined(CONFIG_MT41K128M16JT) 261/* Micron MT41K128M16JT-125 */ 262static struct mx6_ddr3_cfg const ddrtype = { 263 .mem_speed = 1600, 264 .density = 2, 265 .width = 16, 266 .banks = 8, 267 .rowaddr = 14, 268 .coladdr = 10, 269 .pagesz = 2, 270 .trcd = 1375, 271 .trcmin = 4875, 272 .trasmin = 3500, 273}; 274#elif defined(CONFIG_H5TQ4G63AFR) 275/* Hynix H5TQ4G63AFR */ 276static struct mx6_ddr3_cfg const ddrtype = { 277 .mem_speed = 1600, 278 .density = 4, 279 .width = 16, 280 .banks = 8, 281 .rowaddr = 15, 282 .coladdr = 10, 283 .pagesz = 2, 284 .trcd = 1375, 285 .trcmin = 4875, 286 .trasmin = 3500, 287}; 288#elif defined CONFIG_H5TQ2G63DFR 289/* Hynix H5TQ2G63DFR */ 290static struct mx6_ddr3_cfg const ddrtype = { 291 .mem_speed = 1333, 292 .density = 2, 293 .width = 16, 294 .banks = 8, 295 .rowaddr = 14, 296 .coladdr = 10, 297 .pagesz = 2, 298 .trcd = 1350, 299 .trcmin = 4950, 300 .trasmin = 3600, 301}; 302#elif defined(CONFIG_MT42L256M32D2LG) 303/* Micron MT42L256M32D2LG */ 304static struct mx6_lpddr2_cfg ddrtype = { 305 .mem_speed = 800, 306 .density = 4, 307 .width = 32, 308 .banks = 8, 309 .rowaddr = 14, 310 .coladdr = 10, 311 .trcd_lp = 2000, 312 .trppb_lp = 2000, 313 .trpab_lp = 2250, 314 .trasmin = 4200, 315}; 316#elif defined(CONFIG_MT29PZZZ4D4BKESK) 317/* Micron MT29PZZZ4D4BKESK */ 318static struct mx6_lpddr2_cfg ddrtype = { 319 .mem_speed = 800, 320 .density = 4, 321 .width = 32, 322 .banks = 8, 323 .rowaddr = 14, 324 .coladdr = 10, 325 .trcd_lp = 2000, 326 .trppb_lp = 2000, 327 .trpab_lp = 2250, 328 .trasmin = 4200, 329}; 330#else 331#error please select DDR type using menuconfig 332#endif 333 334static void ccgr_init(void) 335{ 336 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 337 338 /* FIXME: these should probably be checked, especially 339 * for i.MX6SL, UL, ULL 340 */ 341 writel(0x00C03F3F, &ccm->CCGR0); 342 writel(0x0030FC03, &ccm->CCGR1); 343 writel(0x0FFFC000, &ccm->CCGR2); 344 writel(0x3FF00000, &ccm->CCGR3); 345 writel(0x00FFF300, &ccm->CCGR4); 346 writel(0x0F0000C3, &ccm->CCGR5); 347 writel(0x000003FF, &ccm->CCGR6); 348} 349 350static void display_calibration(struct mx6_mmdc_calibration *calib) 351{ 352 printf(".p0_mpdgctrl0\t= 0x%08X\n", calib->p0_mpdgctrl0); 353 printf(".p0_mpdgctrl1\t= 0x%08X\n", calib->p0_mpdgctrl1); 354 printf(".p0_mprddlctl\t= 0x%08X\n", calib->p0_mprddlctl); 355 printf(".p0_mpwrdlctl\t= 0x%08X\n", calib->p0_mpwrdlctl); 356 printf(".p0_mpwldectrl0\t= 0x%08X\n", calib->p0_mpwldectrl0); 357 printf(".p0_mpwldectrl1\t= 0x%08X\n", calib->p0_mpwldectrl1); 358 if (sysinfo.dsize == 2) { 359 printf(".p1_mpdgctrl0\t= 0x%08X\n", calib->p1_mpdgctrl0); 360 printf(".p1_mpdgctrl1\t= 0x%08X\n", calib->p1_mpdgctrl1); 361 printf(".p1_mprddlctl\t= 0x%08X\n", calib->p1_mprddlctl); 362 printf(".p1_mpwrdlctl\t= 0x%08X\n", calib->p1_mpwrdlctl); 363 printf(".p1_mpwldectrl0\t= 0x%08X\n", calib->p1_mpwldectrl0); 364 printf(".p1_mpwldectrl1\t= 0x%08X\n", calib->p1_mpwldectrl1); 365 } 366#ifdef CONFIG_IMXIMAGE_OUTPUT 367 printf("DATA 4 MX6_MMDC_P0_MPDGCTRL0\t= 0x%08X\n", calib->p0_mpdgctrl0); 368 printf("DATA 4 MX6_MMDC_P0_MPDGCTRL1\t= 0x%08X\n", calib->p0_mpdgctrl1); 369 printf("DATA 4 MX6_MMDC_P0_MPRDDLCTL\t= 0x%08X\n", calib->p0_mprddlctl); 370 printf("DATA 4 MX6_MMDC_P0_MPWRDLCTL\t= 0x%08X\n", calib->p0_mpwrdlctl); 371 printf("DATA 4 MX6_MMDC_P0_MPWLDECTRL0\t= 0x%08X\n", 372 calib->p0_mpwldectrl0); 373 printf("DATA 4 MX6_MMDC_P0_MPWLDECTRL1\t= 0x%08X\n", 374 calib->p0_mpwldectrl1); 375 if (sysinfo.dsize == 2) { 376 printf("DATA 4 MX6_MMDC_P1_MPDGCTRL0\t= 0x%08X\n", 377 calib->p1_mpdgctrl0); 378 printf("DATA 4 MX6_MMDC_P1_MPDGCTRL1\t= 0x%08X\n", 379 calib->p1_mpdgctrl1); 380 printf("DATA 4 MX6_MMDC_P1_MPRDDLCTL\t= 0x%08X\n", 381 calib->p1_mprddlctl); 382 printf("DATA 4 MX6_MMDC_P1_MPWRDLCTL\t= 0x%08X\n", 383 calib->p1_mpwrdlctl); 384 printf("DATA 4 MX6_MMDC_P1_MPWLDECTRL0\t= 0x%08X\n", 385 calib->p1_mpwldectrl0); 386 printf("DATA 4 MX6_MMDC_P1_MPWLDECTRL1\t= 0x%08X\n", 387 calib->p1_mpwldectrl1); 388 } 389#endif 390} 391 392/* 393 * called from C runtime startup code (arch/arm/lib/crt0.S:_main) 394 * - we have a stack and a place to store GD, both in SRAM 395 * - no variable global data is available 396 */ 397void board_init_f(ulong dummy) 398{ 399 int errs; 400 struct mx6_mmdc_calibration calibration = {0}; 401 402 memset((void *)gd, 0, sizeof(struct global_data)); 403 404 /* write leveling calibration defaults */ 405 calibration.p0_mpwrdlctl = 0x40404040; 406 calibration.p1_mpwrdlctl = 0x40404040; 407 408 /* setup AIPS and disable watchdog */ 409 arch_cpu_init(); 410 411 ccgr_init(); 412 413 SETUP_IOMUX_PADS(uart_pads); 414 415 /* setup GP timer */ 416 timer_init(); 417 418 /* UART clocks enabled and gd valid - init serial console */ 419 preloader_console_init(); 420 421 if (sysinfo.dsize != 1) { 422 if (is_cpu_type(MXC_CPU_MX6SX) || 423 is_cpu_type(MXC_CPU_MX6UL) || 424 is_cpu_type(MXC_CPU_MX6ULL) || 425 is_cpu_type(MXC_CPU_MX6SL)) { 426 printf("cpu type 0x%x doesn't support 64-bit bus\n", 427 get_cpu_type()); 428 reset_cpu(); 429 } 430 } 431#ifdef CONFIG_MX6SL 432 mx6sl_dram_iocfg(CONFIG_DDRWIDTH, &mx6sl_ddr_ioregs, 433 &mx6sl_grp_ioregs); 434#else 435 if (is_cpu_type(MXC_CPU_MX6Q)) { 436 mx6dq_dram_iocfg(CONFIG_DDRWIDTH, &mx6dq_ddr_ioregs, 437 &mx6dq_grp_ioregs); 438 } else { 439 mx6sdl_dram_iocfg(CONFIG_DDRWIDTH, &mx6sdl_ddr_ioregs, 440 &mx6sdl_grp_ioregs); 441 } 442#endif 443 mx6_dram_cfg(&sysinfo, &calibration, &ddrtype); 444 445 errs = mmdc_do_write_level_calibration(&sysinfo); 446 if (errs) { 447 printf("error %d from write level calibration\n", errs); 448 } else { 449 errs = mmdc_do_dqs_calibration(&sysinfo); 450 if (errs) { 451 printf("error %d from dqs calibration\n", errs); 452 } else { 453 printf("completed successfully\n"); 454 mmdc_read_calibration(&sysinfo, &calibration); 455 display_calibration(&calibration); 456 } 457 } 458} 459