@@ -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
@@ -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)
@@ -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)
@@ -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
@@ -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
+
/****************************************************************************/
/*
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+
/* ------------------------------------------------------------------------- */
@@ -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
Initial work in preperation for generic board init for the SPARC architecture. Signed-off-by: Francois Retief <fgretief@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(-) -- 1.9.3