armv8: Make COUNTER_FREQUENCY optional
Subsystems (3)
PATCH 1/6 armv8: Make COUNTER_FREQUENCY optional
From: Thierry Reding <[email protected]>
Some platforms have the means to determine the counter frequency at runtime, so give them an opportunity to do so.
--- arch/arm/cpu/armv8/start.S | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/cpu/armv8/start.S +2 -0
@@ -54,8 +54,10 @@ reset: orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */ msr scr_el3, x0 msr cptr_el3, xzr /* Enable FP/SIMD */ +#ifdef COUNTER_FREQUENCY ldr x0, =COUNTER_FREQUENCY msr cntfrq_el0, x0 /* Initialize CNTFRQ */ +#endif b 0f 2: msr vbar_el2, x0 mov x0, #0x33ff
Signature · 1 line
2.4.5
PATCH 2/6 ARM: tegra: Implement clk_m
From: Thierry Reding <[email protected]>
On currently supported SoCs, clk_m always runs at the same frequency as the oscillator input. However newer SoC generations such as Tegra210 no longer have that restriction. Prepare for that by separating clk_m from the oscillator clock and allow SoC code to override the clk_m rate.
--- arch/arm/include/asm/arch-tegra/clock.h | 3 +++ arch/arm/include/asm/arch-tegra114/clock-tables.h | 1 + arch/arm/include/asm/arch-tegra124/clock-tables.h | 1 + arch/arm/include/asm/arch-tegra20/clock-tables.h | 1 + arch/arm/include/asm/arch-tegra210/clock-tables.h | 1 + arch/arm/include/asm/arch-tegra30/clock-tables.h | 1 + arch/arm/mach-tegra/clock.c | 10 ++++++++++ arch/arm/mach-tegra/tegra210/clock.c | 11 +++++++++++ 8 files changed, 29 insertions(+)
arch/arm/include/asm/arch-tegra/clock.h +3 -0
@@ -44,6 +44,9 @@ enum {/* return the current oscillator clock frequency */ enum clock_osc_freq clock_get_osc_freq (void ); +/* return the clk_m frequency */ +unsigned int clk_m_get_rate (unsigned int parent_rate); +/** * Start PLL using the provided configuration parameters. *
arch/arm/include/asm/arch-tegra114/clock-tables.h +1 -0
@@ -38,6 +38,7 @@ enum clock_id {/* These are the base clocks (inputs to the Tegra SOC) */ CLOCK_ID_32KHZ ,CLOCK_ID_OSC , +CLOCK_ID_CLK_M ,CLOCK_ID_COUNT ,/* number of PLLs */ CLOCK_ID_DISPLAY2, /* placeholder */
arch/arm/include/asm/arch-tegra124/clock-tables.h +1 -0
@@ -30,6 +30,7 @@ enum clock_id {/* These are the base clocks (inputs to the Tegra SoC) */ CLOCK_ID_32KHZ ,CLOCK_ID_OSC , +CLOCK_ID_CLK_M , CLOCK_ID_COUNT, /* number of PLLs */
arch/arm/include/asm/arch-tegra20/clock-tables.h +1 -0
@@ -29,6 +29,7 @@ enum clock_id {/* These are the base clocks (inputs to the Tegra SOC) */ CLOCK_ID_32KHZ ,CLOCK_ID_OSC , +CLOCK_ID_CLK_M ,CLOCK_ID_COUNT ,/* number of clocks */ CLOCK_ID_NONE = -1,
arch/arm/include/asm/arch-tegra210/clock-tables.h +1 -0
@@ -30,6 +30,7 @@ enum clock_id {/* These are the base clocks (inputs to the Tegra SoC) */ CLOCK_ID_32KHZ ,CLOCK_ID_OSC , +CLOCK_ID_CLK_M , CLOCK_ID_COUNT, /* number of PLLs */
arch/arm/include/asm/arch-tegra30/clock-tables.h +1 -0
@@ -38,6 +38,7 @@ enum clock_id {/* These are the base clocks (inputs to the Tegra SOC) */ CLOCK_ID_32KHZ ,CLOCK_ID_OSC , +CLOCK_ID_CLK_M ,CLOCK_ID_COUNT ,/* number of PLLs */ CLOCK_ID_DISPLAY2, /* Tegra3, placeholder */
arch/arm/mach-tegra/clock.c +10 -0
@@ -461,6 +461,11 @@ void reset_cmplx_set_enable(int cpu, int which, int reset)writel (mask, &clkrst->crc_cpu_cmplx_clr); } +unsigned int __weak clk_m_get_rate (unsigned int parent_rate) +{ +return parent_rate; +} +unsigned clock_get_rate (enum clock_id clkid) {struct clk_pll *pll;
@@ -472,6 +477,9 @@ unsigned clock_get_rate(enum clock_id clkid)if (clkid ==CLOCK_ID_OSC )return parent_rate; +if (clkid ==CLOCK_ID_CLK_M ) +return clk_m_get_rate (parent_rate); + pll =get_pll (clkid);if (!pll)return 0 ;
@@ -613,8 +621,10 @@ void clock_init(void) pll_rate[CLOCK_ID_XCPU ] =clock_get_rate (CLOCK_ID_XCPU ); pll_rate[CLOCK_ID_SFROM32KHZ ] =32768 ; pll_rate[CLOCK_ID_OSC ] =clock_get_rate (CLOCK_ID_OSC ); + pll_rate[CLOCK_ID_CLK_M ] =clock_get_rate (CLOCK_ID_CLK_M );debug ("Osc = %d\n" , pll_rate[CLOCK_ID_OSC ]); +debug ("CLKM = %d\n" , pll_rate[CLOCK_ID_CLK_M ]);debug ("PLLC = %d\n" , pll_rate[CLOCK_ID_CGENERAL ]);debug ("PLLM = %d\n" , pll_rate[CLOCK_ID_MEMORY ]);debug ("PLLP = %d\n" , pll_rate[CLOCK_ID_PERIPH ]);
arch/arm/mach-tegra/tegra210/clock.c +11 -0
@@ -998,6 +998,17 @@ void clock_early_init(void)udelay (2 ); } +unsigned int clk_m_get_rate (unsigned parent_rate) +{ +struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE ; +u32 value, div; + + value =readl (&clkrst->crc_spare_reg0); + div = ((value >>2 ) &0x3 ) +1 ; + +return parent_rate / div; +} +void arch_timer_init (void ) {struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE ;
Signature · 1 line
2.4.5
PATCH 2/6 ARM: tegra: Implement clk_m
Quoted 12 lines · Thierry Reding
From: Thierry Reding <[email protected]>
On currently supported SoCs,
clk_malways runs at the same frequency as the oscillator input. However newer SoC generations such as Tegra210 no longer have that restriction. Prepare for that by separatingclk_mfrom the oscillator clock and allow SoC code to override theclk_mrate.arch/arm/include/asm/arch-tegra114/clock-tables.h +0
-0
arch/arm/include/asm/arch-tegra114/clock-tables.h enum clock_id { · line 44
Quoted 7 lines
arch/arm/include/asm/arch-tegra114/clock-tables.h +1
-0@@ -38,6 +38,7 @@ enum clock_id {/* These are the base clocks (inputs to the Tegra SOC) */ CLOCK_ID_32KHZ ,CLOCK_ID_OSC , +CLOCK_ID_CLK_M ,CLOCK_ID_COUNT ,/* number of PLLs */ CLOCK_ID_DISPLAY2, /* placeholder */
clock.h contains the following:
/* Number of PLL-based clocks (i.e. not OSC or 32KHz) */
#define CLOCK_ID_PLL_COUNT (CLOCK_ID_COUNT - 2)
... which would need to be updated. Related, see internal bug number 1676978 to see if any of the other gotchas there affect this patch.
PATCH 2/6 ARM: tegra: Implement clk_m
Stephen/Thierry,
Quoted 27 lines
-----Original Message-----
From: Stephen Warren [mailto:swarren at wwwdotorg.org]
Sent: Thursday, August 20, 2015 7:59 AM
To: Thierry Reding
Cc: Albert Aribaud; Tom Warren; u-boot at lists.denx.de; Stephen Warren
Subject: Re: [U-Boot] [PATCH 2/6] ARM: tegra: Implementclk_mQuoted 6 lines · Thierry Reding
From: Thierry Reding <[email protected]>
On currently supported SoCs,
clk_malways runs at the same frequency as the oscillator input. However newer SoC generations such as Tegra210 no longer have that restriction. Prepare for that by separatingclk_mfrom the oscillator clock and allow SoC code to overridethe
clk_mrate.Quoted 11 lines
arch/arm/include/asm/arch-tegra114/clock-tables.h +1
-0@@ -38,6 +38,7 @@ enum clock_id {/* These are the base clocks (inputs to the Tegra SOC) */ CLOCK_ID_32KHZ ,CLOCK_ID_OSC , + CLOCK_ID_CLK_M,
Quoted 7 lines
arch/arm/include/asm/arch-tegra114/clock-tables.h enum clock_id { · line 44
Quoted 2 lines
arch/arm/include/asm/arch-tegra114/clock-tables.h +0
-0CLOCK_ID_COUNT ,/* number of PLLs */ CLOCK_ID_DISPLAY2, /* placeholder */
clock.hcontains the following:/* Number of PLL-based clocks (i.e. not OSC or 32KHz) */
#defineCLOCK_ID_PLL_COUNT(CLOCK_ID_COUNT- 2)
I decremented the CLOCK_ID_COUNT for my pllinfo tables, since 32KHZ and OSC have no PLL params that can be configured, to remove the 2 extra, empty table entries.
We can either remove it, and add 2 empty entries for OSC/32KHZ in all the pllinfo tables (per SoC), and then add new CLOCK_ID entries wherever, or have a rule that new entries here need to be above ID_32KHZ for any PLL needing dividers, etc., and below it for any static clock like OSC, 32KHz, etc. Of course, we'll need to keep track of the decrement depending on how many IDs are added and where. Might be easier to just have an entry for every CLOCK_ID, regardless.
Tom
--
nvpublic
Quoted 3 lines
... which would need to be updated. Related, see internal bug number 1676978 to see if any of the other gotchas there affect this patch.
PATCH 2/6 ARM: tegra: Implement clk_m
In reply to Stephen WarrenQuoted 45 lines
-----Original Message-----
From: Tom Warren
Sent: Thursday, August 20, 2015 9:20 AM
To: 'Stephen Warren'; Thierry Reding
Cc: Albert Aribaud; u-boot at lists.denx.de; Stephen Warren
Subject: RE: [U-Boot] [PATCH 2/6] ARM: tegra: Implementclk_mStephen/Thierry,
Quoted 28 lines
-----Original Message-----
From: Stephen Warren [mailto:swarren at wwwdotorg.org]
Sent: Thursday, August 20, 2015 7:59 AM
To: Thierry Reding
Cc: Albert Aribaud; Tom Warren; u-boot at lists.denx.de; Stephen Warren
Subject: Re: [U-Boot] [PATCH 2/6] ARM: tegra: Implementclk_mQuoted 7 lines · Thierry Reding
From: Thierry Reding <[email protected]>
On currently supported SoCs,
clk_malways runs at the same frequency as the oscillator input. However newer SoC generations such as Tegra210 no longer have that restriction. Prepare for that by separatingclk_mfrom the oscillator clock and allow SoC code to overridethe
clk_mrate.Quoted 11 lines
arch/arm/include/asm/arch-tegra114/clock-tables.h +1
-0@@ -38,6 +38,7 @@ enum clock_id {/* These are the base clocks (inputs to the Tegra SOC) */ CLOCK_ID_32KHZ ,CLOCK_ID_OSC , + CLOCK_ID_CLK_M,Quoted 7 lines
arch/arm/include/asm/arch-tegra114/clock-tables.h enum clock_id { · line 44
Quoted 2 lines
arch/arm/include/asm/arch-tegra114/clock-tables.h +0
-0CLOCK_ID_COUNT ,/* number of PLLs */ CLOCK_ID_DISPLAY2, /* placeholder */
clock.hcontains the following:/* Number of PLL-based clocks (i.e. not OSC or 32KHz) */
#defineCLOCK_ID_PLL_COUNT(CLOCK_ID_COUNT- 2)
Quoted 10 lines
I decremented the
CLOCK_ID_COUNTfor my pllinfo tables, since 32KHZ and OSC have no PLL params that can be configured, to remove the 2 extra, empty table entries.
We can either remove it, and add 2 empty entries for OSC/32KHZ in all the pllinfo tables (per SoC), and then add newCLOCK_IDentries wherever, or have a rule that new entries here need to be aboveID_32KHZfor any PLL needing dividers, etc., and below it for any static clock like OSC, 32KHz, etc. Of course, we'll need to keep track of the decrement depending on how many IDs are added and where. Might be easier to just have an entry for everyCLOCK_ID, regardless.
I applied Thierry's patchset and found that adding CLK_M to the CLOCK_ID tables results in an extra empty pll_info_table entry (3 32-bit words) for each SoC.
So I can leave it as-is, or I can adjust CLOCK_ID_PLL_COUNT in clock.h to be CLOCK_ID_COUNT - 3 to account for the 3 non-configurable clocks (OSC, 32KHz and MCLK), and there'll be no extra empty data in the pll_info tables.
I'm going to go with the 2nd approach. I've applied these (plus some from Stephen and one from Axel Lin) to u-boot-tegra/next and after some testing today I'll be pushing this to Denx for everyone to play with it before I send a PR to TomR. So PTAL.
Thanks
Tom
--
nvpublic
Quoted 4 lines
Quoted 4 lines
... which would need to be updated. Related, see internal bug number 1676978 to see if any of the other gotchas there affect this patch.
PATCH 3/6 ARM: tegra: clk_m is the architected timer source clock
In reply to Thierry RedingFrom: Thierry Reding <[email protected]>
While clk_m and the oscillator run at the same frequencies on Tegra114 and Tegra124, clk_m is the proper source for the architected timer. On more recent Tegra generations, Tegra210 and later, both the oscillator and clk_m can run at different frequencies. clk_m will be divided down from the oscillator.
--- arch/arm/mach-tegra/tegra114/clock.c | 4 ++-- arch/arm/mach-tegra/tegra124/clock.c | 4 ++-- arch/arm/mach-tegra/tegra210/clock.c | 10 ++++------ 3 files changed, 8 insertions(+), 10 deletions(-)
arch/arm/mach-tegra/tegra114/clock.c +2 -2
@@ -679,8 +679,8 @@ void arch_timer_init(void)struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE ;u32 freq, val; - freq =clock_get_rate (CLOCK_ID_OSC ); -debug ("%s: osc freq is %dHz [0x%08X]\n" , __func__, freq, freq); + freq =clock_get_rate (CLOCK_ID_CLK_M ); +debug ("%s: clk_m freq is %dHz [0x%08X]\n" , __func__, freq, freq);/* ARM CNTFRQ */ asm("mcr p15, 0, %0, c14, c0, 0\n" : :"r" (freq));
arch/arm/mach-tegra/tegra124/clock.c +2 -2
@@ -859,8 +859,8 @@ void arch_timer_init(void)struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE ;u32 freq, val; - freq =clock_get_rate (CLOCK_ID_OSC ); -debug ("%s: osc freq is %dHz [0x%08X]\n" , __func__, freq, freq); + freq =clock_get_rate (CLOCK_ID_CLK_M ); +debug ("%s: clk_m freq is %dHz [0x%08X]\n" , __func__, freq, freq);/* ARM CNTFRQ */ asm("mcr p15, 0, %0, c14, c0, 0\n" : :"r" (freq));
arch/arm/mach-tegra/tegra210/clock.c +4 -6
@@ -1014,13 +1014,11 @@ void arch_timer_init(void)struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE ;u32 freq, val; - freq =clock_get_rate (CLOCK_ID_OSC ); -debug ("%s: osc freq is %dHz [0x%08X]\n" , __func__, freq, freq); + freq =clock_get_rate (CLOCK_ID_CLK_M ); +debug ("%s: clk_m freq is %dHz [0x%08X]\n" , __func__, freq, freq); -/* ARM CNTFRQ */ -#ifndef CONFIG_ARM64 - asm("mcr p15, 0, %0, c14, c0, 0\n" : :"r" (freq)); -#endif +if (current_el () ==3 ) + asm("msr cntfrq_el0, %0\n" : :"r" (freq));/* Only Tegra114+ has the System Counter regs */ debug ("%s: setting CNTFID0 to 0x%08X\n" , __func__, freq);
Signature · 1 line
2.4.5
PATCH 4/6 e2220-1170: Remove hard-coded counter frequency
In reply to Thierry RedingFrom: Thierry Reding <[email protected]>
The counter frequency is derived from clk_m on Tegra, but that clock can be configured by the primary bootloader to run at the same frequency as the oscillator (38.4 MHz on Tegra210) or a divided down frequency (most typically 19.2 MHz). Remove the hard-coded frequency and allow the timer setup code to query the correct value at runtime.
--- include/configs/e2220-1170.h | 2 -- 1 file changed, 2 deletions(-)
include/configs/e2220-1170.h +0 -2
@@ -60,6 +60,4 @@#include "tegra-common-usb-gadget.h" #include "tegra-common-post.h" -#define COUNTER_FREQUENCY 38400000 -#endif /* _E2220_1170_H */
Signature · 1 line
2.4.5
PATCH 5/6 p2371: Remove hard-coded counter frequency
In reply to Thierry RedingFrom: Thierry Reding <[email protected]>
The counter frequency is derived from clk_m on Tegra, but that clock can be configured by the primary bootloader to run at the same frequency as the oscillator (38.4 MHz on Tegra210) or a divided down frequency (most typically 19.2 MHz). Remove the hard-coded frequency and allow the timer setup code to query the correct value at runtime.
--- include/configs/p2371-0000.h | 2 -- 1 file changed, 2 deletions(-)
include/configs/p2371-0000.h +0 -2
@@ -60,6 +60,4 @@#include "tegra-common-usb-gadget.h" #include "tegra-common-post.h" -#define COUNTER_FREQUENCY 38400000 -#endif /* _P2371_0000_H */
Signature · 1 line
2.4.5
PATCH 5/6 p2371: Remove hard-coded counter frequency
Quoted 9 lines · Thierry Reding
From: Thierry Reding <[email protected]>
The counter frequency is derived from
clk_mon Tegra, but that clock can be configured by the primary bootloader to run at the same frequency as the oscillator (38.4 MHz on Tegra210) or a divided down frequency (most typically 19.2 MHz). Remove the hard-coded frequency and allow the timer setup code to query the correct value at runtime.include/configs/p2371-0000.h | 2 --
Oh, there needs to be a patch for p2371-2180.h too. Perhaps just patch all 4 boards in one go?
PATCH 6/6 p2571: Remove hard-coded counter frequency
In reply to Thierry RedingFrom: Thierry Reding <[email protected]>
The counter frequency is derived from clk_m on Tegra, but that clock can be configured by the primary bootloader to run at the same frequency as the oscillator (38.4 MHz on Tegra210) or a divided down frequency (most typically 19.2 MHz). Remove the hard-coded frequency and allow the timer setup code to query the correct value at runtime.
--- include/configs/p2571.h | 1 - 1 file changed, 1 deletion(-)
include/configs/p2571.h +0 -1
@@ -61,7 +61,6 @@#include "tegra-common-usb-gadget.h" #include "tegra-common-post.h" -#define COUNTER_FREQUENCY 38400000#define CONFIG_OF_BOARD_SETUP #endif /* _P2571_H */
Signature · 1 line
2.4.5
PATCH 1/6 armv8: Make COUNTER_FREQUENCY optional
In reply to Thierry RedingQuoted 4 lines · Thierry Reding
From: Thierry Reding <[email protected]>
Some platforms have the means to determine the counter frequency at runtime, so give them an opportunity to do so.
Aside from the one comment I already made, the series,
I validated that the calculated clk_m rate is correct on p2371-2180 when booted under L4T's nvtboot. I didn't validate the programming of cntfrq_el0, since I'm booting at EL2 not EL3. Still, that part is trivial and the same code as in start.S.
Tom, this series would replace my patch "ARM: tegra: fix COUNTER_FREQUENCY for T210". Or perhaps apply my patch then fix up the minor conflicts when applying this series. That would at least document the fact that COUNTER_FREQUENCY was wrong in all the initial header files, in case someone looks back at old git versions.