diff options
39 files changed, 3355 insertions, 1273 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index bf60c67668..b3a45ccbac 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -370,7 +370,7 @@ T: git git://git.denx.de/u-boot-sh.git F: arch/sh/ SPARC -M: Daniel Hellstrom <daniel@gaisler.com> +M: Francois Retief <fgretief@spaceteq.co.za> S: Maintained T: git git://git.denx.de/u-boot-sparc.git F: arch/sparc/ diff --git a/arch/sparc/config.mk b/arch/sparc/config.mk index d615f294fe..43faad48ce 100644 --- a/arch/sparc/config.mk +++ b/arch/sparc/config.mk @@ -1,19 +1,25 @@ # -# (C) Copyright 2007 -# Daniel Hellstrom, Gaisler Research, daniel@gaisler.com +# (C) Copyright 2015 +# Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. # # SPDX-License-Identifier: GPL-2.0+ # ifeq ($(CROSS_COMPILE),) -CROSS_COMPILE := sparc-elf- +CROSS_COMPILE := sparc-linux- endif +# This GCC compiler is known to work: +# https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.9.0/ + gcclibdir := $(shell dirname `$(CC) -print-libgcc-file-name`) CONFIG_STANDALONE_LOAD_ADDR ?= 0x00000000 -L $(gcclibdir) \ -T $(srctree)/examples/standalone/sparc.lds -PLATFORM_CPPFLAGS += -D__sparc__ +cpuflags-$(CONFIG_LEON2) := -mcpu=leon +cpuflags-$(CONFIG_LEON3) := -mcpu=leon3 + +PLATFORM_CPPFLAGS += $(cpuflags-y) PLATFORM_RELFLAGS += -fPIC diff --git a/arch/sparc/cpu/leon2/serial.c b/arch/sparc/cpu/leon2/serial.c index 5cfbb9ed15..603364ee0b 100644 --- a/arch/sparc/cpu/leon2/serial.c +++ b/arch/sparc/cpu/leon2/serial.c @@ -1,72 +1,78 @@ /* GRLIB APBUART Serial controller driver * - * (C) Copyright 2008 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * (C) Copyright 2008, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> -#include <asm/processor.h> -#include <asm/leon.h> +#include <asm/io.h> #include <serial.h> -#include <linux/compiler.h> +#include <watchdog.h> DECLARE_GLOBAL_DATA_PTR; +static unsigned leon2_serial_calc_scaler(unsigned freq, unsigned baud) +{ + return (((freq*10) / (baud*8)) - 5) / 10; +} + static int leon2_serial_init(void) { - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; + LEON2_regs *leon2 = (LEON2_regs *)LEON2_PREGS; LEON2_Uart_regs *regs; unsigned int tmp; - /* Init LEON2 UART - * - * Set scaler / baud rate - * - * Receiver & transmitter enable - */ #if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; + regs = (LEON2_Uart_regs *)&leon2->UART_Channel_1; #else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; + regs = (LEON2_Uart_regs *)&leon2->UART_Channel_2; #endif - regs->UART_Scaler = CONFIG_SYS_LEON2_UART1_SCALER; + /* Set scaler / baud rate */ + tmp = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, CONFIG_BAUDRATE); + writel(tmp, ®s->UART_Scaler); /* Let bit 11 be unchanged (debug bit for GRMON) */ - tmp = READ_WORD(regs->UART_Control); + tmp = readl(®s->UART_Control) & LEON2_UART_CTRL_DBG; + tmp |= (LEON2_UART1_LOOPBACK_ENABLE << 7); + tmp |= (LEON2_UART1_FLOWCTRL_ENABLE << 6); + tmp |= (LEON2_UART1_PARITY_ENABLE << 5); + tmp |= (LEON2_UART1_ODDPAR_ENABLE << 4); + /* Receiver & transmitter enable */ + tmp |= (LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE); + writel(tmp, ®s->UART_Control); + + gd->arch.uart = regs; + return 0; +} - regs->UART_Control = ((tmp & LEON2_UART_CTRL_DBG) | - (LEON2_UART1_LOOPBACK_ENABLE << 7) | - (LEON2_UART1_FLOWCTRL_ENABLE << 6) | - (LEON2_UART1_PARITY_ENABLE << 5) | - (LEON2_UART1_ODDPAR_ENABLE << 4) | - LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE); +static inline LEON2_Uart_regs *leon2_get_uart_regs(void) +{ + LEON2_Uart_regs *uart = gd->arch.uart; - return 0; + return uart; } static void leon2_serial_putc_raw(const char c) { - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - LEON2_Uart_regs *regs; + LEON2_Uart_regs *uart = leon2_get_uart_regs(); -#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; -#else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; -#endif + if (!uart) + return; /* Wait for last character to go. */ - while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_THE)) ; + while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_THE)) + WATCHDOG_RESET(); /* Send data */ - regs->UART_Channel = c; + writel(c, &uart->UART_Channel); #ifdef LEON_DEBUG /* Wait for data to be sent */ - while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_TSE)) ; + while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_TSE)) + WATCHDOG_RESET(); #endif } @@ -80,56 +86,43 @@ static void leon2_serial_putc(const char c) static int leon2_serial_getc(void) { - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - LEON2_Uart_regs *regs; + LEON2_Uart_regs *uart = leon2_get_uart_regs(); -#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; -#else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; -#endif + if (!uart) + return 0; /* Wait for a character to arrive. */ - while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR)) ; + while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_DR)) + WATCHDOG_RESET(); - /* read data */ - return READ_WORD(regs->UART_Channel); + /* Read character data */ + return readl(&uart->UART_Channel); } static int leon2_serial_tstc(void) { - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - LEON2_Uart_regs *regs; + LEON2_Uart_regs *uart = leon2_get_uart_regs(); -#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; -#else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; -#endif + if (!uart) + return 0; - return (READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR); + return readl(&uart->UART_Status) & LEON2_UART_STAT_DR; } -/* set baud rate for uart */ static void leon2_serial_setbrg(void) { - /* update baud rate settings, read it from gd->baudrate */ + LEON2_Uart_regs *uart = leon2_get_uart_regs(); unsigned int scaler; - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - LEON2_Uart_regs *regs; -#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1 - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1; -#else - regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2; -#endif + if (!uart) + return; + + if (!gd->baudrate) + gd->baudrate = CONFIG_BAUDRATE; + + scaler = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, CONFIG_BAUDRATE); - if (gd->baudrate > 0) { - scaler = - (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) - - 5) / 10; - regs->UART_Scaler = scaler; - } + writel(scaler, &uart->UART_Scaler); } static struct serial_device leon2_serial_drv = { diff --git a/arch/sparc/cpu/leon2/start.S b/arch/sparc/cpu/leon2/start.S index e43097cf9b..974de76852 100644 --- a/arch/sparc/cpu/leon2/start.S +++ b/arch/sparc/cpu/leon2/start.S @@ -57,6 +57,27 @@ MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4) #error Must define number of SPARC register windows, default is 8 #endif +/* Macros to load address into a register. Uses GOT table for PIC */ +#ifdef __PIC__ + +#define SPARC_PIC_THUNK_CALL(reg) \ + sethi %pc22(_GLOBAL_OFFSET_TABLE_-4), %##reg; \ + call __sparc_get_pc_thunk.reg; \ + add %##reg, %pc10(_GLOBAL_OFFSET_TABLE_+4), %##reg; + +#define SPARC_LOAD_ADDRESS(sym, got, reg) \ + sethi %gdop_hix22(sym), %##reg; \ + xor %##reg, %gdop_lox10(sym), %##reg; \ + ld [%##got + %##reg], %##reg, %gdop(sym); + +#else + +#define SPARC_PIC_THUNK_CALL(reg) +#define SPARC_LOAD_ADDRESS(sym, got, tmp) \ + set sym, %##reg; + +#endif + #define STACK_ALIGN 8 #define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1)) @@ -278,7 +299,7 @@ leon2_init_mctrl: srl %g2, 30, %g2 andcc %g2, 3, %g6 bne,a leon2_init_wim - mov %g0, %asr16 ! clear err_reg + mov %g0, %asr16 ! clear err_reg leon2_init_wim: set WIM_INIT, %g3 @@ -299,7 +320,7 @@ leon2_init_stackp: cpu_init_unreloc: call cpu_init_f - nop + nop /* un relocated start address of monitor */ #define TEXT_START _text @@ -307,9 +328,10 @@ cpu_init_unreloc: /* un relocated end address of monitor */ #define DATA_END __init_end + SPARC_PIC_THUNK_CALL(l7) reloc: - set TEXT_START,%g2 - set DATA_END,%g3 + 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 @@ -319,7 +341,7 @@ reloc_loop: inc 16,%g2 subcc %g3,%g2,%g0 bne reloc_loop - inc 16,%g4 + inc 16,%g4 clr %l0 clr %l1 @@ -336,8 +358,8 @@ reloc_loop: clr_bss: /* clear bss area (the relocated) */ - set __bss_start,%g2 - set __bss_end,%g3 + SPARC_LOAD_ADDRESS(__bss_start, l7, g2) + SPARC_LOAD_ADDRESS(__bss_end, l7, g3) sub %g3,%g2,%g3 add %g3,%g4,%g3 clr %g1 /* std %g0 uses g0 and g1 */ @@ -348,19 +370,19 @@ clr_bss_16: inc 16,%g4 cmp %g3,%g4 bne clr_bss_16 - nop + nop /* add offsets to GOT table */ fixup_got: - set __got_start,%g4 - set __got_end,%g3 + SPARC_LOAD_ADDRESS(__got_start, l7, 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 - set TEXT_START, %g1 + SPARC_LOAD_ADDRESS(TEXT_START, l7, g1) add %g4,%g2,%g4 sub %g4,%g1,%g4 add %g3,%g2,%g3 @@ -375,11 +397,11 @@ got_loop: inc 4,%g4 cmp %g3,%g4 bne got_loop - nop + nop prom_relocate: - set __prom_start, %g2 - set __prom_end, %g3 + SPARC_LOAD_ADDRESS(__prom_start, l7, g2) + SPARC_LOAD_ADDRESS(__prom_end, l7, g3) set CONFIG_SYS_PROM_OFFSET, %g4 prom_relocate_loop: @@ -390,7 +412,7 @@ prom_relocate_loop: inc 16,%g2 subcc %g3,%g2,%g0 bne prom_relocate_loop - inc 16,%g4 + inc 16,%g4 /* Trap table has been moved, lets tell CPU about * the new trap table address @@ -403,19 +425,19 @@ prom_relocate_loop: nop /* Call relocated init functions */ jump: - set cpu_init_f2,%o1 + 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 + clr %o0 - set board_init_f,%o1 + 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 + clr %o0 dead: ta 0 ! if call returns... nop diff --git a/arch/sparc/cpu/leon3/Makefile b/arch/sparc/cpu/leon3/Makefile index 4f13ec3071..f4cf43cfec 100644 --- a/arch/sparc/cpu/leon3/Makefile +++ b/arch/sparc/cpu/leon3/Makefile @@ -6,4 +6,5 @@ # extra-y = start.o -obj-y = cpu_init.o serial.o cpu.o ambapp.o interrupts.o prom.o usb_uhci.o +obj-y = cpu_init.o serial.o cpu.o ambapp.o ambapp_low.o ambapp_low_c.o \ + interrupts.o prom.o usb_uhci.o memcfg.o memcfg_low.o diff --git a/arch/sparc/cpu/leon3/ambapp.c b/arch/sparc/cpu/leon3/ambapp.c index a30d1f2a99..b8ac05faf1 100644 --- a/arch/sparc/cpu/leon3/ambapp.c +++ b/arch/sparc/cpu/leon3/ambapp.c @@ -1,343 +1,316 @@ -/* Gaisler AMBA Plug&Play bus scanning. Functions - * ending on _nomem is inteded to be used only during - * initialization, only registers are used (no ram). +/* GRLIB AMBA Plug&Play information scanning, relies on assembler + * routines. * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. * * SPDX-License-Identifier: GPL-2.0+ */ +/* #define DEBUG */ + #include <common.h> -#include <command.h> +#include <malloc.h> #include <ambapp.h> +#include <config.h> + +/************ C INTERFACE OF ASSEMBLER SCAN ROUTINES ************/ +struct ambapp_find_apb_info { + /* Address of APB device Plug&Play information */ + struct ambapp_pnp_apb *pnp; + /* AHB Bus index of where the APB-Master Bridge device was found */ + int ahb_bus_index; + int dec_index; +}; -#if defined(CONFIG_CMD_AMBAPP) -extern void ambapp_print_apb(apbctrl_pp_dev * apb, - ambapp_ahbdev * apbmst, int index); -extern void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index); -extern int ambapp_apb_print; -extern int ambapp_ahb_print; -#endif - -static int ambapp_apb_scan(unsigned int vendor, /* Plug&Play Vendor ID */ - unsigned int driver, /* Plug&Play Device ID */ - ambapp_apbdev * dev, /* Result(s) is placed here */ - int index, /* Index of device to start copying Plug&Play - * info into dev - */ - int max_cnt /* Maximal count that dev can hold, if dev - * is NULL function will stop scanning after - * max_cnt devices are found. - */ - ) -{ - int i, cnt = 0; - unsigned int apbmst_base; - ambapp_ahbdev apbmst; - apbctrl_pp_dev *apb; - - if (max_cnt == 0) - return 0; - - /* Get AMBA APB Master */ - if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_APBMST, &apbmst) != 1) { - return 0; - } +struct ambapp_find_ahb_info { + /* Address of AHB device Plug&Play information */ + struct ambapp_pnp_ahb *pnp; + /* AHB Bus index of where the AHB device was found */ + int ahb_bus_index; + int dec_index; +}; - /* Get APB CTRL Plug&Play info area */ - apbmst_base = apbmst.address[0] & LEON3_IO_AREA; - apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA); +extern void ambapp_find_buses(unsigned int ioarea, struct ambapp_bus *abus); - for (i = 0; i < LEON3_APB_SLAVES; i++) { -#if defined(CONFIG_CMD_AMBAPP) - if (ambapp_apb_print && amba_vendor(apb->conf) - && amba_device(apb->conf)) { - ambapp_print_apb(apb, &apbmst, i); - } -#endif - if ((amba_vendor(apb->conf) == vendor) && - (amba_device(apb->conf) == driver) && ((index < 0) - || (index-- == 0))) { - /* Convert Plug&Play info into a more readable format */ - cnt++; - if (dev) { - dev->irq = amba_irq(apb->conf); - dev->ver = amba_ver(apb->conf); - dev->address = - (apbmst_base | - (((apb-> - bar & 0xfff00000) >> 12))) & (((apb-> - bar & - 0x0000fff0) - << 4) | - 0xfff00000); - dev++; - } - /* found max devices? */ - if (cnt >= max_cnt) - return cnt; - } - /* Get next Plug&Play entry */ - apb++; - } - return cnt; -} +extern int ambapp_find_apb(struct ambapp_bus *abus, unsigned int dev_vend, + int index, struct ambapp_find_apb_info *result); -unsigned int ambapp_apb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */ - register unsigned int driver, /* Plug&Play Device ID */ - register int index) -{ - register int i; - register ahbctrl_pp_dev *apbmst; - register apbctrl_pp_dev *apb; - register unsigned int apbmst_base; - - /* APBMST is a AHB Slave */ - apbmst = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0); - if (!apbmst) - return 0; - - apbmst_base = amba_membar_start(apbmst->bars[0]); - if (amba_membar_type(apbmst->bars[0]) == AMBA_TYPE_AHBIO) - apbmst_base = AMBA_TYPE_AHBIO_ADDR(apbmst_base); - apbmst_base &= LEON3_IO_AREA; - - /* Find the vendor/driver device on the first APB bus */ - apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA); - - for (i = 0; i < LEON3_APB_SLAVES; i++) { - if ((amba_vendor(apb->conf) == vendor) && - (amba_device(apb->conf) == driver) && ((index < 0) - || (index-- == 0))) { - /* Convert Plug&Play info info a more readable format */ - return (apbmst_base | (((apb->bar & 0xfff00000) >> 12))) - & (((apb->bar & 0x0000fff0) << 4) | 0xfff00000); - } - /* Get next Plug&Play entry */ - apb++; - } - return 0; -} +extern int ambapp_find_ahb(struct ambapp_bus *abus, unsigned int dev_vend, + int index, int type, struct ambapp_find_ahb_info *result); -/****************************** APB SLAVES ******************************/ +/************ C ROUTINES USED BY U-BOOT AMBA CORE DRIVERS ************/ +struct ambapp_bus ambapp_plb; -int ambapp_apb_count(unsigned int vendor, unsigned int driver) +void ambapp_bus_init( + unsigned int ioarea, + unsigned int freq, + struct ambapp_bus *abus) { - return ambapp_apb_scan(vendor, driver, NULL, 0, LEON3_APB_SLAVES); + int i; + + ambapp_find_buses(ioarea, abus); + for (i = 0; i < 6; i++) + if (abus->ioareas[i] == 0) + break; + abus->buses = i; + abus->freq = freq; } -int ambapp_apb_first(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev) +/* Parse APB PnP Information */ +void ambapp_apb_parse(struct ambapp_find_apb_info *info, ambapp_apbdev *dev) { - return ambapp_apb_scan(vendor, driver, dev, 0, 1); + struct ambapp_pnp_apb *apb = info->pnp; + unsigned int apbbase = (unsigned int)apb & 0xfff00000; + + dev->vendor = amba_vendor(apb->id); + dev->device = amba_device(apb->id); + dev->irq = amba_irq(apb->id); + dev->ver = amba_ver(apb->id); + dev->address = (apbbase | (((apb->iobar & 0xfff00000) >> 12))) & + (((apb->iobar & 0x0000fff0) << 4) | 0xfff00000); + dev->mask = amba_apb_mask(apb->iobar); + dev->ahb_bus_index = info->ahb_bus_index - 1; } -int ambapp_apb_next(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev, int index) +/* Parse AHB PnP information */ +void ambapp_ahb_parse(struct ambapp_find_ahb_info *info, ambapp_ahbdev *dev) { - return ambapp_apb_scan(vendor, driver, dev, index, 1); + struct ambapp_pnp_ahb *ahb = info->pnp; + unsigned int ahbbase = (unsigned int)ahb & 0xfff00000; + int i, type; + unsigned int addr, mask, mbar; + + dev->vendor = amba_vendor(ahb->id); + dev->device = amba_device(ahb->id); + dev->irq = amba_irq(ahb->id); + dev->ver = amba_ver(ahb->id); + dev->userdef[0] = ahb->custom[0]; + dev->userdef[1] = ahb->custom[1]; + dev->userdef[2] = ahb->custom[2]; + dev->ahb_bus_index = info->ahb_bus_index - 1; + for (i = 0; i < 4; i++) { + mbar = ahb->mbar[i]; + addr = amba_membar_start(mbar); + type = amba_membar_type(mbar); + if (type == AMBA_TYPE_AHBIO) { + addr = amba_ahbio_adr(addr, ahbbase); + mask = (((unsigned int) + (amba_membar_mask((~mbar))<<8)|0xff))+1; + } else { + /* AHB memory area, absolute address */ + mask = (~((unsigned int) + (amba_membar_mask(mbar)<<20)))+1; + } + dev->address[i] = addr; + dev->mask[i] = mask; + dev->type[i] = type; + } } -int ambapp_apbs_first(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev, int max_cnt) +int ambapp_apb_find(struct ambapp_bus *abus, int vendor, int device, + int index, ambapp_apbdev *dev) { - return ambapp_apb_scan(vendor, driver, dev, 0, max_cnt); -} + unsigned int devid = AMBA_PNP_ID(vendor, device); + int found; + struct ambapp_find_apb_info apbdev; -enum { - AHB_SCAN_MASTER = 0, - AHB_SCAN_SLAVE = 1 -}; - -/* Scan AMBA Plug&Play bus for AMBA AHB Masters or AHB Slaves - * for a certain matching Vendor and Device ID. - * - * Return number of devices found. - * - * Compact edition... - */ -static int ambapp_ahb_scan(unsigned int vendor, /* Plug&Play Vendor ID */ - unsigned int driver, /* Plug&Play Device ID */ - ambapp_ahbdev * dev, /* Result(s) is placed here */ - int index, /* Index of device to start copying Plug&Play - * info into dev - */ - int max_cnt, /* Maximal count that dev can hold, if dev - * is NULL function will stop scanning after - * max_cnt devices are found. - */ - int type /* Selectes what type of devices to scan. - * 0=AHB Masters - * 1=AHB Slaves - */ - ) -{ - int i, j, cnt = 0, max_pp_devs; - unsigned int addr; - ahbctrl_info *info = (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA); - ahbctrl_pp_dev *ahb; - - if (max_cnt == 0) - return 0; - - if (type == 0) { - max_pp_devs = LEON3_AHB_MASTERS; - ahb = info->masters; - } else { - max_pp_devs = LEON3_AHB_SLAVES; - ahb = info->slaves; - } + found = ambapp_find_apb(abus, devid, index, &apbdev); + if (found == 1) + ambapp_apb_parse(&apbdev, dev); - for (i = 0; i < max_pp_devs; i++) { -#if defined(CONFIG_CMD_AMBAPP) - if (ambapp_ahb_print && amba_vendor(ahb->conf) && - amba_device(ahb->conf)) { - ambapp_print_ahb(ahb, i); - } -#endif - if ((amba_vendor(ahb->conf) == vendor) && - (amba_device(ahb->conf) == driver) && - ((index < 0) || (index-- == 0))) { - /* Convert Plug&Play info info a more readable format */ - cnt++; - if (dev) { - dev->irq = amba_irq(ahb->conf); - dev->ver = amba_ver(ahb->conf); - dev->userdef[0] = ahb->userdef[0]; - dev->userdef[1] = ahb->userdef[1]; - dev->userdef[2] = ahb->userdef[2]; - for (j = 0; j < 4; j++) { - addr = amba_membar_start(ahb->bars[j]); - if (amba_membar_type(ahb->bars[j]) == - AMBA_TYPE_AHBIO) - addr = - AMBA_TYPE_AHBIO_ADDR(addr); - dev->address[j] = addr; - } - dev++; - } - /* found max devices? */ - if (cnt >= max_cnt) - return cnt; - } - /* Get next Plug&Play entry */ - ahb++; - } - return cnt; + return found; } -unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info) +int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device) { - register unsigned int ret; - - if (!ahb) - return 0; - - switch (info) { - default: - info = 0; - case 0: - case 1: - case 2: - case 3: - /* Get Address from PnP Info */ - ret = amba_membar_start(ahb->bars[info]); - if (amba_membar_type(ahb->bars[info]) == AMBA_TYPE_AHBIO) - ret = AMBA_TYPE_AHBIO_ADDR(ret); - return ret; - } - return 0; - + unsigned int devid = AMBA_PNP_ID(vendor, device); + int found; + struct ambapp_find_apb_info apbdev; + + found = ambapp_find_apb(abus, devid, 63, &apbdev); + if (found == 1) + return 64; + else + return 63 - apbdev.dec_index; } -ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */ - register unsigned int driver, /* Plug&Play Device ID */ - register unsigned int opts, /* 1=slave, 0=master */ - register int index) +int ambapp_ahb_find(struct ambapp_bus *abus, int vendor, int device, + int index, ambapp_ahbdev *dev, int type) { - register ahbctrl_pp_dev *ahb; - register ahbctrl_info *info = - (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA); - register int i; - register int max_pp_devs; - - if (opts == 0) { - max_pp_devs = LEON3_AHB_MASTERS; - ahb = info->masters; - } else { - max_pp_devs = LEON3_AHB_SLAVES; - ahb = info->slaves; - } + int found; + struct ambapp_find_ahb_info ahbdev; + unsigned int devid = AMBA_PNP_ID(vendor, device); - for (i = 0; i < max_pp_devs; i++) { - if ((amba_vendor(ahb->conf) == vendor) && - (amba_device(ahb->conf) == driver) && - ((index < 0) || (index-- == 0))) { - /* Convert Plug&Play info info a more readable format */ - return ahb; - } - /* Get next Plug&Play entry */ - ahb++; - } - return 0; + found = ambapp_find_ahb(abus, devid, index, type, &ahbdev); + if (found == 1) + ambapp_ahb_parse(&ahbdev, dev); + + return found; } -/****************************** AHB MASTERS ******************************/ -int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver) +int ambapp_ahbmst_find(struct ambapp_bus *abus, int vendor, int device, + int index, ambapp_ahbdev *dev) { - /* Get number of devices of this vendor&device ID */ - return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_MASTERS, - AHB_SCAN_MASTER); + return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_MST); } -int ambapp_ahbmst_first(unsigned int vendor, unsigned int driver, - ambapp_ahbdev * dev) +int ambapp_ahbslv_find(struct ambapp_bus *abus, int vendor, int device, + int index, ambapp_ahbdev *dev) { - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_MASTER); + return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_SLV); } -int ambapp_ahbmst_next(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int index) +int ambapp_ahb_count(struct ambapp_bus *abus, int vendor, int device, int type) { - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_MASTER); + int found; + struct ambapp_find_ahb_info ahbdev; + unsigned int devid = AMBA_PNP_ID(vendor, device); + + found = ambapp_find_ahb(abus, devid, 63, type, &ahbdev); + if (found == 1) + return 64; + else + return 63 - ahbdev.dec_index; } -int ambapp_ahbmsts_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int max_cnt) +int ambapp_ahbmst_count(struct ambapp_bus *abus, int vendor, int device) { - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, - AHB_SCAN_MASTER); + return ambapp_ahb_count(abus, vendor, device, DEV_AHB_MST); } -/****************************** AHB SLAVES ******************************/ -int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver) +int ambapp_ahbslv_count(struct ambapp_bus *abus, int vendor, int device) { - /* Get number of devices of this vendor&device ID */ - return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_SLAVES, - AHB_SCAN_SLAVE); + return ambapp_ahb_count(abus, vendor, device, DEV_AHB_SLV); } -int ambapp_ahbslv_first(unsigned int vendor, unsigned int driver, - ambapp_ahbdev * dev) +/* The define CONFIG_SYS_GRLIB_SINGLE_BUS may be defined on GRLIB systems + * where only one AHB Bus is available - no bridges are present. This option + * is available only to reduce the footprint. + * + * Defining this on a multi-bus GRLIB system may also work depending on the + * design. + */ + +#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS + +/* GAISLER AHB2AHB Version 1 Bridge Definitions */ +#define AHB2AHB_V1_FLAG_FFACT 0x0f0 /* Frequency factor against top bus */ +#define AHB2AHB_V1_FLAG_FFACT_DIR 0x100 /* Factor direction, 0=down, 1=up */ +#define AHB2AHB_V1_FLAG_MBUS 0x00c /* Master bus number mask */ +#define AHB2AHB_V1_FLAG_SBUS 0x003 /* Slave bus number mask */ + +/* Get Parent bus frequency. Note that since we go from a "child" bus + * to a parent bus, the frequency factor direction is inverted. + */ +unsigned int gaisler_ahb2ahb_v1_freq(ambapp_ahbdev *ahb, unsigned int freq) { - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_SLAVE); + int dir; + unsigned char ffact; + + /* Get division/multiple factor */ + ffact = (ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT) >> 4; + if (ffact != 0) { + dir = ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT_DIR; + + /* Calculate frequency by dividing or + * multiplying system frequency + */ + if (dir) + freq = freq * ffact; + else + freq = freq / ffact; + } + + return freq; } -int ambapp_ahbslv_next(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int index) +/* AHB2AHB and L2CACHE ver 2 is not supported yet. */ +unsigned int gaisler_ahb2ahb_v2_freq(ambapp_ahbdev *ahb, unsigned int freq) { - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_SLAVE); + panic("gaisler_ahb2ahb_v2_freq: AHB2AHB ver 2 not supported\n"); + return -1; } +#endif -int ambapp_ahbslvs_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int max_cnt) +/* Return the frequency of a AHB bus identified by index found + * note that this is not the AHB Bus number. + */ +unsigned int ambapp_bus_freq(struct ambapp_bus *abus, int ahb_bus_index) { - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, AHB_SCAN_SLAVE); + unsigned int freq = abus->freq; +#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS + unsigned int ioarea, ioarea_parent, bridge_pnp_ofs; + struct ambapp_find_ahb_info ahbinfo; + ambapp_ahbdev ahb; + int parent; + + debug("ambapp_bus_freq: get freq on bus %d\n", ahb_bus_index); + + while (ahb_bus_index != 0) { + debug(" BUS[0]: 0x%08x\n", abus->ioareas[0]); + debug(" BUS[1]: 0x%08x\n", abus->ioareas[1]); + debug(" BUS[2]: 0x%08x\n", abus->ioareas[2]); + debug(" BUS[3]: 0x%08x\n", abus->ioareas[3]); + debug(" BUS[4]: 0x%08x\n", abus->ioareas[4]); + debug(" BUS[5]: 0x%08x\n", abus->ioareas[5]); + + /* Get I/O area of AHB bus */ + ioarea = abus->ioareas[ahb_bus_index]; + + debug(" IOAREA: 0x%08x\n", ioarea); + + /* Get parent bus */ + parent = (ioarea & 0x7); + if (parent == 0) { + panic("%s: parent=0 indicates no parent! Stopping.\n", + __func__); + return -1; + } + parent = parent - 1; + bridge_pnp_ofs = ioarea & 0x7e0; + + debug(" PARENT: %d\n", parent); + debug(" BRIDGE_OFS: 0x%08x\n", bridge_pnp_ofs); + + /* Get AHB/AHB bridge PnP address */ + ioarea_parent = (abus->ioareas[parent] & 0xfff00000) | + AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA; + ahbinfo.pnp = (struct ambapp_pnp_ahb *) + (ioarea_parent | bridge_pnp_ofs); + + debug(" IOAREA PARENT: 0x%08x\n", ioarea_parent); + debug(" BRIDGE PNP: 0x%p\n", ahbinfo.pnp); + + /* Parse the AHB information */ + ahbinfo.ahb_bus_index = parent; + ambapp_ahb_parse(&ahbinfo, &ahb); + + debug(" BRIDGE ID: VENDOR=%d(0x%x), DEVICE=%d(0x%x)\n", + ahb.vendor, ahb.vendor, ahb.device, ahb.device); + + /* Different bridges may convert frequency differently */ + if ((ahb.vendor == VENDOR_GAISLER) && + ((ahb.device == GAISLER_AHB2AHB) || + (ahb.device == GAISLER_L2CACHE))) { + /* Get new frequency */ + if (ahb.ver > 1) + freq = gaisler_ahb2ahb_v2_freq(&ahb, freq); + else + freq = gaisler_ahb2ahb_v1_freq(&ahb, freq); + + debug(" NEW FREQ: %dHz\n", freq); + } else { + panic("%s: unsupported AMBA bridge\n", __func__); + return -1; + } + + /* Step upwards towards system top bus */ + ahb_bus_index = parent; + } +#endif + + debug("ambapp_bus_freq: %dHz\n", freq); + + return freq; } diff --git a/arch/sparc/cpu/leon3/ambapp_low.S b/arch/sparc/cpu/leon3/ambapp_low.S new file mode 100644 index 0000000000..2863586dc1 --- /dev/null +++ b/arch/sparc/cpu/leon3/ambapp_low.S @@ -0,0 +1,784 @@ +/* GRLIB AMBA Plug&Play information scanning implemented without + * using memory (stack) and one register window. The code scan + * the PnP info and inserts the AHB bridges/buses into register + * i0-i5. + * The code support + * - up to 6 AHB buses + * - multiple APB buses + * - support for AHB2AHB & L2CACHE bridges + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <ambapp.h> + + .seg "text" + .globl _nomem_amba_init + .globl _nomem_ambapp_find_buses + .globl _nomem_find_apb + .globl _nomem_find_ahb + +/* Overview + * ======== + * + * _nomem_amba_init - Init AMBA bus and calls _nomem_ambapp_find_buses + * _nomem_ambapp_find_buses - Scan AMBA PnP info for AHB buses/bridges and + * place them in i0-i5, see below + * _nomem_find_apb - Find one APB device identified by VENDOR:DEVICE + * ID and an index. + * _nomem_find_ahb - Find one AHB Master or Slave device identified + * by VENDOR:DEVICE ID and an index. + * init_ahb_bridges - Local function. Clears i0-i5 + * insert_ahb_bridge - Local function. Insert a new AHB bus into first + * free register in i0-i5. It also checks that the + * bus has not already been added. + * get_ahb_bridge - Local function. Get AHB bus from registers, + * return register iN, where N is defined by o0. + * + * The _nomem_find_apb and _nomem_find_ahb function requires that i0-i5 + * are populated with the AHB buses of the system. The registers are + * initialized by _nomem_ambapp_find_buses. + * + * AHB Bus result and requirements of i0-i5 + * ======================================== + * + * i0: AHB BUS0 IOAREA, no parent bus + * i1: AHB BUS1 IOAREA, parent bus is always i0 (AHB BUS0) and bridge address + * i2: AHB BUS2 IOAREA, 3-bit parent bus number and bridge address + * i3: AHB BUS3 IOAREA, 3-bit parent bus number and bridge address + * i4: AHB BUS4 IOAREA, 3-bit parent bus number and bridge address + * i5: AHB BUS5 IOAREA, 3-bit parent bus number and bridge address + * + * AHB BUS + * ------- + * Bits 31-20 (0xfff00000) contain the found bus I/O Area (AHB PnP area). + * + * 3-bit Parent bus + * ---------------- + * Bits 2-0 (0x00000007) contain parent bus number. Zero if no parent + * bus, 1 = parent is AHB BUS 0 (i0), 2 = parent is AHB BUS 1 (i1).. + * + * Bridge Address + * -------------- + * Bits 10-5 (0x000007e0) contain the index of the Bridge's PnP + * information on the parent. Since all bridges are found in the + * PnP information they all have a PnP entry. Together with the + * parent bus number the PnP entry can be found: + * PnPEntry = (BRIDGE_ADDRESS + (iN & 0xfff00000)) | 0x000ff800 + * where N is the parent bus minus one. + * + */ + +/* Function initializes the AHB Bridge I/O AREA storage. (Clears i0-i5) + * + * Arguments + * none + * + * Results + * none + * + * Clobbered + * none + */ + +init_ahb_bridges: + mov %g0, %i0 + mov %g0, %i1 + mov %g0, %i2 + mov %g0, %i3 + mov %g0, %i4 + retl + mov %g0, %i5 + +/* Function returns AHB Bridge I/O AREA for specified bus. + * + * Arguments + * - o0 = bus number + * + * Results + * - o0 = I/O AREA + * + * Clobbered + * none + */ +get_ahb_bridge: + cmp %o0, 1 + be,a L1 + mov %i0, %o0 + + cmp %o0, 2 + be,a L1 + mov %i1, %o0 + + cmp %o0, 3 + be,a L1 + mov %i2, %o0 + + cmp %o0, 4 + be,a L1 + mov %i3, %o0 + + cmp %o0, 5 + be,a L1 + mov %i4, %o0 + + cmp %o0, 6 + be,a L1 + mov %i5, %o0 + + /* o0 > 6: only 6 buses supported */ + mov %g0, %o0 +L1: + retl + nop + +/* Function adds a AHB Bridge I/O AREA to the i0-i5 registers if + * not already added. It stores the bus PnP start information. + * + * Arguments + * - o0 = AHB Bridge I/O area + * + * Results + * none + * + * Clobbered + * o2, o3 + */ +insert_ahb_bridge: + /* Check that bridge hasn't already been added */ + andn %o0, 0x7ff, %o2 + andn %i0, 0x7ff, %o3 + cmp %o3, %o2 + be L2 + andn %i1, 0x7ff, %o3 + cmp %o3, %o2 + be L2 + andn %i2, 0x7ff, %o3 + cmp %o3, %o2 + be L2 + andn %i3, 0x7ff, %o3 + cmp %o3, %o2 + be L2 + andn %i4, 0x7ff, %o3 + cmp %o3, %o2 + be L2 + andn %i5, 0x7ff, %o3 + cmp %o3, %o2 + be L2 + + /* Insert into first free posistion */ + cmp %i0, %g0 + be,a L2 + mov %o0, %i0 + + cmp %i1, %g0 + be,a L2 + mov %o0, %i1 + + cmp %i2, %g0 + be,a L2 + mov %o0, %i2 + + cmp %i3, %g0 + be,a L2 + mov %o0, %i3 + + cmp %i4, %g0 + be,a L2 + mov %o0, %i4 + + cmp %i5, %g0 + be,a L2 + mov %o0, %i5 +L2: + retl + nop + +/* FUNCTION int _nomem_find_ahb_bus( + * unsigned int bridge, + * int vendor_device, + * int index, + * void **pconf, + * int not_used, + * int option + * ) + * + * Scans the AHB Master or Slave area for a matching VENDOR:DEVICE, the + * index is decremented when a matching device is found but index is + * greater than zero. When index is zero and a matching DEVICE:VENDOR + * is found the AHB configuration address and AHB I/O area is returned. + * + * i0-i7,l0,l1,l2,l3,l4,g2,o6 is not available for use. + * o1,o5 Must be left untouched + * + * Results + * - o0 Number of found devices (1 or 0) + * - o2 is decremented for each matching VENDOR:DEVICE found, zero if found + * - o3 Address of the AHB PnP configuration entry (Only valid if o0=1) + * + * Clobbered + * - o3 (Clobbered when no device was found) + * - o4 (Number of Devices left to search) + * - o0 (Bus ID, PnP ID, Device) + */ +_nomem_find_ahb_bus: + + /* Get the number of Slaves/Masters. + * Only AHB Bus 0 has 64 AHB Masters/Slaves the + * other AHB buses has 16 slaves and 16 masters. + */ + add %g0, 16, %o4 /* Defaulting to 16 */ + andcc %o0, 0x7, %g0 /* 3-bit bus id */ + be,a .L_maxloops_detected + add %g0, 64, %o4 /* AHB Bus 0 has 64 AHB Masters/Slaves */ +.L_maxloops_detected: + + /* Get start address of AHB Slave or AHB Master area depending on what + * we are searching for. + */ + andn %o0, 0x7ff, %o0 /* Remove Bus ID and 5-bit AHB/AHB + * Bridge PnP Address to get I/O Area */ + set AMBA_CONF_AREA, %o3 + or %o3, %o0, %o3 /* Master area address */ + + cmp %o5, DEV_AHB_SLV + be,a .L_conf_area_calculated + or %o3, AMBA_AHB_SLAVE_CONF_AREA, %o3 /* Add 0x800 to get to slave area */ +.L_conf_area_calculated: + + /* Iterate over all AHB device and try to find matching DEVICE:VENDOR + * o1 - VENDOR|DEVICE + * o2 - Index + * o3 - Current AHB Device Configuration address + * o5 - Type (leave untouched) + * + * o4 - Number of AHB device left to process + * o0 - tmp + */ +.L_process_one_conf: + ld [%o3], %o0 + andn %o0, 0xfff, %o0 + cmp %o0, 0 /* No device if zero */ + beq .L_next_conf + cmp %o1, 0 /* If VENDOR:DEVICE==0, consider all matching */ + beq .L_process_ahb_dev_found + cmp %o0, %o1 /* Does VENDOR and DEVICE Match? */ + bne .L_next_conf + nop +.L_process_ahb_dev_found: + /* Found a Matching VENDOR:DEVICE, index must also match */ + cmp %o2, %g0 + bne .L_next_conf + dec %o2 + /* Index matches also, return happy with o3 set to AHB Conf Address */ + mov %g0, %o2 + retl + add %g0, 1, %o0 + +.L_next_conf: + subcc %o4, 1, %o4 /* One device has been processed, + * Are there more devices to process? */ + bne .L_process_one_conf + add %o3, AMBA_AHB_CONF_LENGH, %o3 /* Next Configuration entry */ + /* No Matching device found */ + retl + mov %g0, %o0 + +/* FUNCTION int _nomem_find_ahb( + * int unused, + * int vendor_device, + * int index, + * void **pconf, + * int *ahb_bus_index, + * int option, + * ) + * + * Find a AHB Master or AHB Slave device, it puts the address of the AHB PnP + * configuration in o3 (pconf), the I/O Area base address in o4 (pioarea). + * + * Calls _nomem_find_ahb_bus for every AHB bus. + * + * i0-i7, l0, l1, o6, g1, g4-g7 is not available for use. + * + * Arguments + * - o0 Unused + * + * Results + * - o0 Number of found devices (1 or 0) + * - o2 Decremented Index (Zero if found) + * - o3 Address of the AHB PnP configuration entry + * - o4 AHB Bus index the device was found on (if o0=1) + * - o5 Left untouched + * + * Clobbered + * - o0 (AHB Bridge and used by _nomem_find_ahb_bus) + * - o2 (index is decremented) + * - l2 (Current AHB Bus index) + * - g2 (return address) + */ +_nomem_find_ahb: + mov %o7, %g2 /* Save return address */ + /* Scan all AHB Buses found for the AHB Master/Slave matching VENDOR:DEVICE */ + clr %l2 +.L_search_next_ahb_bus: + add %l2, 1, %l2 + call get_ahb_bridge /* Get bus %l0 I/O Area */ + mov %l2, %o0 + cmp %o0, %g0 + be .L_no_device_found /* If no more AHB bus is left to be scanned, proceed */ + nop + call _nomem_find_ahb_bus /* Scan AHB bus %o0 for VENDOR:DEVICE. Index in o3 is decremented */ + nop + cmp %o0, %g0 /* If VENDOR:DEVICE was not found scan next AHB Bus */ + be .L_search_next_ahb_bus /* Do next bus is o0=0 (not found) */ + nop + /* The device was found, o0 is 1 */ + mov %g2, %o7 /* Restore return address */ + retl + mov %l2, %o4 /* The AHB bus index the device was found on */ + + /* No device found matching */ +.L_no_device_found: + mov %g2, %o7 /* Restore return address */ + retl + mov %g0, %o0 + + +/* FUNCTION int _nomem_find_apb_bus( + * int apbmst, + * int vendor_device, + * int index, + * void **pconf + * ) + * + * Find a APB Slave device, it puts the address of the APB PnP configuration + * in o3 (pconf). + * + * Calls _nomem_find_ahb_bus for every AHB bus searching for AHB/APB Bridges. + * The AHB/APB bridges are AHB Slaves with ID GAISLER_APBMST. + * + * Results + * - o0 Number of found devices (1 or 0) + * - o2 Decremented Index + * - o3 Address of the found APB device PnP configuration entry + * + * Clobbered + * - o5 PnP VENDOR:DEVICE ID + */ + +_nomem_find_apb_bus: + set AMBA_CONF_AREA, %o3 + or %o0, %o3, %o3 /* Calc start of APB device PnP info */ + add %g0, 16, %o0 /* o0, number of APB Slaves left to scan */ +.L_process_one_apb_conf: + ld [%o3], %o5 + andn %o5, 0xfff, %o5 + cmp %o5, 0 /* No device if zero */ + beq .L_process_apb_dev_not_found + cmp %o1, 0 /* If VENDOR:DEVICE == -1, consider all matching */ + beq .L_process_apb_dev_found + cmp %o1, %o5 /* Found VENDOR:DEVICE */ + bne .L_process_apb_dev_not_found + nop + +.L_process_apb_dev_found: + /* Found matching device, compare index */ + cmp %o2, %g0 + bne .L_process_apb_dev_not_found + dec %o2 + /* Matching index and VENDOR:DEVICE */ + retl + add %g0, 1, %o0 + +.L_process_apb_dev_not_found: + subcc %o0, 1, %o0 + bne .L_process_one_apb_conf + add %o3, 8, %o3 + retl + mov %g0, %o0 + +/* FUNCTION int _nomem_find_apb( + * int unused, + * int vendor_device, + * int index, + * void **pconf, + * int *ahb_bus_index + * ) + * + * Find a APB Slave device, it puts the address of the APB PnP configuration + * in o3 (pconf), the APB Master I/O Area base address in o4 (papbarea). + * + * Calls _nomem_find_ahb_bus for every AHB bus searching for AHB/APB Bridges. + * The AHB/APB bridges are AHB Slaves with ID GAISLER_APBMST. + * + * i0-i7, l0, l1, o6 is not available for use. + * + * Arguments + * - o0 Unused + * + * Results + * - o0 Number of found devices (1 or 0) + * - o2 Decremented Index if not found + * - o3 Address of the APB PnP configuration entry + * - o4 AHB Bus index of APB Bridge/APB Device + * + * Clobbered + * - o0 (AHB Bridge) + * - o2 (index is decremented) + * - l2 (APB DEV Index [7..4] : APBMST AHB Index [3..0]) + * - l3 (Current AHB Bus index) + * - l4 (temporary storage for APB VENDOR:DEVICE) + * - o5 (AHB Slave ID) + * - o0 (clobbered by _nomem_find_ahb_bus) + * - g2 (Return address) + */ +_nomem_find_apb: + /* Scan all AHB Buses found for AHB/APB Bridges */ + mov %o7, %g2 /* Save return address */ + mov %o1, %l4 /* Save APB VENDOR:DEVICE */ + sll %o2, 4, %l2 /* APB MST index = 0 */ + add %g0, 1, %l3 /* AHB Bus index = 0 */ +.L2_search_next_ahb_bus: + call get_ahb_bridge /* Get bus %l3 I/O Area */ + mov %l3, %o0 + cmp %o0, %g0 + be .L2_no_device_found /* If no more AHB bus is left to be scanned, proceed */ + add %g0, DEV_AHB_SLV, %o5 /* Search for AHB Slave */ + sethi %hi(AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_APBMST)), %o1 + call _nomem_find_ahb_bus /* Scan AHB bus %o0 for VENDOR:DEVICE. Index in o3 is decremented */ + and %l2, 0xf, %o2 /* Set APBMST index */ + cmp %o0, %g0 /* If no AHB/APB Bridge was not found, scan next AHB Bus */ + be .L_no_apb_bridge_found /* Do next bus */ + nop + + /* The AHB/APB Bridge was found. + * Search for the requested APB Device on the APB bus using + * find_apb_bus, it will decrement the index. + */ + ld [%o3 + AMBA_AHB_MBAR0_OFS], %o3 + sll %o3, 16, %o0 + and %o0, %o3, %o0 /* Address AND Address Mask */ + sethi %hi(0xfff00000), %o3 + and %o0, %o3, %o0 /* AHB/APB Bridge address */ + + srl %l2, 4, %o2 /* APB DEV Index */ + call _nomem_find_apb_bus + mov %l4, %o1 /* APB VENDOR:DEVICE */ + cmp %o0, %g0 + be .L_apb_dev_not_found + mov %g2, %o7 /* Restore return address */ + /* APB Device found + * o0 1 + * o2 Index is decremented to zero + * o3 APB configuration address, + * o4 APB Bridge Configuration address. + */ + mov %g0, %o2 + retl + mov %l3, %o4 + +.L_apb_dev_not_found: + /* Update APB DEV Index by saving output from find_apb_bus + * (index parameter) into bits [31..4] in L2. + */ + sll %o2, 4, %o2 + and %l2, 0xf, %l2 + or %o2, %l2, %l2 + /* Try finding the next AHB/APB Bridge on the same AHB bus + * to find more APB devices + */ + ba .L2_search_next_ahb_bus /* Find next AHB/APB bridge */ + inc %l2 + +.L_no_apb_bridge_found: + inc %l3 /* Next AHB Bus */ + ba .L2_search_next_ahb_bus /* Process next AHB bus */ + andn %l2, 0xf, %l2 /* Start at APB Bridge index 0 at every AHB Bus */ + /* No device found matching */ +.L2_no_device_found: + mov %g2, %o7 /* Restore return address */ + srl %l2, 4, %o2 /* APB DEV Index */ + retl + mov %g0, %o0 + + + +/* FUNCTION _nomem_amba_scan_gaisler_ahb2ahb_bridge(unsigned int bridge, int bus) + * + * Constraints: + * - o1 may not be used + * - o0, o2, o3 may be used. + * + * Arguments + * - o0 PnP Address of Bridge AHB device + * - o2 PnP ID of AHB device + * + * Results + * - o0 Address of new bus PnP area or a 1 if AHB device is no bridge + * + * Clobbered + * - o0, o2 + * + */ +_nomem_amba_scan_gaisler_ahb2ahb_bridge: + andn %o2, 0xfff, %o2 + sethi %hi(AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_AHB2AHB)), %o3 + cmp %o2, %o3 + beq .L_is_ahb2ahb_bridge + nop + + retl + add %g0, 1, %o0 + +.L_is_ahb2ahb_bridge: + /* Found a GAISLER AHB2AHB bridge */ + retl + ld [%o0 + AMBA_AHB_CUSTOM1_OFS], %o0 /* Get address of bridge PnP area */ + + +/* FUNCTION _nomem_amba_scan_gaisler_l2cache_bridge(unsigned int bridge, int bus) + * + * Constraints: + * - o1 may not be used + * - o0, o2, o3 may be used. + * + * Arguments + * - o0 PnP Address of Bridge AHB device + * - o2 PnP ID of AHB device + * + * Results + * - o0 Address of new bus PnP area or a 1 if AHB device is no bridge + * + * Clobbered + * - o0, o2 + * + */ +_nomem_amba_scan_gaisler_l2cache_bridge: + andn %o2, 0xfff, %o2 + sethi %hi(AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_L2CACHE)), %o3 + cmp %o2, %o3 + beq .L_is_l2cache_bridge + nop + + retl + add %g0, 1, %o0 + +.L_is_l2cache_bridge: + /* Found a GAISLER l2cache bridge */ + retl + ld [%o0 + AMBA_AHB_CUSTOM1_OFS], %o0 /* Get address of bridge PnP area */ + + +/* FUNCTION _nomem_amba_scan(unsigned int bridge, int bus) + * + * Constraints: + * i0-i7, l0 is used by caller + * o5-o7 may not be used. + * + * Arguments + * - o0 Bridge Information: I/O AREA and parent bus + * - o1 Bus + * + * Results + * - o0 Number of AHB bridges found + * + * Clobbered + * - o0 (Current AHB slave conf address) + * - o2 (Used by insert_bridge) + * - o3 (Used by insert_bridge) + * - l1 (Number of AHB Slaves left to process) + * - l2 (Current AHB slave conf address) + * - g2 (Return address) + */ +_nomem_amba_scan: + mov %o7, %g2 /* Save return address */ + set 16, %l1 + cmp %o1, 1 + be,a .L2_maxloops_detected + add %g0, 64, %l1 +.L2_maxloops_detected: + + /* Clear 3-bit parent bus from bridge to get I/O AREA, then or + * (AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA) to get first AHB slave + * conf address. + */ + andn %o0, 0x7ff, %o0 + set (AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA), %l2 + or %o0, %l2, %l2 + + /* Scan AHB Slave area for AHB<->AHB bridges. For each AHB device + * all "bridge drivers" are called, the driver function interface: + * + * Input: + * - o0 PnP Address of Bridge AHB device + * - o2 PnP ID of AHB device + * Return values: + * - o0 Address of new bus PnP area, returning a 1 in o2 means not found + * + * Constraints: + * - o1 may not be used + * - o0, o2, o3 may be used. + * + */ +.L_scan_one_ahb_slave: + ld [%l2], %o2 + + cmp %o2, %g0 + beq .L_scan_next_ahb_slave + nop + + /* Call the GAISLER AHB2AHB bridge driver */ + call _nomem_amba_scan_gaisler_ahb2ahb_bridge + mov %l2, %o0 + cmp %o0, 1 + bne .L_found_bridge + ld [%l2], %o2 + + /* Call the GAISLER L2CACHE bridge driver */ + call _nomem_amba_scan_gaisler_l2cache_bridge + mov %l2, %o0 + cmp %o0, 1 + bne .L_found_bridge + ld [%l2], %o2 + + /* Insert next bridge "driver" function here */ + + + /* The PnP ID did not match a bridge - a new bus was not found ==> + * step to next AHB device */ + ba .L_scan_next_ahb_slave + nop + + /* Add Found bus */ +.L_found_bridge: + and %l2, 0x7e0, %o2 + or %o2, %o0, %o0 /* Add AHB/AHB Bridge PnP address */ + call insert_ahb_bridge /* Insert Bridge into found buses storage */ + or %o1, %o0, %o0 /* Add parent bus LSB 3-bits */ + +.L_scan_next_ahb_slave: + /* More Slaves to process? */ + subcc %l1, 1, %l1 + bne .L_scan_one_ahb_slave + add %l2, AMBA_AHB_CONF_LENGH, %l2 + + /* No more AHB devices to process */ + mov %g2, %o7 /* Restore return address */ + retl + nop + +/* FUNCTION _nomem_ambapp_find_buses(unsigned int ioarea) + * + * Find AMBA AHB buses. + * + * Constraints: + * i6-i7, l7 is used by caller + * + * Arguments + * - o0 Bridge Information: I/O AREA and parent bus + * + * Results + * - o0 Number of AHB bridges found + * - i0-i5 initialized + * + * Clobbered + * - o0 (Current AHB slave conf address) + * - o2 (Used by insert_bridge) + * - o3 (Used by insert_bridge) + * - l0 (Current AHB Bus) + * - l1 (Used by nomem_amba_scan) + * - l2 (Used by nomem_amba_scan) + * - l3 (Used by nomem_amba_scan) + * - l4 (Used by nomem_amba_scan) + * + * - g1 (level 1 return address) + * - g2 (Used by nomem_amba_scan) + */ +_nomem_ambapp_find_buses: + mov %o7, %g1 /* Save return address */ + + /* Initialize AHB Bus storage */ + call init_ahb_bridges + nop + + /* Insert AHB Bus 0 */ + call insert_ahb_bridge + nop /* Argument already prepared by caller */ + + /* Scan AHB Bus 0 for AHB Bridges */ + call _nomem_amba_scan + add %g0, 1, %o1 + + /* Scan all AHB Buses found for more AHB Bridges */ + add %g0, 2, %l0 +.L100_search_next_ahb_bus: + call get_ahb_bridge /* Get bus %l0 I/O Area */ + mov %l0, %o0 + cmp %o0, %g0 + be .L100_return /* If no more AHB bus is left to be scanned, proceed */ + nop + call _nomem_amba_scan /* Scan bus %l0 for AHB Bridges. i0-i7,l0 is used */ + mov %l0, %o1 /* I/O AREA untouched in o0 */ + ba .L100_search_next_ahb_bus /* Do next bus */ + add %l0, 1, %l0 + +.L100_return: + mov %g1, %o7 + retl + nop + + +/* FUNCTION _nomem_amba_init(unsigned int ioarea) + * + * Find all AHB buses + * + * Constraints: + * i6, i7, o6, o7, l7, l6, g3, g4, g5, g6, g7 is used by caller + * + * Arguments + * - o0 Bridge Information: I/O AREA and parent bus + * + * Results + * - o0 Number of AHB bridges found + * + * Clobbered + * - l0, l1, l2, l3, l4, g1, g2 (used by _nomem_ambapp_find_buses) + * - o0, o1, o2, o3 (Used as arguments) + * - o5 (return address) + * - g1 (level 1 return address) + * - g2 (level 2 return address) + */ +_nomem_amba_init: + mov %o7, %o5 /* Save return address, o5 not used */ + + /* Scan for buses, it will init i0-i5 */ + call _nomem_ambapp_find_buses + nop + + mov %o5, %o7 + retl + nop + +/* Call tree and their return address register + * + *_nomem_amba_scan (g1) + * -> init_ahb_bridges (o7) + * -> insert_ahb_bridge (o7) + * -> _nomem_amba_scan (g2) + * -> insert_ahb_bridge (o7) + * -> get_ahb_bridge (o7) + * + * + * -> _nomem_find_apb (g2) + * -> get_ahb_bridge (o7) + * -> _nomem_find_ahb_bus (o7) + * -> _nomem_find_apb_bus (o7) + * -> _nomem_find_ahb (g2) + * -> get_ahb_bridge (o7) + * -> _nomem_find_ahb_bus (o7) + * -> mem_handler.func() (o7) + * + */ diff --git a/arch/sparc/cpu/leon3/ambapp_low_c.S b/arch/sparc/cpu/leon3/ambapp_low_c.S new file mode 100644 index 0000000000..42288fac59 --- /dev/null +++ b/arch/sparc/cpu/leon3/ambapp_low_c.S @@ -0,0 +1,113 @@ +/* C-interface for AMBA PnP scanning functions implemented in + * ambapp_low.S. At the point the memory and stack can be + * used. + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + + .seg "text" + .extern _nomem_ambapp_find_buses + .extern _nomem_find_apb + .extern _nomem_find_ahb + + .globl ambapp_find_buses + .globl ambapp_find_apb + .globl ambapp_find_ahb + + +/* C-interface for _nomem_ambapp_find_buses used when memory is available. + */ +ambapp_find_buses: + save %sp, -104, %sp + mov %i1, %l7 /* Save second argument */ + call _nomem_ambapp_find_buses + mov %i0, %o0 + + /* Store result */ + st %g0, [%l7+0x00] + st %i0, [%l7+0x04] + st %i1, [%l7+0x08] + st %i2, [%l7+0x0c] + st %i3, [%l7+0x10] + st %i4, [%l7+0x14] + st %i5, [%l7+0x18] + + ret + restore + +/* C-interface for _nomem_find_apb used when memory is available. + * + * void ambapp_find_apb( + * struct ambapp_bus *abus, + * unsigned int dev_vend, + * int index, + * struct ambapp_find_apb_info *result + * ); + * + */ +ambapp_find_apb: + save %sp, -104, %sp + + mov %i3, %l7 /* Save second argument */ + mov %i1, %o1 + mov %i2, %o2 + + /* Initialize buses available in system */ + ld [%i0+0x08], %i1 + ld [%i0+0x0c], %i2 + ld [%i0+0x10], %i3 + ld [%i0+0x14], %i4 + ld [%i0+0x18], %i5 + + call _nomem_find_apb + ld [%i0+0x04], %i0 + + st %o2, [%l7+0x08] /* Decremented Index */ + st %o3, [%l7] /* PnP configuration address of APB Device */ + st %o4, [%l7+0x04] /* AHB Bus Index of AHB/APB bridge and APB Device */ + mov %o0, %i0 + ret + restore + +/* C-interface for _nomem_find_ahb used when memory is available. + * + * void ambapp_find_ahb( + * struct ambapp_bus *abus, + * unsigned int dev_vend, + * int index, + * int type, + * struct ambapp_find_ahb_info *result + * ); + * + */ +ambapp_find_ahb: + save %sp, -104, %sp + + mov %i4, %l7 /* Save second argument */ + clr %o0 + mov %i1, %o1 + mov %i2, %o2 + clr %o3 + clr %o4 + mov %i3, %o5 + + /* Initialize buses available in system */ + ld [%i0+0x08], %i1 + ld [%i0+0x0c], %i2 + ld [%i0+0x10], %i3 + ld [%i0+0x14], %i4 + ld [%i0+0x18], %i5 + + call _nomem_find_ahb + ld [%i0+0x04], %i0 + + st %o2, [%l7+0x08] /* Decremented Index */ + st %o3, [%l7] /* PnP configuration address of AHB Device */ + st %o4, [%l7+0x04] /* AHB Bus Index of AHB Device */ + mov %o0, %i0 + ret + restore diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c index 2f41d8847b..b140da31b1 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/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+ */ @@ -11,9 +11,17 @@ #include <asm/asi.h> #include <asm/leon.h> #include <ambapp.h> +#include <grlib/irqmp.h> +#include <grlib/gptimer.h> +#include <debug_uart.h> #include <config.h> +/* Default Plug&Play I/O area */ +#ifndef CONFIG_AMBAPP_IOAREA +#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA +#endif + #define TIMER_BASE_CLK 1000000 #define US_PER_TICK (1000000 / CONFIG_SYS_HZ) @@ -22,11 +30,7 @@ DECLARE_GLOBAL_DATA_PTR; /* reset CPU (jump to 0, without reset) */ void start(void); -/* find & initialize the memory controller */ -int init_memory_ctrl(void); - ambapp_dev_irqmp *irqmp = NULL; -ambapp_dev_mctrl memctrl; ambapp_dev_gptimer *gptimer = NULL; unsigned int gptimer_irq = 0; int leon3_snooping_avail = 0; @@ -39,64 +43,32 @@ struct { /* * Breath some life into the CPU... * - * Set up the memory map, - * initialize a bunch of registers. - * * Run from FLASH/PROM: * - until memory controller is set up, only registers available + * - memory controller has already been setup up, stack can be used * - no global variables available for writing * - constants available */ - void cpu_init_f(void) { - /* these varaiable must not be initialized */ - ambapp_dev_irqmp *irqmp; - ambapp_apbdev apbdev; - register unsigned int apbmst; - - /* find AMBA APB Master */ - apbmst = (unsigned int) - ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0); - if (!apbmst) { - /* - * no AHB/APB bridge, something is wrong - * ==> jump to start (or hang) - */ - while (1) ; - } - /* Init memory controller */ - if (init_memory_ctrl()) { - while (1) ; - } - - /**************************************************** - * From here we can use the main memory and the stack. - */ - - /* Find AMBA APB IRQMP Controller */ - if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev) != 1) { - /* no IRQ controller, something is wrong - * ==> jump to start (or hang) - */ - while (1) ; - } - irqmp = (ambapp_dev_irqmp *) apbdev.address; - - /* initialize the IRQMP */ - irqmp->ilevel = 0xf; /* all IRQ off */ - irqmp->iforce = 0; - irqmp->ipend = 0; - irqmp->iclear = 0xfffe; /* clear all old pending interrupts */ - irqmp->cpu_mask[0] = 0; /* mask all IRQs on CPU 0 */ - irqmp->cpu_force[0] = 0; /* no force IRQ on CPU 0 */ - - /* cache */ +#ifdef CONFIG_DEBUG_UART + debug_uart_init(); +#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) { - + /* 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); } /* @@ -105,95 +77,58 @@ 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; /* * 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; - - /* timer */ - if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_GPTIMER, &apbdev) != 1) { - printf("cpu_init_r: gptimer not found!\n"); - 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; - - return (0); -} - -/* find & setup memory controller */ -int init_memory_ctrl() -{ - register ambapp_dev_mctrl *mctrl; - register ambapp_dev_sdctrl *sdctrl; - register ambapp_dev_ddrspa *ddrspa; - register ambapp_dev_ddr2spa *ddr2spa; - register ahbctrl_pp_dev *ahb; - register unsigned int base; - register int not_found_mctrl = -1; - - /* find ESA Memory controller */ - base = ambapp_apb_next_nomem(VENDOR_ESA, ESA_MCTRL, 0); - if (base) { - mctrl = (ambapp_dev_mctrl *) base; - - /* config MCTRL memory controller */ - mctrl->mcfg1 = CONFIG_SYS_GRLIB_MEMCFG1 | (mctrl->mcfg1 & 0x300); - mctrl->mcfg2 = CONFIG_SYS_GRLIB_MEMCFG2; - mctrl->mcfg3 = CONFIG_SYS_GRLIB_MEMCFG3; - not_found_mctrl = 0; + if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, + GAISLER_IRQMP, 0, &apbdev) != 1) { + panic("%s: IRQ controller not found\n", __func__); + return -1; } + irqmp = (ambapp_dev_irqmp *)apbdev.address; - /* find Gaisler Fault Tolerant Memory controller */ - base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_FTMCTRL, 0); - if (base) { - mctrl = (ambapp_dev_mctrl *) base; - - /* config MCTRL memory controller */ - mctrl->mcfg1 = CONFIG_SYS_GRLIB_FT_MEMCFG1 | (mctrl->mcfg1 & 0x300); - mctrl->mcfg2 = CONFIG_SYS_GRLIB_FT_MEMCFG2; - mctrl->mcfg3 = CONFIG_SYS_GRLIB_FT_MEMCFG3; - not_found_mctrl = 0; + /* initialize the IRQMP */ + irqmp->ilevel = 0xf; /* all IRQ off */ + irqmp->iforce = 0; + irqmp->ipend = 0; + irqmp->iclear = 0xfffe; /* clear all old pending interrupts */ + for (cpu = 0; cpu < 16; cpu++) { + /* mask and clear force for all IRQs on CPU[N] */ + irqmp->cpu_mask[cpu] = 0; + irqmp->cpu_force[cpu] = 0; } - /* find SDRAM controller */ - base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_SDCTRL, 0); - if (base) { - sdctrl = (ambapp_dev_sdctrl *) base; - - /* config memory controller */ - sdctrl->sdcfg = CONFIG_SYS_GRLIB_SDRAM; - not_found_mctrl = 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); - ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDR2SPA, 1, 0); - if (ahb) { - ddr2spa = (ambapp_dev_ddr2spa *) ambapp_ahb_get_info(ahb, 1); + /* initialize prescaler common to all timers to 1MHz */ + timer->scalar = timer->scalar_reload = + (((bus_freq / 1000) + 500) / 1000) - 1; - /* Config DDR2 memory controller */ - ddr2spa->cfg1 = CONFIG_SYS_GRLIB_DDR2_CFG1; - ddr2spa->cfg3 = CONFIG_SYS_GRLIB_DDR2_CFG3; - not_found_mctrl = 0; + index++; } - - ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDRSPA, 1, 0); - if (ahb) { - ddrspa = (ambapp_dev_ddrspa *) ambapp_ahb_get_info(ahb, 1); - - /* Config DDR memory controller */ - ddrspa->ctrl = CONFIG_SYS_GRLIB_DDR_CFG; - not_found_mctrl = 0; + if (!gptimer) { + printf("%s: gptimer not found!\n", __func__); + return 1; } - - /* failed to find any memory controller */ - return not_found_mctrl; + return 0; } /* Uses Timer 0 to get accurate @@ -216,8 +151,8 @@ int timer_interrupt_init_cpu(void) gptimer->e[0].val = 0; gptimer->e[0].rld = (TIMER_BASE_CLK / CONFIG_SYS_HZ) - 1; gptimer->e[0].ctrl = - (LEON3_GPTIMER_EN | - LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN); + (GPTIMER_CTRL_EN | GPTIMER_CTRL_RS | + GPTIMER_CTRL_LD | GPTIMER_CTRL_IE); return gptimer_irq; } diff --git a/arch/sparc/cpu/leon3/interrupts.c b/arch/sparc/cpu/leon3/interrupts.c index a834aa024b..2312b58d29 100644 --- a/arch/sparc/cpu/leon3/interrupts.c +++ b/arch/sparc/cpu/leon3/interrupts.c @@ -23,6 +23,8 @@ #include <asm/leon.h> #include <ambapp.h> +#include <grlib/irqmp.h> +#include <grlib/gptimer.h> /* 15 normal irqs and a non maskable interrupt */ #define NR_IRQS 15 @@ -125,9 +127,8 @@ int interrupt_init_cpu(void) /* Handle Timer 0 IRQ */ void timer_interrupt_cpu(void *arg) { - gptimer->e[0].ctrl = (LEON3_GPTIMER_EN | - LEON3_GPTIMER_RL | - LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN); + gptimer->e[0].ctrl = (GPTIMER_CTRL_EN | GPTIMER_CTRL_RS | + GPTIMER_CTRL_LD | GPTIMER_CTRL_IE); /* nothing to do here */ return; } diff --git a/arch/sparc/cpu/leon3/memcfg.c b/arch/sparc/cpu/leon3/memcfg.c new file mode 100644 index 0000000000..b9eda440e2 --- /dev/null +++ b/arch/sparc/cpu/leon3/memcfg.c @@ -0,0 +1,237 @@ +/* GRLIB Memory controller setup. The register values are used + * from the associated low level assembler routine implemented + * in memcfg_low.S. + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <ambapp.h> +#include "memcfg.h" +#include <config.h> + +#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL1 +struct mctrl_setup esa_mctrl1_cfg = { + .reg_mask = 0x7, + .regs = { + { + .mask = 0x00000300, + .value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3, + }, + } +}; +#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL2 +struct mctrl_setup esa_mctrl2_cfg = { + .reg_mask = 0x7, + .regs = { + { + .mask = 0x00000300, + .value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG1, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG2, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG3, + }, + } +}; +#endif +#endif + +#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 +struct mctrl_setup gaisler_ftmctrl1_cfg = { + .reg_mask = 0x7, + .regs = { + { + .mask = 0x00000300, + .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3, + }, + } +}; +#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2 +struct mctrl_setup gaisler_ftmctrl2_cfg = { + .reg_mask = 0x7, + .regs = { + { + .mask = 0x00000300, + .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG1, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG2, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG3, + }, + } +}; +#endif +#endif + +#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 +struct mctrl_setup gaisler_sdctrl1_cfg = { + .reg_mask = 0x1, + .regs = { + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_SDCTRL1_CTRL, + }, + } +}; +#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL2 +struct mctrl_setup gaisler_sdctrl2_cfg = { + .reg_mask = 0x1, + .regs = { + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_SDCTRL2_CTRL, + }, + } +}; +#endif +#endif + +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 +struct ahbmctrl_setup gaisler_ddr2spa1_cfg = { + .ahb_mbar_no = 1, + .reg_mask = 0xd, + .regs = { + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG1, + }, + { 0x00000000, 0}, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG3, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG4, + }, + } +}; +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2 +struct ahbmctrl_setup gaisler_ddr2spa2_cfg = { + .ahb_mbar_no = 1, + .reg_mask = 0xd, + .regs = { + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG1, + }, + { 0x00000000, 0}, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG3, + }, + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG4, + }, + } +}; +#endif +#endif + +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 +struct ahbmctrl_setup gaisler_ddrspa1_cfg = { + .ahb_mbar_no = 1, + .reg_mask = 0x1, + .regs = { + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDRSPA1_CTRL, + }, + } +}; +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA2 +struct ahbmctrl_setup gaisler_ddrspa2_cfg = { + .ahb_mbar_no = 1, + .reg_mask = 0x1, + .regs = { + { + .mask = 0x00000000, + .value = CONFIG_SYS_GRLIB_GAISLER_DDRSPA2_CTRL, + }, + } +}; +#endif +#endif + +struct grlib_mctrl_handler grlib_mctrl_handlers[] = { +/* ESA MCTRL (PROM/FLASH/IO/SRAM/SDRAM) */ +#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL1 + {DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_ESA, ESA_MCTRL), + _nomem_mctrl_init, (void *)&esa_mctrl1_cfg}, +#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL2 + {DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_ESA, ESA_MCTRL), + _nomem_mctrl_init, (void *)&esa_mctrl2_cfg}, +#endif +#endif + +/* GAISLER Fault Tolerant Memory controller (PROM/FLASH/IO/SRAM/SDRAM) */ +#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 + {DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_FTMCTRL), + _nomem_mctrl_init, (void *)&gaisler_ftmctrl1_cfg}, +#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2 + {DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_FTMCTRL), + _nomem_mctrl_init, (void *)&gaisler_ftmctrl2_cfg}, +#endif +#endif + +/* GAISLER SDRAM-only Memory controller (SDRAM) */ +#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 + {DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_SDCTRL), + _nomem_mctrl_init, (void *)&gaisler_sdctrl1_cfg}, +#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL2 + {DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_SDCTRL), + _nomem_mctrl_init, (void *)&gaisler_sdctrl2_cfg}, +#endif +#endif + +/* GAISLER DDR Memory controller (DDR) */ +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 + {DEV_AHB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDRSP), + _nomem_ahbmctrl_init, (void *)&gaisler_ddrspa1_cfg}, +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA2 + {DEV_AHB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDRSP), + _nomem_ahbmctrl_init, (void *)&gaisler_ddrspa2_cfg}, +#endif +#endif + +/* GAISLER DDR2 Memory controller (DDR2) */ +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 + {DEV_AHB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDR2SP), + _nomem_ahbmctrl_init, (void *)&gaisler_ddr2spa1_cfg}, +#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2 + {DEV_AHB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDR2SP), + _nomem_ahbmctrl_init, (void *)&gaisler_ddr2spa2_cfg}, +#endif +#endif + + /* Mark end */ + MH_END +}; diff --git a/arch/sparc/cpu/leon3/memcfg.h b/arch/sparc/cpu/leon3/memcfg.h new file mode 100644 index 0000000000..a524896e5a --- /dev/null +++ b/arch/sparc/cpu/leon3/memcfg.h @@ -0,0 +1,90 @@ +/* GRLIB Memory controller setup structures + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __MEMCFG_H__ +#define __MEMCFG_H__ + +/*********** Low Level Memory Controller Initalization ***********/ + +#ifndef __ASSEMBLER__ + +struct grlib_mctrl_handler; + +typedef void (*mctrl_handler_t)( + struct grlib_mctrl_handler *dev, + void *conf, + unsigned int ioarea + ); + +/* Memory Controller Handler Structure */ +struct grlib_mctrl_handler { + unsigned char type; /* 0x00. MASK: AHB MST&SLV, APB SLV */ + char index; /* 0x01. Unit number, 0, 1, 2... */ + char unused[2]; /* 0x02 */ + unsigned int ven_dev; /* 0x04. Device and Vendor */ + mctrl_handler_t func; /* 0x08. Memory Controller Handler */ + void *priv; /* 0x0c. Optional private data, ptr to + * info how to set up controller */ +}; + +extern struct grlib_mctrl_handler grlib_mctrl_handlers[]; + +#endif + +#define MH_STRUCT_SIZE (4*4) +#define MH_TYPE 0x00 +#define MH_INDEX 0x01 +#define MH_VENDOR_DEVICE 0x04 +#define MH_FUNC 0x08 +#define MH_PRIV 0x0c + +#define MH_TYPE_NONE DEV_NONE +#define MH_TYPE_AHB_MST DEV_AHB_MST +#define MH_TYPE_AHB_SLV DEV_AHB_SLV +#define MH_TYPE_APB_SLV DEV_APB_SLV + +#define MH_UNUSED {0, 0} +#define MH_END {DEV_NONE, 0, MH_UNUSED, AMBA_PNP_ID(0, 0), 0, 0} + +/*********** Low Level Memory Controller Initalization Handlers ***********/ + +#ifndef __ASSEMBLER__ +extern void _nomem_mctrl_init( + struct grlib_mctrl_handler *dev, + void *conf, + unsigned int ioarea_apbmst); + +struct mctrl_setup { + unsigned int reg_mask; /* Which registers to write */ + struct { + unsigned int mask; /* Mask used keep reg bits unchanged */ + unsigned int value; /* Value written to register */ + } regs[8]; +}; + +extern void _nomem_ahbmctrl_init( + struct grlib_mctrl_handler *dev, + void *conf, + unsigned int ioarea_apbmst); + +struct ahbmctrl_setup { + int ahb_mbar_no; /* MBAR to get register address from */ + unsigned int reg_mask; /* Which registers to write */ + struct { + unsigned int mask; /* Mask used keep reg bits unchanged */ + unsigned int value; /* Value written to register */ + } regs[8]; +}; +#endif + +/* mctrl_setup data structure defines */ +#define NREGS_OFS 0 +#define REGS_OFS 0x4 +#define REGS_SIZE 8 + +#endif diff --git a/arch/sparc/cpu/leon3/memcfg_low.S b/arch/sparc/cpu/leon3/memcfg_low.S new file mode 100644 index 0000000000..84a81a90a9 --- /dev/null +++ b/arch/sparc/cpu/leon3/memcfg_low.S @@ -0,0 +1,253 @@ +/* This is the memory initialization functions, the function + * implemented below initializes each memory controller + * found and specified by the input grlib_mctrl_handler structure. + * + * After the memory controllers have been initialized the stack + * can be used. + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <ambapp.h> +#include "memcfg.h" +#include <config.h> + + .seg "text" + .globl _nomem_memory_ctrl_init + .globl _nomem_mctrl_init, _nomem_ahbmctrl_init + .extern _nomem_find_apb + .extern _nomem_find_ahb + + +/* FUNCTION + * _nomem_memory_controller_init(struct grlib_mctrl_handler *mem_handlers) + * + * Initialize AMBA devices, _nomem_amba_init() has prepared i0-i5 + * with the AHB buses on the system. + * + * For each entry in mem_handlers find the VENDOR:DEVICE and handle it + * by calling the handler function pointer. + * + * Constraints: + * i6, i7, o6, l7, l6, g3, g4, g5, g6, g7 is used by caller + * o7 is return address + * l5 reserved for this function for future use. + * + * Arguments + * - o0 Pointer to memory handler array + * + * Results + * - o0 Number of memory controllers found + * + * Clobbered + * - o0 (Current AHB slave conf address) + * - l0 (mem handler entry address) + * - l1 (Return value, number of memory controllers found) + * - o7 (function pointer) + * - l0, l1, l2, l3, l4, g1, g2 (used by _nomem_ambapp_find_buses) + * - o0, o1, o2, o3, o4, o5 (Used as arguments) + * + * - g1 ( level 1 return address) + * - g2 ( level 2 return address) + */ + +_nomem_memory_ctrl_init: + /* At this point all AHB buses has been found and the I/O Areas of + * all AHB buses is stored in the i0-i5 registers. Max 6 buses. Next, + * memory controllers are found by searching all buses for matching + * VENDOR:DEVICE. The VENDOR:DEVICE to search for are taken from the + * mem_handlers array. For each match the function pointer stored in + * the mem_handler entry is called to handle the hardware setup. + */ + mov %o7, %g1 /* Save return address */ + mov %o0, %l0 + mov %g0, %l1 /* The return value */ + +.L_do_one_mem_handler: + ld [%l0 + MH_FUNC], %o7 + cmp %o7, %g0 + be .L_all_mctrl_handled + nop + + /*** Scan for memory controller ***/ + + /* Set up argments, o5 not used by _nomem_find_apb */ + ldub [%l0 + MH_TYPE], %o5 + clr %o4 + clr %o3 + ldub [%l0 + MH_INDEX], %o2 + ld [%l0 + MH_VENDOR_DEVICE], %o1 + + /* An empty config? */ + cmp %o5, DEV_NONE + beq .L_all_mctrl_next + + /* Select function (APB or AHB) */ + cmp %o5, DEV_APB_SLV + bne .L_find_ahb_memctrl + clr %o0 +.L_find_apb_memctrl: + call _nomem_find_apb /* Scan for APB slave device */ + nop + + /* o3 = iobar address + * o4 = AHB Bus index + * + * REG ADR = ((iobar >> 12) & (iobar << 4) & 0xfff00) | "APB Base" + */ + ld [%o3 + AMBA_APB_IOBAR_OFS], %o5 + srl %o5, 12, %o2 + sll %o5, 4, %o5 + and %o2, %o5, %o5 + set 0xfff00, %o2 + and %o2, %o5, %o5 + sethi %hi(0xfff00000), %o2 + and %o3, %o2, %o2 + or %o5, %o2, %o5 /* Register base address */ + + ba .L_call_one_mem_handler + nop + +.L_find_ahb_memctrl: + call _nomem_find_ahb /* Scan for AHB Slave or Master. + * o5 determine type. */ + nop + clr %o5 + + /* Call the handler function if the hardware was found + * + * o0 = mem_handler + * o1 = Configuration address + * o2 = AHB Bus index + * o3 = APB Base register (if APB Slave) + * + * Constraints: + * i0-i7, l0, l1, l5, g1, g3-g7 may no be used. + */ +.L_call_one_mem_handler: + cmp %o0, %g0 + be .L_all_mctrl_next + mov %l0, %o0 /* Mem handler pointer */ + mov %o3, %o1 /* AMBA PnP Configuration address */ + mov %o4, %o2 /* AHB Bus index */ + ld [%l0 + MH_FUNC], %o7 /* Get Function pointer */ + call %o7 + mov %o5, %o3 /* APB Register Base Address */ + + inc %l1 /* Number of Memory controllers + * handled. */ + + /* Do next entry in mem_handlers */ +.L_all_mctrl_next: + ba .L_do_one_mem_handler + add %l0, MH_STRUCT_SIZE, %l0 + +.L_all_mctrl_handled: + mov %g1, %o7 /* Restore return address */ + retl + mov %l1, %o0 + + + +/* Generic Memory controller initialization routine (APB Registers) + * + * o0 = mem_handler structure pointer + * o1 = Configuration address + * o2 = AHB Bus index + * o3 = APB Base register + * + * Clobbered + * o0-o4 + */ +_nomem_mctrl_init: + ld [%o0 + MH_PRIV], %o0 /* Get Private structure */ + ld [%o0], %o1 /* Get Reg Mask */ + and %o1, 0xff, %o1 + add %o0, REGS_OFS, %o0 /* Point to first reg */ +.L_do_one_reg: + andcc %o1, 0x1, %g0 + beq .L_do_next_reg + ld [%o0], %o2 + ld [%o3], %o4 + and %o4, %o2, %o4 + ld [%o0 + 4], %o2 + or %o4, %o2, %o4 + st %o4, [%o3] + +.L_do_next_reg: + add %o0, REGS_SIZE, %o0 + add %o3, 4, %o3 + srl %o1, 1, %o1 + cmp %o1, 0 + bne .L_do_one_reg + nop + + /* No more registers to write */ + retl + nop + + + +/* Generic Memory controller initialization routine (AHB Registers) + * + * o0 = mem_handler structure pointer + * o1 = Configuration address of memory controller + * o2 = AHB Bus index + * + * Clobbered + * o0-o5 + */ +_nomem_ahbmctrl_init: + ld [%o0 + MH_PRIV], %o0 /* Get Private structure */ + + /* Get index of AHB MBAR to get registers from */ + ld [%o0], %o5 + add %o0, 4, %o0 + + /* Get Address of MBAR in PnP info */ + add %o5, 4, %o5 + sll %o5, 2, %o5 + add %o5, %o1, %o5 /* Address of MBAR */ + + /* Get Address of registers from PnP information + * Address is in AHB I/O format, i.e. relative to bus + * + * ADR = (iobar & (iobar << 16) & 0xfff00000) + * IOADR = (ADR >> 12) | "APB Base" + */ + ld [%o5], %o5 + sll %o5, 16, %o4 + and %o5, %o4, %o5 + sethi %hi(0xfff00000), %o4 + and %o5, %o4, %o5 /* ADR */ + and %o4, %o1, %o4 + srl %o5, 12, %o5 + or %o5, %o4, %o3 /* IOADR in o3 */ + + ld [%o0], %o1 /* Get Reg Mask */ + and %o1, 0xff, %o1 + add %o0, REGS_OFS, %o0 /* Point to first reg */ +.L_do_one_ahbreg: + andcc %o1, 0x1, %g0 + beq .L_do_next_reg + ld [%o0], %o2 + ld [%o3], %o4 + and %o4, %o2, %o4 + ld [%o0 + 4], %o2 + or %o4, %o2, %o4 + st %o4, [%o3] + +.L_do_next_ahbreg: + add %o0, REGS_SIZE, %o0 + add %o3, 4, %o3 + srl %o1, 1, %o1 + cmp %o1, 0 + bne .L_do_one_reg + nop + + /* No more registers to write */ + retl + nop diff --git a/arch/sparc/cpu/leon3/prom.c b/arch/sparc/cpu/leon3/prom.c index b83776bc06..c391be7420 100644 --- a/arch/sparc/cpu/leon3/prom.c +++ b/arch/sparc/cpu/leon3/prom.c @@ -15,13 +15,17 @@ #include <asm/irq.h> #include <asm/leon.h> #include <ambapp.h> +#include <grlib/apbuart.h> +#include <grlib/irqmp.h> +#include <grlib/gptimer.h> #include <config.h> /* #define PRINT_ROM_VEC */ extern struct linux_romvec *kernel_arg_promvec; -extern ambapp_dev_apbuart *leon3_apbuart; + +DECLARE_GLOBAL_DATA_PTR; #define PROM_PGT __attribute__ ((__section__ (".prom.pgt"))) #define PROM_TEXT __attribute__ ((__section__ (".prom.text"))) @@ -740,14 +744,14 @@ static int PROM_TEXT leon_nbputchar(int c) /* Wait for last character to go. */ while (!(SPARC_BYPASS_READ(&uart->status) - & LEON_REG_UART_STATUS_THE)) ; + & APBUART_STATUS_THE)); /* Send data */ SPARC_BYPASS_WRITE(&uart->data, c); /* Wait for data to be sent */ while (!(SPARC_BYPASS_READ(&uart->status) - & LEON_REG_UART_STATUS_TSE)) ; + & APBUART_STATUS_TSE)); return 0; } @@ -909,7 +913,7 @@ void leon_prom_init(struct leon_prom_info *pspi) pspi->avail.num_bytes = pspi->totphys.num_bytes; /* Set the pointer to the Console UART in romvec */ - pspi->reloc_funcs.leon3_apbuart = leon3_apbuart; + pspi->reloc_funcs.leon3_apbuart = gd->arch.uart; { int j = 1; diff --git a/arch/sparc/cpu/leon3/serial.c b/arch/sparc/cpu/leon3/serial.c index bca6b6548b..66b3773027 100644 --- a/arch/sparc/cpu/leon3/serial.c +++ b/arch/sparc/cpu/leon3/serial.c @@ -1,66 +1,79 @@ /* GRLIB APBUART Serial controller driver * - * (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+ */ #include <common.h> -#include <asm/processor.h> -#include <asm/leon.h> +#include <asm/io.h> #include <ambapp.h> +#include <grlib/apbuart.h> #include <serial.h> -#include <linux/compiler.h> +#include <watchdog.h> DECLARE_GLOBAL_DATA_PTR; -ambapp_dev_apbuart *leon3_apbuart = NULL; +/* Select which UART that will become u-boot console */ +#ifndef CONFIG_SYS_GRLIB_APBUART_INDEX +#define CONFIG_SYS_GRLIB_APBUART_INDEX 0 +#endif static int leon3_serial_init(void) { + ambapp_dev_apbuart *uart; ambapp_apbdev apbdev; unsigned int tmp; /* find UART */ - if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) == 1) { + if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_APBUART, + CONFIG_SYS_GRLIB_APBUART_INDEX, &apbdev) != 1) { + panic("%s: apbuart not found!\n", __func__); + return -1; /* didn't find hardware */ + } - leon3_apbuart = (ambapp_dev_apbuart *) apbdev.address; + /* found apbuart, let's init .. */ + uart = (ambapp_dev_apbuart *) apbdev.address; - /* found apbuart, let's init... - * - * Set scaler / baud rate - * - * Receiver & transmitter enable - */ - leon3_apbuart->scaler = CONFIG_SYS_GRLIB_APBUART_SCALER; + /* Set scaler / baud rate */ + tmp = (((CONFIG_SYS_CLK_FREQ*10) / (CONFIG_BAUDRATE*8)) - 5)/10; + writel(tmp, &uart->scaler); - /* Let bit 11 be unchanged (debug bit for GRMON) */ - tmp = READ_WORD(leon3_apbuart->ctrl); + /* Let bit 11 be unchanged (debug bit for GRMON) */ + tmp = readl(&uart->ctrl) & APBUART_CTRL_DBG; + /* Receiver & transmitter enable */ + tmp |= APBUART_CTRL_RE | APBUART_CTRL_TE; + writel(tmp, &uart->ctrl); - leon3_apbuart->ctrl = ((tmp & LEON_REG_UART_CTRL_DBG) | - LEON_REG_UART_CTRL_RE | - LEON_REG_UART_CTRL_TE); + gd->arch.uart = uart; + return 0; +} - return 0; - } - return -1; /* didn't find hardware */ +static inline ambapp_dev_apbuart *leon3_get_uart_regs(void) +{ + ambapp_dev_apbuart *uart = gd->arch.uart; + return uart; } static void leon3_serial_putc_raw(const char c) { - if (!leon3_apbuart) + ambapp_dev_apbuart * const uart = leon3_get_uart_regs(); + + if (!uart) return; /* Wait for last character to go. */ - while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_THE)) ; + while (!(readl(&uart->status) & APBUART_STATUS_THE)) + WATCHDOG_RESET(); /* Send data */ - leon3_apbuart->data = c; + writel(c, &uart->data); #ifdef LEON_DEBUG /* Wait for data to be sent */ - while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_TSE)) ; + while (!(readl(&uart->status) & APBUART_STATUS_TSE)) + WATCHDOG_RESET(); #endif } @@ -74,36 +87,44 @@ static void leon3_serial_putc(const char c) static int leon3_serial_getc(void) { - if (!leon3_apbuart) + ambapp_dev_apbuart * const uart = leon3_get_uart_regs(); + + if (!uart) return 0; /* Wait for a character to arrive. */ - while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_DR)) ; + while (!(readl(&uart->status) & APBUART_STATUS_DR)) + WATCHDOG_RESET(); - /* read data */ - return READ_WORD(leon3_apbuart->data); + /* Read character data */ + return readl(&uart->data); } static int leon3_serial_tstc(void) { - if (leon3_apbuart) - return (READ_WORD(leon3_apbuart->status) & - LEON_REG_UART_STATUS_DR); - return 0; + ambapp_dev_apbuart * const uart = leon3_get_uart_regs(); + + if (!uart) + return 0; + + return readl(&uart->status) & APBUART_STATUS_DR; } /* set baud rate for uart */ static void leon3_serial_setbrg(void) { - /* update baud rate settings, read it from gd->baudrate */ + ambapp_dev_apbuart * const uart = leon3_get_uart_regs(); unsigned int scaler; - if (leon3_apbuart && (gd->baudrate > 0)) { - scaler = - (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) - - 5) / 10; - leon3_apbuart->scaler = scaler; - } - return; + + if (!uart) + return; + + if (!gd->baudrate) + gd->baudrate = CONFIG_BAUDRATE; + + scaler = (((CONFIG_SYS_CLK_FREQ*10) / (gd->baudrate*8)) - 5)/10; + + writel(scaler, &uart->scaler); } static struct serial_device leon3_serial_drv = { @@ -126,3 +147,26 @@ __weak struct serial_device *default_serial_console(void) { return &leon3_serial_drv; } + +#ifdef CONFIG_DEBUG_UART_APBUART + +#include <debug_uart.h> + +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->ctrl = APBUART_CTRL_RE | APBUART_CTRL_TE; +} + +static inline void _debug_uart_putc(int ch) +{ + ambapp_dev_apbuart *uart = (ambapp_dev_apbuart *)CONFIG_DEBUG_UART_BASE; + while (!(readl(&uart->status) & APBUART_STATUS_THE)) + WATCHDOG_RESET(); + writel(ch, &uart->data); +} + +DEBUG_UART_FUNCS + +#endif diff --git a/arch/sparc/cpu/leon3/start.S b/arch/sparc/cpu/leon3/start.S index cf897f6877..203114970b 100644 --- a/arch/sparc/cpu/leon3/start.S +++ b/arch/sparc/cpu/leon3/start.S @@ -2,9 +2,6 @@ * Copyright (C) 2007, * Daniel Hellstrom, daniel@gaisler.com * - * See file CREDITS for list of people who contributed to this - * project. - * * SPDX-License-Identifier: GPL-2.0+ */ @@ -16,6 +13,12 @@ #include <asm/stack.h> #include <asm/leon.h> #include <version.h> +#include <ambapp.h> + +/* Default Plug&Play I/O area */ +#ifndef CONFIG_AMBAPP_IOAREA +#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA +#endif /* Entry for traps which jump to a programmer-specified trap handler. */ #define TRAPR(H) \ @@ -60,6 +63,27 @@ MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4) #error Must define number of SPARC register windows, default is 8 #endif +/* Macros to load address into a register. Uses GOT table for PIC */ +#ifdef __PIC__ + +#define SPARC_PIC_THUNK_CALL(reg) \ + sethi %pc22(_GLOBAL_OFFSET_TABLE_-4), %##reg; \ + call __sparc_get_pc_thunk.reg; \ + add %##reg, %pc10(_GLOBAL_OFFSET_TABLE_+4), %##reg; + +#define SPARC_LOAD_ADDRESS(sym, got, reg) \ + sethi %gdop_hix22(sym), %##reg; \ + xor %##reg, %gdop_lox10(sym), %##reg; \ + ld [%##got + %##reg], %##reg, %gdop(sym); + +#else + +#define SPARC_PIC_THUNK_CALL(reg) +#define SPARC_LOAD_ADDRESS(sym, got, tmp) \ + set sym, %##reg; + +#endif + #define STACK_ALIGN 8 #define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1)) @@ -190,6 +214,7 @@ version_string: .ascii U_BOOT_VERSION_STRING, "\0" .section ".text" + .extern _nomem_amba_init, _nomem_memory_ctrl_init .align 4 _hardreset: @@ -232,7 +257,7 @@ clear_window: bge clear_window save -wininit: +wiminit: set WIM_INIT, %g3 mov %g3, %wim @@ -241,9 +266,41 @@ stackp: andn %fp, 0x0f, %fp sub %fp, 64, %sp +/* Obtain the address of _GLOBAL_OFFSET_TABLE_ */ + SPARC_PIC_THUNK_CALL(l7) + +/* Scan AMBA Bus for AMBA buses using PnP information. All found + * AMBA buses I/O area will be located in i0-i5 upon return. + * The i0-i5 registers are later used by _nomem_amba_init2 + */ +ambainit: + call _nomem_amba_init + sethi %hi(CONFIG_AMBAPP_IOAREA), %o0 + +/* Scan AMBA Buses for memory controllers, then initialize the + * memory controllers. Note that before setting up the memory controller + * the stack can not be used. + */ +memory_ctrl_init: + SPARC_LOAD_ADDRESS(grlib_mctrl_handlers, l7, o0) + + call _nomem_memory_ctrl_init + nop + +/* The return valu indicate how many memory controllers where found and + * initialized, if no memory controller was initialized, we can not continue + * because from here on we expect memory to be working. + */ + cmp %o0, 0 +memory_ctrl_init_failed: + beq memory_ctrl_init_failed + nop + +/*** From now on the stack can be used. ***/ + cpu_init_unreloc: call cpu_init_f - nop + nop /* un relocated start address of monitor */ #define TEXT_START _text @@ -252,8 +309,8 @@ cpu_init_unreloc: #define DATA_END __init_end reloc: - set TEXT_START,%g2 - set DATA_END,%g3 + 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 @@ -263,7 +320,7 @@ reloc_loop: inc 16,%g2 subcc %g3,%g2,%g0 bne reloc_loop - inc 16,%g4 + inc 16,%g4 clr %l0 clr %l1 @@ -280,8 +337,8 @@ reloc_loop: clr_bss: /* clear bss area (the relocated) */ - set __bss_start,%g2 - set __bss_end,%g3 + SPARC_LOAD_ADDRESS(__bss_start, l7, g2) + SPARC_LOAD_ADDRESS(__bss_end, l7, g3) sub %g3,%g2,%g3 add %g3,%g4,%g3 clr %g1 /* std %g0 uses g0 and g1 */ @@ -292,19 +349,19 @@ clr_bss_16: inc 16,%g4 cmp %g3,%g4 bne clr_bss_16 - nop + nop /* add offsets to GOT table */ fixup_got: - set __got_start,%g4 - set __got_end,%g3 + SPARC_LOAD_ADDRESS(__got_start, l7, 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 - set TEXT_START, %g1 + SPARC_LOAD_ADDRESS(TEXT_START, l7, g1) add %g4,%g2,%g4 sub %g4,%g1,%g4 add %g3,%g2,%g3 @@ -319,11 +376,11 @@ got_loop: inc 4,%g4 cmp %g3,%g4 bne got_loop - nop + nop prom_relocate: - set __prom_start, %g2 - set __prom_end, %g3 + SPARC_LOAD_ADDRESS(__prom_start, l7, g2) + SPARC_LOAD_ADDRESS(__prom_end, l7, g3) set CONFIG_SYS_PROM_OFFSET, %g4 prom_relocate_loop: @@ -334,7 +391,7 @@ prom_relocate_loop: inc 16,%g2 subcc %g3,%g2,%g0 bne prom_relocate_loop - inc 16,%g4 + inc 16,%g4 /* Trap table has been moved, lets tell CPU about * the new trap table address @@ -361,19 +418,20 @@ snoop_detect: nop /* Call relocated init functions */ jump: - set cpu_init_f2,%o1 + 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 + clr %o0 - set board_init_f,%o1 + 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 + clr %o0 dead: ta 0 ! if call returns... nop diff --git a/arch/sparc/cpu/leon3/usb_uhci.c b/arch/sparc/cpu/leon3/usb_uhci.c index ca7d6e86f0..1be84c646b 100644 --- a/arch/sparc/cpu/leon3/usb_uhci.c +++ b/arch/sparc/cpu/leon3/usb_uhci.c @@ -690,11 +690,11 @@ void handle_usb_interrupt(void) */ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) { - unsigned char temp; ambapp_ahbdev ahbdev; /* Find GRUSB core using AMBA Plug&Play information */ - if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_UHCI, &ahbdev) != 1) { + if (ambapp_ahbslv_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_UHCI, + CONFIG_SYS_GRLIB_GRUSB_INDEX, &ahbdev) != 1) { printf("USB UHCI: Failed to find GRUSB controller\n"); return -1; } diff --git a/arch/sparc/include/asm/global_data.h b/arch/sparc/include/asm/global_data.h index 667e7d6d3b..0680a56758 100644 --- a/arch/sparc/include/asm/global_data.h +++ b/arch/sparc/include/asm/global_data.h @@ -15,6 +15,7 @@ /* Architecture-specific global data */ struct arch_global_data { + void *uart; }; #include <asm-generic/global_data.h> diff --git a/arch/sparc/include/asm/io.h b/arch/sparc/include/asm/io.h index f7b89c890f..a317d132be 100644 --- a/arch/sparc/include/asm/io.h +++ b/arch/sparc/include/asm/io.h @@ -1,7 +1,7 @@ /* SPARC I/O definitions * - * (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+ */ @@ -12,45 +12,57 @@ /* Nothing to sync, total store ordering (TSO)... */ #define sync() +/* + * Generic virtual read/write. + */ + +#ifndef CONFIG_SYS_HAS_NO_CACHE + /* Forces a cache miss on read/load. * On some architectures we need to bypass the cache when reading * I/O registers so that we are not reading the same status word * over and over again resulting in a hang (until an IRQ if lucky) - * */ -#ifndef CONFIG_SYS_HAS_NO_CACHE -#define READ_BYTE(var) SPARC_NOCACHE_READ_BYTE((unsigned int)(var)) -#define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)(var)) -#define READ_WORD(var) SPARC_NOCACHE_READ((unsigned int)(var)) -#define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)(var)) + +#define __arch_getb(a) SPARC_NOCACHE_READ_BYTE((unsigned int)(a)) +#define __arch_getw(a) SPARC_NOCACHE_READ_HWORD((unsigned int)(a)) +#define __arch_getl(a) SPARC_NOCACHE_READ((unsigned int)(a)) +#define __arch_getq(a) SPARC_NOCACHE_READ_DWORD((unsigned int)(a)) + #else -#define READ_BYTE(var) (var) -#define READ_HWORD(var) (var) -#define READ_WORD(var) (var) -#define READ_DWORD(var) (var) -#endif -/* - * Generic virtual read/write. - */ -#define __arch_getb(a) (READ_BYTE(a)) -#define __arch_getw(a) (READ_HWORD(a)) -#define __arch_getl(a) (READ_WORD(a)) -#define __arch_getq(a) (READ_DWORD(a)) +#define __arch_getb(a) (*(volatile unsigned char *)(a)) +#define __arch_getw(a) (*(volatile unsigned short *)(a)) +#define __arch_getl(a) (*(volatile unsigned int *)(a)) +#define __arch_getq(a) (*(volatile unsigned long long *)(a)) + +#endif /* CONFIG_SYS_HAS_NO_CACHE */ -#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v)) -#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) -#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v)) +#define __arch_putb(v, a) (*(volatile unsigned char *)(a) = (v)) +#define __arch_putw(v, a) (*(volatile unsigned short *)(a) = (v)) +#define __arch_putl(v, a) (*(volatile unsigned int *)(a) = (v)) +#define __arch_putq(v, a) (*(volatile unsigned long long *)(a) = (v)) -#define __raw_writeb(v,a) __arch_putb(v,a) -#define __raw_writew(v,a) __arch_putw(v,a) -#define __raw_writel(v,a) __arch_putl(v,a) +#define __raw_writeb(v, a) __arch_putb(v, a) +#define __raw_writew(v, a) __arch_putw(v, a) +#define __raw_writel(v, a) __arch_putl(v, a) +#define __raw_writeq(v, a) __arch_putq(v, a) #define __raw_readb(a) __arch_getb(a) #define __raw_readw(a) __arch_getw(a) #define __raw_readl(a) __arch_getl(a) #define __raw_readq(a) __arch_getq(a) +#define writeb __raw_writeb +#define writew __raw_writew +#define writel __raw_writel +#define writeq __raw_writeq + +#define readb __raw_readb +#define readw __raw_readw +#define readl __raw_readl +#define readq __raw_readq + /* * Given a physical address and a length, return a virtual address * that can be used to access the memory range with the caching diff --git a/arch/sparc/include/asm/winmacro.h b/arch/sparc/include/asm/winmacro.h index 65e4561e7d..4f68fbda69 100644 --- a/arch/sparc/include/asm/winmacro.h +++ b/arch/sparc/include/asm/winmacro.h @@ -136,130 +136,3 @@ ld [reg + FW_FSR], %fsr; #endif - -#ifndef __SPARC_WINMACRO_H__ -#define __SPARC_WINMACRO_H__ - -#include <asm/asmmacro.h> -#include <asm/stack.h> - -/* Store the register window onto the 8-byte aligned area starting - * at %reg. It might be %sp, it might not, we don't care. - */ -#define RW_STORE(reg) \ - std %l0, [%reg + RW_L0]; \ - std %l2, [%reg + RW_L2]; \ - std %l4, [%reg + RW_L4]; \ - std %l6, [%reg + RW_L6]; \ - std %i0, [%reg + RW_I0]; \ - std %i2, [%reg + RW_I2]; \ - std %i4, [%reg + RW_I4]; \ - std %i6, [%reg + RW_I6]; - -/* Load a register window from the area beginning at %reg. */ -#define RW_LOAD(reg) \ - ldd [%reg + RW_L0], %l0; \ - ldd [%reg + RW_L2], %l2; \ - ldd [%reg + RW_L4], %l4; \ - ldd [%reg + RW_L6], %l6; \ - ldd [%reg + RW_I0], %i0; \ - ldd [%reg + RW_I2], %i2; \ - ldd [%reg + RW_I4], %i4; \ - ldd [%reg + RW_I6], %i6; - -/* Loading and storing struct pt_reg trap frames. */ -#define PT_LOAD_INS(base_reg) \ - ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \ - ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \ - ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \ - ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6; - -#define PT_LOAD_GLOBALS(base_reg) \ - ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \ - ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \ - ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \ - ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6; - -#define PT_LOAD_YREG(base_reg, scratch) \ - ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \ - wr %scratch, 0x0, %y; - -#define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \ - ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \ - ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \ - ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc; - -#define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \ - PT_LOAD_YREG(base_reg, scratch) \ - PT_LOAD_INS(base_reg) \ - PT_LOAD_GLOBALS(base_reg) \ - PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) - -#define PT_STORE_INS(base_reg) \ - std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \ - std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \ - std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \ - std %i6, [%base_reg + SF_REGS_SZ + PT_I6]; - -#define PT_STORE_GLOBALS(base_reg) \ - st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \ - std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \ - std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \ - std %g6, [%base_reg + SF_REGS_SZ + PT_G6]; - -#define PT_STORE_YREG(base_reg, scratch) \ - rd %y, %scratch; \ - st %scratch, [%base_reg + SF_REGS_SZ + PT_Y]; - -#define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \ - st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \ - st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \ - st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC]; - -#define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \ - PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \ - PT_STORE_GLOBALS(base_reg) \ - PT_STORE_YREG(base_reg, g_scratch) \ - PT_STORE_INS(base_reg) - -/* Store the fpu register window*/ -#define FW_STORE(reg) \ - std %f0, [reg + FW_F0]; \ - std %f2, [reg + FW_F2]; \ - std %f4, [reg + FW_F4]; \ - std %f6, [reg + FW_F6]; \ - std %f8, [reg + FW_F8]; \ - std %f10, [reg + FW_F10]; \ - std %f12, [reg + FW_F12]; \ - std %f14, [reg + FW_F14]; \ - std %f16, [reg + FW_F16]; \ - std %f18, [reg + FW_F18]; \ - std %f20, [reg + FW_F20]; \ - std %f22, [reg + FW_F22]; \ - std %f24, [reg + FW_F24]; \ - std %f26, [reg + FW_F26]; \ - std %f28, [reg + FW_F28]; \ - std %f30, [reg + FW_F30]; \ - st %fsr, [reg + FW_FSR]; - -/* Load a fpu register window from the area beginning at reg. */ -#define FW_LOAD(reg) \ - ldd [reg + FW_F0], %f0; \ - ldd [reg + FW_F2], %f2; \ - ldd [reg + FW_F4], %f4; \ - ldd [reg + FW_F6], %f6; \ - ldd [reg + FW_F8], %f8; \ - ldd [reg + FW_F10], %f10; \ - ldd [reg + FW_F12], %f12; \ - ldd [reg + FW_F14], %f14; \ - ldd [reg + FW_F16], %f16; \ - ldd [reg + FW_F18], %f18; \ - ldd [reg + FW_F20], %f20; \ - ldd [reg + FW_F22], %f22; \ - ldd [reg + FW_F24], %f24; \ - ldd [reg + FW_F26], %f26; \ - ldd [reg + FW_F28], %f28; \ - ldd [reg + FW_F30], %f30; \ - ld [reg + FW_FSR], %fsr; - -#endif diff --git a/common/Kconfig b/common/Kconfig index 0388a6c34d..440cb372a1 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -455,6 +455,20 @@ endmenu menu "Misc commands" +config CMD_AMBAPP + bool "ambapp" + depends on LEON3 + default y + help + Lists AMBA Plug-n-Play information. + +config SYS_AMBAPP_PRINT_ON_STARTUP + bool "Show AMBA PnP info on startup" + depends on CMD_AMBAPP + default n + help + Show AMBA Plug-n-Play information on startup. + config CMD_TIME bool "time" help diff --git a/common/board_r.c b/common/board_r.c index 2270e2ed0f..c6aa7e5224 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -46,6 +46,9 @@ #include <stdio_dev.h> #include <trace.h> #include <watchdog.h> +#ifdef CONFIG_CMD_AMBAPP +#include <ambapp.h> +#endif #ifdef CONFIG_ADDR_MAP #include <asm/mmu.h> #endif @@ -559,6 +562,18 @@ static int initr_status_led(void) } #endif +#if defined(CONFIG_CMD_AMBAPP) && defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP) +extern int do_ambapp_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); + +static int initr_ambapp_print(void) +{ + puts("AMBA:\n"); + do_ambapp_print(NULL, 0, 0, NULL); + + return 0; +} +#endif + #if defined(CONFIG_CMD_SCSI) static int initr_scsi(void) { @@ -850,6 +865,12 @@ init_fnc_t init_sequence_r[] = { #ifdef CONFIG_BOARD_LATE_INIT board_late_init, #endif +#if defined(CONFIG_CMD_AMBAPP) + ambapp_init_reloc, +#if defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP) + initr_ambapp_print, +#endif +#endif #ifdef CONFIG_CMD_SCSI INIT_FUNC_WATCHDOG_RESET initr_scsi, diff --git a/common/cmd_ambapp.c b/common/cmd_ambapp.c index 2a1995a761..4b6d1741e9 100644 --- a/common/cmd_ambapp.c +++ b/common/cmd_ambapp.c @@ -15,92 +15,375 @@ DECLARE_GLOBAL_DATA_PTR; -/* We put these variables into .data section so that they are zero - * when entering the AMBA Plug & Play routines (in cpu/cpu/ambapp.c) - * the first time. BSS is not garantueed to be zero since BSS - * hasn't been cleared the first times entering the CPU AMBA functions. - * - * The AMBA PnP routines call these functions if ambapp_???_print is set. - * - */ -int ambapp_apb_print __attribute__ ((section(".data"))) = 0; -int ambapp_ahb_print __attribute__ ((section(".data"))) = 0; - typedef struct { int device_id; char *name; + char *desc; } ambapp_device_name; -static ambapp_device_name gaisler_devices[] = { - {GAISLER_LEON3, "GAISLER_LEON3"}, - {GAISLER_LEON3DSU, "GAISLER_LEON3DSU"}, - {GAISLER_ETHAHB, "GAISLER_ETHAHB"}, - {GAISLER_ETHMAC, "GAISLER_ETHMAC"}, - {GAISLER_APBMST, "GAISLER_APBMST"}, - {GAISLER_AHBUART, "GAISLER_AHBUART"}, - {GAISLER_SRCTRL, "GAISLER_SRCTRL"}, - {GAISLER_SDCTRL, "GAISLER_SDCTRL"}, - {GAISLER_APBUART, "GAISLER_APBUART"}, - {GAISLER_IRQMP, "GAISLER_IRQMP"}, - {GAISLER_AHBRAM, "GAISLER_AHBRAM"}, - {GAISLER_GPTIMER, "GAISLER_GPTIMER"}, - {GAISLER_PCITRG, "GAISLER_PCITRG"}, - {GAISLER_PCISBRG, "GAISLER_PCISBRG"}, - {GAISLER_PCIFBRG, "GAISLER_PCIFBRG"}, - {GAISLER_PCITRACE, "GAISLER_PCITRACE"}, - {GAISLER_AHBTRACE, "GAISLER_AHBTRACE"}, - {GAISLER_ETHDSU, "GAISLER_ETHDSU"}, - {GAISLER_PIOPORT, "GAISLER_PIOPORT"}, - {GAISLER_AHBJTAG, "GAISLER_AHBJTAG"}, - {GAISLER_ATACTRL, "GAISLER_ATACTRL"}, - {GAISLER_VGA, "GAISLER_VGA"}, - {GAISLER_KBD, "GAISLER_KBD"}, - {GAISLER_L2TIME, "GAISLER_L2TIME"}, - {GAISLER_L2C, "GAISLER_L2C"}, - {GAISLER_PLUGPLAY, "GAISLER_PLUGPLAY"}, - {GAISLER_SPW, "GAISLER_SPW"}, - {GAISLER_SPW2, "GAISLER_SPW2"}, - {GAISLER_EHCI, "GAISLER_EHCI"}, - {GAISLER_UHCI, "GAISLER_UHCI"}, - {GAISLER_AHBSTAT, "GAISLER_AHBSTAT"}, - {GAISLER_DDR2SPA, "GAISLER_DDR2SPA"}, - {GAISLER_DDRSPA, "GAISLER_DDRSPA"}, - {0, NULL} +typedef struct { + unsigned int vendor_id; + char *name; + char *desc; + ambapp_device_name *devices; +} ambapp_vendor_devnames; + +/** Vendor GAISLER devices */ +static ambapp_device_name GAISLER_devices[] = { + {GAISLER_LEON2DSU, "LEON2DSU", "Leon2 Debug Support Unit"}, + {GAISLER_LEON3, "LEON3", "Leon3 SPARC V8 Processor"}, + {GAISLER_LEON3DSU, "LEON3DSU", "Leon3 Debug Support Unit"}, + {GAISLER_ETHAHB, "ETHAHB", "OC ethernet AHB interface"}, + {GAISLER_APBMST, "APBMST", "AHB/APB Bridge"}, + {GAISLER_AHBUART, "AHBUART", "AHB Debug UART"}, + {GAISLER_SRCTRL, "SRCTRL", "Simple SRAM Controller"}, + {GAISLER_SDCTRL, "SDCTRL", "PC133 SDRAM Controller"}, + {GAISLER_SSRCTRL, "SSRCTRL", "Synchronous SRAM Controller"}, + {GAISLER_APBUART, "APBUART", "Generic UART"}, + {GAISLER_IRQMP, "IRQMP", "Multi-processor Interrupt Ctrl."}, + {GAISLER_AHBRAM, "AHBRAM", "Single-port AHB SRAM module"}, + {GAISLER_AHBDPRAM, "AHBDPRAM", "Dual-port AHB SRAM module"}, + {GAISLER_GPTIMER, "GPTIMER", "Modular Timer Unit"}, + {GAISLER_PCITRG, "PCITRG", "Simple 32-bit PCI Target"}, + {GAISLER_PCISBRG, "PCISBRG", "Simple 32-bit PCI Bridge"}, + {GAISLER_PCIFBRG, "PCIFBRG", "Fast 32-bit PCI Bridge"}, + {GAISLER_PCITRACE, "PCITRACE", "32-bit PCI Trace Buffer"}, + {GAISLER_DMACTRL, "DMACTRL", "AMBA DMA controller"}, + {GAISLER_AHBTRACE, "AHBTRACE", "AMBA Trace Buffer"}, + {GAISLER_DSUCTRL, "DSUCTRL", "DSU/ETH controller"}, + {GAISLER_CANAHB, "CANAHB", "OC CAN AHB interface"}, + {GAISLER_GPIO, "GPIO", "General Purpose I/O port"}, + {GAISLER_AHBROM, "AHBROM", "Generic AHB ROM"}, + {GAISLER_AHBJTAG, "AHBJTAG", "JTAG Debug Link"}, + {GAISLER_ETHMAC, "ETHMAC", "GR Ethernet MAC"}, + {GAISLER_SWNODE, "SWNODE", "SpaceWire Node Interface"}, + {GAISLER_SPW, "SPW", "SpaceWire Serial Link"}, + {GAISLER_AHB2AHB, "AHB2AHB", "AHB-to-AHB Bridge"}, + {GAISLER_USBDC, "USBDC", "GR USB 2.0 Device Controller"}, + {GAISLER_USB_DCL, "USB_DCL", "USB Debug Communication Link"}, + {GAISLER_DDRMP, "DDRMP", "Multi-port DDR controller"}, + {GAISLER_ATACTRL, "ATACTRL", "ATA controller"}, + {GAISLER_DDRSP, "DDRSP", "Single-port DDR266 controller"}, + {GAISLER_EHCI, "EHCI", "USB Enhanced Host Controller"}, + {GAISLER_UHCI, "UHCI", "USB Universal Host Controller"}, + {GAISLER_I2CMST, "I2CMST", "AMBA Wrapper for OC I2C-master"}, + {GAISLER_SPW2, "SPW2", "GRSPW2 SpaceWire Serial Link"}, + {GAISLER_AHBDMA, "AHBDMA", ""}, + {GAISLER_NUHOSP3, "NUHOSP3", "Nuhorizons Spartan3 IO I/F"}, + {GAISLER_CLKGATE, "CLKGATE", "Clock gating unit"}, + {GAISLER_SPICTRL, "SPICTRL", "SPI Controller"}, + {GAISLER_DDR2SP, "DDR2SP", "Single-port DDR2 controller"}, + {GAISLER_SLINK, "SLINK", "SLINK Master"}, + {GAISLER_GRTM, "GRTM", "CCSDS Telemetry Encoder"}, + {GAISLER_GRTC, "GRTC", "CCSDS Telecommand Decoder"}, + {GAISLER_GRPW, "GRPW", "PacketWire to AMBA AHB I/F"}, + {GAISLER_GRCTM, "GRCTM", "CCSDS Time Manager"}, + {GAISLER_GRHCAN, "GRHCAN", "ESA HurriCANe CAN with DMA"}, + {GAISLER_GRFIFO, "GRFIFO", "FIFO Controller"}, + {GAISLER_GRADCDAC, "GRADCDAC", "ADC / DAC Interface"}, + {GAISLER_GRPULSE, "GRPULSE", "General Purpose I/O with Pulses"}, + {GAISLER_GRTIMER, "GRTIMER", "Timer Unit with Latches"}, + {GAISLER_AHB2PP, "AHB2PP", "AMBA AHB to Packet Parallel I/F"}, + {GAISLER_GRVERSION, "GRVERSION", "Version and Revision Register"}, + {GAISLER_APB2PW, "APB2PW", "PacketWire Transmit Interface"}, + {GAISLER_PW2APB, "PW2APB", "PacketWire Receive Interface"}, + {GAISLER_GRCAN, "GRCAN", "CAN Controller with DMA"}, + {GAISLER_I2CSLV, "I2CSLV", "I2C Slave"}, + {GAISLER_U16550, "U16550", "Simple 16550 UART"}, + {GAISLER_AHBMST_EM, "AHBMST_EM", "AMBA Master Emulator"}, + {GAISLER_AHBSLV_EM, "AHBSLV_EM", "AMBA Slave Emulator"}, + {GAISLER_GRTESTMOD, "GRTESTMOD", "Test report module"}, + {GAISLER_ASCS, "ASCS", "ASCS Master"}, + {GAISLER_IPMVBCTRL, "IPMVBCTRL", "IPM-bus/MVBC memory controller"}, + {GAISLER_SPIMCTRL, "SPIMCTRL", "SPI Memory Controller"}, + {GAISLER_L4STAT, "L4STAT", "Leon4 Statistics Module"}, + {GAISLER_LEON4, "LEON4", "Leon4 SPARC V8 Processor"}, + {GAISLER_LEON4DSU, "LEON4DSU", "Leon4 Debug Support Unit"}, + {GAISLER_PWM, "PWM", "PWM generator"}, + {GAISLER_L2CACHE, "L2CACHE", "L2-Cache Controller"}, + {GAISLER_SDCTRL64, "SDCTRL64", "64-bit PC133 SDRAM Controller"}, + {GAISLER_GR1553B, "GR1553B", "MIL-STD-1553B Interface"}, + {GAISLER_1553TST, "1553TST", "MIL-STD-1553B Test Device"}, + {GAISLER_GRIOMMU, "GRIOMMU", "I/O Memory Management Unit"}, + {GAISLER_FTAHBRAM, "FTAHBRAM", "Generic FT AHB SRAM module"}, + {GAISLER_FTSRCTRL, "FTSRCTRL", "Simple FT SRAM Controller"}, + {GAISLER_AHBSTAT, "AHBSTAT", "AHB Status Register"}, + {GAISLER_LEON3FT, "LEON3FT", "Leon3-FT SPARC V8 Processor"}, + {GAISLER_FTMCTRL, "FTMCTRL", "Memory controller with EDAC"}, + {GAISLER_FTSDCTRL, "FTSDCTRL", "FT PC133 SDRAM Controller"}, + {GAISLER_FTSRCTRL8, "FTSRCTRL8", "FT 8-bit SRAM/16-bit IO Ctrl"}, + {GAISLER_MEMSCRUB, "MEMSCRUB", "AHB Memory Scrubber"}, + {GAISLER_FTSDCTRL64, "FTSDCTRL64", "64-bit FT SDRAM Controller"}, + {GAISLER_APBPS2, "APBPS2", "PS2 interface"}, + {GAISLER_VGACTRL, "VGACTRL", "VGA controller"}, + {GAISLER_LOGAN, "LOGAN", "On chip Logic Analyzer"}, + {GAISLER_SVGACTRL, "SVGACTRL", "SVGA frame buffer"}, + {GAISLER_T1AHB, "T1AHB", "Niagara T1 PCX/AHB bridge"}, + {GAISLER_MP7WRAP, "MP7WRAP", "CoreMP7 wrapper"}, + {GAISLER_GRSYSMON, "GRSYSMON", "AMBA wrapper for System Monitor"}, + {GAISLER_GRACECTRL, "GRACECTRL", "System ACE I/F Controller"}, + {GAISLER_ATAHBSLV, "ATAHBSLV", "AMBA Test Framework AHB Slave"}, + {GAISLER_ATAHBMST, "ATAHBMST", "AMBA Test Framework AHB Master"}, + {GAISLER_ATAPBSLV, "ATAPBSLV", "AMBA Test Framework APB Slave"}, + {GAISLER_B1553BC, "B1553BC", "AMBA Wrapper for Core1553BBC"}, + {GAISLER_B1553RT, "B1553RT", "AMBA Wrapper for Core1553BRT"}, + {GAISLER_B1553BRM, "B1553BRM", "AMBA Wrapper for Core1553BRM"}, + {GAISLER_AES, "AES", "Advanced Encryption Standard"}, + {GAISLER_ECC, "ECC", "Elliptic Curve Cryptography"}, + {GAISLER_PCIF, "PCIF", "AMBA Wrapper for CorePCIF"}, + {GAISLER_CLKMOD, "CLKMOD", "CPU Clock Switching Ctrl module"}, + {GAISLER_HAPSTRAK, "HAPSTRAK", "HAPS HapsTrak I/O Port"}, + {GAISLER_TEST_1X2, "TEST_1X2", "HAPS TEST_1x2 interface"}, + {GAISLER_WILD2AHB, "WILD2AHB", "WildCard CardBus interface"}, + {GAISLER_BIO1, "BIO1", "Basic I/O board BIO1"}, + {GAISLER_AESDMA, "AESDMA", "AES 256 DMA"}, + {GAISLER_SATCAN, "SATCAN", "SatCAN controller"}, + {GAISLER_CANMUX, "CANMUX", "CAN Bus multiplexer"}, + {GAISLER_GRTMRX, "GRTMRX", "CCSDS Telemetry Receiver"}, + {GAISLER_GRTCTX, "GRTCTX", "CCSDS Telecommand Transmitter"}, + {GAISLER_GRTMDESC, "GRTMDESC", "CCSDS Telemetry Descriptor"}, + {GAISLER_GRTMVC, "GRTMVC", "CCSDS Telemetry VC Generator"}, + {GAISLER_GEFFE, "GEFFE", "Geffe Generator"}, + {GAISLER_GPREG, "GPREG", "General Purpose Register"}, + {GAISLER_GRTMPAHB, "GRTMPAHB", "CCSDS Telemetry VC AHB Input"}, + {GAISLER_SPWCUC, "SPWCUC", "CCSDS CUC / SpaceWire I/F"}, + {GAISLER_SPW2_DMA, "SPW2_DMA", "GRSPW Router DMA interface"}, + {GAISLER_SPWROUTER, "SPWROUTER", "GRSPW Router"}, + {0, NULL, NULL} }; -static ambapp_device_name esa_devices[] = { - {ESA_LEON2, "ESA_LEON2"}, - {ESA_MCTRL, "ESA_MCTRL"}, - {0, NULL} + +/** Vendor PENDER devices */ +static ambapp_device_name PENDER_devices[] = { + {0, NULL, NULL} }; -static ambapp_device_name opencores_devices[] = { - {OPENCORES_PCIBR, "OPENCORES_PCIBR"}, - {OPENCORES_ETHMAC, "OPENCORES_ETHMAC"}, + +/** Vendor ESA devices */ +static ambapp_device_name ESA_devices[] = { + {ESA_LEON2, "LEON2", "Leon2 SPARC V8 Processor"}, + {ESA_LEON2APB, "LEON2APB", "Leon2 Peripheral Bus"}, + {ESA_IRQ, "IRQ", "Leon2 Interrupt Controller"}, + {ESA_TIMER, "TIMER", "Leon2 Timer"}, + {ESA_UART, "UART", "Leon2 UART"}, + {ESA_CFG, "CFG", "Leon2 Configuration Register"}, + {ESA_IO, "IO", "Leon2 Input/Output"}, + {ESA_MCTRL, "MCTRL", "Leon2 Memory Controller"}, + {ESA_PCIARB, "PCIARB", "PCI Arbiter"}, + {ESA_HURRICANE, "HURRICANE", "HurriCANe/HurryAMBA CAN Ctrl"}, + {ESA_SPW_RMAP, "SPW_RMAP", "UoD/Saab SpaceWire/RMAP link"}, + {ESA_AHBUART, "AHBUART", "Leon2 AHB Debug UART"}, + {ESA_SPWA, "SPWA", "ESA/ASTRIUM SpaceWire link"}, + {ESA_BOSCHCAN, "BOSCHCAN", "SSC/BOSCH CAN Ctrl"}, + {ESA_IRQ2, "IRQ2", "Leon2 Secondary Irq Controller"}, + {ESA_AHBSTAT, "AHBSTAT", "Leon2 AHB Status Register"}, + {ESA_WPROT, "WPROT", "Leon2 Write Protection"}, + {ESA_WPROT2, "WPROT2", "Leon2 Extended Write Protection"}, + {ESA_PDEC3AMBA, "PDEC3AMBA", "ESA CCSDS PDEC3AMBA TC Decoder"}, + {ESA_PTME3AMBA, "PTME3AMBA", "ESA CCSDS PTME3AMBA TM Encoder"}, + {0, NULL, NULL} +}; + + +/** Vendor ASTRIUM devices */ +static ambapp_device_name ASTRIUM_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor OPENCHIP devices */ +static ambapp_device_name OPENCHIP_devices[] = { + {OPENCHIP_APBGPIO, "APBGPIO", "APB General Purpose IO"}, + {OPENCHIP_APBI2C, "APBI2C", "APB I2C Interface"}, + {OPENCHIP_APBSPI, "APBSPI", "APB SPI Interface"}, + {OPENCHIP_APBCHARLCD, "APBCHARLCD", "APB Character LCD"}, + {OPENCHIP_APBPWM, "APBPWM", "APB PWM"}, + {OPENCHIP_APBPS2, "APBPS2", "APB PS/2 Interface"}, + {OPENCHIP_APBMMCSD, "APBMMCSD", "APB MMC/SD Card Interface"}, + {OPENCHIP_APBNAND, "APBNAND", "APB NAND(SmartMedia) Interface"}, + {OPENCHIP_APBLPC, "APBLPC", "APB LPC Interface"}, + {OPENCHIP_APBCF, "APBCF", "APB CompactFlash (IDE)"}, + {OPENCHIP_APBSYSACE, "APBSYSACE", "APB SystemACE Interface"}, + {OPENCHIP_APB1WIRE, "APB1WIRE", "APB 1-Wire Interface"}, + {OPENCHIP_APBJTAG, "APBJTAG", "APB JTAG TAP Master"}, + {OPENCHIP_APBSUI, "APBSUI", "APB Simple User Interface"}, + {0, NULL, NULL} +}; + + +/** Vendor OPENCORES devices */ +static ambapp_device_name OPENCORES_devices[] = { + {OPENCORES_PCIBR, "PCIBR", "PCI Bridge"}, + {OPENCORES_ETHMAC, "ETHMAC", "Ethernet MAC"}, {0, NULL} }; -typedef struct { - unsigned int vendor_id; - char *name; - ambapp_device_name *devices; -} ambapp_vendor_devnames; +/** Vendor CONTRIB devices */ +static ambapp_device_name CONTRIB_devices[] = { + {CONTRIB_CORE1, "CORE1", "Contributed core 1"}, + {CONTRIB_CORE2, "CORE2", "Contributed core 2"}, + {0, NULL, NULL} +}; + + +/** Vendor EONIC devices */ +static ambapp_device_name EONIC_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor RADIONOR devices */ +static ambapp_device_name RADIONOR_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor GLEICHMANN devices */ +static ambapp_device_name GLEICHMANN_devices[] = { + {GLEICHMANN_CUSTOM, "CUSTOM", "Custom device"}, + {GLEICHMANN_GEOLCD01, "GEOLCD01", "GEOLCD01 graphics system"}, + {GLEICHMANN_DAC, "DAC", "Sigma delta DAC"}, + {GLEICHMANN_HPI, "HPI", "AHB-to-HPI bridge"}, + {GLEICHMANN_SPI, "SPI", "SPI master"}, + {GLEICHMANN_HIFC, "HIFC", "Human interface controller"}, + {GLEICHMANN_ADCDAC, "ADCDAC", "Sigma delta ADC/DAC"}, + {GLEICHMANN_SPIOC, "SPIOC", ""}, + {GLEICHMANN_AC97, "AC97", ""}, + {0, NULL, NULL} +}; + + +/** Vendor MENTA devices */ +static ambapp_device_name MENTA_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor SUN devices */ +static ambapp_device_name SUN_devices[] = { + {SUN_T1, "T1", "Niagara T1 SPARC V9 Processor"}, + {SUN_S1, "S1", "Niagara S1 SPARC V9 Processor"}, + {0, NULL, NULL} +}; + + +/** Vendor MOVIDIA devices */ +static ambapp_device_name MOVIDIA_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor ORBITA devices */ +static ambapp_device_name ORBITA_devices[] = { + {ORBITA_1553B, "1553B", "MIL-STD-1553B Controller"}, + {ORBITA_429, "429", "429 Interface"}, + {ORBITA_SPI, "SPI", "SPI Interface"}, + {ORBITA_I2C, "I2C", "I2C Interface"}, + {ORBITA_SMARTCARD, "SMARTCARD", "Smart Card Reader"}, + {ORBITA_SDCARD, "SDCARD", "SD Card Reader"}, + {ORBITA_UART16550, "UART16550", "16550 UART"}, + {ORBITA_CRYPTO, "CRYPTO", "Crypto Engine"}, + {ORBITA_SYSIF, "SYSIF", "System Interface"}, + {ORBITA_PIO, "PIO", "Programmable IO module"}, + {ORBITA_RTC, "RTC", "Real-Time Clock"}, + {ORBITA_COLORLCD, "COLORLCD", "Color LCD Controller"}, + {ORBITA_PCI, "PCI", "PCI Module"}, + {ORBITA_DSP, "DSP", "DPS Co-Processor"}, + {ORBITA_USBHOST, "USBHOST", "USB Host"}, + {ORBITA_USBDEV, "USBDEV", "USB Device"}, + {0, NULL, NULL} +}; + + +/** Vendor SYNOPSYS devices */ +static ambapp_device_name SYNOPSYS_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor NASA devices */ +static ambapp_device_name NASA_devices[] = { + {NASA_EP32, "EP32", "EP32 Forth processor"}, + {0, NULL, NULL} +}; + + +/** Vendor CAL devices */ +static ambapp_device_name CAL_devices[] = { + {CAL_DDRCTRL, "DDRCTRL", ""}, + {0, NULL, NULL} +}; + + +/** Vendor EMBEDDIT devices */ +static ambapp_device_name EMBEDDIT_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor CETON devices */ +static ambapp_device_name CETON_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor S3 devices */ +static ambapp_device_name S3_devices[] = { + {0, NULL, NULL} +}; + + +/** Vendor ACTEL devices */ +static ambapp_device_name ACTEL_devices[] = { + {ACTEL_COREMP7, "COREMP7", "CoreMP7 Processor"}, + {0, NULL, NULL} +}; + + +/** Vendor APPLECORE devices */ +static ambapp_device_name APPLECORE_devices[] = { + {APPLECORE_UTLEON3, "UTLEON3", "AppleCore uT-LEON3 Processor"}, + {APPLECORE_UTLEON3DSU, "UTLEON3DSU", "AppleCore uT-LEON3 DSU"}, + {0, NULL, NULL} +}; + + +/** Vendors and their devices */ static ambapp_vendor_devnames vendors[] = { - {VENDOR_GAISLER, "VENDOR_GAISLER", gaisler_devices}, - {VENDOR_ESA, "VENDOR_ESA", esa_devices}, - {VENDOR_OPENCORES, "VENDOR_OPENCORES", opencores_devices}, - {0, NULL, 0} + {VENDOR_GAISLER, "GAISLER", "Gaisler Research", GAISLER_devices}, + {VENDOR_PENDER, "PENDER", "", PENDER_devices}, + {VENDOR_ESA, "ESA", "European Space Agency", ESA_devices}, + {VENDOR_ASTRIUM, "ASTRIUM", "", ASTRIUM_devices}, + {VENDOR_OPENCHIP, "OPENCHIP", "OpenChip", OPENCHIP_devices}, + {VENDOR_OPENCORES, "OPENCORES", "OpenCores", OPENCORES_devices}, + {VENDOR_CONTRIB, "CONTRIB", "Various contributions", CONTRIB_devices}, + {VENDOR_EONIC, "EONIC", "Eonic BV", EONIC_devices}, + {VENDOR_RADIONOR, "RADIONOR", "Radionor Communications", RADIONOR_devices}, + {VENDOR_GLEICHMANN, "GLEICHMANN", "Gleichmann Electronics", GLEICHMANN_devices}, + {VENDOR_MENTA, "MENTA", "Menta", MENTA_devices}, + {VENDOR_SUN, "SUN", "Sun Microsystems", SUN_devices}, + {VENDOR_MOVIDIA, "MOVIDIA", "", MOVIDIA_devices}, + {VENDOR_ORBITA, "ORBITA", "Orbita", ORBITA_devices}, + {VENDOR_SYNOPSYS, "SYNOPSYS", "Synopsys Inc.", SYNOPSYS_devices}, + {VENDOR_NASA, "NASA", "NASA", NASA_devices}, + {VENDOR_S3, "S3", "S3 Group", S3_devices}, + {VENDOR_CAL, "CAL", "", CAL_devices}, + {VENDOR_EMBEDDIT, "EMBEDDIT", "Embedd.it", EMBEDDIT_devices}, + {VENDOR_CETON, "CETON", "Ceton Corporation", CETON_devices}, + {VENDOR_ACTEL, "ACTEL", "Actel Corporation", ACTEL_devices}, + {VENDOR_APPLECORE, "APPLECORE", "AppleCore", APPLECORE_devices}, + {0, NULL, NULL, NULL} }; -static char *ambapp_get_devname(ambapp_device_name * devs, int id) +static ambapp_device_name *ambapp_get_dev(ambapp_device_name *devs, int id) { if (!devs) return NULL; while (devs->device_id > 0) { if (devs->device_id == id) - return devs->name; + return devs; devs++; } return NULL; @@ -109,10 +392,31 @@ static char *ambapp_get_devname(ambapp_device_name * devs, int id) char *ambapp_device_id2str(int vendor, int id) { ambapp_vendor_devnames *ven = &vendors[0]; + ambapp_device_name *dev; + + while (ven->vendor_id > 0) { + if (ven->vendor_id == vendor) { + dev = ambapp_get_dev(ven->devices, id); + if (!dev) + return NULL; + return dev->name; + } + ven++; + } + return NULL; +} + +char *ambapp_device_id2desc(int vendor, int id) +{ + ambapp_vendor_devnames *ven = &vendors[0]; + ambapp_device_name *dev; while (ven->vendor_id > 0) { if (ven->vendor_id == vendor) { - return ambapp_get_devname(ven->devices, id); + dev = ambapp_get_dev(ven->devices, id); + if (!dev) + return NULL; + return dev->desc; } ven++; } @@ -134,101 +438,106 @@ char *ambapp_vendor_id2str(int vendor) static char *unknown = "unknown"; +char *ambapp_type_names[4] = { + /* 0 */ "UNUSED", + /* 1 */ "apb", + /* 2 */ "ahbmem", + /* 3 */ "ahbio" +}; + /* Print one APB device */ -void ambapp_print_apb(apbctrl_pp_dev * apb, ambapp_ahbdev * apbmst, int index) +void ambapp_print_apb(ambapp_apbdev *dev, int index) { char *dev_str, *ven_str; - int irq, ver, vendor, deviceid; - unsigned int address, apbmst_base, mask; - - vendor = amba_vendor(apb->conf); - deviceid = amba_device(apb->conf); - irq = amba_irq(apb->conf); - ver = amba_ver(apb->conf); - apbmst_base = apbmst->address[0] & LEON3_IO_AREA; - address = (apbmst_base | (((apb->bar & 0xfff00000) >> 12))) & - (((apb->bar & 0x0000fff0) << 4) | 0xfff00000); + unsigned int freq; - mask = amba_membar_mask(apb->bar) << 8; - mask = ((~mask) & 0x000fffff) + 1; - - ven_str = ambapp_vendor_id2str(vendor); + ven_str = ambapp_vendor_id2str(dev->vendor); if (!ven_str) { ven_str = unknown; dev_str = unknown; } else { - dev_str = ambapp_device_id2str(vendor, deviceid); + dev_str = ambapp_device_id2str(dev->vendor, dev->device); if (!dev_str) dev_str = unknown; } - printf("0x%02x:0x%02x:0x%02x: %s %s\n" + /* Get Frequency of Core */ + freq = ambapp_bus_freq(&ambapp_plb, dev->ahb_bus_index); + + printf("0x%02x:0x%02x:0x%02x: %s %s (%dkHz)\n" " apb: 0x%08x - 0x%08x\n" " irq: %-2d (ver: %-2d)\n", - index, vendor, deviceid, ven_str, dev_str, address, - address + mask, irq, ver); + index, dev->vendor, dev->device, ven_str, dev_str, freq / 1000, + dev->address, dev->address + (dev->mask-1), + dev->irq, dev->ver); } -void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index) +void ambapp_print_ahb(ambapp_ahbdev *dev, int index) { - char *dev_str, *ven_str; - int irq, ver, vendor, deviceid; - unsigned int addr, mask; - int j; + char *dev_str, *ven_str, *type_str; + int i; + unsigned int freq; - vendor = amba_vendor(ahb->conf); - deviceid = amba_device(ahb->conf); - irq = amba_irq(ahb->conf); - ver = amba_ver(ahb->conf); - - ven_str = ambapp_vendor_id2str(vendor); + ven_str = ambapp_vendor_id2str(dev->vendor); if (!ven_str) { ven_str = unknown; dev_str = unknown; } else { - dev_str = ambapp_device_id2str(vendor, deviceid); + dev_str = ambapp_device_id2str(dev->vendor, dev->device); if (!dev_str) dev_str = unknown; } - printf("0x%02x:0x%02x:0x%02x: %s %s\n", - index, vendor, deviceid, ven_str, dev_str); + /* Get Frequency of Core */ + freq = ambapp_bus_freq(&ambapp_plb, dev->ahb_bus_index); + + printf("0x%02x:0x%02x:0x%02x: %s %s (%dkHz)\n", + index, dev->vendor, dev->device, ven_str, dev_str, freq / 1000); - for (j = 0; j < 4; j++) { - addr = amba_membar_start(ahb->bars[j]); - if (amba_membar_type(ahb->bars[j]) == 0) + for (i = 0; i < 4; i++) { + if (dev->type[i] == 0) continue; - if (amba_membar_type(ahb->bars[j]) == AMBA_TYPE_AHBIO) - addr = AMBA_TYPE_AHBIO_ADDR(addr); - mask = amba_membar_mask(ahb->bars[j]) << 20; - printf(" mem: 0x%08x - 0x%08x\n", addr, addr + ((~mask) + 1)); + type_str = ambapp_type_names[dev->type[i]]; + printf(" %-7s: 0x%08x - 0x%08x\n", type_str, dev->address[i], + dev->address[i] + (dev->mask[i]-1)); } - printf(" irq: %-2d (ver: %d)\n", irq, ver); + printf(" irq: %-2d (ver: %d)\n", dev->irq, dev->ver); } int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { + int index; + ambapp_apbdev apbdev; + ambapp_ahbdev ahbdev; /* Print AHB Masters */ - puts("--------- AHB Masters ---------\n"); - ambapp_apb_print = 0; - ambapp_ahb_print = 1; - ambapp_ahbmst_count(99, 99); /* Get vendor&device 99 = nonexistent... */ + puts("\n--------- AHB Masters ---------\n"); + index = 0; + while (ambapp_ahbmst_find(&ambapp_plb, 0, 0, index, &ahbdev) == 1) { + /* Found a AHB Master Device */ + ambapp_print_ahb(&ahbdev, index); + index++; + } /* Print AHB Slaves */ - puts("--------- AHB Slaves ---------\n"); - ambapp_ahbslv_count(99, 99); /* Get vendor&device 99 = nonexistent... */ + puts("\n--------- AHB Slaves ---------\n"); + index = 0; + while (ambapp_ahbslv_find(&ambapp_plb, 0, 0, index, &ahbdev) == 1) { + /* Found a AHB Slave Device */ + ambapp_print_ahb(&ahbdev, index); + index++; + } /* Print APB Slaves */ - puts("--------- APB Slaves ---------\n"); - ambapp_apb_print = 1; - ambapp_ahb_print = 0; - ambapp_apb_count(99, 99); /* Get vendor&device 99 = nonexistent... */ - - /* Reset, no futher printing */ - ambapp_apb_print = 0; - ambapp_ahb_print = 0; + puts("\n--------- APB Slaves ---------\n"); + index = 0; + while (ambapp_apb_find(&ambapp_plb, 0, 0, index, &apbdev) == 1) { + /* Found a APB Slave Device */ + ambapp_print_apb(&apbdev, index); + index++; + } + puts("\n"); return 0; } @@ -240,16 +549,18 @@ int ambapp_init_reloc(void) while (vend->vendor_id && vend->name) { vend->name = (char *)((unsigned int)vend->name + gd->reloc_off); - vend->devices = - (ambapp_device_name *) ((unsigned int)vend->devices + - gd->reloc_off);; + vend->desc = (char *)((unsigned int)vend->desc + gd->reloc_off); + vend->devices = (ambapp_device_name *) + ((unsigned int)vend->devices + gd->reloc_off); dev = vend->devices; vend++; if (!dev) continue; while (dev->device_id && dev->name) { dev->name = - (char *)((unsigned int)dev->name + gd->reloc_off);; + (char *)((unsigned int)dev->name + gd->reloc_off); + dev->desc = + (char *)((unsigned int)dev->desc + gd->reloc_off); dev++; } } diff --git a/configs/grsim_defconfig b/configs/grsim_defconfig index f0fa23f810..d2f709f834 100644 --- a/configs/grsim_defconfig +++ b/configs/grsim_defconfig @@ -11,4 +11,10 @@ CONFIG_SYS_TEXT_BASE=0x00000000 # CONFIG_CMD_MEMORY is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set +CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP=y +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_APBUART=y +CONFIG_DEBUG_UART_BASE=0x80000100 +CONFIG_DEBUG_UART_CLOCK=40000000 diff --git a/doc/git-mailrc b/doc/git-mailrc index 6fe78a1d08..1b26e232d2 100644 --- a/doc/git-mailrc +++ b/doc/git-mailrc @@ -106,7 +106,7 @@ alias ppc4xx uboot, stroese alias sandbox sjg alias sb sandbox -alias sparc uboot, Daniel Hellstrom <daniel@gaisler.com> +alias sparc uboot, Francois Retief <fgretief@spaceteq.co.za> alias superh uboot, iwamatsu alias sh superh diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 9bc8a8d1aa..0624eb8cac 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -20,7 +20,7 @@ #include <ambapp.h> #include <asm/leon.h> -#include "greth.h" +#include <grlib/greth.h> /* Default to 3s timeout on autonegotiation */ #ifndef GRETH_PHY_TIMEOUT_MS @@ -34,6 +34,13 @@ #define GRETH_PHY_ADR_DEFAULT 0 #endif +/* Let board select which GRETH to use as network interface, set + * this to zero if only one GRETH is available. + */ +#ifndef CONFIG_SYS_GRLIB_GRETH_INDEX +#define CONFIG_SYS_GRLIB_GRETH_INDEX 0 +#endif + /* ByPass Cache when reading regs */ #define GRETH_REGLOAD(addr) SPARC_NOCACHE_READ(addr) /* Write-through cache ==> no bypassing needed on writes */ @@ -593,8 +600,12 @@ int greth_initialize(bd_t * bis) debug("Scanning for GRETH\n"); - /* Find Device & IRQ via AMBA Plug&Play information */ - if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_ETHMAC, &apbdev) != 1) { + /* Find Device & IRQ via AMBA Plug&Play information, + * CONFIG_SYS_GRLIB_GRETH_INDEX select which GRETH if multiple + * GRETHs in system. + */ + if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_ETHMAC, + CONFIG_SYS_GRLIB_GRETH_INDEX, &apbdev) != 1) { return -1; /* GRETH not found */ } diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index d462244a04..eba96f4a80 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -98,6 +98,14 @@ config DEBUG_UART_ZYNQ will need to provide parameters to make this work. The driver will be available until the real driver-model serial is running. +config DEBUG_UART_APBUART + depends on LEON3 + bool "Gaisler APBUART" + help + Select this to enable a debug UART using the serial_leon3 driver. You + will need to provide parameters to make this work. The driver will + be available until the real driver model serial is running. + endchoice config DEBUG_UART_BASE diff --git a/include/ambapp.h b/include/ambapp.h index 405637d8cd..d79fcedb41 100644 --- a/include/ambapp.h +++ b/include/ambapp.h @@ -3,8 +3,8 @@ * the APB bus, also freely available in GRLIB at * www.gaisler.com. * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. + * (C) Copyright 2009, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -12,366 +12,214 @@ #ifndef __AMBAPP_H__ #define __AMBAPP_H__ -/* Default location of Plug&Play info - * normally 0xfffff000 for AHB masters - * and 0xfffff800 for AHB slaves. - * Normally no need to change this. - */ -#define LEON3_IO_AREA 0xfff00000 -#define LEON3_CONF_AREA 0xff000 -#define LEON3_AHB_SLAVE_CONF_AREA (1 << 11) - -/* Max devices this software will support */ -#define LEON3_AHB_MASTERS 16 -#define LEON3_AHB_SLAVES 16 -/*#define LEON3_APB_MASTERS 1*/ /* Number of APB buses that has Plug&Play */ -#define LEON3_APB_SLAVES 16 /* Total number of APB slaves per APB bus */ - -/* Vendor codes */ -#define VENDOR_GAISLER 1 -#define VENDOR_PENDER 2 -#define VENDOR_ESA 4 -#define VENDOR_ASTRIUM 6 -#define VENDOR_OPENCHIP 7 -#define VENDOR_OPENCORES 8 -#define VENDOR_CONTRIB 9 -#define VENDOR_EONIC 11 -#define VENDOR_RADIONOR 15 -#define VENDOR_GLEICHMANN 16 -#define VENDOR_MENTA 17 -#define VENDOR_SUN 19 -#define VENDOR_EMBEDDIT 234 -#define VENDOR_CAL 202 - -/* Gaisler Research device id's */ -#define GAISLER_LEON3 0x003 -#define GAISLER_LEON3DSU 0x004 -#define GAISLER_ETHAHB 0x005 -#define GAISLER_APBMST 0x006 -#define GAISLER_AHBUART 0x007 -#define GAISLER_SRCTRL 0x008 -#define GAISLER_SDCTRL 0x009 -#define GAISLER_APBUART 0x00C -#define GAISLER_IRQMP 0x00D -#define GAISLER_AHBRAM 0x00E -#define GAISLER_GPTIMER 0x011 -#define GAISLER_PCITRG 0x012 -#define GAISLER_PCISBRG 0x013 -#define GAISLER_PCIFBRG 0x014 -#define GAISLER_PCITRACE 0x015 -#define GAISLER_PCIDMA 0x016 -#define GAISLER_AHBTRACE 0x017 -#define GAISLER_ETHDSU 0x018 -#define GAISLER_PIOPORT 0x01A -#define GAISLER_AHBJTAG 0x01c -#define GAISLER_SPW 0x01f -#define GAISLER_ATACTRL 0x024 -#define GAISLER_VGA 0x061 -#define GAISLER_KBD 0X060 -#define GAISLER_ETHMAC 0x01D -#define GAISLER_DDRSPA 0x025 -#define GAISLER_EHCI 0x026 -#define GAISLER_UHCI 0x027 -#define GAISLER_SPW2 0x029 -#define GAISLER_DDR2SPA 0x02E -#define GAISLER_AHBSTAT 0x052 -#define GAISLER_FTMCTRL 0x054 - -#define GAISLER_L2TIME 0xffd /* internal device: leon2 timer */ -#define GAISLER_L2C 0xffe /* internal device: leon2compat */ -#define GAISLER_PLUGPLAY 0xfff /* internal device: plug & play configarea */ - -/* European Space Agency device id's */ -#define ESA_LEON2 0x2 -#define ESA_MCTRL 0xF - -/* Opencores device id's */ -#define OPENCORES_PCIBR 0x4 -#define OPENCORES_ETHMAC 0x5 - -/* Vendor codes */ - -/* - * - * Macros for manipulating Configuration registers - * - */ - -#define amba_vendor(x) (((x) >> 24) & 0xff) - -#define amba_device(x) (((x) >> 12) & 0xfff) - -#define amba_membar_start(mbar) \ - (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16)) - -#define amba_iobar_start(base, iobar) \ - ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) ) - -#define amba_irq(conf) ((conf) & 0xf) - -#define amba_ver(conf) (((conf)>>5) & 0x1f) - -#define amba_membar_type(mbar) ((mbar) & 0xf) - -#define amba_membar_mask(mbar) (((mbar)>>4) & 0xfff) - -#define AMBA_TYPE_APBIO 0x1 -#define AMBA_TYPE_MEM 0x2 -#define AMBA_TYPE_AHBIO 0x3 - -#define AMBA_TYPE_AHBIO_ADDR(addr) (LEON3_IO_AREA | ((addr) >> 12)) +#include <ambapp_ids.h> #ifndef __ASSEMBLER__ +/* Structures used to access Plug&Play information directly */ +struct ambapp_pnp_ahb { + const unsigned int id; /* VENDOR, DEVICE, VER, IRQ, */ + const unsigned int custom[3]; + const unsigned int mbar[4]; /* MASK, ADDRESS, TYPE, + * CACHABLE/PREFETCHABLE */ +}; + +struct ambapp_pnp_apb { + const unsigned int id; /* VENDOR, DEVICE, VER, IRQ, */ + const unsigned int iobar; /* MASK, ADDRESS, TYPE, + * CACHABLE/PREFETCHABLE */ +}; -#ifdef CONFIG_CMD_AMBAPP - -/* AMBA Plug&Play relocation & initialization */ -int ambapp_init_reloc(void); - -/* AMBA Plug&Play Name of Vendors and devices */ - -/* Return name of device */ -char *ambapp_device_id2str(int vendor, int id); - -/* Return name of vendor */ -char *ambapp_vendor_id2str(int vendor); -#endif - -/* - * Types and structure used for AMBA Plug & Play bus scanning - */ - -/* AMBA Plug&Play AHB information layout */ -typedef struct { - unsigned int conf; - unsigned int userdef[3]; - unsigned int bars[4]; -} ahbctrl_pp_dev; - -/* Prototypes for scanning AMBA Plug&Play bus for AMBA - * i) AHB Masters - * ii) AHB Slaves - * iii) APB Slaves (APB MST is a AHB Slave) +/* AMBA Plug&Play AHB Masters & Slaves information locations + * Max devices is 64 supported by HW, however often only 16 + * are used. */ - -typedef struct { +struct ambapp_pnp_info { + struct ambapp_pnp_ahb masters[64]; + struct ambapp_pnp_ahb slaves[63]; + const unsigned int unused[4]; + const unsigned int systemid[4]; +}; + +/* Describes a AMBA PnP bus */ +struct ambapp_bus { + int buses; /* Number of buses */ + unsigned int ioareas[6]; /* PnP I/O AREAs of AHB buses */ + unsigned int freq; /* Frequency of bus0 [Hz] */ +}; + +/* Processor Local AMBA bus */ +extern struct ambapp_bus ambapp_plb; + +/* Get Bus frequency of a certain AMBA bus */ +extern unsigned int ambapp_bus_freq( + struct ambapp_bus *abus, + int ahb_bus_index + ); + +/* AMBA PnP information of a APB Device */ +typedef struct { + unsigned int vendor; + unsigned int device; unsigned char irq; unsigned char ver; unsigned int address; + unsigned int mask; + int ahb_bus_index; } ambapp_apbdev; +/* AMBA PnP information of a AHB Device */ typedef struct { + unsigned int vendor; + unsigned int device; unsigned char irq; unsigned char ver; unsigned int userdef[3]; unsigned int address[4]; + unsigned int mask[4]; + int type[4]; + int ahb_bus_index; } ambapp_ahbdev; -/* AMBA Plug&Play AHB Masters & Slaves information locations - * Max devices is 64 supported by HW, however often only 8 - * are used. - */ -typedef struct { - ahbctrl_pp_dev masters[64]; - ahbctrl_pp_dev slaves[64]; -} ahbctrl_info; +/* Scan AMBA Bus for AHB Bridges */ +extern void ambapp_bus_init( + unsigned int ioarea, + unsigned int freq, + struct ambapp_bus *abus); -/* AMBA Plug&Play AHB information layout */ -typedef struct { - unsigned int conf; - unsigned int bar; -} apbctrl_pp_dev; - -/* All functions return the number of found devices - * 0 = no devices found +/* Find APB Slave device by index using breath first search. + * + * When vendor and device are both set to zero, any device + * with a non-zero device ID will match the search. It may be + * useful when processing all devices on a AMBA bus. */ +extern int ambapp_apb_find( + struct ambapp_bus *abus, + int vendor, + int device, + int index, + ambapp_apbdev *dev + ); + +/* Find AHB Master device by index using breath first search. + * + * When vendor and device are both set to zero, any device + * with a non-zero device ID will match the search. It may be + * useful when processing all devices on a AMBA bus. + */ +extern int ambapp_ahbmst_find( + struct ambapp_bus *abus, + int vendor, + int device, + int index, + ambapp_ahbdev *dev + ); + +/* Find AHB Slave device by index using breath first search. + * + * When vendor and device are both set to zero, any device + * with a non-zero device ID will match the search. It may be + * useful when processing all devices on a AMBA bus. + */ +extern int ambapp_ahbslv_find( + struct ambapp_bus *abus, + int vendor, + int device, + int index, + ambapp_ahbdev *dev + ); + +/* Return number of APB Slave devices of a certain ID (VENDOR:DEVICE) + * zero is returned if no devices was found. + */ +extern int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device); -/****************************** APB SLAVES ******************************/ -int ambapp_apb_count(unsigned int vendor, unsigned int driver); - -int ambapp_apb_first(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev); - -int ambapp_apb_next(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev, int index); - -int ambapp_apbs_first(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev, int max_cnt); - -/****************************** AHB MASTERS ******************************/ -int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver); - -int ambapp_ahbmst_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev); - -int ambapp_ahbmst_next(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int index); +/* Return number of AHB Master devices of a certain ID (VENDOR:DEVICE) + * zero is returned if no devices was found. + */ +extern int ambapp_ahbmst_count(struct ambapp_bus *abus, int vendor, int device); -int ambapp_ahbmsts_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int max_cnt); +/* Return number of AHB Slave devices of a certain ID (VENDOR:DEVICE) + * zero is returned if no devices was found. + */ +extern int ambapp_ahbslv_count(struct ambapp_bus *abus, int vendor, int device); -/****************************** AHB SLAVES ******************************/ -int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver); +#ifdef CONFIG_CMD_AMBAPP -int ambapp_ahbslv_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev); +/* AMBA Plug&Play relocation & initialization */ +int ambapp_init_reloc(void); -int ambapp_ahbslv_next(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int index); +/* AMBA Plug&Play Name of Vendors and devices */ -int ambapp_ahbslvs_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int max_cnt); +/* Return name of device */ +char *ambapp_device_id2str(int vendor, int id); -/*************************** AHB/APB only regs functions ************************* - * During start up, no memory is available we can use the simplified functions - * to get to the memory controller. - * - * Functions uses no stack/memory, only registers. - */ -unsigned int ambapp_apb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */ - register unsigned int driver, /* Plug&Play Device ID */ - register int index); +/* Return name of vendor */ +char *ambapp_vendor_id2str(int vendor); -ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */ - register unsigned int driver, /* Plug&Play Device ID */ - register unsigned int opts, /* scan for AHB 1=slave, 0=masters */ - register int index); +/* Return description of a device */ +char *ambapp_device_id2desc(int vendor, int id); -unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info); +#endif -/*************************** AMBA Plug&Play device register MAPS *****************/ +#endif /* defined(__ASSEMBLER__) */ -/* - * The following defines the bits in the LEON UART Status Registers. - */ +#define AMBA_DEFAULT_IOAREA 0xfff00000 +#define AMBA_CONF_AREA 0xff000 +#define AMBA_AHB_SLAVE_CONF_AREA 0x800 -#define LEON_REG_UART_STATUS_DR 0x00000001 /* Data Ready */ -#define LEON_REG_UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */ -#define LEON_REG_UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */ -#define LEON_REG_UART_STATUS_BR 0x00000008 /* Break Error */ -#define LEON_REG_UART_STATUS_OE 0x00000010 /* RX Overrun Error */ -#define LEON_REG_UART_STATUS_PE 0x00000020 /* RX Parity Error */ -#define LEON_REG_UART_STATUS_FE 0x00000040 /* RX Framing Error */ -#define LEON_REG_UART_STATUS_ERR 0x00000078 /* Error Mask */ - -/* - * The following defines the bits in the LEON UART Ctrl Registers. - */ +#define DEV_NONE 0 +#define DEV_AHB_MST 1 +#define DEV_AHB_SLV 2 +#define DEV_APB_SLV 3 -#define LEON_REG_UART_CTRL_RE 0x00000001 /* Receiver enable */ -#define LEON_REG_UART_CTRL_TE 0x00000002 /* Transmitter enable */ -#define LEON_REG_UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */ -#define LEON_REG_UART_CTRL_TI 0x00000008 /* Transmitter interrupt enable */ -#define LEON_REG_UART_CTRL_PS 0x00000010 /* Parity select */ -#define LEON_REG_UART_CTRL_PE 0x00000020 /* Parity enable */ -#define LEON_REG_UART_CTRL_FL 0x00000040 /* Flow control enable */ -#define LEON_REG_UART_CTRL_LB 0x00000080 /* Loop Back enable */ -#define LEON_REG_UART_CTRL_DBG (1<<11) /* Debug Bit used by GRMON */ - -#define LEON3_GPTIMER_EN 1 -#define LEON3_GPTIMER_RL 2 -#define LEON3_GPTIMER_LD 4 -#define LEON3_GPTIMER_IRQEN 8 - -/* - * The following defines the bits in the LEON PS/2 Status Registers. - */ - -#define LEON_REG_PS2_STATUS_DR 0x00000001 /* Data Ready */ -#define LEON_REG_PS2_STATUS_PE 0x00000002 /* Parity error */ -#define LEON_REG_PS2_STATUS_FE 0x00000004 /* Framing error */ -#define LEON_REG_PS2_STATUS_KI 0x00000008 /* Keyboard inhibit */ +#define AMBA_TYPE_APBIO 0x1 +#define AMBA_TYPE_MEM 0x2 +#define AMBA_TYPE_AHBIO 0x3 -/* - * The following defines the bits in the LEON PS/2 Ctrl Registers. +/* ID layout for APB and AHB devices */ +#define AMBA_PNP_ID(vendor, device) (((vendor)<<24) | ((device)<<12)) + +/* APB Slave PnP layout definitions */ +#define AMBA_APB_ID_OFS (0*4) +#define AMBA_APB_IOBAR_OFS (1*4) +#define AMBA_APB_CONF_LENGH (2*4) + +/* AHB Master/Slave layout PnP definitions */ +#define AMBA_AHB_ID_OFS (0*4) +#define AMBA_AHB_CUSTOM0_OFS (1*4) +#define AMBA_AHB_CUSTOM1_OFS (2*4) +#define AMBA_AHB_CUSTOM2_OFS (3*4) +#define AMBA_AHB_MBAR0_OFS (4*4) +#define AMBA_AHB_MBAR1_OFS (5*4) +#define AMBA_AHB_MBAR2_OFS (6*4) +#define AMBA_AHB_MBAR3_OFS (7*4) +#define AMBA_AHB_CONF_LENGH (8*4) + +/* Macros for extracting information from AMBA PnP information + * registers. */ -#define LEON_REG_PS2_CTRL_RE 0x00000001 /* Receiver enable */ -#define LEON_REG_PS2_CTRL_TE 0x00000002 /* Transmitter enable */ -#define LEON_REG_PS2_CTRL_RI 0x00000004 /* Keyboard receive interrupt */ -#define LEON_REG_PS2_CTRL_TI 0x00000008 /* Keyboard transmit interrupt */ - -typedef struct { - volatile unsigned int ilevel; - volatile unsigned int ipend; - volatile unsigned int iforce; - volatile unsigned int iclear; - volatile unsigned int mstatus; - volatile unsigned int notused[11]; - volatile unsigned int cpu_mask[16]; - volatile unsigned int cpu_force[16]; -} ambapp_dev_irqmp; - -typedef struct { - volatile unsigned int data; - volatile unsigned int status; - volatile unsigned int ctrl; - volatile unsigned int scaler; -} ambapp_dev_apbuart; +#define amba_vendor(x) (((x) >> 24) & 0xff) -typedef struct { - volatile unsigned int val; - volatile unsigned int rld; - volatile unsigned int ctrl; - volatile unsigned int unused; -} ambapp_dev_gptimer_element; - -#define LEON3_GPTIMER_CTRL_EN 0x1 /* Timer enable */ -#define LEON3_GPTIMER_CTRL_RS 0x2 /* Timer reStart */ -#define LEON3_GPTIMER_CTRL_LD 0x4 /* Timer reLoad */ -#define LEON3_GPTIMER_CTRL_IE 0x8 /* interrupt enable */ -#define LEON3_GPTIMER_CTRL_IP 0x10 /* interrupt flag/pending */ -#define LEON3_GPTIMER_CTRL_CH 0x20 /* Chain with previous timer */ +#define amba_device(x) (((x) >> 12) & 0xfff) -typedef struct { - volatile unsigned int scalar; - volatile unsigned int scalar_reload; - volatile unsigned int config; - volatile unsigned int unused; - volatile ambapp_dev_gptimer_element e[8]; -} ambapp_dev_gptimer; +#define amba_irq(conf) ((conf) & 0x1f) -typedef struct { - volatile unsigned int iodata; - volatile unsigned int ioout; - volatile unsigned int iodir; - volatile unsigned int irqmask; - volatile unsigned int irqpol; - volatile unsigned int irqedge; -} ambapp_dev_ioport; - -typedef struct { - volatile unsigned int write; - volatile unsigned int dummy; - volatile unsigned int txcolor; - volatile unsigned int bgcolor; -} ambapp_dev_textvga; +#define amba_ver(conf) (((conf)>>5) & 0x1f) -typedef struct { - volatile unsigned int data; - volatile unsigned int status; - volatile unsigned int ctrl; -} ambapp_dev_apbps2; +#define amba_iobar_start(base, iobar) \ + ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4))) -typedef struct { - unsigned int mcfg1, mcfg2, mcfg3; -} ambapp_dev_mctrl; +#define amba_membar_start(mbar) \ + (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16)) -typedef struct { - unsigned int sdcfg; -} ambapp_dev_sdctrl; +#define amba_membar_type(mbar) ((mbar) & 0xf) -typedef struct { - unsigned int cfg1; - unsigned int cfg2; - unsigned int cfg3; -} ambapp_dev_ddr2spa; +#define amba_membar_mask(mbar) (((mbar) >> 4) & 0xfff) -typedef struct { - unsigned int ctrl; - unsigned int cfg; -} ambapp_dev_ddrspa; +#define amba_ahbio_adr(addr, base_ioarea) \ + ((unsigned int)(base_ioarea) | ((addr) >> 12)) -#endif +#define amba_apb_mask(iobar) ((~(amba_membar_mask(iobar)<<8) & 0x000fffff) + 1) #endif diff --git a/include/ambapp_ids.h b/include/ambapp_ids.h new file mode 100644 index 0000000000..1eae34e554 --- /dev/null +++ b/include/ambapp_ids.h @@ -0,0 +1,250 @@ +/* AMBA Plug & Play Bus Vendor and Device IDs. + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#ifndef __AMBAPP_IDS_H__ +#define __AMBAPP_IDS_H__ + +/* Vendor ID defines */ +#define VENDOR_GAISLER 0x01 +#define VENDOR_PENDER 0x02 +#define VENDOR_ESA 0x04 +#define VENDOR_ASTRIUM 0x06 +#define VENDOR_OPENCHIP 0x07 +#define VENDOR_OPENCORES 0x08 +#define VENDOR_CONTRIB 0x09 +#define VENDOR_EONIC 0x0b +#define VENDOR_RADIONOR 0x0f +#define VENDOR_GLEICHMANN 0x10 +#define VENDOR_MENTA 0x11 +#define VENDOR_SUN 0x13 +#define VENDOR_MOVIDIA 0x14 +#define VENDOR_ORBITA 0x17 +#define VENDOR_SYNOPSYS 0x21 +#define VENDOR_NASA 0x22 +#define VENDOR_S3 0x31 +#define VENDOR_CAL 0xca +#define VENDOR_EMBEDDIT 0xea +#define VENDOR_CETON 0xcb +#define VENDOR_ACTEL 0xac +#define VENDOR_APPLECORE 0xae + +/* Aeroflex Gaisler device ID defines */ +#define GAISLER_LEON2DSU 0x002 +#define GAISLER_LEON3 0x003 +#define GAISLER_LEON3DSU 0x004 +#define GAISLER_ETHAHB 0x005 +#define GAISLER_APBMST 0x006 +#define GAISLER_AHBUART 0x007 +#define GAISLER_SRCTRL 0x008 +#define GAISLER_SDCTRL 0x009 +#define GAISLER_SSRCTRL 0x00a +#define GAISLER_APBUART 0x00c +#define GAISLER_IRQMP 0x00d +#define GAISLER_AHBRAM 0x00e +#define GAISLER_AHBDPRAM 0x00f +#define GAISLER_GPTIMER 0x011 +#define GAISLER_PCITRG 0x012 +#define GAISLER_PCISBRG 0x013 +#define GAISLER_PCIFBRG 0x014 +#define GAISLER_PCITRACE 0x015 +#define GAISLER_DMACTRL 0x016 +#define GAISLER_AHBTRACE 0x017 +#define GAISLER_DSUCTRL 0x018 +#define GAISLER_CANAHB 0x019 +#define GAISLER_GPIO 0x01a +#define GAISLER_AHBROM 0x01b +#define GAISLER_AHBJTAG 0x01c +#define GAISLER_ETHMAC 0x01d +#define GAISLER_SWNODE 0x01e +#define GAISLER_SPW 0x01f +#define GAISLER_AHB2AHB 0x020 +#define GAISLER_USBDC 0x021 +#define GAISLER_USB_DCL 0x022 +#define GAISLER_DDRMP 0x023 +#define GAISLER_ATACTRL 0x024 +#define GAISLER_DDRSP 0x025 +#define GAISLER_EHCI 0x026 +#define GAISLER_UHCI 0x027 +#define GAISLER_I2CMST 0x028 +#define GAISLER_SPW2 0x029 +#define GAISLER_AHBDMA 0x02a +#define GAISLER_NUHOSP3 0x02b +#define GAISLER_CLKGATE 0x02c +#define GAISLER_SPICTRL 0x02d +#define GAISLER_DDR2SP 0x02e +#define GAISLER_SLINK 0x02f +#define GAISLER_GRTM 0x030 +#define GAISLER_GRTC 0x031 +#define GAISLER_GRPW 0x032 +#define GAISLER_GRCTM 0x033 +#define GAISLER_GRHCAN 0x034 +#define GAISLER_GRFIFO 0x035 +#define GAISLER_GRADCDAC 0x036 +#define GAISLER_GRPULSE 0x037 +#define GAISLER_GRTIMER 0x038 +#define GAISLER_AHB2PP 0x039 +#define GAISLER_GRVERSION 0x03a +#define GAISLER_APB2PW 0x03b +#define GAISLER_PW2APB 0x03c +#define GAISLER_GRCAN 0x03d +#define GAISLER_I2CSLV 0x03e +#define GAISLER_U16550 0x03f +#define GAISLER_AHBMST_EM 0x040 +#define GAISLER_AHBSLV_EM 0x041 +#define GAISLER_GRTESTMOD 0x042 +#define GAISLER_ASCS 0x043 +#define GAISLER_IPMVBCTRL 0x044 +#define GAISLER_SPIMCTRL 0x045 +#define GAISLER_L4STAT 0x047 +#define GAISLER_LEON4 0x048 +#define GAISLER_LEON4DSU 0x049 +#define GAISLER_PWM 0x04a +#define GAISLER_L2CACHE 0x04b +#define GAISLER_SDCTRL64 0x04c +#define GAISLER_GR1553B 0x04d +#define GAISLER_1553TST 0x04e +#define GAISLER_GRIOMMU 0x04f +#define GAISLER_FTAHBRAM 0x050 +#define GAISLER_FTSRCTRL 0x051 +#define GAISLER_AHBSTAT 0x052 +#define GAISLER_LEON3FT 0x053 +#define GAISLER_FTMCTRL 0x054 +#define GAISLER_FTSDCTRL 0x055 +#define GAISLER_FTSRCTRL8 0x056 +#define GAISLER_MEMSCRUB 0x057 +#define GAISLER_FTSDCTRL64 0x058 +#define GAISLER_APBPS2 0x060 +#define GAISLER_VGACTRL 0x061 +#define GAISLER_LOGAN 0x062 +#define GAISLER_SVGACTRL 0x063 +#define GAISLER_T1AHB 0x064 +#define GAISLER_MP7WRAP 0x065 +#define GAISLER_GRSYSMON 0x066 +#define GAISLER_GRACECTRL 0x067 +#define GAISLER_ATAHBSLV 0x068 +#define GAISLER_ATAHBMST 0x069 +#define GAISLER_ATAPBSLV 0x06a +#define GAISLER_B1553BC 0x070 +#define GAISLER_B1553RT 0x071 +#define GAISLER_B1553BRM 0x072 +#define GAISLER_AES 0x073 +#define GAISLER_ECC 0x074 +#define GAISLER_PCIF 0x075 +#define GAISLER_CLKMOD 0x076 +#define GAISLER_HAPSTRAK 0x077 +#define GAISLER_TEST_1X2 0x078 +#define GAISLER_WILD2AHB 0x079 +#define GAISLER_BIO1 0x07a +#define GAISLER_AESDMA 0x07b +#define GAISLER_SATCAN 0x080 +#define GAISLER_CANMUX 0x081 +#define GAISLER_GRTMRX 0x082 +#define GAISLER_GRTCTX 0x083 +#define GAISLER_GRTMDESC 0x084 +#define GAISLER_GRTMVC 0x085 +#define GAISLER_GEFFE 0x086 +#define GAISLER_GPREG 0x087 +#define GAISLER_GRTMPAHB 0x088 +#define GAISLER_SPWCUC 0x089 +#define GAISLER_SPW2_DMA 0x08a +#define GAISLER_SPWROUTER 0x08b + +/* European Space Agency device ID defines */ +#define ESA_LEON2 0x002 +#define ESA_LEON2APB 0x003 +#define ESA_IRQ 0x005 +#define ESA_TIMER 0x006 +#define ESA_UART 0x007 +#define ESA_CFG 0x008 +#define ESA_IO 0x009 +#define ESA_MCTRL 0x00f +#define ESA_PCIARB 0x010 +#define ESA_HURRICANE 0x011 +#define ESA_SPW_RMAP 0x012 +#define ESA_AHBUART 0x013 +#define ESA_SPWA 0x014 +#define ESA_BOSCHCAN 0x015 +#define ESA_IRQ2 0x016 +#define ESA_AHBSTAT 0x017 +#define ESA_WPROT 0x018 +#define ESA_WPROT2 0x019 +#define ESA_PDEC3AMBA 0x020 +#define ESA_PTME3AMBA 0x021 + +/* OpenChip device ID defines */ +#define OPENCHIP_APBGPIO 0x001 +#define OPENCHIP_APBI2C 0x002 +#define OPENCHIP_APBSPI 0x003 +#define OPENCHIP_APBCHARLCD 0x004 +#define OPENCHIP_APBPWM 0x005 +#define OPENCHIP_APBPS2 0x006 +#define OPENCHIP_APBMMCSD 0x007 +#define OPENCHIP_APBNAND 0x008 +#define OPENCHIP_APBLPC 0x009 +#define OPENCHIP_APBCF 0x00a +#define OPENCHIP_APBSYSACE 0x00b +#define OPENCHIP_APB1WIRE 0x00c +#define OPENCHIP_APBJTAG 0x00d +#define OPENCHIP_APBSUI 0x00e + +/* Various contributions device ID defines */ +#define CONTRIB_CORE1 0x001 +#define CONTRIB_CORE2 0x002 + +/* Gleichmann Electronics device ID defines */ +#define GLEICHMANN_CUSTOM 0x001 +#define GLEICHMANN_GEOLCD01 0x002 +#define GLEICHMANN_DAC 0x003 +#define GLEICHMANN_HPI 0x004 +#define GLEICHMANN_SPI 0x005 +#define GLEICHMANN_HIFC 0x006 +#define GLEICHMANN_ADCDAC 0x007 +#define GLEICHMANN_SPIOC 0x008 +#define GLEICHMANN_AC97 0x009 + +/* Sun Microsystems device ID defines */ +#define SUN_T1 0x001 +#define SUN_S1 0x011 + +/* Orbita device ID defines */ +#define ORBITA_1553B 0x001 +#define ORBITA_429 0x002 +#define ORBITA_SPI 0x003 +#define ORBITA_I2C 0x004 +#define ORBITA_SMARTCARD 0x064 +#define ORBITA_SDCARD 0x065 +#define ORBITA_UART16550 0x066 +#define ORBITA_CRYPTO 0x067 +#define ORBITA_SYSIF 0x068 +#define ORBITA_PIO 0x069 +#define ORBITA_RTC 0x0c8 +#define ORBITA_COLORLCD 0x12c +#define ORBITA_PCI 0x190 +#define ORBITA_DSP 0x1f4 +#define ORBITA_USBHOST 0x258 +#define ORBITA_USBDEV 0x2bc + +/* NASA device ID defines */ +#define NASA_EP32 0x001 + +/* CAL device ID defines */ +#define CAL_DDRCTRL 0x188 + +/* Actel Corporation device ID defines */ +#define ACTEL_COREMP7 0x001 + +/* AppleCore device ID defines */ +#define APPLECORE_UTLEON3 0x001 +#define APPLECORE_UTLEON3DSU 0x002 + +/* Opencores device id's */ +#define OPENCORES_PCIBR 0x4 +#define OPENCORES_ETHMAC 0x5 + +#endif diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h index 8832552f31..424721b7e7 100644 --- a/include/config_cmd_all.h +++ b/include/config_cmd_all.h @@ -13,7 +13,6 @@ * Alphabetical list of all possible commands. */ -#define CONFIG_CMD_AMBAPP /* AMBA Plug & Play Bus print utility */ #define CONFIG_CMD_ASKENV /* ask for env variable */ #define CONFIG_CMD_BEDBUG /* Include BedBug Debugger */ #define CONFIG_CMD_BMP /* BMP support */ diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h index 782746e4e0..5bbf1aaae8 100644 --- a/include/configs/gr_cpci_ax2000.h +++ b/include/configs/gr_cpci_ax2000.h @@ -60,7 +60,6 @@ * Supported commands */ #define CONFIG_CMD_REGINFO -#define CONFIG_CMD_AMBAPP #define CONFIG_CMD_PING #define CONFIG_CMD_DIAG #define CONFIG_CMD_IRQ @@ -311,40 +310,38 @@ /***** Gaisler GRLIB IP-Cores Config ********/ -/* AMBA Plug & Play info display on startup */ -/*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/ - #define CONFIG_SYS_GRLIB_SDRAM 0 +/* No SDRAM Configuration */ +#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 + /* See, GRLIB Docs (grip.pdf) on how to set up * These the memory controller registers. */ -#define CONFIG_SYS_GRLIB_MEMCFG1 (0x10f800ff | (1<<11)) +#define CONFIG_SYS_GRLIB_ESA_MCTRL1 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1 (0x10f800ff | (1<<11)) #if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM_NOSRAM -#define CONFIG_SYS_GRLIB_MEMCFG2 0x82206000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x82206000 #else -#define CONFIG_SYS_GRLIB_MEMCFG2 0x82205260 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x82205260 #endif -#define CONFIG_SYS_GRLIB_MEMCFG3 0x0809a000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3 0x0809a000 -#define CONFIG_SYS_GRLIB_FT_MEMCFG1 (0x10f800ff | (1<<11)) +/* GRLIB FT-MCTRL configuration */ +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1 (0x10f800ff | (1<<11)) #if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM_NOSRAM -#define CONFIG_SYS_GRLIB_FT_MEMCFG2 0x82206000 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2 0x82206000 #else -#define CONFIG_SYS_GRLIB_FT_MEMCFG2 0x82205260 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2 0x82205260 #endif -#define CONFIG_SYS_GRLIB_FT_MEMCFG3 0x0809a000 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3 0x0809a000 /* no DDR controller */ -#define CONFIG_SYS_GRLIB_DDR_CFG 0x00000000 +#undef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 /* no DDR2 Controller */ -#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000 -#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000 - -/* Calculate scaler register value from default baudrate */ -#define CONFIG_SYS_GRLIB_APBUART_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) +#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 /* Identification string */ #define CONFIG_IDENT_STRING "GAISLER LEON3 GR-CPCI-AX2000" diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h index 5c466f2929..b55ca77a87 100644 --- a/include/configs/gr_ep2s60.h +++ b/include/configs/gr_ep2s60.h @@ -54,7 +54,6 @@ * Supported commands */ #define CONFIG_CMD_REGINFO -#define CONFIG_CMD_AMBAPP #define CONFIG_CMD_PING #define CONFIG_CMD_DIAG #define CONFIG_CMD_IRQ @@ -288,30 +287,31 @@ /***** Gaisler GRLIB IP-Cores Config ********/ -/* AMBA Plug & Play info display on startup */ -/*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/ - #define CONFIG_SYS_GRLIB_SDRAM 0 +/* No SDRAM Configuration */ +#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 + /* See, GRLIB Docs (grip.pdf) on how to set up * These the memory controller registers. */ -#define CONFIG_SYS_GRLIB_MEMCFG1 (0x10f800ff | (1<<11)) -#define CONFIG_SYS_GRLIB_MEMCFG2 0x00000000 -#define CONFIG_SYS_GRLIB_MEMCFG3 0x00000000 - -#define CONFIG_SYS_GRLIB_FT_MEMCFG1 (0x10f800ff | (1<<11)) -#define CONFIG_SYS_GRLIB_FT_MEMCFG2 0x00000000 -#define CONFIG_SYS_GRLIB_FT_MEMCFG3 0x00000000 - -#define CONFIG_SYS_GRLIB_DDR_CFG 0xa900830a - -#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000 -#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000 - -/* Calculate scaler register value from default baudrate */ -#define CONFIG_SYS_GRLIB_APBUART_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) +#define CONFIG_SYS_GRLIB_ESA_MCTRL1 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1 (0x10f800ff | (1<<11)) +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x00000000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3 0x00000000 + +/* GRLIB FT-MCTRL configuration */ +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1 (0x10f800ff | (1<<11)) +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2 0x00000000 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3 0x00000000 + +/* DDR controller */ +#define CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 +#define CONFIG_SYS_GRLIB_GAISLER_DDRSPA1_CTRL 0xa900830a + +/* no DDR2 Controller */ +#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 /* Identification string */ #define CONFIG_IDENT_STRING "GAISLER LEON3 EP2S60" diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h index e01578cbb2..d086b694c2 100644 --- a/include/configs/gr_xc3s_1500.h +++ b/include/configs/gr_xc3s_1500.h @@ -41,7 +41,6 @@ * Supported commands */ #define CONFIG_CMD_REGINFO -#define CONFIG_CMD_AMBAPP #define CONFIG_CMD_PING #define CONFIG_CMD_DIAG #define CONFIG_CMD_IRQ @@ -251,32 +250,30 @@ /***** Gaisler GRLIB IP-Cores Config ********/ -/* AMBA Plug & Play info display on startup */ -/*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/ - #define CONFIG_SYS_GRLIB_SDRAM 0 +/* No SDRAM Configuration */ +#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 + /* See, GRLIB Docs (grip.pdf) on how to set up * These the memory controller registers. */ -#define CONFIG_SYS_GRLIB_MEMCFG1 (0x000000ff | (1<<11)) -#define CONFIG_SYS_GRLIB_MEMCFG2 0x82206000 -#define CONFIG_SYS_GRLIB_MEMCFG3 0x00136000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1 (0x000000ff | (1<<11)) +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x82206000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3 0x00136000 -#define CONFIG_SYS_GRLIB_FT_MEMCFG1 (0x000000ff | (1<<11)) -#define CONFIG_SYS_GRLIB_FT_MEMCFG2 0x82206000 -#define CONFIG_SYS_GRLIB_FT_MEMCFG3 0x00136000 +/* GRLIB FT-MCTRL configuration */ +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1 (0x000000ff | (1<<11)) +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2 0x82206000 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3 0x00136000 /* no DDR controller */ -#define CONFIG_SYS_GRLIB_DDR_CFG 0x00000000 +#undef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 /* no DDR2 Controller */ -#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000 -#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000 - -/* Calculate scaler register value from default baudrate */ -#define CONFIG_SYS_GRLIB_APBUART_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) +#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 /* Identification string */ #define CONFIG_IDENT_STRING "GAISLER LEON3 GR-XC3S-1500" diff --git a/include/configs/grsim.h b/include/configs/grsim.h index f54919eaae..e1f7dc3bf6 100644 --- a/include/configs/grsim.h +++ b/include/configs/grsim.h @@ -19,9 +19,13 @@ * * Select between TSIM or GRSIM by setting CONFIG_GRSIM or CONFIG_TSIM to 1. * - * TSIM command - * tsim-leon3 -sdram 0 -ram 32000 -rom 8192 -mmu + * TSIM command: + * $ tsim-leon3 -sdram 32768 -ram 4096 -rom 2048 -mmu -cas * + * In the evaluation version of TSIM, the -sdram/-ram/-rom arguments are + * hard-coded to these values and need not be specified. (see below) + * + * Get TSIM from http://www.gaisler.com/index.php/downloads/simulators */ #define CONFIG_GRSIM 0 /* ... not running on GRSIM */ @@ -47,7 +51,6 @@ /* * Supported commands */ -#define CONFIG_CMD_AMBAPP /* AMBA Plyg&Play information */ #define CONFIG_CMD_DIAG #define CONFIG_CMD_FPGA_LOADMK #define CONFIG_CMD_IRQ @@ -184,18 +187,18 @@ /* * Memory map */ -#define CONFIG_SYS_SDRAM_BASE 0x40000000 -#define CONFIG_SYS_SDRAM_SIZE 0x02000000 -#define CONFIG_SYS_SDRAM_END (CONFIG_SYS_SDRAM_BASE+CONFIG_SYS_SDRAM_SIZE) +#define CONFIG_SYS_SDRAM_BASE 0x60000000 +#define CONFIG_SYS_SDRAM_SIZE 0x02000000 /* 32MiB SDRAM */ +#define CONFIG_SYS_SDRAM_END (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE) -/* no SRAM available */ -#undef CONFIG_SYS_SRAM_BASE -#undef CONFIG_SYS_SRAM_SIZE +#define CONFIG_SYS_SRAM_BASE 0x40000000 +#define CONFIG_SYS_SRAM_SIZE 0x00400000 /* 4MiB SRAM */ +#define CONFIG_SYS_SRAM_END (CONFIG_SYS_SRAM_BASE + CONFIG_SYS_SRAM_SIZE) /* Always Run U-Boot from SDRAM */ -#define CONFIG_SYS_RAM_BASE CONFIG_SYS_SDRAM_BASE -#define CONFIG_SYS_RAM_SIZE CONFIG_SYS_SDRAM_SIZE -#define CONFIG_SYS_RAM_END CONFIG_SYS_SDRAM_END +#define CONFIG_SYS_RAM_BASE CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_RAM_SIZE CONFIG_SYS_SDRAM_SIZE +#define CONFIG_SYS_RAM_END CONFIG_SYS_SDRAM_END #define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_RAM_END - GENERATED_GBL_DATA_SIZE) @@ -224,6 +227,7 @@ /* make un relocated address from relocated address */ #define UN_RELOC(address) (address-(CONFIG_SYS_RELOC_MONITOR_BASE-CONFIG_SYS_TEXT_BASE)) +#ifdef CONFIG_CMD_NET /* * Ethernet configuration */ @@ -235,6 +239,8 @@ /* #define CONFIG_GRETH_10MBIT 1 */ #define CONFIG_PHY_ADDR 0x00 +#endif /* CONFIG_CMD_NET */ + /* * Miscellaneous configurable options */ @@ -255,37 +261,65 @@ /***** Gaisler GRLIB IP-Cores Config ********/ -/* AMBA Plug & Play info display on startup */ -/*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/ - #define CONFIG_SYS_GRLIB_SDRAM 0 + #define CONFIG_SYS_GRLIB_MEMCFG1 (0x000000ff | (1<<11)) + +/* No SDRAM Configuration */ +#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1 + +/* LEON2 MCTRL configuration */ +#define CONFIG_SYS_GRLIB_ESA_MCTRL1 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1 (0x000000ff | (1<<11)) #if CONFIG_GRSIM /* GRSIM configuration */ -#define CONFIG_SYS_GRLIB_MEMCFG2 0x82206000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x82206000 #else /* TSIM configuration */ -#define CONFIG_SYS_GRLIB_MEMCFG2 0x00001820 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x81805220 #endif -#define CONFIG_SYS_GRLIB_MEMCFG3 0x00136000 +#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3 0x00136000 -#define CONFIG_SYS_GRLIB_FT_MEMCFG1 (0x000000ff | (1<<11)) -#define CONFIG_SYS_GRLIB_FT_MEMCFG2 0x82206000 -#define CONFIG_SYS_GRLIB_FT_MEMCFG3 0x00136000 +/* GRLIB FT-MCTRL configuration */ +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1 (0x000000ff | (1<<11)) +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2 0x82206000 +#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3 0x00136000 /* no DDR controller */ -#define CONFIG_SYS_GRLIB_DDR_CFG 0x00000000 +#undef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1 /* no DDR2 Controller */ -#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000 -#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000 - -#define CONFIG_SYS_GRLIB_APBUART_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) +#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 /* default kernel command line */ #define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0" #define CONFIG_IDENT_STRING "Gaisler GRSIM" +/* TSIM command: + * $ ./tsim-leon3 -mmu -cas + * + * This TSIM evaluation version will expire 2015-04-02 + * + * + * TSIM/LEON3 SPARC simulator, version 2.0.35 (evaluation version) + * + * Copyright (C) 2014, Aeroflex Gaisler - all rights reserved. + * This software may only be used with a valid license. + * For latest updates, go to http://www.gaisler.com/ + * Comments or bug-reports to support@gaisler.com + * + * serial port A on stdin/stdout + * allocated 4096 K SRAM memory, in 1 bank + * allocated 32 M SDRAM memory, in 1 bank + * allocated 2048 K ROM memory + * icache: 1 * 4 kbytes, 16 bytes/line (4 kbytes total) + * dcache: 1 * 4 kbytes, 16 bytes/line (4 kbytes total) + * tsim> leon + * 0x80000000 Memory configuration register 1 0x000002ff + * 0x80000004 Memory configuration register 2 0x81805220 + * 0x80000008 Memory configuration register 3 0x00000000 + */ + #endif /* __CONFIG_H */ diff --git a/include/configs/grsim_leon2.h b/include/configs/grsim_leon2.h index bd2eaa9fda..83fd7fae50 100644 --- a/include/configs/grsim_leon2.h +++ b/include/configs/grsim_leon2.h @@ -264,8 +264,6 @@ #define CONFIG_SYS_GRLIB_MEMCFG3 0x00136000 /*** LEON2 UART 1 ***/ -#define CONFIG_SYS_LEON2_UART1_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) /* UART1 Define to 1 or 0 */ #define LEON2_UART1_LOOPBACK_ENABLE 0 @@ -275,9 +273,6 @@ /*** LEON2 UART 2 ***/ -#define CONFIG_SYS_LEON2_UART2_SCALER \ - ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10) - /* UART2 Define to 1 or 0 */ #define LEON2_UART2_LOOPBACK_ENABLE 0 #define LEON2_UART2_FLOWCTRL_ENABLE 0 diff --git a/include/grlib/apbuart.h b/include/grlib/apbuart.h new file mode 100644 index 0000000000..1e1eb9a77c --- /dev/null +++ b/include/grlib/apbuart.h @@ -0,0 +1,47 @@ +/* GRLIB APBUART definitions + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __GRLIB_APBUART_H__ +#define __GRLIB_APBUART_H__ + +/* APBUART Register map */ +typedef struct { + volatile unsigned int data; + volatile unsigned int status; + volatile unsigned int ctrl; + volatile unsigned int scaler; +} ambapp_dev_apbuart; + +/* + * The following defines the bits in the LEON UART Status Registers. + */ + +#define APBUART_STATUS_DR 0x00000001 /* Data Ready */ +#define APBUART_STATUS_TSE 0x00000002 /* TX Send Register Empty */ +#define APBUART_STATUS_THE 0x00000004 /* TX Hold Register Empty */ +#define APBUART_STATUS_BR 0x00000008 /* Break Error */ +#define APBUART_STATUS_OE 0x00000010 /* RX Overrun Error */ +#define APBUART_STATUS_PE 0x00000020 /* RX Parity Error */ +#define APBUART_STATUS_FE 0x00000040 /* RX Framing Error */ +#define APBUART_STATUS_ERR 0x00000078 /* Error Mask */ + +/* + * The following defines the bits in the LEON UART Ctrl Registers. + */ + +#define APBUART_CTRL_RE 0x00000001 /* Receiver enable */ +#define APBUART_CTRL_TE 0x00000002 /* Transmitter enable */ +#define APBUART_CTRL_RI 0x00000004 /* Receiver interrupt enable */ +#define APBUART_CTRL_TI 0x00000008 /* Transmitter interrupt enable */ +#define APBUART_CTRL_PS 0x00000010 /* Parity select */ +#define APBUART_CTRL_PE 0x00000020 /* Parity enable */ +#define APBUART_CTRL_FL 0x00000040 /* Flow control enable */ +#define APBUART_CTRL_LB 0x00000080 /* Loop Back enable */ +#define APBUART_CTRL_DBG (1<<11) /* Debug Bit used by GRMON */ + +#endif diff --git a/include/grlib/gptimer.h b/include/grlib/gptimer.h new file mode 100644 index 0000000000..8b2b1651b0 --- /dev/null +++ b/include/grlib/gptimer.h @@ -0,0 +1,34 @@ +/* GRLIB GPTIMER (General Purpose Timer) definitions + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __GRLIB_GPTIMER_H__ +#define __GRLIB_GPTIMER_H__ + +typedef struct { + volatile unsigned int val; + volatile unsigned int rld; + volatile unsigned int ctrl; + volatile unsigned int unused; +} ambapp_dev_gptimer_element; + +#define GPTIMER_CTRL_EN 0x1 /* Timer enable */ +#define GPTIMER_CTRL_RS 0x2 /* Timer reStart */ +#define GPTIMER_CTRL_LD 0x4 /* Timer reLoad */ +#define GPTIMER_CTRL_IE 0x8 /* interrupt enable */ +#define GPTIMER_CTRL_IP 0x10 /* interrupt flag/pending */ +#define GPTIMER_CTRL_CH 0x20 /* Chain with previous timer */ + +typedef struct { + volatile unsigned int scalar; + volatile unsigned int scalar_reload; + volatile unsigned int config; + volatile unsigned int unused; + volatile ambapp_dev_gptimer_element e[8]; +} ambapp_dev_gptimer; + +#endif diff --git a/include/grlib/greth.h b/include/grlib/greth.h new file mode 100644 index 0000000000..89c1e49387 --- /dev/null +++ b/include/grlib/greth.h @@ -0,0 +1,87 @@ +/* Gaisler.com GRETH 10/100/1000 Ethernet MAC definitions + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __GRLIB_GRETH_H__ +#define __GRLIB_GRETH_H__ + +#define GRETH_FD 0x10 +#define GRETH_RESET 0x40 +#define GRETH_MII_BUSY 0x8 +#define GRETH_MII_NVALID 0x10 + +/* MII registers */ +#define GRETH_MII_EXTADV_1000FD 0x00000200 +#define GRETH_MII_EXTADV_1000HD 0x00000100 +#define GRETH_MII_EXTPRT_1000FD 0x00000800 +#define GRETH_MII_EXTPRT_1000HD 0x00000400 + +#define GRETH_MII_100T4 0x00000200 +#define GRETH_MII_100TXFD 0x00000100 +#define GRETH_MII_100TXHD 0x00000080 +#define GRETH_MII_10FD 0x00000040 +#define GRETH_MII_10HD 0x00000020 + +#define GRETH_BD_EN 0x800 +#define GRETH_BD_WR 0x1000 +#define GRETH_BD_IE 0x2000 +#define GRETH_BD_LEN 0x7FF + +#define GRETH_TXEN 0x1 +#define GRETH_INT_TX 0x8 +#define GRETH_TXI 0x4 +#define GRETH_TXBD_STATUS 0x0001C000 +#define GRETH_TXBD_MORE 0x20000 +#define GRETH_TXBD_IPCS 0x40000 +#define GRETH_TXBD_TCPCS 0x80000 +#define GRETH_TXBD_UDPCS 0x100000 +#define GRETH_TXBD_ERR_LC 0x10000 +#define GRETH_TXBD_ERR_UE 0x4000 +#define GRETH_TXBD_ERR_AL 0x8000 +#define GRETH_TXBD_NUM 128 +#define GRETH_TXBD_NUM_MASK (GRETH_TXBD_NUM-1) +#define GRETH_TX_BUF_SIZE 2048 + +#define GRETH_INT_RX 0x4 +#define GRETH_RXEN 0x2 +#define GRETH_RXI 0x8 +#define GRETH_RXBD_STATUS 0xFFFFC000 +#define GRETH_RXBD_ERR_AE 0x4000 +#define GRETH_RXBD_ERR_FT 0x8000 +#define GRETH_RXBD_ERR_CRC 0x10000 +#define GRETH_RXBD_ERR_OE 0x20000 +#define GRETH_RXBD_ERR_LE 0x40000 +#define GRETH_RXBD_IP_DEC 0x80000 +#define GRETH_RXBD_IP_CSERR 0x100000 +#define GRETH_RXBD_UDP_DEC 0x200000 +#define GRETH_RXBD_UDP_CSERR 0x400000 +#define GRETH_RXBD_TCP_DEC 0x800000 +#define GRETH_RXBD_TCP_CSERR 0x1000000 + +#define GRETH_RXBD_NUM 128 +#define GRETH_RXBD_NUM_MASK (GRETH_RXBD_NUM-1) +#define GRETH_RX_BUF_SIZE 2048 + +/* Ethernet configuration registers */ +typedef struct _greth_regs { + volatile unsigned int control; + volatile unsigned int status; + volatile unsigned int esa_msb; + volatile unsigned int esa_lsb; + volatile unsigned int mdio; + volatile unsigned int tx_desc_p; + volatile unsigned int rx_desc_p; + volatile unsigned int edcl_ip; +} greth_regs; + +/* Ethernet buffer descriptor */ +typedef struct _greth_bd { + volatile unsigned int stat; + unsigned int addr; /* Buffer address not changed by HW */ +} greth_bd; + +#endif diff --git a/include/grlib/irqmp.h b/include/grlib/irqmp.h new file mode 100644 index 0000000000..0354d5c21c --- /dev/null +++ b/include/grlib/irqmp.h @@ -0,0 +1,23 @@ +/* GRLIB IRQMP (IRQ Multi-processor controller) definitions + * + * (C) Copyright 2010, 2015 + * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __GRLIB_IRQMP_H__ +#define __GRLIB_IRQMP_H__ + +typedef struct { + volatile unsigned int ilevel; + volatile unsigned int ipend; + volatile unsigned int iforce; + volatile unsigned int iclear; + volatile unsigned int mstatus; + volatile unsigned int notused[11]; + volatile unsigned int cpu_mask[16]; + volatile unsigned int cpu_force[16]; +} ambapp_dev_irqmp; + +#endif |