diff mbox

[U-Boot,3/4,v3] arm: Support new Xilinx Zynq platform

Message ID 1347603816-24772-3-git-send-email-monstr@monstr.eu
State Accepted
Delegated to: Albert ARIBAUD
Headers show

Commit Message

Michal Simek Sept. 14, 2012, 6:23 a.m. UTC
Add timer driver.

Signed-off-by: Michal Simek <monstr@monstr.eu>
CC: Joe Hershberger <joe.hershberger@gmail.com>
CC: Marek Vasut <marex@denx.de>

---
v2: Move lowlevel_init.S from board to cpu folder
    Remove XPSS prefix
    Rename XSCUTIMER -> SCUTIMER

v3: Using clrsetbits_le32
    Fix compilation warning
    Move reset_cpu from board to cpu.c
    Move lowlevel_init to cpu.c
---
 arch/arm/cpu/armv7/zynq/Makefile |   51 +++++++++++++
 arch/arm/cpu/armv7/zynq/cpu.c    |   31 ++++++++
 arch/arm/cpu/armv7/zynq/timer.c  |  150 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 232 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/zynq/Makefile
 create mode 100644 arch/arm/cpu/armv7/zynq/cpu.c
 create mode 100644 arch/arm/cpu/armv7/zynq/timer.c

Comments

Marek Vasut Sept. 14, 2012, 7:50 a.m. UTC | #1
Dear Michal Simek,

> Add timer driver.
> 
> Signed-off-by: Michal Simek <monstr@monstr.eu>
> CC: Joe Hershberger <joe.hershberger@gmail.com>
> CC: Marek Vasut <marex@denx.de>
> 
> ---
> v2: Move lowlevel_init.S from board to cpu folder
>     Remove XPSS prefix
>     Rename XSCUTIMER -> SCUTIMER
> 
> v3: Using clrsetbits_le32
>     Fix compilation warning
>     Move reset_cpu from board to cpu.c
>     Move lowlevel_init to cpu.c

[...]

> +#include <common.h>
> +
> +inline void lowlevel_init(void) {}
> +
> +void reset_cpu(ulong addr)
> +{
> +	while (1)
> +		;
> +}

I wonder how useful such CPU is if simple endless loop restarts it ;-)

[...]

Acked-by: Marek Vasut <marex@denx.de>
Michal Simek Sept. 14, 2012, 8:10 a.m. UTC | #2
On 09/14/2012 09:50 AM, Marek Vasut wrote:
> Dear Michal Simek,
>
>> Add timer driver.
>>
>> Signed-off-by: Michal Simek <monstr@monstr.eu>
>> CC: Joe Hershberger <joe.hershberger@gmail.com>
>> CC: Marek Vasut <marex@denx.de>
>>
>> ---
>> v2: Move lowlevel_init.S from board to cpu folder
>>      Remove XPSS prefix
>>      Rename XSCUTIMER -> SCUTIMER
>>
>> v3: Using clrsetbits_le32
>>      Fix compilation warning
>>      Move reset_cpu from board to cpu.c
>>      Move lowlevel_init to cpu.c
>
> [...]
>
>> +#include <common.h>
>> +
>> +inline void lowlevel_init(void) {}
>> +
>> +void reset_cpu(ulong addr)
>> +{
>> +	while (1)
>> +		;
>> +}
>
> I wonder how useful such CPU is if simple endless loop restarts it ;-)

Don't be scared it will be fixed when slcr is ready.

Thanks,
Michal
Marek Vasut Sept. 14, 2012, 9:59 a.m. UTC | #3
Dear Michal Simek,

> On 09/14/2012 09:50 AM, Marek Vasut wrote:
> > Dear Michal Simek,
> > 
> >> Add timer driver.
> >> 
> >> Signed-off-by: Michal Simek <monstr@monstr.eu>
> >> CC: Joe Hershberger <joe.hershberger@gmail.com>
> >> CC: Marek Vasut <marex@denx.de>
> >> 
> >> ---
> >> v2: Move lowlevel_init.S from board to cpu folder
> >> 
> >>      Remove XPSS prefix
> >>      Rename XSCUTIMER -> SCUTIMER
> >> 
> >> v3: Using clrsetbits_le32
> >> 
> >>      Fix compilation warning
> >>      Move reset_cpu from board to cpu.c
> >>      Move lowlevel_init to cpu.c
> > 
> > [...]
> > 
> >> +#include <common.h>
> >> +
> >> +inline void lowlevel_init(void) {}
> >> +
> >> +void reset_cpu(ulong addr)
> >> +{
> >> +	while (1)
> >> +		;
> >> +}
> > 
> > I wonder how useful such CPU is if simple endless loop restarts it ;-)
> 
> Don't be scared it will be fixed when slcr is ready.

Nay, I was just rambling and giving you a bit of torture :-)

What's SLCR ?

> Thanks,
> Michal

Best regards,
Marek Vasut
Michal Simek Sept. 14, 2012, 10:42 a.m. UTC | #4
On 09/14/2012 11:59 AM, Marek Vasut wrote:
> Dear Michal Simek,
>
>> On 09/14/2012 09:50 AM, Marek Vasut wrote:
>>> Dear Michal Simek,
>>>
>>>> Add timer driver.
>>>>
>>>> Signed-off-by: Michal Simek <monstr@monstr.eu>
>>>> CC: Joe Hershberger <joe.hershberger@gmail.com>
>>>> CC: Marek Vasut <marex@denx.de>
>>>>
>>>> ---
>>>> v2: Move lowlevel_init.S from board to cpu folder
>>>>
>>>>       Remove XPSS prefix
>>>>       Rename XSCUTIMER -> SCUTIMER
>>>>
>>>> v3: Using clrsetbits_le32
>>>>
>>>>       Fix compilation warning
>>>>       Move reset_cpu from board to cpu.c
>>>>       Move lowlevel_init to cpu.c
>>>
>>> [...]
>>>
>>>> +#include <common.h>
>>>> +
>>>> +inline void lowlevel_init(void) {}
>>>> +
>>>> +void reset_cpu(ulong addr)
>>>> +{
>>>> +	while (1)
>>>> +		;
>>>> +}
>>>
>>> I wonder how useful such CPU is if simple endless loop restarts it ;-)
>>
>> Don't be scared it will be fixed when slcr is ready.
>
> Nay, I was just rambling and giving you a bit of torture :-)

:-)

>
> What's SLCR ?

System level control registers. For example for clock setup, unit reset, ddr setup
configuration pin setup, etc.

Thanks,
Michal
Marek Vasut Sept. 14, 2012, 10:58 a.m. UTC | #5
Dear Michal Simek,

> On 09/14/2012 11:59 AM, Marek Vasut wrote:
> > Dear Michal Simek,
> > 
> >> On 09/14/2012 09:50 AM, Marek Vasut wrote:
> >>> Dear Michal Simek,
> >>> 
> >>>> Add timer driver.
> >>>> 
> >>>> Signed-off-by: Michal Simek <monstr@monstr.eu>
> >>>> CC: Joe Hershberger <joe.hershberger@gmail.com>
> >>>> CC: Marek Vasut <marex@denx.de>
> >>>> 
> >>>> ---
> >>>> v2: Move lowlevel_init.S from board to cpu folder
> >>>> 
> >>>>       Remove XPSS prefix
> >>>>       Rename XSCUTIMER -> SCUTIMER
> >>>> 
> >>>> v3: Using clrsetbits_le32
> >>>> 
> >>>>       Fix compilation warning
> >>>>       Move reset_cpu from board to cpu.c
> >>>>       Move lowlevel_init to cpu.c
> >>> 
> >>> [...]
> >>> 
> >>>> +#include <common.h>
> >>>> +
> >>>> +inline void lowlevel_init(void) {}
> >>>> +
> >>>> +void reset_cpu(ulong addr)
> >>>> +{
> >>>> +	while (1)
> >>>> +		;
> >>>> +}
> >>> 
> >>> I wonder how useful such CPU is if simple endless loop restarts it ;-)
> >> 
> >> Don't be scared it will be fixed when slcr is ready.
> > 
> > Nay, I was just rambling and giving you a bit of torture :-)
> :
> :-)
> :
> > What's SLCR ?
> 
> System level control registers. For example for clock setup, unit reset,
> ddr setup configuration pin setup, etc.

Shouldn't that be part of this patchset then?

> 
> Thanks,
> Michal

Best regards,
Marek Vasut
Michal Simek Sept. 14, 2012, 11:09 a.m. UTC | #6
On 09/14/2012 12:58 PM, Marek Vasut wrote:
> Dear Michal Simek,
>
>> On 09/14/2012 11:59 AM, Marek Vasut wrote:
>>> Dear Michal Simek,
>>>
>>>> On 09/14/2012 09:50 AM, Marek Vasut wrote:
>>>>> Dear Michal Simek,
>>>>>
>>>>>> Add timer driver.
>>>>>>
>>>>>> Signed-off-by: Michal Simek <monstr@monstr.eu>
>>>>>> CC: Joe Hershberger <joe.hershberger@gmail.com>
>>>>>> CC: Marek Vasut <marex@denx.de>
>>>>>>
>>>>>> ---
>>>>>> v2: Move lowlevel_init.S from board to cpu folder
>>>>>>
>>>>>>        Remove XPSS prefix
>>>>>>        Rename XSCUTIMER -> SCUTIMER
>>>>>>
>>>>>> v3: Using clrsetbits_le32
>>>>>>
>>>>>>        Fix compilation warning
>>>>>>        Move reset_cpu from board to cpu.c
>>>>>>        Move lowlevel_init to cpu.c
>>>>>
>>>>> [...]
>>>>>
>>>>>> +#include <common.h>
>>>>>> +
>>>>>> +inline void lowlevel_init(void) {}
>>>>>> +
>>>>>> +void reset_cpu(ulong addr)
>>>>>> +{
>>>>>> +	while (1)
>>>>>> +		;
>>>>>> +}
>>>>>
>>>>> I wonder how useful such CPU is if simple endless loop restarts it ;-)
>>>>
>>>> Don't be scared it will be fixed when slcr is ready.
>>>
>>> Nay, I was just rambling and giving you a bit of torture :-)
>> :
>> :-)
>> :
>>> What's SLCR ?
>>
>> System level control registers. For example for clock setup, unit reset,
>> ddr setup configuration pin setup, etc.
>
> Shouldn't that be part of this patchset then?

No. Basic setup is done in first stage bootloader. I will talk with
Xilinx how to handle this. I think that special driver(in zynq cpu folder)
for slcr make sense to have all SLCR operation at one place and not
to call it directly.

Thanks,
Michal
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/zynq/Makefile b/arch/arm/cpu/armv7/zynq/Makefile
new file mode 100644
index 0000000..499ace4
--- /dev/null
+++ b/arch/arm/cpu/armv7/zynq/Makefile
@@ -0,0 +1,51 @@ 
+#
+# (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
+
+COBJS-y	:= timer.o
+COBJS-y	+= cpu.o
+
+COBJS	:= $(COBJS-y)
+
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(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/cpu.c b/arch/arm/cpu/armv7/zynq/cpu.c
new file mode 100644
index 0000000..ab615cc
--- /dev/null
+++ b/arch/arm/cpu/armv7/zynq/cpu.c
@@ -0,0 +1,31 @@ 
+/*
+ * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2012 Xilinx, Inc. All rights reserved.
+ *
+ * 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>
+
+inline void lowlevel_init(void) {}
+
+void reset_cpu(ulong addr)
+{
+	while (1)
+		;
+}
diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/cpu/armv7/zynq/timer.c
new file mode 100644
index 0000000..323e7b5
--- /dev/null
+++ b/arch/arm/cpu/armv7/zynq/timer.c
@@ -0,0 +1,150 @@ 
+/*
+ * 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 =
+			      (struct scu_timer *) 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)
+{
+	const u32 emask = SCUTIMER_CONTROL_AUTO_RELOAD_MASK |
+			(TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) |
+			SCUTIMER_CONTROL_ENABLE_MASK;
+
+	/* Load the timer counter register */
+	writel(0xFFFFFFFF, &timer_base->counter);
+
+	/*
+	 * Start the A9Timer device
+	 * Enable Auto reload mode, Clear prescaler control bits
+	 * Set prescaler value, Enable the decrementer
+	 */
+	clrsetbits_le32(&timer_base->control, SCUTIMER_CONTROL_PRESCALER_MASK,
+								emask);
+
+	/* 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;
+}