diff options
Diffstat (limited to 'arch/sparc/cpu')
-rw-r--r-- | arch/sparc/cpu/leon2/cpu.c | 14 | ||||
-rw-r--r-- | arch/sparc/cpu/leon2/cpu_init.c | 94 | ||||
-rw-r--r-- | arch/sparc/cpu/leon2/interrupts.c | 14 | ||||
-rw-r--r-- | arch/sparc/cpu/leon2/prom.c | 2 | ||||
-rw-r--r-- | arch/sparc/cpu/leon2/serial.c | 2 | ||||
-rw-r--r-- | arch/sparc/cpu/leon2/start.S | 213 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/ambapp.c | 2 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/cpu.c | 60 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/cpu_init.c | 175 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/interrupts.c | 11 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/prom.c | 2 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/serial.c | 23 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/start.S | 303 | ||||
-rw-r--r-- | arch/sparc/cpu/leon3/usb_uhci.c | 7 |
14 files changed, 497 insertions, 425 deletions
diff --git a/arch/sparc/cpu/leon2/cpu.c b/arch/sparc/cpu/leon2/cpu.c index 380c397be04..d044c3abc72 100644 --- a/arch/sparc/cpu/leon2/cpu.c +++ b/arch/sparc/cpu/leon2/cpu.c @@ -1,7 +1,7 @@ /* CPU specific code for the LEON2 CPU * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com + * (C) Copyright 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com * * SPDX-License-Identifier: GPL-2.0+ */ @@ -22,6 +22,16 @@ int checkcpu(void) return 0; } +#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/leon2/cpu_init.c b/arch/sparc/cpu/leon2/cpu_init.c index 6e07fe6bb40..9dfb99cb0f7 100644 --- a/arch/sparc/cpu/leon2/cpu_init.c +++ b/arch/sparc/cpu/leon2/cpu_init.c @@ -1,8 +1,8 @@ /* Initializes CPU and basic hardware such as memory * controllers, IRQ controller and system timer 0. * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com + * (C) Copyright 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com * * SPDX-License-Identifier: GPL-2.0+ */ @@ -10,22 +10,12 @@ #include <common.h> #include <asm/asi.h> #include <asm/leon.h> +#include <asm/io.h> #include <config.h> -#define TIMER_BASE_CLK 1000000 -#define US_PER_TICK (1000000 / CONFIG_SYS_HZ) - DECLARE_GLOBAL_DATA_PTR; -/* reset CPU (jump to 0, without reset) */ -void start(void); - -struct { - gd_t gd_area; - bd_t bd; -} global_data; - /* * Breath some life into the CPU... * @@ -50,82 +40,56 @@ void cpu_init_f(void) /* cache */ - /* I/O port setup */ + /* I/O port setup */ #ifdef LEON2_IO_PORT_DIR - leon2->PIO_Direction = LEON2_IO_PORT_DIR; + leon2->PIO_Direction = LEON2_IO_PORT_DIR; #endif #ifdef LEON2_IO_PORT_DATA - leon2->PIO_Data = LEON2_IO_PORT_DATA; + leon2->PIO_Data = LEON2_IO_PORT_DATA; #endif #ifdef LEON2_IO_PORT_INT - leon2->PIO_Interrupt = LEON2_IO_PORT_INT; + leon2->PIO_Interrupt = LEON2_IO_PORT_INT; #else - leon2->PIO_Interrupt = 0; + leon2->PIO_Interrupt = 0; #endif + + /* disable timers */ + leon2->Timer_Control_1 = leon2->Timer_Control_2 = 0; } -void cpu_init_f2(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; } /* - * initialize higher level parts of CPU like time base and timers + * initialize higher level parts of CPU */ int cpu_init_r(void) { - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - - /* initialize prescaler common to all timers to 1MHz */ - leon2->Scaler_Counter = leon2->Scaler_Reload = - (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1; - - return (0); + return 0; } -/* Uses Timer 0 to get accurate - * pauses. Max 2 raised to 32 ticks - * +/* initiate and setup timer0 to configured HZ. Base clock is 1MHz. */ -void cpu_wait_ticks(unsigned long ticks) +int timer_init(void) { - unsigned long start = get_timer(0); - while (get_timer(start) < ticks) ; -} + LEON2_regs *leon2 = (LEON2_regs *)LEON2_PREGS; -/* 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 - */ -int timer_interrupt_init_cpu(void) -{ - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; + /* initialize prescaler common to all timers to 1MHz */ + leon2->Scaler_Counter = leon2->Scaler_Reload = + (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1; /* SYS_HZ ticks per second */ leon2->Timer_Counter_1 = 0; - leon2->Timer_Reload_1 = (TIMER_BASE_CLK / CONFIG_SYS_HZ) - 1; - leon2->Timer_Control_1 = - (LEON2_TIMER_CTRL_EN | LEON2_TIMER_CTRL_RS | LEON2_TIMER_CTRL_LD); - - return LEON2_TIMER1_IRQNO; -} - -ulong get_tbclk(void) -{ - return TIMER_BASE_CLK; -} + leon2->Timer_Reload_1 = (CONFIG_SYS_TIMER_RATE / CONFIG_SYS_HZ) - 1; + leon2->Timer_Control_1 = LEON2_TIMER_CTRL_EN | LEON2_TIMER_CTRL_RS | + LEON2_TIMER_CTRL_LD; -/* - * This function is intended for SHORT delays only. - */ -unsigned long cpu_usec2ticks(unsigned long usec) -{ - if (usec < US_PER_TICK) - return 1; - return usec / US_PER_TICK; -} - -unsigned long cpu_ticks2usec(unsigned long ticks) -{ - return ticks * US_PER_TICK; + CONFIG_SYS_TIMER_COUNTER = (void *)&leon2->Timer_Counter_1; + return 0; } diff --git a/arch/sparc/cpu/leon2/interrupts.c b/arch/sparc/cpu/leon2/interrupts.c index f78ec8a4109..602e4a67ba8 100644 --- a/arch/sparc/cpu/leon2/interrupts.c +++ b/arch/sparc/cpu/leon2/interrupts.c @@ -118,20 +118,6 @@ int interrupt_init_cpu(void) /****************************************************************************/ -/* Handle Timer 0 IRQ */ -void timer_interrupt_cpu(void *arg) -{ - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - - leon2->Timer_Control_1 = - (LEON2_TIMER_CTRL_EN | LEON2_TIMER_CTRL_RS | LEON2_TIMER_CTRL_LD); - - /* nothing to do here */ - return; -} - -/****************************************************************************/ - /* * Install and free a interrupt handler. */ diff --git a/arch/sparc/cpu/leon2/prom.c b/arch/sparc/cpu/leon2/prom.c index cd2571f0d6e..7829e7abb2e 100644 --- a/arch/sparc/cpu/leon2/prom.c +++ b/arch/sparc/cpu/leon2/prom.c @@ -25,6 +25,8 @@ extern struct linux_romvec *kernel_arg_promvec; #define PROM_TEXT __attribute__ ((__section__ (".prom.text"))) #define PROM_DATA __attribute__ ((__section__ (".prom.data"))) +void *__prom_start_reloc; /* relocated prom_start address */ + /* for __va */ extern int __prom_start; #define PAGE_OFFSET 0xf0000000 diff --git a/arch/sparc/cpu/leon2/serial.c b/arch/sparc/cpu/leon2/serial.c index 603364ee0bd..460abd1d9f5 100644 --- a/arch/sparc/cpu/leon2/serial.c +++ b/arch/sparc/cpu/leon2/serial.c @@ -120,7 +120,7 @@ static void leon2_serial_setbrg(void) if (!gd->baudrate) gd->baudrate = CONFIG_BAUDRATE; - scaler = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, CONFIG_BAUDRATE); + scaler = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, gd->baudrate); writel(scaler, &uart->UART_Scaler); } diff --git a/arch/sparc/cpu/leon2/start.S b/arch/sparc/cpu/leon2/start.S index 974de76852e..1b404da3629 100644 --- a/arch/sparc/cpu/leon2/start.S +++ b/arch/sparc/cpu/leon2/start.S @@ -1,6 +1,7 @@ /* This is where the SPARC/LEON3 starts - * Copyright (C) 2007, - * Daniel Hellstrom, daniel@gaisler.com + * + * Copyright (C) 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com * * SPDX-License-Identifier: GPL-2.0+ */ @@ -12,7 +13,6 @@ #include <asm/psr.h> #include <asm/stack.h> #include <asm/leon.h> -#include <version.h> /* Entry for traps which jump to a programmer-specified trap handler. */ #define TRAPR(H) \ @@ -197,14 +197,6 @@ _trap_table: SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f4-f7 SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f8-fb SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! fc-ff -/* - * Version string - */ - - .data - .globl version_string -version_string: - .ascii U_BOOT_VERSION_STRING, "\0" .section ".text" .align 4 @@ -318,30 +310,62 @@ leon2_init_stackp: andn %fp, 0x0f, %fp sub %fp, 64, %sp +leon2_init_tbr: + set CONFIG_SYS_TEXT_BASE, %g2 + wr %g0, %g2, %tbr + nop + nop + nop + cpu_init_unreloc: call cpu_init_f nop +board_init_unreloc: + call board_init_f + clr %o0 ! boot_flags + +dead_unreloc: + ba dead_unreloc ! infinte loop + nop + +!------------------------------------------------------------------------------- + +/* void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM after + * relocating the monitor code. + * + * %o0 = Relocated stack pointer + * %o1 = Relocated global data pointer + * %o2 = Relocated text pointer + */ + .globl relocate_code + .type relocate_code, #function + .align 4 +relocate_code: + SPARC_PIC_THUNK_CALL(l7) + /* un relocated start address of monitor */ #define TEXT_START _text /* un relocated end address of monitor */ #define DATA_END __init_end - SPARC_PIC_THUNK_CALL(l7) reloc: SPARC_LOAD_ADDRESS(TEXT_START, l7, g2) SPARC_LOAD_ADDRESS(DATA_END, l7, g3) - set CONFIG_SYS_RELOC_MONITOR_BASE,%g4 -reloc_loop: - ldd [%g2],%l0 - ldd [%g2+8],%l2 - std %l0,[%g4] - std %l2,[%g4+8] - inc 16,%g2 - subcc %g3,%g2,%g0 - bne reloc_loop - inc 16,%g4 + mov %o2, %g4 ! relocation address + sub %g4, %g2, %g6 ! relocation offset + /* copy .text & .data to relocated address */ +10: ldd [%g2], %l0 + ldd [%g2+8], %l2 + std %l0, [%g4] + std %l2, [%g4+8] + inc 16, %g2 ! src += 16 + cmp %g2, %g3 + bcs 10b ! while (src < end) + inc 16, %g4 ! dst += 16 clr %l0 clr %l1 @@ -356,91 +380,93 @@ reloc_loop: * */ + /* clear bss area (the relocated) */ clr_bss: -/* clear bss area (the relocated) */ SPARC_LOAD_ADDRESS(__bss_start, l7, g2) SPARC_LOAD_ADDRESS(__bss_end, l7, g3) - sub %g3,%g2,%g3 + sub %g3,%g2,%g3 ! length of .bss area add %g3,%g4,%g3 + /* clearing 16byte a time ==> linker script need to align to 16 byte offset */ clr %g1 /* std %g0 uses g0 and g1 */ -/* clearing 16byte a time ==> linker script need to align to 16 byte offset */ -clr_bss_16: - std %g0,[%g4] - std %g0,[%g4+8] - inc 16,%g4 - cmp %g3,%g4 - bne clr_bss_16 +20: + std %g0, [%g4] + std %g0, [%g4+8] + inc 16, %g4 ! ptr += 16 + cmp %g4, %g3 + bcs 20b ! while (ptr < end) nop -/* add offsets to GOT table */ + /* add offsets to GOT table */ fixup_got: SPARC_LOAD_ADDRESS(__got_start, l7, g4) + add %g4, %g6, %g4 SPARC_LOAD_ADDRESS(__got_end, l7, g3) -/* - * new got offset = (old GOT-PTR (read with ld) - - * CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) + - * Destination Address (from define) - */ - set CONFIG_SYS_RELOC_MONITOR_BASE,%g2 - SPARC_LOAD_ADDRESS(TEXT_START, l7, g1) - add %g4,%g2,%g4 - sub %g4,%g1,%g4 - add %g3,%g2,%g3 - sub %g3,%g1,%g3 - sub %g2,%g1,%g2 ! prepare register with (new base address) - - ! (old base address) -got_loop: - ld [%g4],%l0 ! load old GOT-PTR - add %l0,%g2,%l0 ! increase with (new base address) - - ! (old base) - st %l0,[%g4] - inc 4,%g4 - cmp %g3,%g4 - bne got_loop + add %g3, %g6, %g3 +30: ld [%g4], %l0 ! load old GOT-PTR +#ifdef CONFIG_RELOC_GOT_SKIP_NULL + cmp %l0, 0 + be 32f +#endif + add %l0, %g6, %l0 ! relocate GOT pointer + st %l0, [%g4] +32: inc 4, %g4 ! ptr += 4 + cmp %g4, %g3 + bcs 30b ! while (ptr < end) nop prom_relocate: SPARC_LOAD_ADDRESS(__prom_start, l7, g2) SPARC_LOAD_ADDRESS(__prom_end, l7, g3) - set CONFIG_SYS_PROM_OFFSET, %g4 - -prom_relocate_loop: - ldd [%g2],%l0 - ldd [%g2+8],%l2 - std %l0,[%g4] - std %l2,[%g4+8] - inc 16,%g2 - subcc %g3,%g2,%g0 - bne prom_relocate_loop - inc 16,%g4 + /* + * Calculated addres is stored in this variable by + * reserve_prom() function in common/board_f.c + */ + SPARC_LOAD_ADDRESS(__prom_start_reloc, l7, g4) + ld [%g4], %g4 + +40: ldd [%g2], %l0 + ldd [%g2+8], %l2 + std %l0, [%g4] + std %l2, [%g4+8] + inc 16, %g2 + cmp %g2, %g3 + bcs 40b + inc 16, %g4 + +! %o0 = stack pointer (relocated) +! %o1 = global data pointer (relocated) +! %o2 = text pointer (relocated) + +! %g6 = relocation offset +! %l7 = _GLOBAL_OFFSET_TABLE_ /* Trap table has been moved, lets tell CPU about * the new trap table address */ - - set CONFIG_SYS_RELOC_MONITOR_BASE, %g2 - wr %g0, %g2, %tbr - -/* call relocate*/ +update_trap_table_address: + wr %g0, %o2, %tbr + nop + nop nop -/* Call relocated init functions */ -jump: - SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1) - set CONFIG_SYS_RELOC_MONITOR_BASE,%o2 - add %o1,%o2,%o1 - sub %o1,%g1,%o1 - call %o1 - clr %o0 - SPARC_LOAD_ADDRESS(board_init_f, l7, o1) - set CONFIG_SYS_RELOC_MONITOR_BASE,%o2 - add %o1,%o2,%o1 - sub %o1,%g1,%o1 - call %o1 - clr %o0 +update_stack_pointers: + mov %o0, %fp + andn %fp, 0x0f, %fp ! align to 16 bytes + add %fp, -64, %fp ! make space for a window push + mov %fp, %sp ! setup stack pointer + +jump_board_init_r: + mov %o1, %o0 ! relocated global data pointer + mov %o2, %o1 ! relocated text pointer + SPARC_LOAD_ADDRESS(board_init_r, l7, o3) + add %o3, %g6, %o3 ! add relocation offset + call %o3 + nop dead: ta 0 ! if call returns... - nop + nop + +!------------------------------------------------------------------------------ /* Interrupt handler caller, * reg L7: interrupt number @@ -469,7 +495,11 @@ _irq_entry: RESTORE_ALL -!Window overflow trap handler. +!------------------------------------------------------------------------------ + +/* + * Window overflow trap handler. + */ .global _window_overflow _window_overflow: @@ -477,14 +507,12 @@ _window_overflow: mov %wim, %l3 ! Calculate next WIM mov %g1, %l7 srl %l3, 1, %g1 - sll %l3, (CONFIG_SYS_SPARC_NWINDOWS-1) , %l4 + sll %l3, (CONFIG_SYS_SPARC_NWINDOWS-1), %l4 or %l4, %g1, %g1 save ! Get into window to be saved. mov %g1, %wim - nop; - nop; - nop + nop; nop; nop st %l0, [%sp + 0]; st %l1, [%sp + 4]; st %l2, [%sp + 8]; @@ -506,8 +534,9 @@ _window_overflow: jmp %l1 ! Re-execute save. rett %l2 -/* Window underflow trap handler. */ - +/* + * Window underflow trap handler. + */ .global _window_underflow _window_underflow: @@ -541,7 +570,7 @@ _window_underflow: jmp %l1 ! Re-execute restore. rett %l2 - retl +!------------------------------------------------------------------------------ _nmi_trap: nop diff --git a/arch/sparc/cpu/leon3/ambapp.c b/arch/sparc/cpu/leon3/ambapp.c index b8ac05faf12..47769cffd70 100644 --- a/arch/sparc/cpu/leon3/ambapp.c +++ b/arch/sparc/cpu/leon3/ambapp.c @@ -40,7 +40,7 @@ extern int ambapp_find_ahb(struct ambapp_bus *abus, unsigned int dev_vend, int index, int type, struct ambapp_find_ahb_info *result); /************ C ROUTINES USED BY U-BOOT AMBA CORE DRIVERS ************/ -struct ambapp_bus ambapp_plb; +struct ambapp_bus ambapp_plb __section(.data); void ambapp_bus_init( unsigned int ioarea, diff --git a/arch/sparc/cpu/leon3/cpu.c b/arch/sparc/cpu/leon3/cpu.c index 8ab315016b6..149e5c69e63 100644 --- a/arch/sparc/cpu/leon3/cpu.c +++ b/arch/sparc/cpu/leon3/cpu.c @@ -1,7 +1,7 @@ /* CPU specific code for the LEON3 CPU * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com + * (C) Copyright 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com * * SPDX-License-Identifier: GPL-2.0+ */ @@ -13,18 +13,72 @@ #include <asm/io.h> #include <asm/processor.h> +#include <ambapp.h> DECLARE_GLOBAL_DATA_PTR; extern void _reset_reloc(void); +int leon_cpu_cnt = 1; +int leon_ver = 3; +unsigned int leon_cpu_freq = CONFIG_SYS_CLK_FREQ; + +int cpu_freq(void) +{ + ambapp_ahbdev dev; + + if (leon_ver == 3) { + ambapp_ahbmst_find(&ambapp_plb, VENDOR_GAISLER, + GAISLER_LEON3, 0, &dev); + } else { + ambapp_ahbmst_find(&ambapp_plb, VENDOR_GAISLER, + GAISLER_LEON4, 0, &dev); + } + + leon_cpu_freq = ambapp_bus_freq(&ambapp_plb, dev.ahb_bus_index); + + return 0; +} + int checkcpu(void) { + int cnt; + char str[4]; + /* check LEON version here */ - printf("CPU: LEON3\n"); + cnt = ambapp_ahbmst_count(&ambapp_plb, VENDOR_GAISLER, GAISLER_LEON3); + if (cnt <= 0) { + cnt = ambapp_ahbmst_count(&ambapp_plb, VENDOR_GAISLER, + GAISLER_LEON4); + if (cnt > 0) + leon_ver = 4; + } + + cpu_freq(); + + str[0] = '\0'; + if (cnt > 1) { + leon_cpu_cnt = cnt; + str[0] = '0' + cnt; + str[1] = 'x'; + str[2] = '\0'; + } + printf("CPU: %sLEON%d @ %dMHz\n", str, leon_ver, + leon_cpu_freq / 1000000); + return 0; } +#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 b140da31b13..f25388cf841 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -10,6 +10,7 @@ #include <common.h> #include <asm/asi.h> #include <asm/leon.h> +#include <asm/io.h> #include <ambapp.h> #include <grlib/irqmp.h> #include <grlib/gptimer.h> @@ -22,23 +23,14 @@ #define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA #endif -#define TIMER_BASE_CLK 1000000 -#define US_PER_TICK (1000000 / CONFIG_SYS_HZ) +/* Select which TIMER that will become the time base */ +#ifndef CONFIG_SYS_GRLIB_GPTIMER_INDEX +#define CONFIG_SYS_GRLIB_GPTIMER_INDEX 0 +#endif DECLARE_GLOBAL_DATA_PTR; -/* reset CPU (jump to 0, without reset) */ -void start(void); - ambapp_dev_irqmp *irqmp = NULL; -ambapp_dev_gptimer *gptimer = NULL; -unsigned int gptimer_irq = 0; -int leon3_snooping_avail = 0; - -struct { - gd_t gd_area; - bd_t bd; -} global_data; /* * Breath some life into the CPU... @@ -56,19 +48,62 @@ void cpu_init_f(void) #endif } -/* Routine called from start.S, - * - * Run from FLASH/PROM: - * - memory controller has already been setup up, stack can be used - * - global variables available for read/writing - * - constants avaiable - */ -void cpu_init_f2(void) +/* If cache snooping is available in hardware the result will be set + * to 0x800000, otherwise 0. + */ +static unsigned int snoop_detect(void) { + unsigned int result; + asm("lda [%%g0] 2, %0" : "=r"(result)); + return result & 0x00800000; +} + +int arch_cpu_init(void) +{ + ambapp_apbdev apbdev; + int index; + + gd->cpu_clk = CONFIG_SYS_CLK_FREQ; + gd->bus_clk = CONFIG_SYS_CLK_FREQ; + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + + gd->arch.snooping_available = snoop_detect(); + /* Initialize the AMBA Plug & Play bus structure, the bus * structure represents the AMBA bus that the CPU is located at. */ ambapp_bus_init(CONFIG_AMBAPP_IOAREA, CONFIG_SYS_CLK_FREQ, &ambapp_plb); + + /* Initialize/clear all the timers in the system. + */ + for (index = 0; ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, + GAISLER_GPTIMER, index, &apbdev) == 1; index++) { + ambapp_dev_gptimer *timer; + unsigned int bus_freq; + int i, ntimers; + + timer = (ambapp_dev_gptimer *)apbdev.address; + + /* Different buses may have different frequency, the + * frequency of the bus tell in which frequency the timer + * prescaler operates. + */ + bus_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index); + + /* Initialize prescaler common to all timers to 1MHz */ + timer->scalar = timer->scalar_reload = + (((bus_freq / 1000) + 500) / 1000) - 1; + + /* Clear all timers */ + ntimers = timer->config & 0x7; + for (i = 0; i < ntimers; i++) { + timer->e[i].ctrl = GPTIMER_CTRL_IP; + timer->e[i].rld = 0; + timer->e[i].ctrl = GPTIMER_CTRL_LD; + } + } + + return 0; } /* @@ -77,9 +112,7 @@ void cpu_init_f2(void) int cpu_init_r(void) { ambapp_apbdev apbdev; - int index, cpu; - ambapp_dev_gptimer *timer = NULL; - unsigned int bus_freq; + int cpu; /* * Find AMBA APB IRQMP Controller, @@ -102,77 +135,41 @@ int cpu_init_r(void) irqmp->cpu_force[cpu] = 0; } - /* timer */ - index = 0; - while (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_GPTIMER, - index, &apbdev) == 1) { - timer = (ambapp_dev_gptimer *)apbdev.address; - if (gptimer == NULL) { - gptimer = timer; - gptimer_irq = apbdev.irq; - } - - /* Different buses may have different frequency, the - * frequency of the bus tell in which frequency the timer - * prescaler operates. - */ - bus_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index); - - /* initialize prescaler common to all timers to 1MHz */ - timer->scalar = timer->scalar_reload = - (((bus_freq / 1000) + 500) / 1000) - 1; - - index++; - } - if (!gptimer) { - printf("%s: gptimer not found!\n", __func__); - return 1; - } return 0; } -/* Uses Timer 0 to get accurate - * pauses. Max 2 raised to 32 ticks - * - */ -void cpu_wait_ticks(unsigned long ticks) + ; +int timer_init(void) { - unsigned long start = get_timer(0); - while (get_timer(start) < ticks) ; -} + ambapp_dev_gptimer_element *tmr; + ambapp_dev_gptimer *gptimer; + ambapp_apbdev apbdev; + unsigned bus_freq; -/* 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 - */ -int timer_interrupt_init_cpu(void) -{ - /* SYS_HZ ticks per second */ - gptimer->e[0].val = 0; - gptimer->e[0].rld = (TIMER_BASE_CLK / CONFIG_SYS_HZ) - 1; - gptimer->e[0].ctrl = - (GPTIMER_CTRL_EN | GPTIMER_CTRL_RS | - GPTIMER_CTRL_LD | GPTIMER_CTRL_IE); - - return gptimer_irq; -} + if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_GPTIMER, + CONFIG_SYS_GRLIB_GPTIMER_INDEX, &apbdev) != 1) { + panic("%s: gptimer not found!\n", __func__); + return -1; + } -ulong get_tbclk(void) -{ - return TIMER_BASE_CLK; -} + gptimer = (ambapp_dev_gptimer *) apbdev.address; -/* - * This function is intended for SHORT delays only. - */ -unsigned long cpu_usec2ticks(unsigned long usec) -{ - if (usec < US_PER_TICK) - return 1; - return usec / US_PER_TICK; -} + /* Different buses may have different frequency, the + * frequency of the bus tell in which frequency the timer + * prescaler operates. + */ + bus_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index); -unsigned long cpu_ticks2usec(unsigned long ticks) -{ - return ticks * US_PER_TICK; + /* initialize prescaler common to all timers to 1MHz */ + gptimer->scalar = gptimer->scalar_reload = + (((bus_freq / 1000) + 500) / 1000) - 1; + + tmr = (ambapp_dev_gptimer_element *)&gptimer->e[0]; + + tmr->val = 0; + tmr->rld = ~0; + tmr->ctrl = GPTIMER_CTRL_EN | GPTIMER_CTRL_RS | GPTIMER_CTRL_LD; + + CONFIG_SYS_TIMER_COUNTER = (void *)&tmr->val; + return 0; } diff --git a/arch/sparc/cpu/leon3/interrupts.c b/arch/sparc/cpu/leon3/interrupts.c index 2312b58d29b..00c3288774f 100644 --- a/arch/sparc/cpu/leon3/interrupts.c +++ b/arch/sparc/cpu/leon3/interrupts.c @@ -124,17 +124,6 @@ int interrupt_init_cpu(void) /****************************************************************************/ -/* Handle Timer 0 IRQ */ -void timer_interrupt_cpu(void *arg) -{ - gptimer->e[0].ctrl = (GPTIMER_CTRL_EN | GPTIMER_CTRL_RS | - GPTIMER_CTRL_LD | GPTIMER_CTRL_IE); - /* nothing to do here */ - return; -} - -/****************************************************************************/ - /* * Install and free a interrupt handler. */ diff --git a/arch/sparc/cpu/leon3/prom.c b/arch/sparc/cpu/leon3/prom.c index c391be7420c..1f185b776b4 100644 --- a/arch/sparc/cpu/leon3/prom.c +++ b/arch/sparc/cpu/leon3/prom.c @@ -33,6 +33,8 @@ DECLARE_GLOBAL_DATA_PTR; ambapp_dev_gptimer *gptimer; +void *__prom_start_reloc; /* relocated prom_start address */ + /* for __va */ extern int __prom_start; #define PAGE_OFFSET 0xf0000000 diff --git a/arch/sparc/cpu/leon3/serial.c b/arch/sparc/cpu/leon3/serial.c index 66b37730270..bc6e7a172e5 100644 --- a/arch/sparc/cpu/leon3/serial.c +++ b/arch/sparc/cpu/leon3/serial.c @@ -17,8 +17,18 @@ DECLARE_GLOBAL_DATA_PTR; /* Select which UART that will become u-boot console */ #ifndef CONFIG_SYS_GRLIB_APBUART_INDEX +/* Try to use CONFIG_CONS_INDEX, if available, it is numbered from 1 */ +#ifdef CONFIG_CONS_INDEX +#define CONFIG_SYS_GRLIB_APBUART_INDEX (CONFIG_CONS_INDEX - 1) +#else #define CONFIG_SYS_GRLIB_APBUART_INDEX 0 #endif +#endif + +static unsigned apbuart_calc_scaler(unsigned apbuart_freq, unsigned baud) +{ + return (((apbuart_freq * 10) / (baud * 8)) - 5) / 10; +} static int leon3_serial_init(void) { @@ -29,6 +39,7 @@ static int leon3_serial_init(void) /* find UART */ if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_APBUART, CONFIG_SYS_GRLIB_APBUART_INDEX, &apbdev) != 1) { + gd->flags &= ~GD_FLG_SERIAL_READY; panic("%s: apbuart not found!\n", __func__); return -1; /* didn't find hardware */ } @@ -36,8 +47,11 @@ static int leon3_serial_init(void) /* found apbuart, let's init .. */ uart = (ambapp_dev_apbuart *) apbdev.address; + /* APBUART Frequency is equal to bus frequency */ + gd->arch.uart_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index); + /* Set scaler / baud rate */ - tmp = (((CONFIG_SYS_CLK_FREQ*10) / (CONFIG_BAUDRATE*8)) - 5)/10; + tmp = apbuart_calc_scaler(gd->arch.uart_freq, CONFIG_BAUDRATE); writel(tmp, &uart->scaler); /* Let bit 11 be unchanged (debug bit for GRMON) */ @@ -122,7 +136,10 @@ static void leon3_serial_setbrg(void) if (!gd->baudrate) gd->baudrate = CONFIG_BAUDRATE; - scaler = (((CONFIG_SYS_CLK_FREQ*10) / (gd->baudrate*8)) - 5)/10; + if (!gd->arch.uart_freq) + gd->arch.uart_freq = CONFIG_SYS_CLK_FREQ; + + scaler = apbuart_calc_scaler(gd->arch.uart_freq, gd->baudrate); writel(scaler, &uart->scaler); } @@ -155,7 +172,7 @@ __weak struct serial_device *default_serial_console(void) static inline void _debug_uart_init(void) { ambapp_dev_apbuart *uart = (ambapp_dev_apbuart *)CONFIG_DEBUG_UART_BASE; - uart->scaler = (((CONFIG_DEBUG_UART_CLOCK*10) / (CONFIG_BAUDRATE*8)) - 5)/10; + uart->scaler = apbuart_calc_scaler(CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE); uart->ctrl = APBUART_CTRL_RE | APBUART_CTRL_TE; } diff --git a/arch/sparc/cpu/leon3/start.S b/arch/sparc/cpu/leon3/start.S index 203114970b2..1527d72a6d7 100644 --- a/arch/sparc/cpu/leon3/start.S +++ b/arch/sparc/cpu/leon3/start.S @@ -1,6 +1,7 @@ /* This is where the SPARC/LEON3 starts - * Copyright (C) 2007, - * Daniel Hellstrom, daniel@gaisler.com + * + * Copyright (C) 2007, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com * * SPDX-License-Identifier: GPL-2.0+ */ @@ -12,7 +13,6 @@ #include <asm/psr.h> #include <asm/stack.h> #include <asm/leon.h> -#include <version.h> #include <ambapp.h> /* Default Plug&Play I/O area */ @@ -20,6 +20,11 @@ #define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA #endif +/* Default number of SPARC register windows */ +#ifndef CONFIG_SYS_SPARC_NWINDOWS +#define CONFIG_SYS_SPARC_NWINDOWS 8 +#endif + /* Entry for traps which jump to a programmer-specified trap handler. */ #define TRAPR(H) \ wr %g0, 0xfe0, %psr; \ @@ -203,15 +208,6 @@ _trap_table: SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f4-f7 SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f8-fb SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! fc-ff -/* - * Version string - */ - - .data - .extern leon3_snooping_avail - .globl version_string -version_string: - .ascii U_BOOT_VERSION_STRING, "\0" .section ".text" .extern _nomem_amba_init, _nomem_memory_ctrl_init @@ -261,11 +257,18 @@ wiminit: set WIM_INIT, %g3 mov %g3, %wim -stackp: +stackinit: set CONFIG_SYS_INIT_SP_OFFSET, %fp andn %fp, 0x0f, %fp sub %fp, 64, %sp +tbrinit: + set CONFIG_SYS_TEXT_BASE, %g2 + wr %g0, %g2, %tbr + nop + nop + nop + /* Obtain the address of _GLOBAL_OFFSET_TABLE_ */ SPARC_PIC_THUNK_CALL(l7) @@ -302,25 +305,50 @@ cpu_init_unreloc: call cpu_init_f nop -/* un relocated start address of monitor */ -#define TEXT_START _text +board_init_unreloc: + call board_init_f + clr %o0 ! boot_flags -/* un relocated end address of monitor */ -#define DATA_END __init_end +dead_unreloc: + mov 1, %g1 ! For GRMON2 to exit normally. + ta 0 ! If board_init_f call returns.. (unlikely) + nop + nop + ba dead_unreloc ! infinte loop + nop + +!------------------------------------------------------------------------------- +/* void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM after + * relocating the monitor code. + * + * %o0 = Relocated stack pointer + * %o1 = Relocated global data pointer + * %o2 = Relocated text pointer + * + * %l7 = _GLOBAL_OFFSET_TABLE_ address + */ + .globl relocate_code + .type relocate_code, #function + .align 4 +relocate_code: + !SPARC_PIC_THUNK_CALL(l7) reloc: - SPARC_LOAD_ADDRESS(TEXT_START, l7, g2) - SPARC_LOAD_ADDRESS(DATA_END, l7, g3) - set CONFIG_SYS_RELOC_MONITOR_BASE,%g4 -reloc_loop: - ldd [%g2],%l0 - ldd [%g2+8],%l2 - std %l0,[%g4] - std %l2,[%g4+8] - inc 16,%g2 - subcc %g3,%g2,%g0 - bne reloc_loop - inc 16,%g4 + SPARC_LOAD_ADDRESS(_text, l7, g2) ! start address of monitor + SPARC_LOAD_ADDRESS(__init_end, l7, g3) ! end address of monitor + mov %o2, %g4 ! relocation address + sub %g4, %g2, %g6 ! relocation offset + /* copy .text & .data to relocated address */ +10: ldd [%g2], %l0 + ldd [%g2+8], %l2 + std %l0, [%g4] + std %l2, [%g4+8] + inc 16, %g2 ! src += 16 + cmp %g2, %g3 + bcs 10b ! while (src < end) + inc 16, %g4 ! dst += 16 clr %l0 clr %l1 @@ -335,106 +363,97 @@ reloc_loop: * */ + /* clear the relocated .bss area */ clr_bss: -/* clear bss area (the relocated) */ SPARC_LOAD_ADDRESS(__bss_start, l7, g2) SPARC_LOAD_ADDRESS(__bss_end, l7, g3) - sub %g3,%g2,%g3 + sub %g3,%g2,%g3 ! length of .bss area add %g3,%g4,%g3 + /* clearing 16byte a time ==> linker script need to align to 16 byte offset */ clr %g1 /* std %g0 uses g0 and g1 */ -/* clearing 16byte a time ==> linker script need to align to 16 byte offset */ -clr_bss_16: - std %g0,[%g4] - std %g0,[%g4+8] - inc 16,%g4 - cmp %g3,%g4 - bne clr_bss_16 +20: + std %g0, [%g4] + std %g0, [%g4+8] + inc 16, %g4 ! ptr += 16 + cmp %g4, %g3 + bcs 20b ! while (ptr < end) nop -/* add offsets to GOT table */ + /* add offsets to GOT table */ fixup_got: SPARC_LOAD_ADDRESS(__got_start, l7, g4) + add %g4, %g6, %g4 SPARC_LOAD_ADDRESS(__got_end, l7, g3) -/* - * new got offset = (old GOT-PTR (read with ld) - - * CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) + - * Destination Address (from define) - */ - set CONFIG_SYS_RELOC_MONITOR_BASE,%g2 - SPARC_LOAD_ADDRESS(TEXT_START, l7, g1) - add %g4,%g2,%g4 - sub %g4,%g1,%g4 - add %g3,%g2,%g3 - sub %g3,%g1,%g3 - sub %g2,%g1,%g2 ! prepare register with (new base address) - - ! (old base address) -got_loop: - ld [%g4],%l0 ! load old GOT-PTR - add %l0,%g2,%l0 ! increase with (new base address) - - ! (old base) - st %l0,[%g4] - inc 4,%g4 - cmp %g3,%g4 - bne got_loop + add %g3, %g6, %g3 +30: ld [%g4], %l0 +#ifdef CONFIG_RELOC_GOT_SKIP_NULL + cmp %l0, 0 + be 32f +#endif + add %l0, %g6, %l0 ! relocate GOT pointer + st %l0, [%g4] +32: inc 4, %g4 ! ptr += 4 + cmp %g4, %g3 + bcs 30b ! while (ptr < end) nop prom_relocate: SPARC_LOAD_ADDRESS(__prom_start, l7, g2) SPARC_LOAD_ADDRESS(__prom_end, l7, g3) - set CONFIG_SYS_PROM_OFFSET, %g4 - -prom_relocate_loop: - ldd [%g2],%l0 - ldd [%g2+8],%l2 - std %l0,[%g4] - std %l2,[%g4+8] - inc 16,%g2 - subcc %g3,%g2,%g0 - bne prom_relocate_loop - inc 16,%g4 + /* + * Calculated addres is stored in this variable by + * reserve_prom() function in common/board_f.c + */ + SPARC_LOAD_ADDRESS(__prom_start_reloc, l7, g4) + ld [%g4], %g4 + +40: ldd [%g2], %l0 + ldd [%g2+8], %l2 + std %l0, [%g4] + std %l2, [%g4+8] + inc 16, %g2 + cmp %g2, %g3 + bcs 40b + inc 16, %g4 + +! %o0 = stack pointer (relocated) +! %o1 = global data pointer (relocated) +! %o2 = text pointer (relocated) + +! %g6 = relocation offset +! %l7 = _GLOBAL_OFFSET_TABLE_ /* Trap table has been moved, lets tell CPU about * the new trap table address */ - - set CONFIG_SYS_RELOC_MONITOR_BASE, %g2 - wr %g0, %g2, %tbr +update_trap_table_address: + wr %g0, %o2, %tbr nop nop nop -/* If CACHE snooping is available in hardware the - * variable leon3_snooping_avail will be set to - * 0x800000 else 0. - */ -snoop_detect: - sethi %hi(0x00800000), %o0 - lda [%g0] 2, %o1 - and %o0, %o1, %o0 - sethi %hi(leon3_snooping_avail+CONFIG_SYS_RELOC_MONITOR_BASE-CONFIG_SYS_TEXT_BASE), %o1 - st %o0, [%lo(leon3_snooping_avail+CONFIG_SYS_RELOC_MONITOR_BASE-CONFIG_SYS_TEXT_BASE)+%o1] - -/* call relocate*/ - nop -/* Call relocated init functions */ -jump: - SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1) - set CONFIG_SYS_RELOC_MONITOR_BASE,%o2 - add %o1,%o2,%o1 - sub %o1,%g1,%o1 - call %o1 - clr %o0 +update_stack_pointers: + mov %o0, %fp + andn %fp, 0x0f, %fp ! align to 16 bytes + add %fp, -64, %fp ! make space for a window push + mov %fp, %sp ! setup stack pointer + +jump_board_init_r: + mov %o1, %o0 ! relocated global data pointer + mov %o2, %o1 ! relocated text pointer + SPARC_LOAD_ADDRESS(board_init_r, l7, o3) + add %o3, %g6, %o3 ! add relocation offset + call %o3 + nop - SPARC_LOAD_ADDRESS(board_init_f, l7, o1) - set CONFIG_SYS_RELOC_MONITOR_BASE,%o2 - SPARC_LOAD_ADDRESS(TEXT_START, l7, g1) - add %o1,%o2,%o1 - sub %o1,%g1,%o1 - call %o1 - clr %o0 +dead: + mov 1, %g1 ! For GRMON2 to exit normally. + ta 0 ! if call returns.. (unlikely) + nop + b dead ! infinte loop + nop -dead: ta 0 ! if call returns... - nop +!------------------------------------------------------------------------------ /* Interrupt handler caller, * reg L7: interrupt number @@ -463,54 +482,56 @@ _irq_entry: RESTORE_ALL -!Window overflow trap handler. +!------------------------------------------------------------------------------ + +/* + * Window overflow trap handler + */ .global _window_overflow _window_overflow: mov %wim, %l3 ! Calculate next WIM - mov %g1, %l7 - srl %l3, 1, %g1 - sll %l3, (CONFIG_SYS_SPARC_NWINDOWS-1) , %l4 - or %l4, %g1, %g1 - + mov %g1, %l7 + srl %l3, 1, %g1 + sll %l3, (CONFIG_SYS_SPARC_NWINDOWS-1), %l4 + or %g1, %l4, %g1 save ! Get into window to be saved. - mov %g1, %wim - nop; - nop; - nop - st %l0, [%sp + 0]; - st %l1, [%sp + 4]; - st %l2, [%sp + 8]; - st %l3, [%sp + 12]; - st %l4, [%sp + 16]; - st %l5, [%sp + 20]; - st %l6, [%sp + 24]; - st %l7, [%sp + 28]; - st %i0, [%sp + 32]; - st %i1, [%sp + 36]; - st %i2, [%sp + 40]; - st %i3, [%sp + 44]; - st %i4, [%sp + 48]; - st %i5, [%sp + 52]; - st %i6, [%sp + 56]; - st %i7, [%sp + 60]; + mov %g1, %wim + nop; nop; nop + st %l0, [%sp + 0] ! Save window to the stack + st %l1, [%sp + 4] + st %l2, [%sp + 8] + st %l3, [%sp + 12] + st %l4, [%sp + 16] + st %l5, [%sp + 20] + st %l6, [%sp + 24] + st %l7, [%sp + 28] + st %i0, [%sp + 32] + st %i1, [%sp + 36] + st %i2, [%sp + 40] + st %i3, [%sp + 44] + st %i4, [%sp + 48] + st %i5, [%sp + 52] + st %i6, [%sp + 56] + st %i7, [%sp + 60] restore ! Go back to trap window. - mov %l7, %g1 + mov %l7, %g1 jmp %l1 ! Re-execute save. - rett %l2 - -/* Window underflow trap handler. */ + rett %l2 +/* + * Window underflow trap handler + */ .global _window_underflow _window_underflow: - mov %wim, %l3 ! Calculate next WIM - sll %l3, 1, %l4 - srl %l3, (CONFIG_SYS_SPARC_NWINDOWS-1), %l5 - or %l5, %l4, %l5 - mov %l5, %wim + mov %wim, %l3 ! Calculate next WIM + srl %l3, (CONFIG_SYS_SPARC_NWINDOWS-1), %l5 + sll %l3, 1, %l4 + or %l5, %l4, %l5 + mov %l5, %wim nop; nop; nop restore ! Two restores to get into the restore ! window to restore @@ -533,9 +554,9 @@ _window_underflow: save ! Get back to the trap window. save jmp %l1 ! Re-execute restore. - rett %l2 + rett %l2 - retl +!------------------------------------------------------------------------------ _nmi_trap: nop diff --git a/arch/sparc/cpu/leon3/usb_uhci.c b/arch/sparc/cpu/leon3/usb_uhci.c index 1be84c646b8..242b83fbcfa 100644 --- a/arch/sparc/cpu/leon3/usb_uhci.c +++ b/arch/sparc/cpu/leon3/usb_uhci.c @@ -85,10 +85,11 @@ #include <usb.h> #include "usb_uhci.h" +DECLARE_GLOBAL_DATA_PTR; + #define USB_MAX_TEMP_TD 128 /* number of temporary TDs for bulk and control transfers */ #define USB_MAX_TEMP_INT_TD 32 /* number of temporary TDs for Interrupt transfers */ -extern int leon3_snooping_avail; /* #define out16r(address,data) (*(unsigned short *)(address) = \ (unsigned short)( \ @@ -573,7 +574,7 @@ void usb_check_skel(void) if (qh_cntrl.dev_ptr != 0) { /* it's a device assigned check if this caused IRQ */ dev = (struct usb_device *)qh_cntrl.dev_ptr; /* Flush cache now that hardware updated DATA and TDs/QHs */ - if (!leon3_snooping_avail) + if (!gd->arch.snooping_avail) sparc_dcache_flush_all(); usb_get_td_status(&tmp_td[0], dev); /* update status */ if (!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */ @@ -584,7 +585,7 @@ void usb_check_skel(void) if (qh_bulk.dev_ptr != 0) { /* it's a device assigned check if this caused IRQ */ dev = (struct usb_device *)qh_bulk.dev_ptr; /* Flush cache now that hardware updated DATA and TDs/QHs */ - if (!leon3_snooping_avail) + if (!gd->arch.snooping_avail) sparc_dcache_flush_all(); usb_get_td_status(&tmp_td[0], dev); /* update status */ if (!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */ |