uboot/board/engicam/common/spl.c
<<
>>
Prefs
   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
   8#include <common.h>
   9#include <serial.h>
  10#include <spl.h>
  11
  12#include <asm/io.h>
  13#include <asm/gpio.h>
  14#include <linux/sizes.h>
  15
  16#include <asm/arch/clock.h>
  17#include <asm/arch/crm_regs.h>
  18#include <asm/arch/iomux.h>
  19#include <asm/arch/mx6-ddr.h>
  20#include <asm/arch/mx6-pins.h>
  21#include <asm/arch/sys_proto.h>
  22
  23#include <asm/mach-imx/iomux-v3.h>
  24#include <asm/mach-imx/video.h>
  25
  26#define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |             \
  27        PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
  28        PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
  29
  30static iomux_v3_cfg_t const uart_pads[] = {
  31#ifdef CONFIG_MX6QDL
  32        IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
  33        IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
  34#elif CONFIG_MX6UL
  35        IOMUX_PADS(PAD_UART1_TX_DATA__UART1_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL)),
  36        IOMUX_PADS(PAD_UART1_RX_DATA__UART1_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL)),
  37#endif
  38};
  39
  40#ifdef CONFIG_SPL_LOAD_FIT
  41int board_fit_config_name_match(const char *name)
  42{
  43        if (is_mx6dq() && !strcmp(name, "imx6q-icore"))
  44                return 0;
  45        else if (is_mx6dq() && !strcmp(name, "imx6q-icore-rqs"))
  46                return 0;
  47        else if (is_mx6dq() && !strcmp(name, "imx6q-icore-mipi"))
  48                return 0;
  49        else if ((is_mx6dl() || is_mx6solo()) && !strcmp(name, "imx6dl-icore"))
  50                return 0;
  51        else if ((is_mx6dl() || is_mx6solo()) && !strcmp(name, "imx6dl-icore-rqs"))
  52                return 0;
  53        else if ((is_mx6dl() || is_mx6solo()) && !strcmp(name, "imx6dl-icore-mipi"))
  54                return 0;
  55        else
  56                return -1;
  57}
  58#endif
  59
  60#ifdef CONFIG_ENV_IS_IN_MMC
  61void board_boot_order(u32 *spl_boot_list)
  62{
  63        u32 bmode = imx6_src_get_boot_mode();
  64        u8 boot_dev = BOOT_DEVICE_MMC1;
  65
  66        switch ((bmode & IMX6_BMODE_MASK) >> IMX6_BMODE_SHIFT) {
  67        case IMX6_BMODE_SD:
  68        case IMX6_BMODE_ESD:
  69                /* SD/eSD - BOOT_DEVICE_MMC1 */
  70                break;
  71        case IMX6_BMODE_MMC:
  72        case IMX6_BMODE_EMMC:
  73                /* MMC/eMMC */
  74                boot_dev = BOOT_DEVICE_MMC2;
  75                break;
  76        default:
  77                /* Default - BOOT_DEVICE_MMC1 */
  78                printf("Wrong board boot order\n");
  79                break;
  80        }
  81
  82        spl_boot_list[0] = boot_dev;
  83}
  84#endif
  85
  86#ifdef CONFIG_SPL_OS_BOOT
  87int spl_start_uboot(void)
  88{
  89        /* break into full u-boot on 'c' */
  90        if (serial_tstc() && serial_getc() == 'c')
  91                return 1;
  92
  93        return 0;
  94}
  95#endif
  96
  97#ifdef CONFIG_MX6QDL
  98/*
  99 * Driving strength:
 100 *   0x30 == 40 Ohm
 101 *   0x28 == 48 Ohm
 102 */
 103#define IMX6DQ_DRIVE_STRENGTH           0x30
 104#define IMX6SDL_DRIVE_STRENGTH          0x28
 105
 106/* configure MX6Q/DUAL mmdc DDR io registers */
 107static struct mx6dq_iomux_ddr_regs mx6dq_ddr_ioregs = {
 108        .dram_sdqs0 = IMX6DQ_DRIVE_STRENGTH,
 109        .dram_sdqs1 = IMX6DQ_DRIVE_STRENGTH,
 110        .dram_sdqs2 = IMX6DQ_DRIVE_STRENGTH,
 111        .dram_sdqs3 = IMX6DQ_DRIVE_STRENGTH,
 112        .dram_sdqs4 = IMX6DQ_DRIVE_STRENGTH,
 113        .dram_sdqs5 = IMX6DQ_DRIVE_STRENGTH,
 114        .dram_sdqs6 = IMX6DQ_DRIVE_STRENGTH,
 115        .dram_sdqs7 = IMX6DQ_DRIVE_STRENGTH,
 116        .dram_dqm0 = IMX6DQ_DRIVE_STRENGTH,
 117        .dram_dqm1 = IMX6DQ_DRIVE_STRENGTH,
 118        .dram_dqm2 = IMX6DQ_DRIVE_STRENGTH,
 119        .dram_dqm3 = IMX6DQ_DRIVE_STRENGTH,
 120        .dram_dqm4 = IMX6DQ_DRIVE_STRENGTH,
 121        .dram_dqm5 = IMX6DQ_DRIVE_STRENGTH,
 122        .dram_dqm6 = IMX6DQ_DRIVE_STRENGTH,
 123        .dram_dqm7 = IMX6DQ_DRIVE_STRENGTH,
 124        .dram_cas = IMX6DQ_DRIVE_STRENGTH,
 125        .dram_ras = IMX6DQ_DRIVE_STRENGTH,
 126        .dram_sdclk_0 = IMX6DQ_DRIVE_STRENGTH,
 127        .dram_sdclk_1 = IMX6DQ_DRIVE_STRENGTH,
 128        .dram_reset = IMX6DQ_DRIVE_STRENGTH,
 129        .dram_sdcke0 = IMX6DQ_DRIVE_STRENGTH,
 130        .dram_sdcke1 = IMX6DQ_DRIVE_STRENGTH,
 131        .dram_sdba2 = 0x00000000,
 132        .dram_sdodt0 = IMX6DQ_DRIVE_STRENGTH,
 133        .dram_sdodt1 = IMX6DQ_DRIVE_STRENGTH,
 134};
 135
 136/* configure MX6Q/DUAL mmdc GRP io registers */
 137static struct mx6dq_iomux_grp_regs mx6dq_grp_ioregs = {
 138        .grp_b0ds = IMX6DQ_DRIVE_STRENGTH,
 139        .grp_b1ds = IMX6DQ_DRIVE_STRENGTH,
 140        .grp_b2ds = IMX6DQ_DRIVE_STRENGTH,
 141        .grp_b3ds = IMX6DQ_DRIVE_STRENGTH,
 142        .grp_b4ds = IMX6DQ_DRIVE_STRENGTH,
 143        .grp_b5ds = IMX6DQ_DRIVE_STRENGTH,
 144        .grp_b6ds = IMX6DQ_DRIVE_STRENGTH,
 145        .grp_b7ds = IMX6DQ_DRIVE_STRENGTH,
 146        .grp_addds = IMX6DQ_DRIVE_STRENGTH,
 147        .grp_ddrmode_ctl = 0x00020000,
 148        .grp_ddrpke = 0x00000000,
 149        .grp_ddrmode = 0x00020000,
 150        .grp_ctlds = IMX6DQ_DRIVE_STRENGTH,
 151        .grp_ddr_type = 0x000c0000,
 152};
 153
 154/* configure MX6SOLO/DUALLITE mmdc DDR io registers */
 155struct mx6sdl_iomux_ddr_regs mx6sdl_ddr_ioregs = {
 156        .dram_sdclk_0 = IMX6SDL_DRIVE_STRENGTH,
 157        .dram_sdclk_1 = IMX6SDL_DRIVE_STRENGTH,
 158        .dram_cas = IMX6SDL_DRIVE_STRENGTH,
 159        .dram_ras = IMX6SDL_DRIVE_STRENGTH,
 160        .dram_reset = IMX6SDL_DRIVE_STRENGTH,
 161        .dram_sdcke0 = IMX6SDL_DRIVE_STRENGTH,
 162        .dram_sdcke1 = IMX6SDL_DRIVE_STRENGTH,
 163        .dram_sdba2 = 0x00000000,
 164        .dram_sdodt0 = IMX6SDL_DRIVE_STRENGTH,
 165        .dram_sdodt1 = IMX6SDL_DRIVE_STRENGTH,
 166        .dram_sdqs0 = IMX6SDL_DRIVE_STRENGTH,
 167        .dram_sdqs1 = IMX6SDL_DRIVE_STRENGTH,
 168        .dram_sdqs2 = IMX6SDL_DRIVE_STRENGTH,
 169        .dram_sdqs3 = IMX6SDL_DRIVE_STRENGTH,
 170        .dram_sdqs4 = IMX6SDL_DRIVE_STRENGTH,
 171        .dram_sdqs5 = IMX6SDL_DRIVE_STRENGTH,
 172        .dram_sdqs6 = IMX6SDL_DRIVE_STRENGTH,
 173        .dram_sdqs7 = IMX6SDL_DRIVE_STRENGTH,
 174        .dram_dqm0 = IMX6SDL_DRIVE_STRENGTH,
 175        .dram_dqm1 = IMX6SDL_DRIVE_STRENGTH,
 176        .dram_dqm2 = IMX6SDL_DRIVE_STRENGTH,
 177        .dram_dqm3 = IMX6SDL_DRIVE_STRENGTH,
 178        .dram_dqm4 = IMX6SDL_DRIVE_STRENGTH,
 179        .dram_dqm5 = IMX6SDL_DRIVE_STRENGTH,
 180        .dram_dqm6 = IMX6SDL_DRIVE_STRENGTH,
 181        .dram_dqm7 = IMX6SDL_DRIVE_STRENGTH,
 182};
 183
 184/* configure MX6SOLO/DUALLITE mmdc GRP io registers */
 185struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = {
 186        .grp_ddr_type = 0x000c0000,
 187        .grp_ddrmode_ctl = 0x00020000,
 188        .grp_ddrpke = 0x00000000,
 189        .grp_addds = IMX6SDL_DRIVE_STRENGTH,
 190        .grp_ctlds = IMX6SDL_DRIVE_STRENGTH,
 191        .grp_ddrmode = 0x00020000,
 192        .grp_b0ds = IMX6SDL_DRIVE_STRENGTH,
 193        .grp_b1ds = IMX6SDL_DRIVE_STRENGTH,
 194        .grp_b2ds = IMX6SDL_DRIVE_STRENGTH,
 195        .grp_b3ds = IMX6SDL_DRIVE_STRENGTH,
 196        .grp_b4ds = IMX6SDL_DRIVE_STRENGTH,
 197        .grp_b5ds = IMX6SDL_DRIVE_STRENGTH,
 198        .grp_b6ds = IMX6SDL_DRIVE_STRENGTH,
 199        .grp_b7ds = IMX6SDL_DRIVE_STRENGTH,
 200};
 201
 202/* mt41j256 */
 203static struct mx6_ddr3_cfg mt41j256 = {
 204        .mem_speed = 1066,
 205        .density = 2,
 206        .width = 16,
 207        .banks = 8,
 208        .rowaddr = 13,
 209        .coladdr = 10,
 210        .pagesz = 2,
 211        .trcd = 1375,
 212        .trcmin = 4875,
 213        .trasmin = 3500,
 214        .SRT = 0,
 215};
 216
 217static struct mx6_mmdc_calibration mx6dq_mmdc_calib = {
 218        .p0_mpwldectrl0 = 0x000E0009,
 219        .p0_mpwldectrl1 = 0x0018000E,
 220        .p1_mpwldectrl0 = 0x00000007,
 221        .p1_mpwldectrl1 = 0x00000000,
 222        .p0_mpdgctrl0 = 0x43280334,
 223        .p0_mpdgctrl1 = 0x031C0314,
 224        .p1_mpdgctrl0 = 0x4318031C,
 225        .p1_mpdgctrl1 = 0x030C0258,
 226        .p0_mprddlctl = 0x3E343A40,
 227        .p1_mprddlctl = 0x383C3844,
 228        .p0_mpwrdlctl = 0x40404440,
 229        .p1_mpwrdlctl = 0x4C3E4446,
 230};
 231
 232/* DDR 64bit */
 233static struct mx6_ddr_sysinfo mem_q = {
 234        .ddr_type       = DDR_TYPE_DDR3,
 235        .dsize          = 2,
 236        .cs1_mirror     = 0,
 237        /* config for full 4GB range so that get_mem_size() works */
 238        .cs_density     = 32,
 239        .ncs            = 1,
 240        .bi_on          = 1,
 241        .rtt_nom        = 2,
 242        .rtt_wr         = 2,
 243        .ralat          = 5,
 244        .walat          = 0,
 245        .mif3_mode      = 3,
 246        .rst_to_cke     = 0x23,
 247        .sde_to_rst     = 0x10,
 248};
 249
 250static struct mx6_mmdc_calibration mx6dl_mmdc_calib = {
 251        .p0_mpwldectrl0 = 0x001F0024,
 252        .p0_mpwldectrl1 = 0x00110018,
 253        .p1_mpwldectrl0 = 0x001F0024,
 254        .p1_mpwldectrl1 = 0x00110018,
 255        .p0_mpdgctrl0 = 0x4230022C,
 256        .p0_mpdgctrl1 = 0x02180220,
 257        .p1_mpdgctrl0 = 0x42440248,
 258        .p1_mpdgctrl1 = 0x02300238,
 259        .p0_mprddlctl = 0x44444A48,
 260        .p1_mprddlctl = 0x46484A42,
 261        .p0_mpwrdlctl = 0x38383234,
 262        .p1_mpwrdlctl = 0x3C34362E,
 263};
 264
 265/* DDR 64bit 1GB */
 266static struct mx6_ddr_sysinfo mem_dl = {
 267        .dsize          = 2,
 268        .cs1_mirror     = 0,
 269        /* config for full 4GB range so that get_mem_size() works */
 270        .cs_density     = 32,
 271        .ncs            = 1,
 272        .bi_on          = 1,
 273        .rtt_nom        = 1,
 274        .rtt_wr         = 1,
 275        .ralat          = 5,
 276        .walat          = 0,
 277        .mif3_mode      = 3,
 278        .rst_to_cke     = 0x23,
 279        .sde_to_rst     = 0x10,
 280};
 281
 282/* DDR 32bit 512MB */
 283static struct mx6_ddr_sysinfo mem_s = {
 284        .dsize          = 1,
 285        .cs1_mirror     = 0,
 286        /* config for full 4GB range so that get_mem_size() works */
 287        .cs_density     = 32,
 288        .ncs            = 1,
 289        .bi_on          = 1,
 290        .rtt_nom        = 1,
 291        .rtt_wr         = 1,
 292        .ralat          = 5,
 293        .walat          = 0,
 294        .mif3_mode      = 3,
 295        .rst_to_cke     = 0x23,
 296        .sde_to_rst     = 0x10,
 297};
 298#endif /* CONFIG_MX6QDL */
 299
 300#ifdef CONFIG_MX6UL
 301static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = {
 302        .grp_addds = 0x00000030,
 303        .grp_ddrmode_ctl = 0x00020000,
 304        .grp_b0ds = 0x00000030,
 305        .grp_ctlds = 0x00000030,
 306        .grp_b1ds = 0x00000030,
 307        .grp_ddrpke = 0x00000000,
 308        .grp_ddrmode = 0x00020000,
 309        .grp_ddr_type = 0x000c0000,
 310};
 311
 312static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = {
 313        .dram_dqm0 = 0x00000030,
 314        .dram_dqm1 = 0x00000030,
 315        .dram_ras = 0x00000030,
 316        .dram_cas = 0x00000030,
 317        .dram_odt0 = 0x00000030,
 318        .dram_odt1 = 0x00000030,
 319        .dram_sdba2 = 0x00000000,
 320        .dram_sdclk_0 = 0x00000008,
 321        .dram_sdqs0 = 0x00000038,
 322        .dram_sdqs1 = 0x00000030,
 323        .dram_reset = 0x00000030,
 324};
 325
 326static struct mx6_mmdc_calibration mx6_mmcd_calib = {
 327        .p0_mpwldectrl0 = 0x00070007,
 328        .p0_mpdgctrl0 = 0x41490145,
 329        .p0_mprddlctl = 0x40404546,
 330        .p0_mpwrdlctl = 0x4040524D,
 331};
 332
 333struct mx6_ddr_sysinfo ddr_sysinfo = {
 334        .dsize = 0,
 335        .cs_density = 20,
 336        .ncs = 1,
 337        .cs1_mirror = 0,
 338        .rtt_wr = 2,
 339        .rtt_nom = 1,           /* RTT_Nom = RZQ/2 */
 340        .walat = 1,             /* Write additional latency */
 341        .ralat = 5,             /* Read additional latency */
 342        .mif3_mode = 3,         /* Command prediction working mode */
 343        .bi_on = 1,             /* Bank interleaving enabled */
 344        .sde_to_rst = 0x10,     /* 14 cycles, 200us (JEDEC default) */
 345        .rst_to_cke = 0x23,     /* 33 cycles, 500us (JEDEC default) */
 346        .ddr_type = DDR_TYPE_DDR3,
 347};
 348
 349static struct mx6_ddr3_cfg mem_ddr = {
 350        .mem_speed = 800,
 351        .density = 4,
 352        .width = 16,
 353        .banks = 8,
 354#ifdef TARGET_MX6UL_ISIOT
 355        .rowaddr = 15,
 356#else
 357        .rowaddr = 13,
 358#endif
 359        .coladdr = 10,
 360        .pagesz = 2,
 361        .trcd = 1375,
 362        .trcmin = 4875,
 363        .trasmin = 3500,
 364};
 365#endif /* CONFIG_MX6UL */
 366
 367static void ccgr_init(void)
 368{
 369        struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 370
 371#ifdef CONFIG_MX6QDL
 372        writel(0x00003F3F, &ccm->CCGR0);
 373        writel(0x0030FC00, &ccm->CCGR1);
 374        writel(0x000FC000, &ccm->CCGR2);
 375        writel(0x3F300000, &ccm->CCGR3);
 376        writel(0xFF00F300, &ccm->CCGR4);
 377        writel(0x0F0000C3, &ccm->CCGR5);
 378        writel(0x000003CC, &ccm->CCGR6);
 379#elif CONFIG_MX6UL
 380        writel(0x00c03f3f, &ccm->CCGR0);
 381        writel(0xfcffff00, &ccm->CCGR1);
 382        writel(0x0cffffcc, &ccm->CCGR2);
 383        writel(0x3f3c3030, &ccm->CCGR3);
 384        writel(0xff00fffc, &ccm->CCGR4);
 385        writel(0x033f30ff, &ccm->CCGR5);
 386        writel(0x00c00fff, &ccm->CCGR6);
 387#endif
 388}
 389
 390static void spl_dram_init(void)
 391{
 392#ifdef CONFIG_MX6QDL
 393        if (is_mx6solo()) {
 394                mx6sdl_dram_iocfg(32, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs);
 395                mx6_dram_cfg(&mem_s, &mx6dl_mmdc_calib, &mt41j256);
 396        } else if (is_mx6dl()) {
 397                mx6sdl_dram_iocfg(64, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs);
 398                mx6_dram_cfg(&mem_dl, &mx6dl_mmdc_calib, &mt41j256);
 399        } else if (is_mx6dq()) {
 400                mx6dq_dram_iocfg(64, &mx6dq_ddr_ioregs, &mx6dq_grp_ioregs);
 401                mx6_dram_cfg(&mem_q, &mx6dq_mmdc_calib, &mt41j256);
 402        }
 403#elif CONFIG_MX6UL
 404        mx6ul_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
 405        mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr);
 406#endif
 407
 408        udelay(100);
 409}
 410
 411void board_init_f(ulong dummy)
 412{
 413        ccgr_init();
 414
 415        /* setup AIPS and disable watchdog */
 416        arch_cpu_init();
 417
 418        if (!(is_mx6ul()))
 419                gpr_init();
 420
 421        /* iomux */
 422        SETUP_IOMUX_PADS(uart_pads);
 423
 424        /* setup GP timer */
 425        timer_init();
 426
 427        /* UART clocks enabled and gd valid - init serial console */
 428        preloader_console_init();
 429
 430        /* DDR initialization */
 431        spl_dram_init();
 432}
 433