
Hi John,
Le 12/04/2011 08:17, John Rigby a écrit :
diff --git a/arch/arm/cpu/armv7/u8500/lowlevel.S b/arch/arm/cpu/armv7/u8500/lowlevel.S new file mode 100644 index 0000000..0e3f8fc --- /dev/null +++ b/arch/arm/cpu/armv7/u8500/lowlevel.S @@ -0,0 +1,33 @@ +/*
- 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
Please add a copyright notice identifying the right holder(s). Readers *must* be able to tell who the rights holders are and how to contact them -- don't assume the file is too simple to qualify.
diff --git a/arch/arm/cpu/armv7/u8500/timer.c b/arch/arm/cpu/armv7/u8500/timer.c new file mode 100644 index 0000000..8850fd5 --- /dev/null +++ b/arch/arm/cpu/armv7/u8500/timer.c @@ -0,0 +1,167 @@ +/*
- Copyright (C) 2010 Linaro Limited
- John Rigbyjohn.rigby@linaro.org
- Based on original from Linux kernel source and
- internal ST-Ericsson U-Boot source.
- (C) Copyright 2009 Alessandro Rubini
- (C) Copyright 2010 ST-Ericsson
- 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<asm/io.h> +#include<asm/arch/hardware.h>
+DECLARE_GLOBAL_DATA_PTR;
+/*
- The MTU device has some interrupt control registers
- followed by 4 timers.
- */
+/* The timers */ +struct u8500_mtu_timer {
- u32 lr; /* Load value */
- u32 cv; /* Current value */
- u32 cr; /* Control reg */
- u32 bglr; /* ??? */
+};
+/* The MTU that contains the timers */ +struct u8500_mtu {
- u32 imsc; /* Interrupt mask set/clear */
- u32 ris; /* Raw interrupt status */
- u32 mis; /* Masked interrupt status */
- u32 icr; /* Interrupt clear register */
- struct u8500_mtu_timer pt[4];
+};
+/* bits for the control register */ +#define MTU_CR_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR */ +#define MTU_CR_32BITS 0x02
+#define MTU_CR_PRESCALE_1 0x00 +#define MTU_CR_PRESCALE_16 0x04 +#define MTU_CR_PRESCALE_256 0x08 +#define MTU_CR_PRESCALE_MASK 0x0c
+#define MTU_CR_PERIODIC 0x40 /* if 0 = free-running */ +#define MTU_CR_ENA 0x80
+/*
- The MTU is clocked at 133 MHz by default. (V1 and later)
- */
+#define TIMER_CLOCK (133 * 1000 * 1000 / 16) +#define COUNT_TO_USEC(x) ((x) * 16 / 133) +#define USEC_TO_COUNT(x) ((x) * 133 / 16) +#define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ) +#define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ) +#define TIMER_LOAD_VAL 0xffffffff
+/*
- MTU timer to use (from 0 to 3).
- Linux ux500 timer0 on MTU0 and timer0 on MTU1
If you really mean the same timer for both, please explicitly state "timer0 for both MTU0 and MTU1", otherwise fix.
- */
+#define MTU_TIMER 2
+static struct u8500_mtu_timer *timer_base =
- &((struct u8500_mtu *)U8500_MTU0_BASE_V1)->pt[MTU_TIMER];
+/* macro to read the 32 bit timer: since it decrements, we invert read value */ +#define READ_TIMER() (~readl(&timer_base->cv))
+/* Configure a free-running, auto-wrap counter with /16 prescaler */ +int timer_init(void) +{
- writel(MTU_CR_ENA | MTU_CR_PRESCALE_16 | MTU_CR_32BITS,
- &timer_base->cr);
- reset_timer();
- return 0;
+}
+ulong get_timer_masked(void) +{
- /* current tick value */
- ulong now = TICKS_TO_HZ(READ_TIMER());
- if (now>= gd->lastinc) /* normal (non rollover) */
gd->tbl += (now - gd->lastinc);
- else /* rollover */
gd->tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) - gd->lastinc) + now;
- gd->lastinc = now;
- return gd->tbl;
+}
+/* Delay x useconds */ +void __udelay(ulong usec) +{
- long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
- ulong now, last = READ_TIMER();
- while (tmo> 0) {
now = READ_TIMER();
if (now> last) /* normal (non rollover) */
tmo -= now - last;
else /* rollover */
tmo -= TIMER_LOAD_VAL - last + now;
last = now;
- }
+}
+ulong get_timer(ulong base) +{
- return get_timer_masked() - base;
+}
+void set_timer(ulong t) +{
- gd->tbl = t;
+}
+void reset_timer_masked(void) +{
- gd->lastinc = TICKS_TO_HZ(READ_TIMER());
- gd->tbl = 0; /* reset ticks to 0 */
+}
+void reset_timer(void) +{
- reset_timer_masked();
+}
Please remove these reset_timer functions and in the client code. Resetting a timer is never useful for timing loops. Client code that resets the timer must be fixed.
Amicalement,