ARM: tegra: don't exceed AVP limits when configuring PLLP
Subsystems (2)
PATCH v2 1/1 ARM: tegra: don't exceed AVP limits when configuring PLLP
From: Jimmy Zhang <[email protected]>
Based on the Tegra TRM, the system clock (which is the AVP clock) can run up to 275MHz. On power on, the default sytem clock source is set to PLLP_OUT0. In function clock_early_init(), PLLP_OUT0 will be set to 408MHz which is beyond system clock's upper limit.
The fix is to set the system clock to CLK_M before initializing PLLP, and then switch back to PLLP_OUT4, which has an appropriate divider configured, after PLLP has been configured
Implement this logic in new function tegra30_or_later_adjust_pllp(), which sets up PLLP and all PLLP_OUT* dividers, and handles the AVP clock switching. Remove the duplicate PLLP setup from pllx_set_rate() and adjust_pllp_out_freqs().
---
v2:
* Remove duplicate adjustment of PLLP dividers from pllx_set_rate()
* Adjust PLLP_OUT1/PLLP_OUT2 dividers from clock_early_init() so that everything related to PLLP is set up at once.
* Initialize PLLP from a new common function tegra30_or_later_adjust_pllp() so the code isn't duplicated.
--- arch/arm/cpu/arm720t/tegra-common/cpu.c | 26 +-------- arch/arm/cpu/arm720t/tegra114/cpu.c | 14 +---- arch/arm/cpu/arm720t/tegra30/cpu.c | 14 +---- arch/arm/cpu/tegra-common/clock.c | 90 ++++++++++++++++++++++++++++++- arch/arm/cpu/tegra114-common/clock.c | 8 ++- arch/arm/cpu/tegra30-common/clock.c | 31 +---------- arch/arm/include/asm/arch-tegra/clk_rst.h | 16 +++++- arch/arm/include/asm/arch-tegra/clock.h | 2 + 8 files changed, 114 insertions(+), 87 deletions(-)
arch/arm/cpu/arm720t/tegra-common/cpu.c +1 -25
@@ -1,5 +1,5 @@/* -* Copyright (c) 2010-2012, 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,
@@ -114,24 +114,6 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = { }, }; -void adjust_pllp_out_freqs (void ) -{ -struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE ; -struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_PERIPH ]; -u32 reg; - -/* Set T30 PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */ - reg =readl (&pll->pll_out[0 ]);/* OUTA, contains OUT2 / OUT1 */ - reg |= (IN_408_OUT_48_DIVISOR <<PLLP_OUT2_RATIO ) |PLLP_OUT2_OVR - | (IN_408_OUT_9_6_DIVISOR <<PLLP_OUT1_RATIO ) |PLLP_OUT1_OVR ; -writel (reg, &pll->pll_out[0 ]); - - reg =readl (&pll->pll_out[1 ]);/* OUTB, contains OUT4 / OUT3 */ - reg |= (IN_408_OUT_204_DIVISOR <<PLLP_OUT4_RATIO ) |PLLP_OUT4_OVR - | (IN_408_OUT_102_DIVISOR <<PLLP_OUT3_RATIO ) |PLLP_OUT3_OVR ; -writel (reg, &pll->pll_out[1 ]); -} -int pllx_set_rate (struct clk_pll_simple *pll ,u32 divn,u32 divm,u32 divp,u32 cpcon) {
@@ -207,12 +189,6 @@ void init_pllx(void)/* set pllx */ sel = &tegra_pll_x_table[chip_sku][osc];pllx_set_rate (pll, sel->n, sel->m, sel->p, sel->cpcon); - -/* adjust PLLP_out1-4 on T3x/T114 */ -if (soc_type >=CHIPID_TEGRA30 ) { -debug (" init_pllx: adjusting PLLP out freqs\n" ); -adjust_pllp_out_freqs (); - } }void enable_cpu_clock (int enable)
arch/arm/cpu/arm720t/tegra114/cpu.c +1 -13
@@ -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" );
arch/arm/cpu/arm720t/tegra30/cpu.c +1 -13
@@ -1,5 +1,5 @@/* -* Copyright (c) 2010-2012, 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,
@@ -84,18 +84,6 @@ void t30_init_clocks(void)/* Set active CPU cluster to G */ clrbits_le32 (flow->cluster_control,1 <<0 ); -/* -* Switch system clock to PLLP_OUT4 (108 MHz), AVP will now run -*@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); val = (0 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT) |
arch/arm/cpu/tegra-common/clock.c +89 -1
97 lines not on this page · raw message
arch/arm/cpu/tegra114-common/clock.c +3 -5
@@ -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,
@@ -604,26 +604,24 @@ void clock_early_init(void)struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE ; +tegra30_or_later_adjust_pllp (); +/* -* PLLP output frequency set to 408Mhz * PLLC output frequency set to 600Mhz * PLLD output frequency set to 925Mhz */ switch (clock_get_osc_freq ()) {case CLOCK_OSC_FREQ_12_0 :/* OSC is 12Mhz */ -clock_set_rate (CLOCK_ID_PERIPH ,408 ,12 ,0 ,8 );clock_set_rate (CLOCK_ID_CGENERAL ,600 ,12 ,0 ,8 );clock_set_rate (CLOCK_ID_DISPLAY ,925 ,12 ,0 ,12 );break ;case CLOCK_OSC_FREQ_26_0 :/* OSC is 26Mhz */ -clock_set_rate (CLOCK_ID_PERIPH ,408 ,26 ,0 ,8 );clock_set_rate (CLOCK_ID_CGENERAL ,600 ,26 ,0 ,8 );clock_set_rate (CLOCK_ID_DISPLAY ,925 ,26 ,0 ,12 );break ;case CLOCK_OSC_FREQ_13_0 :/* OSC is 13Mhz */ -clock_set_rate (CLOCK_ID_PERIPH ,408 ,13 ,0 ,8 );clock_set_rate (CLOCK_ID_CGENERAL ,600 ,13 ,0 ,8 );clock_set_rate (CLOCK_ID_DISPLAY ,925 ,13 ,0 ,12 );break ;
arch/arm/cpu/tegra30-common/clock.c +2 -29
@@ -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,
@@ -581,34 +581,7 @@ enum periph_id clk_id_to_periph_id(int clk_id)void clock_early_init (void ) { -/* -* PLLP output frequency set to 408Mhz -* PLLC output frequency set to 228Mhz -*/ -switch (clock_get_osc_freq ()) { -case CLOCK_OSC_FREQ_12_0 :/* OSC is 12Mhz */ -clock_set_rate (CLOCK_ID_PERIPH ,408 ,12 ,0 ,8 ); -clock_set_rate (CLOCK_ID_CGENERAL ,456 ,12 ,1 ,8 ); -break ; - -case CLOCK_OSC_FREQ_26_0 :/* OSC is 26Mhz */ -clock_set_rate (CLOCK_ID_PERIPH ,408 ,26 ,0 ,8 ); -clock_set_rate (CLOCK_ID_CGENERAL ,600 ,26 ,0 ,8 ); -break ; - -case CLOCK_OSC_FREQ_13_0 :/* OSC is 13Mhz */ -clock_set_rate (CLOCK_ID_PERIPH ,408 ,13 ,0 ,8 ); -clock_set_rate (CLOCK_ID_CGENERAL ,600 ,13 ,0 ,8 ); -break ; -case CLOCK_OSC_FREQ_19_2 : -default : -/* -* These are not supported. It is too early to print a -* message and the UART likely won't work anyway due to the -* oscillator being wrong. -*/ -break ; - } +tegra30_or_later_adjust_pllp (); }void arch_timer_init (void )
arch/arm/include/asm/arch-tegra/clk_rst.h +15 -1
@@ -1,5 +1,5 @@/* -* (C) Copyright 2010,2011 +* (C) Copyright 2010-2014 * NVIDIA Corporation <www.nvidia.com> * * SPDX-License-Identifier: GPL-2.0+
@@ -209,6 +209,20 @@ enum { IN_408_OUT_9_6_DIVISOR = 83, }; +#define PLLP_OUT1_RSTN_DIS (1 << 0) +#define PLLP_OUT1_RSTN_EN (0 << 0) +#define PLLP_OUT1_CLKEN (1 << 1) +#define PLLP_OUT2_RSTN_DIS (1 << 16) +#define PLLP_OUT2_RSTN_EN (0 << 16) +#define PLLP_OUT2_CLKEN (1 << 17) + +#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)
arch/arm/include/asm/arch-tegra/clock.h +2 -0
@@ -320,4 +320,6 @@ int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon);/* SoC-specific TSC init */ void arch_timer_init (void ); +void tegra30_or_later_adjust_pllp (void ); +#endif /* _TEGRA_CLOCK_H_ */
Signature · 1 line
1.8.1.5
PATCH v2 1/1 ARM: tegra: don't exceed AVP limits when configuring PLLP
On Thu, Jan 23, 2014 at 11:58:13AM -0700, Stephen Warren wrote:
[...]
Quoted 1 line
arch/arm/cpu/tegra-common/clock.c +0
-0
[...]
arch/arm/cpu/tegra-common/clock.c void clock_init(void) · line 579
Quoted 6 lines
arch/arm/cpu/tegra-common/clock.c +2
-0@@ -575,3 +575,91 @@ void clock_init(void)/* Do any special system timer/TSC setup */ arch_timer_init (); } + +static void set_avp_clock_to (u32 src)
Perhaps a better name would be "set_avp_clock_source()"? _to had me confused at first because I assumed it would be setting a frequency.
arch/arm/cpu/tegra-common/clock.c void clock_init(void) · line 594
Quoted 1 line
arch/arm/cpu/tegra-common/clock.c +1
-0+void tegra30_or_later_adjust_pllp (void )
I would've called this simply tegra30_adjust_pllp(), where it's implied that when you call tegra30_*() from code targetted at later generations these would be compatible with Tegra30.
But if you'd rather make it implicit that's fine too.
Either way:
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140124/903f6173/attachment.pgp>
PATCH v2 1/1 ARM: tegra: don't exceed AVP limits when configuring PLLP
Quoted 4 lines · Thierry Reding
On Thu, Jan 23, 2014 at 11:58:13AM -0700, Stephen Warren wrote:
[...]Quoted 1 line
arch/arm/cpu/tegra-common/clock.c +0
-0[...]
Quoted 9 lines
arch/arm/cpu/tegra-common/clock.c void clock_init(void) · line 579
Quoted 6 lines
arch/arm/cpu/tegra-common/clock.c +2
-0@@ -575,3 +575,91 @@ void clock_init(void)/* Do any special system timer/TSC setup */ arch_timer_init (); } + +static void set_avp_clock_to (u32 src)Perhaps a better name would be "
set_avp_clock_source()"?_tohad me confused at first because I assumed it would be setting a frequency.
Yes, that name is better.
Quoted 7 lines
arch/arm/cpu/tegra-common/clock.c void clock_init(void) · line 594
Quoted 1 line
arch/arm/cpu/tegra-common/clock.c +1
-0+void tegra30_or_later_adjust_pllp (void )I would've called this simply
tegra30_adjust_pllp(), where it's implied that when you call tegra30_*() from code targetted at later generations these would be compatible with Tegra30.But if you'd rather make it implicit that's fine too.
I wondered about that, and thought it'd be odd for e.g. Tegra114 clock code to be calling Tegra30 functions. That said, if we start encoding into function names a complete description of which chips they support, we'll have very long function names, so I guess renaming it makes sense. I'll post V3.