1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
20107f240SMasahiro Yamada /*
3c7abb824SStefan Herbrechtsmeier * Copyright (C) 2017 Weidmüller Interface GmbH & Co. KG
4c7abb824SStefan Herbrechtsmeier * Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
5c7abb824SStefan Herbrechtsmeier *
60107f240SMasahiro Yamada * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
73e1b61deSMichal Simek * Copyright (C) 2011-2017 Xilinx, Inc. All rights reserved.
80107f240SMasahiro Yamada *
90107f240SMasahiro Yamada * (C) Copyright 2008
100107f240SMasahiro Yamada * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
110107f240SMasahiro Yamada *
120107f240SMasahiro Yamada * (C) Copyright 2004
130107f240SMasahiro Yamada * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
140107f240SMasahiro Yamada *
150107f240SMasahiro Yamada * (C) Copyright 2002-2004
160107f240SMasahiro Yamada * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
170107f240SMasahiro Yamada *
180107f240SMasahiro Yamada * (C) Copyright 2003
190107f240SMasahiro Yamada * Texas Instruments <www.ti.com>
200107f240SMasahiro Yamada *
210107f240SMasahiro Yamada * (C) Copyright 2002
220107f240SMasahiro Yamada * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
230107f240SMasahiro Yamada * Marius Groeger <mgroeger@sysgo.de>
240107f240SMasahiro Yamada *
250107f240SMasahiro Yamada * (C) Copyright 2002
260107f240SMasahiro Yamada * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
270107f240SMasahiro Yamada * Alex Zuepke <azu@sysgo.de>
280107f240SMasahiro Yamada */
290107f240SMasahiro Yamada
30c7abb824SStefan Herbrechtsmeier #include <clk.h>
310107f240SMasahiro Yamada #include <common.h>
320107f240SMasahiro Yamada #include <div64.h>
33c7abb824SStefan Herbrechtsmeier #include <dm.h>
340107f240SMasahiro Yamada #include <asm/io.h>
350107f240SMasahiro Yamada #include <asm/arch/hardware.h>
360107f240SMasahiro Yamada #include <asm/arch/clk.h>
370107f240SMasahiro Yamada
380107f240SMasahiro Yamada DECLARE_GLOBAL_DATA_PTR;
390107f240SMasahiro Yamada
400107f240SMasahiro Yamada struct scu_timer {
410107f240SMasahiro Yamada u32 load; /* Timer Load Register */
420107f240SMasahiro Yamada u32 counter; /* Timer Counter Register */
430107f240SMasahiro Yamada u32 control; /* Timer Control Register */
440107f240SMasahiro Yamada };
450107f240SMasahiro Yamada
460107f240SMasahiro Yamada static struct scu_timer *timer_base =
470107f240SMasahiro Yamada (struct scu_timer *)ZYNQ_SCUTIMER_BASEADDR;
480107f240SMasahiro Yamada
490107f240SMasahiro Yamada #define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */
500107f240SMasahiro Yamada #define SCUTIMER_CONTROL_PRESCALER_SHIFT 8
510107f240SMasahiro Yamada #define SCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002 /* Auto-reload */
520107f240SMasahiro Yamada #define SCUTIMER_CONTROL_ENABLE_MASK 0x00000001 /* Timer enable */
530107f240SMasahiro Yamada
540107f240SMasahiro Yamada #define TIMER_LOAD_VAL 0xFFFFFFFF
550107f240SMasahiro Yamada #define TIMER_PRESCALE 255
560107f240SMasahiro Yamada
timer_init(void)570107f240SMasahiro Yamada int timer_init(void)
580107f240SMasahiro Yamada {
590107f240SMasahiro Yamada const u32 emask = SCUTIMER_CONTROL_AUTO_RELOAD_MASK |
600107f240SMasahiro Yamada (TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) |
610107f240SMasahiro Yamada SCUTIMER_CONTROL_ENABLE_MASK;
620107f240SMasahiro Yamada
63c7abb824SStefan Herbrechtsmeier struct udevice *dev;
64c7abb824SStefan Herbrechtsmeier struct clk clk;
65c7abb824SStefan Herbrechtsmeier int ret;
66c7abb824SStefan Herbrechtsmeier
67c7abb824SStefan Herbrechtsmeier ret = uclass_get_device_by_driver(UCLASS_CLK,
68c7abb824SStefan Herbrechtsmeier DM_GET_DRIVER(zynq_clk), &dev);
69c7abb824SStefan Herbrechtsmeier if (ret)
70c7abb824SStefan Herbrechtsmeier return ret;
71c7abb824SStefan Herbrechtsmeier
72c7abb824SStefan Herbrechtsmeier clk.id = cpu_6or4x_clk;
73c7abb824SStefan Herbrechtsmeier ret = clk_request(dev, &clk);
74c7abb824SStefan Herbrechtsmeier if (ret < 0)
75c7abb824SStefan Herbrechtsmeier return ret;
76c7abb824SStefan Herbrechtsmeier
77c7abb824SStefan Herbrechtsmeier gd->cpu_clk = clk_get_rate(&clk);
78c7abb824SStefan Herbrechtsmeier
79c7abb824SStefan Herbrechtsmeier clk_free(&clk);
80c7abb824SStefan Herbrechtsmeier
810107f240SMasahiro Yamada gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / (TIMER_PRESCALE + 1);
820107f240SMasahiro Yamada
830107f240SMasahiro Yamada /* Load the timer counter register */
840107f240SMasahiro Yamada writel(0xFFFFFFFF, &timer_base->load);
850107f240SMasahiro Yamada
860107f240SMasahiro Yamada /*
870107f240SMasahiro Yamada * Start the A9Timer device
880107f240SMasahiro Yamada * Enable Auto reload mode, Clear prescaler control bits
890107f240SMasahiro Yamada * Set prescaler value, Enable the decrementer
900107f240SMasahiro Yamada */
910107f240SMasahiro Yamada clrsetbits_le32(&timer_base->control, SCUTIMER_CONTROL_PRESCALER_MASK,
920107f240SMasahiro Yamada emask);
930107f240SMasahiro Yamada
940107f240SMasahiro Yamada /* Reset time */
950107f240SMasahiro Yamada gd->arch.lastinc = readl(&timer_base->counter) /
960107f240SMasahiro Yamada (gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
970107f240SMasahiro Yamada gd->arch.tbl = 0;
980107f240SMasahiro Yamada
990107f240SMasahiro Yamada return 0;
1000107f240SMasahiro Yamada }
1010107f240SMasahiro Yamada
1020107f240SMasahiro Yamada /*
1030107f240SMasahiro Yamada * This function is derived from PowerPC code (timebase clock frequency).
1040107f240SMasahiro Yamada * On ARM it returns the number of timer ticks per second.
1050107f240SMasahiro Yamada */
get_tbclk(void)1060107f240SMasahiro Yamada ulong get_tbclk(void)
1070107f240SMasahiro Yamada {
108a2ec7fb9SMichal Simek return gd->arch.timer_rate_hz;
1090107f240SMasahiro Yamada }
110