
Hi Michal,
On Tue, Aug 14, 2012 at 6:42 AM, Michal Simek monstr@monstr.eu wrote:
Add timer driver.
Signed-off-by: Michal Simek monstr@monstr.eu
arch/arm/cpu/armv7/zynq/Makefile | 48 ++++++++++++ arch/arm/cpu/armv7/zynq/timer.c | 151 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+), 0 deletions(-) create mode 100644 arch/arm/cpu/armv7/zynq/Makefile create mode 100644 arch/arm/cpu/armv7/zynq/timer.c
diff --git a/arch/arm/cpu/armv7/zynq/Makefile b/arch/arm/cpu/armv7/zynq/Makefile new file mode 100644 index 0000000..814c1d4 --- /dev/null +++ b/arch/arm/cpu/armv7/zynq/Makefile @@ -0,0 +1,48 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, lg@denx.de +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +#
+include $(TOPDIR)/config.mk
+LIB = $(obj)lib$(SOC).o
You should include the lowlevel_init.o here instead of in the board.
+COBJS = timer.o
Preferably emulate the Makefile in arch/arm/cpu/armv7/tegra2/. By that I mean use COBJS-y instead of COBJS directly. This is more forward looking to allow for features to be disabled in the future.
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+all: $(obj).depend $(LIB)
+$(LIB): $(OBJS)
$(call cmd_link_o_target, $(OBJS))
+#########################################################################
+# defines $(obj).depend target +include $(SRCTREE)/rules.mk
+sinclude $(obj).depend
+######################################################################### diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/cpu/armv7/zynq/timer.c new file mode 100644 index 0000000..d79da97 --- /dev/null +++ b/arch/arm/cpu/armv7/zynq/timer.c @@ -0,0 +1,151 @@ +/*
- Copyright (C) 2012 Michal Simek monstr@monstr.eu
- Copyright (C) 2011-2012 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
- See file CREDITS for list of people who contributed to this
- project.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
+#include <common.h> +#include <div64.h> +#include <asm/io.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct scu_timer {
u32 load; /* Timer Load Register */
u32 counter; /* Timer Counter Register */
u32 control; /* Timer Control Register */
+};
You are using the timer in the ARM Cortex A9 core. This is not Zynq-specific in any way. It should be made available in a different place. Probably in arch/arm/lib. It should be stripped on any "XSCU" references. Use ARM names instead.
+static struct scu_timer *timer_base = CONFIG_XPSS_SCUTIMER_BASEADDR;
+#define XSCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */ +#define XSCUTIMER_CONTROL_PRESCALER_SHIFT 8 +#define XSCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002 /* Auto-reload */ +#define XSCUTIMER_CONTROL_ENABLE_MASK 0x00000001 /* Timer enable */
+#define TIMER_LOAD_VAL 0xFFFFFFFF +#define TIMER_PRESCALE 255 +#define TIMER_TICK_HZ (CONFIG_CPU_FREQ_HZ / 2 / TIMER_PRESCALE)
+int timer_init(void) +{
u32 val;
/* Load the timer counter register */
writel(0xFFFFFFFF, &timer_base->counter);
/* Start the A9Timer device */
val = readl(&timer_base->control);
/* Enable Auto reload mode */
val |= XSCUTIMER_CONTROL_AUTO_RELOAD_MASK;
/* Clear prescaler control bits */
val &= ~XSCUTIMER_CONTROL_PRESCALER_MASK;
/* Set prescaler value */
val |= (TIMER_PRESCALE << XSCUTIMER_CONTROL_PRESCALER_SHIFT);
/* Enable the decrementer */
val |= XSCUTIMER_CONTROL_ENABLE_MASK;
writel(val, &timer_base->control);
/* Reset time */
gd->lastinc = readl(&timer_base->counter) /
(TIMER_TICK_HZ / CONFIG_SYS_HZ);
gd->tbl = 0;
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) / (TIMER_TICK_HZ / CONFIG_SYS_HZ);
if (gd->lastinc >= now) {
/* Normal mode */
gd->tbl += gd->lastinc - now;
} else {
/* We have an overflow ... */
gd->tbl += gd->lastinc + TIMER_LOAD_VAL - now;
}
gd->lastinc = now;
return gd->tbl;
+}
+void __udelay(unsigned long usec) +{
unsigned long long tmp;
ulong tmo;
tmo = usec / (1000000 / CONFIG_SYS_HZ);
tmp = get_ticks() + tmo; /* Get current timestamp */
while (get_ticks() < tmp) { /* Loop till event */
/* NOP */;
}
+}
+/* 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;
+}
1.7.0.4
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot