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