u-boot-brain/arch/arm/mach-zynq/timer.c
Simon Glass 401d1c4f5d common: Drop asm/global_data.h from common header
Move this out of the common header and include it only where needed.  In
a number of cases this requires adding "struct udevice;" to avoid adding
another large header or in other cases replacing / adding missing header
files that had been pulled in, very indirectly.   Finally, we have a few
cases where we did not need to include <asm/global_data.h> at all, so
remove that include.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Tom Rini <trini@konsulko.com>
2021-02-02 15:33:42 -05:00

114 lines
2.8 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2017 Weidmüller Interface GmbH & Co. KG
* Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
*
* Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
* Copyright (C) 2011-2017 Xilinx, Inc. All rights reserved.
*
* (C) Copyright 2008
* Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
*
* (C) Copyright 2004
* Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
*
* (C) Copyright 2002-2004
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
*
* (C) Copyright 2003
* Texas Instruments <www.ti.com>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Alex Zuepke <azu@sysgo.de>
*/
#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>
DECLARE_GLOBAL_DATA_PTR;
struct scu_timer {
u32 load; /* Timer Load Register */
u32 counter; /* Timer Counter Register */
u32 control; /* Timer Control Register */
};
static struct scu_timer *timer_base =
(struct scu_timer *)ZYNQ_SCUTIMER_BASEADDR;
#define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */
#define SCUTIMER_CONTROL_PRESCALER_SHIFT 8
#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002 /* Auto-reload */
#define SCUTIMER_CONTROL_ENABLE_MASK 0x00000001 /* Timer enable */
#define TIMER_LOAD_VAL 0xFFFFFFFF
#define TIMER_PRESCALE 255
int timer_init(void)
{
const u32 emask = SCUTIMER_CONTROL_AUTO_RELOAD_MASK |
(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 */
writel(0xFFFFFFFF, &timer_base->load);
/*
* Start the A9Timer device
* Enable Auto reload mode, Clear prescaler control bits
* Set prescaler value, Enable the decrementer
*/
clrsetbits_le32(&timer_base->control, SCUTIMER_CONTROL_PRESCALER_MASK,
emask);
/* Reset time */
gd->arch.lastinc = readl(&timer_base->counter) /
(gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
gd->arch.tbl = 0;
return 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 gd->arch.timer_rate_hz;
}