[U-Boot] [PATCH v2 04/10] sparc: Initial work for generic board-init
Francois Retief
fgretief at spaceteq.co.za
Wed Nov 5 13:08:17 CET 2014
Initial work in preperation for generic board init for the SPARC
architecture.
Signed-off-by: Francois Retief <fgretief at spaceteq.co.za>
---
Changes in v2: None
arch/sparc/config.mk | 3 +++
arch/sparc/cpu/leon2/cpu.c | 23 ++++++++++++++++
arch/sparc/cpu/leon3/cpu.c | 23 ++++++++++++++++
arch/sparc/cpu/leon3/cpu_init.c | 57 +++++++++++++++++++++++++++++++++++++++
arch/sparc/cpu/leon3/interrupts.c | 14 ++++++++++
arch/sparc/include/asm/config.h | 1 +
arch/sparc/include/asm/u-boot.h | 7 +++++
arch/sparc/lib/Makefile | 7 ++++-
arch/sparc/lib/interrupts.c | 7 +++++
arch/sparc/lib/time.c | 5 ++++
common/board_f.c | 2 +-
11 files changed, 147 insertions(+), 2 deletions(-)
diff --git a/arch/sparc/config.mk b/arch/sparc/config.mk
index d615f29..6d342a1 100644
--- a/arch/sparc/config.mk
+++ b/arch/sparc/config.mk
@@ -17,3 +17,6 @@ CONFIG_STANDALONE_LOAD_ADDR ?= 0x00000000 -L $(gcclibdir) \
PLATFORM_CPPFLAGS += -D__sparc__
PLATFORM_RELFLAGS += -fPIC
+
+# Support generic board on SPARC
+__HAVE_ARCH_GENERIC_BOARD := y
diff --git a/arch/sparc/cpu/leon2/cpu.c b/arch/sparc/cpu/leon2/cpu.c
index 380c397..d1c804e 100644
--- a/arch/sparc/cpu/leon2/cpu.c
+++ b/arch/sparc/cpu/leon2/cpu.c
@@ -15,6 +15,17 @@ DECLARE_GLOBAL_DATA_PTR;
extern void _reset_reloc(void);
+int arch_cpu_init(void)
+{
+ gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
+ gd->bus_clk = CONFIG_SYS_CLK_FREQ;
+ gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+
+ return 0;
+}
+
+#ifndef CONFIG_SYS_GENERIC_BOARD
+
int checkcpu(void)
{
/* check LEON version here */
@@ -22,6 +33,18 @@ int checkcpu(void)
return 0;
}
+#endif
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+
+int print_cpuinfo(void)
+{
+ printf("CPU: LEON2\n");
+ return 0;
+}
+
+#endif
+
/* ------------------------------------------------------------------------- */
void cpu_reset(void)
diff --git a/arch/sparc/cpu/leon3/cpu.c b/arch/sparc/cpu/leon3/cpu.c
index 8ab3150..5786751 100644
--- a/arch/sparc/cpu/leon3/cpu.c
+++ b/arch/sparc/cpu/leon3/cpu.c
@@ -18,6 +18,17 @@ DECLARE_GLOBAL_DATA_PTR;
extern void _reset_reloc(void);
+int arch_cpu_init(void)
+{
+ gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
+ gd->bus_clk = CONFIG_SYS_CLK_FREQ;
+ gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+
+ return 0;
+}
+
+#ifndef CONFIG_SYS_GENERIC_BOARD
+
int checkcpu(void)
{
/* check LEON version here */
@@ -25,6 +36,18 @@ int checkcpu(void)
return 0;
}
+#endif
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+
+int print_cpuinfo(void)
+{
+ printf("CPU: LEON3\n");
+ return 0;
+}
+
+#endif
+
/* ------------------------------------------------------------------------- */
void cpu_reset(void)
diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c
index 2f41d88..1144610 100644
--- a/arch/sparc/cpu/leon3/cpu_init.c
+++ b/arch/sparc/cpu/leon3/cpu_init.c
@@ -94,11 +94,17 @@ void cpu_init_f(void)
/* cache */
}
+#ifndef CONFIG_SYS_GENERIC_BOARD
+
void cpu_init_f2(void)
{
}
+#endif
+
+#ifndef CONFIG_SYS_GENERIC_BOARD
+
/*
* initialize higher level parts of CPU like time base and timers
*/
@@ -128,6 +134,8 @@ int cpu_init_r(void)
return (0);
}
+#endif
+
/* find & setup memory controller */
int init_memory_ctrl()
{
@@ -196,6 +204,8 @@ int init_memory_ctrl()
return not_found_mctrl;
}
+#ifndef CONFIG_SYS_GENERIC_BOARD
+
/* Uses Timer 0 to get accurate
* pauses. Max 2 raised to 32 ticks
*
@@ -206,6 +216,10 @@ void cpu_wait_ticks(unsigned long ticks)
while (get_timer(start) < ticks) ;
}
+#endif
+
+#ifndef CONFIG_SYS_GENERIC_BOARD
+
/* initiate and setup timer0 interrupt to configured HZ. Base clock is 1MHz.
* Return irq number for timer int or a negative number for
* dealing with self
@@ -222,11 +236,14 @@ int timer_interrupt_init_cpu(void)
return gptimer_irq;
}
+#endif
+
ulong get_tbclk(void)
{
return TIMER_BASE_CLK;
}
+#ifndef CONFIG_SYS_GENERIC_BOARD
/*
* This function is intended for SHORT delays only.
*/
@@ -241,3 +258,43 @@ unsigned long cpu_ticks2usec(unsigned long ticks)
{
return ticks * US_PER_TICK;
}
+
+#endif
+
+#ifdef CONFIG_SYS_GENERIC_BOARD
+
+static ambapp_dev_gptimer_element *tmr = NULL;
+
+int timer_init(void)
+{
+ ambapp_apbdev apbdev;
+
+ if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_GPTIMER, &apbdev) != 1) {
+ printf("%s: gptimer not found!\n", __func__);
+ return 1;
+ }
+ gptimer = (ambapp_dev_gptimer *) apbdev.address;
+ gptimer_irq = apbdev.irq;
+
+ /* initialize prescaler common to all timers to 1MHz */
+ gptimer->scalar = gptimer->scalar_reload =
+ (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1;
+
+ tmr = (ambapp_dev_gptimer_element *)&gptimer->e[0]; /* user timer 0 */
+
+ tmr->val = 0;
+ tmr->rld = ~0;
+ tmr->ctrl = LEON3_GPTIMER_EN | LEON3_GPTIMER_RL | LEON3_GPTIMER_LD;
+
+ return 0;
+}
+
+unsigned long timer_read_counter(void)
+{
+ if (tmr == NULL && timer_init())
+ return 0;
+
+ return ~tmr->val;
+}
+
+#endif
diff --git a/arch/sparc/cpu/leon3/interrupts.c b/arch/sparc/cpu/leon3/interrupts.c
index a834aa0..20e295c 100644
--- a/arch/sparc/cpu/leon3/interrupts.c
+++ b/arch/sparc/cpu/leon3/interrupts.c
@@ -116,12 +116,24 @@ void leon3_force_int(int irq)
int interrupt_init_cpu(void)
{
+#ifdef CONFIG_SYS_GENERIC_BOARD
+ ambapp_apbdev apbdev;
+
+ /*
+ * Find AMBA APB IRQMP Controller,
+ * When we come so far we know there is a IRQMP available
+ */
+ ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev);
+ irqmp = (ambapp_dev_irqmp *) apbdev.address;
+#endif
return (0);
}
/****************************************************************************/
+#ifndef CONFIG_SYS_GENERIC_BOARD
+
/* Handle Timer 0 IRQ */
void timer_interrupt_cpu(void *arg)
{
@@ -132,6 +144,8 @@ void timer_interrupt_cpu(void *arg)
return;
}
+#endif
+
/****************************************************************************/
/*
diff --git a/arch/sparc/include/asm/config.h b/arch/sparc/include/asm/config.h
index fd0b551..66cde58 100644
--- a/arch/sparc/include/asm/config.h
+++ b/arch/sparc/include/asm/config.h
@@ -8,6 +8,7 @@
#define _ASM_CONFIG_H_
#define CONFIG_NEEDS_MANUAL_RELOC
+#define CONFIG_SYS_GENERIC_GLOBAL_DATA
#define CONFIG_LMB
#define CONFIG_SYS_BOOT_RAMDISK_HIGH
diff --git a/arch/sparc/include/asm/u-boot.h b/arch/sparc/include/asm/u-boot.h
index 5f12e58..4c4b5f2 100644
--- a/arch/sparc/include/asm/u-boot.h
+++ b/arch/sparc/include/asm/u-boot.h
@@ -17,6 +17,11 @@
#ifndef __U_BOOT_H__
#define __U_BOOT_H__
+#ifdef CONFIG_SYS_GENERIC_BOARD
+/* Use the generic board which requires a unified bd_info */
+#include <asm-generic/u-boot.h>
+#else
+
/*
* Currently, this Board information is not passed to
* Linux kernel from U-Boot, but may be passed to other
@@ -44,6 +49,8 @@ typedef struct bd_info {
#endif /* __ASSEMBLY__ */
+#endif /* !CONFIG_SYS_GENERIC_BOARD */
+
/* For image.h:image_check_target_arch() */
#define IH_ARCH_DEFAULT IH_ARCH_SPARC
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index e69b9ba..84c3ac2 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -5,5 +5,10 @@
# SPDX-License-Identifier: GPL-2.0+
#
-obj-y = board.o cache.o interrupts.o time.o
+obj-y = cache.o interrupts.o time.o
+
obj-$(CONFIG_CMD_BOOTM) += bootm.o
+
+ifndef CONFIG_SYS_GENERIC_BOARD
+obj-y += board.o
+endif
diff --git a/arch/sparc/lib/interrupts.c b/arch/sparc/lib/interrupts.c
index b7c3993..93479a9 100644
--- a/arch/sparc/lib/interrupts.c
+++ b/arch/sparc/lib/interrupts.c
@@ -17,8 +17,11 @@
/* Implemented by SPARC CPUs */
extern int interrupt_init_cpu(void);
+
+#ifndef CONFIG_SYS_GENERIC_BOARD
extern void timer_interrupt_cpu(void *arg);
extern int timer_interrupt_init_cpu(void);
+#endif
int intLock(void)
{
@@ -60,6 +63,8 @@ int interrupt_init(void)
return ret;
}
+#ifndef CONFIG_SYS_GENERIC_BOARD
+
/* timer interrupt/overflow counter */
static volatile ulong timestamp = 0;
@@ -94,3 +99,5 @@ void timer_interrupt_init(void)
/* register interrupt handler for timer */
irq_install_handler(irq, (void (*)(void *))timer_interrupt, NULL);
}
+
+#endif
diff --git a/arch/sparc/lib/time.c b/arch/sparc/lib/time.c
index 50a09ad..257b41b 100644
--- a/arch/sparc/lib/time.c
+++ b/arch/sparc/lib/time.c
@@ -10,6 +10,8 @@
#include <common.h>
+#ifndef CONFIG_SYS_GENERIC_BOARD
+
/* Implemented by SPARC CPUs */
extern void cpu_wait_ticks(unsigned long ticks);
extern unsigned long cpu_usec2ticks(unsigned long usec);
@@ -32,6 +34,7 @@ unsigned long usec2ticks(unsigned long usec)
/* ------------------------------------------------------------------------- */
+
/*
* We implement the delay by converting the delay (the number of
* microseconds to wait) into a number of time base ticks; then we
@@ -59,4 +62,6 @@ int init_timebase(void)
return (0);
}
+#endif
+
/* ------------------------------------------------------------------------- */
diff --git a/common/board_f.c b/common/board_f.c
index b5bebc9..c97a1f8 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -842,7 +842,7 @@ static init_fnc_t init_sequence_f[] = {
/* TODO: can we rename this to timer_init()? */
init_timebase,
#endif
-#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_BLACKFIN)
+#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_BLACKFIN) || defined(CONFIG_SPARC)
timer_init, /* initialize timer */
#endif
#ifdef CONFIG_SYS_ALLOC_DPRAM
--
1.9.3
________________________________
Disclaimer and confidentiality note – refer to our website for further details: www.spaceteq.co.za <http://www.spaceteq.co.za/home/emaildisclaimer/>
More information about the U-Boot
mailing list