[U-Boot] [PATCH resend] armv7/ltimer: Add support for local timer on armv7 cpus

Certain ARMV7 cpus eg. CortexA9 contains a local and a global timer within the CPU core itself. This patch adds generic support for local timer.
Signed-off-by: Vipin Kumar vipin.kumar@st.com --- arch/arm/cpu/armv7/Makefile | 11 ++- arch/arm/cpu/armv7/ca9_ltimer.c | 152 ++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/ca9_ltimer.h | 40 ++++++++++ 3 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 arch/arm/cpu/armv7/ca9_ltimer.c create mode 100644 arch/arm/include/asm/ca9_ltimer.h
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 4fdbee4..3ef01f6 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -27,15 +27,18 @@ LIB = $(obj)lib$(CPU).o
START := start.o
-COBJS += cache_v7.o +COBJS-y += cache_v7.o
-COBJS += cpu.o -COBJS += syslib.o +COBJS-y += cpu.o +COBJS-y += syslib.o +COBJS-$(CONFIG_ARMV7_CA9LTIMER) += ca9_ltimer.o
ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),) -SOBJS += lowlevel_init.o +SOBJS-y += lowlevel_init.o endif
+COBJS := $(sort $(COBJS-y)) +SOBJS := $(sort $(SOBJS-y)) SRCS := $(START:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) START := $(addprefix $(obj),$(START)) diff --git a/arch/arm/cpu/armv7/ca9_ltimer.c b/arch/arm/cpu/armv7/ca9_ltimer.c new file mode 100644 index 0000000..cbf1552 --- /dev/null +++ b/arch/arm/cpu/armv7/ca9_ltimer.c @@ -0,0 +1,152 @@ +/* + * (C) Copyright 2012 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. + * + * 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/ca9_ltimer.h> +#include <asm/arch/hardware.h> + +#define READ_TIMER() readl(&ca9_timer_p->count) + +static struct ca9_timer_regs *const ca9_timer_p = + (struct ca9_timer_regs *)CONFIG_ARMV7_LTIMER_BASE; + +DECLARE_GLOBAL_DATA_PTR; + +#define timestamp gd->tbl +#define lastdec gd->lastinc +#define tickshz gd->timer_rate_hz +#define ticksper10usec gd->tbu + +int timer_init(void) +{ + u32 prescaler, timertickshz; + /* + * Genrally, CortexA9 MPUs are operating from 500MHz to 1500MHz which + * means that CA9 local timer clock would be in the range of 250 MHz to + * 750MHz. + * Try to find a prescaler which can perfectly divide the local timer + * clock. Take prescaler as 200 if nothing is found + */ + for (prescaler = 255; prescaler > 1; prescaler--) { + if (CONFIG_ARMV7_LTMR_CLK == + (CONFIG_ARMV7_LTMR_CLK / prescaler) * prescaler) + break; + } + + if (prescaler == 1) + prescaler = 200; + timertickshz = CONFIG_ARMV7_LTMR_CLK / prescaler; + ticksper10usec = timertickshz / (100 * 1000); + tickshz = timertickshz / CONFIG_SYS_HZ; + + /* disable timers */ + writel(((prescaler - 1) << 8) | AUTO_RELOAD, &ca9_timer_p->control); + + /* load value for free running */ + writel(FREE_RUNNING, &ca9_timer_p->load); + + /* auto reload, start timer */ + setbits_le32(&ca9_timer_p->control, TIMER_ENABLE); + + reset_timer_masked(); + + return 0; +} + +/* + * timer without interrupts + */ + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ + return (get_timer_masked() / tickshz) - base; +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +void __udelay(unsigned long usec) +{ + ulong tmo; + ulong start = get_timer_masked(); + ulong rndoff; + + rndoff = (usec % 10) ? 1 : 0; + tmo = ((usec / 10) + rndoff) * ticksper10usec; + + while ((ulong) (get_timer_masked() - start) < tmo); +} + +void reset_timer_masked(void) +{ + /* reset time */ + lastdec = READ_TIMER(); + timestamp = 0; +} + +ulong get_timer_masked(void) +{ + ulong now = READ_TIMER(); + + if (now <= lastdec) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += lastdec + FREE_RUNNING - now; + } + lastdec = now; + + return timestamp; +} + +void udelay_masked(unsigned long usec) +{ + return udelay(usec); +} + +/* + * 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; +} diff --git a/arch/arm/include/asm/ca9_ltimer.h b/arch/arm/include/asm/ca9_ltimer.h new file mode 100644 index 0000000..8833853 --- /dev/null +++ b/arch/arm/include/asm/ca9_ltimer.h @@ -0,0 +1,40 @@ +/* + * (C) Copyright 2012 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. + * + * 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 + */ + +#ifndef __ARCH_ARM_CA9TIMER_H +#define __ARCH_ARM_CA9TIMER_H + +struct ca9_timer_regs { + u32 load; + u32 count; + u32 control; +}; + +/* control related definitions */ +#define AUTO_RELOAD (1 << 1) +#define TIMER_ENABLE (1 << 0) + +/* load related definitions */ +#define FREE_RUNNING (0xFFFFFFFF) + +#endif

ping
On 12/6/2012 2:52 PM, Vipin KUMAR wrote:
Certain ARMV7 cpus eg. CortexA9 contains a local and a global timer within the CPU core itself. This patch adds generic support for local timer.
Signed-off-by: Vipin Kumarvipin.kumar@st.com
arch/arm/cpu/armv7/Makefile | 11 ++- arch/arm/cpu/armv7/ca9_ltimer.c | 152 ++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/ca9_ltimer.h | 40 ++++++++++ 3 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 arch/arm/cpu/armv7/ca9_ltimer.c create mode 100644 arch/arm/include/asm/ca9_ltimer.h
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 4fdbee4..3ef01f6 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -27,15 +27,18 @@ LIB = $(obj)lib$(CPU).o
START := start.o
-COBJS += cache_v7.o +COBJS-y += cache_v7.o
-COBJS += cpu.o -COBJS += syslib.o +COBJS-y += cpu.o +COBJS-y += syslib.o +COBJS-$(CONFIG_ARMV7_CA9LTIMER) += ca9_ltimer.o
ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),) -SOBJS += lowlevel_init.o +SOBJS-y += lowlevel_init.o endif
+COBJS := $(sort $(COBJS-y)) +SOBJS := $(sort $(SOBJS-y)) SRCS := $(START:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) START := $(addprefix $(obj),$(START)) diff --git a/arch/arm/cpu/armv7/ca9_ltimer.c b/arch/arm/cpu/armv7/ca9_ltimer.c new file mode 100644 index 0000000..cbf1552 --- /dev/null +++ b/arch/arm/cpu/armv7/ca9_ltimer.c @@ -0,0 +1,152 @@ +/*
- (C) Copyright 2012
- Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
- 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/ca9_ltimer.h> +#include<asm/arch/hardware.h>
+#define READ_TIMER() readl(&ca9_timer_p->count)
+static struct ca9_timer_regs *const ca9_timer_p =
- (struct ca9_timer_regs *)CONFIG_ARMV7_LTIMER_BASE;
+DECLARE_GLOBAL_DATA_PTR;
+#define timestamp gd->tbl +#define lastdec gd->lastinc +#define tickshz gd->timer_rate_hz +#define ticksper10usec gd->tbu
+int timer_init(void) +{
- u32 prescaler, timertickshz;
- /*
* Genrally, CortexA9 MPUs are operating from 500MHz to 1500MHz which
* means that CA9 local timer clock would be in the range of 250 MHz to
* 750MHz.
* Try to find a prescaler which can perfectly divide the local timer
* clock. Take prescaler as 200 if nothing is found
*/
- for (prescaler = 255; prescaler> 1; prescaler--) {
if (CONFIG_ARMV7_LTMR_CLK ==
(CONFIG_ARMV7_LTMR_CLK / prescaler) * prescaler)
break;
- }
- if (prescaler == 1)
prescaler = 200;
- timertickshz = CONFIG_ARMV7_LTMR_CLK / prescaler;
- ticksper10usec = timertickshz / (100 * 1000);
- tickshz = timertickshz / CONFIG_SYS_HZ;
- /* disable timers */
- writel(((prescaler - 1)<< 8) | AUTO_RELOAD,&ca9_timer_p->control);
- /* load value for free running */
- writel(FREE_RUNNING,&ca9_timer_p->load);
- /* auto reload, start timer */
- setbits_le32(&ca9_timer_p->control, TIMER_ENABLE);
- reset_timer_masked();
- return 0;
+}
+/*
- timer without interrupts
- */
+void reset_timer(void) +{
- reset_timer_masked();
+}
+ulong get_timer(ulong base) +{
- return (get_timer_masked() / tickshz) - base;
+}
+void set_timer(ulong t) +{
- timestamp = t;
+}
+void __udelay(unsigned long usec) +{
- ulong tmo;
- ulong start = get_timer_masked();
- ulong rndoff;
- rndoff = (usec % 10) ? 1 : 0;
- tmo = ((usec / 10) + rndoff) * ticksper10usec;
- while ((ulong) (get_timer_masked() - start)< tmo);
+}
+void reset_timer_masked(void) +{
- /* reset time */
- lastdec = READ_TIMER();
- timestamp = 0;
+}
+ulong get_timer_masked(void) +{
- ulong now = READ_TIMER();
- if (now<= lastdec) {
/* normal mode */
timestamp += lastdec - now;
- } else {
/* we have an overflow ... */
timestamp += lastdec + FREE_RUNNING - now;
- }
- lastdec = now;
- return timestamp;
+}
+void udelay_masked(unsigned long usec) +{
- return udelay(usec);
+}
+/*
- 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;
+} diff --git a/arch/arm/include/asm/ca9_ltimer.h b/arch/arm/include/asm/ca9_ltimer.h new file mode 100644 index 0000000..8833853 --- /dev/null +++ b/arch/arm/include/asm/ca9_ltimer.h @@ -0,0 +1,40 @@ +/*
- (C) Copyright 2012
- Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
- 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
- */
+#ifndef __ARCH_ARM_CA9TIMER_H +#define __ARCH_ARM_CA9TIMER_H
+struct ca9_timer_regs {
- u32 load;
- u32 count;
- u32 control;
+};
+/* control related definitions */ +#define AUTO_RELOAD (1<< 1) +#define TIMER_ENABLE (1<< 0)
+/* load related definitions */ +#define FREE_RUNNING (0xFFFFFFFF)
+#endif

ping again
On 12/6/2012 2:52 PM, Vipin KUMAR wrote:
Certain ARMV7 cpus eg. CortexA9 contains a local and a global timer within the CPU core itself. This patch adds generic support for local timer.
Signed-off-by: Vipin Kumarvipin.kumar@st.com
arch/arm/cpu/armv7/Makefile | 11 ++- arch/arm/cpu/armv7/ca9_ltimer.c | 152 ++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/ca9_ltimer.h | 40 ++++++++++ 3 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 arch/arm/cpu/armv7/ca9_ltimer.c create mode 100644 arch/arm/include/asm/ca9_ltimer.h
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 4fdbee4..3ef01f6 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -27,15 +27,18 @@ LIB = $(obj)lib$(CPU).o
START := start.o
-COBJS += cache_v7.o +COBJS-y += cache_v7.o
-COBJS += cpu.o -COBJS += syslib.o +COBJS-y += cpu.o +COBJS-y += syslib.o +COBJS-$(CONFIG_ARMV7_CA9LTIMER) += ca9_ltimer.o
ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),) -SOBJS += lowlevel_init.o +SOBJS-y += lowlevel_init.o endif
+COBJS := $(sort $(COBJS-y)) +SOBJS := $(sort $(SOBJS-y)) SRCS := $(START:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) START := $(addprefix $(obj),$(START)) diff --git a/arch/arm/cpu/armv7/ca9_ltimer.c b/arch/arm/cpu/armv7/ca9_ltimer.c new file mode 100644 index 0000000..cbf1552 --- /dev/null +++ b/arch/arm/cpu/armv7/ca9_ltimer.c @@ -0,0 +1,152 @@ +/*
- (C) Copyright 2012
- Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
- 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/ca9_ltimer.h> +#include<asm/arch/hardware.h>
+#define READ_TIMER() readl(&ca9_timer_p->count)
+static struct ca9_timer_regs *const ca9_timer_p =
- (struct ca9_timer_regs *)CONFIG_ARMV7_LTIMER_BASE;
+DECLARE_GLOBAL_DATA_PTR;
+#define timestamp gd->tbl +#define lastdec gd->lastinc +#define tickshz gd->timer_rate_hz +#define ticksper10usec gd->tbu
+int timer_init(void) +{
- u32 prescaler, timertickshz;
- /*
* Genrally, CortexA9 MPUs are operating from 500MHz to 1500MHz which
* means that CA9 local timer clock would be in the range of 250 MHz to
* 750MHz.
* Try to find a prescaler which can perfectly divide the local timer
* clock. Take prescaler as 200 if nothing is found
*/
- for (prescaler = 255; prescaler> 1; prescaler--) {
if (CONFIG_ARMV7_LTMR_CLK ==
(CONFIG_ARMV7_LTMR_CLK / prescaler) * prescaler)
break;
- }
- if (prescaler == 1)
prescaler = 200;
- timertickshz = CONFIG_ARMV7_LTMR_CLK / prescaler;
- ticksper10usec = timertickshz / (100 * 1000);
- tickshz = timertickshz / CONFIG_SYS_HZ;
- /* disable timers */
- writel(((prescaler - 1)<< 8) | AUTO_RELOAD,&ca9_timer_p->control);
- /* load value for free running */
- writel(FREE_RUNNING,&ca9_timer_p->load);
- /* auto reload, start timer */
- setbits_le32(&ca9_timer_p->control, TIMER_ENABLE);
- reset_timer_masked();
- return 0;
+}
+/*
- timer without interrupts
- */
+void reset_timer(void) +{
- reset_timer_masked();
+}
+ulong get_timer(ulong base) +{
- return (get_timer_masked() / tickshz) - base;
+}
+void set_timer(ulong t) +{
- timestamp = t;
+}
+void __udelay(unsigned long usec) +{
- ulong tmo;
- ulong start = get_timer_masked();
- ulong rndoff;
- rndoff = (usec % 10) ? 1 : 0;
- tmo = ((usec / 10) + rndoff) * ticksper10usec;
- while ((ulong) (get_timer_masked() - start)< tmo);
+}
+void reset_timer_masked(void) +{
- /* reset time */
- lastdec = READ_TIMER();
- timestamp = 0;
+}
+ulong get_timer_masked(void) +{
- ulong now = READ_TIMER();
- if (now<= lastdec) {
/* normal mode */
timestamp += lastdec - now;
- } else {
/* we have an overflow ... */
timestamp += lastdec + FREE_RUNNING - now;
- }
- lastdec = now;
- return timestamp;
+}
+void udelay_masked(unsigned long usec) +{
- return udelay(usec);
+}
+/*
- 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;
+} diff --git a/arch/arm/include/asm/ca9_ltimer.h b/arch/arm/include/asm/ca9_ltimer.h new file mode 100644 index 0000000..8833853 --- /dev/null +++ b/arch/arm/include/asm/ca9_ltimer.h @@ -0,0 +1,40 @@ +/*
- (C) Copyright 2012
- Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
- 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
- */
+#ifndef __ARCH_ARM_CA9TIMER_H +#define __ARCH_ARM_CA9TIMER_H
+struct ca9_timer_regs {
- u32 load;
- u32 count;
- u32 control;
+};
+/* control related definitions */ +#define AUTO_RELOAD (1<< 1) +#define TIMER_ENABLE (1<< 0)
+/* load related definitions */ +#define FREE_RUNNING (0xFFFFFFFF)
+#endif

Dear Vipin Kumar,
In message 50CAF0CB.1050108@st.com you wrote:
ping again
pong ;-)
On 12/6/2012 2:52 PM, Vipin KUMAR wrote:
Certain ARMV7 cpus eg. CortexA9 contains a local and a global timer within the CPU core itself. This patch adds generic support for local timer.
What would be the use of such timer support? Is there any code that actually needs it, and why does it need anything beyond the existing timer support we have?
Best regards,
Wolfgang Denk

Hi
On Sat, Dec 15, 2012 at 6:20 AM, Wolfgang Denk wd@denx.de wrote:
Dear Vipin Kumar,
In message 50CAF0CB.1050108@st.com you wrote:
ping again
pong ;-)
On 12/6/2012 2:52 PM, Vipin KUMAR wrote:
Certain ARMV7 cpus eg. CortexA9 contains a local and a global timer
within the
CPU core itself. This patch adds generic support for local timer.
What would be the use of such timer support? Is there any code that actually needs it, and why does it need anything beyond the existing timer support we have?
Hi wolfgang: I think vipin here is trying to provide a generic timer support for ARMV7 architecture, which contains private(local) and global timer. It's general a good thing which means we can maximize the code usage.. Actually I was planing to test the code, but haven't find the time yet ;-)
Hi vipin: why you only support local timer(private)? shouldn't it different to support global timer too?
Best regards,
Wolfgang Denk
-- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de There is a time in the tides of men, Which, taken at its flood, leads on to success. On the other hand, don't count on it. - T. K. Lawson _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On 12/16/2012 1:14 PM, Dennis Lan (dlan) wrote:
Hi
On Sat, Dec 15, 2012 at 6:20 AM, Wolfgang Denk <wd@denx.de mailto:wd@denx.de> wrote:
Dear Vipin Kumar, In message <50CAF0CB.1050108@st.com <mailto:50CAF0CB.1050108@st.com>> you wrote: > ping again pong ;-) > On 12/6/2012 2:52 PM, Vipin KUMAR wrote: > > Certain ARMV7 cpus eg. CortexA9 contains a local and a global timer within the > > CPU core itself. This patch adds generic support for local timer. What would be the use of such timer support? Is there any code that actually needs it, and why does it need anything beyond the existing timer support we have?
Hi wolfgang: I think vipin here is trying to provide a generic timer support for ARMV7 architecture, which contains private(local) and global timer. It's general a good thing which means we can maximize the code usage.. Actually I was planing to test the code, but haven't find the time yet ;-)
Hello Wolfgang
Dennis is right. I am trying to provide the armv7 local timer support.
Hi vipin: why you only support local timer(private)? shouldn't it different to support global timer too?
Well, actually the local timer was used in the spear13xx support which is to be added later on. The global timer was not used and hence the driver was not needed (at least by us). but I agree that such a driver would be useful for a lot of people using armv7 cores and CPU timers
The global timer support, even if it is added, would be added as a separate driver so this is infact complete in its own
Regards Vipin

Dear Vipin Kumar,
In message 50CE9E90.1090406@st.com you wrote:
Dennis is right. I am trying to provide the armv7 local timer support.
Why would we need such? And how is the term "local" defined here? Local to what?
Well, actually the local timer was used in the spear13xx support which is to be added later on. The global timer was not used and hence the driver was not needed (at least by us). but I agree that such a driver would be useful for a lot of people using armv7 cores and CPU timers
Please explain why? We do have timer support on armv7, right?
Why are you adding something new, then? If you are tring to replace existing code with some better implementation, I would expect to see code being removed, too?
The global timer support, even if it is added, would be added as a separate driver so this is infact complete in its own
Please understand that completeness has never been any goal for U-Boot, on contrary.
Quote:
Perfection is reached, not when there is no longer anything to add, but when there is no longer anything to take away. - Antoine de Saint-Exupery
Best regards,
Wolfgang Denk

Dear "Dennis Lan (dlan)",
In message CAF1ZMEcVWc3DNdcb7gQ60D-8Nx-MHOpkLs=eY0ph2w_Lgcozaw@mail.gmail.com you wrote:
What would be the use of such timer support? Is there any code that actually needs it, and why does it need anything beyond the existing timer support we have?
I think vipin here is trying to provide a generic timer support for ARMV7 architecture, which contains private(local) and global timer. It's general a good thing which means we can maximize the code usage..
Sorry, I don't get it. Why would we need separate global and local timers? And what exactly is "local" here - local to what?
We don't need anything like that on other architectures - so why here?
"general a good thing" sounds like "nice to have", and this is usually something we don't really need, especially not in a boot loader.
Best regards,
Wolfgang Denk

On 12/17/2012 11:20 PM, Wolfgang Denk wrote:
Dear "Dennis Lan (dlan)",
In messageCAF1ZMEcVWc3DNdcb7gQ60D-8Nx-MHOpkLs=eY0ph2w_Lgcozaw@mail.gmail.com you wrote:
What would be the use of such timer support? Is there any code that actually needs it, and why does it need anything beyond the existing timer support we have?
I think vipin here is trying to provide a generic timer support for ARMV7 architecture, which contains private(local) and global timer. It's general a good thing which means we can maximize the code usage..
Sorry, I don't get it. Why would we need separate global and local timers? And what exactly is "local" here - local to what?
We don't need anything like that on other architectures - so why here?
Let me start afresh. There are two timer peripherals (called as local and global) built into armv7 cores. The local timer is specific to each processor while the global timer is common for all cores. These timers may be initialized and used for timer operations in armv7 based SoCs
"general a good thing" sounds like "nice to have", and this is usually something we don't really need, especially not in a boot loader.
This is nothing but a timer peripheral driver. The timer is a part of armv7 core so it is kept in arch/arm/cpu/armv7
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0407i/index.h...
Regards Vipin
Best regards,
Wolfgang Denk

Ciao Vipin,
Yes, I agree about the need to have the generic local_timer support in u-boot.
Internally I was not able to give comment about this part. So, see my comments now.
On 12/06/2012 10:22 AM, Vipin KUMAR wrote:
Certain ARMV7 cpus eg. CortexA9 contains a local and a global timer within the CPU core itself. This patch adds generic support for local timer.
Signed-off-by: Vipin Kumarvipin.kumar@st.com
arch/arm/cpu/armv7/Makefile | 11 ++- arch/arm/cpu/armv7/ca9_ltimer.c | 152 ++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/ca9_ltimer.h | 40 ++++++++++ 3 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 arch/arm/cpu/armv7/ca9_ltimer.c create mode 100644 arch/arm/include/asm/ca9_ltimer.h
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 4fdbee4..3ef01f6 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -27,15 +27,18 @@ LIB = $(obj)lib$(CPU).o
START := start.o
-COBJS += cache_v7.o +COBJS-y += cache_v7.o
-COBJS += cpu.o -COBJS += syslib.o +COBJS-y += cpu.o +COBJS-y += syslib.o +COBJS-$(CONFIG_ARMV7_CA9LTIMER) += ca9_ltimer.o
Is it really necessary to have the 'ca9' prefix here? I think it would be better to stay more generic here, like: 'CONFIG_ARMV7_LTIMER' and 'ltimer.o'.
In linux as well is kept generic, even across architectures...
If accepted, apply globally...
ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),) -SOBJS += lowlevel_init.o +SOBJS-y += lowlevel_init.o endif
+COBJS := $(sort $(COBJS-y)) +SOBJS := $(sort $(SOBJS-y)) SRCS := $(START:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) START := $(addprefix $(obj),$(START)) diff --git a/arch/arm/cpu/armv7/ca9_ltimer.c b/arch/arm/cpu/armv7/ca9_ltimer.c new file mode 100644 index 0000000..cbf1552 --- /dev/null +++ b/arch/arm/cpu/armv7/ca9_ltimer.c @@ -0,0 +1,152 @@ +/*
- (C) Copyright 2012
- Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
- 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/ca9_ltimer.h> +#include<asm/arch/hardware.h>
+#define READ_TIMER() readl(&ca9_timer_p->count)
+static struct ca9_timer_regs *const ca9_timer_p =
- (struct ca9_timer_regs *)CONFIG_ARMV7_LTIMER_BASE;
+DECLARE_GLOBAL_DATA_PTR;
+#define timestamp gd->tbl +#define lastdec gd->lastinc +#define tickshz gd->timer_rate_hz +#define ticksper10usec gd->tbu
+int timer_init(void) +{
- u32 prescaler, timertickshz;
- /*
* Genrally, CortexA9 MPUs are operating from 500MHz to 1500MHz which
* means that CA9 local timer clock would be in the range of 250 MHz to
* 750MHz.
* Try to find a prescaler which can perfectly divide the local timer
* clock. Take prescaler as 200 if nothing is found
*/
- for (prescaler = 255; prescaler> 1; prescaler--) {
if (CONFIG_ARMV7_LTMR_CLK ==
(CONFIG_ARMV7_LTMR_CLK / prescaler) * prescaler)
break;
- }
- if (prescaler == 1)
prescaler = 200;
Where the default '200' prescaler selection come from? Shouldn't it be a configurable option (i.e. CONFIG_)? Or passed as an argument to this function?
- timertickshz = CONFIG_ARMV7_LTMR_CLK / prescaler;
- ticksper10usec = timertickshz / (100 * 1000);
- tickshz = timertickshz / CONFIG_SYS_HZ;
- /* disable timers */
- writel(((prescaler - 1)<< 8) | AUTO_RELOAD,&ca9_timer_p->control);
Why can't single-shot be selectable? Shouldn't it be passed as an argument to timer_init()?
- /* load value for free running */
- writel(FREE_RUNNING,&ca9_timer_p->load);
- /* auto reload, start timer */
- setbits_le32(&ca9_timer_p->control, TIMER_ENABLE);
- reset_timer_masked();
- return 0;
+}
+/*
- timer without interrupts
- */
+void reset_timer(void) +{
- reset_timer_masked();
+}
+ulong get_timer(ulong base) +{
- return (get_timer_masked() / tickshz) - base;
+}
+void set_timer(ulong t) +{
- timestamp = t;
+}
+void __udelay(unsigned long usec) +{
- ulong tmo;
- ulong start = get_timer_masked();
- ulong rndoff;
- rndoff = (usec % 10) ? 1 : 0;
- tmo = ((usec / 10) + rndoff) * ticksper10usec;
- while ((ulong) (get_timer_masked() - start)< tmo);
+}
+void reset_timer_masked(void) +{
- /* reset time */
- lastdec = READ_TIMER();
- timestamp = 0;
+}
+ulong get_timer_masked(void) +{
- ulong now = READ_TIMER();
- if (now<= lastdec) {
/* normal mode */
timestamp += lastdec - now;
- } else {
/* we have an overflow ... */
timestamp += lastdec + FREE_RUNNING - now;
- }
- lastdec = now;
- return timestamp;
+}
+void udelay_masked(unsigned long usec) +{
- return udelay(usec);
+}
+/*
- 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;
+} diff --git a/arch/arm/include/asm/ca9_ltimer.h b/arch/arm/include/asm/ca9_ltimer.h new file mode 100644 index 0000000..8833853 --- /dev/null +++ b/arch/arm/include/asm/ca9_ltimer.h @@ -0,0 +1,40 @@ +/*
- (C) Copyright 2012
- Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
- 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
- */
+#ifndef __ARCH_ARM_CA9TIMER_H +#define __ARCH_ARM_CA9TIMER_H
+struct ca9_timer_regs {
- u32 load;
- u32 count;
- u32 control;
+};
+/* control related definitions */ +#define AUTO_RELOAD (1<< 1) +#define TIMER_ENABLE (1<< 0)
+/* load related definitions */ +#define FREE_RUNNING (0xFFFFFFFF)
+#endif
Seems good otherwise. Reveiewed-by:armando.visconti@st.com

Hi Vipin,
On Thu, 6 Dec 2012 14:52:55 +0530, Vipin Kumar vipin.kumar@st.com wrote:
Certain ARMV7 cpus eg. CortexA9 contains a local and a global timer within the CPU core itself. This patch adds generic support for local timer.
Signed-off-by: Vipin Kumar vipin.kumar@st.com
arch/arm/cpu/armv7/Makefile | 11 ++- arch/arm/cpu/armv7/ca9_ltimer.c | 152 ++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/ca9_ltimer.h | 40 ++++++++++ 3 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 arch/arm/cpu/armv7/ca9_ltimer.c create mode 100644 arch/arm/include/asm/ca9_ltimer.h
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 4fdbee4..3ef01f6 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -27,15 +27,18 @@ LIB = $(obj)lib$(CPU).o
START := start.o
-COBJS += cache_v7.o +COBJS-y += cache_v7.o
-COBJS += cpu.o -COBJS += syslib.o +COBJS-y += cpu.o +COBJS-y += syslib.o +COBJS-$(CONFIG_ARMV7_CA9LTIMER) += ca9_ltimer.o
ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),) -SOBJS += lowlevel_init.o +SOBJS-y += lowlevel_init.o endif
+COBJS := $(sort $(COBJS-y)) +SOBJS := $(sort $(SOBJS-y)) SRCS := $(START:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) START := $(addprefix $(obj),$(START)) diff --git a/arch/arm/cpu/armv7/ca9_ltimer.c b/arch/arm/cpu/armv7/ca9_ltimer.c new file mode 100644 index 0000000..cbf1552 --- /dev/null +++ b/arch/arm/cpu/armv7/ca9_ltimer.c @@ -0,0 +1,152 @@ +/*
- (C) Copyright 2012
- Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
- 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/ca9_ltimer.h> +#include <asm/arch/hardware.h>
+#define READ_TIMER() readl(&ca9_timer_p->count)
+static struct ca9_timer_regs *const ca9_timer_p =
- (struct ca9_timer_regs *)CONFIG_ARMV7_LTIMER_BASE;
+DECLARE_GLOBAL_DATA_PTR;
+#define timestamp gd->tbl +#define lastdec gd->lastinc +#define tickshz gd->timer_rate_hz +#define ticksper10usec gd->tbu
+int timer_init(void) +{
- u32 prescaler, timertickshz;
- /*
* Genrally, CortexA9 MPUs are operating from 500MHz to 1500MHz which
* means that CA9 local timer clock would be in the range of 250 MHz to
* 750MHz.
* Try to find a prescaler which can perfectly divide the local timer
* clock. Take prescaler as 200 if nothing is found
*/
- for (prescaler = 255; prescaler > 1; prescaler--) {
if (CONFIG_ARMV7_LTMR_CLK ==
(CONFIG_ARMV7_LTMR_CLK / prescaler) * prescaler)
break;
- }
- if (prescaler == 1)
prescaler = 200;
- timertickshz = CONFIG_ARMV7_LTMR_CLK / prescaler;
- ticksper10usec = timertickshz / (100 * 1000);
- tickshz = timertickshz / CONFIG_SYS_HZ;
- /* disable timers */
- writel(((prescaler - 1) << 8) | AUTO_RELOAD, &ca9_timer_p->control);
- /* load value for free running */
- writel(FREE_RUNNING, &ca9_timer_p->load);
- /* auto reload, start timer */
- setbits_le32(&ca9_timer_p->control, TIMER_ENABLE);
- reset_timer_masked();
- return 0;
+}
+/*
- timer without interrupts
- */
+void reset_timer(void) +{
- reset_timer_masked();
+}
+ulong get_timer(ulong base) +{
- return (get_timer_masked() / tickshz) - base;
+}
+void set_timer(ulong t) +{
- timestamp = t;
+}
+void __udelay(unsigned long usec) +{
- ulong tmo;
- ulong start = get_timer_masked();
- ulong rndoff;
- rndoff = (usec % 10) ? 1 : 0;
- tmo = ((usec / 10) + rndoff) * ticksper10usec;
- while ((ulong) (get_timer_masked() - start) < tmo);
+}
+void reset_timer_masked(void) +{
- /* reset time */
- lastdec = READ_TIMER();
- timestamp = 0;
+}
+ulong get_timer_masked(void) +{
- ulong now = READ_TIMER();
- if (now <= lastdec) {
/* normal mode */
timestamp += lastdec - now;
- } else {
/* we have an overflow ... */
timestamp += lastdec + FREE_RUNNING - now;
- }
- lastdec = now;
- return timestamp;
+}
+void udelay_masked(unsigned long usec) +{
- return udelay(usec);
+}
+/*
- 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;
+} diff --git a/arch/arm/include/asm/ca9_ltimer.h b/arch/arm/include/asm/ca9_ltimer.h new file mode 100644 index 0000000..8833853 --- /dev/null +++ b/arch/arm/include/asm/ca9_ltimer.h @@ -0,0 +1,40 @@ +/*
- (C) Copyright 2012
- Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
- 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
- */
+#ifndef __ARCH_ARM_CA9TIMER_H +#define __ARCH_ARM_CA9TIMER_H
+struct ca9_timer_regs {
- u32 load;
- u32 count;
- u32 control;
+};
+/* control related definitions */ +#define AUTO_RELOAD (1 << 1) +#define TIMER_ENABLE (1 << 0)
+/* load related definitions */ +#define FREE_RUNNING (0xFFFFFFFF)
+#endif
Rejected on the grounds that it is basically dead code. Feel free to resubmit within a series where it is needed, for instance in support of a new target where current timer implementation would not be useable, or at least, where using the core-local timer module brings benefits with respect to the current implementation.
Amicalement,

On 2/3/2013 7:28 PM, Albert ARIBAUD wrote:
Hi Vipin,
On Thu, 6 Dec 2012 14:52:55 +0530, Vipin Kumarvipin.kumar@st.com wrote:
Certain ARMV7 cpus eg. CortexA9 contains a local and a global timer within the CPU core itself. This patch adds generic support for local timer.
Signed-off-by: Vipin Kumarvipin.kumar@st.com
arch/arm/cpu/armv7/Makefile | 11 ++- arch/arm/cpu/armv7/ca9_ltimer.c | 152 ++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/ca9_ltimer.h | 40 ++++++++++ 3 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 arch/arm/cpu/armv7/ca9_ltimer.c create mode 100644 arch/arm/include/asm/ca9_ltimer.h
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 4fdbee4..3ef01f6 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -27,15 +27,18 @@ LIB = $(obj)lib$(CPU).o
START := start.o
-COBJS += cache_v7.o +COBJS-y += cache_v7.o
-COBJS += cpu.o -COBJS += syslib.o +COBJS-y += cpu.o +COBJS-y += syslib.o +COBJS-$(CONFIG_ARMV7_CA9LTIMER) += ca9_ltimer.o
ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),) -SOBJS += lowlevel_init.o +SOBJS-y += lowlevel_init.o endif
+COBJS := $(sort $(COBJS-y)) +SOBJS := $(sort $(SOBJS-y)) SRCS := $(START:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) START := $(addprefix $(obj),$(START)) diff --git a/arch/arm/cpu/armv7/ca9_ltimer.c b/arch/arm/cpu/armv7/ca9_ltimer.c new file mode 100644 index 0000000..cbf1552 --- /dev/null +++ b/arch/arm/cpu/armv7/ca9_ltimer.c @@ -0,0 +1,152 @@ +/*
- (C) Copyright 2012
- Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
- 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/ca9_ltimer.h> +#include<asm/arch/hardware.h>
+#define READ_TIMER() readl(&ca9_timer_p->count)
+static struct ca9_timer_regs *const ca9_timer_p =
- (struct ca9_timer_regs *)CONFIG_ARMV7_LTIMER_BASE;
+DECLARE_GLOBAL_DATA_PTR;
+#define timestamp gd->tbl +#define lastdec gd->lastinc +#define tickshz gd->timer_rate_hz +#define ticksper10usec gd->tbu
+int timer_init(void) +{
- u32 prescaler, timertickshz;
- /*
* Genrally, CortexA9 MPUs are operating from 500MHz to 1500MHz which
* means that CA9 local timer clock would be in the range of 250 MHz to
* 750MHz.
* Try to find a prescaler which can perfectly divide the local timer
* clock. Take prescaler as 200 if nothing is found
*/
- for (prescaler = 255; prescaler> 1; prescaler--) {
if (CONFIG_ARMV7_LTMR_CLK ==
(CONFIG_ARMV7_LTMR_CLK / prescaler) * prescaler)
break;
- }
- if (prescaler == 1)
prescaler = 200;
- timertickshz = CONFIG_ARMV7_LTMR_CLK / prescaler;
- ticksper10usec = timertickshz / (100 * 1000);
- tickshz = timertickshz / CONFIG_SYS_HZ;
- /* disable timers */
- writel(((prescaler - 1)<< 8) | AUTO_RELOAD,&ca9_timer_p->control);
- /* load value for free running */
- writel(FREE_RUNNING,&ca9_timer_p->load);
- /* auto reload, start timer */
- setbits_le32(&ca9_timer_p->control, TIMER_ENABLE);
- reset_timer_masked();
- return 0;
+}
+/*
- timer without interrupts
- */
+void reset_timer(void) +{
- reset_timer_masked();
+}
+ulong get_timer(ulong base) +{
- return (get_timer_masked() / tickshz) - base;
+}
+void set_timer(ulong t) +{
- timestamp = t;
+}
+void __udelay(unsigned long usec) +{
- ulong tmo;
- ulong start = get_timer_masked();
- ulong rndoff;
- rndoff = (usec % 10) ? 1 : 0;
- tmo = ((usec / 10) + rndoff) * ticksper10usec;
- while ((ulong) (get_timer_masked() - start)< tmo);
+}
+void reset_timer_masked(void) +{
- /* reset time */
- lastdec = READ_TIMER();
- timestamp = 0;
+}
+ulong get_timer_masked(void) +{
- ulong now = READ_TIMER();
- if (now<= lastdec) {
/* normal mode */
timestamp += lastdec - now;
- } else {
/* we have an overflow ... */
timestamp += lastdec + FREE_RUNNING - now;
- }
- lastdec = now;
- return timestamp;
+}
+void udelay_masked(unsigned long usec) +{
- return udelay(usec);
+}
+/*
- 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;
+} diff --git a/arch/arm/include/asm/ca9_ltimer.h b/arch/arm/include/asm/ca9_ltimer.h new file mode 100644 index 0000000..8833853 --- /dev/null +++ b/arch/arm/include/asm/ca9_ltimer.h @@ -0,0 +1,40 @@ +/*
- (C) Copyright 2012
- Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
- 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
- */
+#ifndef __ARCH_ARM_CA9TIMER_H +#define __ARCH_ARM_CA9TIMER_H
+struct ca9_timer_regs {
- u32 load;
- u32 count;
- u32 control;
+};
+/* control related definitions */ +#define AUTO_RELOAD (1<< 1) +#define TIMER_ENABLE (1<< 0)
+/* load related definitions */ +#define FREE_RUNNING (0xFFFFFFFF)
+#endif
Rejected on the grounds that it is basically dead code. Feel free to resubmit within a series where it is needed, for instance in support of a new target where current timer implementation would not be useable, or at least, where using the core-local timer module brings benefits with respect to the current implementation.
OK. I thought this driver can be used by anyone using a CA9. Infact, I remember that someone showed interest to use it
Anyways, I would resubmit with its user
Vipin
Amicalement,
participants (5)
-
Albert ARIBAUD
-
Armando Visconti
-
Dennis Lan (dlan)
-
Vipin Kumar
-
Wolfgang Denk