]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
feat(intel): implement timer init divider via CPU frequency for N5X
authorSieu Mun Tang <sieu.mun.tang@intel.com>
Thu, 23 Jun 2022 10:05:02 +0000 (18:05 +0800)
committerSieu Mun Tang <sieu.mun.tang@intel.com>
Fri, 14 Apr 2023 01:17:33 +0000 (09:17 +0800)
Get CPU frequency and update the timer init div with it.
The timer is vary based on the CPU frequency instead of hardcoded.

Signed-off-by: Jit Loon Lim <jit.loon.lim@intel.com>
Signed-off-by: Sieu Mun Tang <sieu.mun.tang@intel.com>
Change-Id: Ibfaa47fb7a25176eebf06f4828bf9729d56f12ed

plat/intel/soc/agilex/include/agilex_clock_manager.h
plat/intel/soc/agilex/include/socfpga_plat_def.h
plat/intel/soc/common/socfpga_delay_timer.c
plat/intel/soc/n5x/include/n5x_clock_manager.h [new file with mode: 0644]
plat/intel/soc/n5x/include/socfpga_plat_def.h
plat/intel/soc/n5x/platform.mk
plat/intel/soc/n5x/soc/n5x_clock_manager.c [new file with mode: 0644]
plat/intel/soc/stratix10/include/s10_clock_manager.h
plat/intel/soc/stratix10/include/socfpga_plat_def.h

index f39d475e6753408861fe38b492d7dcb4448915e7..8ec8e592b2bfe3ebf147ee1ce9bf5abc3c936aa0 100644 (file)
@@ -127,5 +127,6 @@ void config_clkmgr_handoff(handoff *hoff_ptr);
 uint32_t get_wdt_clk(void);
 uint32_t get_uart_clk(void);
 uint32_t get_mmc_clk(void);
+uint32_t get_cpu_clk(void);
 
 #endif
index b216ab14b9ea6f80c6aa7a71108dd91f0c16ecec..4d7198cbe9a611a816a9b7bd64f1f8e22576ba32 100644 (file)
@@ -35,6 +35,4 @@
 /* Platform specific system counter */
 #define PLAT_SYS_COUNTER_FREQ_IN_MHZ   get_cpu_clk()
 
-uint32_t get_cpu_clk(void);
-
 #endif /* PLAT_SOCFPGA_DEF_H */
index dcd51e270f1c354c30c193bfba0a664732b41efe..8fce5cf886295bf84b59b2566e3404ca18a7d73b 100644 (file)
 #include <lib/mmio.h>
 #include "socfpga_plat_def.h"
 
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX
+#include "agilex_clock_manager.h"
+#elif PLATFORM_MODEL == PLAT_SOCFPGA_N5X
+#include "n5x_clock_manager.h"
+#elif PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
+#include "s10_clock_manager.h"
+#endif
+
 #define SOCFPGA_GLOBAL_TIMER           0xffd01000
 #define SOCFPGA_GLOBAL_TIMER_EN                0x3
 
@@ -43,6 +52,8 @@ void socfpga_delay_timer_init(void)
        socfpga_delay_timer_init_args();
        mmio_write_32(SOCFPGA_GLOBAL_TIMER, SOCFPGA_GLOBAL_TIMER_EN);
 
+       NOTICE("BL31 CLK freq = %d MHz\n", PLAT_SYS_COUNTER_FREQ_IN_MHZ);
+
        asm volatile("msr cntp_ctl_el0, %0" : : "r" (SOCFPGA_GLOBAL_TIMER_EN));
        asm volatile("msr cntp_tval_el0, %0" : : "r" (~0));
 
diff --git a/plat/intel/soc/n5x/include/n5x_clock_manager.h b/plat/intel/soc/n5x/include/n5x_clock_manager.h
new file mode 100644 (file)
index 0000000..6e2b978
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CLOCKMANAGER_H
+#define CLOCKMANAGER_H
+
+#include "socfpga_handoff.h"
+
+/* MACRO DEFINITION */
+#define SOCFPGA_GLOBAL_TIMER                           0xffd01000
+#define SOCFPGA_GLOBAL_TIMER_EN                                0x3
+
+#define CLKMGR_PLLGLOB_VCO_PSRC_MASK                   GENMASK(17, 16)
+#define CLKMGR_PLLGLOB_VCO_PSRC_OFFSET                 16
+#define CLKMGR_PLLDIV_FDIV_MASK                                GENMASK(16, 8)
+#define CLKMGR_PLLDIV_FDIV_OFFSET                      8
+#define CLKMGR_PLLDIV_REFCLKDIV_MASK                   GENMASK(5, 0)
+#define CLKMGR_PLLDIV_REFCLKDIV_OFFSET                 0
+#define CLKMGR_PLLDIV_OUTDIV_QDIV_MASK                 GENMASK(26, 24)
+#define CLKMGR_PLLDIV_OUTDIV_QDIV_OFFSET               24
+
+#define CLKMGR_PLLOUTDIV_C1CNT_MASK                    GENMASK(12, 8)
+#define CLKMGR_PLLOUTDIV_C1CNT_OFFSET                  8
+#define CLKMGR_PLLDIV_OUTDIV_QDIV_MASK                 GENMASK(26, 24)
+#define CLKMGR_PLLDIV_OUTDIV_QDIV_OFFSET               24
+#define CLKMGR_CLKSRC_MASK                             GENMASK(18, 16)
+#define CLKMGR_CLKSRC_OFFSET                           16
+#define CLKMGR_NOCDIV_DIVIDER_MASK                     GENMASK(1, 0)
+#define CLKMGR_NOCDIV_L4MAIN_OFFSET                    0
+
+#define CLKMGR_INTOSC_HZ                               400000000
+#define CLKMGR_VCO_PSRC_EOSC1                          0
+#define CLKMGR_VCO_PSRC_INTOSC                         1
+#define CLKMGR_VCO_PSRC_F2S                            2
+#define CLKMGR_CLKSRC_MAIN                             0
+#define CLKMGR_CLKSRC_PER                              1
+
+#define CLKMGR_N5X_BASE                                        0xffd10000
+#define CLKMGR_MAINPLL_NOCCLK                          0x40
+#define CLKMGR_MAINPLL_NOCDIV                          0x44
+#define CLKMGR_MAINPLL_PLLGLOB                         0x48
+#define CLKMGR_MAINPLL_PLLOUTDIV                       0x54
+#define CLKMGR_MAINPLL_PLLDIV                          0x50
+#define CLKMGR_PERPLL_PLLGLOB                          0x9c
+#define CLKMGR_PERPLL_PLLDIV                           0xa4
+#define CLKMGR_PERPLL_PLLOUTDIV                                0xa8
+
+/* FUNCTION DEFINITION */
+uint64_t clk_get_pll_output_hz(void);
+uint64_t get_l4_clk(void);
+uint32_t get_clk_freq(uint32_t psrc_reg);
+uint32_t get_cpu_clk(void);
+
+#endif
index 4c36f91f537193d28df301aeabe47b478c8998b0..eec841111b7733b2dd1afe56ef54b071ad48f8b9 100644 (file)
 #define SOCFPGA_SOC2FPGA_SCR_REG_BASE                  U(0xffd21200)
 #define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE                        U(0xffd21300)
 
-/* Platform specific system counter */
-/*
- * In N5X the clk init is done in Uboot SPL.
- * BL31 shall bypass the clk init and only provides other APIs.
- */
-#define PLAT_SYS_COUNTER_FREQ_IN_MHZ   (400)
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ   get_cpu_clk()
 
 #endif /* PLAT_SOCFPGA_DEF_H */
index 4f3da4edb1d78cefb1a16101639f43f9d21280b7..7afeb74741c517a45e89ec83d227da79eaaf03a8 100644 (file)
@@ -36,6 +36,7 @@ BL31_SOURCES  +=      \
                lib/cpus/aarch64/cortex_a53.S                           \
                plat/common/plat_psci_common.c                          \
                plat/intel/soc/n5x/bl31_plat_setup.c                    \
+               plat/intel/soc/n5x/soc/n5x_clock_manager.c              \
                plat/intel/soc/common/socfpga_psci.c                    \
                plat/intel/soc/common/socfpga_sip_svc.c                 \
                plat/intel/soc/common/socfpga_sip_svc_v2.c              \
diff --git a/plat/intel/soc/n5x/soc/n5x_clock_manager.c b/plat/intel/soc/n5x/soc/n5x_clock_manager.c
new file mode 100644 (file)
index 0000000..c09b25b
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include "n5x_clock_manager.h"
+#include "socfpga_system_manager.h"
+
+
+uint64_t clk_get_pll_output_hz(void)
+{
+       uint32_t clksrc;
+       uint32_t scr_reg;
+       uint32_t divf;
+       uint32_t divr;
+       uint32_t divq;
+       uint32_t power = 1;
+       uint64_t clock = 0;
+
+       clksrc = ((get_clk_freq(CLKMGR_PERPLL_PLLGLOB)) &
+                       CLKMGR_PLLGLOB_VCO_PSRC_MASK) >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET;
+
+       switch (clksrc) {
+       case CLKMGR_VCO_PSRC_EOSC1:
+               scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1);
+               clock = mmio_read_32(scr_reg);
+               break;
+
+       case CLKMGR_VCO_PSRC_INTOSC:
+               clock = CLKMGR_INTOSC_HZ;
+               break;
+
+       case CLKMGR_VCO_PSRC_F2S:
+               scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2);
+               clock = mmio_read_32(scr_reg);
+               break;
+       }
+
+       divf = ((get_clk_freq(CLKMGR_PERPLL_PLLDIV)) &
+                       CLKMGR_PLLDIV_FDIV_MASK) >> CLKMGR_PLLDIV_FDIV_OFFSET;
+       divr = ((get_clk_freq(CLKMGR_PERPLL_PLLDIV)) &
+                       CLKMGR_PLLDIV_REFCLKDIV_MASK) >> CLKMGR_PLLDIV_REFCLKDIV_OFFSET;
+       divq = ((get_clk_freq(CLKMGR_PERPLL_PLLDIV)) &
+                       CLKMGR_PLLDIV_OUTDIV_QDIV_MASK) >> CLKMGR_PLLDIV_OUTDIV_QDIV_OFFSET;
+
+       while (divq) {
+               power *= 2;
+               divq--;
+       }
+
+       return ((clock * 2 * (divf + 1)) / ((divr + 1) * power));
+}
+
+uint64_t get_l4_clk(void)
+{
+       uint32_t clock = 0;
+       uint32_t mainpll_c1cnt;
+       uint32_t perpll_c1cnt;
+       uint32_t clksrc;
+
+       mainpll_c1cnt = ((get_clk_freq(CLKMGR_MAINPLL_PLLOUTDIV)) &
+                       CLKMGR_PLLOUTDIV_C1CNT_MASK) >> CLKMGR_PLLOUTDIV_C1CNT_OFFSET;
+
+       perpll_c1cnt = ((get_clk_freq(CLKMGR_PERPLL_PLLOUTDIV)) &
+                       CLKMGR_PLLOUTDIV_C1CNT_MASK) >> CLKMGR_PLLOUTDIV_C1CNT_OFFSET;
+
+       clksrc = ((get_clk_freq(CLKMGR_MAINPLL_NOCCLK)) & CLKMGR_CLKSRC_MASK) >>
+                       CLKMGR_CLKSRC_OFFSET;
+
+       switch (clksrc) {
+       case CLKMGR_CLKSRC_MAIN:
+               clock = clk_get_pll_output_hz();
+               clock /= 1 + mainpll_c1cnt;
+               break;
+
+       case CLKMGR_CLKSRC_PER:
+               clock = clk_get_pll_output_hz();
+               clock /= 1 + perpll_c1cnt;
+               break;
+
+       default:
+               return 0;
+       }
+
+       clock /= BIT(((get_clk_freq(CLKMGR_MAINPLL_NOCDIV)) >>
+                       CLKMGR_NOCDIV_L4MAIN_OFFSET) & CLKMGR_NOCDIV_DIVIDER_MASK);
+
+       return clock;
+}
+
+/* Calculate clock frequency based on parameter */
+uint32_t get_clk_freq(uint32_t psrc_reg)
+{
+       uint32_t clk_psrc;
+
+       clk_psrc = mmio_read_32(CLKMGR_N5X_BASE + psrc_reg);
+
+       return clk_psrc;
+}
+
+/* Get cpu freq clock */
+uint32_t get_cpu_clk(void)
+{
+       uint32_t cpu_clk = 0;
+
+       cpu_clk = get_l4_clk()/PLAT_SYS_COUNTER_CONVERT_TO_MHZ;
+
+       return cpu_clk;
+}
index cf57df342b5453ccd48763c9a53e703794301c26..661e2040f66c0214a5cee418dccfd4b8f6d64aa0 100644 (file)
@@ -95,5 +95,6 @@ uint32_t get_uart_clk(void);
 uint32_t get_mmc_clk(void);
 uint32_t get_l3_clk(uint32_t ref_clk);
 uint32_t get_ref_clk(uint32_t pllglob);
+uint32_t get_cpu_clk(void);
 
 #endif
index 516cc7562efc3465b53e763fcf86cc701c8014d0..da6414f4e884856653f22ba5b1cb09d1dd21311a 100644 (file)
@@ -34,7 +34,5 @@
 /* Platform specific system counter */
 #define PLAT_SYS_COUNTER_FREQ_IN_MHZ   get_cpu_clk()
 
-uint32_t get_cpu_clk(void);
-
 #endif /* PLATSOCFPGA_DEF_H */