[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