fix(versal): initialize cntfrq_el0 register

The set_cnt_freq() function is introduced to configure the counter
frequency register.If the counter frequency register is zero, it writes
the output of plat_get_syscnt_freq2() the cpu_clocks to the counter
frequency register.

According to the design specifications provided for Versal, the
lpd_data.cdo file contains a mask_write operation for register
0xFF140020 (base_frequency_ID_register) to set it to 0x5f5e100,
configuring it for a 100MHz clock frequency.

Reading the value of the IOU_SCNTRS_BASE_FREQ register using
mmio_read_32() to determine the counter frequency. If the counter
frequency is zero, the system will set the default CPU clocks constants
in TF-A and displays message. However, if the counter frequency is
non-zero, the program will return the value stored in the
IOU_SCNTRS_BASE_FREQ register.

The issue lies in dcc_status_timeout(),function verifying timeout
status, particularly within timeout_cnt_us2cnt(), converting
microseconds to counter ticks using read_cntfrq_el0(), which returns
zero. timeout_elapsed() then checks if the current counter from
read_cntpct_el0()exceeds the expiration count, denoting timeout.

After the function set_cnt_freq() writes into the counter frequency
register, the function timeout_cnt_us2cnt() is used to obtain the
appropriate counter ticks. Subsequently, the function timeout_elapsed()
checks whether the current counter value read_cntpct_el0() has
exceeded the specified expiration count. If it has, this indicates
that the timeout has lapsed.

Change-Id: I8f2f4d804b5aefa6f92083d831a5ebfade384294
Signed-off-by: Prasad Kummari <prasad.kummari@amd.com>
diff --git a/plat/xilinx/common/include/plat_clkfunc.h b/plat/xilinx/common/include/plat_clkfunc.h
new file mode 100644
index 0000000..a182f91
--- /dev/null
+++ b/plat/xilinx/common/include/plat_clkfunc.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLAT_CLKFUNC_H
+#define PLAT_CLKFUNC_H
+
+void set_cnt_freq(void);
+
+#endif /* PLAT_CLKFUNC_H */
diff --git a/plat/xilinx/common/plat_clkfunc.c b/plat/xilinx/common/plat_clkfunc.c
new file mode 100644
index 0000000..80b8ab5
--- /dev/null
+++ b/plat/xilinx/common/plat_clkfunc.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <common/debug.h>
+#include <plat/common/platform.h>
+
+#include <platform_def.h>
+#include <plat_private.h>
+
+void set_cnt_freq(void)
+{
+	uint64_t counter_freq;
+
+	/* Configure counter frequency */
+	counter_freq = read_cntfrq_el0();
+	if (counter_freq == 0U) {
+		write_cntfrq_el0(plat_get_syscnt_freq2());
+	}
+}
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index aba190d..5357148 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -18,6 +18,7 @@
 #include <versal_def.h>
 
 uint32_t platform_id, platform_version;
+uint32_t cpu_clock = VERSAL_CPU_CLOCK;
 
 /*
  * Table of regions to map using the MMU.
@@ -55,7 +56,21 @@
 
 uint32_t plat_get_syscnt_freq2(void)
 {
-	return VERSAL_CPU_CLOCK;
+	uint32_t counter_freq = 0;
+	uint32_t ret = 0;
+
+	counter_freq = mmio_read_32(IOU_SCNTRS_BASE
+				    + IOU_SCNTRS_BASE_FREQ_OFFSET);
+
+	if (counter_freq != 0U) {
+		ret = counter_freq;
+	} else {
+		INFO("Indicates counter frequency %dHz setting to %dHz\n",
+		     counter_freq, cpu_clock);
+		ret = cpu_clock;
+	}
+
+	return ret;
 }
 
 void board_detection(void)
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index cd105c6..d19a263 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -17,6 +17,7 @@
 #include <plat/common/platform.h>
 #include <plat_arm.h>
 #include <plat_console.h>
+#include <plat_clkfunc.h>
 
 #include <plat_fdt.h>
 #include <plat_private.h>
@@ -72,6 +73,8 @@
 	enum pm_ret_status ret_status;
 	uint64_t addr[HANDOFF_PARAMS_MAX_SIZE];
 
+	set_cnt_freq();
+
 	setup_console();
 
 	/* Initialize the platform config for future decision making */
diff --git a/plat/xilinx/versal/include/plat_private.h b/plat/xilinx/versal/include/plat_private.h
index a4210cd..932c6de 100644
--- a/plat/xilinx/versal/include/plat_private.h
+++ b/plat/xilinx/versal/include/plat_private.h
@@ -22,7 +22,7 @@
 
 const mmap_region_t *plat_get_mmap(void);
 
-extern uint32_t platform_id, platform_version;
+extern uint32_t cpu_clock, platform_id, platform_version;
 
 void board_detection(void);
 void plat_versal_gic_driver_init(void);
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index 92c0ba6..f21d409 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -111,6 +111,10 @@
 #define CRF_RST_APU_ACPU_RESET		(1 << 0)
 #define CRF_RST_APU_ACPU_PWRON_RESET	(1 << 10)
 
+/* IOU SCNTRS */
+#define IOU_SCNTRS_BASE	U(0xFF140000)
+#define IOU_SCNTRS_BASE_FREQ_OFFSET	U(0x20)
+
 /* APU registers and bitfields */
 #define FPD_APU_BASE		0xFD5C0000U
 #define FPD_APU_CONFIG_0	(FPD_APU_BASE + 0x20U)
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 612e956..35d6bc7 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -96,6 +96,7 @@
 				plat/xilinx/common/ipi.c			\
 				plat/xilinx/common/plat_fdt.c			\
 				plat/xilinx/common/plat_console.c               \
+				plat/xilinx/common/plat_clkfunc.c               \
 				plat/xilinx/common/plat_startup.c		\
 				plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \
 				plat/xilinx/common/pm_service/pm_ipi.c		\