From: Soby Mathew Date: Mon, 11 Jun 2018 15:21:30 +0000 (+0100) Subject: ARM Platforms: Update CNTFRQ register in CNTCTLBase frame X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=342d6220e6ef59148455debc8ef9b4adb3d292d8;p=project%2Fbcm63xx%2Fatf.git ARM Platforms: Update CNTFRQ register in CNTCTLBase frame Currently TF-A doesn't initialise CNTFRQ register in CNTCTLBase frame of the system timer. ARM ARM states that "The instance of the register in the CNTCTLBase frame must be programmed with this value as part of system initialization." The psci_arch_setup() updates the CNTFRQ system register but according to the ARM ARM, this instance of the register is independent of the memory mapped instance. This is only an issue for Normal world software which relies on the memory mapped instance rather than the system register one. This patch resolves the issue for ARM platforms. The patch also solves a related issue on Juno, wherein CNTBaseN.CNTFRQ can be written and does not reflect the value of the register in CNTCTLBase frame. Hence this patch additionally updates CNTFRQ register in the Non Secure frame of the CNTBaseN. Fixes ARM-Software/tf-issues#593 Change-Id: I09cebb6633688b34d5b1bc349fbde4751025b350 Signed-off-by: Soby Mathew --- diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h index 3624cc68..910341a7 100644 --- a/include/lib/aarch32/arch.h +++ b/include/lib/aarch32/arch.h @@ -379,6 +379,7 @@ * Definitions of register offsets and fields in the CNTCTLBase Frame of the * system level implementation of the Generic Timer. ******************************************************************************/ +#define CNTCTLBASE_CNTFRQ U(0x0) #define CNTNSAR 0x4 #define CNTNSAR_NS_SHIFT(x) (x) @@ -390,6 +391,12 @@ #define CNTACR_RWVT_SHIFT 0x4 #define CNTACR_RWPT_SHIFT 0x5 +/******************************************************************************* + * Definitions of register offsets in the CNTBaseN Frame of the + * system level implementation of the Generic Timer. + ******************************************************************************/ +#define CNTBASE_CNTFRQ U(0x10) + /* MAIR macros */ #define MAIR0_ATTR_SET(attr, index) ((attr) << ((index) << 3)) #define MAIR1_ATTR_SET(attr, index) ((attr) << (((index) - 3) << 3)) diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index 92bb97d5..7cc4b237 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -554,6 +554,7 @@ * Definitions of register offsets and fields in the CNTCTLBase Frame of the * system level implementation of the Generic Timer. ******************************************************************************/ +#define CNTCTLBASE_CNTFRQ U(0x0) #define CNTNSAR U(0x4) #define CNTNSAR_NS_SHIFT(x) (x) @@ -565,6 +566,12 @@ #define CNTACR_RWVT_SHIFT U(0x4) #define CNTACR_RWPT_SHIFT U(0x5) +/******************************************************************************* + * Definitions of register offsets in the CNTBaseN Frame of the + * system level implementation of the Generic Timer. + ******************************************************************************/ +#define CNTBASE_CNTFRQ U(0x10) + /* PMCR_EL0 definitions */ #define PMCR_EL0_RESET_VAL U(0x0) #define PMCR_EL0_N_SHIFT U(11) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index e07156c0..e3d0edbc 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -258,6 +258,8 @@ #define ARM_SYS_CNTCTL_BASE 0x2a430000 #define ARM_SYS_CNTREAD_BASE 0x2a800000 #define ARM_SYS_TIMCTL_BASE 0x2a810000 +#define ARM_SYS_CNT_BASE_S 0x2a820000 +#define ARM_SYS_CNT_BASE_NS 0x2a830000 #define ARM_CONSOLE_BAUDRATE 115200 diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index 11bdeac6..32fd9ee6 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -160,6 +160,9 @@ void arm_configure_sys_timer(void) { unsigned int reg_val; + /* Read the frequency of the system counter */ + unsigned int freq_val = plat_get_syscnt_freq2(); + #if ARM_CONFIG_CNTACR reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT); reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT); @@ -169,6 +172,23 @@ void arm_configure_sys_timer(void) reg_val = (1 << CNTNSAR_NS_SHIFT(PLAT_ARM_NSTIMER_FRAME_ID)); mmio_write_32(ARM_SYS_TIMCTL_BASE + CNTNSAR, reg_val); + + /* + * Initialize CNTFRQ register in CNTCTLBase frame. The CNTFRQ + * system register initialized during psci_arch_setup() is different + * from this and has to be updated independently. + */ + mmio_write_32(ARM_SYS_TIMCTL_BASE + CNTCTLBASE_CNTFRQ, freq_val); + +#ifdef PLAT_juno + /* + * Initialize CNTFRQ register in Non-secure CNTBase frame. + * This is only required for Juno, because it doesn't follow ARM ARM + * in that the value updated in CNTFRQ is not reflected in CNTBASE_CNTFRQ. + * Hence update the value manually. + */ + mmio_write_32(ARM_SYS_CNT_BASE_NS + CNTBASE_CNTFRQ, freq_val); +#endif } #endif /* ARM_SYS_TIMCTL_BASE */