feat(intel): implement timer init divider via cpu frequency. (#1)

Get cpu frequency and update the timer init div with it.
The timer is vary based on the cpu frequency instead of hardcoded.
The implementation shall apply to only Agilex and S10

Signed-off-by: Jit Loon Lim <jit.loon.lim@intel.com>
Change-Id: I61684d9762ad34e5a60b8b176b60c8848db4b422
diff --git a/plat/intel/soc/agilex/include/agilex_clock_manager.h b/plat/intel/soc/agilex/include/agilex_clock_manager.h
index 20667f0..f39d475 100644
--- a/plat/intel/soc/agilex/include/agilex_clock_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_clock_manager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
index 6a5cf9b..499684d 100644
--- a/plat/intel/soc/agilex/include/socfpga_plat_def.h
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -31,5 +31,9 @@
 #define SOCFPGA_SOC2FPGA_SCR_REG_BASE           0xffd21200
 #define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE         0xffd21300
 
-#endif /* PLAT_SOCFPGA_DEF_H */
+/* 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 */
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index 89df46a..0e5f911 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -45,7 +45,7 @@
 		plat/intel/soc/agilex/soc/agilex_memory_controller.c	\
 		plat/intel/soc/agilex/soc/agilex_mmc.c			\
 		plat/intel/soc/agilex/soc/agilex_pinmux.c		\
-                plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
+		plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
 		plat/intel/soc/common/socfpga_image_load.c		\
 		plat/intel/soc/common/socfpga_storage.c			\
 		plat/intel/soc/common/soc/socfpga_emac.c		\
@@ -62,6 +62,7 @@
 		lib/cpus/aarch64/cortex_a53.S				\
 		plat/common/plat_psci_common.c				\
 		plat/intel/soc/agilex/bl31_plat_setup.c 		\
+		plat/intel/soc/agilex/soc/agilex_clock_manager.c	\
 		plat/intel/soc/common/socfpga_psci.c			\
 		plat/intel/soc/common/socfpga_sip_svc.c			\
 		plat/intel/soc/common/socfpga_topology.c		\
diff --git a/plat/intel/soc/agilex/soc/agilex_clock_manager.c b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
index 4efd713..76b9937 100644
--- a/plat/intel/soc/agilex/soc/agilex_clock_manager.c
+++ b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -387,3 +387,13 @@
 
 	return mmc_clk;
 }
+
+/* Get cpu freq clock */
+uint32_t get_cpu_clk(void)
+{
+	uint32_t cpu_clk;
+
+	cpu_clk = get_l3_clk()/PLAT_SYS_COUNTER_CONVERT_TO_MHZ;
+
+	return cpu_clk;
+}
diff --git a/plat/intel/soc/common/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index d37904b..a31adf7 100644
--- a/plat/intel/soc/common/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -192,7 +192,7 @@
  * System counter frequency related constants
  ******************************************************************************/
 #define PLAT_SYS_COUNTER_FREQ_IN_TICKS	(400000000)
-#define PLAT_SYS_COUNTER_FREQ_IN_MHZ	(400)
+#define PLAT_SYS_COUNTER_CONVERT_TO_MHZ	(1000000)
 
 #define PLAT_INTEL_SOCFPGA_GICD_BASE	PLAT_GICD_BASE
 #define PLAT_INTEL_SOCFPGA_GICC_BASE	PLAT_GICC_BASE
diff --git a/plat/intel/soc/common/include/socfpga_private.h b/plat/intel/soc/common/include/socfpga_private.h
index ca38f62..9d389e3 100644
--- a/plat/intel/soc/common/include/socfpga_private.h
+++ b/plat/intel/soc/common/include/socfpga_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -55,6 +55,8 @@
 
 void socfpga_gic_driver_init(void);
 
+void socfpga_delay_timer_init_args(void);
+
 uint32_t socfpga_get_spsr_for_bl32_entry(void);
 
 uint32_t socfpga_get_spsr_for_bl33_entry(void);
diff --git a/plat/intel/soc/common/socfpga_delay_timer.c b/plat/intel/soc/common/socfpga_delay_timer.c
index c55cc9d..957738c 100644
--- a/plat/intel/soc/common/socfpga_delay_timer.c
+++ b/plat/intel/soc/common/socfpga_delay_timer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,10 +8,12 @@
 #include <arch_helpers.h>
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
+#include "socfpga_plat_def.h"
 
 #define SOCFPGA_GLOBAL_TIMER		0xffd01000
 #define SOCFPGA_GLOBAL_TIMER_EN		0x3
 
+static timer_ops_t plat_timer_ops;
 /********************************************************************
  * The timer delay function
  ********************************************************************/
@@ -26,15 +28,20 @@
 	return (uint32_t)(~read_cntpct_el0());
 }
 
-static const timer_ops_t plat_timer_ops = {
-	.get_timer_value    = socfpga_get_timer_value,
-	.clk_mult           = 1,
-	.clk_div	    = PLAT_SYS_COUNTER_FREQ_IN_MHZ,
-};
+void socfpga_delay_timer_init_args(void)
+{
+	plat_timer_ops.get_timer_value	= socfpga_get_timer_value;
+	plat_timer_ops.clk_mult		= 1;
+	plat_timer_ops.clk_div		= PLAT_SYS_COUNTER_FREQ_IN_MHZ;
+
+	timer_init(&plat_timer_ops);
+
+	NOTICE("BL31: MPU clock frequency: %d MHz\n", plat_timer_ops.clk_div);
+}
 
 void socfpga_delay_timer_init(void)
 {
-	timer_init(&plat_timer_ops);
+	socfpga_delay_timer_init_args();
 	mmio_write_32(SOCFPGA_GLOBAL_TIMER, SOCFPGA_GLOBAL_TIMER_EN);
 
 	asm volatile("msr cntp_ctl_el0, %0" : : "r" (SOCFPGA_GLOBAL_TIMER_EN));
diff --git a/plat/intel/soc/n5x/include/socfpga_plat_def.h b/plat/intel/soc/n5x/include/socfpga_plat_def.h
index 9186852..3ce03dc 100644
--- a/plat/intel/soc/n5x/include/socfpga_plat_def.h
+++ b/plat/intel/soc/n5x/include/socfpga_plat_def.h
@@ -29,4 +29,11 @@
 #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)
+
 #endif /* PLAT_SOCFPGA_DEF_H */
diff --git a/plat/intel/soc/stratix10/include/s10_clock_manager.h b/plat/intel/soc/stratix10/include/s10_clock_manager.h
index acc700a..a2e4f37 100644
--- a/plat/intel/soc/stratix10/include/s10_clock_manager.h
+++ b/plat/intel/soc/stratix10/include/s10_clock_manager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -92,5 +92,7 @@
 uint32_t get_wdt_clk(void);
 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);
 
 #endif
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
index 2defeb9..ae4b674 100644
--- a/plat/intel/soc/stratix10/include/socfpga_plat_def.h
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -30,6 +30,10 @@
 #define SOCFPGA_SOC2FPGA_SCR_REG_BASE		0xffd21200
 #define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE		0xffd21300
 
+/* Platform specific system counter */
+#define PLAT_SYS_COUNTER_FREQ_IN_MHZ	get_cpu_clk()
+
+uint32_t get_cpu_clk(void);
 
 #endif /* PLATSOCFPGA_DEF_H */
 
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index b7808ae..bfac206 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -44,7 +44,7 @@
 		plat/intel/soc/stratix10/soc/s10_clock_manager.c	\
 		plat/intel/soc/stratix10/soc/s10_memory_controller.c	\
 		plat/intel/soc/stratix10/soc/s10_pinmux.c		\
-                plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
+		plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
 		plat/intel/soc/common/socfpga_image_load.c		\
 		plat/intel/soc/common/socfpga_storage.c			\
 		plat/intel/soc/common/soc/socfpga_emac.c		\
@@ -59,6 +59,7 @@
 		lib/cpus/aarch64/aem_generic.S				\
 		lib/cpus/aarch64/cortex_a53.S				\
 		plat/common/plat_psci_common.c				\
+		plat/intel/soc/stratix10/soc/s10_clock_manager.c	\
 		plat/intel/soc/stratix10/bl31_plat_setup.c	 	\
 		plat/intel/soc/common/socfpga_psci.c			\
 		plat/intel/soc/common/socfpga_sip_svc.c			\
diff --git a/plat/intel/soc/stratix10/soc/s10_clock_manager.c b/plat/intel/soc/stratix10/soc/s10_clock_manager.c
index 1e092de..30009f7 100644
--- a/plat/intel/soc/stratix10/soc/s10_clock_manager.c
+++ b/plat/intel/soc/stratix10/soc/s10_clock_manager.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -307,3 +307,16 @@
 
 	return mmc_clk;
 }
+
+/* Get cpu freq clock */
+uint32_t get_cpu_clk(void)
+{
+	uint32_t data32, ref_clk, cpu_clk;
+
+	data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB);
+	ref_clk = get_ref_clk(data32);
+
+	cpu_clk = get_l3_clk(ref_clk)/PLAT_SYS_COUNTER_CONVERT_TO_MHZ;
+
+	return cpu_clk;
+}