* [U-Boot] [PATCH v2 04/28] armv8/ls2085a: Fix generic timer clock source
@ 2015-03-19 20:34 York Sun
2015-03-20 17:34 ` Mark Rutland
0 siblings, 1 reply; 4+ messages in thread
From: York Sun @ 2015-03-19 20:34 UTC (permalink / raw)
To: u-boot
The timer clock is system clock divided by 4, not fixed 12MHz. This is
common to the SoC, not board specific.
Signed-off-by: York Sun <yorksun@freescale.com>
---
Changes in v2:
Fix CNTFRQ for secondary cores when COUNTER_FREQUENCY_REAL is defined.
README | 8 ++++++++
arch/arm/cpu/armv8/fsl-lsch3/cpu.c | 26 ++++++++++++++++++++++++++
arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S | 6 ++++++
arch/arm/cpu/armv8/fsl-lsch3/mp.h | 1 +
board/freescale/ls2085a/ls2085a.c | 18 ------------------
include/configs/ls2085a_common.h | 6 +++++-
6 files changed, 46 insertions(+), 19 deletions(-)
diff --git a/README b/README
index f473515..776ebf4 100644
--- a/README
+++ b/README
@@ -690,6 +690,14 @@ The following options need to be configured:
exists, unlike the similar options in the Linux kernel. Do not
set these options unless they apply!
+ COUNTER_FREQUENCY
+ Generic timer clock source frequency.
+
+ COUNTER_FREQUENCY_REAL
+ Generic timer clock source frequency if the real clock is
+ different from COUNTER_FREQUENCY, and can only be determined
+ at run time.
+
NOTE: The following can be machine specific errata. These
do have ability to provide rudimentary version and machine
specific checks, but expect no product checks.
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
index 94fd147..f75b21d 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
@@ -395,3 +395,29 @@ int arch_early_init_r(void)
return 0;
}
+
+int timer_init(void)
+{
+ u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR;
+ u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR;
+#ifdef COUNTER_FREQUENCY_REAL
+ unsigned long cntfrq = COUNTER_FREQUENCY_REAL;
+
+ /* Update with accurate clock frequency */
+ asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory");
+
+ __real_cntfrq = cntfrq; /* update for secondary cores */
+#endif
+
+ /* Enable timebase for all clusters.
+ * It is safe to do so even some clusters are not enabled.
+ */
+ out_le32(cltbenr, 0xf);
+
+ /* Enable clock for timer
+ * This is a global setting.
+ */
+ out_le32(cntcr, 0x1);
+
+ return 0;
+}
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S b/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
index 886576e..8d330ff 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
+++ b/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
@@ -224,6 +224,9 @@ ENTRY(secondary_boot_func)
/* physical address of this cpus spin table element */
add x11, x1, x0
+ ldr x0, =__real_cntfrq
+ ldr x0, [x0]
+ msr cntfrq_el0, x0 /* set with real frequency */
str x9, [x11, #16] /* LPID */
mov x4, #1
str x4, [x11, #8] /* STATUS */
@@ -275,6 +278,9 @@ ENDPROC(secondary_switch_to_el1)
/* 64 bit alignment for elements accessed as data */
.align 4
+ .global __real_cntfrq
+__real_cntfrq:
+ .quad 0x17d7840 /* 25MHz */
.globl __secondary_boot_code_size
.type __secondary_boot_code_size, %object
/* Secondary Boot Code ends here */
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/mp.h b/arch/arm/cpu/armv8/fsl-lsch3/mp.h
index 66144d6..c985d6a 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/mp.h
+++ b/arch/arm/cpu/armv8/fsl-lsch3/mp.h
@@ -26,6 +26,7 @@
#define id_to_core(x) ((x & 3) | (x >> 6))
#ifndef __ASSEMBLY__
extern u64 __spin_table[];
+extern u64 __real_cntfrq;
extern u64 *secondary_boot_code;
extern size_t __secondary_boot_code_size;
int fsl_lsch3_wake_seconday_cores(void);
diff --git a/board/freescale/ls2085a/ls2085a.c b/board/freescale/ls2085a/ls2085a.c
index e78c63a..bd016e9 100644
--- a/board/freescale/ls2085a/ls2085a.c
+++ b/board/freescale/ls2085a/ls2085a.c
@@ -55,24 +55,6 @@ int dram_init(void)
return 0;
}
-int timer_init(void)
-{
- u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR;
- u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR;
-
- /* Enable timebase for all clusters.
- * It is safe to do so even some clusters are not enabled.
- */
- out_le32(cltbenr, 0xf);
-
- /* Enable clock for timer
- * This is a global setting.
- */
- out_le32(cntcr, 0x1);
-
- return 0;
-}
-
/*
* Board specific reset that is system reset.
*/
diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h
index 339337d..b47cf68 100644
--- a/include/configs/ls2085a_common.h
+++ b/include/configs/ls2085a_common.h
@@ -72,7 +72,11 @@
#define CONFIG_DP_DDR_NUM_CTRLS 1
/* Generic Timer Definitions */
-#define COUNTER_FREQUENCY 12000000 /* 12MHz */
+/*
+ * This is not an accurate number. It is used in start.S. The frequency
+ * will be udpated later when get_bus_freq(0) is available.
+ */
+#define COUNTER_FREQUENCY 25000000 /* 25MHz */
/* Size of malloc() pool */
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2048 * 1024)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH v2 04/28] armv8/ls2085a: Fix generic timer clock source
2015-03-19 20:34 [U-Boot] [PATCH v2 04/28] armv8/ls2085a: Fix generic timer clock source York Sun
@ 2015-03-20 17:34 ` Mark Rutland
2015-03-20 17:46 ` York Sun
0 siblings, 1 reply; 4+ messages in thread
From: Mark Rutland @ 2015-03-20 17:34 UTC (permalink / raw)
To: u-boot
Hi,
On Thu, Mar 19, 2015 at 08:34:22PM +0000, York Sun wrote:
> The timer clock is system clock divided by 4, not fixed 12MHz. This is
> common to the SoC, not board specific.
>
> Signed-off-by: York Sun <yorksun@freescale.com>
>
> ---
>
> Changes in v2:
> Fix CNTFRQ for secondary cores when COUNTER_FREQUENCY_REAL is defined.
>
> README | 8 ++++++++
> arch/arm/cpu/armv8/fsl-lsch3/cpu.c | 26 ++++++++++++++++++++++++++
> arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S | 6 ++++++
> arch/arm/cpu/armv8/fsl-lsch3/mp.h | 1 +
> board/freescale/ls2085a/ls2085a.c | 18 ------------------
> include/configs/ls2085a_common.h | 6 +++++-
> 6 files changed, 46 insertions(+), 19 deletions(-)
>
> diff --git a/README b/README
> index f473515..776ebf4 100644
> --- a/README
> +++ b/README
> @@ -690,6 +690,14 @@ The following options need to be configured:
> exists, unlike the similar options in the Linux kernel. Do not
> set these options unless they apply!
>
> + COUNTER_FREQUENCY
> + Generic timer clock source frequency.
> +
> + COUNTER_FREQUENCY_REAL
> + Generic timer clock source frequency if the real clock is
> + different from COUNTER_FREQUENCY, and can only be determined
> + at run time.
> +
> NOTE: The following can be machine specific errata. These
> do have ability to provide rudimentary version and machine
> specific checks, but expect no product checks.
> diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
> index 94fd147..f75b21d 100644
> --- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
> +++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
> @@ -395,3 +395,29 @@ int arch_early_init_r(void)
>
> return 0;
> }
> +
> +int timer_init(void)
> +{
> + u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR;
> + u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR;
> +#ifdef COUNTER_FREQUENCY_REAL
> + unsigned long cntfrq = COUNTER_FREQUENCY_REAL;
> +
> + /* Update with accurate clock frequency */
> + asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory");
The commit message says that this can only be determined at runtime, but
this looks like we're writing a compile-time static value.
> +
> + __real_cntfrq = cntfrq; /* update for secondary cores */
Do we need anything in the way or barriers and/or cache flushing to
ensure that this is visible to the secondary CPUs? Or is the MMU off at
this point?
> +#endif
> +
> + /* Enable timebase for all clusters.
> + * It is safe to do so even some clusters are not enabled.
> + */
> + out_le32(cltbenr, 0xf);
> +
> + /* Enable clock for timer
> + * This is a global setting.
> + */
> + out_le32(cntcr, 0x1);
> +
> + return 0;
> +}
> diff --git a/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S b/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
> index 886576e..8d330ff 100644
> --- a/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
> +++ b/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
> @@ -224,6 +224,9 @@ ENTRY(secondary_boot_func)
> /* physical address of this cpus spin table element */
> add x11, x1, x0
>
> + ldr x0, =__real_cntfrq
> + ldr x0, [x0]
> + msr cntfrq_el0, x0 /* set with real frequency */
> str x9, [x11, #16] /* LPID */
> mov x4, #1
> str x4, [x11, #8] /* STATUS */
> @@ -275,6 +278,9 @@ ENDPROC(secondary_switch_to_el1)
>
> /* 64 bit alignment for elements accessed as data */
> .align 4
> + .global __real_cntfrq
> +__real_cntfrq:
> + .quad 0x17d7840 /* 25MHz */
I think this would be better as COUNTER_FREQUENCY, so as to avoid
duplicating the value.
Thanks,
Mark.
^ permalink raw reply [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH v2 04/28] armv8/ls2085a: Fix generic timer clock source
2015-03-20 17:34 ` Mark Rutland
@ 2015-03-20 17:46 ` York Sun
2015-03-20 18:21 ` Mark Rutland
0 siblings, 1 reply; 4+ messages in thread
From: York Sun @ 2015-03-20 17:46 UTC (permalink / raw)
To: u-boot
On 03/20/2015 10:34 AM, Mark Rutland wrote:
> Hi,
>
> On Thu, Mar 19, 2015 at 08:34:22PM +0000, York Sun wrote:
>> The timer clock is system clock divided by 4, not fixed 12MHz. This is
>> common to the SoC, not board specific.
>>
>> Signed-off-by: York Sun <yorksun@freescale.com>
>>
>> ---
>>
>> Changes in v2:
>> Fix CNTFRQ for secondary cores when COUNTER_FREQUENCY_REAL is defined.
>>
>> README | 8 ++++++++
>> arch/arm/cpu/armv8/fsl-lsch3/cpu.c | 26 ++++++++++++++++++++++++++
>> arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S | 6 ++++++
>> arch/arm/cpu/armv8/fsl-lsch3/mp.h | 1 +
>> board/freescale/ls2085a/ls2085a.c | 18 ------------------
>> include/configs/ls2085a_common.h | 6 +++++-
>> 6 files changed, 46 insertions(+), 19 deletions(-)
>>
>> diff --git a/README b/README
>> index f473515..776ebf4 100644
>> --- a/README
>> +++ b/README
>> @@ -690,6 +690,14 @@ The following options need to be configured:
>> exists, unlike the similar options in the Linux kernel. Do not
>> set these options unless they apply!
>>
>> + COUNTER_FREQUENCY
>> + Generic timer clock source frequency.
>> +
>> + COUNTER_FREQUENCY_REAL
>> + Generic timer clock source frequency if the real clock is
>> + different from COUNTER_FREQUENCY, and can only be determined
>> + at run time.
>> +
>> NOTE: The following can be machine specific errata. These
>> do have ability to provide rudimentary version and machine
>> specific checks, but expect no product checks.
>> diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
>> index 94fd147..f75b21d 100644
>> --- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
>> +++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
>> @@ -395,3 +395,29 @@ int arch_early_init_r(void)
>>
>> return 0;
>> }
>> +
>> +int timer_init(void)
>> +{
>> + u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR;
>> + u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR;
>> +#ifdef COUNTER_FREQUENCY_REAL
>> + unsigned long cntfrq = COUNTER_FREQUENCY_REAL;
>> +
>> + /* Update with accurate clock frequency */
>> + asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory");
>
> The commit message says that this can only be determined at runtime, but
> this looks like we're writing a compile-time static value.
>
The macro COUNTER_FREQUENCY_REA is (CONFIG_SYS_CLK_FREQ/4), where
CONFIG_SYS_CLK_FREQ is a function call get_board_sys_clk().
>> +
>> + __real_cntfrq = cntfrq; /* update for secondary cores */
>
> Do we need anything in the way or barriers and/or cache flushing to
> ensure that this is visible to the secondary CPUs? Or is the MMU off at
> this point?
It is flushed before booting secondary cores. But I am relying on the trick of
enabling cache on flash. It may not be as reliable if someone decide to disable
the cache to begin with. I will move the code to somewhere safe in next version.
>
>> +#endif
>> +
>> + /* Enable timebase for all clusters.
>> + * It is safe to do so even some clusters are not enabled.
>> + */
>> + out_le32(cltbenr, 0xf);
>> +
>> + /* Enable clock for timer
>> + * This is a global setting.
>> + */
>> + out_le32(cntcr, 0x1);
>> +
>> + return 0;
>> +}
>> diff --git a/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S b/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
>> index 886576e..8d330ff 100644
>> --- a/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
>> +++ b/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
>> @@ -224,6 +224,9 @@ ENTRY(secondary_boot_func)
>> /* physical address of this cpus spin table element */
>> add x11, x1, x0
>>
>> + ldr x0, =__real_cntfrq
>> + ldr x0, [x0]
>> + msr cntfrq_el0, x0 /* set with real frequency */
>> str x9, [x11, #16] /* LPID */
>> mov x4, #1
>> str x4, [x11, #8] /* STATUS */
>> @@ -275,6 +278,9 @@ ENDPROC(secondary_switch_to_el1)
>>
>> /* 64 bit alignment for elements accessed as data */
>> .align 4
>> + .global __real_cntfrq
>> +__real_cntfrq:
>> + .quad 0x17d7840 /* 25MHz */
>
> I think this would be better as COUNTER_FREQUENCY, so as to avoid
> duplicating the value.
Good idea. Will fix in next version.
York
^ permalink raw reply [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH v2 04/28] armv8/ls2085a: Fix generic timer clock source
2015-03-20 17:46 ` York Sun
@ 2015-03-20 18:21 ` Mark Rutland
0 siblings, 0 replies; 4+ messages in thread
From: Mark Rutland @ 2015-03-20 18:21 UTC (permalink / raw)
To: u-boot
> >> +int timer_init(void)
> >> +{
> >> + u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR;
> >> + u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR;
> >> +#ifdef COUNTER_FREQUENCY_REAL
> >> + unsigned long cntfrq = COUNTER_FREQUENCY_REAL;
> >> +
> >> + /* Update with accurate clock frequency */
> >> + asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory");
> >
> > The commit message says that this can only be determined at runtime, but
> > this looks like we're writing a compile-time static value.
> >
>
> The macro COUNTER_FREQUENCY_REA is (CONFIG_SYS_CLK_FREQ/4), where
> CONFIG_SYS_CLK_FREQ is a function call get_board_sys_clk().
Ah, that sounds fine to me then.
> >> + __real_cntfrq = cntfrq; /* update for secondary cores */
> >
> > Do we need anything in the way or barriers and/or cache flushing to
> > ensure that this is visible to the secondary CPUs? Or is the MMU off at
> > this point?
>
> It is flushed before booting secondary cores. But I am relying on the trick of
> enabling cache on flash. It may not be as reliable if someone decide to disable
> the cache to begin with. I will move the code to somewhere safe in next version.
Ok.
> >> + .global __real_cntfrq
> >> +__real_cntfrq:
> >> + .quad 0x17d7840 /* 25MHz */
> >
> > I think this would be better as COUNTER_FREQUENCY, so as to avoid
> > duplicating the value.
>
> Good idea. Will fix in next version.
Great!
Mark.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-03-20 18:21 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-19 20:34 [U-Boot] [PATCH v2 04/28] armv8/ls2085a: Fix generic timer clock source York Sun
2015-03-20 17:34 ` Mark Rutland
2015-03-20 17:46 ` York Sun
2015-03-20 18:21 ` Mark Rutland
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox