armv8/ls2085a: Fix generic timer clock source

The timer clock is system clock divided by 4, not fixed 12MHz.
This is common to the SoC, not board specific. Primary core is
fixed when u-boot still runs in board_f. Secondary cores are
fixed by reading a variable set by u-boot.

Signed-off-by: York Sun <yorksun@freescale.com>
CC: Mark Rutland <mark.rutland@arm.com>
This commit is contained in:
York Sun 2015-03-20 19:28:08 -07:00
parent 19f9175027
commit 207774b213
7 changed files with 51 additions and 19 deletions

8
README
View File

@ -690,6 +690,14 @@ The following options need to be configured:
exists, unlike the similar options in the Linux kernel. Do not exists, unlike the similar options in the Linux kernel. Do not
set these options unless they apply! 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 NOTE: The following can be machine specific errata. These
do have ability to provide rudimentary version and machine do have ability to provide rudimentary version and machine
specific checks, but expect no product checks. specific checks, but expect no product checks.

View File

@ -395,3 +395,27 @@ int arch_early_init_r(void)
return 0; 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");
#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;
}

View File

@ -224,6 +224,9 @@ ENTRY(secondary_boot_func)
/* physical address of this cpus spin table element */ /* physical address of this cpus spin table element */
add x11, x1, x0 add x11, x1, x0
ldr x0, =__real_cntfrq
ldr x0, [x0]
msr cntfrq_el0, x0 /* set with real frequency */
str x9, [x11, #16] /* LPID */ str x9, [x11, #16] /* LPID */
mov x4, #1 mov x4, #1
str x4, [x11, #8] /* STATUS */ str x4, [x11, #8] /* STATUS */
@ -275,6 +278,9 @@ ENDPROC(secondary_switch_to_el1)
/* 64 bit alignment for elements accessed as data */ /* 64 bit alignment for elements accessed as data */
.align 4 .align 4
.global __real_cntfrq
__real_cntfrq:
.quad COUNTER_FREQUENCY
.globl __secondary_boot_code_size .globl __secondary_boot_code_size
.type __secondary_boot_code_size, %object .type __secondary_boot_code_size, %object
/* Secondary Boot Code ends here */ /* Secondary Boot Code ends here */

View File

@ -31,6 +31,13 @@ int fsl_lsch3_wake_seconday_cores(void)
int i, timeout = 10; int i, timeout = 10;
u64 *table = get_spin_tbl_addr(); u64 *table = get_spin_tbl_addr();
#ifdef COUNTER_FREQUENCY_REAL
/* update for secondary cores */
__real_cntfrq = COUNTER_FREQUENCY_REAL;
flush_dcache_range((unsigned long)&__real_cntfrq,
(unsigned long)&__real_cntfrq + 8);
#endif
cores = cpu_mask(); cores = cpu_mask();
/* Clear spin table so that secondary processors /* Clear spin table so that secondary processors
* observe the correct value after waking up from wfe. * observe the correct value after waking up from wfe.

View File

@ -26,6 +26,7 @@
#define id_to_core(x) ((x & 3) | (x >> 6)) #define id_to_core(x) ((x & 3) | (x >> 6))
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
extern u64 __spin_table[]; extern u64 __spin_table[];
extern u64 __real_cntfrq;
extern u64 *secondary_boot_code; extern u64 *secondary_boot_code;
extern size_t __secondary_boot_code_size; extern size_t __secondary_boot_code_size;
int fsl_lsch3_wake_seconday_cores(void); int fsl_lsch3_wake_seconday_cores(void);

View File

@ -55,24 +55,6 @@ int dram_init(void)
return 0; 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. * Board specific reset that is system reset.
*/ */

View File

@ -72,7 +72,11 @@
#define CONFIG_DP_DDR_NUM_CTRLS 1 #define CONFIG_DP_DDR_NUM_CTRLS 1
/* Generic Timer Definitions */ /* 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 */ /* Size of malloc() pool */
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2048 * 1024) #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2048 * 1024)