Initial work in preperation for generic board init for the SPARC architecture.
Signed-off-by: Francois Retief <fgret...@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/> _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot