Patchwork [U-Boot,2/8,V2] add at91 SoC access with c structures

login
register
mail settings
Submitter Jens Scharsig
Date Jan. 16, 2010, 8:28 p.m.
Message ID <4B522177.3020701@scharsoft.de>
Download mbox | patch
Permalink /patch/71704/
State Accepted
Delegated to: Reinhard Meyer
Headers show

Comments

Jens Scharsig - Jan. 16, 2010, 8:28 p.m.
* add at91 soc to arm920t, needs to join at91rm9200 into at91 arch


Signed-off-by: Jens Scharsig <js_at_ng@scharsoft.de>
---
 cpu/arm920t/at91/Makefile        |   47 ++++++++++
 cpu/arm920t/at91/lowlevel_init.S |  177 ++++++++++++++++++++++++++++++++++++++
 cpu/arm920t/at91/reset.c         |   58 ++++++++++++
 cpu/arm920t/at91/timer.c         |  166 +++++++++++++++++++++++++++++++++++
 4 files changed, 448 insertions(+), 0 deletions(-)
 create mode 100644 cpu/arm920t/at91/Makefile
 create mode 100644 cpu/arm920t/at91/lowlevel_init.S
 create mode 100644 cpu/arm920t/at91/reset.c
 create mode 100644 cpu/arm920t/at91/timer.c

Patch

diff --git a/cpu/arm920t/at91/Makefile b/cpu/arm920t/at91/Makefile
new file mode 100644
index 0000000..6e683f6
--- /dev/null
+++ b/cpu/arm920t/at91/Makefile
@@ -0,0 +1,47 @@ 
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@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).a
+
+SOBJS	+= lowlevel_init.o
+COBJS	+= reset.o
+COBJS	+= timer.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm920t/at91/lowlevel_init.S b/cpu/arm920t/at91/lowlevel_init.S
new file mode 100644
index 0000000..8e081dc
--- /dev/null
+++ b/cpu/arm920t/at91/lowlevel_init.S
@@ -0,0 +1,177 @@ 
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
+ *		       Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
+ *
+ * Modified for the at91rm9200dk board by
+ * (C) Copyright 2004
+ * Gary Jennejohn, DENX Software Engineering, <garyj@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 <config.h>
+#include <version.h>
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+
+#define AT91_PMC_MOR		0xFFFFFC20 	/* Main oscillator register */
+#define AT91_PMC_PLLAR		0xFFFFFC28
+#define AT91_PMC_PLLBR		0xFFFFFC2C
+#define AT91_PMC_MCKR		0xFFFFFC30
+
+#define AT91_PIOC_ASR		0xFFFFF870
+#define AT91_PIOC_BSR		0xFFFFF874
+#define AT91_PIOC_PDR		0xFFFFF804
+
+#define AT91_MC_EBI_CSA		0xFFFFFF60
+#define AT91_MC_EBI_CFG		0xFFFFFF64
+#define AT91_MC_SMC_CSR0	0xFFFFFF70
+
+#define AT91_MC_SDRAMC_MR	0xFFFFFF90
+#define AT91_MC_SDRAMC_TR	0xFFFFFF94
+#define AT91_MC_SDRAMC_CR	0xFFFFFF98
+
+_MTEXT_BASE:
+#undef START_FROM_MEM
+#ifdef START_FROM_MEM
+	.word	TEXT_BASE-PHYS_FLASH_1
+#else
+	.word	TEXT_BASE
+#endif
+
+.globl lowlevel_init
+lowlevel_init:
+	ldr     r1, =AT91_PMC_MOR
+	/* Main oscillator Enable register */
+#ifdef CONFIG_SYS_USE_MAIN_OSCILLATOR
+	ldr     r0, =0x0000FF01		/* Enable main oscillator,  OSCOUNT = 0xFF */
+#else
+	ldr     r0, =0x0000FF00		/* Disable main oscillator, OSCOUNT = 0xFF */
+#endif
+	str     r0, [r1] /*AT91C_CKGR_MOR] */
+	/* Add loop to compensate Main Oscillator startup time */
+	ldr     r0, =0x00000010
+LoopOsc:
+	subs    r0, r0, #1
+	bhi     LoopOsc
+
+	/* memory control configuration */
+	/* this isn't very elegant, but	 what the heck */
+	ldr	r0, =SMRDATA
+	ldr	r1, _MTEXT_BASE
+	sub	r0, r0, r1
+	add	r2, r0, #80
+0:
+	/* the address */
+	ldr	r1, [r0], #4
+	/* the value */
+	ldr	r3, [r0], #4
+	str	r3, [r1]
+	cmp	r2, r0
+	bne	0b
+	/* delay - this is all done by guess */
+	ldr	r0, =0x00010000
+	/* (vs reading PMC_SR for LOCKA, LOCKB ... or MOSCS earlier) */
+1:
+	subs	r0, r0, #1
+	bhi	1b
+	ldr	r0, =SMRDATA1
+	ldr	r1, _MTEXT_BASE
+	sub	r0, r0, r1
+	add	r2, r0, #176
+2:
+	/* the address */
+	ldr	r1, [r0], #4
+	/* the value */
+	ldr	r3, [r0], #4
+	str	r3, [r1]
+	cmp	r2, r0
+	bne	2b
+
+	/* switch from FastBus to Asynchronous clock mode */
+	mrc	p15, 0, r0, c1, c0, 0
+	orr	r0, r0, #0xC0000000	@ set bit 31 (iA) and 30 (nF)
+	mcr	p15, 0, r0, c1, c0, 0
+
+	/* everything is fine now */
+	mov	pc, lr
+
+	.ltorg
+
+SMRDATA:
+	.word AT91_MC_EBI_CFG
+	.word CONFIG_SYS_EBI_CFGR_VAL
+	.word AT91_MC_SMC_CSR0
+	.word CONFIG_SYS_SMC_CSR0_VAL
+	.word AT91_PMC_PLLAR
+	.word CONFIG_SYS_PLLAR_VAL
+	.word AT91_PMC_PLLBR
+	.word CONFIG_SYS_PLLBR_VAL
+	.word AT91_PMC_MCKR
+	.word CONFIG_SYS_MCKR_VAL
+	/* here there's a delay */
+SMRDATA1:
+	.word AT91_PIOC_ASR
+	.word CONFIG_SYS_PIOC_ASR_VAL
+	.word AT91_PIOC_BSR
+	.word CONFIG_SYS_PIOC_BSR_VAL
+	.word AT91_PIOC_PDR
+	.word CONFIG_SYS_PIOC_PDR_VAL
+	.word AT91_MC_EBI_CSA
+	.word CONFIG_SYS_EBI_CSA_VAL
+	.word AT91_MC_SDRAMC_CR
+	.word CONFIG_SYS_SDRC_CR_VAL
+	.word AT91_MC_SDRAMC_MR
+	.word CONFIG_SYS_SDRC_MR_VAL
+	.word CONFIG_SYS_SDRAM
+	.word CONFIG_SYS_SDRAM_VAL
+	.word AT91_MC_SDRAMC_MR
+	.word CONFIG_SYS_SDRC_MR_VAL1
+	.word CONFIG_SYS_SDRAM
+	.word CONFIG_SYS_SDRAM_VAL
+	.word CONFIG_SYS_SDRAM
+	.word CONFIG_SYS_SDRAM_VAL
+	.word CONFIG_SYS_SDRAM
+	.word CONFIG_SYS_SDRAM_VAL
+	.word CONFIG_SYS_SDRAM
+	.word CONFIG_SYS_SDRAM_VAL
+	.word CONFIG_SYS_SDRAM
+	.word CONFIG_SYS_SDRAM_VAL
+	.word CONFIG_SYS_SDRAM
+	.word CONFIG_SYS_SDRAM_VAL
+	.word CONFIG_SYS_SDRAM
+	.word CONFIG_SYS_SDRAM_VAL
+	.word CONFIG_SYS_SDRAM
+	.word CONFIG_SYS_SDRAM_VAL
+	.word AT91_MC_SDRAMC_MR
+	.word CONFIG_SYS_SDRC_MR_VAL2
+	.word CONFIG_SYS_SDRAM1
+	.word CONFIG_SYS_SDRAM_VAL
+	.word AT91_MC_SDRAMC_TR
+	.word CONFIG_SYS_SDRC_TR_VAL
+	.word CONFIG_SYS_SDRAM
+	.word CONFIG_SYS_SDRAM_VAL
+	.word AT91_MC_SDRAMC_MR
+	.word CONFIG_SYS_SDRC_MR_VAL3
+	.word CONFIG_SYS_SDRAM
+	.word CONFIG_SYS_SDRAM_VAL
+	/* SMRDATA1 is 176 bytes long */
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
diff --git a/cpu/arm920t/at91/reset.c b/cpu/arm920t/at91/reset.c
new file mode 100644
index 0000000..ab05167
--- /dev/null
+++ b/cpu/arm920t/at91/reset.c
@@ -0,0 +1,58 @@ 
+/*
+ * (C) Copyright 2002
+ * Lineo, Inc. <www.lineo.com>
+ * Bernhard Kuhn <bkuhn@lineo.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 <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/at91_st.h>
+
+void board_reset(void) __attribute__((__weak__));
+
+void reset_cpu (ulong ignored)
+{
+	at91_st_t *st = (at91_st_t *) AT91_ST_BASE;
+#if defined(CONFIG_AT91RM9200_USART) || defined(CONFIG_AT91_USART)
+	/*shutdown the console to avoid strange chars during reset */
+	serial_exit();
+#endif
+
+	if (board_reset)
+		board_reset();
+
+	/* Reset the cpu by setting up the watchdog timer */
+	writel(AT91_ST_WDMR_RSTEN | AT91_ST_WDMR_EXTEN | AT91_ST_WDMR_WDV(2),
+		&st->wdmr);
+	writel(AT91_ST_CR_WDRST, &st->cr);
+	/* and let him time out */
+	while (1);
+	/* Never reached */
+}
diff --git a/cpu/arm920t/at91/timer.c b/cpu/arm920t/at91/timer.c
new file mode 100644
index 0000000..ea7698a
--- /dev/null
+++ b/cpu/arm920t/at91/timer.c
@@ -0,0 +1,166 @@ 
+/*
+ * (C) Copyright 2002
+ * Lineo, Inc. <www.lineo.com>
+ * Bernhard Kuhn <bkuhn@lineo.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 <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/at91_tc.h>
+#include <asm/arch/at91_pmc.h>
+
+/* the number of clocks per CONFIG_SYS_HZ */
+#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ)
+
+/* macro to read the 16 bit timer */
+//#define READ_TIMER (tmr->TC_CV & 0x0000ffff)
+/*#AT91PS_TC tmr; */
+
+static u32 timestamp;
+static u32 lastinc;
+
+int timer_init (void)
+{
+	at91_tc_t *tc = (at91_tc_t *) AT91_TC_BASE;
+	at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
+
+	/* enables TC1.0 clock */
+	writel(1 << AT91_ID_TC0, &pmc->pcer);	/* enable clock */
+
+	writel(0, &tc->bcr);
+	writel(AT91_TC_BMR_TC0XC0S_NONE | AT91_TC_BMR_TC1XC1S_NONE |
+		AT91_TC_BMR_TC2XC2S_NONE , &tc->bmr);
+
+	writel(AT91_TC_CCR_CLKDIS, &tc->tc[0].ccr);
+	/* set to MCLK/2 and restart the timer when the vlaue in TC_RC is reached */
+	writel(AT91_TC_CMR_TCCLKS_CLOCK1 | AT91_TC_CMR_CPCTRG, &tc->tc[0].cmr);
+
+	writel(0xFFFFFFFF, &tc->tc[0].idr); /* disable interupts */
+	writel(TIMER_LOAD_VAL, &tc->tc[0].rc);
+
+	writel(AT91_TC_CCR_SWTRG | AT91_TC_CCR_CLKEN, &tc->tc[0].ccr);
+	lastinc = 0;
+	timestamp = 0;
+
+	return (0);
+}
+
+/*
+ * timer without interrupts
+ */
+
+void reset_timer (void)
+{
+	reset_timer_masked ();
+}
+
+ulong get_timer (ulong base)
+{
+	return get_timer_masked () - base;
+}
+
+void set_timer (ulong t)
+{
+	timestamp = t;
+}
+
+void __udelay (unsigned long usec)
+{
+	udelay_masked(usec);
+}
+
+void reset_timer_masked (void)
+{
+	/* reset time */
+	at91_tc_t *tc = (at91_tc_t *) AT91_TC_BASE;
+	lastinc = readl(&tc->tc[0].cv) & 0x0000ffff;
+	timestamp = 0;
+}
+
+ulong get_timer_raw (void)
+{
+	at91_tc_t *tc = (at91_tc_t *) AT91_TC_BASE;
+	u32 now;
+
+	now = readl(&tc->tc[0].cv) & 0x0000ffff;
+
+	if (now >= lastinc) {
+		/* normal mode */
+		timestamp += now - lastinc;
+	} else {
+		/* we have an overflow ... */
+		timestamp += now + TIMER_LOAD_VAL - lastinc;
+	}
+	lastinc = now;
+
+	return timestamp;
+}
+
+ulong get_timer_masked (void)
+{
+	return get_timer_raw()/TIMER_LOAD_VAL;
+}
+
+void udelay_masked (unsigned long usec)
+{
+	u32 tmo;
+	u32 endtime;
+	signed long diff;
+
+	tmo = CONFIG_SYS_HZ_CLOCK / 1000;
+	tmo *= usec;
+	tmo /= 1000;
+
+	endtime = get_timer_raw () + tmo;
+
+	do {
+		u32 now = get_timer_raw ();
+		diff = endtime - now;
+	} while (diff >= 0);
+}
+
+/*
+ * 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;
+}