uboot/arch/arm/mach-imx/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 <linux/errno.h>
  12#include <asm/io.h>
  13#include <asm/arch/imx-regs.h>
  14#include <asm/arch/clock.h>
  15#include <asm/arch/sys_proto.h>
  16#include <asm/bootm.h>
  17#include <asm/mach-imx/boot_mode.h>
  18#include <asm/mach-imx/dma.h>
  19#include <asm/mach-imx/hab.h>
  20#include <stdbool.h>
  21#include <asm/arch/mxc_hdmi.h>
  22#include <asm/arch/crm_regs.h>
  23#include <dm.h>
  24#include <imx_thermal.h>
  25#include <mmc.h>
  26
  27enum ldo_reg {
  28        LDO_ARM,
  29        LDO_SOC,
  30        LDO_PU,
  31};
  32
  33struct scu_regs {
  34        u32     ctrl;
  35        u32     config;
  36        u32     status;
  37        u32     invalidate;
  38        u32     fpga_rev;
  39};
  40
  41#if defined(CONFIG_IMX_THERMAL)
  42static const struct imx_thermal_plat imx6_thermal_plat = {
  43        .regs = (void *)ANATOP_BASE_ADDR,
  44        .fuse_bank = 1,
  45        .fuse_word = 6,
  46};
  47
  48U_BOOT_DEVICE(imx6_thermal) = {
  49        .name = "imx_thermal",
  50        .platdata = &imx6_thermal_plat,
  51};
  52#endif
  53
  54#if defined(CONFIG_SECURE_BOOT)
  55struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
  56        .bank = 0,
  57        .word = 6,
  58};
  59#endif
  60
  61u32 get_nr_cpus(void)
  62{
  63        struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
  64        return readl(&scu->config) & 3;
  65}
  66
  67u32 get_cpu_rev(void)
  68{
  69        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
  70        u32 reg = readl(&anatop->digprog_sololite);
  71        u32 type = ((reg >> 16) & 0xff);
  72        u32 major, cfg = 0;
  73
  74        if (type != MXC_CPU_MX6SL) {
  75                reg = readl(&anatop->digprog);
  76                struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
  77                cfg = readl(&scu->config) & 3;
  78                type = ((reg >> 16) & 0xff);
  79                if (type == MXC_CPU_MX6DL) {
  80                        if (!cfg)
  81                                type = MXC_CPU_MX6SOLO;
  82                }
  83
  84                if (type == MXC_CPU_MX6Q) {
  85                        if (cfg == 1)
  86                                type = MXC_CPU_MX6D;
  87                }
  88
  89        }
  90        major = ((reg >> 8) & 0xff);
  91        if ((major >= 1) &&
  92            ((type == MXC_CPU_MX6Q) || (type == MXC_CPU_MX6D))) {
  93                major--;
  94                type = MXC_CPU_MX6QP;
  95                if (cfg == 1)
  96                        type = MXC_CPU_MX6DP;
  97        }
  98        reg &= 0xff;            /* mx6 silicon revision */
  99        return (type << 12) | (reg + (0x10 * (major + 1)));
 100}
 101
 102/*
 103 * OCOTP_CFG3[17:16] (see Fusemap Description Table offset 0x440)
 104 * defines a 2-bit SPEED_GRADING
 105 */
 106#define OCOTP_CFG3_SPEED_SHIFT  16
 107#define OCOTP_CFG3_SPEED_800MHZ 0
 108#define OCOTP_CFG3_SPEED_850MHZ 1
 109#define OCOTP_CFG3_SPEED_1GHZ   2
 110#define OCOTP_CFG3_SPEED_1P2GHZ 3
 111
 112/*
 113 * For i.MX6UL
 114 */
 115#define OCOTP_CFG3_SPEED_528MHZ 1
 116#define OCOTP_CFG3_SPEED_696MHZ 2
 117
 118/*
 119 * For i.MX6ULL
 120 */
 121#define OCOTP_CFG3_SPEED_792MHZ 2
 122#define OCOTP_CFG3_SPEED_900MHZ 3
 123
 124u32 get_cpu_speed_grade_hz(void)
 125{
 126        struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
 127        struct fuse_bank *bank = &ocotp->bank[0];
 128        struct fuse_bank0_regs *fuse =
 129                (struct fuse_bank0_regs *)bank->fuse_regs;
 130        uint32_t val;
 131
 132        val = readl(&fuse->cfg3);
 133        val >>= OCOTP_CFG3_SPEED_SHIFT;
 134        val &= 0x3;
 135
 136        if (is_mx6ul()) {
 137                if (val == OCOTP_CFG3_SPEED_528MHZ)
 138                        return 528000000;
 139                else if (val == OCOTP_CFG3_SPEED_696MHZ)
 140                        return 696000000;
 141                else
 142                        return 0;
 143        }
 144
 145        if (is_mx6ull()) {
 146                if (val == OCOTP_CFG3_SPEED_528MHZ)
 147                        return 528000000;
 148                else if (val == OCOTP_CFG3_SPEED_792MHZ)
 149                        return 792000000;
 150                else if (val == OCOTP_CFG3_SPEED_900MHZ)
 151                        return 900000000;
 152                else
 153                        return 0;
 154        }
 155
 156        switch (val) {
 157        /* Valid for IMX6DQ */
 158        case OCOTP_CFG3_SPEED_1P2GHZ:
 159                if (is_mx6dq() || is_mx6dqp())
 160                        return 1200000000;
 161        /* Valid for IMX6SX/IMX6SDL/IMX6DQ */
 162        case OCOTP_CFG3_SPEED_1GHZ:
 163                return 996000000;
 164        /* Valid for IMX6DQ */
 165        case OCOTP_CFG3_SPEED_850MHZ:
 166                if (is_mx6dq() || is_mx6dqp())
 167                        return 852000000;
 168        /* Valid for IMX6SX/IMX6SDL/IMX6DQ */
 169        case OCOTP_CFG3_SPEED_800MHZ:
 170                return 792000000;
 171        }
 172        return 0;
 173}
 174
 175/*
 176 * OCOTP_MEM0[7:6] (see Fusemap Description Table offset 0x480)
 177 * defines a 2-bit Temperature Grade
 178 *
 179 * return temperature grade and min/max temperature in Celsius
 180 */
 181#define OCOTP_MEM0_TEMP_SHIFT          6
 182
 183u32 get_cpu_temp_grade(int *minc, int *maxc)
 184{
 185        struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
 186        struct fuse_bank *bank = &ocotp->bank[1];
 187        struct fuse_bank1_regs *fuse =
 188                (struct fuse_bank1_regs *)bank->fuse_regs;
 189        uint32_t val;
 190
 191        val = readl(&fuse->mem0);
 192        val >>= OCOTP_MEM0_TEMP_SHIFT;
 193        val &= 0x3;
 194
 195        if (minc && maxc) {
 196                if (val == TEMP_AUTOMOTIVE) {
 197                        *minc = -40;
 198                        *maxc = 125;
 199                } else if (val == TEMP_INDUSTRIAL) {
 200                        *minc = -40;
 201                        *maxc = 105;
 202                } else if (val == TEMP_EXTCOMMERCIAL) {
 203                        *minc = -20;
 204                        *maxc = 105;
 205                } else {
 206                        *minc = 0;
 207                        *maxc = 95;
 208                }
 209        }
 210        return val;
 211}
 212
 213#ifdef CONFIG_REVISION_TAG
 214u32 __weak get_board_rev(void)
 215{
 216        u32 cpurev = get_cpu_rev();
 217        u32 type = ((cpurev >> 12) & 0xff);
 218        if (type == MXC_CPU_MX6SOLO)
 219                cpurev = (MXC_CPU_MX6DL) << 12 | (cpurev & 0xFFF);
 220
 221        if (type == MXC_CPU_MX6D)
 222                cpurev = (MXC_CPU_MX6Q) << 12 | (cpurev & 0xFFF);
 223
 224        return cpurev;
 225}
 226#endif
 227
 228static void clear_ldo_ramp(void)
 229{
 230        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 231        int reg;
 232
 233        /* ROM may modify LDO ramp up time according to fuse setting, so in
 234         * order to be in the safe side we neeed to reset these settings to
 235         * match the reset value: 0'b00
 236         */
 237        reg = readl(&anatop->ana_misc2);
 238        reg &= ~(0x3f << 24);
 239        writel(reg, &anatop->ana_misc2);
 240}
 241
 242/*
 243 * Set the PMU_REG_CORE register
 244 *
 245 * Set LDO_SOC/PU/ARM regulators to the specified millivolt level.
 246 * Possible values are from 0.725V to 1.450V in steps of
 247 * 0.025V (25mV).
 248 */
 249static int set_ldo_voltage(enum ldo_reg ldo, u32 mv)
 250{
 251        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 252        u32 val, step, old, reg = readl(&anatop->reg_core);
 253        u8 shift;
 254
 255        /* No LDO_SOC/PU/ARM */
 256        if (is_mx6sll())
 257                return 0;
 258
 259        if (mv < 725)
 260                val = 0x00;     /* Power gated off */
 261        else if (mv > 1450)
 262                val = 0x1F;     /* Power FET switched full on. No regulation */
 263        else
 264                val = (mv - 700) / 25;
 265
 266        clear_ldo_ramp();
 267
 268        switch (ldo) {
 269        case LDO_SOC:
 270                shift = 18;
 271                break;
 272        case LDO_PU:
 273                shift = 9;
 274                break;
 275        case LDO_ARM:
 276                shift = 0;
 277                break;
 278        default:
 279                return -EINVAL;
 280        }
 281
 282        old = (reg & (0x1F << shift)) >> shift;
 283        step = abs(val - old);
 284        if (step == 0)
 285                return 0;
 286
 287        reg = (reg & ~(0x1F << shift)) | (val << shift);
 288        writel(reg, &anatop->reg_core);
 289
 290        /*
 291         * The LDO ramp-up is based on 64 clock cycles of 24 MHz = 2.6 us per
 292         * step
 293         */
 294        udelay(3 * step);
 295
 296        return 0;
 297}
 298
 299static void set_ahb_rate(u32 val)
 300{
 301        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 302        u32 reg, div;
 303
 304        div = get_periph_clk() / val - 1;
 305        reg = readl(&mxc_ccm->cbcdr);
 306
 307        writel((reg & (~MXC_CCM_CBCDR_AHB_PODF_MASK)) |
 308                (div << MXC_CCM_CBCDR_AHB_PODF_OFFSET), &mxc_ccm->cbcdr);
 309}
 310
 311static void clear_mmdc_ch_mask(void)
 312{
 313        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 314        u32 reg;
 315        reg = readl(&mxc_ccm->ccdr);
 316
 317        /* Clear MMDC channel mask */
 318        if (is_mx6sx() || is_mx6ul() || is_mx6ull() || is_mx6sl() || is_mx6sll())
 319                reg &= ~(MXC_CCM_CCDR_MMDC_CH1_HS_MASK);
 320        else
 321                reg &= ~(MXC_CCM_CCDR_MMDC_CH1_HS_MASK | MXC_CCM_CCDR_MMDC_CH0_HS_MASK);
 322        writel(reg, &mxc_ccm->ccdr);
 323}
 324
 325#define OCOTP_MEM0_REFTOP_TRIM_SHIFT          8
 326
 327static void init_bandgap(void)
 328{
 329        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 330        struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
 331        struct fuse_bank *bank = &ocotp->bank[1];
 332        struct fuse_bank1_regs *fuse =
 333                (struct fuse_bank1_regs *)bank->fuse_regs;
 334        uint32_t val;
 335
 336        /*
 337         * Ensure the bandgap has stabilized.
 338         */
 339        while (!(readl(&anatop->ana_misc0) & 0x80))
 340                ;
 341        /*
 342         * For best noise performance of the analog blocks using the
 343         * outputs of the bandgap, the reftop_selfbiasoff bit should
 344         * be set.
 345         */
 346        writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set);
 347        /*
 348         * On i.MX6ULL,we need to set VBGADJ bits according to the
 349         * REFTOP_TRIM[3:0] in fuse table
 350         *      000 - set REFTOP_VBGADJ[2:0] to 3b'110,
 351         *      110 - set REFTOP_VBGADJ[2:0] to 3b'000,
 352         *      001 - set REFTOP_VBGADJ[2:0] to 3b'001,
 353         *      010 - set REFTOP_VBGADJ[2:0] to 3b'010,
 354         *      011 - set REFTOP_VBGADJ[2:0] to 3b'011,
 355         *      100 - set REFTOP_VBGADJ[2:0] to 3b'100,
 356         *      101 - set REFTOP_VBGADJ[2:0] to 3b'101,
 357         *      111 - set REFTOP_VBGADJ[2:0] to 3b'111,
 358         */
 359        if (is_mx6ull()) {
 360                val = readl(&fuse->mem0);
 361                val >>= OCOTP_MEM0_REFTOP_TRIM_SHIFT;
 362                val &= 0x7;
 363
 364                writel(val << BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ_SHIFT,
 365                       &anatop->ana_misc0_set);
 366        }
 367}
 368
 369int arch_cpu_init(void)
 370{
 371        struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 372
 373        init_aips();
 374
 375        /* Need to clear MMDC_CHx_MASK to make warm reset work. */
 376        clear_mmdc_ch_mask();
 377
 378        /*
 379         * Disable self-bias circuit in the analog bandap.
 380         * The self-bias circuit is used by the bandgap during startup.
 381         * This bit should be set after the bandgap has initialized.
 382         */
 383        init_bandgap();
 384
 385        if (!is_mx6ul() && !is_mx6ull()) {
 386                /*
 387                 * When low freq boot is enabled, ROM will not set AHB
 388                 * freq, so we need to ensure AHB freq is 132MHz in such
 389                 * scenario.
 390                 *
 391                 * To i.MX6UL, when power up, default ARM core and
 392                 * AHB rate is 396M and 132M.
 393                 */
 394                if (mxc_get_clock(MXC_ARM_CLK) == 396000000)
 395                        set_ahb_rate(132000000);
 396        }
 397
 398        if (is_mx6ul()) {
 399                if (is_soc_rev(CHIP_REV_1_0) == 0) {
 400                        /*
 401                         * According to the design team's requirement on
 402                         * i.MX6UL,the PMIC_STBY_REQ PAD should be configured
 403                         * as open drain 100K (0x0000b8a0).
 404                         * Only exists on TO1.0
 405                         */
 406                        writel(0x0000b8a0, IOMUXC_BASE_ADDR + 0x29c);
 407                } else {
 408                        /*
 409                         * From TO1.1, SNVS adds internal pull up control
 410                         * for POR_B, the register filed is GPBIT[1:0],
 411                         * after system boot up, it can be set to 2b'01
 412                         * to disable internal pull up.It can save about
 413                         * 30uA power in SNVS mode.
 414                         */
 415                        writel((readl(MX6UL_SNVS_LP_BASE_ADDR + 0x10) &
 416                               (~0x1400)) | 0x400,
 417                               MX6UL_SNVS_LP_BASE_ADDR + 0x10);
 418                }
 419        }
 420
 421        if (is_mx6ull()) {
 422                /*
 423                 * GPBIT[1:0] is suggested to set to 2'b11:
 424                 * 2'b00 : always PUP100K
 425                 * 2'b01 : PUP100K when PMIC_ON_REQ or SOC_NOT_FAIL
 426                 * 2'b10 : always disable PUP100K
 427                 * 2'b11 : PDN100K when SOC_FAIL, PUP100K when SOC_NOT_FAIL
 428                 * register offset is different from i.MX6UL, since
 429                 * i.MX6UL is fixed by ECO.
 430                 */
 431                writel(readl(MX6UL_SNVS_LP_BASE_ADDR) |
 432                        0x3, MX6UL_SNVS_LP_BASE_ADDR);
 433        }
 434
 435        /* Set perclk to source from OSC 24MHz */
 436        if (is_mx6sl())
 437                setbits_le32(&ccm->cscmr1, MXC_CCM_CSCMR1_PER_CLK_SEL_MASK);
 438
 439        imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */
 440
 441        if (is_mx6sx())
 442                setbits_le32(&ccm->cscdr1, MXC_CCM_CSCDR1_UART_CLK_SEL);
 443
 444        init_src();
 445
 446        return 0;
 447}
 448
 449#ifdef CONFIG_ENV_IS_IN_MMC
 450__weak int board_mmc_get_env_dev(int devno)
 451{
 452        return CONFIG_SYS_MMC_ENV_DEV;
 453}
 454
 455static int mmc_get_boot_dev(void)
 456{
 457        struct src *src_regs = (struct src *)SRC_BASE_ADDR;
 458        u32 soc_sbmr = readl(&src_regs->sbmr1);
 459        u32 bootsel;
 460        int devno;
 461
 462        /*
 463         * Refer to
 464         * "i.MX 6Dual/6Quad Applications Processor Reference Manual"
 465         * Chapter "8.5.3.1 Expansion Device eFUSE Configuration"
 466         * i.MX6SL/SX/UL has same layout.
 467         */
 468        bootsel = (soc_sbmr & 0x000000FF) >> 6;
 469
 470        /* No boot from sd/mmc */
 471        if (bootsel != 1)
 472                return -1;
 473
 474        /* BOOT_CFG2[3] and BOOT_CFG2[4] */
 475        devno = (soc_sbmr & 0x00001800) >> 11;
 476
 477        return devno;
 478}
 479
 480int mmc_get_env_dev(void)
 481{
 482        int devno = mmc_get_boot_dev();
 483
 484        /* If not boot from sd/mmc, use default value */
 485        if (devno < 0)
 486                return CONFIG_SYS_MMC_ENV_DEV;
 487
 488        return board_mmc_get_env_dev(devno);
 489}
 490
 491#ifdef CONFIG_SYS_MMC_ENV_PART
 492__weak int board_mmc_get_env_part(int devno)
 493{
 494        return CONFIG_SYS_MMC_ENV_PART;
 495}
 496
 497uint mmc_get_env_part(struct mmc *mmc)
 498{
 499        int devno = mmc_get_boot_dev();
 500
 501        /* If not boot from sd/mmc, use default value */
 502        if (devno < 0)
 503                return CONFIG_SYS_MMC_ENV_PART;
 504
 505        return board_mmc_get_env_part(devno);
 506}
 507#endif
 508#endif
 509
 510int board_postclk_init(void)
 511{
 512        /* NO LDO SOC on i.MX6SLL */
 513        if (is_mx6sll())
 514                return 0;
 515
 516        set_ldo_voltage(LDO_SOC, 1175); /* Set VDDSOC to 1.175V */
 517
 518        return 0;
 519}
 520
 521#if defined(CONFIG_FEC_MXC)
 522void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
 523{
 524        struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
 525        struct fuse_bank *bank = &ocotp->bank[4];
 526        struct fuse_bank4_regs *fuse =
 527                        (struct fuse_bank4_regs *)bank->fuse_regs;
 528
 529        if ((is_mx6sx() || is_mx6ul() || is_mx6ull()) && dev_id == 1) {
 530                u32 value = readl(&fuse->mac_addr2);
 531                mac[0] = value >> 24 ;
 532                mac[1] = value >> 16 ;
 533                mac[2] = value >> 8 ;
 534                mac[3] = value ;
 535
 536                value = readl(&fuse->mac_addr1);
 537                mac[4] = value >> 24 ;
 538                mac[5] = value >> 16 ;
 539                
 540        } else {
 541                u32 value = readl(&fuse->mac_addr1);
 542                mac[0] = (value >> 8);
 543                mac[1] = value ;
 544
 545                value = readl(&fuse->mac_addr0);
 546                mac[2] = value >> 24 ;
 547                mac[3] = value >> 16 ;
 548                mac[4] = value >> 8 ;
 549                mac[5] = value ;
 550        }
 551
 552}
 553#endif
 554
 555#ifndef CONFIG_SPL_BUILD
 556/*
 557 * cfg_val will be used for
 558 * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0]
 559 * After reset, if GPR10[28] is 1, ROM will use GPR9[25:0]
 560 * instead of SBMR1 to determine the boot device.
 561 */
 562const struct boot_mode soc_boot_modes[] = {
 563        {"normal",      MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)},
 564        /* reserved value should start rom usb */
 565#if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL)
 566        {"usb",         MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)},
 567#else
 568        {"usb",         MAKE_CFGVAL(0x10, 0x00, 0x00, 0x00)},
 569#endif
 570        {"sata",        MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)},
 571        {"ecspi1:0",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)},
 572        {"ecspi1:1",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)},
 573        {"ecspi1:2",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)},
 574        {"ecspi1:3",    MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)},
 575        /* 4 bit bus width */
 576        {"esdhc1",      MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
 577        {"esdhc2",      MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
 578        {"esdhc3",      MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
 579        {"esdhc4",      MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
 580        {NULL,          0},
 581};
 582#endif
 583
 584void reset_misc(void)
 585{
 586#ifdef CONFIG_VIDEO_MXS
 587        lcdif_power_down();
 588#endif
 589}
 590
 591void s_init(void)
 592{
 593        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 594        struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 595        u32 mask480;
 596        u32 mask528;
 597        u32 reg, periph1, periph2;
 598
 599        if (is_mx6sx() || is_mx6ul() || is_mx6ull() || is_mx6sll())
 600                return;
 601
 602        /* Due to hardware limitation, on MX6Q we need to gate/ungate all PFDs
 603         * to make sure PFD is working right, otherwise, PFDs may
 604         * not output clock after reset, MX6DL and MX6SL have added 396M pfd
 605         * workaround in ROM code, as bus clock need it
 606         */
 607
 608        mask480 = ANATOP_PFD_CLKGATE_MASK(0) |
 609                ANATOP_PFD_CLKGATE_MASK(1) |
 610                ANATOP_PFD_CLKGATE_MASK(2) |
 611                ANATOP_PFD_CLKGATE_MASK(3);
 612        mask528 = ANATOP_PFD_CLKGATE_MASK(1) |
 613                ANATOP_PFD_CLKGATE_MASK(3);
 614
 615        reg = readl(&ccm->cbcmr);
 616        periph2 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK)
 617                >> MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET);
 618        periph1 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK)
 619                >> MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET);
 620
 621        /* Checking if PLL2 PFD0 or PLL2 PFD2 is using for periph clock */
 622        if ((periph2 != 0x2) && (periph1 != 0x2))
 623                mask528 |= ANATOP_PFD_CLKGATE_MASK(0);
 624
 625        if ((periph2 != 0x1) && (periph1 != 0x1) &&
 626                (periph2 != 0x3) && (periph1 != 0x3))
 627                mask528 |= ANATOP_PFD_CLKGATE_MASK(2);
 628
 629        writel(mask480, &anatop->pfd_480_set);
 630        writel(mask528, &anatop->pfd_528_set);
 631        writel(mask480, &anatop->pfd_480_clr);
 632        writel(mask528, &anatop->pfd_528_clr);
 633}
 634
 635#ifdef CONFIG_IMX_HDMI
 636void imx_enable_hdmi_phy(void)
 637{
 638        struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
 639        u8 reg;
 640        reg = readb(&hdmi->phy_conf0);
 641        reg |= HDMI_PHY_CONF0_PDZ_MASK;
 642        writeb(reg, &hdmi->phy_conf0);
 643        udelay(3000);
 644        reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
 645        writeb(reg, &hdmi->phy_conf0);
 646        udelay(3000);
 647        reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
 648        writeb(reg, &hdmi->phy_conf0);
 649        writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
 650}
 651
 652void imx_setup_hdmi(void)
 653{
 654        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 655        struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
 656        int reg, count;
 657        u8 val;
 658
 659        /* Turn on HDMI PHY clock */
 660        reg = readl(&mxc_ccm->CCGR2);
 661        reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK|
 662                 MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
 663        writel(reg, &mxc_ccm->CCGR2);
 664        writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
 665        reg = readl(&mxc_ccm->chsccdr);
 666        reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK|
 667                 MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK|
 668                 MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
 669        reg |= (CHSCCDR_PODF_DIVIDE_BY_3
 670                 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
 671                 |(CHSCCDR_IPU_PRE_CLK_540M_PFD
 672                 << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
 673        writel(reg, &mxc_ccm->chsccdr);
 674
 675        /* Clear the overflow condition */
 676        if (readb(&hdmi->ih_fc_stat2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK) {
 677                /* TMDS software reset */
 678                writeb((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, &hdmi->mc_swrstz);
 679                val = readb(&hdmi->fc_invidconf);
 680                /* Need minimum 3 times to write to clear the register */
 681                for (count = 0 ; count < 5 ; count++)
 682                        writeb(val, &hdmi->fc_invidconf);
 683        }
 684}
 685#endif
 686
 687void gpr_init(void)
 688{
 689        struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
 690
 691        /* enable AXI cache for VDOA/VPU/IPU */
 692        writel(0xF00000CF, &iomux->gpr[4]);
 693        if (is_mx6dqp()) {
 694                /* set IPU AXI-id1 Qos=0x1 AXI-id0/2/3 Qos=0x7 */
 695                writel(0x77177717, &iomux->gpr[6]);
 696                writel(0x77177717, &iomux->gpr[7]);
 697        } else {
 698                /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
 699                writel(0x007F007F, &iomux->gpr[6]);
 700                writel(0x007F007F, &iomux->gpr[7]);
 701        }
 702}
 703
 704#ifdef CONFIG_IMX_BOOTAUX
 705int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
 706{
 707        struct src *src_reg;
 708        u32 stack, pc;
 709
 710        if (!boot_private_data)
 711                return -EINVAL;
 712
 713        stack = *(u32 *)boot_private_data;
 714        pc = *(u32 *)(boot_private_data + 4);
 715
 716        /* Set the stack and pc to M4 bootROM */
 717        writel(stack, M4_BOOTROM_BASE_ADDR);
 718        writel(pc, M4_BOOTROM_BASE_ADDR + 4);
 719
 720        /* Enable M4 */
 721        src_reg = (struct src *)SRC_BASE_ADDR;
 722        clrsetbits_le32(&src_reg->scr, SRC_SCR_M4C_NON_SCLR_RST_MASK,
 723                        SRC_SCR_M4_ENABLE_MASK);
 724
 725        return 0;
 726}
 727
 728int arch_auxiliary_core_check_up(u32 core_id)
 729{
 730        struct src *src_reg = (struct src *)SRC_BASE_ADDR;
 731        unsigned val;
 732
 733        val = readl(&src_reg->scr);
 734
 735        if (val & SRC_SCR_M4C_NON_SCLR_RST_MASK)
 736                return 0;  /* assert in reset */
 737
 738        return 1;
 739}
 740#endif
 741