Merge pull request #625 from antonio-nino-diaz-arm/an/delay-timer-v2

Implement generic delay timer and use it on platforms
diff --git a/bl31/aarch64/bl31_arch_setup.c b/bl31/aarch64/bl31_arch_setup.c
index 0871b41..3deacba 100644
--- a/bl31/aarch64/bl31_arch_setup.c
+++ b/bl31/aarch64/bl31_arch_setup.c
@@ -44,7 +44,7 @@
 void bl31_arch_setup(void)
 {
 	/* Program the counter frequency */
-	write_cntfrq_el0(plat_get_syscnt_freq());
+	write_cntfrq_el0(plat_get_syscnt_freq2());
 
 	/* Initialize the cpu_ops pointer. */
 	init_cpu_ops();
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index 5004d30..0cd3613 100644
--- a/docs/porting-guide.md
+++ b/docs/porting-guide.md
@@ -1529,10 +1529,10 @@
 (that was copied during `bl31_early_platform_setup()`) if the image exists. It
 should return NULL otherwise.
 
-### Function : plat_get_syscnt_freq() [mandatory]
+### Function : plat_get_syscnt_freq2() [mandatory]
 
     Argument : void
-    Return   : uint64_t
+    Return   : unsigned int
 
 This function is used by the architecture setup code to retrieve the counter
 frequency for the CPU's generic timer.  This value will be programmed into the
diff --git a/docs/user-guide.md b/docs/user-guide.md
index 2bb9eac..cd9c8c3 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -492,6 +492,9 @@
      Trusted Firmware is configured for dual cluster topology and this option
      can be used to override the default value.
 
+*   `FVP_USE_SP804_TIMER`  : Use the SP804 timer instead of the Generic Timer
+     for functions that wait for an arbitrary time length (udelay and mdelay).
+     The default value is 0.
 
 ### Debugging options
 
diff --git a/drivers/delay_timer/delay_timer.c b/drivers/delay_timer/delay_timer.c
index 0bee876..ed7ed52 100644
--- a/drivers/delay_timer/delay_timer.c
+++ b/drivers/delay_timer/delay_timer.c
@@ -48,19 +48,22 @@
 		(ops->clk_div != 0) &&
 		(ops->get_timer_value != 0));
 
-	uint32_t start, cnt, delta, delta_us;
+	uint32_t start, delta, total_delta;
 
-	/* counter is decreasing */
+	assert(usec < UINT32_MAX / ops->clk_div);
+
 	start = ops->get_timer_value();
+
+	total_delta = (usec * ops->clk_div) / ops->clk_mult;
+
 	do {
-		cnt = ops->get_timer_value();
-		if (cnt > start) {
-			delta = UINT32_MAX - cnt;
-			delta += start;
-		} else
-			delta = start - cnt;
-		delta_us = (delta * ops->clk_mult) / ops->clk_div;
-	} while (delta_us < usec);
+		/*
+		 * If the timer value wraps around, the subtraction will
+		 * overflow and it will still give the correct result.
+		 */
+		delta = start - ops->get_timer_value(); /* Decreasing counter */
+
+	} while (delta < total_delta);
 }
 
 /***********************************************************
diff --git a/plat/rockchip/common/plat_delay_timer.c b/drivers/delay_timer/generic_delay_timer.c
similarity index 64%
copy from plat/rockchip/common/plat_delay_timer.c
copy to drivers/delay_timer/generic_delay_timer.c
index 797ce05..4c364a3 100644
--- a/plat/rockchip/common/plat_delay_timer.c
+++ b/drivers/delay_timer/generic_delay_timer.c
@@ -29,26 +29,54 @@
  */
 
 #include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
 #include <delay_timer.h>
-#include <platform_def.h>
+#include <platform.h>
 
-static uint32_t plat_get_timer_value(void)
+/* Ticks elapsed in one second by a signal of 1 MHz */
+#define MHZ_TICKS_PER_SEC 1000000
+
+static timer_ops_t ops;
+
+static uint32_t get_timer_value(void)
 {
 	/*
 	 * Generic delay timer implementation expects the timer to be a down
 	 * counter. We apply bitwise NOT operator to the tick values returned
-	 * by read_cntpct_el0() to simulate the down counter.
+	 * by read_cntpct_el0() to simulate the down counter. The value is
+	 * clipped from 64 to 32 bits.
 	 */
 	return (uint32_t)(~read_cntpct_el0());
 }
 
+void generic_delay_timer_init_args(uint32_t mult, uint32_t div)
+{
+	ops.get_timer_value	= get_timer_value;
+	ops.clk_mult		= mult;
+	ops.clk_div		= div;
+
+	timer_init(&ops);
+
-static const timer_ops_t plat_timer_ops = {
-	.get_timer_value	= plat_get_timer_value,
-	.clk_mult		= 1,
-	.clk_div		= SYS_COUNTER_FREQ_IN_MHZ,
-};
+	VERBOSE("Generic delay timer configured with mult=%u and div=%u\n",
+		mult, div);
+}
 
-void plat_delay_timer_init(void)
+void generic_delay_timer_init(void)
 {
-	timer_init(&plat_timer_ops);
+	/* Value in ticks */
+	unsigned int mult = MHZ_TICKS_PER_SEC;
+
+	/* Value in ticks per second (Hz) */
+	unsigned int div  = plat_get_syscnt_freq2();
+
+	/* Reduce multiplier and divider by dividing them repeatedly by 10 */
+	while ((mult % 10 == 0) && (div % 10 == 0)) {
+		mult /= 10;
+		div /= 10;
+	}
+
+	generic_delay_timer_init_args(mult, div);
 }
+
diff --git a/plat/rockchip/common/plat_delay_timer.c b/include/drivers/generic_delay_timer.h
similarity index 72%
rename from plat/rockchip/common/plat_delay_timer.c
rename to include/drivers/generic_delay_timer.h
index 797ce05..1450162 100644
--- a/plat/rockchip/common/plat_delay_timer.c
+++ b/include/drivers/generic_delay_timer.h
@@ -28,27 +28,13 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <arch_helpers.h>
-#include <delay_timer.h>
-#include <platform_def.h>
+#ifndef __GENERIC_DELAY_TIMER_H__
+#define __GENERIC_DELAY_TIMER_H__
 
-static uint32_t plat_get_timer_value(void)
-{
-	/*
-	 * Generic delay timer implementation expects the timer to be a down
-	 * counter. We apply bitwise NOT operator to the tick values returned
-	 * by read_cntpct_el0() to simulate the down counter.
-	 */
-	return (uint32_t)(~read_cntpct_el0());
-}
+#include <stdint.h>
 
-static const timer_ops_t plat_timer_ops = {
-	.get_timer_value	= plat_get_timer_value,
-	.clk_mult		= 1,
-	.clk_div		= SYS_COUNTER_FREQ_IN_MHZ,
-};
+void generic_delay_timer_init_args(uint32_t mult, uint32_t div);
+
+void generic_delay_timer_init(void);
 
-void plat_delay_timer_init(void)
-{
-	timer_init(&plat_timer_ops);
-}
+#endif /* __GENERIC_DELAY_TIMER_H__ */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 42260e9..a08a12e 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -56,7 +56,9 @@
 /*******************************************************************************
  * Mandatory common functions
  ******************************************************************************/
-unsigned long long plat_get_syscnt_freq(void);
+unsigned long long plat_get_syscnt_freq(void) __deprecated;
+unsigned int plat_get_syscnt_freq2(void);
+
 int plat_get_image_source(unsigned int image_id,
 			uintptr_t *dev_handle,
 			uintptr_t *image_spec);
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index 305309a..ee49c30 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -28,6 +28,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <generic_delay_timer.h>
 #include <mmio.h>
 #include <plat_arm.h>
 #include <sp804_delay_timer.h>
@@ -48,6 +49,7 @@
 {
 	arm_bl2_platform_setup();
 
+#if FVP_USE_SP804_TIMER
 	/* Enable the clock override for SP804 timer 0, which means that no
 	 * clock dividers are applied and the raw (35 MHz) clock will be used */
 	mmio_write_32(V2M_SP810_BASE, FVP_SP810_CTRL_TIM0_OV);
@@ -55,4 +57,7 @@
 	/* Initialize delay timer driver using SP804 dual timer 0 */
 	sp804_timer_init(V2M_SP804_TIMER0_BASE,
 			SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV);
+#else
+	generic_delay_timer_init();
+#endif /* FVP_USE_SP804_TIMER */
 }
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index eecb597..c0fe662 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -30,6 +30,11 @@
 
 # Use the GICv3 driver on the FVP by default
 FVP_USE_GIC_DRIVER	:= FVP_GICV3
+# Use the SP804 timer instead of the generic one
+FVP_USE_SP804_TIMER	:= 0
+
+$(eval $(call assert_boolean,FVP_USE_SP804_TIMER))
+$(eval $(call add_define,FVP_USE_SP804_TIMER))
 
 # The FVP platform depends on this macro to build with correct GIC driver.
 $(eval $(call add_define,FVP_USE_GIC_DRIVER))
@@ -92,8 +97,7 @@
 				${FVP_INTERCONNECT_SOURCES}
 
 
-BL2_SOURCES		+=	drivers/arm/sp804/sp804_delay_timer.c		\
-				drivers/io/io_semihosting.c			\
+BL2_SOURCES		+=	drivers/io/io_semihosting.c			\
 				drivers/delay_timer/delay_timer.c		\
 				lib/semihosting/semihosting.c			\
 				lib/semihosting/aarch64/semihosting_call.S	\
@@ -102,6 +106,12 @@
 				plat/arm/board/fvp/fvp_io_storage.c		\
 				${FVP_SECURITY_SOURCES}
 
+ifeq (${FVP_USE_SP804_TIMER},1)
+BL2_SOURCES		+=	drivers/arm/sp804/sp804_delay_timer.c
+else
+BL2_SOURCES		+=	drivers/delay_timer/generic_delay_timer.c
+endif
+
 BL2U_SOURCES		+=	plat/arm/board/fvp/fvp_bl2u_setup.c		\
 				${FVP_SECURITY_SOURCES}
 
diff --git a/plat/arm/common/aarch64/arm_common.c b/plat/arm/common/aarch64/arm_common.c
index cf1f3ba..616edc9 100644
--- a/plat/arm/common/aarch64/arm_common.c
+++ b/plat/arm/common/aarch64/arm_common.c
@@ -29,6 +29,7 @@
  */
 #include <arch.h>
 #include <arch_helpers.h>
+#include <assert.h>
 #include <debug.h>
 #include <mmio.h>
 #include <plat_arm.h>
@@ -40,7 +41,14 @@
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak plat_get_ns_image_entrypoint
 #pragma weak plat_arm_get_mmap
+
+/* Conditionally provide a weak definition of plat_get_syscnt_freq2 to avoid
+ * conflicts with the definition in plat/common. */
+#if ERROR_DEPRECATED
+#pragma weak plat_get_syscnt_freq2
+#else
 #pragma weak plat_get_syscnt_freq
+#endif
 
 /*******************************************************************************
  * Macro generating the code for the function setting up the pagetables as per
@@ -164,9 +172,16 @@
 }
 
 #ifdef ARM_SYS_CNTCTL_BASE
+
+#if ERROR_DEPRECATED
+unsigned int plat_get_syscnt_freq2(void)
+{
+	unsigned int counter_base_frequency
+#else
 unsigned long long plat_get_syscnt_freq(void)
 {
 	unsigned long long counter_base_frequency;
+#endif /* ERROR_DEPRECATED */
 
 	/* Read the frequency from Frequency modes table */
 	counter_base_frequency = mmio_read_32(ARM_SYS_CNTCTL_BASE + CNTFID_OFF);
@@ -177,4 +192,5 @@
 
 	return counter_base_frequency;
 }
+
 #endif /* ARM_SYS_CNTCTL_BASE */
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index 9070c61..4322341 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -40,6 +40,9 @@
 #pragma weak bl31_plat_enable_mmu
 #pragma weak bl32_plat_enable_mmu
 #pragma weak bl31_plat_runtime_setup
+#if !ERROR_DEPRECATED
+#pragma weak plat_get_syscnt_freq2
+#endif /* ERROR_DEPRECATED */
 
 void bl31_plat_enable_mmu(uint32_t flags)
 {
@@ -74,3 +77,14 @@
 }
 #endif
 
+
+#if !ERROR_DEPRECATED
+unsigned int plat_get_syscnt_freq2(void)
+{
+	unsigned long long freq = plat_get_syscnt_freq();
+
+	assert(freq >> 32 == 0);
+
+	return (unsigned int)freq;
+}
+#endif /* ERROR_DEPRECATED */
diff --git a/plat/mediatek/mt8173/aarch64/platform_common.c b/plat/mediatek/mt8173/aarch64/platform_common.c
index d83e147..365df1b 100644
--- a/plat/mediatek/mt8173/aarch64/platform_common.c
+++ b/plat/mediatek/mt8173/aarch64/platform_common.c
@@ -84,7 +84,7 @@
 /* Define EL3 variants of the function initialising the MMU */
 DEFINE_CONFIGURE_MMU_EL(3)
 
-unsigned long long plat_get_syscnt_freq(void)
+unsigned int plat_get_syscnt_freq2(void)
 {
 	return SYS_COUNTER_FREQ_IN_TICKS;
 }
diff --git a/plat/mediatek/mt8173/bl31_plat_setup.c b/plat/mediatek/mt8173/bl31_plat_setup.c
index 749009e..4626f81 100644
--- a/plat/mediatek/mt8173/bl31_plat_setup.c
+++ b/plat/mediatek/mt8173/bl31_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -32,6 +32,7 @@
 #include <bl_common.h>
 #include <console.h>
 #include <debug.h>
+#include <generic_delay_timer.h>
 #include <mcucfg.h>
 #include <mmio.h>
 #include <mtcmos.h>
@@ -167,7 +168,7 @@
 	platform_setup_cpu();
 	platform_setup_sram();
 
-	plat_delay_timer_init();
+	generic_delay_timer_init();
 
 	/* Initialize the gic cpu and distributor interfaces */
 	plat_mt_gic_init();
diff --git a/plat/mediatek/mt8173/include/mt8173_def.h b/plat/mediatek/mt8173/include/mt8173_def.h
index 360be6c..87e9c04 100644
--- a/plat/mediatek/mt8173/include/mt8173_def.h
+++ b/plat/mediatek/mt8173/include/mt8173_def.h
@@ -83,7 +83,6 @@
  * System counter frequency related constants
  ******************************************************************************/
 #define SYS_COUNTER_FREQ_IN_TICKS	13000000
-#define SYS_COUNTER_FREQ_IN_MHZ		13
 
 /*******************************************************************************
  * GIC-400 & interrupt handling related constants
diff --git a/plat/mediatek/mt8173/include/plat_private.h b/plat/mediatek/mt8173/include/plat_private.h
index bdde6a6..ae50e44 100644
--- a/plat/mediatek/mt8173/include/plat_private.h
+++ b/plat/mediatek/mt8173/include/plat_private.h
@@ -51,6 +51,4 @@
 /* Declarations for plat_topology.c */
 int mt_setup_topology(void);
 
-void plat_delay_timer_init(void);
-
 #endif /* __PLAT_PRIVATE_H__ */
diff --git a/plat/mediatek/mt8173/plat_delay_timer.c b/plat/mediatek/mt8173/plat_delay_timer.c
deleted file mode 100644
index cc66b80..0000000
--- a/plat/mediatek/mt8173/plat_delay_timer.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of ARM nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#include <arch_helpers.h>
-#include <delay_timer.h>
-#include <mt8173_def.h>
-
-static uint32_t plat_get_timer_value(void)
-{
-	/* Generic delay timer implementation expects the timer to be a down
-	 * counter. We apply bitwise NOT operator to the tick values returned
-	 * by read_cntpct_el0() to simulate the down counter. */
-	return (uint32_t)(~read_cntpct_el0());
-}
-
-static const timer_ops_t plat_timer_ops = {
-	.get_timer_value	= plat_get_timer_value,
-	.clk_mult		= 1,
-	.clk_div		= SYS_COUNTER_FREQ_IN_MHZ,
-};
-
-void plat_delay_timer_init(void)
-{
-	timer_init(&plat_timer_ops);
-}
diff --git a/plat/mediatek/mt8173/platform.mk b/plat/mediatek/mt8173/platform.mk
index 1c550f3..8f48230 100644
--- a/plat/mediatek/mt8173/platform.mk
+++ b/plat/mediatek/mt8173/platform.mk
@@ -52,6 +52,7 @@
 				drivers/arm/gic/gic_v3.c			\
 				drivers/console/console.S			\
 				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
 				lib/cpus/aarch64/aem_generic.S			\
 				lib/cpus/aarch64/cortex_a53.S			\
 				lib/cpus/aarch64/cortex_a57.S			\
@@ -72,7 +73,6 @@
 				${MTK_PLAT_SOC}/drivers/spm/spm_suspend.c	\
 				${MTK_PLAT_SOC}/drivers/timer/mt_cpuxgpt.c	\
 				${MTK_PLAT_SOC}/drivers/uart/8250_console.S	\
-				${MTK_PLAT_SOC}/plat_delay_timer.c		\
 				${MTK_PLAT_SOC}/plat_mt_gic.c			\
 				${MTK_PLAT_SOC}/plat_pm.c			\
 				${MTK_PLAT_SOC}/plat_sip_calls.c		\
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index fb47f48..cf75d9f 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -52,7 +52,6 @@
 
 /* Declarations for plat_setup.c */
 const mmap_region_t *plat_get_mmio_map(void);
-unsigned long long plat_get_syscnt_freq(void);
 
 /* Declarations for plat_secondary.c */
 void plat_secondary_setup(void);
diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c
index 5b10505..0d66413 100644
--- a/plat/nvidia/tegra/soc/t132/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t132/plat_setup.c
@@ -74,7 +74,7 @@
 	return tegra_mmap;
 }
 
-unsigned long long plat_get_syscnt_freq(void)
+unsigned int plat_get_syscnt_freq2(void)
 {
 	return 12000000;
 }
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index eecedb3..70a55c6 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -80,7 +80,7 @@
 /*******************************************************************************
  * Handler to get the System Counter Frequency
  ******************************************************************************/
-unsigned long long plat_get_syscnt_freq(void)
+unsigned int plat_get_syscnt_freq2(void)
 {
 	return 19200000;
 }
diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c
index ba4d1a4..6e9dab7 100644
--- a/plat/rockchip/common/aarch64/platform_common.c
+++ b/plat/rockchip/common/aarch64/platform_common.c
@@ -75,7 +75,7 @@
 /* Define EL3 variants of the function initialising the MMU */
 DEFINE_CONFIGURE_MMU_EL(3)
 
-unsigned long long plat_get_syscnt_freq(void)
+unsigned int plat_get_syscnt_freq2(void)
 {
 	return SYS_COUNTER_FREQ_IN_TICKS;
 }
diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c
index 30fb5ac..727a2c7 100644
--- a/plat/rockchip/common/bl31_plat_setup.c
+++ b/plat/rockchip/common/bl31_plat_setup.c
@@ -33,6 +33,7 @@
 #include <bl_common.h>
 #include <console.h>
 #include <debug.h>
+#include <generic_delay_timer.h>
 #include <mmio.h>
 #include <platform.h>
 #include <plat_private.h>
@@ -126,7 +127,7 @@
  ******************************************************************************/
 void bl31_platform_setup(void)
 {
-	plat_delay_timer_init();
+	generic_delay_timer_init();
 	plat_rockchip_soc_init();
 
 	/* Initialize the gic cpu and distributor interfaces */
diff --git a/plat/rockchip/rk3368/platform.mk b/plat/rockchip/rk3368/platform.mk
index 0d34cf4..0e64b7e 100644
--- a/plat/rockchip/rk3368/platform.mk
+++ b/plat/rockchip/rk3368/platform.mk
@@ -58,13 +58,13 @@
 				drivers/console/console.S			\
 				drivers/ti/uart/16550_console.S			\
 				drivers/delay_timer/delay_timer.c		\
+				drivers/delay_timer/generic_delay_timer.c	\
 				lib/cpus/aarch64/cortex_a53.S			\
 				plat/common/aarch64/platform_mp_stack.S		\
 				${RK_PLAT_COMMON}/aarch64/plat_helpers.S	\
 				${RK_PLAT_COMMON}/bl31_plat_setup.c		\
 				${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S		\
 				${RK_PLAT_COMMON}/pmusram/pmu_sram.c		\
-				${RK_PLAT_COMMON}/plat_delay_timer.c		\
 				${RK_PLAT_COMMON}/plat_pm.c			\
 				${RK_PLAT_COMMON}/plat_topology.c		\
 				${RK_PLAT_COMMON}/aarch64/platform_common.c	\
diff --git a/plat/rockchip/rk3368/rk3368_def.h b/plat/rockchip/rk3368/rk3368_def.h
index 614f270..2242cee 100644
--- a/plat/rockchip/rk3368/rk3368_def.h
+++ b/plat/rockchip/rk3368/rk3368_def.h
@@ -89,7 +89,6 @@
  * System counter frequency related constants
  ******************************************************************************/
 #define SYS_COUNTER_FREQ_IN_TICKS	24000000
-#define SYS_COUNTER_FREQ_IN_MHZ		24
 
 /******************************************************************************
  * GIC-400 & interrupt handling related constants
diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index 6d7e134..45064e7 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -57,6 +57,7 @@
                                 drivers/console/console.S                       \
                                 drivers/ti/uart/16550_console.S                 \
                                 drivers/delay_timer/delay_timer.c               \
+                                drivers/delay_timer/generic_delay_timer.c	\
                                 lib/cpus/aarch64/cortex_a53.S                   \
                                 lib/cpus/aarch64/cortex_a72.S                   \
                                 plat/common/aarch64/platform_mp_stack.S         \
@@ -64,7 +65,6 @@
                                 ${RK_PLAT_COMMON}/bl31_plat_setup.c             \
                                 ${RK_PLAT_COMMON}/pmusram/pmu_sram_cpus_on.S	\
 				${RK_PLAT_COMMON}/pmusram/pmu_sram.c		\
-                                ${RK_PLAT_COMMON}/plat_delay_timer.c            \
                                 ${RK_PLAT_COMMON}/plat_pm.c                     \
                                 ${RK_PLAT_COMMON}/plat_topology.c               \
                                 ${RK_PLAT_COMMON}/aarch64/platform_common.c        \
diff --git a/plat/rockchip/rk3399/rk3399_def.h b/plat/rockchip/rk3399/rk3399_def.h
index 6a8be84..b1fc1e6 100644
--- a/plat/rockchip/rk3399/rk3399_def.h
+++ b/plat/rockchip/rk3399/rk3399_def.h
@@ -89,7 +89,6 @@
  * System counter frequency related constants
  ******************************************************************************/
 #define SYS_COUNTER_FREQ_IN_TICKS	24000000
-#define SYS_COUNTER_FREQ_IN_MHZ		24
 
 /* Base rockchip_platform compatible GIC memory map */
 #define BASE_GICD_BASE		(GIC500_BASE)
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index 6e5cee3..f89cdce 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -297,9 +297,9 @@
 	mmio_write_32(IOU_SCNTRS_CONTROL, IOU_SCNTRS_CONTROL_EN);
 }
 
-unsigned long long plat_get_syscnt_freq(void)
+unsigned int plat_get_syscnt_freq2(void)
 {
-	unsigned long long counter_base_frequency;
+	unsigned int counter_base_frequency;
 
 	/* FIXME: Read the frequency from Frequency modes table */
 	counter_base_frequency = zynqmp_get_system_timer_freq();
diff --git a/services/std_svc/psci/psci_suspend.c b/services/std_svc/psci/psci_suspend.c
index bd0c5db..367bb32 100644
--- a/services/std_svc/psci/psci_suspend.c
+++ b/services/std_svc/psci/psci_suspend.c
@@ -214,7 +214,7 @@
 void psci_cpu_suspend_finish(unsigned int cpu_idx,
 			     psci_power_state_t *state_info)
 {
-	unsigned long long counter_freq;
+	unsigned int counter_freq;
 	unsigned int max_off_lvl;
 
 	/* Ensure we have been woken up from a suspended state */
@@ -238,7 +238,7 @@
 	psci_do_pwrup_cache_maintenance();
 
 	/* Re-init the cntfrq_el0 register */
-	counter_freq = plat_get_syscnt_freq();
+	counter_freq = plat_get_syscnt_freq2();
 	write_cntfrq_el0(counter_freq);
 
 	/*