Skip to contentSkip to conversation

armv7/ltimer: Add support for local timer on armv7 cpus

PATCH RESEND Superseded Vipin Kumar 5 participants 12 messages Dec 6, 2012 – Feb 6, 2013 Arm (32-bit)

lore
Share & tools
lore
#0 lore raw

PATCH RESEND 1/1 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.

---
 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
arch/arm/cpu/armv7/Makefile +7 -4
index 4fdbee4..3ef01f6 100644
@@ -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))
arch/arm/cpu/armv7/ca9_ltimer.c new file +152 -0

152 lines not on this page · raw message

arch/arm/include/asm/ca9_ltimer.h new file +40 -0
new file mode 100644
index 0000000..8833853
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Micoelectronics, [email protected].
+ *
+ * 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
Signature · 1 line
1.8.0
#1 lore raw

PATCH RESEND 1/1 armv7/ltimer: Add support for local timer on armv7 cpus

ping

Quoted 243 lines · Vipin KUMAR

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.

---
  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

arch/arm/cpu/armv7/Makefile +7 -4
index 4fdbee4..3ef01f6 100644
@@ -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))
arch/arm/cpu/armv7/ca9_ltimer.c new file +152 -0
new file mode 100644
index 0000000..cbf1552
@@ -0,0 +1,152 @@
+/*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at 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;
+}
arch/arm/include/asm/ca9_ltimer.h new file +40 -0
new file mode 100644
index 0000000..8833853
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at 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
#2 lore raw

PATCH RESEND 1/1 armv7/ltimer: Add support for local timer on armv7 cpus

In reply to Vipin Kumar

ping again

Quoted 243 lines · Vipin KUMAR

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.

---
  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

arch/arm/cpu/armv7/Makefile +7 -4
index 4fdbee4..3ef01f6 100644
@@ -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))
arch/arm/cpu/armv7/ca9_ltimer.c new file +152 -0
new file mode 100644
index 0000000..cbf1552
@@ -0,0 +1,152 @@
+/*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at 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;
+}
arch/arm/include/asm/ca9_ltimer.h new file +40 -0
new file mode 100644
index 0000000..8833853
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at 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
#3 lore raw

PATCH RESEND 1/1 armv7/ltimer: Add support for local timer on armv7 cpus

Dear Vipin Kumar,

Quoted 1 line · In message <[email protected]> you wrote:

ping again

pong ;-)

Quoted 3 lines · Vipin KUMAR
Quoted 2 lines

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

Signature · 5 lines
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 at 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
#4 lore raw

PATCH RESEND 1/1 armv7/ltimer: Add support for local timer on armv7 cpus

Hi

Quoted 7 lines · Wolfgang Denk

Dear Vipin Kumar,

Quoted 1 line · In message <[email protected]> you wrote:

ping again

pong ;-)

Quoted 9 lines
Quoted 2 lines · Vipin KUMAR
Quoted 1 line

Certain ARMV7 cpus eg. CortexA9 contains a local and a global timer

within the

Quoted 1 line
Quoted 1 line

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?

Quoted 15 lines

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 at 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 at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

#5 lore raw

PATCH RESEND 1/1 armv7/ltimer: Add support for local timer on armv7 cpus

Quoted 23 lines · Dennis Lan (dlan)

Hi

On Sat, Dec 15, 2012 at 6:20 AM, Wolfgang Denk <[email protected] <mailto:[email protected]>> wrote:

Dear Vipin Kumar,

In message <[email protected]
<mailto:[email protected]>> 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?

Quoted 8 lines

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.

Quoted 4 lines

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

#6 lore raw

PATCH RESEND 1/1 armv7/ltimer: Add support for local timer on armv7 cpus

Dear Vipin Kumar,

Quoted 2 lines · In message <[email protected]> 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?

Quoted 4 lines

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?

Quoted 2 lines

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

Signature · 5 lines
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 at denx.de
"Confound these ancestors.... They've stolen our best ideas!"
- Ben Jonson
#7 lore raw

PATCH RESEND 1/1 armv7/ltimer: Add support for local timer on armv7 cpus

In reply to Dennis Lan (dlan)

Dear "Dennis Lan (dlan)",

Quoted 9 lines · In message <CAF1ZMEcVWc3DNdcb7gQ60D-8Nx-MHOpkLs=eY0ph2w_Lgcozaw@mail.gmail.com>…
Quoted 4 lines

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

Signature · 5 lines
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 at denx.de
One does not thank logic.
	-- Sarek, "Journey to Babel", stardate 3842.4
#8 lore raw

PATCH RESEND 1/1 armv7/ltimer: Add support for local timer on armv7 cpus

Quoted 13 lines · Wolfgang Denk

Dear "Dennis Lan (dlan)",

Quoted 9 lines · In message<CAF1ZMEcVWc3DNdcb7gQ60D-8Nx-MHOpkLs=eY0ph2w_Lgcozaw@mail.gmail.com>…
Quoted 4 lines

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..

Quoted 5 lines

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

Quoted 3 lines

"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.html

Regards
Vipin

Quoted 4 lines

Best regards,

Wolfgang Denk

#9 lore raw

PATCH RESEND 1/1 armv7/ltimer: Add support for local timer on armv7 cpus

In reply to Vipin Kumar

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.

Quoted 19 lines · Vipin KUMAR

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.

---
  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

arch/arm/cpu/armv7/Makefile +0 -0
index 4fdbee4..3ef01f6 100644
@@ -27,15 +27,18 @@ LIB	= $(obj)lib$(CPU).o
 
  START	:= start.o

arch/arm/cpu/armv7/Makefile LIB = $(obj)lib$(CPU).o · line 35

Quoted 10 lines
arch/arm/cpu/armv7/Makefile +4 -3
 
-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...

Quoted 64 lines
arch/arm/cpu/armv7/Makefile +3 -1
  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))
arch/arm/cpu/armv7/ca9_ltimer.c new file +48 -0
new file mode 100644
index 0000000..cbf1552
@@ -0,0 +1,152 @@
+/*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at 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

arch/arm/cpu/armv7/ca9_ltimer.c line 58

Quoted 10 lines
arch/arm/cpu/armv7/ca9_ltimer.c new file +10 -0
+	 * 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?

arch/arm/cpu/armv7/ca9_ltimer.c line 65

Quoted 7 lines
arch/arm/cpu/armv7/ca9_ltimer.c new file +7 -0
+	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()?

Quoted 123 lines
arch/arm/cpu/armv7/ca9_ltimer.c new file +87 -0
+	/* 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;
+}
arch/arm/include/asm/ca9_ltimer.h new file +30 -0
new file mode 100644
index 0000000..8833853
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at 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;

arch/arm/include/asm/ca9_ltimer.h line 40

Quoted 10 lines
arch/arm/include/asm/ca9_ltimer.h new file +10 -0
+};
+
+/* 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 at st.com

#10 lore raw

PATCH RESEND 1/1 armv7/ltimer: Add support for local timer on armv7 cpus

In reply to Vipin Kumar

Hi Vipin,

Quoted 233 lines · Vipin Kumar

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.

---
 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
arch/arm/cpu/armv7/Makefile +7 -4
index 4fdbee4..3ef01f6 100644
@@ -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))
arch/arm/cpu/armv7/ca9_ltimer.c new file +152 -0
new file mode 100644
index 0000000..cbf1552
@@ -0,0 +1,152 @@
+/*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at 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;
+}
arch/arm/include/asm/ca9_ltimer.h new file +30 -0
new file mode 100644
index 0000000..8833853
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at 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;

arch/arm/include/asm/ca9_ltimer.h line 40

Quoted 10 lines
arch/arm/include/asm/ca9_ltimer.h new file +10 -0
+};
+
+/* 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,

Signature · 1 line
Albert.
#11 lore raw

PATCH RESEND 1/1 armv7/ltimer: Add support for local timer on armv7 cpus

Quoted 246 lines · Albert ARIBAUD

Hi Vipin,

Quoted 241 lines · Vipin Kumar

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.

---
  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

arch/arm/cpu/armv7/Makefile +7 -4
index 4fdbee4..3ef01f6 100644
@@ -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))
arch/arm/cpu/armv7/ca9_ltimer.c new file +152 -0
new file mode 100644
index 0000000..cbf1552
@@ -0,0 +1,152 @@
+/*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at 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;
+}
arch/arm/include/asm/ca9_ltimer.h new file +38 -0
new file mode 100644
index 0000000..8833853
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar at 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)
Quoted 9 lines

arch/arm/include/asm/ca9_ltimer.h line 40

Quoted 2 lines
arch/arm/include/asm/ca9_ltimer.h new file +2 -0
+
+#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

Quoted 1 line

Amicalement,