From 72bcbd4bfb99a68d11dabce6a2a13f4c499cdd4d Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Sat, 24 Oct 2015 23:14:55 +0200 Subject: sparc: Fix broken files during license changes Fixes broken search and replaced license changes in files cpu/leon3/start.S and include/asm/winmacro.h from commit 1a4596601fd395f3afb8f82f3f840c5e00bdd57a Signed-off-by: Francois Retief Series-to: u-boot Series-cc: Tom Rini Series-version: 2 Cover-letter: sparc: Updates to SPARC architecture in preperation for generic board This patch series is a backlog of preparation work for upcomming generic board changes. I first want to get these reviewed and submitted to mainline before sending out more patches. END --- arch/sparc/cpu/leon3/start.S | 3 - arch/sparc/include/asm/winmacro.h | 127 -------------------------------------- 2 files changed, 130 deletions(-) diff --git a/arch/sparc/cpu/leon3/start.S b/arch/sparc/cpu/leon3/start.S index cf897f6877..5f904faf71 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+ */ 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 -#include - -/* 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 -- cgit v1.2.1 From fdf075fbeef6da2ffebab03268974ad81f10fc84 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Mon, 26 Oct 2015 12:32:25 +0200 Subject: sparc: Update the maintainer for SPARC architecture Signed-off-by: Francois Retief --- MAINTAINERS | 2 +- doc/git-mailrc | 2 +- 2 files changed, 2 insertions(+), 2 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 +M: Francois Retief S: Maintained T: git git://git.denx.de/u-boot-sparc.git F: arch/sparc/ 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 +alias sparc uboot, Francois Retief alias superh uboot, iwamatsu alias sh superh -- cgit v1.2.1 From c33759aebdb390ba20fa40a97e9d6f3cd19371f6 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Mon, 26 Oct 2015 12:27:15 +0200 Subject: sparc: Add -mcpu= compiler flags for LEON2/LEON3 Signed-off-by: Francois Retief --- arch/sparc/config.mk | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) 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 -- cgit v1.2.1 From a50adb7b4d86b924789dbe437ae92006d2f654f8 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Wed, 28 Oct 2015 10:35:12 +0200 Subject: sparc: Update LEON serial drivers to use readl/writel macros Update the LEON2/3 serial driver to make use of the readl and writel macros as well as the WATCHDOG_RESET() macro. Add readl/writel and friends to the asm/io.h file. Introduce the gd->arch.uart variable to store register address. Lastly, remove baudrate scaler macro variables from board config. It is now calculated in the serial driver using the global data variable. Signed-off-by: Francois Retief --- arch/sparc/cpu/leon2/serial.c | 125 +++++++++++++++++------------------ arch/sparc/cpu/leon3/prom.c | 5 +- arch/sparc/cpu/leon3/serial.c | 100 ++++++++++++++++------------ arch/sparc/include/asm/global_data.h | 1 + arch/sparc/include/asm/io.h | 64 ++++++++++-------- include/configs/gr_cpci_ax2000.h | 4 -- include/configs/gr_ep2s60.h | 4 -- include/configs/gr_xc3s_1500.h | 4 -- include/configs/grsim.h | 3 - include/configs/grsim_leon2.h | 5 -- 10 files changed, 157 insertions(+), 158 deletions(-) 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 -#include -#include +#include #include -#include +#include 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/leon3/prom.c b/arch/sparc/cpu/leon3/prom.c index b83776bc06..d0f18603a1 100644 --- a/arch/sparc/cpu/leon3/prom.c +++ b/arch/sparc/cpu/leon3/prom.c @@ -21,7 +21,8 @@ #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"))) @@ -909,7 +910,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..f1dcab3377 100644 --- a/arch/sparc/cpu/leon3/serial.c +++ b/arch/sparc/cpu/leon3/serial.c @@ -1,66 +1,70 @@ /* 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 -#include -#include +#include #include #include -#include +#include DECLARE_GLOBAL_DATA_PTR; -ambapp_dev_apbuart *leon3_apbuart = NULL; - 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_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) != 1) + 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) & LEON_REG_UART_CTRL_DBG; + /* Receiver & transmitter enable */ + tmp |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_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) & LEON_REG_UART_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) & LEON_REG_UART_STATUS_TSE)) + WATCHDOG_RESET(); #endif } @@ -74,36 +78,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) & LEON_REG_UART_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) & LEON_REG_UART_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 = { 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 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/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h index 782746e4e0..060f116df2 100644 --- a/include/configs/gr_cpci_ax2000.h +++ b/include/configs/gr_cpci_ax2000.h @@ -342,10 +342,6 @@ #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) - /* 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..005f7796fb 100644 --- a/include/configs/gr_ep2s60.h +++ b/include/configs/gr_ep2s60.h @@ -309,10 +309,6 @@ #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) - /* 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..3523cde3c7 100644 --- a/include/configs/gr_xc3s_1500.h +++ b/include/configs/gr_xc3s_1500.h @@ -274,10 +274,6 @@ #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) - /* 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..8959e332ce 100644 --- a/include/configs/grsim.h +++ b/include/configs/grsim.h @@ -280,9 +280,6 @@ #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) - /* default kernel command line */ #define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0" 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 -- cgit v1.2.1 From b6b280ce07b33b05279a31aff0edeba7b7e446f5 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Tue, 4 Nov 2014 16:51:44 +0200 Subject: sparc: Update GRSIM board with memory settings for TSIM eval Update the GRSIM board with the memory settings for the evaluation version of TSIM. This free version of TSIM is used for testing. Signed-off-by: Francois Retief --- configs/grsim_defconfig | 1 + include/configs/grsim.h | 57 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/configs/grsim_defconfig b/configs/grsim_defconfig index f0fa23f810..b0295f2f0c 100644 --- a/configs/grsim_defconfig +++ b/configs/grsim_defconfig @@ -11,4 +11,5 @@ 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 diff --git a/include/configs/grsim.h b/include/configs/grsim.h index 8959e332ce..a5387852c2 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 */ @@ -184,18 +188,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 +228,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 +240,8 @@ /* #define CONFIG_GRETH_10MBIT 1 */ #define CONFIG_PHY_ADDR 0x00 +#endif /* CONFIG_CMD_NET */ + /* * Miscellaneous configurable options */ @@ -259,13 +266,14 @@ /*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/ #define CONFIG_SYS_GRLIB_SDRAM 0 + #define CONFIG_SYS_GRLIB_MEMCFG1 (0x000000ff | (1<<11)) #if CONFIG_GRSIM /* GRSIM configuration */ #define CONFIG_SYS_GRLIB_MEMCFG2 0x82206000 #else /* TSIM configuration */ -#define CONFIG_SYS_GRLIB_MEMCFG2 0x00001820 +#define CONFIG_SYS_GRLIB_MEMCFG2 0x81805220 #endif #define CONFIG_SYS_GRLIB_MEMCFG3 0x00136000 @@ -285,4 +293,29 @@ #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 */ -- cgit v1.2.1 From 0070109f683657ba3f864792ae134f74282ae4e8 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Wed, 28 Oct 2015 09:06:41 +0200 Subject: sparc: Update startup code to take PIC mode into account Signed-off-by: Francois Retief --- arch/sparc/cpu/leon2/start.S | 60 ++++++++++++++++++++++++++++++-------------- arch/sparc/cpu/leon3/start.S | 60 ++++++++++++++++++++++++++++++-------------- 2 files changed, 82 insertions(+), 38 deletions(-) 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/start.S b/arch/sparc/cpu/leon3/start.S index 5f904faf71..be9b3fb20b 100644 --- a/arch/sparc/cpu/leon3/start.S +++ b/arch/sparc/cpu/leon3/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)) @@ -229,7 +250,7 @@ clear_window: bge clear_window save -wininit: +wiminit: set WIM_INIT, %g3 mov %g3, %wim @@ -240,7 +261,7 @@ stackp: cpu_init_unreloc: call cpu_init_f - nop + nop /* un relocated start address of monitor */ #define TEXT_START _text @@ -248,9 +269,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 @@ -260,7 +282,7 @@ reloc_loop: inc 16,%g2 subcc %g3,%g2,%g0 bne reloc_loop - inc 16,%g4 + inc 16,%g4 clr %l0 clr %l1 @@ -277,8 +299,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 */ @@ -289,19 +311,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 @@ -316,11 +338,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: @@ -331,7 +353,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 @@ -358,19 +380,19 @@ 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 add %o1,%o2,%o1 sub %o1,%g1,%o1 call %o1 - clr %o0 + clr %o0 dead: ta 0 ! if call returns... nop -- cgit v1.2.1 From 898cc81da3dd5bfa0f77f1791f76d3512b5e4dce Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Mon, 25 Jan 2010 09:54:51 +0100 Subject: sparc: leon3: Reimplemented AMBA Plug&Play scanning routines. Signed-off-by: Daniel Hellstrom --- arch/sparc/cpu/leon3/Makefile | 3 +- arch/sparc/cpu/leon3/ambapp.c | 544 ++++++++++++------------- arch/sparc/cpu/leon3/ambapp_low.S | 784 ++++++++++++++++++++++++++++++++++++ arch/sparc/cpu/leon3/ambapp_low_c.S | 113 ++++++ arch/sparc/cpu/leon3/cpu_init.c | 184 +++------ arch/sparc/cpu/leon3/serial.c | 8 +- arch/sparc/cpu/leon3/usb_uhci.c | 4 +- common/cmd_ambapp.c | 542 +++++++++++++++++++------ drivers/net/greth.c | 15 +- include/ambapp.h | 365 ++++++++--------- include/ambapp_ids.h | 239 +++++++++++ 11 files changed, 2070 insertions(+), 731 deletions(-) create mode 100644 arch/sparc/cpu/leon3/ambapp_low.S create mode 100644 arch/sparc/cpu/leon3/ambapp_low_c.S create mode 100644 include/ambapp_ids.h diff --git a/arch/sparc/cpu/leon3/Makefile b/arch/sparc/cpu/leon3/Makefile index 4f13ec3071..c5068a8ecf 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 diff --git a/arch/sparc/cpu/leon3/ambapp.c b/arch/sparc/cpu/leon3/ambapp.c index a30d1f2a99..bb81338dac 100644 --- a/arch/sparc/cpu/leon3/ambapp.c +++ b/arch/sparc/cpu/leon3/ambapp.c @@ -1,343 +1,315 @@ -/* 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 -#include #include +#include + +/************ 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]; + + printf(" 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 + + .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..f23ecb89be 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+ */ @@ -14,6 +14,11 @@ #include +/* 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) @@ -39,64 +44,30 @@ 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 */ } +/* 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 +76,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 diff --git a/arch/sparc/cpu/leon3/serial.c b/arch/sparc/cpu/leon3/serial.c index f1dcab3377..c4a49ed369 100644 --- a/arch/sparc/cpu/leon3/serial.c +++ b/arch/sparc/cpu/leon3/serial.c @@ -14,6 +14,11 @@ DECLARE_GLOBAL_DATA_PTR; +/* 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; @@ -21,7 +26,8 @@ static int leon3_serial_init(void) 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) return -1; /* didn't find hardware */ /* found apbuart, let's init .. */ 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/common/cmd_ambapp.c b/common/cmd_ambapp.c index 2a1995a761..b1a8fa8f0b 100644 --- a/common/cmd_ambapp.c +++ b/common/cmd_ambapp.c @@ -15,92 +15,358 @@ 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_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", ""}, + {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_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_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", ""}, + {GAISLER_GRTMPAHB, "GRTMPAHB", "CCSDS Telemetry VC AHB Input"}, + {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 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_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 +375,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) { - return ambapp_get_devname(ven->devices, id); + 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) { + dev = ambapp_get_dev(ven->devices, id); + if (!dev) + return NULL; + return dev->desc; } ven++; } @@ -134,101 +421,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 +532,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/drivers/net/greth.c b/drivers/net/greth.c index 9bc8a8d1aa..375646396a 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -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/include/ambapp.h b/include/ambapp.h index 405637d8cd..7643df5759 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,116 +12,136 @@ #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 - * - */ +#include -#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) +#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 */ +}; -#define amba_ver(conf) (((conf)>>5) & 0x1f) +/* AMBA Plug&Play AHB Masters & Slaves information locations + * Max devices is 64 supported by HW, however often only 16 + * are used. + */ +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; -#define amba_membar_type(mbar) ((mbar) & 0xf) +/* 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; -#define amba_membar_mask(mbar) (((mbar)>>4) & 0xfff) +/* Scan AMBA Bus for AHB Bridges */ +extern void ambapp_bus_init( + unsigned int ioarea, + unsigned int freq, + struct ambapp_bus *abus); -#define AMBA_TYPE_APBIO 0x1 -#define AMBA_TYPE_MEM 0x2 -#define AMBA_TYPE_AHBIO 0x3 +/* 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); -#define AMBA_TYPE_AHBIO_ADDR(addr) (LEON3_IO_AREA | ((addr) >> 12)) +/* 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); -#ifndef __ASSEMBLER__ +/* 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); #ifdef CONFIG_CMD_AMBAPP @@ -135,109 +155,72 @@ 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 - */ +/* Return description of a device */ +char *ambapp_device_id2desc(int vendor, int id); -/* AMBA Plug&Play AHB information layout */ -typedef struct { - unsigned int conf; - unsigned int userdef[3]; - unsigned int bars[4]; -} ahbctrl_pp_dev; +#endif -/* Prototypes for scanning AMBA Plug&Play bus for AMBA - * i) AHB Masters - * ii) AHB Slaves - * iii) APB Slaves (APB MST is a AHB Slave) - */ +#endif /* defined(__ASSEMBLER__) */ -typedef struct { - unsigned char irq; - unsigned char ver; - unsigned int address; -} ambapp_apbdev; - -typedef struct { - unsigned char irq; - unsigned char ver; - unsigned int userdef[3]; - unsigned int address[4]; -} ambapp_ahbdev; +#define AMBA_DEFAULT_IOAREA 0xfff00000 +#define AMBA_CONF_AREA 0xff000 +#define AMBA_AHB_SLAVE_CONF_AREA 0x800 -/* 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; +#define DEV_NONE 0 +#define DEV_AHB_MST 1 +#define DEV_AHB_SLV 2 +#define DEV_APB_SLV 3 -/* AMBA Plug&Play AHB information layout */ -typedef struct { - unsigned int conf; - unsigned int bar; -} apbctrl_pp_dev; +#define AMBA_TYPE_APBIO 0x1 +#define AMBA_TYPE_MEM 0x2 +#define AMBA_TYPE_AHBIO 0x3 -/* All functions return the number of found devices - * 0 = no devices found +/* 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. */ -/****************************** 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); +#define amba_vendor(x) (((x) >> 24) & 0xff) -int ambapp_ahbmst_next(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int index); +#define amba_device(x) (((x) >> 12) & 0xfff) -int ambapp_ahbmsts_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int max_cnt); +#define amba_irq(conf) ((conf) & 0x1f) -/****************************** AHB SLAVES ******************************/ -int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver); +#define amba_ver(conf) (((conf)>>5) & 0x1f) -int ambapp_ahbslv_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev); +#define amba_iobar_start(base, iobar) \ + ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4))) -int ambapp_ahbslv_next(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int index); +#define amba_membar_start(mbar) \ + (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16)) -int ambapp_ahbslvs_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int max_cnt); +#define amba_membar_type(mbar) ((mbar) & 0xf) -/*************************** 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); +#define amba_membar_mask(mbar) (((mbar) >> 4) & 0xfff) -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); +#define amba_ahbio_adr(addr, base_ioarea) \ + ((unsigned int)(base_ioarea) | ((addr) >> 12)) -unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info); +#define amba_apb_mask(iobar) ((~(amba_membar_mask(iobar)<<8) & 0x000fffff) + 1) /*************************** AMBA Plug&Play device register MAPS *****************/ @@ -291,6 +274,8 @@ unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info); #define LEON_REG_PS2_CTRL_RI 0x00000004 /* Keyboard receive interrupt */ #define LEON_REG_PS2_CTRL_TI 0x00000008 /* Keyboard transmit interrupt */ +#ifndef __ASSEMBLER__ + typedef struct { volatile unsigned int ilevel; volatile unsigned int ipend; diff --git a/include/ambapp_ids.h b/include/ambapp_ids.h new file mode 100644 index 0000000000..c010d604cc --- /dev/null +++ b/include/ambapp_ids.h @@ -0,0 +1,239 @@ +/* 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_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_LEON4 0x048 +#define GAISLER_LEON4DSU 0x049 +#define GAISLER_PWM 0x04a +#define GAISLER_L2CACHE 0x04b +#define GAISLER_SDCTRL64 0x04c +#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_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_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 + +/* 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 -- cgit v1.2.1 From 3f33f6a28b7a823bfa19157353e8b7c78c63f63c Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Mon, 27 Oct 2014 13:39:03 +0200 Subject: sparc: Kconfig: Move the CMD_AMBAPP command to Kconfig Add an initr function in the board_r.c file for the AMBA Plug&Play command. Add a Kconfig entry for the ambapp command and remove all CONFIG_CMD_AMBAPP defines from the board configuration headers. Add a Kconfig entry to display the AMBA Plug&Play information on startup. This option is off by default. Remove relevent define from board configuration headers. Signed-off-by: Francois Retief --- common/Kconfig | 14 ++++++++++++++ common/board_r.c | 21 +++++++++++++++++++++ configs/grsim_defconfig | 1 + include/config_cmd_all.h | 1 - include/configs/gr_cpci_ax2000.h | 4 ---- include/configs/gr_ep2s60.h | 4 ---- include/configs/gr_xc3s_1500.h | 4 ---- include/configs/grsim.h | 4 ---- 8 files changed, 36 insertions(+), 17 deletions(-) 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 c4fd3eaf8c..32cb4b767e 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -46,6 +46,9 @@ #include #include #include +#ifdef CONFIG_CMD_AMBAPP +#include +#endif #ifdef CONFIG_ADDR_MAP #include #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) { @@ -851,6 +866,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/configs/grsim_defconfig b/configs/grsim_defconfig index b0295f2f0c..a5ea7ab8d8 100644 --- a/configs/grsim_defconfig +++ b/configs/grsim_defconfig @@ -13,3 +13,4 @@ CONFIG_SYS_TEXT_BASE=0x00000000 # 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 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 060f116df2..846178793d 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,9 +310,6 @@ /***** 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 /* See, GRLIB Docs (grip.pdf) on how to set up diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h index 005f7796fb..2f953aeb9a 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,9 +287,6 @@ /***** 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 /* See, GRLIB Docs (grip.pdf) on how to set up diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h index 3523cde3c7..428b5324ee 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,9 +250,6 @@ /***** 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 /* See, GRLIB Docs (grip.pdf) on how to set up diff --git a/include/configs/grsim.h b/include/configs/grsim.h index a5387852c2..e07b81641a 100644 --- a/include/configs/grsim.h +++ b/include/configs/grsim.h @@ -51,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 @@ -262,9 +261,6 @@ /***** 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)) -- cgit v1.2.1 From cff009ed6ff7da2e87f8213d34ed869be4373604 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Mon, 25 Jan 2010 09:56:08 +0100 Subject: sparc: leon3: Added memory controller initialization using new AMBA PnP routines. Signed-off-by: Daniel Hellstrom --- arch/sparc/cpu/leon3/Makefile | 2 +- arch/sparc/cpu/leon3/memcfg.c | 237 +++++++++++++++++++++++++++++++++++ arch/sparc/cpu/leon3/memcfg.h | 90 ++++++++++++++ arch/sparc/cpu/leon3/memcfg_low.S | 253 ++++++++++++++++++++++++++++++++++++++ arch/sparc/cpu/leon3/start.S | 41 +++++- include/configs/gr_cpci_ax2000.h | 27 ++-- include/configs/gr_ep2s60.h | 32 +++-- include/configs/gr_xc3s_1500.h | 23 ++-- include/configs/grsim.h | 26 ++-- 9 files changed, 688 insertions(+), 43 deletions(-) create mode 100644 arch/sparc/cpu/leon3/memcfg.c create mode 100644 arch/sparc/cpu/leon3/memcfg.h create mode 100644 arch/sparc/cpu/leon3/memcfg_low.S diff --git a/arch/sparc/cpu/leon3/Makefile b/arch/sparc/cpu/leon3/Makefile index c5068a8ecf..f4cf43cfec 100644 --- a/arch/sparc/cpu/leon3/Makefile +++ b/arch/sparc/cpu/leon3/Makefile @@ -7,4 +7,4 @@ extra-y = start.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 + interrupts.o prom.o usb_uhci.o memcfg.o memcfg_low.o 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 +#include "memcfg.h" +#include + +#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 +#include "memcfg.h" +#include + + .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/start.S b/arch/sparc/cpu/leon3/start.S index be9b3fb20b..203114970b 100644 --- a/arch/sparc/cpu/leon3/start.S +++ b/arch/sparc/cpu/leon3/start.S @@ -13,6 +13,12 @@ #include #include #include +#include + +/* 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) \ @@ -208,6 +214,7 @@ version_string: .ascii U_BOOT_VERSION_STRING, "\0" .section ".text" + .extern _nomem_amba_init, _nomem_memory_ctrl_init .align 4 _hardreset: @@ -259,6 +266,38 @@ 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 @@ -269,7 +308,6 @@ cpu_init_unreloc: /* un relocated end address of monitor */ #define DATA_END __init_end - SPARC_PIC_THUNK_CALL(l7) reloc: SPARC_LOAD_ADDRESS(TEXT_START, l7, g2) SPARC_LOAD_ADDRESS(DATA_END, l7, g3) @@ -389,6 +427,7 @@ jump: 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 diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h index 846178793d..5bbf1aaae8 100644 --- a/include/configs/gr_cpci_ax2000.h +++ b/include/configs/gr_cpci_ax2000.h @@ -312,31 +312,36 @@ #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 +#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 2f953aeb9a..b55ca77a87 100644 --- a/include/configs/gr_ep2s60.h +++ b/include/configs/gr_ep2s60.h @@ -289,21 +289,29 @@ #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 +#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 428b5324ee..d086b694c2 100644 --- a/include/configs/gr_xc3s_1500.h +++ b/include/configs/gr_xc3s_1500.h @@ -252,23 +252,28 @@ #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 +#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 e07b81641a..e1f7dc3bf6 100644 --- a/include/configs/grsim.h +++ b/include/configs/grsim.h @@ -264,25 +264,33 @@ #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 0x81805220 +#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 +#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1 /* default kernel command line */ #define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0" -- cgit v1.2.1 From f2879f5952b35009c76de92ca57d67ab628bac0c Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Thu, 21 Jan 2010 16:09:37 +0100 Subject: sparc: leon3: Moved GRLIB core header files to common include/grlib directory Signed-off-by: Daniel Hellstrom --- arch/sparc/cpu/leon3/cpu_init.c | 10 ++- arch/sparc/cpu/leon3/interrupts.c | 7 +- arch/sparc/cpu/leon3/prom.c | 7 +- arch/sparc/cpu/leon3/serial.c | 13 ++-- common/cmd_ambapp.c | 21 +++++- drivers/net/greth.c | 2 +- include/ambapp.h | 137 -------------------------------------- include/ambapp_ids.h | 11 +++ include/grlib/apbuart.h | 47 +++++++++++++ include/grlib/gptimer.h | 34 ++++++++++ include/grlib/greth.h | 87 ++++++++++++++++++++++++ include/grlib/irqmp.h | 23 +++++++ 12 files changed, 242 insertions(+), 157 deletions(-) create mode 100644 include/grlib/apbuart.h create mode 100644 include/grlib/gptimer.h create mode 100644 include/grlib/greth.h create mode 100644 include/grlib/irqmp.h diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c index f23ecb89be..40d1751fcb 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include @@ -27,11 +29,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; @@ -150,8 +148,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 #include +#include +#include /* 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/prom.c b/arch/sparc/cpu/leon3/prom.c index d0f18603a1..c391be7420 100644 --- a/arch/sparc/cpu/leon3/prom.c +++ b/arch/sparc/cpu/leon3/prom.c @@ -15,6 +15,9 @@ #include #include #include +#include +#include +#include #include /* @@ -741,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; } diff --git a/arch/sparc/cpu/leon3/serial.c b/arch/sparc/cpu/leon3/serial.c index c4a49ed369..cefb9d2c36 100644 --- a/arch/sparc/cpu/leon3/serial.c +++ b/arch/sparc/cpu/leon3/serial.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -38,9 +39,9 @@ static int leon3_serial_init(void) writel(tmp, &uart->scaler); /* Let bit 11 be unchanged (debug bit for GRMON) */ - tmp = readl(&uart->ctrl) & LEON_REG_UART_CTRL_DBG; + tmp = readl(&uart->ctrl) & APBUART_CTRL_DBG; /* Receiver & transmitter enable */ - tmp |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE; + tmp |= APBUART_CTRL_RE | APBUART_CTRL_TE; writel(tmp, &uart->ctrl); gd->arch.uart = uart; @@ -61,7 +62,7 @@ static void leon3_serial_putc_raw(const char c) return; /* Wait for last character to go. */ - while (!(readl(&uart->status) & LEON_REG_UART_STATUS_THE)) + while (!(readl(&uart->status) & APBUART_STATUS_THE)) WATCHDOG_RESET(); /* Send data */ @@ -69,7 +70,7 @@ static void leon3_serial_putc_raw(const char c) #ifdef LEON_DEBUG /* Wait for data to be sent */ - while (!(readl(&uart->status) & LEON_REG_UART_STATUS_TSE)) + while (!(readl(&uart->status) & APBUART_STATUS_TSE)) WATCHDOG_RESET(); #endif } @@ -90,7 +91,7 @@ static int leon3_serial_getc(void) return 0; /* Wait for a character to arrive. */ - while (!(readl(&uart->status) & LEON_REG_UART_STATUS_DR)) + while (!(readl(&uart->status) & APBUART_STATUS_DR)) WATCHDOG_RESET(); /* Read character data */ @@ -104,7 +105,7 @@ static int leon3_serial_tstc(void) if (!uart) return 0; - return readl(&uart->status) & LEON_REG_UART_STATUS_DR; + return readl(&uart->status) & APBUART_STATUS_DR; } /* set baud rate for uart */ diff --git a/common/cmd_ambapp.c b/common/cmd_ambapp.c index b1a8fa8f0b..4b6d1741e9 100644 --- a/common/cmd_ambapp.c +++ b/common/cmd_ambapp.c @@ -96,11 +96,15 @@ static ambapp_device_name GAISLER_devices[] = { {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", ""}, + {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"}, @@ -108,6 +112,8 @@ static ambapp_device_name GAISLER_devices[] = { {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"}, @@ -130,6 +136,7 @@ static ambapp_device_name GAISLER_devices[] = { {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"}, @@ -137,8 +144,11 @@ static ambapp_device_name GAISLER_devices[] = { {GAISLER_GRTMDESC, "GRTMDESC", "CCSDS Telemetry Descriptor"}, {GAISLER_GRTMVC, "GRTMVC", "CCSDS Telemetry VC Generator"}, {GAISLER_GEFFE, "GEFFE", "Geffe Generator"}, - {GAISLER_GPREG, "GPREG", ""}, + {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} }; @@ -318,6 +328,12 @@ static ambapp_device_name CETON_devices[] = { }; +/** 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"}, @@ -351,6 +367,7 @@ static ambapp_vendor_devnames vendors[] = { {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}, diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 375646396a..0624eb8cac 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -20,7 +20,7 @@ #include #include -#include "greth.h" +#include /* Default to 3s timeout on autonegotiation */ #ifndef GRETH_PHY_TIMEOUT_MS diff --git a/include/ambapp.h b/include/ambapp.h index 7643df5759..d79fcedb41 100644 --- a/include/ambapp.h +++ b/include/ambapp.h @@ -222,141 +222,4 @@ char *ambapp_device_id2desc(int vendor, int id); #define amba_apb_mask(iobar) ((~(amba_membar_mask(iobar)<<8) & 0x000fffff) + 1) -/*************************** AMBA Plug&Play device register MAPS *****************/ - -/* - * The following defines the bits in the LEON UART Status Registers. - */ - -#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 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 */ - -/* - * The following defines the bits in the LEON PS/2 Ctrl 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 */ - -#ifndef __ASSEMBLER__ - -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; - -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 */ - -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; - -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; - -typedef struct { - volatile unsigned int data; - volatile unsigned int status; - volatile unsigned int ctrl; -} ambapp_dev_apbps2; - -typedef struct { - unsigned int mcfg1, mcfg2, mcfg3; -} ambapp_dev_mctrl; - -typedef struct { - unsigned int sdcfg; -} ambapp_dev_sdctrl; - -typedef struct { - unsigned int cfg1; - unsigned int cfg2; - unsigned int cfg3; -} ambapp_dev_ddr2spa; - -typedef struct { - unsigned int ctrl; - unsigned int cfg; -} ambapp_dev_ddrspa; - -#endif - #endif diff --git a/include/ambapp_ids.h b/include/ambapp_ids.h index c010d604cc..1eae34e554 100644 --- a/include/ambapp_ids.h +++ b/include/ambapp_ids.h @@ -27,6 +27,7 @@ #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 @@ -100,11 +101,15 @@ #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 @@ -112,6 +117,8 @@ #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 @@ -134,6 +141,7 @@ #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 @@ -143,6 +151,9 @@ #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 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 -- cgit v1.2.1 From 5786071e4a3b9091940580c208e27d21fdc269cf Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Mon, 20 Sep 2010 10:00:49 +0200 Subject: sparc: ambapp: Removed warning and unnecessary printout. Signed-off-by: Daniel Hellstrom --- arch/sparc/cpu/leon3/ambapp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/sparc/cpu/leon3/ambapp.c b/arch/sparc/cpu/leon3/ambapp.c index bb81338dac..b8ac05faf1 100644 --- a/arch/sparc/cpu/leon3/ambapp.c +++ b/arch/sparc/cpu/leon3/ambapp.c @@ -10,6 +10,7 @@ /* #define DEBUG */ #include +#include #include #include @@ -257,7 +258,7 @@ unsigned int ambapp_bus_freq(struct ambapp_bus *abus, int ahb_bus_index) /* Get I/O area of AHB bus */ ioarea = abus->ioareas[ahb_bus_index]; - printf(" IOAREA: 0x%08x\n", ioarea); + debug(" IOAREA: 0x%08x\n", ioarea); /* Get parent bus */ parent = (ioarea & 0x7); -- cgit v1.2.1 From e43ce3fca755d79635899b658a97f3c4a7dbf220 Mon Sep 17 00:00:00 2001 From: Francois Retief Date: Thu, 29 Oct 2015 12:55:34 +0200 Subject: sparc: leon3: Add debug_uart support to LEON3 serial driver. Signed-off-by: Francois Retief --- arch/sparc/cpu/leon3/cpu_init.c | 5 ++++- arch/sparc/cpu/leon3/serial.c | 27 ++++++++++++++++++++++++++- configs/grsim_defconfig | 4 ++++ drivers/serial/Kconfig | 8 ++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/arch/sparc/cpu/leon3/cpu_init.c b/arch/sparc/cpu/leon3/cpu_init.c index 40d1751fcb..b140da31b1 100644 --- a/arch/sparc/cpu/leon3/cpu_init.c +++ b/arch/sparc/cpu/leon3/cpu_init.c @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -50,7 +51,9 @@ struct { */ void cpu_init_f(void) { - +#ifdef CONFIG_DEBUG_UART + debug_uart_init(); +#endif } /* Routine called from start.S, diff --git a/arch/sparc/cpu/leon3/serial.c b/arch/sparc/cpu/leon3/serial.c index cefb9d2c36..66b3773027 100644 --- a/arch/sparc/cpu/leon3/serial.c +++ b/arch/sparc/cpu/leon3/serial.c @@ -28,8 +28,10 @@ static int leon3_serial_init(void) /* find UART */ if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_APBUART, - CONFIG_SYS_GRLIB_APBUART_INDEX, &apbdev) != 1) + CONFIG_SYS_GRLIB_APBUART_INDEX, &apbdev) != 1) { + panic("%s: apbuart not found!\n", __func__); return -1; /* didn't find hardware */ + } /* found apbuart, let's init .. */ uart = (ambapp_dev_apbuart *) apbdev.address; @@ -145,3 +147,26 @@ __weak struct serial_device *default_serial_console(void) { return &leon3_serial_drv; } + +#ifdef CONFIG_DEBUG_UART_APBUART + +#include + +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/configs/grsim_defconfig b/configs/grsim_defconfig index a5ea7ab8d8..d2f709f834 100644 --- a/configs/grsim_defconfig +++ b/configs/grsim_defconfig @@ -14,3 +14,7 @@ CONFIG_SYS_TEXT_BASE=0x00000000 # 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/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 -- cgit v1.2.1