]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
ti: k3: common: Make plat_get_syscnt_freq2 check CNT_FID0 GTC reg
authorNishanth Menon <nm@ti.com>
Fri, 11 Dec 2020 02:51:51 +0000 (20:51 -0600)
committerNishanth Menon <nm@ti.com>
Wed, 23 Dec 2020 12:33:39 +0000 (06:33 -0600)
ARM's generic timer[1] picks up it's graycode from GTC. However, the
frequency of the GTC is supposed to be programmed in CNTFID0[2]
register.

In K3, architecture, GTC provides a central time to many parts of the
SoC including graycode to the generic timer in the ARMv8 subsystem.
However, due to the central nature and the need to enable the counter
early in the boot process, the R5 based bootloader enables GTC and
programs it's frequency based on central needs of the system. This
may not be a constant 200MHz based on the system. The bootloader is
supposed to program the FID0 register with the correct frequency it
has sourced for GTC from the central system controller, and TF-A is
supposed to use that as the frequency for it's local timer.

A mismatch in programmed frequency and what we program for generic
timer will, as we can imagine, all kind of weird mayhem.

So, check the CNTFID0 register, if it is 0, warn and use the default
frequency to continue the boot process.

While at it, we can also check CNTCR register to provide some basic
diagnostics to make sure that we don't have OS folks scratch their
heads. Even though this is used during cpu online operations, the cost
of this additional check is minimal enough for us not to use #ifdeffery
with DEBUG flags.

[1] https://developer.arm.com/documentation/100095/0002/generic-timer/generic-timer-register-summary/aarch64-generic-timer-register-summary
[2] https://developer.arm.com/docs/ddi0595/h/external-system-registers/cntfid0
[3] https://developer.arm.com/docs/ddi0595/h/external-system-registers/cntcr

Signed-off-by: Nishanth Menon <nm@ti.com>
Change-Id: Ib03e06788580f3540dcb1a11677d0d6d398b2c9f

plat/ti/k3/common/k3_bl31_setup.c
plat/ti/k3/include/platform_def.h

index 8bd736292333f886880b6d84cb201fbd96620f74..ac4e60e4d12fdffd76d3807831b6adc98c006b7e 100644 (file)
@@ -13,6 +13,7 @@
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 
 #include <k3_console.h>
@@ -23,6 +24,7 @@
 const mmap_region_t plat_k3_mmap[] = {
        MAP_REGION_FLAT(K3_USART_BASE,       K3_USART_SIZE,       MT_DEVICE | MT_RW | MT_SECURE),
        MAP_REGION_FLAT(K3_GIC_BASE,         K3_GIC_SIZE,         MT_DEVICE | MT_RW | MT_SECURE),
+       MAP_REGION_FLAT(K3_GTC_BASE,         K3_GTC_SIZE,         MT_DEVICE | MT_RW | MT_SECURE),
        MAP_REGION_FLAT(SEC_PROXY_RT_BASE,   SEC_PROXY_RT_SIZE,   MT_DEVICE | MT_RW | MT_SECURE),
        MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
        MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
@@ -127,6 +129,38 @@ void platform_mem_init(void)
 
 unsigned int plat_get_syscnt_freq2(void)
 {
+       uint32_t gtc_freq;
+       uint32_t gtc_ctrl;
+
+       /* Lets try and provide basic diagnostics - cost is low */
+       gtc_ctrl = mmio_read_32(K3_GTC_BASE + K3_GTC_CNTCR_OFFSET);
+       /* Did the bootloader fail to enable timer and OS guys are confused? */
+       if ((gtc_ctrl & K3_GTC_CNTCR_EN_MASK) == 0U) {
+               ERROR("GTC is disabled! Timekeeping broken. Fix Bootloader\n");
+       }
+       /*
+        * If debug will not pause time, we will have issues like
+        * drivers timing out while debugging, in cases of OS like Linux,
+        * RCU stall errors, which can be hard to differentiate vs real issues.
+        */
+       if ((gtc_ctrl & K3_GTC_CNTCR_HDBG_MASK) == 0U) {
+               WARN("GTC: Debug access doesn't stop time. Fix Bootloader\n");
+       }
+
+       gtc_freq = mmio_read_32(K3_GTC_BASE + K3_GTC_CNTFID0_OFFSET);
+       /* Many older bootloaders may have missed programming FID0 register */
+       if (gtc_freq != 0U) {
+               return gtc_freq;
+       }
+
+       /*
+        * We could have just warned about this, but this can have serious
+        * hard to debug side effects if we are NOT sure what the actual
+        * frequency is. Lets make sure people don't miss this.
+        */
+       ERROR("GTC_CNTFID0 is 0! Assuming %d Hz. Fix Bootloader\n",
+             SYS_COUNTER_FREQ_IN_TICKS);
+
        return SYS_COUNTER_FREQ_IN_TICKS;
 }
 
index 98db626e247b8919b11a14abc84bc845372d7a20..a56dd3d74d7d7a4f8066cbbb9cd2e2d04bc42ef1 100644 (file)
        INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
                        GIC_INTR_CFG_EDGE)
 
+
+#define K3_GTC_BASE            0x00A90000
+/* We just need 20 byte offset, but simpler to just remap the 64K page in */
+#define K3_GTC_SIZE            0x10000
+#define K3_GTC_CNTCR_OFFSET    0x00
+#define K3_GTC_CNTCR_EN_MASK   0x01
+#define K3_GTC_CNTCR_HDBG_MASK 0x02
+#define K3_GTC_CNTFID0_OFFSET  0x20
+
 #define K3_GIC_BASE    0x01800000
 #define K3_GIC_SIZE    0x200000