uboot/board/seeed/npi_imx6ull/spl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2021 Linumiz
   4 * Author: Navin Sankar Velliangiri <navin@linumiz.com>
   5 */
   6
   7#include <common.h>
   8#include <init.h>
   9#include <spl.h>
  10#include <asm/arch/clock.h>
  11#include <asm/io.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 <fsl_esdhc_imx.h>
  17
  18/* Configuration for Micron MT41K256M16TW-107 32M x 16 x 8 -> 512MiB */
  19
  20static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = {
  21        .grp_addds = 0x00000030,
  22        .grp_ddrmode_ctl = 0x00020000,
  23        .grp_b0ds = 0x00000030,
  24        .grp_ctlds = 0x00000030,
  25        .grp_b1ds = 0x00000030,
  26        .grp_ddrpke = 0x00000000,
  27        .grp_ddrmode = 0x00020000,
  28        .grp_ddr_type = 0x000c0000,
  29};
  30
  31static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = {
  32        .dram_dqm0 = 0x00000030,
  33        .dram_dqm1 = 0x00000030,
  34        .dram_ras = 0x00000030,
  35        .dram_cas = 0x00000030,
  36        .dram_odt0 = 0x00000030,
  37        .dram_odt1 = 0x00000030,
  38        .dram_sdba2 = 0x00000000,
  39        .dram_sdclk_0 = 0x00000030,
  40        .dram_sdqs0 = 0x00000030,
  41        .dram_sdqs1 = 0x00000030,
  42        .dram_reset = 0x00000030,
  43};
  44
  45static struct mx6_mmdc_calibration mx6_mmcd_calib = {
  46        .p0_mpwldectrl0 = 0x00000000,
  47        .p0_mpdgctrl0 = 0x41480148,
  48        .p0_mprddlctl = 0x40403E42,
  49        .p0_mpwrdlctl = 0x40405852,
  50};
  51
  52struct mx6_ddr_sysinfo ddr_sysinfo = {
  53        .dsize = 0,             /* Bus size = 16bit */
  54        .cs_density = 32,
  55        .ncs = 1,
  56        .cs1_mirror = 0,
  57        .rtt_wr = 1,
  58        .rtt_nom = 1,
  59        .walat = 1,             /* Write additional latency */
  60        .ralat = 5,             /* Read additional latency */
  61        .mif3_mode = 3,         /* Command prediction working mode */
  62        .bi_on = 1,             /* Bank interleaving enabled */
  63        .pd_fast_exit = 1,
  64        .sde_to_rst = 0x10,
  65        .rst_to_cke = 0x23,     /* 33 cycles, 500us (JEDEC default) */
  66        .ddr_type = DDR_TYPE_DDR3,
  67        .refsel = 1,            /* Refresh cycles at 32KHz */
  68        .refr = 7,              /* 8 refresh commands per refresh cycle */
  69};
  70
  71static struct mx6_ddr3_cfg mem_ddr = {
  72        .mem_speed = 1600,
  73        .density = 4,
  74        .width = 16,
  75        .banks = 8,
  76        .rowaddr = 15,
  77        .coladdr = 10,
  78        .pagesz = 2,
  79        .trcd = 1375,
  80        .trcmin = 4875,
  81        .trasmin = 3500,
  82};
  83
  84static void ccgr_init(void)
  85{
  86        struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  87
  88        writel(0xFFFFFFFF, &ccm->CCGR0);
  89        writel(0xFFFFFFFF, &ccm->CCGR1);
  90        writel(0xFFFFFFFF, &ccm->CCGR2);
  91        writel(0xFFFFFFFF, &ccm->CCGR3);
  92        writel(0xFFFFFFFF, &ccm->CCGR4);
  93        writel(0xFFFFFFFF, &ccm->CCGR5);
  94        writel(0xFFFFFFFF, &ccm->CCGR6);
  95}
  96
  97static void spl_dram_init(void)
  98{
  99        mx6ul_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
 100        mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr);
 101}
 102
 103#ifdef CONFIG_FSL_ESDHC_IMX
 104
 105#define USDHC_PAD_CTRL (PAD_CTL_PKE         | PAD_CTL_PUE       | \
 106                        PAD_CTL_PUS_22K_UP  | PAD_CTL_SPEED_LOW | \
 107                        PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | \
 108                        PAD_CTL_HYS)
 109
 110static iomux_v3_cfg_t const usdhc1_pads[] = {
 111        MX6_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 112        MX6_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 113        MX6_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 114        MX6_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 115        MX6_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 116        MX6_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 117        MX6_PAD_UART1_RTS_B__USDHC1_CD_B | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 118};
 119
 120#ifndef CONFIG_NAND_MXS
 121static iomux_v3_cfg_t const usdhc2_pads[] = {
 122        MX6_PAD_NAND_RE_B__USDHC2_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 123        MX6_PAD_NAND_WE_B__USDHC2_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 124        MX6_PAD_NAND_DATA00__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 125        MX6_PAD_NAND_DATA01__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 126        MX6_PAD_NAND_DATA02__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 127        MX6_PAD_NAND_DATA03__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 128        MX6_PAD_NAND_DATA04__USDHC2_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 129        MX6_PAD_NAND_DATA05__USDHC2_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 130        MX6_PAD_NAND_DATA06__USDHC2_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 131        MX6_PAD_NAND_DATA07__USDHC2_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 132};
 133#endif
 134
 135static struct fsl_esdhc_cfg usdhc_cfg[] = {
 136        {
 137                .esdhc_base = USDHC1_BASE_ADDR,
 138                .max_bus_width = 4,
 139        },
 140#ifndef CONFIG_NAND_MXS
 141        {
 142                .esdhc_base = USDHC2_BASE_ADDR,
 143                .max_bus_width = 8,
 144        },
 145#endif
 146};
 147
 148int board_mmc_getcd(struct mmc *mmc)
 149{
 150        return 1;
 151}
 152
 153int board_mmc_init(struct bd_info *bis)
 154{
 155        int i, ret;
 156
 157        for (i = 0; i < CFG_SYS_FSL_USDHC_NUM; i++) {
 158                switch (i) {
 159                case 0:
 160                        SETUP_IOMUX_PADS(usdhc1_pads);
 161                        usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
 162                        break;
 163#ifndef CONFIG_NAND_MXS
 164                case 1:
 165                        SETUP_IOMUX_PADS(usdhc2_pads);
 166                        usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
 167                        break;
 168#endif
 169                default:
 170                        printf("Warning - USDHC%d controller not supporting\n",
 171                               i + 1);
 172                        return 0;
 173                }
 174
 175                ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
 176                if (ret) {
 177                        printf("Warning: failed to initialize mmc dev %d\n", i);
 178                        return ret;
 179                }
 180        }
 181
 182        return 0;
 183}
 184
 185#endif /* CONFIG_FSL_ESDHC_IMX */
 186
 187void board_init_f(ulong dummy)
 188{
 189        ccgr_init();
 190
 191        /* Setup AIPS and disable watchdog */
 192        arch_cpu_init();
 193
 194        /* Setup iomux and fec */
 195        board_early_init_f();
 196
 197        /* Setup GP timer */
 198        timer_init();
 199
 200        /* UART clocks enabled and gd valid - init serial console */
 201        preloader_console_init();
 202
 203        /* DDR initialization */
 204        spl_dram_init();
 205}
 206