* [U-Boot] [PATCH v2] Tegra114: SPL: Set SCLK source to CLK_M before PLLP init.
@ 2013-10-15 21:18 Tom Warren
2013-10-16 20:36 ` Stephen Warren
0 siblings, 1 reply; 2+ messages in thread
From: Tom Warren @ 2013-10-15 21:18 UTC (permalink / raw)
To: u-boot
From: Jimmy Zhang <jimmzhang@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 <jimmzhang@nvidia.com>
Signed-off-by: Tom Warren <twarren@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
^ permalink raw reply related [flat|nested] 2+ messages in thread* [U-Boot] [PATCH v2] Tegra114: SPL: Set SCLK source to CLK_M before PLLP init.
2013-10-15 21:18 [U-Boot] [PATCH v2] Tegra114: SPL: Set SCLK source to CLK_M before PLLP init Tom Warren
@ 2013-10-16 20:36 ` Stephen Warren
0 siblings, 0 replies; 2+ messages in thread
From: Stephen Warren @ 2013-10-16 20:36 UTC (permalink / raw)
To: u-boot
On 10/15/2013 03:18 PM, Tom Warren wrote:
> From: Jimmy Zhang <jimmzhang@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.
> diff --git a/arch/arm/cpu/arm720t/tegra-common/spl.c b/arch/arm/cpu/arm720t/tegra-common/spl.c
> +__weak void set_avp_clock_to_clkm(void)
> +{
> +}
Why do we need a weak symbol here? You always want to pick up the
implementation in arch/arm/cpu/arm720t/tegra114/cpu.c, or it won't work...
Sorry for not noticing this earlier.
> diff --git a/arch/arm/cpu/tegra114-common/clock.c b/arch/arm/cpu/tegra114-common/clock.c
> @@ -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]);
Rather than calling set_avp_clock_to_clkm() from spl.c, wouldn't it make
sense to call it from inside clock_early_init() where the PLL_P rate
change actually happens? That would absolutely minimize the time the
AVP spends running at a slow speed.
Also, shouldn't there be a matching set_avp_clock_to_pllpout4() or
similar after PLL_P is fully configured, or the AVP will continue to run
slowly for the rest of the time too. Admittedly it doesn't run a lot of
code so the different isn't likely to be large, but just dumping it down
to 12MHz forever seems like a bad idea.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2013-10-16 20:36 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-15 21:18 [U-Boot] [PATCH v2] Tegra114: SPL: Set SCLK source to CLK_M before PLLP init Tom Warren
2013-10-16 20:36 ` Stephen Warren
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox