Message ID | 1345098630-27902-3-git-send-email-monstr@monstr.eu |
---|---|
State | Superseded |
Delegated to: | Albert ARIBAUD |
Headers | show |
On 08/16/2012 08:30 AM, Michal Simek wrote: > Add timer driver. > > Signed-off-by: Michal Simek <monstr@monstr.eu> > > --- > v2: Move lowlevel_init.S from board to cpu folder > Remove XPSS prefix > Rename XSCUTIMER -> SCUTIMER > > Keep timer in zynq folder till ARM custodian comments it. > --- > arch/arm/cpu/armv7/zynq/Makefile | 52 +++++++++++ > arch/arm/cpu/armv7/zynq/lowlevel_init.S | 27 ++++++ > arch/arm/cpu/armv7/zynq/timer.c | 151 +++++++++++++++++++++++++++++++ > 3 files changed, 230 insertions(+), 0 deletions(-) > create mode 100644 arch/arm/cpu/armv7/zynq/Makefile > create mode 100644 arch/arm/cpu/armv7/zynq/lowlevel_init.S > create mode 100644 arch/arm/cpu/armv7/zynq/timer.c We haven't got any reaction for Albert. Marek and Joe: Can you review this? And give me your ACK or NACK. Thanks, Michal
Dear Michal Simek, [...] > +#include <config.h> > +#include <linux/linkage.h> > + > +ENTRY(lowlevel_init) > + mov pc, lr > +ENDPROC(lowlevel_init) inline void lowlevel_init(void) {} works as well and you don't need the assembly file. > diff --git a/arch/arm/cpu/armv7/zynq/timer.c > b/arch/arm/cpu/armv7/zynq/timer.c new file mode 100644 > index 0000000..0252220 > --- /dev/null > +++ b/arch/arm/cpu/armv7/zynq/timer.c > @@ -0,0 +1,151 @@ > +/* > + * Copyright (C) 2012 Michal Simek <monstr@monstr.eu> > + * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved. > + * > + * (C) Copyright 2008 > + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> > + * > + * (C) Copyright 2004 > + * Philippe Robin, ARM Ltd. <philippe.robin@arm.com> > + * > + * (C) Copyright 2002-2004 > + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> > + * > + * (C) Copyright 2003 > + * Texas Instruments <www.ti.com> > + * > + * (C) Copyright 2002 > + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> > + * Marius Groeger <mgroeger@sysgo.de> > + * > + * (C) Copyright 2002 > + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> > + * Alex Zuepke <azu@sysgo.de> > + * > + * See file CREDITS for list of people who contributed to this > + * project. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of > + * the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, > + * MA 02111-1307 USA > + */ > + > +#include <common.h> > +#include <div64.h> > +#include <asm/io.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +struct scu_timer { > + u32 load; /* Timer Load Register */ > + u32 counter; /* Timer Counter Register */ > + u32 control; /* Timer Control Register */ > +}; > + > +static struct scu_timer *timer_base = CONFIG_SCUTIMER_BASEADDR; > + > +#define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */ > +#define SCUTIMER_CONTROL_PRESCALER_SHIFT 8 > +#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002 /* Auto-reload */ > +#define SCUTIMER_CONTROL_ENABLE_MASK 0x00000001 /* Timer enable */ > + > +#define TIMER_LOAD_VAL 0xFFFFFFFF > +#define TIMER_PRESCALE 255 > +#define TIMER_TICK_HZ (CONFIG_CPU_FREQ_HZ / 2 / TIMER_PRESCALE) > + > +int timer_init(void) > +{ > + u32 val; > + > + /* Load the timer counter register */ > + writel(0xFFFFFFFF, &timer_base->counter); > + > + /* Start the A9Timer device */ > + val = readl(&timer_base->control); > + /* Enable Auto reload mode */ > + val |= SCUTIMER_CONTROL_AUTO_RELOAD_MASK; > + /* Clear prescaler control bits */ > + val &= ~SCUTIMER_CONTROL_PRESCALER_MASK; > + /* Set prescaler value */ > + val |= (TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT); > + /* Enable the decrementer */ > + val |= SCUTIMER_CONTROL_ENABLE_MASK; > + writel(val, &timer_base->control); clrsetbits_le32() > + /* Reset time */ > + gd->lastinc = readl(&timer_base->counter) / > + (TIMER_TICK_HZ / CONFIG_SYS_HZ); > + gd->tbl = 0; > + > + return 0; > +} > + > +/* > + * This function is derived from PowerPC code (read timebase as long > long). + * On ARM it just returns the timer value. > + */ > +ulong get_timer_masked(void) > +{ > + ulong now; > + > + now = readl(&timer_base->counter) / (TIMER_TICK_HZ / CONFIG_SYS_HZ); > + > + if (gd->lastinc >= now) { > + /* Normal mode */ > + gd->tbl += gd->lastinc - now; > + } else { > + /* We have an overflow ... */ > + gd->tbl += gd->lastinc + TIMER_LOAD_VAL - now; > + } > + gd->lastinc = now; > + > + return gd->tbl; > +} > + > +void __udelay(unsigned long usec) > +{ > + unsigned long long tmp; > + ulong tmo; > + > + tmo = usec / (1000000 / CONFIG_SYS_HZ); > + tmp = get_ticks() + tmo; /* Get current timestamp */ > + > + while (get_ticks() < tmp) { /* Loop till event */ > + /* NOP */; > + } > +} > + > +/* Timer without interrupts */ > +ulong get_timer(ulong base) > +{ > + return get_timer_masked() - base; > +} > + > +/* > + * This function is derived from PowerPC code (read timebase as long > long). + * On ARM it just returns the timer value. > + */ > +unsigned long long get_ticks(void) > +{ > + return get_timer(0); > +} > + > +/* > + * This function is derived from PowerPC code (timebase clock frequency). > + * On ARM it returns the number of timer ticks per second. > + */ > +ulong get_tbclk(void) > +{ > + return CONFIG_SYS_HZ; > +}
Dear Michal Simek, > On 08/16/2012 08:30 AM, Michal Simek wrote: > > Add timer driver. > > > > Signed-off-by: Michal Simek <monstr@monstr.eu> > > > > --- > > v2: Move lowlevel_init.S from board to cpu folder > > > > Remove XPSS prefix > > Rename XSCUTIMER -> SCUTIMER > > > > Keep timer in zynq folder till ARM custodian comments it. > > --- > > > > arch/arm/cpu/armv7/zynq/Makefile | 52 +++++++++++ > > arch/arm/cpu/armv7/zynq/lowlevel_init.S | 27 ++++++ > > arch/arm/cpu/armv7/zynq/timer.c | 151 > > +++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+), 0 > > deletions(-) > > create mode 100644 arch/arm/cpu/armv7/zynq/Makefile > > create mode 100644 arch/arm/cpu/armv7/zynq/lowlevel_init.S > > create mode 100644 arch/arm/cpu/armv7/zynq/timer.c > > We haven't got any reaction for Albert. > Marek and Joe: Can you review this? And give me your ACK or NACK. Oh I'll gladly torture you :-) btw I might need a bit of a review for a ublaze stuff eventually and maybe some xilinx uart too, there's a large stdio patchset I have queued. Would you review please? > Thanks, > Michal Best regards, Marek Vasut
On 09/13/2012 11:32 AM, Marek Vasut wrote: > Dear Michal Simek, > >> On 08/16/2012 08:30 AM, Michal Simek wrote: >>> Add timer driver. >>> >>> Signed-off-by: Michal Simek <monstr@monstr.eu> >>> >>> --- >>> v2: Move lowlevel_init.S from board to cpu folder >>> >>> Remove XPSS prefix >>> Rename XSCUTIMER -> SCUTIMER >>> >>> Keep timer in zynq folder till ARM custodian comments it. >>> --- >>> >>> arch/arm/cpu/armv7/zynq/Makefile | 52 +++++++++++ >>> arch/arm/cpu/armv7/zynq/lowlevel_init.S | 27 ++++++ >>> arch/arm/cpu/armv7/zynq/timer.c | 151 >>> +++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+), 0 >>> deletions(-) >>> create mode 100644 arch/arm/cpu/armv7/zynq/Makefile >>> create mode 100644 arch/arm/cpu/armv7/zynq/lowlevel_init.S >>> create mode 100644 arch/arm/cpu/armv7/zynq/timer.c >> >> We haven't got any reaction for Albert. >> Marek and Joe: Can you review this? And give me your ACK or NACK. > > Oh I'll gladly torture you :-) Go ahead. :-) > > btw I might need a bit of a review for a ublaze stuff eventually and maybe some > xilinx uart too, there's a large stdio patchset I have queued. Would you review > please? Feel free to contact me if you need any help with any xilinx stuff. Microblaze/xilinx ppc or current arm code. I am keen to change current code to u-boot new standard and also with dts support. Thanks, Michal
On 09/13/2012 11:31 AM, Marek Vasut wrote: > Dear Michal Simek, > > [...] > >> +#include <config.h> >> +#include <linux/linkage.h> >> + >> +ENTRY(lowlevel_init) >> + mov pc, lr >> +ENDPROC(lowlevel_init) > > inline void lowlevel_init(void) {} works as well and you don't need the assembly > file. :-) yes. The reason why I have done it in this way that we have some asm code which will go to this area. That's why I have kept it in asm instead of C. Michal
Dear Michal Simek, > On 09/13/2012 11:31 AM, Marek Vasut wrote: > > Dear Michal Simek, > > > > [...] > > > >> +#include <config.h> > >> +#include <linux/linkage.h> > >> + > >> +ENTRY(lowlevel_init) > >> + mov pc, lr > >> +ENDPROC(lowlevel_init) > > > > inline void lowlevel_init(void) {} works as well and you don't need the > > assembly file. > : > :-) yes. The reason why I have done it in this way that we have some asm > :code > > which will go to this area. That's why I have kept it in asm instead of C. What code? Will the code go into lowlevel_init() ? Best regards, Marek Vasut
On 09/13/2012 12:31 PM, Marek Vasut wrote: > Dear Michal Simek, > >> On 09/13/2012 11:31 AM, Marek Vasut wrote: >>> Dear Michal Simek, >>> >>> [...] >>> >>>> +#include <config.h> >>>> +#include <linux/linkage.h> >>>> + >>>> +ENTRY(lowlevel_init) >>>> + mov pc, lr >>>> +ENDPROC(lowlevel_init) >>> >>> inline void lowlevel_init(void) {} works as well and you don't need the >>> assembly file. >> : >> :-) yes. The reason why I have done it in this way that we have some asm >> :code >> >> which will go to this area. That's why I have kept it in asm instead of C. > > What code? Will the code go into lowlevel_init() ? For example SLCR locking if is not locked from the first stage bootloader. Also if necessary OCM and DDR remap, FPGA reset can be also there based on configuration. Thanks, Michal
Dear Michal Simek, > On 09/13/2012 12:31 PM, Marek Vasut wrote: > > Dear Michal Simek, > > > >> On 09/13/2012 11:31 AM, Marek Vasut wrote: > >>> Dear Michal Simek, > >>> > >>> [...] > >>> > >>>> +#include <config.h> > >>>> +#include <linux/linkage.h> > >>>> + > >>>> +ENTRY(lowlevel_init) > >>>> + mov pc, lr > >>>> +ENDPROC(lowlevel_init) > >>> > >>> inline void lowlevel_init(void) {} works as well and you don't need the > >>> assembly file. > >>> > >> :-) yes. The reason why I have done it in this way that we have some asm > >> :code > >> > >> which will go to this area. That's why I have kept it in asm instead of > >> C. > > > > What code? Will the code go into lowlevel_init() ? > > For example SLCR locking if is not locked from the first stage bootloader. > Also if necessary OCM and DDR remap, FPGA reset can be also there > based on configuration. Can it not be in C code ? > Thanks, > Michal Best regards, Marek Vasut
On 09/13/2012 02:32 PM, Marek Vasut wrote: > Dear Michal Simek, > >> On 09/13/2012 12:31 PM, Marek Vasut wrote: >>> Dear Michal Simek, >>> >>>> On 09/13/2012 11:31 AM, Marek Vasut wrote: >>>>> Dear Michal Simek, >>>>> >>>>> [...] >>>>> >>>>>> +#include <config.h> >>>>>> +#include <linux/linkage.h> >>>>>> + >>>>>> +ENTRY(lowlevel_init) >>>>>> + mov pc, lr >>>>>> +ENDPROC(lowlevel_init) >>>>> >>>>> inline void lowlevel_init(void) {} works as well and you don't need the >>>>> assembly file. >>>>> >>>> :-) yes. The reason why I have done it in this way that we have some asm >>>> :code >>>> >>>> which will go to this area. That's why I have kept it in asm instead of >>>> C. >>> >>> What code? Will the code go into lowlevel_init() ? >> >> For example SLCR locking if is not locked from the first stage bootloader. >> Also if necessary OCM and DDR remap, FPGA reset can be also there >> based on configuration. > > Can it not be in C code ? Probably can be in C code. I have no problem to move it to C. Cheers, Michal
Dear Michal Simek, > On 09/13/2012 02:32 PM, Marek Vasut wrote: > > Dear Michal Simek, > > > >> On 09/13/2012 12:31 PM, Marek Vasut wrote: > >>> Dear Michal Simek, > >>> > >>>> On 09/13/2012 11:31 AM, Marek Vasut wrote: > >>>>> Dear Michal Simek, > >>>>> > >>>>> [...] > >>>>> > >>>>>> +#include <config.h> > >>>>>> +#include <linux/linkage.h> > >>>>>> + > >>>>>> +ENTRY(lowlevel_init) > >>>>>> + mov pc, lr > >>>>>> +ENDPROC(lowlevel_init) > >>>>> > >>>>> inline void lowlevel_init(void) {} works as well and you don't need > >>>>> the assembly file. > >>>>> > >>>> :-) yes. The reason why I have done it in this way that we have some > >>>> :asm code > >>>> > >>>> which will go to this area. That's why I have kept it in asm instead > >>>> of C. > >>> > >>> What code? Will the code go into lowlevel_init() ? > >> > >> For example SLCR locking if is not locked from the first stage > >> bootloader. Also if necessary OCM and DDR remap, FPGA reset can be also > >> there based on configuration. > > > > Can it not be in C code ? > > Probably can be in C code. I have no problem to move it to C. Please do, cut the assembly to minimum. > Cheers, > Michal Best regards, Marek Vasut
diff --git a/arch/arm/cpu/armv7/zynq/Makefile b/arch/arm/cpu/armv7/zynq/Makefile new file mode 100644 index 0000000..1d2d7e1 --- /dev/null +++ b/arch/arm/cpu/armv7/zynq/Makefile @@ -0,0 +1,52 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).o + +SOBJS-y := lowlevel_init.o +COBJS-y := timer.o + +SOBJS := $(SOBJS-y) +COBJS := $(COBJS-y) + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/armv7/zynq/lowlevel_init.S b/arch/arm/cpu/armv7/zynq/lowlevel_init.S new file mode 100644 index 0000000..642eb18 --- /dev/null +++ b/arch/arm/cpu/armv7/zynq/lowlevel_init.S @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2012 Michal Simek <monstr@monstr.eu> + * + * 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. + */ + +#include <config.h> +#include <linux/linkage.h> + +ENTRY(lowlevel_init) + mov pc, lr +ENDPROC(lowlevel_init) diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/cpu/armv7/zynq/timer.c new file mode 100644 index 0000000..0252220 --- /dev/null +++ b/arch/arm/cpu/armv7/zynq/timer.c @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2012 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved. + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. <philippe.robin@arm.com> + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * (C) Copyright 2003 + * Texas Instruments <www.ti.com> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <div64.h> +#include <asm/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct scu_timer { + u32 load; /* Timer Load Register */ + u32 counter; /* Timer Counter Register */ + u32 control; /* Timer Control Register */ +}; + +static struct scu_timer *timer_base = CONFIG_SCUTIMER_BASEADDR; + +#define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */ +#define SCUTIMER_CONTROL_PRESCALER_SHIFT 8 +#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002 /* Auto-reload */ +#define SCUTIMER_CONTROL_ENABLE_MASK 0x00000001 /* Timer enable */ + +#define TIMER_LOAD_VAL 0xFFFFFFFF +#define TIMER_PRESCALE 255 +#define TIMER_TICK_HZ (CONFIG_CPU_FREQ_HZ / 2 / TIMER_PRESCALE) + +int timer_init(void) +{ + u32 val; + + /* Load the timer counter register */ + writel(0xFFFFFFFF, &timer_base->counter); + + /* Start the A9Timer device */ + val = readl(&timer_base->control); + /* Enable Auto reload mode */ + val |= SCUTIMER_CONTROL_AUTO_RELOAD_MASK; + /* Clear prescaler control bits */ + val &= ~SCUTIMER_CONTROL_PRESCALER_MASK; + /* Set prescaler value */ + val |= (TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT); + /* Enable the decrementer */ + val |= SCUTIMER_CONTROL_ENABLE_MASK; + writel(val, &timer_base->control); + + /* Reset time */ + gd->lastinc = readl(&timer_base->counter) / + (TIMER_TICK_HZ / CONFIG_SYS_HZ); + gd->tbl = 0; + + return 0; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +ulong get_timer_masked(void) +{ + ulong now; + + now = readl(&timer_base->counter) / (TIMER_TICK_HZ / CONFIG_SYS_HZ); + + if (gd->lastinc >= now) { + /* Normal mode */ + gd->tbl += gd->lastinc - now; + } else { + /* We have an overflow ... */ + gd->tbl += gd->lastinc + TIMER_LOAD_VAL - now; + } + gd->lastinc = now; + + return gd->tbl; +} + +void __udelay(unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = usec / (1000000 / CONFIG_SYS_HZ); + tmp = get_ticks() + tmo; /* Get current timestamp */ + + while (get_ticks() < tmp) { /* Loop till event */ + /* NOP */; + } +} + +/* Timer without interrupts */ +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +}
Add timer driver. Signed-off-by: Michal Simek <monstr@monstr.eu> --- v2: Move lowlevel_init.S from board to cpu folder Remove XPSS prefix Rename XSCUTIMER -> SCUTIMER Keep timer in zynq folder till ARM custodian comments it. --- arch/arm/cpu/armv7/zynq/Makefile | 52 +++++++++++ arch/arm/cpu/armv7/zynq/lowlevel_init.S | 27 ++++++ arch/arm/cpu/armv7/zynq/timer.c | 151 +++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+), 0 deletions(-) create mode 100644 arch/arm/cpu/armv7/zynq/Makefile create mode 100644 arch/arm/cpu/armv7/zynq/lowlevel_init.S create mode 100644 arch/arm/cpu/armv7/zynq/timer.c