]> git.sur5r.net Git - u-boot/blobdiff - arch/arm/cpu/arm720t/tegra114/cpu.c
ARM: tegra: don't exceed AVP limits when configuring PLLP
[u-boot] / arch / arm / cpu / arm720t / tegra114 / cpu.c
index 5962e15b4f3835155cb8abab6b9faa4521aa5b6c..385e1a1c86e0610f4509dc32867b8f66e81abfe2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2013, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2010-2014, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -126,18 +126,6 @@ void t114_init_clocks(void)
        /* Set active CPU cluster to G */
        clrbits_le32(&flow->cluster_control, 1);
 
-       /*
-        * Switch system clock to PLLP_OUT4 (108 MHz), AVP will now run
-        * at 108 MHz. This is glitch free as only the source is changed, no
-        * special precaution needed.
-        */
-       val = (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) |
-               (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) |
-               (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) |
-               (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) |
-               (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT);
-       writel(val, &clkrst->crc_sclk_brst_pol);
-
        writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div);
 
        debug("Setting up PLLX\n");
@@ -170,15 +158,13 @@ void t114_init_clocks(void)
        clock_set_enable(PERIPH_ID_MC1, 1);
        clock_set_enable(PERIPH_ID_DVFS, 1);
 
-       /* Switch MSELECT clock to PLLP (00) */
-       clock_ll_set_source(PERIPH_ID_MSELECT, 0);
-
        /*
-        * Clock divider request for 102MHz would setup MSELECT clock as
-        * 102MHz for PLLP base 408MHz
+        * Set MSELECT clock source as PLLP (00), and ask for a clock
+        * divider that would set the MSELECT clock at 102MHz for a
+        * PLLP base of 408MHz.
         */
        clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0,
-               (NVBL_PLLP_KHZ/102000));
+               CLK_DIVIDER(NVBL_PLLP_KHZ, 102000));
 
        /* I2C5 (DVC) gets CLK_M and a divisor of 17 */
        clock_ll_set_source_divisor(PERIPH_ID_I2C5, 3, 16);
@@ -201,6 +187,7 @@ void t114_init_clocks(void)
        reset_set_enable(PERIPH_ID_MSELECT, 0);
        reset_set_enable(PERIPH_ID_EMC1, 0);
        reset_set_enable(PERIPH_ID_MC1, 0);
+       reset_set_enable(PERIPH_ID_DVFS, 0);
 
        debug("t114_init_clocks exit\n");
 }
@@ -220,8 +207,8 @@ static int is_clamp_enabled(u32 mask)
        struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
        u32 reg;
 
-       /* Get clamp status. TODO: Add pmc_clamp_status alias to pmc.h */
-       reg = readl(&pmc->pmc_pwrgate_timer_on);
+       /* Get clamp status. */
+       reg = readl(&pmc->pmc_clamp_status);
        return (reg & mask) == mask;
 }
 
@@ -269,6 +256,8 @@ void powerup_cpus(void)
 
 void start_cpu(u32 reset_vector)
 {
+       u32 imme, inst;
+
        debug("start_cpu entry, reset_vector = %x\n", reset_vector);
 
        t114_init_clocks();
@@ -285,12 +274,38 @@ void start_cpu(u32 reset_vector)
        /* Take CPU(s) out of reset */
        remove_cpu_resets();
 
+       /* Set the entry point for CPU execution from reset */
+
        /*
-        * Set the entry point for CPU execution from reset,
-        *  if it's a non-zero value.
+        * A01P with patched boot ROM; vector hard-coded to 0x4003fffc.
+        * See nvbug 1193357 for details.
         */
-       if (reset_vector)
-               writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR);
+
+       /* mov r0, #lsb(reset_vector) */
+       imme = reset_vector & 0xffff;
+       inst = imme & 0xfff;
+       inst |= ((imme >> 12) << 16);
+       inst |= 0xe3000000;
+       writel(inst, 0x4003fff0);
+
+       /* movt r0, #msb(reset_vector) */
+       imme = (reset_vector >> 16) & 0xffff;
+       inst = imme & 0xfff;
+       inst |= ((imme >> 12) << 16);
+       inst |= 0xe3400000;
+       writel(inst, 0x4003fff4);
+
+       /* bx r0 */
+       writel(0xe12fff10, 0x4003fff8);
+
+       /* b -12 */
+       imme = (u32)-20;
+       inst = (imme >> 2) & 0xffffff;
+       inst |= 0xea000000;
+       writel(inst, 0x4003fffc);
+
+       /* Write to orignal location for compatibility */
+       writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR);
 
        /* If the CPU(s) don't already have power, power 'em up */
        powerup_cpus();