uboot/board/liebherr/display5/spl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2017 DENX Software Engineering
   4 * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
   5 */
   6
   7#include <common.h>
   8#include <spl.h>
   9#include <linux/libfdt.h>
  10#include <asm/io.h>
  11#include <asm/arch/clock.h>
  12#include <asm/arch/mx6-ddr.h>
  13#include <asm/arch/mx6-pins.h>
  14#include "asm/arch/crm_regs.h"
  15#include <asm/arch/sys_proto.h>
  16#include <asm/arch/imx-regs.h>
  17#include "asm/arch/iomux.h"
  18#include <asm/mach-imx/iomux-v3.h>
  19#include <asm/gpio.h>
  20#include <environment.h>
  21#include <fsl_esdhc.h>
  22#include <netdev.h>
  23#include <bootcount.h>
  24#include <watchdog.h>
  25#include "common.h"
  26
  27DECLARE_GLOBAL_DATA_PTR;
  28
  29static const struct mx6dq_iomux_ddr_regs mx6_ddr_ioregs = {
  30        .dram_sdclk_0 = 0x00000030,
  31        .dram_sdclk_1 = 0x00000030,
  32        .dram_cas = 0x00000030,
  33        .dram_ras = 0x00000030,
  34        .dram_reset = 0x00000030,
  35        .dram_sdcke0 = 0x00003000,
  36        .dram_sdcke1 = 0x00003000,
  37        .dram_sdba2 = 0x00000000,
  38        .dram_sdodt0 = 0x00000030,
  39        .dram_sdodt1 = 0x00000030,
  40
  41        .dram_sdqs0 = 0x00000030,
  42        .dram_sdqs1 = 0x00000030,
  43        .dram_sdqs2 = 0x00000030,
  44        .dram_sdqs3 = 0x00000030,
  45        .dram_sdqs4 = 0x00000030,
  46        .dram_sdqs5 = 0x00000030,
  47        .dram_sdqs6 = 0x00000030,
  48        .dram_sdqs7 = 0x00000030,
  49
  50        .dram_dqm0 = 0x00000030,
  51        .dram_dqm1 = 0x00000030,
  52        .dram_dqm2 = 0x00000030,
  53        .dram_dqm3 = 0x00000030,
  54        .dram_dqm4 = 0x00000030,
  55        .dram_dqm5 = 0x00000030,
  56        .dram_dqm6 = 0x00000030,
  57        .dram_dqm7 = 0x00000030,
  58};
  59
  60static const struct mx6dq_iomux_grp_regs mx6_grp_ioregs = {
  61        .grp_ddr_type = 0x000c0000,
  62        .grp_ddrmode_ctl = 0x00020000,
  63        .grp_ddrpke = 0x00000000,
  64        .grp_addds = 0x00000030,
  65        .grp_ctlds = 0x00000030,
  66        .grp_ddrmode = 0x00020000,
  67        .grp_b0ds = 0x00000030,
  68        .grp_b1ds = 0x00000030,
  69        .grp_b2ds = 0x00000030,
  70        .grp_b3ds = 0x00000030,
  71        .grp_b4ds = 0x00000030,
  72        .grp_b5ds = 0x00000030,
  73        .grp_b6ds = 0x00000030,
  74        .grp_b7ds = 0x00000030,
  75};
  76
  77/* 4x128Mx16.cfg */
  78static const struct mx6_mmdc_calibration mx6_4x256mx16_mmdc_calib = {
  79        .p0_mpwldectrl0 = 0x002D0028,
  80        .p0_mpwldectrl1 = 0x0032002D,
  81        .p1_mpwldectrl0 = 0x00210036,
  82        .p1_mpwldectrl1 = 0x0019002E,
  83        .p0_mpdgctrl0 = 0x4349035C,
  84        .p0_mpdgctrl1 = 0x0348033D,
  85        .p1_mpdgctrl0 = 0x43550362,
  86        .p1_mpdgctrl1 = 0x03520316,
  87        .p0_mprddlctl = 0x41393940,
  88        .p1_mprddlctl = 0x3F3A3C47,
  89        .p0_mpwrdlctl = 0x413A423A,
  90        .p1_mpwrdlctl = 0x4042483E,
  91};
  92
  93/* MT41K128M16JT-125 (2Gb density) */
  94static const struct mx6_ddr3_cfg mt41k128m16jt_125 = {
  95        .mem_speed = 1600,
  96        .density = 2,
  97        .width = 16,
  98        .banks = 8,
  99        .rowaddr = 14,
 100        .coladdr = 10,
 101        .pagesz = 2,
 102        .trcd = 1375,
 103        .trcmin = 4875,
 104        .trasmin = 3500,
 105};
 106
 107static void ccgr_init(void)
 108{
 109        struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 110
 111        writel(0x00C03F3F, &ccm->CCGR0);
 112        writel(0x0030FC3F, &ccm->CCGR1);
 113        writel(0x0FFFCFC0, &ccm->CCGR2);
 114        writel(0x3FF00000, &ccm->CCGR3);
 115        writel(0x00FFF300, &ccm->CCGR4);
 116        writel(0x0F0000C3, &ccm->CCGR5);
 117        writel(0x000003FF, &ccm->CCGR6);
 118}
 119
 120#ifdef CONFIG_MX6_DDRCAL
 121static void spl_dram_print_cal(struct mx6_ddr_sysinfo const *sysinfo)
 122{
 123        struct mx6_mmdc_calibration calibration = {0};
 124
 125        mmdc_read_calibration(sysinfo, &calibration);
 126
 127        debug(".p0_mpdgctrl0\t= 0x%08X\n", calibration.p0_mpdgctrl0);
 128        debug(".p0_mpdgctrl1\t= 0x%08X\n", calibration.p0_mpdgctrl1);
 129        debug(".p0_mprddlctl\t= 0x%08X\n", calibration.p0_mprddlctl);
 130        debug(".p0_mpwrdlctl\t= 0x%08X\n", calibration.p0_mpwrdlctl);
 131        debug(".p0_mpwldectrl0\t= 0x%08X\n", calibration.p0_mpwldectrl0);
 132        debug(".p0_mpwldectrl1\t= 0x%08X\n", calibration.p0_mpwldectrl1);
 133        debug(".p1_mpdgctrl0\t= 0x%08X\n", calibration.p1_mpdgctrl0);
 134        debug(".p1_mpdgctrl1\t= 0x%08X\n", calibration.p1_mpdgctrl1);
 135        debug(".p1_mprddlctl\t= 0x%08X\n", calibration.p1_mprddlctl);
 136        debug(".p1_mpwrdlctl\t= 0x%08X\n", calibration.p1_mpwrdlctl);
 137        debug(".p1_mpwldectrl0\t= 0x%08X\n", calibration.p1_mpwldectrl0);
 138        debug(".p1_mpwldectrl1\t= 0x%08X\n", calibration.p1_mpwldectrl1);
 139}
 140
 141static void spl_dram_perform_cal(struct mx6_ddr_sysinfo const *sysinfo)
 142{
 143        int ret;
 144
 145        /* Perform DDR DRAM calibration */
 146        udelay(100);
 147        ret = mmdc_do_write_level_calibration(sysinfo);
 148        if (ret) {
 149                printf("DDR: Write level calibration error [%d]\n", ret);
 150                return;
 151        }
 152
 153        ret = mmdc_do_dqs_calibration(sysinfo);
 154        if (ret) {
 155                printf("DDR: DQS calibration error [%d]\n", ret);
 156                return;
 157        }
 158
 159        spl_dram_print_cal(sysinfo);
 160}
 161#endif /* CONFIG_MX6_DDRCAL */
 162
 163static void spl_dram_init(void)
 164{
 165        struct mx6_ddr_sysinfo sysinfo = {
 166                /* width of data bus:0=16,1=32,2=64 */
 167                .dsize = 2,
 168                /* config for full 4GB range so that get_mem_size() works */
 169                .cs_density = 32, /* 32Gb per CS */
 170                /* single chip select */
 171                .ncs = 1,
 172                .cs1_mirror = 0,
 173                .rtt_wr = 1 /*DDR3_RTT_60_OHM*/,        /* RTT_Wr = RZQ/4 */
 174                .rtt_nom = 2 /*DDR3_RTT_120_OHM*/,      /* RTT_Nom = RZQ/2 */
 175                .walat = 1,     /* Write additional latency */
 176                .ralat = 5,     /* Read additional latency */
 177                .mif3_mode = 3, /* Command prediction working mode */
 178                .bi_on = 1,     /* Bank interleaving enabled */
 179                .sde_to_rst = 0x10,     /* 14 cycles, 200us (JEDEC default) */
 180                .rst_to_cke = 0x23,     /* 33 cycles, 500us (JEDEC default) */
 181                .pd_fast_exit = 1, /* enable precharge power-down fast exit */
 182                .ddr_type = DDR_TYPE_DDR3,
 183                .refsel = 1,    /* Refresh cycles at 32KHz */
 184                .refr = 7,      /* 8 refresh commands per refresh cycle */
 185        };
 186
 187        mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs);
 188        mx6_dram_cfg(&sysinfo, &mx6_4x256mx16_mmdc_calib, &mt41k128m16jt_125);
 189
 190#ifdef CONFIG_MX6_DDRCAL
 191        spl_dram_perform_cal(&sysinfo);
 192#endif
 193}
 194
 195#ifdef CONFIG_SPL_SPI_SUPPORT
 196static void displ5_init_ecspi(void)
 197{
 198        displ5_set_iomux_ecspi_spl();
 199        enable_spi_clk(1, 1);
 200}
 201#else
 202static inline void displ5_init_ecspi(void) { }
 203#endif
 204
 205#ifdef CONFIG_SPL_MMC_SUPPORT
 206static struct fsl_esdhc_cfg usdhc_cfg = {
 207        .esdhc_base = USDHC4_BASE_ADDR,
 208        .max_bus_width = 8,
 209};
 210
 211int board_mmc_init(bd_t *bd)
 212{
 213        displ5_set_iomux_usdhc_spl();
 214
 215        usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
 216        gd->arch.sdhc_clk = usdhc_cfg.sdhc_clk;
 217
 218        return fsl_esdhc_initialize(bd, &usdhc_cfg);
 219}
 220#endif
 221
 222void board_init_f(ulong dummy)
 223{
 224        ccgr_init();
 225
 226        arch_cpu_init();
 227
 228        gpr_init();
 229
 230        /* setup GP timer */
 231        timer_init();
 232
 233        displ5_set_iomux_uart_spl();
 234
 235        /* UART clocks enabled and gd valid - init serial console */
 236        preloader_console_init();
 237
 238        displ5_init_ecspi();
 239
 240        /* DDR initialization */
 241        spl_dram_init();
 242
 243        /* Clear the BSS. */
 244        memset(__bss_start, 0, __bss_end - __bss_start);
 245
 246        displ5_set_iomux_misc_spl();
 247
 248        /* Initialize and reset WDT in SPL */
 249        hw_watchdog_init();
 250        WATCHDOG_RESET();
 251
 252        /* load/boot image from boot device */
 253        board_init_r(NULL, 0);
 254}
 255
 256#define EM_PAD IMX_GPIO_NR(3, 29)
 257int board_check_emergency_pad(void)
 258{
 259        int ret;
 260
 261        ret = gpio_direction_input(EM_PAD);
 262        if (ret)
 263                return ret;
 264
 265        return !gpio_get_value(EM_PAD);
 266}
 267
 268void board_boot_order(u32 *spl_boot_list)
 269{
 270        /* Default boot sequence SPI -> MMC */
 271        spl_boot_list[0] = spl_boot_device();
 272        spl_boot_list[1] = BOOT_DEVICE_MMC1;
 273        spl_boot_list[2] = BOOT_DEVICE_UART;
 274        spl_boot_list[3] = BOOT_DEVICE_NONE;
 275
 276        /*
 277         * In case of emergency PAD pressed, we always boot
 278         * to proper u-boot and perform recovery tasks there.
 279         */
 280        if (board_check_emergency_pad())
 281                return;
 282
 283#ifdef CONFIG_SPL_ENV_SUPPORT
 284        /* 'fastboot' */
 285        const char *s;
 286
 287        if (env_init() || env_load())
 288                return;
 289
 290        s = env_get("BOOT_FROM");
 291        if (s && !bootcount_error() && strcmp(s, "ACTIVE") == 0) {
 292                spl_boot_list[0] = BOOT_DEVICE_MMC1;
 293                spl_boot_list[1] = spl_boot_device();
 294        }
 295#endif
 296}
 297
 298void reset_cpu(ulong addr) {}
 299
 300#ifdef CONFIG_SPL_LOAD_FIT
 301int board_fit_config_name_match(const char *name)
 302{
 303        return 0;
 304}
 305#endif
 306
 307#ifdef CONFIG_SPL_OS_BOOT
 308/* Return: 1 - boot to U-Boot. 0 - boot OS (falcon mode) */
 309int spl_start_uboot(void)
 310{
 311        /* break into full u-boot on 'c' */
 312        if (serial_tstc() && serial_getc() == 'c')
 313                return 1;
 314
 315#ifdef CONFIG_SPL_ENV_SUPPORT
 316        if (env_get_yesno("boot_os") != 1)
 317                return 1;
 318#endif
 319        return 0;
 320}
 321#endif
 322