+// SPDX-License-Identifier: GPL-2.0+
/*
+ * Copyright (C) 2017 Weidmüller Interface GmbH & Co. KG
+ *
- * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved.
+ * Copyright (C) 2011-2017 Xilinx, Inc. All rights reserved.
*
* (C) Copyright 2008
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
+#include <clk.h>
#include <common.h>
#include <div64.h>
+#include <dm.h>
+#include <init.h>
+#include <time.h>
+#include <malloc.h>
+#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>
#include <asm/arch/clk.h>
(TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) |
SCUTIMER_CONTROL_ENABLE_MASK;
+ struct udevice *dev;
+ struct clk clk;
+ int ret;
+
+ ret = uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(zynq_clk), &dev);
+ if (ret)
+ return ret;
+
+ clk.id = cpu_6or4x_clk;
+ ret = clk_request(dev, &clk);
+ if (ret < 0)
+ return ret;
+
+ gd->cpu_clk = clk_get_rate(&clk);
+
+ clk_free(&clk);
+
gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / (TIMER_PRESCALE + 1);
/* Load the timer counter register */
return 0;
}
-/*
- * This function is derived from PowerPC code (read timebase as long long).
- * On ARM it just returns the timer value.
- */
-ulong get_timer_masked(void)
-{
- ulong now;
-
- now = readl(&timer_base->counter) /
- (gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
-
- if (gd->arch.lastinc >= now) {
- /* Normal mode */
- gd->arch.tbl += gd->arch.lastinc - now;
- } else {
- /* We have an overflow ... */
- gd->arch.tbl += gd->arch.lastinc + (TIMER_LOAD_VAL /
- (gd->arch.timer_rate_hz / CONFIG_SYS_HZ)) -
- now + 1;
- }
- gd->arch.lastinc = now;
-
- return gd->arch.tbl;
-}
-
-void __udelay(unsigned long usec)
-{
- u32 countticks;
- u32 timeend;
- u32 timediff;
- u32 timenow;
-
- if (usec == 0)
- return;
-
- countticks = lldiv(((unsigned long long)gd->arch.timer_rate_hz * usec),
- 1000000);
-
- /* decrementing timer */
- timeend = readl(&timer_base->counter) - countticks;
-
-#if TIMER_LOAD_VAL != 0xFFFFFFFF
- /* do not manage multiple overflow */
- if (countticks >= TIMER_LOAD_VAL)
- countticks = TIMER_LOAD_VAL - 1;
-#endif
-
- do {
- timenow = readl(&timer_base->counter);
-
- if (timenow >= timeend) {
- /* normal case */
- timediff = timenow - timeend;
- } else {
- if ((TIMER_LOAD_VAL - timeend + timenow) <=
- countticks) {
- /* overflow */
- timediff = TIMER_LOAD_VAL - timeend + timenow;
- } else {
- /* missed the exact match */
- break;
- }
- }
- } while (timediff > 0);
-}
-
-/* Timer without interrupts */
-ulong get_timer(ulong base)
-{
- return get_timer_masked() - base;
-}
-
-/*
- * This function is derived from PowerPC code (read timebase as long long).
- * On ARM it just returns the timer value.
- */
-unsigned long long get_ticks(void)
-{
- return get_timer(0);
-}
-
/*
* This function is derived from PowerPC code (timebase clock frequency).
* On ARM it returns the number of timer ticks per second.
*/
ulong get_tbclk(void)
{
- return CONFIG_SYS_HZ;
+ return gd->arch.timer_rate_hz;
}