From: Jimmy Zhang <jimmzh...@nvidia.com>

Based on the Tegra114 TRM, SCLK (system clock) can run up to 275MHz.
At POR, the default SCLK source is set to PLLP_OUT0. In function
clock_early_init(), PLLP_OUT0 will be set to 480MHz which is beyond
the SCLK's upper limit.

The fix is to set SCLK source to CLK_M before initializing PLLP.
Tested on A02 dalmore board.

Signed-off-by: Jimmy Zhang <jimmzh...@nvidia.com>
Signed-off-by: Tom Warren <twar...@nvidia.com>
---
v2: 
- Move/clarify comments and commit msg as per StephenW
- Don't remove various unrelated clock enable/reset calls

 arch/arm/cpu/arm720t/tegra-common/spl.c   | 12 ++++++++++++
 arch/arm/cpu/arm720t/tegra114/cpu.c       | 20 ++++++++++++++++++--
 arch/arm/cpu/tegra114-common/clock.c      | 13 +++++++++++++
 arch/arm/include/asm/arch-tegra/clk_rst.h |  7 +++++++
 4 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/arch/arm/cpu/arm720t/tegra-common/spl.c 
b/arch/arm/cpu/arm720t/tegra-common/spl.c
index 5171a8f..49a0544 100644
--- a/arch/arm/cpu/arm720t/tegra-common/spl.c
+++ b/arch/arm/cpu/arm720t/tegra-common/spl.c
@@ -17,6 +17,10 @@
 #include <asm/arch/spl.h>
 #include "cpu.h"
 
+__weak void set_avp_clock_to_clkm(void)
+{
+}
+
 void spl_board_init(void)
 {
        struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
@@ -24,6 +28,14 @@ void spl_board_init(void)
        /* enable JTAG */
        writel(0xC0, &pmt->pmt_cfg_ctl);
 
+       /*
+        * On poweron, AVP's clock source (also called system clock, or SCLK)
+        * is set to PLLP_OUT0 with a frequency of 1MHz. Before initializing
+        * PLLP, we need to move the SCLK source to CLK_M temporarily, and then
+        * switch it to PLLP_OUT4 (204MHz) at a later time.
+        */
+       set_avp_clock_to_clkm();
+
        board_init_uart_f();
 
        /* Initialize periph GPIOs */
diff --git a/arch/arm/cpu/arm720t/tegra114/cpu.c 
b/arch/arm/cpu/arm720t/tegra114/cpu.c
index 51ecff7..8f7bce4 100644
--- a/arch/arm/cpu/arm720t/tegra114/cpu.c
+++ b/arch/arm/cpu/arm720t/tegra114/cpu.c
@@ -127,8 +127,8 @@ void t114_init_clocks(void)
        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
+        * Switch system clock to PLLP_OUT4 (204 MHz), AVP will now run
+        * at 204 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) |
@@ -322,3 +322,19 @@ void start_cpu(u32 reset_vector)
        /* If the CPU(s) don't already have power, power 'em up */
        powerup_cpus();
 }
+
+/* Use CLK_M (crystal freq) as AVP/COP (SCLK) clock source */
+void set_avp_clock_to_clkm(void)
+{
+       struct clk_rst_ctlr *clkrst =
+                       (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+       u32 val;
+
+       val = (SCLK_SOURCE_CLKM << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) |
+               (SCLK_SOURCE_CLKM << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) |
+               (SCLK_SOURCE_CLKM << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) |
+               (SCLK_SOURCE_CLKM << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) |
+               (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT);
+       writel(val, &clkrst->crc_sclk_brst_pol);
+       udelay(3);
+}
diff --git a/arch/arm/cpu/tegra114-common/clock.c 
b/arch/arm/cpu/tegra114-common/clock.c
index 5c4305a..e9a1a80 100644
--- a/arch/arm/cpu/tegra114-common/clock.c
+++ b/arch/arm/cpu/tegra114-common/clock.c
@@ -609,6 +609,7 @@ void clock_early_init(void)
 {
        struct clk_rst_ctlr *clkrst =
                (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+       u32     reg;
 
        /*
         * PLLP output frequency set to 408Mhz
@@ -653,6 +654,18 @@ void clock_early_init(void)
        /* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1 */
        writel(0x40000C10, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc);
        udelay(2);
+
+       /* Set PLLP_OUT3 and 4 freqs to 102MHz and 204MHz */
+       /* Assert RSTN before enable */
+       reg = PLLP_OUT4_RSTN_EN | PLLP_OUT3_RSTN_EN;
+       writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[1]);
+
+       /* set divisor and reenable */
+       reg = (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO)
+               | PLLP_OUT4_OVR | PLLP_OUT4_CLKEN | PLLP_OUT4_RSTN_DIS
+               | (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO)
+               | PLLP_OUT3_OVR | PLLP_OUT3_CLKEN | PLLP_OUT3_RSTN_DIS;
+       writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[1]);
 }
 
 void arch_timer_init(void)
diff --git a/arch/arm/include/asm/arch-tegra/clk_rst.h 
b/arch/arm/include/asm/arch-tegra/clk_rst.h
index 074b3bc..a4c17e7 100644
--- a/arch/arm/include/asm/arch-tegra/clk_rst.h
+++ b/arch/arm/include/asm/arch-tegra/clk_rst.h
@@ -209,6 +209,13 @@ enum {
        IN_408_OUT_9_6_DIVISOR = 83,
 };
 
+#define PLLP_OUT3_RSTN_DIS     (1 << 0)
+#define PLLP_OUT3_RSTN_EN      (0 << 0)
+#define PLLP_OUT3_CLKEN                (1 << 1)
+#define PLLP_OUT4_RSTN_DIS     (1 << 16)
+#define PLLP_OUT4_RSTN_EN      (0 << 16)
+#define PLLP_OUT4_CLKEN                (1 << 17)
+
 /* CLK_RST_CONTROLLER_UTMIP_PLL_CFG1_0 */
 #define PLLU_POWERDOWN         (1 << 16)
 #define PLL_ENABLE_POWERDOWN   (1 << 14)
-- 
1.8.1.5

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to