uboot/arch/arm/cpu/armv7/mx6/soc.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2007
   3 * Sascha Hauer, Pengutronix
   4 *
   5 * (C) Copyright 2009 Freescale Semiconductor, Inc.
   6 *
   7 * SPDX-License-Identifier:     GPL-2.0+
   8 */
   9
  10#include <common.h>
  11#include <asm/armv7.h>
  12#include <asm/pl310.h>
  13#include <asm/errno.h>
  14#include <asm/io.h>
  15#include <asm/arch/imx-regs.h>
  16#include <asm/arch/clock.h>
  17#include <asm/arch/sys_proto.h>
  18#include <asm/imx-common/boot_mode.h>
  19#include <asm/imx-common/dma.h>
  20#include <stdbool.h>
  21#include <asm/arch/mxc_hdmi.h>
  22#include <asm/arch/crm_regs.h>
  23
  24enum ldo_reg {
  25        LDO_ARM,
  26        LDO_SOC,
  27        LDO_PU,
  28};
  29
  30struct scu_regs {
  31        u32     ctrl;
  32        u32     config;
  33        u32     status;
  34        u32     invalidate;
  35        u32     fpga_rev;
  36};
  37
  38u32 get_cpu_rev(void)
  39{
  40        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
  41        u32 reg = readl(&anatop->digprog_sololite);
  42        u32 type = ((reg >> 16) & 0xff);
  43
  44        if (type != MXC_CPU_MX6SL) {
  45                reg = readl(&anatop->digprog);
  46                struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
  47                u32 cfg = readl(&scu->config) & 3;
  48                type = ((reg >> 16) & 0xff);
  49                if (type == MXC_CPU_MX6DL) {
  50                        if (!cfg)
  51                                type = MXC_CPU_MX6SOLO;
  52                }
  53
  54                if (type == MXC_CPU_MX6Q) {
  55                        if (cfg == 1)
  56                                type = MXC_CPU_MX6D;
  57                }
  58
  59        }
  60        reg &= 0xff;            /* mx6 silicon revision */
  61        return (type << 12) | (reg + 0x10);
  62}
  63
  64#ifdef CONFIG_REVISION_TAG
  65u32 __weak get_board_rev(void)
  66{
  67        u32 cpurev = get_cpu_rev();
  68        u32 type = ((cpurev >> 12) & 0xff);
  69        if (type == MXC_CPU_MX6SOLO)
  70                cpurev = (MXC_CPU_MX6DL) << 12 | (cpurev & 0xFFF);
  71
  72        if (type == MXC_CPU_MX6D)
  73                cpurev = (MXC_CPU_MX6Q) << 12 | (cpurev & 0xFFF);
  74
  75        return cpurev;
  76}
  77#endif
  78
  79void init_aips(void)
  80{
  81        struct aipstz_regs *aips1, *aips2;
  82
  83        aips1 = (struct aipstz_regs *)AIPS1_BASE_ADDR;
  84        aips2 = (struct aipstz_regs *)AIPS2_BASE_ADDR;
  85
  86        /*
  87         * Set all MPROTx to be non-bufferable, trusted for R/W,
  88         * not forced to user-mode.
  89         */
  90        writel(0x77777777, &aips1->mprot0);
  91        writel(0x77777777, &aips1->mprot1);
  92        writel(0x77777777, &aips2->mprot0);
  93        writel(0x77777777, &aips2->mprot1);
  94
  95        /*
  96         * Set all OPACRx to be non-bufferable, not require
  97         * supervisor privilege level for access,allow for
  98         * write access and untrusted master access.
  99         */
 100        writel(0x00000000, &aips1->opacr0);
 101        writel(0x00000000, &aips1->opacr1);
 102        writel(0x00000000, &aips1->opacr2);
 103        writel(0x00000000, &aips1->opacr3);
 104        writel(0x00000000, &aips1->opacr4);
 105        writel(0x00000000, &aips2->opacr0);
 106        writel(0x00000000, &aips2->opacr1);
 107        writel(0x00000000, &aips2->opacr2);
 108        writel(0x00000000, &aips2->opacr3);
 109        writel(0x00000000, &aips2->opacr4);
 110}
 111
 112static void clear_ldo_ramp(void)
 113{
 114        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 115        int reg;
 116
 117        /* ROM may modify LDO ramp up time according to fuse setting, so in
 118         * order to be in the safe side we neeed to reset these settings to
 119         * match the reset value: 0'b00
 120         */
 121        reg = readl(&anatop->ana_misc2);
 122        reg &= ~(0x3f << 24);
 123        writel(reg, &anatop->ana_misc2);
 124}
 125
 126/*
 127 * Set the PMU_REG_CORE register
 128 *
 129 * Set LDO_SOC/PU/ARM regulators to the specified millivolt level.
 130 * Possible values are from 0.725V to 1.450V in steps of
 131 * 0.025V (25mV).
 132 */
 133static int set_ldo_voltage(enum ldo_reg ldo, u32 mv)
 134{
 135        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 136        u32 val, step, old, reg = readl(&anatop->reg_core);
 137        u8 shift;
 138
 139        if (mv < 725)
 140                val = 0x00;     /* Power gated off */
 141        else if (mv > 1450)
 142                val = 0x1F;     /* Power FET switched full on. No regulation */
 143        else
 144                val = (mv - 700) / 25;
 145
 146        clear_ldo_ramp();
 147
 148        switch (ldo) {
 149        case LDO_SOC:
 150                shift = 18;
 151                break;
 152        case LDO_PU:
 153                shift = 9;
 154                break;
 155        case LDO_ARM:
 156                shift = 0;
 157                break;
 158        default:
 159                return -EINVAL;
 160        }
 161
 162        old = (reg & (0x1F << shift)) >> shift;
 163        step = abs(val - old);
 164        if (step == 0)
 165                return 0;
 166
 167        reg = (reg & ~(0x1F << shift)) | (val << shift);
 168        writel(reg, &anatop->reg_core);
 169
 170        /*
 171         * The LDO ramp-up is based on 64 clock cycles of 24 MHz = 2.6 us per
 172         * step
 173         */
 174        udelay(3 * step);
 175
 176        return 0;
 177}
 178
 179static void imx_set_wdog_powerdown(bool enable)
 180{
 181        struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR;
 182        struct wdog_regs *wdog2 = (struct wdog_regs *)WDOG2_BASE_ADDR;
 183
 184        /* Write to the PDE (Power Down Enable) bit */
 185        writew(enable, &wdog1->wmcr);
 186        writew(enable, &wdog2->wmcr);
 187}
 188
 189static void set_ahb_rate(u32 val)
 190{
 191        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 192        u32 reg, div;
 193
 194        div = get_periph_clk() / val - 1;
 195        reg = readl(&mxc_ccm->cbcdr);
 196
 197        writel((reg & (~MXC_CCM_CBCDR_AHB_PODF_MASK)) |
 198                (div << MXC_CCM_CBCDR_AHB_PODF_OFFSET), &mxc_ccm->cbcdr);
 199}
 200
 201static void clear_mmdc_ch_mask(void)
 202{
 203        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 204
 205        /* Clear MMDC channel mask */
 206        writel(0, &mxc_ccm->ccdr);
 207}
 208
 209int arch_cpu_init(void)
 210{
 211        init_aips();
 212
 213        /* Need to clear MMDC_CHx_MASK to make warm reset work. */
 214        clear_mmdc_ch_mask();
 215
 216        /*
 217         * When low freq boot is enabled, ROM will not set AHB
 218         * freq, so we need to ensure AHB freq is 132MHz in such
 219         * scenario.
 220         */
 221        if (mxc_get_clock(MXC_ARM_CLK) == 396000000)
 222                set_ahb_rate(132000000);
 223
 224        imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */
 225
 226#ifdef CONFIG_APBH_DMA
 227        /* Start APBH DMA */
 228        mxs_dma_init();
 229#endif
 230
 231        return 0;
 232}
 233
 234int board_postclk_init(void)
 235{
 236        set_ldo_voltage(LDO_SOC, 1175); /* Set VDDSOC to 1.175V */
 237
 238        return 0;
 239}
 240
 241#ifndef CONFIG_SYS_DCACHE_OFF
 242void enable_caches(void)
 243{
 244        /* Avoid random hang when download by usb */
 245        invalidate_dcache_all();
 246        /* Enable D-cache. I-cache is already enabled in start.S */
 247        dcache_enable();
 248}
 249#endif
 250
 251#if defined(CONFIG_FEC_MXC)
 252void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
 253{
 254        struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
 255        struct fuse_bank *bank = &ocotp->bank[4];
 256        struct fuse_bank4_regs *fuse =
 257                        (struct fuse_bank4_regs *)bank->fuse_regs;
 258
 259        u32 value = readl(&fuse->mac_addr_high);
 260        mac[0] = (value >> 8);
 261        mac[1] = value ;
 262
 263        value = readl(&fuse->mac_addr_low);
 264        mac[2] = value >> 24 ;
 265        mac[3] = value >> 16 ;
 266        mac[4] = value >> 8 ;
 267        mac[5] = value ;
 268
 269}
 270#endif
 271
 272void boot_mode_apply(unsigned cfg_val)
 273{
 274        unsigned reg;
 275        struct src *psrc = (struct src *)SRC_BASE_ADDR;
 276        writel(cfg_val, &psrc->gpr9);
 277        reg = readl(&psrc->gpr10);
 278        if (cfg_val)
 279                reg |= 1 << 28;
 280        else
 281                reg &= ~(1 << 28);
 282        writel(reg, &psrc->gpr10);
 283}
 284/*
 285 * cfg_val will be used for
 286 * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0]
 287 * After reset, if GPR10[28] is 1, ROM will copy GPR9[25:0]
 288 * to SBMR1, which will determine the boot device.
 289 */
 290const struct boot_mode soc_boot_modes[] = {
 291        {"normal",      MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)},
 292        /* reserved value should start rom usb */
 293        {"usb",         MAKE_CFGVAL(0x01, 0x00, 0x00, 0x00)},
 294        {"sata",        MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)},
 295        {"escpi1:0",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)},
 296        {"escpi1:1",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)},
 297        {"escpi1:2",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)},
 298        {"escpi1:3",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)},
 299        /* 4 bit bus width */
 300        {"esdhc1",      MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
 301        {"esdhc2",      MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
 302        {"esdhc3",      MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
 303        {"esdhc4",      MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
 304        {NULL,          0},
 305};
 306
 307void s_init(void)
 308{
 309        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 310        int is_6q = is_cpu_type(MXC_CPU_MX6Q);
 311        u32 mask480;
 312        u32 mask528;
 313
 314        /* Due to hardware limitation, on MX6Q we need to gate/ungate all PFDs
 315         * to make sure PFD is working right, otherwise, PFDs may
 316         * not output clock after reset, MX6DL and MX6SL have added 396M pfd
 317         * workaround in ROM code, as bus clock need it
 318         */
 319
 320        mask480 = ANATOP_PFD_CLKGATE_MASK(0) |
 321                ANATOP_PFD_CLKGATE_MASK(1) |
 322                ANATOP_PFD_CLKGATE_MASK(2) |
 323                ANATOP_PFD_CLKGATE_MASK(3);
 324        mask528 = ANATOP_PFD_CLKGATE_MASK(0) |
 325                ANATOP_PFD_CLKGATE_MASK(1) |
 326                ANATOP_PFD_CLKGATE_MASK(3);
 327
 328        /*
 329         * Don't reset PFD2 on DL/S
 330         */
 331        if (is_6q)
 332                mask528 |= ANATOP_PFD_CLKGATE_MASK(2);
 333        writel(mask480, &anatop->pfd_480_set);
 334        writel(mask528, &anatop->pfd_528_set);
 335        writel(mask480, &anatop->pfd_480_clr);
 336        writel(mask528, &anatop->pfd_528_clr);
 337}
 338
 339#ifdef CONFIG_IMX_HDMI
 340void imx_enable_hdmi_phy(void)
 341{
 342        struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
 343        u8 reg;
 344        reg = readb(&hdmi->phy_conf0);
 345        reg |= HDMI_PHY_CONF0_PDZ_MASK;
 346        writeb(reg, &hdmi->phy_conf0);
 347        udelay(3000);
 348        reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
 349        writeb(reg, &hdmi->phy_conf0);
 350        udelay(3000);
 351        reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
 352        writeb(reg, &hdmi->phy_conf0);
 353        writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
 354}
 355
 356void imx_setup_hdmi(void)
 357{
 358        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 359        struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
 360        int reg;
 361
 362        /* Turn on HDMI PHY clock */
 363        reg = readl(&mxc_ccm->CCGR2);
 364        reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK|
 365                 MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
 366        writel(reg, &mxc_ccm->CCGR2);
 367        writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
 368        reg = readl(&mxc_ccm->chsccdr);
 369        reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK|
 370                 MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK|
 371                 MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
 372        reg |= (CHSCCDR_PODF_DIVIDE_BY_3
 373                 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
 374                 |(CHSCCDR_IPU_PRE_CLK_540M_PFD
 375                 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
 376        writel(reg, &mxc_ccm->chsccdr);
 377}
 378#endif
 379
 380#ifndef CONFIG_SYS_L2CACHE_OFF
 381#define IOMUXC_GPR11_L2CACHE_AS_OCRAM 0x00000002
 382void v7_outer_cache_enable(void)
 383{
 384        struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
 385        unsigned int val;
 386
 387#if defined CONFIG_MX6SL
 388        struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 389        val = readl(&iomux->gpr[11]);
 390        if (val & IOMUXC_GPR11_L2CACHE_AS_OCRAM) {
 391                /* L2 cache configured as OCRAM, reset it */
 392                val &= ~IOMUXC_GPR11_L2CACHE_AS_OCRAM;
 393                writel(val, &iomux->gpr[11]);
 394        }
 395#endif
 396
 397        writel(0x132, &pl310->pl310_tag_latency_ctrl);
 398        writel(0x132, &pl310->pl310_data_latency_ctrl);
 399
 400        val = readl(&pl310->pl310_prefetch_ctrl);
 401
 402        /* Turn on the L2 I/D prefetch */
 403        val |= 0x30000000;
 404
 405        /*
 406         * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
 407         * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2
 408         * But according to ARM PL310 errata: 752271
 409         * ID: 752271: Double linefill feature can cause data corruption
 410         * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2
 411         * Workaround: The only workaround to this erratum is to disable the
 412         * double linefill feature. This is the default behavior.
 413         */
 414
 415#ifndef CONFIG_MX6Q
 416        val |= 0x40800000;
 417#endif
 418        writel(val, &pl310->pl310_prefetch_ctrl);
 419
 420        val = readl(&pl310->pl310_power_ctrl);
 421        val |= L2X0_DYNAMIC_CLK_GATING_EN;
 422        val |= L2X0_STNDBY_MODE_EN;
 423        writel(val, &pl310->pl310_power_ctrl);
 424
 425        setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
 426}
 427
 428void v7_outer_cache_disable(void)
 429{
 430        struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
 431
 432        clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
 433}
 434#endif /* !CONFIG_SYS_L2CACHE_OFF */
 435