提交 618a51e9 编写于 作者: T Tom Rini

Merge branch 'series1_v2' of git://git.denx.de/u-boot-sparc

......@@ -370,7 +370,7 @@ T: git git://git.denx.de/u-boot-sh.git
F: arch/sh/
SPARC
M: Daniel Hellstrom <daniel@gaisler.com>
M: Francois Retief <fgretief@spaceteq.co.za>
S: Maintained
T: git git://git.denx.de/u-boot-sparc.git
F: arch/sparc/
......
#
# (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
/* GRLIB APBUART Serial controller driver
*
* (C) Copyright 2008
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
* (C) Copyright 2008, 2015
* Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/processor.h>
#include <asm/leon.h>
#include <asm/io.h>
#include <serial.h>
#include <linux/compiler.h>
#include <watchdog.h>
DECLARE_GLOBAL_DATA_PTR;
static unsigned leon2_serial_calc_scaler(unsigned freq, unsigned baud)
{
return (((freq*10) / (baud*8)) - 5) / 10;
}
static int leon2_serial_init(void)
{
LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
LEON2_regs *leon2 = (LEON2_regs *)LEON2_PREGS;
LEON2_Uart_regs *regs;
unsigned int tmp;
/* Init LEON2 UART
*
* Set scaler / baud rate
*
* Receiver & transmitter enable
*/
#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
regs = (LEON2_Uart_regs *)&leon2->UART_Channel_1;
#else
regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
regs = (LEON2_Uart_regs *)&leon2->UART_Channel_2;
#endif
regs->UART_Scaler = CONFIG_SYS_LEON2_UART1_SCALER;
/* Set scaler / baud rate */
tmp = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, CONFIG_BAUDRATE);
writel(tmp, &regs->UART_Scaler);
/* Let bit 11 be unchanged (debug bit for GRMON) */
tmp = READ_WORD(regs->UART_Control);
tmp = readl(&regs->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, &regs->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 = {
......
......@@ -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))
......@@ -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
......@@ -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 */
......@@ -352,15 +374,15 @@ clr_bss_16:
/* 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
......@@ -378,8 +400,8 @@ got_loop:
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:
......@@ -403,14 +425,14 @@ 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
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
......
......@@ -6,4 +6,5 @@
#
extra-y = start.o
obj-y = cpu_init.o serial.o cpu.o ambapp.o interrupts.o prom.o usb_uhci.o
obj-y = cpu_init.o serial.o cpu.o ambapp.o ambapp_low.o ambapp_low_c.o \
interrupts.o prom.o usb_uhci.o memcfg.o memcfg_low.o
/* Gaisler AMBA Plug&Play bus scanning. Functions
* ending on _nomem is inteded to be used only during
* initialization, only registers are used (no ram).
/* GRLIB AMBA Plug&Play information scanning, relies on assembler
* routines.
*
* (C) Copyright 2007
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
* (C) Copyright 2010, 2015
* Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/* #define DEBUG */
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <ambapp.h>
#include <config.h>
/************ C INTERFACE OF ASSEMBLER SCAN ROUTINES ************/
struct ambapp_find_apb_info {
/* Address of APB device Plug&Play information */
struct ambapp_pnp_apb *pnp;
/* AHB Bus index of where the APB-Master Bridge device was found */
int ahb_bus_index;
int dec_index;
};
#if defined(CONFIG_CMD_AMBAPP)
extern void ambapp_print_apb(apbctrl_pp_dev * apb,
ambapp_ahbdev * apbmst, int index);
extern void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index);
extern int ambapp_apb_print;
extern int ambapp_ahb_print;
#endif
static int ambapp_apb_scan(unsigned int vendor, /* Plug&Play Vendor ID */
unsigned int driver, /* Plug&Play Device ID */
ambapp_apbdev * dev, /* Result(s) is placed here */
int index, /* Index of device to start copying Plug&Play
* info into dev
*/
int max_cnt /* Maximal count that dev can hold, if dev
* is NULL function will stop scanning after
* max_cnt devices are found.
*/
)
{
int i, cnt = 0;
unsigned int apbmst_base;
ambapp_ahbdev apbmst;
apbctrl_pp_dev *apb;
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;
};
if (max_cnt == 0)
return 0;
extern void ambapp_find_buses(unsigned int ioarea, struct ambapp_bus *abus);
/* Get AMBA APB Master */
if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_APBMST, &apbmst) != 1) {
return 0;
}
extern int ambapp_find_apb(struct ambapp_bus *abus, unsigned int dev_vend,
int index, struct ambapp_find_apb_info *result);
/* 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 int ambapp_find_ahb(struct ambapp_bus *abus, unsigned int dev_vend,
int index, int type, struct ambapp_find_ahb_info *result);
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;
}
/************ C ROUTINES USED BY U-BOOT AMBA CORE DRIVERS ************/
struct ambapp_bus ambapp_plb;
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)
void ambapp_bus_init(
unsigned int ioarea,
unsigned int freq,
struct ambapp_bus *abus)
{
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;
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;
}
/****************************** APB SLAVES ******************************/
int ambapp_apb_count(unsigned int vendor, unsigned int driver)
/* Parse APB PnP Information */
void ambapp_apb_parse(struct ambapp_find_apb_info *info, ambapp_apbdev *dev)
{
return ambapp_apb_scan(vendor, driver, NULL, 0, LEON3_APB_SLAVES);
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_first(unsigned int vendor,
unsigned int driver, ambapp_apbdev * dev)
/* Parse AHB PnP information */
void ambapp_ahb_parse(struct ambapp_find_ahb_info *info, ambapp_ahbdev *dev)
{
return ambapp_apb_scan(vendor, driver, dev, 0, 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_apb_next(unsigned int vendor,
unsigned int driver, ambapp_apbdev * dev, int index)
int ambapp_apb_find(struct ambapp_bus *abus, int vendor, int device,
int index, ambapp_apbdev *dev)
{
return ambapp_apb_scan(vendor, driver, dev, index, 1);
unsigned int devid = AMBA_PNP_ID(vendor, device);
int found;
struct ambapp_find_apb_info apbdev;
found = ambapp_find_apb(abus, devid, index, &apbdev);
if (found == 1)
ambapp_apb_parse(&apbdev, dev);
return found;
}
int ambapp_apbs_first(unsigned int vendor,
unsigned int driver, ambapp_apbdev * dev, int max_cnt)
int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device)
{
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;
found = ambapp_find_apb(abus, devid, 63, &apbdev);
if (found == 1)
return 64;
else
return 63 - apbdev.dec_index;
}
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 ambapp_ahb_find(struct ambapp_bus *abus, int vendor, int device,
int index, ambapp_ahbdev *dev, int type)
{
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;
int found;
struct ambapp_find_ahb_info ahbdev;
unsigned int devid = AMBA_PNP_ID(vendor, device);
if (max_cnt == 0)
return 0;
found = ambapp_find_ahb(abus, devid, index, type, &ahbdev);
if (found == 1)
ambapp_ahb_parse(&ahbdev, dev);
if (type == 0) {
max_pp_devs = LEON3_AHB_MASTERS;
ahb = info->masters;
} else {
max_pp_devs = LEON3_AHB_SLAVES;
ahb = info->slaves;
}
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_ahbmst_find(struct ambapp_bus *abus, int vendor, int device,
int index, ambapp_ahbdev *dev)
{
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;
return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_MST);
}
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_ahbslv_find(struct ambapp_bus *abus, int vendor, int device,
int index, ambapp_ahbdev *dev)
{
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;
}
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;
return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_SLV);
}
/****************************** AHB MASTERS ******************************/
int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver)
int ambapp_ahb_count(struct ambapp_bus *abus, int vendor, int device, int type)
{
/* Get number of devices of this vendor&device ID */
return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_MASTERS,
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_ahbmst_first(unsigned int vendor, unsigned int driver,
ambapp_ahbdev * dev)
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, 1, AHB_SCAN_MASTER);
return ambapp_ahb_count(abus, vendor, device, DEV_AHB_MST);
}
int ambapp_ahbmst_next(unsigned int vendor,
unsigned int driver, ambapp_ahbdev * dev, int index)
int ambapp_ahbslv_count(struct ambapp_bus *abus, int vendor, int device)
{
/* find first device of this */
return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_MASTER);
return ambapp_ahb_count(abus, vendor, device, DEV_AHB_SLV);
}
int ambapp_ahbmsts_first(unsigned int vendor,
unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
{
/* find first device of this */
return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt,
AHB_SCAN_MASTER);
}
/* 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.
*/
/****************************** AHB SLAVES ******************************/
int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver)
{
/* Get number of devices of this vendor&device ID */
return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_SLAVES,
AHB_SCAN_SLAVE);
}
#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS
int ambapp_ahbslv_first(unsigned int vendor, unsigned int driver,
ambapp_ahbdev * dev)
/* GAISLER AHB2AHB Version 1 Bridge Definitions */
#define AHB2AHB_V1_FLAG_FFACT 0x0f0 /* Frequency factor against top bus */
#define AHB2AHB_V1_FLAG_FFACT_DIR 0x100 /* Factor direction, 0=down, 1=up */
#define AHB2AHB_V1_FLAG_MBUS 0x00c /* Master bus number mask */
#define AHB2AHB_V1_FLAG_SBUS 0x003 /* Slave bus number mask */
/* Get Parent bus frequency. Note that since we go from a "child" bus
* to a parent bus, the frequency factor direction is inverted.
*/
unsigned int gaisler_ahb2ahb_v1_freq(ambapp_ahbdev *ahb, unsigned int freq)
{
/* find first device of this */
return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_SLAVE);
int dir;
unsigned char ffact;
/* Get division/multiple factor */
ffact = (ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT) >> 4;
if (ffact != 0) {
dir = ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT_DIR;
/* Calculate frequency by dividing or
* multiplying system frequency
*/
if (dir)
freq = freq * ffact;
else
freq = freq / ffact;
}
return freq;
}
int ambapp_ahbslv_next(unsigned int vendor,
unsigned int driver, ambapp_ahbdev * dev, int index)
/* AHB2AHB and L2CACHE ver 2 is not supported yet. */
unsigned int gaisler_ahb2ahb_v2_freq(ambapp_ahbdev *ahb, unsigned int freq)
{
/* find first device of this */
return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_SLAVE);
panic("gaisler_ahb2ahb_v2_freq: AHB2AHB ver 2 not supported\n");
return -1;
}
#endif
int ambapp_ahbslvs_first(unsigned int vendor,
unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
/* Return the frequency of a AHB bus identified by index found
* note that this is not the AHB Bus number.
*/
unsigned int ambapp_bus_freq(struct ambapp_bus *abus, int ahb_bus_index)
{
/* find first device of this */
return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, AHB_SCAN_SLAVE);
unsigned int freq = abus->freq;
#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS
unsigned int ioarea, ioarea_parent, bridge_pnp_ofs;
struct ambapp_find_ahb_info ahbinfo;
ambapp_ahbdev ahb;
int parent;
debug("ambapp_bus_freq: get freq on bus %d\n", ahb_bus_index);
while (ahb_bus_index != 0) {
debug(" BUS[0]: 0x%08x\n", abus->ioareas[0]);
debug(" BUS[1]: 0x%08x\n", abus->ioareas[1]);
debug(" BUS[2]: 0x%08x\n", abus->ioareas[2]);
debug(" BUS[3]: 0x%08x\n", abus->ioareas[3]);
debug(" BUS[4]: 0x%08x\n", abus->ioareas[4]);
debug(" BUS[5]: 0x%08x\n", abus->ioareas[5]);
/* Get I/O area of AHB bus */
ioarea = abus->ioareas[ahb_bus_index];
debug(" IOAREA: 0x%08x\n", ioarea);
/* Get parent bus */
parent = (ioarea & 0x7);
if (parent == 0) {
panic("%s: parent=0 indicates no parent! Stopping.\n",
__func__);
return -1;
}
parent = parent - 1;
bridge_pnp_ofs = ioarea & 0x7e0;
debug(" PARENT: %d\n", parent);
debug(" BRIDGE_OFS: 0x%08x\n", bridge_pnp_ofs);
/* Get AHB/AHB bridge PnP address */
ioarea_parent = (abus->ioareas[parent] & 0xfff00000) |
AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA;
ahbinfo.pnp = (struct ambapp_pnp_ahb *)
(ioarea_parent | bridge_pnp_ofs);
debug(" IOAREA PARENT: 0x%08x\n", ioarea_parent);
debug(" BRIDGE PNP: 0x%p\n", ahbinfo.pnp);
/* Parse the AHB information */
ahbinfo.ahb_bus_index = parent;
ambapp_ahb_parse(&ahbinfo, &ahb);
debug(" BRIDGE ID: VENDOR=%d(0x%x), DEVICE=%d(0x%x)\n",
ahb.vendor, ahb.vendor, ahb.device, ahb.device);
/* Different bridges may convert frequency differently */
if ((ahb.vendor == VENDOR_GAISLER) &&
((ahb.device == GAISLER_AHB2AHB) ||
(ahb.device == GAISLER_L2CACHE))) {
/* Get new frequency */
if (ahb.ver > 1)
freq = gaisler_ahb2ahb_v2_freq(&ahb, freq);
else
freq = gaisler_ahb2ahb_v1_freq(&ahb, freq);
debug(" NEW FREQ: %dHz\n", freq);
} else {
panic("%s: unsupported AMBA bridge\n", __func__);
return -1;
}
/* Step upwards towards system top bus */
ahb_bus_index = parent;
}
#endif
debug("ambapp_bus_freq: %dHz\n", freq);
return freq;
}
此差异已折叠。
/* 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
/* Initializes CPU and basic hardware such as memory
* controllers, IRQ controller and system timer 0.
*
* (C) Copyright 2007
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
* (C) Copyright 2007, 2015
* Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com
*
* SPDX-License-Identifier: GPL-2.0+
*/
......@@ -11,9 +11,17 @@
#include <asm/asi.h>
#include <asm/leon.h>
#include <ambapp.h>
#include <grlib/irqmp.h>
#include <grlib/gptimer.h>
#include <debug_uart.h>
#include <config.h>
/* Default Plug&Play I/O area */
#ifndef CONFIG_AMBAPP_IOAREA
#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA
#endif
#define TIMER_BASE_CLK 1000000
#define US_PER_TICK (1000000 / CONFIG_SYS_HZ)
......@@ -22,11 +30,7 @@ DECLARE_GLOBAL_DATA_PTR;
/* reset CPU (jump to 0, without reset) */
void start(void);
/* find & initialize the memory controller */
int init_memory_ctrl(void);
ambapp_dev_irqmp *irqmp = NULL;
ambapp_dev_mctrl memctrl;
ambapp_dev_gptimer *gptimer = NULL;
unsigned int gptimer_irq = 0;
int leon3_snooping_avail = 0;
......@@ -39,64 +43,32 @@ struct {
/*
* Breath some life into the CPU...
*
* Set up the memory map,
* initialize a bunch of registers.
*
* Run from FLASH/PROM:
* - until memory controller is set up, only registers available
* - memory controller has already been setup up, stack can be used
* - no global variables available for writing
* - constants available
*/
void cpu_init_f(void)
{
/* these varaiable must not be initialized */
ambapp_dev_irqmp *irqmp;
ambapp_apbdev apbdev;
register unsigned int apbmst;
/* find AMBA APB Master */
apbmst = (unsigned int)
ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
if (!apbmst) {
/*
* no AHB/APB bridge, something is wrong
* ==> jump to start (or hang)
*/
while (1) ;
}
/* Init memory controller */
if (init_memory_ctrl()) {
while (1) ;
}
/****************************************************
* From here we can use the main memory and the stack.
*/
/* Find AMBA APB IRQMP Controller */
if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev) != 1) {
/* no IRQ controller, something is wrong
* ==> jump to start (or hang)
*/
while (1) ;
}
irqmp = (ambapp_dev_irqmp *) apbdev.address;
/* initialize the IRQMP */
irqmp->ilevel = 0xf; /* all IRQ off */
irqmp->iforce = 0;
irqmp->ipend = 0;
irqmp->iclear = 0xfffe; /* clear all old pending interrupts */
irqmp->cpu_mask[0] = 0; /* mask all IRQs on CPU 0 */
irqmp->cpu_force[0] = 0; /* no force IRQ on CPU 0 */
/* cache */
#ifdef CONFIG_DEBUG_UART
debug_uart_init();
#endif
}
/* Routine called from start.S,
*
* Run from FLASH/PROM:
* - memory controller has already been setup up, stack can be used
* - global variables available for read/writing
* - constants avaiable
*/
void cpu_init_f2(void)
{
/* Initialize the AMBA Plug & Play bus structure, the bus
* structure represents the AMBA bus that the CPU is located at.
*/
ambapp_bus_init(CONFIG_AMBAPP_IOAREA, CONFIG_SYS_CLK_FREQ, &ambapp_plb);
}
/*
......@@ -105,95 +77,58 @@ void cpu_init_f2(void)
int cpu_init_r(void)
{
ambapp_apbdev apbdev;
int index, cpu;
ambapp_dev_gptimer *timer = NULL;
unsigned int bus_freq;
/*
* Find AMBA APB IRQMP Controller,
* When we come so far we know there is a IRQMP available
*/
ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev);
irqmp = (ambapp_dev_irqmp *) apbdev.address;
/* timer */
if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_GPTIMER, &apbdev) != 1) {
printf("cpu_init_r: gptimer not found!\n");
return 1;
if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER,
GAISLER_IRQMP, 0, &apbdev) != 1) {
panic("%s: IRQ controller not found\n", __func__);
return -1;
}
gptimer = (ambapp_dev_gptimer *) apbdev.address;
gptimer_irq = apbdev.irq;
/* initialize prescaler common to all timers to 1MHz */
gptimer->scalar = gptimer->scalar_reload =
(((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1;
irqmp = (ambapp_dev_irqmp *)apbdev.address;
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;
/* 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 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;
/* 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;
}
/* 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;
}
/* Different buses may have different frequency, the
* frequency of the bus tell in which frequency the timer
* prescaler operates.
*/
bus_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index);
ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDR2SPA, 1, 0);
if (ahb) {
ddr2spa = (ambapp_dev_ddr2spa *) ambapp_ahb_get_info(ahb, 1);
/* initialize prescaler common to all timers to 1MHz */
timer->scalar = timer->scalar_reload =
(((bus_freq / 1000) + 500) / 1000) - 1;
/* Config DDR2 memory controller */
ddr2spa->cfg1 = CONFIG_SYS_GRLIB_DDR2_CFG1;
ddr2spa->cfg3 = CONFIG_SYS_GRLIB_DDR2_CFG3;
not_found_mctrl = 0;
index++;
}
ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDRSPA, 1, 0);
if (ahb) {
ddrspa = (ambapp_dev_ddrspa *) ambapp_ahb_get_info(ahb, 1);
/* Config DDR memory controller */
ddrspa->ctrl = CONFIG_SYS_GRLIB_DDR_CFG;
not_found_mctrl = 0;
if (!gptimer) {
printf("%s: gptimer not found!\n", __func__);
return 1;
}
/* failed to find any memory controller */
return not_found_mctrl;
return 0;
}
/* Uses Timer 0 to get accurate
......@@ -216,8 +151,8 @@ int timer_interrupt_init_cpu(void)
gptimer->e[0].val = 0;
gptimer->e[0].rld = (TIMER_BASE_CLK / CONFIG_SYS_HZ) - 1;
gptimer->e[0].ctrl =
(LEON3_GPTIMER_EN |
LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
(GPTIMER_CTRL_EN | GPTIMER_CTRL_RS |
GPTIMER_CTRL_LD | GPTIMER_CTRL_IE);
return gptimer_irq;
}
......
......@@ -23,6 +23,8 @@
#include <asm/leon.h>
#include <ambapp.h>
#include <grlib/irqmp.h>
#include <grlib/gptimer.h>
/* 15 normal irqs and a non maskable interrupt */
#define NR_IRQS 15
......@@ -125,9 +127,8 @@ int interrupt_init_cpu(void)
/* Handle Timer 0 IRQ */
void timer_interrupt_cpu(void *arg)
{
gptimer->e[0].ctrl = (LEON3_GPTIMER_EN |
LEON3_GPTIMER_RL |
LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
gptimer->e[0].ctrl = (GPTIMER_CTRL_EN | GPTIMER_CTRL_RS |
GPTIMER_CTRL_LD | GPTIMER_CTRL_IE);
/* nothing to do here */
return;
}
......
/* GRLIB Memory controller setup. The register values are used
* from the associated low level assembler routine implemented
* in memcfg_low.S.
*
* (C) Copyright 2010, 2015
* Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <ambapp.h>
#include "memcfg.h"
#include <config.h>
#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL1
struct mctrl_setup esa_mctrl1_cfg = {
.reg_mask = 0x7,
.regs = {
{
.mask = 0x00000300,
.value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1,
},
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2,
},
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3,
},
}
};
#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL2
struct mctrl_setup esa_mctrl2_cfg = {
.reg_mask = 0x7,
.regs = {
{
.mask = 0x00000300,
.value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG1,
},
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG2,
},
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG3,
},
}
};
#endif
#endif
#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
struct mctrl_setup gaisler_ftmctrl1_cfg = {
.reg_mask = 0x7,
.regs = {
{
.mask = 0x00000300,
.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1,
},
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2,
},
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3,
},
}
};
#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2
struct mctrl_setup gaisler_ftmctrl2_cfg = {
.reg_mask = 0x7,
.regs = {
{
.mask = 0x00000300,
.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG1,
},
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG2,
},
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG3,
},
}
};
#endif
#endif
#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
struct mctrl_setup gaisler_sdctrl1_cfg = {
.reg_mask = 0x1,
.regs = {
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_SDCTRL1_CTRL,
},
}
};
#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL2
struct mctrl_setup gaisler_sdctrl2_cfg = {
.reg_mask = 0x1,
.regs = {
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_SDCTRL2_CTRL,
},
}
};
#endif
#endif
#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
struct ahbmctrl_setup gaisler_ddr2spa1_cfg = {
.ahb_mbar_no = 1,
.reg_mask = 0xd,
.regs = {
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG1,
},
{ 0x00000000, 0},
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG3,
},
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG4,
},
}
};
#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2
struct ahbmctrl_setup gaisler_ddr2spa2_cfg = {
.ahb_mbar_no = 1,
.reg_mask = 0xd,
.regs = {
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG1,
},
{ 0x00000000, 0},
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG3,
},
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG4,
},
}
};
#endif
#endif
#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
struct ahbmctrl_setup gaisler_ddrspa1_cfg = {
.ahb_mbar_no = 1,
.reg_mask = 0x1,
.regs = {
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_DDRSPA1_CTRL,
},
}
};
#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA2
struct ahbmctrl_setup gaisler_ddrspa2_cfg = {
.ahb_mbar_no = 1,
.reg_mask = 0x1,
.regs = {
{
.mask = 0x00000000,
.value = CONFIG_SYS_GRLIB_GAISLER_DDRSPA2_CTRL,
},
}
};
#endif
#endif
struct grlib_mctrl_handler grlib_mctrl_handlers[] = {
/* ESA MCTRL (PROM/FLASH/IO/SRAM/SDRAM) */
#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL1
{DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_ESA, ESA_MCTRL),
_nomem_mctrl_init, (void *)&esa_mctrl1_cfg},
#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL2
{DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_ESA, ESA_MCTRL),
_nomem_mctrl_init, (void *)&esa_mctrl2_cfg},
#endif
#endif
/* GAISLER Fault Tolerant Memory controller (PROM/FLASH/IO/SRAM/SDRAM) */
#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
{DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_FTMCTRL),
_nomem_mctrl_init, (void *)&gaisler_ftmctrl1_cfg},
#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2
{DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_FTMCTRL),
_nomem_mctrl_init, (void *)&gaisler_ftmctrl2_cfg},
#endif
#endif
/* GAISLER SDRAM-only Memory controller (SDRAM) */
#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
{DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_SDCTRL),
_nomem_mctrl_init, (void *)&gaisler_sdctrl1_cfg},
#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL2
{DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_SDCTRL),
_nomem_mctrl_init, (void *)&gaisler_sdctrl2_cfg},
#endif
#endif
/* GAISLER DDR Memory controller (DDR) */
#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
{DEV_AHB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDRSP),
_nomem_ahbmctrl_init, (void *)&gaisler_ddrspa1_cfg},
#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA2
{DEV_AHB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDRSP),
_nomem_ahbmctrl_init, (void *)&gaisler_ddrspa2_cfg},
#endif
#endif
/* GAISLER DDR2 Memory controller (DDR2) */
#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
{DEV_AHB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDR2SP),
_nomem_ahbmctrl_init, (void *)&gaisler_ddr2spa1_cfg},
#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2
{DEV_AHB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_DDR2SP),
_nomem_ahbmctrl_init, (void *)&gaisler_ddr2spa2_cfg},
#endif
#endif
/* Mark end */
MH_END
};
/* 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
/* This is the memory initialization functions, the function
* implemented below initializes each memory controller
* found and specified by the input grlib_mctrl_handler structure.
*
* After the memory controllers have been initialized the stack
* can be used.
*
* (C) Copyright 2010, 2015
* Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <ambapp.h>
#include "memcfg.h"
#include <config.h>
.seg "text"
.globl _nomem_memory_ctrl_init
.globl _nomem_mctrl_init, _nomem_ahbmctrl_init
.extern _nomem_find_apb
.extern _nomem_find_ahb
/* FUNCTION
* _nomem_memory_controller_init(struct grlib_mctrl_handler *mem_handlers)
*
* Initialize AMBA devices, _nomem_amba_init() has prepared i0-i5
* with the AHB buses on the system.
*
* For each entry in mem_handlers find the VENDOR:DEVICE and handle it
* by calling the handler function pointer.
*
* Constraints:
* i6, i7, o6, l7, l6, g3, g4, g5, g6, g7 is used by caller
* o7 is return address
* l5 reserved for this function for future use.
*
* Arguments
* - o0 Pointer to memory handler array
*
* Results
* - o0 Number of memory controllers found
*
* Clobbered
* - o0 (Current AHB slave conf address)
* - l0 (mem handler entry address)
* - l1 (Return value, number of memory controllers found)
* - o7 (function pointer)
* - l0, l1, l2, l3, l4, g1, g2 (used by _nomem_ambapp_find_buses)
* - o0, o1, o2, o3, o4, o5 (Used as arguments)
*
* - g1 ( level 1 return address)
* - g2 ( level 2 return address)
*/
_nomem_memory_ctrl_init:
/* At this point all AHB buses has been found and the I/O Areas of
* all AHB buses is stored in the i0-i5 registers. Max 6 buses. Next,
* memory controllers are found by searching all buses for matching
* VENDOR:DEVICE. The VENDOR:DEVICE to search for are taken from the
* mem_handlers array. For each match the function pointer stored in
* the mem_handler entry is called to handle the hardware setup.
*/
mov %o7, %g1 /* Save return address */
mov %o0, %l0
mov %g0, %l1 /* The return value */
.L_do_one_mem_handler:
ld [%l0 + MH_FUNC], %o7
cmp %o7, %g0
be .L_all_mctrl_handled
nop
/*** Scan for memory controller ***/
/* Set up argments, o5 not used by _nomem_find_apb */
ldub [%l0 + MH_TYPE], %o5
clr %o4
clr %o3
ldub [%l0 + MH_INDEX], %o2
ld [%l0 + MH_VENDOR_DEVICE], %o1
/* An empty config? */
cmp %o5, DEV_NONE
beq .L_all_mctrl_next
/* Select function (APB or AHB) */
cmp %o5, DEV_APB_SLV
bne .L_find_ahb_memctrl
clr %o0
.L_find_apb_memctrl:
call _nomem_find_apb /* Scan for APB slave device */
nop
/* o3 = iobar address
* o4 = AHB Bus index
*
* REG ADR = ((iobar >> 12) & (iobar << 4) & 0xfff00) | "APB Base"
*/
ld [%o3 + AMBA_APB_IOBAR_OFS], %o5
srl %o5, 12, %o2
sll %o5, 4, %o5
and %o2, %o5, %o5
set 0xfff00, %o2
and %o2, %o5, %o5
sethi %hi(0xfff00000), %o2
and %o3, %o2, %o2
or %o5, %o2, %o5 /* Register base address */
ba .L_call_one_mem_handler
nop
.L_find_ahb_memctrl:
call _nomem_find_ahb /* Scan for AHB Slave or Master.
* o5 determine type. */
nop
clr %o5
/* Call the handler function if the hardware was found
*
* o0 = mem_handler
* o1 = Configuration address
* o2 = AHB Bus index
* o3 = APB Base register (if APB Slave)
*
* Constraints:
* i0-i7, l0, l1, l5, g1, g3-g7 may no be used.
*/
.L_call_one_mem_handler:
cmp %o0, %g0
be .L_all_mctrl_next
mov %l0, %o0 /* Mem handler pointer */
mov %o3, %o1 /* AMBA PnP Configuration address */
mov %o4, %o2 /* AHB Bus index */
ld [%l0 + MH_FUNC], %o7 /* Get Function pointer */
call %o7
mov %o5, %o3 /* APB Register Base Address */
inc %l1 /* Number of Memory controllers
* handled. */
/* Do next entry in mem_handlers */
.L_all_mctrl_next:
ba .L_do_one_mem_handler
add %l0, MH_STRUCT_SIZE, %l0
.L_all_mctrl_handled:
mov %g1, %o7 /* Restore return address */
retl
mov %l1, %o0
/* Generic Memory controller initialization routine (APB Registers)
*
* o0 = mem_handler structure pointer
* o1 = Configuration address
* o2 = AHB Bus index
* o3 = APB Base register
*
* Clobbered
* o0-o4
*/
_nomem_mctrl_init:
ld [%o0 + MH_PRIV], %o0 /* Get Private structure */
ld [%o0], %o1 /* Get Reg Mask */
and %o1, 0xff, %o1
add %o0, REGS_OFS, %o0 /* Point to first reg */
.L_do_one_reg:
andcc %o1, 0x1, %g0
beq .L_do_next_reg
ld [%o0], %o2
ld [%o3], %o4
and %o4, %o2, %o4
ld [%o0 + 4], %o2
or %o4, %o2, %o4
st %o4, [%o3]
.L_do_next_reg:
add %o0, REGS_SIZE, %o0
add %o3, 4, %o3
srl %o1, 1, %o1
cmp %o1, 0
bne .L_do_one_reg
nop
/* No more registers to write */
retl
nop
/* Generic Memory controller initialization routine (AHB Registers)
*
* o0 = mem_handler structure pointer
* o1 = Configuration address of memory controller
* o2 = AHB Bus index
*
* Clobbered
* o0-o5
*/
_nomem_ahbmctrl_init:
ld [%o0 + MH_PRIV], %o0 /* Get Private structure */
/* Get index of AHB MBAR to get registers from */
ld [%o0], %o5
add %o0, 4, %o0
/* Get Address of MBAR in PnP info */
add %o5, 4, %o5
sll %o5, 2, %o5
add %o5, %o1, %o5 /* Address of MBAR */
/* Get Address of registers from PnP information
* Address is in AHB I/O format, i.e. relative to bus
*
* ADR = (iobar & (iobar << 16) & 0xfff00000)
* IOADR = (ADR >> 12) | "APB Base"
*/
ld [%o5], %o5
sll %o5, 16, %o4
and %o5, %o4, %o5
sethi %hi(0xfff00000), %o4
and %o5, %o4, %o5 /* ADR */
and %o4, %o1, %o4
srl %o5, 12, %o5
or %o5, %o4, %o3 /* IOADR in o3 */
ld [%o0], %o1 /* Get Reg Mask */
and %o1, 0xff, %o1
add %o0, REGS_OFS, %o0 /* Point to first reg */
.L_do_one_ahbreg:
andcc %o1, 0x1, %g0
beq .L_do_next_reg
ld [%o0], %o2
ld [%o3], %o4
and %o4, %o2, %o4
ld [%o0 + 4], %o2
or %o4, %o2, %o4
st %o4, [%o3]
.L_do_next_ahbreg:
add %o0, REGS_SIZE, %o0
add %o3, 4, %o3
srl %o1, 1, %o1
cmp %o1, 0
bne .L_do_one_reg
nop
/* No more registers to write */
retl
nop
......@@ -15,13 +15,17 @@
#include <asm/irq.h>
#include <asm/leon.h>
#include <ambapp.h>
#include <grlib/apbuart.h>
#include <grlib/irqmp.h>
#include <grlib/gptimer.h>
#include <config.h>
/*
#define PRINT_ROM_VEC
*/
extern struct linux_romvec *kernel_arg_promvec;
extern ambapp_dev_apbuart *leon3_apbuart;
DECLARE_GLOBAL_DATA_PTR;
#define PROM_PGT __attribute__ ((__section__ (".prom.pgt")))
#define PROM_TEXT __attribute__ ((__section__ (".prom.text")))
......@@ -740,14 +744,14 @@ static int PROM_TEXT leon_nbputchar(int c)
/* Wait for last character to go. */
while (!(SPARC_BYPASS_READ(&uart->status)
& LEON_REG_UART_STATUS_THE)) ;
& APBUART_STATUS_THE));
/* Send data */
SPARC_BYPASS_WRITE(&uart->data, c);
/* Wait for data to be sent */
while (!(SPARC_BYPASS_READ(&uart->status)
& LEON_REG_UART_STATUS_TSE)) ;
& APBUART_STATUS_TSE));
return 0;
}
......@@ -909,7 +913,7 @@ void leon_prom_init(struct leon_prom_info *pspi)
pspi->avail.num_bytes = pspi->totphys.num_bytes;
/* Set the pointer to the Console UART in romvec */
pspi->reloc_funcs.leon3_apbuart = leon3_apbuart;
pspi->reloc_funcs.leon3_apbuart = gd->arch.uart;
{
int j = 1;
......
/* GRLIB APBUART Serial controller driver
*
* (C) Copyright 2007
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
* (C) Copyright 2007, 2015
* Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/processor.h>
#include <asm/leon.h>
#include <asm/io.h>
#include <ambapp.h>
#include <grlib/apbuart.h>
#include <serial.h>
#include <linux/compiler.h>
#include <watchdog.h>
DECLARE_GLOBAL_DATA_PTR;
ambapp_dev_apbuart *leon3_apbuart = NULL;
/* Select which UART that will become u-boot console */
#ifndef CONFIG_SYS_GRLIB_APBUART_INDEX
#define CONFIG_SYS_GRLIB_APBUART_INDEX 0
#endif
static int leon3_serial_init(void)
{
ambapp_dev_apbuart *uart;
ambapp_apbdev apbdev;
unsigned int tmp;
/* find UART */
if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) == 1) {
if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_APBUART,
CONFIG_SYS_GRLIB_APBUART_INDEX, &apbdev) != 1) {
panic("%s: apbuart not found!\n", __func__);
return -1; /* didn't find hardware */
}
leon3_apbuart = (ambapp_dev_apbuart *) apbdev.address;
/* found apbuart, let's init .. */
uart = (ambapp_dev_apbuart *) apbdev.address;
/* found apbuart, let's init...
*
* Set scaler / baud rate
*
* Receiver & transmitter enable
*/
leon3_apbuart->scaler = CONFIG_SYS_GRLIB_APBUART_SCALER;
/* Set scaler / baud rate */
tmp = (((CONFIG_SYS_CLK_FREQ*10) / (CONFIG_BAUDRATE*8)) - 5)/10;
writel(tmp, &uart->scaler);
/* Let bit 11 be unchanged (debug bit for GRMON) */
tmp = READ_WORD(leon3_apbuart->ctrl);
leon3_apbuart->ctrl = ((tmp & LEON_REG_UART_CTRL_DBG) |
LEON_REG_UART_CTRL_RE |
LEON_REG_UART_CTRL_TE);
tmp = readl(&uart->ctrl) & APBUART_CTRL_DBG;
/* Receiver & transmitter enable */
tmp |= APBUART_CTRL_RE | APBUART_CTRL_TE;
writel(tmp, &uart->ctrl);
gd->arch.uart = uart;
return 0;
}
return -1; /* didn't find hardware */
}
static inline ambapp_dev_apbuart *leon3_get_uart_regs(void)
{
ambapp_dev_apbuart *uart = gd->arch.uart;
return uart;
}
static void leon3_serial_putc_raw(const char c)
{
if (!leon3_apbuart)
ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
if (!uart)
return;
/* Wait for last character to go. */
while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_THE)) ;
while (!(readl(&uart->status) & APBUART_STATUS_THE))
WATCHDOG_RESET();
/* Send data */
leon3_apbuart->data = c;
writel(c, &uart->data);
#ifdef LEON_DEBUG
/* Wait for data to be sent */
while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_TSE)) ;
while (!(readl(&uart->status) & APBUART_STATUS_TSE))
WATCHDOG_RESET();
#endif
}
......@@ -74,36 +87,44 @@ static void leon3_serial_putc(const char c)
static int leon3_serial_getc(void)
{
if (!leon3_apbuart)
ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
if (!uart)
return 0;
/* Wait for a character to arrive. */
while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_DR)) ;
while (!(readl(&uart->status) & APBUART_STATUS_DR))
WATCHDOG_RESET();
/* read data */
return READ_WORD(leon3_apbuart->data);
/* Read character data */
return readl(&uart->data);
}
static int leon3_serial_tstc(void)
{
if (leon3_apbuart)
return (READ_WORD(leon3_apbuart->status) &
LEON_REG_UART_STATUS_DR);
ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
if (!uart)
return 0;
return readl(&uart->status) & APBUART_STATUS_DR;
}
/* set baud rate for uart */
static void leon3_serial_setbrg(void)
{
/* update baud rate settings, read it from gd->baudrate */
ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
unsigned int scaler;
if (leon3_apbuart && (gd->baudrate > 0)) {
scaler =
(((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) -
5) / 10;
leon3_apbuart->scaler = scaler;
}
if (!uart)
return;
if (!gd->baudrate)
gd->baudrate = CONFIG_BAUDRATE;
scaler = (((CONFIG_SYS_CLK_FREQ*10) / (gd->baudrate*8)) - 5)/10;
writel(scaler, &uart->scaler);
}
static struct serial_device leon3_serial_drv = {
......@@ -126,3 +147,26 @@ __weak struct serial_device *default_serial_console(void)
{
return &leon3_serial_drv;
}
#ifdef CONFIG_DEBUG_UART_APBUART
#include <debug_uart.h>
static inline void _debug_uart_init(void)
{
ambapp_dev_apbuart *uart = (ambapp_dev_apbuart *)CONFIG_DEBUG_UART_BASE;
uart->scaler = (((CONFIG_DEBUG_UART_CLOCK*10) / (CONFIG_BAUDRATE*8)) - 5)/10;
uart->ctrl = APBUART_CTRL_RE | APBUART_CTRL_TE;
}
static inline void _debug_uart_putc(int ch)
{
ambapp_dev_apbuart *uart = (ambapp_dev_apbuart *)CONFIG_DEBUG_UART_BASE;
while (!(readl(&uart->status) & APBUART_STATUS_THE))
WATCHDOG_RESET();
writel(ch, &uart->data);
}
DEBUG_UART_FUNCS
#endif
......@@ -2,9 +2,6 @@
* Copyright (C) 2007,
* Daniel Hellstrom, daniel@gaisler.com
*
* See file CREDITS for list of people who contributed to this
* project.
*
* SPDX-License-Identifier: GPL-2.0+
*/
......@@ -16,6 +13,12 @@
#include <asm/stack.h>
#include <asm/leon.h>
#include <version.h>
#include <ambapp.h>
/* Default Plug&Play I/O area */
#ifndef CONFIG_AMBAPP_IOAREA
#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA
#endif
/* Entry for traps which jump to a programmer-specified trap handler. */
#define TRAPR(H) \
......@@ -60,6 +63,27 @@ MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4)
#error Must define number of SPARC register windows, default is 8
#endif
/* Macros to load address into a register. Uses GOT table for PIC */
#ifdef __PIC__
#define SPARC_PIC_THUNK_CALL(reg) \
sethi %pc22(_GLOBAL_OFFSET_TABLE_-4), %##reg; \
call __sparc_get_pc_thunk.reg; \
add %##reg, %pc10(_GLOBAL_OFFSET_TABLE_+4), %##reg;
#define SPARC_LOAD_ADDRESS(sym, got, reg) \
sethi %gdop_hix22(sym), %##reg; \
xor %##reg, %gdop_lox10(sym), %##reg; \
ld [%##got + %##reg], %##reg, %gdop(sym);
#else
#define SPARC_PIC_THUNK_CALL(reg)
#define SPARC_LOAD_ADDRESS(sym, got, tmp) \
set sym, %##reg;
#endif
#define STACK_ALIGN 8
#define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
......@@ -190,6 +214,7 @@ version_string:
.ascii U_BOOT_VERSION_STRING, "\0"
.section ".text"
.extern _nomem_amba_init, _nomem_memory_ctrl_init
.align 4
_hardreset:
......@@ -232,7 +257,7 @@ clear_window:
bge clear_window
save
wininit:
wiminit:
set WIM_INIT, %g3
mov %g3, %wim
......@@ -241,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
......@@ -252,8 +309,8 @@ cpu_init_unreloc:
#define DATA_END __init_end
reloc:
set TEXT_START,%g2
set DATA_END,%g3
SPARC_LOAD_ADDRESS(TEXT_START, l7, g2)
SPARC_LOAD_ADDRESS(DATA_END, l7, g3)
set CONFIG_SYS_RELOC_MONITOR_BASE,%g4
reloc_loop:
ldd [%g2],%l0
......@@ -280,8 +337,8 @@ reloc_loop:
clr_bss:
/* clear bss area (the relocated) */
set __bss_start,%g2
set __bss_end,%g3
SPARC_LOAD_ADDRESS(__bss_start, l7, g2)
SPARC_LOAD_ADDRESS(__bss_end, l7, g3)
sub %g3,%g2,%g3
add %g3,%g4,%g3
clr %g1 /* std %g0 uses g0 and g1 */
......@@ -296,15 +353,15 @@ clr_bss_16:
/* 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
......@@ -322,8 +379,8 @@ got_loop:
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:
......@@ -361,15 +418,16 @@ 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
set board_init_f,%o1
SPARC_LOAD_ADDRESS(board_init_f, l7, o1)
set CONFIG_SYS_RELOC_MONITOR_BASE,%o2
SPARC_LOAD_ADDRESS(TEXT_START, l7, g1)
add %o1,%o2,%o1
sub %o1,%g1,%o1
call %o1
......
......@@ -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;
}
......
......@@ -15,6 +15,7 @@
/* Architecture-specific global data */
struct arch_global_data {
void *uart;
};
#include <asm-generic/global_data.h>
......
/* 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
......
......@@ -136,130 +136,3 @@
ld [reg + FW_FSR], %fsr;
#endif
#ifndef __SPARC_WINMACRO_H__
#define __SPARC_WINMACRO_H__
#include <asm/asmmacro.h>
#include <asm/stack.h>
/* Store the register window onto the 8-byte aligned area starting
* at %reg. It might be %sp, it might not, we don't care.
*/
#define RW_STORE(reg) \
std %l0, [%reg + RW_L0]; \
std %l2, [%reg + RW_L2]; \
std %l4, [%reg + RW_L4]; \
std %l6, [%reg + RW_L6]; \
std %i0, [%reg + RW_I0]; \
std %i2, [%reg + RW_I2]; \
std %i4, [%reg + RW_I4]; \
std %i6, [%reg + RW_I6];
/* Load a register window from the area beginning at %reg. */
#define RW_LOAD(reg) \
ldd [%reg + RW_L0], %l0; \
ldd [%reg + RW_L2], %l2; \
ldd [%reg + RW_L4], %l4; \
ldd [%reg + RW_L6], %l6; \
ldd [%reg + RW_I0], %i0; \
ldd [%reg + RW_I2], %i2; \
ldd [%reg + RW_I4], %i4; \
ldd [%reg + RW_I6], %i6;
/* Loading and storing struct pt_reg trap frames. */
#define PT_LOAD_INS(base_reg) \
ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \
ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \
ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \
ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6;
#define PT_LOAD_GLOBALS(base_reg) \
ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \
ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \
ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \
ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6;
#define PT_LOAD_YREG(base_reg, scratch) \
ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \
wr %scratch, 0x0, %y;
#define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \
ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \
ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc;
#define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
PT_LOAD_YREG(base_reg, scratch) \
PT_LOAD_INS(base_reg) \
PT_LOAD_GLOBALS(base_reg) \
PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
#define PT_STORE_INS(base_reg) \
std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \
std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \
std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \
std %i6, [%base_reg + SF_REGS_SZ + PT_I6];
#define PT_STORE_GLOBALS(base_reg) \
st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \
std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \
std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \
std %g6, [%base_reg + SF_REGS_SZ + PT_G6];
#define PT_STORE_YREG(base_reg, scratch) \
rd %y, %scratch; \
st %scratch, [%base_reg + SF_REGS_SZ + PT_Y];
#define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \
st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \
st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC];
#define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
PT_STORE_GLOBALS(base_reg) \
PT_STORE_YREG(base_reg, g_scratch) \
PT_STORE_INS(base_reg)
/* Store the fpu register window*/
#define FW_STORE(reg) \
std %f0, [reg + FW_F0]; \
std %f2, [reg + FW_F2]; \
std %f4, [reg + FW_F4]; \
std %f6, [reg + FW_F6]; \
std %f8, [reg + FW_F8]; \
std %f10, [reg + FW_F10]; \
std %f12, [reg + FW_F12]; \
std %f14, [reg + FW_F14]; \
std %f16, [reg + FW_F16]; \
std %f18, [reg + FW_F18]; \
std %f20, [reg + FW_F20]; \
std %f22, [reg + FW_F22]; \
std %f24, [reg + FW_F24]; \
std %f26, [reg + FW_F26]; \
std %f28, [reg + FW_F28]; \
std %f30, [reg + FW_F30]; \
st %fsr, [reg + FW_FSR];
/* Load a fpu register window from the area beginning at reg. */
#define FW_LOAD(reg) \
ldd [reg + FW_F0], %f0; \
ldd [reg + FW_F2], %f2; \
ldd [reg + FW_F4], %f4; \
ldd [reg + FW_F6], %f6; \
ldd [reg + FW_F8], %f8; \
ldd [reg + FW_F10], %f10; \
ldd [reg + FW_F12], %f12; \
ldd [reg + FW_F14], %f14; \
ldd [reg + FW_F16], %f16; \
ldd [reg + FW_F18], %f18; \
ldd [reg + FW_F20], %f20; \
ldd [reg + FW_F22], %f22; \
ldd [reg + FW_F24], %f24; \
ldd [reg + FW_F26], %f26; \
ldd [reg + FW_F28], %f28; \
ldd [reg + FW_F30], %f30; \
ld [reg + FW_FSR], %fsr;
#endif
......@@ -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
......
......@@ -46,6 +46,9 @@
#include <stdio_dev.h>
#include <trace.h>
#include <watchdog.h>
#ifdef CONFIG_CMD_AMBAPP
#include <ambapp.h>
#endif
#ifdef CONFIG_ADDR_MAP
#include <asm/mmu.h>
#endif
......@@ -559,6 +562,18 @@ static int initr_status_led(void)
}
#endif
#if defined(CONFIG_CMD_AMBAPP) && defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP)
extern int do_ambapp_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
static int initr_ambapp_print(void)
{
puts("AMBA:\n");
do_ambapp_print(NULL, 0, 0, NULL);
return 0;
}
#endif
#if defined(CONFIG_CMD_SCSI)
static int initr_scsi(void)
{
......@@ -850,6 +865,12 @@ init_fnc_t init_sequence_r[] = {
#ifdef CONFIG_BOARD_LATE_INIT
board_late_init,
#endif
#if defined(CONFIG_CMD_AMBAPP)
ambapp_init_reloc,
#if defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP)
initr_ambapp_print,
#endif
#endif
#ifdef CONFIG_CMD_SCSI
INIT_FUNC_WATCHDOG_RESET
initr_scsi,
......
此差异已折叠。
......@@ -11,4 +11,10 @@ CONFIG_SYS_TEXT_BASE=0x00000000
# CONFIG_CMD_MEMORY is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_SETEXPR is not set
# CONFIG_CMD_NET is not set
# CONFIG_CMD_NFS is not set
CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP=y
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_APBUART=y
CONFIG_DEBUG_UART_BASE=0x80000100
CONFIG_DEBUG_UART_CLOCK=40000000
......@@ -106,7 +106,7 @@ alias ppc4xx uboot, stroese
alias sandbox sjg
alias sb sandbox
alias sparc uboot, Daniel Hellstrom <daniel@gaisler.com>
alias sparc uboot, Francois Retief <fgretief@spaceteq.co.za>
alias superh uboot, iwamatsu
alias sh superh
......
......@@ -20,7 +20,7 @@
#include <ambapp.h>
#include <asm/leon.h>
#include "greth.h"
#include <grlib/greth.h>
/* Default to 3s timeout on autonegotiation */
#ifndef GRETH_PHY_TIMEOUT_MS
......@@ -34,6 +34,13 @@
#define GRETH_PHY_ADR_DEFAULT 0
#endif
/* Let board select which GRETH to use as network interface, set
* this to zero if only one GRETH is available.
*/
#ifndef CONFIG_SYS_GRLIB_GRETH_INDEX
#define CONFIG_SYS_GRLIB_GRETH_INDEX 0
#endif
/* ByPass Cache when reading regs */
#define GRETH_REGLOAD(addr) SPARC_NOCACHE_READ(addr)
/* Write-through cache ==> no bypassing needed on writes */
......@@ -593,8 +600,12 @@ int greth_initialize(bd_t * bis)
debug("Scanning for GRETH\n");
/* Find Device & IRQ via AMBA Plug&Play information */
if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_ETHMAC, &apbdev) != 1) {
/* Find Device & IRQ via AMBA Plug&Play information,
* CONFIG_SYS_GRLIB_GRETH_INDEX select which GRETH if multiple
* GRETHs in system.
*/
if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_ETHMAC,
CONFIG_SYS_GRLIB_GRETH_INDEX, &apbdev) != 1) {
return -1; /* GRETH not found */
}
......
......@@ -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
......
......@@ -3,8 +3,8 @@
* the APB bus, also freely available in GRLIB at
* www.gaisler.com.
*
* (C) Copyright 2007
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
* (C) Copyright 2009, 2015
* Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
*
* SPDX-License-Identifier: GPL-2.0+
*/
......@@ -12,366 +12,214 @@
#ifndef __AMBAPP_H__
#define __AMBAPP_H__
/* Default location of Plug&Play info
* normally 0xfffff000 for AHB masters
* and 0xfffff800 for AHB slaves.
* Normally no need to change this.
*/
#define LEON3_IO_AREA 0xfff00000
#define LEON3_CONF_AREA 0xff000
#define LEON3_AHB_SLAVE_CONF_AREA (1 << 11)
/* Max devices this software will support */
#define LEON3_AHB_MASTERS 16
#define LEON3_AHB_SLAVES 16
/*#define LEON3_APB_MASTERS 1*/ /* Number of APB buses that has Plug&Play */
#define LEON3_APB_SLAVES 16 /* Total number of APB slaves per APB bus */
/* Vendor codes */
#define VENDOR_GAISLER 1
#define VENDOR_PENDER 2
#define VENDOR_ESA 4
#define VENDOR_ASTRIUM 6
#define VENDOR_OPENCHIP 7
#define VENDOR_OPENCORES 8
#define VENDOR_CONTRIB 9
#define VENDOR_EONIC 11
#define VENDOR_RADIONOR 15
#define VENDOR_GLEICHMANN 16
#define VENDOR_MENTA 17
#define VENDOR_SUN 19
#define VENDOR_EMBEDDIT 234
#define VENDOR_CAL 202
/* Gaisler Research device id's */
#define GAISLER_LEON3 0x003
#define GAISLER_LEON3DSU 0x004
#define GAISLER_ETHAHB 0x005
#define GAISLER_APBMST 0x006
#define GAISLER_AHBUART 0x007
#define GAISLER_SRCTRL 0x008
#define GAISLER_SDCTRL 0x009
#define GAISLER_APBUART 0x00C
#define GAISLER_IRQMP 0x00D
#define GAISLER_AHBRAM 0x00E
#define GAISLER_GPTIMER 0x011
#define GAISLER_PCITRG 0x012
#define GAISLER_PCISBRG 0x013
#define GAISLER_PCIFBRG 0x014
#define GAISLER_PCITRACE 0x015
#define GAISLER_PCIDMA 0x016
#define GAISLER_AHBTRACE 0x017
#define GAISLER_ETHDSU 0x018
#define GAISLER_PIOPORT 0x01A
#define GAISLER_AHBJTAG 0x01c
#define GAISLER_SPW 0x01f
#define GAISLER_ATACTRL 0x024
#define GAISLER_VGA 0x061
#define GAISLER_KBD 0X060
#define GAISLER_ETHMAC 0x01D
#define GAISLER_DDRSPA 0x025
#define GAISLER_EHCI 0x026
#define GAISLER_UHCI 0x027
#define GAISLER_SPW2 0x029
#define GAISLER_DDR2SPA 0x02E
#define GAISLER_AHBSTAT 0x052
#define GAISLER_FTMCTRL 0x054
#define GAISLER_L2TIME 0xffd /* internal device: leon2 timer */
#define GAISLER_L2C 0xffe /* internal device: leon2compat */
#define GAISLER_PLUGPLAY 0xfff /* internal device: plug & play configarea */
/* European Space Agency device id's */
#define ESA_LEON2 0x2
#define ESA_MCTRL 0xF
/* Opencores device id's */
#define OPENCORES_PCIBR 0x4
#define OPENCORES_ETHMAC 0x5
/* Vendor codes */
/*
*
* Macros for manipulating Configuration registers
*
*/
#define amba_vendor(x) (((x) >> 24) & 0xff)
#define amba_device(x) (((x) >> 12) & 0xfff)
#define amba_membar_start(mbar) \
(((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
#define amba_iobar_start(base, iobar) \
((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) )
#define amba_irq(conf) ((conf) & 0xf)
#define amba_ver(conf) (((conf)>>5) & 0x1f)
#define amba_membar_type(mbar) ((mbar) & 0xf)
#define amba_membar_mask(mbar) (((mbar)>>4) & 0xfff)
#define AMBA_TYPE_APBIO 0x1
#define AMBA_TYPE_MEM 0x2
#define AMBA_TYPE_AHBIO 0x3
#define AMBA_TYPE_AHBIO_ADDR(addr) (LEON3_IO_AREA | ((addr) >> 12))
#include <ambapp_ids.h>
#ifndef __ASSEMBLER__
/* Structures used to access Plug&Play information directly */
struct ambapp_pnp_ahb {
const unsigned int id; /* VENDOR, DEVICE, VER, IRQ, */
const unsigned int custom[3];
const unsigned int mbar[4]; /* MASK, ADDRESS, TYPE,
* CACHABLE/PREFETCHABLE */
};
struct ambapp_pnp_apb {
const unsigned int id; /* VENDOR, DEVICE, VER, IRQ, */
const unsigned int iobar; /* MASK, ADDRESS, TYPE,
* CACHABLE/PREFETCHABLE */
};
#ifdef CONFIG_CMD_AMBAPP
/* AMBA Plug&Play relocation & initialization */
int ambapp_init_reloc(void);
/* AMBA Plug&Play Name of Vendors and devices */
/* Return name of device */
char *ambapp_device_id2str(int vendor, int id);
/* Return name of vendor */
char *ambapp_vendor_id2str(int vendor);
#endif
/*
* Types and structure used for AMBA Plug & Play bus scanning
*/
/* AMBA Plug&Play AHB information layout */
typedef struct {
unsigned int conf;
unsigned int userdef[3];
unsigned int bars[4];
} ahbctrl_pp_dev;
/* Prototypes for scanning AMBA Plug&Play bus for AMBA
* i) AHB Masters
* ii) AHB Slaves
* iii) APB Slaves (APB MST is a AHB Slave)
/* AMBA Plug&Play AHB Masters & Slaves information locations
* Max devices is 64 supported by HW, however often only 16
* are used.
*/
typedef struct {
struct ambapp_pnp_info {
struct ambapp_pnp_ahb masters[64];
struct ambapp_pnp_ahb slaves[63];
const unsigned int unused[4];
const unsigned int systemid[4];
};
/* Describes a AMBA PnP bus */
struct ambapp_bus {
int buses; /* Number of buses */
unsigned int ioareas[6]; /* PnP I/O AREAs of AHB buses */
unsigned int freq; /* Frequency of bus0 [Hz] */
};
/* Processor Local AMBA bus */
extern struct ambapp_bus ambapp_plb;
/* Get Bus frequency of a certain AMBA bus */
extern unsigned int ambapp_bus_freq(
struct ambapp_bus *abus,
int ahb_bus_index
);
/* AMBA PnP information of a APB Device */
typedef struct {
unsigned int vendor;
unsigned int device;
unsigned char irq;
unsigned char ver;
unsigned int address;
unsigned int mask;
int ahb_bus_index;
} ambapp_apbdev;
/* AMBA PnP information of a AHB Device */
typedef struct {
unsigned int vendor;
unsigned int device;
unsigned char irq;
unsigned char ver;
unsigned int userdef[3];
unsigned int address[4];
unsigned int mask[4];
int type[4];
int ahb_bus_index;
} ambapp_ahbdev;
/* AMBA Plug&Play AHB Masters & Slaves information locations
* Max devices is 64 supported by HW, however often only 8
* are used.
*/
typedef struct {
ahbctrl_pp_dev masters[64];
ahbctrl_pp_dev slaves[64];
} ahbctrl_info;
/* Scan AMBA Bus for AHB Bridges */
extern void ambapp_bus_init(
unsigned int ioarea,
unsigned int freq,
struct ambapp_bus *abus);
/* AMBA Plug&Play AHB information layout */
typedef struct {
unsigned int conf;
unsigned int bar;
} apbctrl_pp_dev;
/* All functions return the number of found devices
* 0 = no devices found
/* Find APB Slave device by index using breath first search.
*
* When vendor and device are both set to zero, any device
* with a non-zero device ID will match the search. It may be
* useful when processing all devices on a AMBA bus.
*/
extern int ambapp_apb_find(
struct ambapp_bus *abus,
int vendor,
int device,
int index,
ambapp_apbdev *dev
);
/* Find AHB Master device by index using breath first search.
*
* When vendor and device are both set to zero, any device
* with a non-zero device ID will match the search. It may be
* useful when processing all devices on a AMBA bus.
*/
extern int ambapp_ahbmst_find(
struct ambapp_bus *abus,
int vendor,
int device,
int index,
ambapp_ahbdev *dev
);
/* Find AHB Slave device by index using breath first search.
*
* When vendor and device are both set to zero, any device
* with a non-zero device ID will match the search. It may be
* useful when processing all devices on a AMBA bus.
*/
extern int ambapp_ahbslv_find(
struct ambapp_bus *abus,
int vendor,
int device,
int index,
ambapp_ahbdev *dev
);
/* Return number of APB Slave devices of a certain ID (VENDOR:DEVICE)
* zero is returned if no devices was found.
*/
extern int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device);
/****************************** APB SLAVES ******************************/
int ambapp_apb_count(unsigned int vendor, unsigned int driver);
int ambapp_apb_first(unsigned int vendor,
unsigned int driver, ambapp_apbdev * dev);
int ambapp_apb_next(unsigned int vendor,
unsigned int driver, ambapp_apbdev * dev, int index);
int ambapp_apbs_first(unsigned int vendor,
unsigned int driver, ambapp_apbdev * dev, int max_cnt);
/****************************** AHB MASTERS ******************************/
int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver);
int ambapp_ahbmst_first(unsigned int vendor,
unsigned int driver, ambapp_ahbdev * dev);
int ambapp_ahbmst_next(unsigned int vendor,
unsigned int driver, ambapp_ahbdev * dev, int index);
/* Return number of AHB Master devices of a certain ID (VENDOR:DEVICE)
* zero is returned if no devices was found.
*/
extern int ambapp_ahbmst_count(struct ambapp_bus *abus, int vendor, int device);
int ambapp_ahbmsts_first(unsigned int vendor,
unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
/* Return number of AHB Slave devices of a certain ID (VENDOR:DEVICE)
* zero is returned if no devices was found.
*/
extern int ambapp_ahbslv_count(struct ambapp_bus *abus, int vendor, int device);
/****************************** AHB SLAVES ******************************/
int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver);
#ifdef CONFIG_CMD_AMBAPP
int ambapp_ahbslv_first(unsigned int vendor,
unsigned int driver, ambapp_ahbdev * dev);
/* AMBA Plug&Play relocation & initialization */
int ambapp_init_reloc(void);
int ambapp_ahbslv_next(unsigned int vendor,
unsigned int driver, ambapp_ahbdev * dev, int index);
/* AMBA Plug&Play Name of Vendors and devices */
int ambapp_ahbslvs_first(unsigned int vendor,
unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
/* Return name of device */
char *ambapp_device_id2str(int vendor, int id);
/*************************** AHB/APB only regs functions *************************
* During start up, no memory is available we can use the simplified functions
* to get to the memory controller.
*
* Functions uses no stack/memory, only registers.
*/
unsigned int ambapp_apb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */
register unsigned int driver, /* Plug&Play Device ID */
register int index);
/* Return name of vendor */
char *ambapp_vendor_id2str(int vendor);
ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */
register unsigned int driver, /* Plug&Play Device ID */
register unsigned int opts, /* scan for AHB 1=slave, 0=masters */
register int index);
/* Return description of a device */
char *ambapp_device_id2desc(int vendor, int id);
unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info);
#endif
/*************************** AMBA Plug&Play device register MAPS *****************/
#endif /* defined(__ASSEMBLER__) */
/*
* The following defines the bits in the LEON UART Status Registers.
*/
#define AMBA_DEFAULT_IOAREA 0xfff00000
#define AMBA_CONF_AREA 0xff000
#define AMBA_AHB_SLAVE_CONF_AREA 0x800
#define LEON_REG_UART_STATUS_DR 0x00000001 /* Data Ready */
#define LEON_REG_UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */
#define LEON_REG_UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */
#define LEON_REG_UART_STATUS_BR 0x00000008 /* Break Error */
#define LEON_REG_UART_STATUS_OE 0x00000010 /* RX Overrun Error */
#define LEON_REG_UART_STATUS_PE 0x00000020 /* RX Parity Error */
#define LEON_REG_UART_STATUS_FE 0x00000040 /* RX Framing Error */
#define LEON_REG_UART_STATUS_ERR 0x00000078 /* Error Mask */
/*
* The following defines the bits in the LEON UART Ctrl Registers.
*/
#define DEV_NONE 0
#define DEV_AHB_MST 1
#define DEV_AHB_SLV 2
#define DEV_APB_SLV 3
#define LEON_REG_UART_CTRL_RE 0x00000001 /* Receiver enable */
#define LEON_REG_UART_CTRL_TE 0x00000002 /* Transmitter enable */
#define LEON_REG_UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */
#define LEON_REG_UART_CTRL_TI 0x00000008 /* Transmitter interrupt enable */
#define LEON_REG_UART_CTRL_PS 0x00000010 /* Parity select */
#define LEON_REG_UART_CTRL_PE 0x00000020 /* Parity enable */
#define LEON_REG_UART_CTRL_FL 0x00000040 /* Flow control enable */
#define LEON_REG_UART_CTRL_LB 0x00000080 /* Loop Back enable */
#define LEON_REG_UART_CTRL_DBG (1<<11) /* Debug Bit used by GRMON */
#define LEON3_GPTIMER_EN 1
#define LEON3_GPTIMER_RL 2
#define LEON3_GPTIMER_LD 4
#define LEON3_GPTIMER_IRQEN 8
/*
* The following defines the bits in the LEON PS/2 Status Registers.
*/
#define LEON_REG_PS2_STATUS_DR 0x00000001 /* Data Ready */
#define LEON_REG_PS2_STATUS_PE 0x00000002 /* Parity error */
#define LEON_REG_PS2_STATUS_FE 0x00000004 /* Framing error */
#define LEON_REG_PS2_STATUS_KI 0x00000008 /* Keyboard inhibit */
#define AMBA_TYPE_APBIO 0x1
#define AMBA_TYPE_MEM 0x2
#define AMBA_TYPE_AHBIO 0x3
/*
* The following defines the bits in the LEON PS/2 Ctrl Registers.
/* ID layout for APB and AHB devices */
#define AMBA_PNP_ID(vendor, device) (((vendor)<<24) | ((device)<<12))
/* APB Slave PnP layout definitions */
#define AMBA_APB_ID_OFS (0*4)
#define AMBA_APB_IOBAR_OFS (1*4)
#define AMBA_APB_CONF_LENGH (2*4)
/* AHB Master/Slave layout PnP definitions */
#define AMBA_AHB_ID_OFS (0*4)
#define AMBA_AHB_CUSTOM0_OFS (1*4)
#define AMBA_AHB_CUSTOM1_OFS (2*4)
#define AMBA_AHB_CUSTOM2_OFS (3*4)
#define AMBA_AHB_MBAR0_OFS (4*4)
#define AMBA_AHB_MBAR1_OFS (5*4)
#define AMBA_AHB_MBAR2_OFS (6*4)
#define AMBA_AHB_MBAR3_OFS (7*4)
#define AMBA_AHB_CONF_LENGH (8*4)
/* Macros for extracting information from AMBA PnP information
* registers.
*/
#define LEON_REG_PS2_CTRL_RE 0x00000001 /* Receiver enable */
#define LEON_REG_PS2_CTRL_TE 0x00000002 /* Transmitter enable */
#define LEON_REG_PS2_CTRL_RI 0x00000004 /* Keyboard receive interrupt */
#define LEON_REG_PS2_CTRL_TI 0x00000008 /* Keyboard transmit interrupt */
typedef struct {
volatile unsigned int ilevel;
volatile unsigned int ipend;
volatile unsigned int iforce;
volatile unsigned int iclear;
volatile unsigned int mstatus;
volatile unsigned int notused[11];
volatile unsigned int cpu_mask[16];
volatile unsigned int cpu_force[16];
} ambapp_dev_irqmp;
typedef struct {
volatile unsigned int data;
volatile unsigned int status;
volatile unsigned int ctrl;
volatile unsigned int scaler;
} ambapp_dev_apbuart;
typedef struct {
volatile unsigned int val;
volatile unsigned int rld;
volatile unsigned int ctrl;
volatile unsigned int unused;
} ambapp_dev_gptimer_element;
#define LEON3_GPTIMER_CTRL_EN 0x1 /* Timer enable */
#define LEON3_GPTIMER_CTRL_RS 0x2 /* Timer reStart */
#define LEON3_GPTIMER_CTRL_LD 0x4 /* Timer reLoad */
#define LEON3_GPTIMER_CTRL_IE 0x8 /* interrupt enable */
#define LEON3_GPTIMER_CTRL_IP 0x10 /* interrupt flag/pending */
#define LEON3_GPTIMER_CTRL_CH 0x20 /* Chain with previous timer */
#define amba_vendor(x) (((x) >> 24) & 0xff)
typedef struct {
volatile unsigned int scalar;
volatile unsigned int scalar_reload;
volatile unsigned int config;
volatile unsigned int unused;
volatile ambapp_dev_gptimer_element e[8];
} ambapp_dev_gptimer;
#define amba_device(x) (((x) >> 12) & 0xfff)
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;
#define amba_irq(conf) ((conf) & 0x1f)
typedef struct {
volatile unsigned int write;
volatile unsigned int dummy;
volatile unsigned int txcolor;
volatile unsigned int bgcolor;
} ambapp_dev_textvga;
#define amba_ver(conf) (((conf)>>5) & 0x1f)
typedef struct {
volatile unsigned int data;
volatile unsigned int status;
volatile unsigned int ctrl;
} ambapp_dev_apbps2;
#define amba_iobar_start(base, iobar) \
((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)))
typedef struct {
unsigned int mcfg1, mcfg2, mcfg3;
} ambapp_dev_mctrl;
#define amba_membar_start(mbar) \
(((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
typedef struct {
unsigned int sdcfg;
} ambapp_dev_sdctrl;
#define amba_membar_type(mbar) ((mbar) & 0xf)
typedef struct {
unsigned int cfg1;
unsigned int cfg2;
unsigned int cfg3;
} ambapp_dev_ddr2spa;
#define amba_membar_mask(mbar) (((mbar) >> 4) & 0xfff)
typedef struct {
unsigned int ctrl;
unsigned int cfg;
} ambapp_dev_ddrspa;
#define amba_ahbio_adr(addr, base_ioarea) \
((unsigned int)(base_ioarea) | ((addr) >> 12))
#endif
#define amba_apb_mask(iobar) ((~(amba_membar_mask(iobar)<<8) & 0x000fffff) + 1)
#endif
/* AMBA Plug & Play Bus Vendor and Device IDs.
*
* (C) Copyright 2010, 2015
* Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __AMBAPP_IDS_H__
#define __AMBAPP_IDS_H__
/* Vendor ID defines */
#define VENDOR_GAISLER 0x01
#define VENDOR_PENDER 0x02
#define VENDOR_ESA 0x04
#define VENDOR_ASTRIUM 0x06
#define VENDOR_OPENCHIP 0x07
#define VENDOR_OPENCORES 0x08
#define VENDOR_CONTRIB 0x09
#define VENDOR_EONIC 0x0b
#define VENDOR_RADIONOR 0x0f
#define VENDOR_GLEICHMANN 0x10
#define VENDOR_MENTA 0x11
#define VENDOR_SUN 0x13
#define VENDOR_MOVIDIA 0x14
#define VENDOR_ORBITA 0x17
#define VENDOR_SYNOPSYS 0x21
#define VENDOR_NASA 0x22
#define VENDOR_S3 0x31
#define VENDOR_CAL 0xca
#define VENDOR_EMBEDDIT 0xea
#define VENDOR_CETON 0xcb
#define VENDOR_ACTEL 0xac
#define VENDOR_APPLECORE 0xae
/* Aeroflex Gaisler device ID defines */
#define GAISLER_LEON2DSU 0x002
#define GAISLER_LEON3 0x003
#define GAISLER_LEON3DSU 0x004
#define GAISLER_ETHAHB 0x005
#define GAISLER_APBMST 0x006
#define GAISLER_AHBUART 0x007
#define GAISLER_SRCTRL 0x008
#define GAISLER_SDCTRL 0x009
#define GAISLER_SSRCTRL 0x00a
#define GAISLER_APBUART 0x00c
#define GAISLER_IRQMP 0x00d
#define GAISLER_AHBRAM 0x00e
#define GAISLER_AHBDPRAM 0x00f
#define GAISLER_GPTIMER 0x011
#define GAISLER_PCITRG 0x012
#define GAISLER_PCISBRG 0x013
#define GAISLER_PCIFBRG 0x014
#define GAISLER_PCITRACE 0x015
#define GAISLER_DMACTRL 0x016
#define GAISLER_AHBTRACE 0x017
#define GAISLER_DSUCTRL 0x018
#define GAISLER_CANAHB 0x019
#define GAISLER_GPIO 0x01a
#define GAISLER_AHBROM 0x01b
#define GAISLER_AHBJTAG 0x01c
#define GAISLER_ETHMAC 0x01d
#define GAISLER_SWNODE 0x01e
#define GAISLER_SPW 0x01f
#define GAISLER_AHB2AHB 0x020
#define GAISLER_USBDC 0x021
#define GAISLER_USB_DCL 0x022
#define GAISLER_DDRMP 0x023
#define GAISLER_ATACTRL 0x024
#define GAISLER_DDRSP 0x025
#define GAISLER_EHCI 0x026
#define GAISLER_UHCI 0x027
#define GAISLER_I2CMST 0x028
#define GAISLER_SPW2 0x029
#define GAISLER_AHBDMA 0x02a
#define GAISLER_NUHOSP3 0x02b
#define GAISLER_CLKGATE 0x02c
#define GAISLER_SPICTRL 0x02d
#define GAISLER_DDR2SP 0x02e
#define GAISLER_SLINK 0x02f
#define GAISLER_GRTM 0x030
#define GAISLER_GRTC 0x031
#define GAISLER_GRPW 0x032
#define GAISLER_GRCTM 0x033
#define GAISLER_GRHCAN 0x034
#define GAISLER_GRFIFO 0x035
#define GAISLER_GRADCDAC 0x036
#define GAISLER_GRPULSE 0x037
#define GAISLER_GRTIMER 0x038
#define GAISLER_AHB2PP 0x039
#define GAISLER_GRVERSION 0x03a
#define GAISLER_APB2PW 0x03b
#define GAISLER_PW2APB 0x03c
#define GAISLER_GRCAN 0x03d
#define GAISLER_I2CSLV 0x03e
#define GAISLER_U16550 0x03f
#define GAISLER_AHBMST_EM 0x040
#define GAISLER_AHBSLV_EM 0x041
#define GAISLER_GRTESTMOD 0x042
#define GAISLER_ASCS 0x043
#define GAISLER_IPMVBCTRL 0x044
#define GAISLER_SPIMCTRL 0x045
#define GAISLER_L4STAT 0x047
#define GAISLER_LEON4 0x048
#define GAISLER_LEON4DSU 0x049
#define GAISLER_PWM 0x04a
#define GAISLER_L2CACHE 0x04b
#define GAISLER_SDCTRL64 0x04c
#define GAISLER_GR1553B 0x04d
#define GAISLER_1553TST 0x04e
#define GAISLER_GRIOMMU 0x04f
#define GAISLER_FTAHBRAM 0x050
#define GAISLER_FTSRCTRL 0x051
#define GAISLER_AHBSTAT 0x052
#define GAISLER_LEON3FT 0x053
#define GAISLER_FTMCTRL 0x054
#define GAISLER_FTSDCTRL 0x055
#define GAISLER_FTSRCTRL8 0x056
#define GAISLER_MEMSCRUB 0x057
#define GAISLER_FTSDCTRL64 0x058
#define GAISLER_APBPS2 0x060
#define GAISLER_VGACTRL 0x061
#define GAISLER_LOGAN 0x062
#define GAISLER_SVGACTRL 0x063
#define GAISLER_T1AHB 0x064
#define GAISLER_MP7WRAP 0x065
#define GAISLER_GRSYSMON 0x066
#define GAISLER_GRACECTRL 0x067
#define GAISLER_ATAHBSLV 0x068
#define GAISLER_ATAHBMST 0x069
#define GAISLER_ATAPBSLV 0x06a
#define GAISLER_B1553BC 0x070
#define GAISLER_B1553RT 0x071
#define GAISLER_B1553BRM 0x072
#define GAISLER_AES 0x073
#define GAISLER_ECC 0x074
#define GAISLER_PCIF 0x075
#define GAISLER_CLKMOD 0x076
#define GAISLER_HAPSTRAK 0x077
#define GAISLER_TEST_1X2 0x078
#define GAISLER_WILD2AHB 0x079
#define GAISLER_BIO1 0x07a
#define GAISLER_AESDMA 0x07b
#define GAISLER_SATCAN 0x080
#define GAISLER_CANMUX 0x081
#define GAISLER_GRTMRX 0x082
#define GAISLER_GRTCTX 0x083
#define GAISLER_GRTMDESC 0x084
#define GAISLER_GRTMVC 0x085
#define GAISLER_GEFFE 0x086
#define GAISLER_GPREG 0x087
#define GAISLER_GRTMPAHB 0x088
#define GAISLER_SPWCUC 0x089
#define GAISLER_SPW2_DMA 0x08a
#define GAISLER_SPWROUTER 0x08b
/* European Space Agency device ID defines */
#define ESA_LEON2 0x002
#define ESA_LEON2APB 0x003
#define ESA_IRQ 0x005
#define ESA_TIMER 0x006
#define ESA_UART 0x007
#define ESA_CFG 0x008
#define ESA_IO 0x009
#define ESA_MCTRL 0x00f
#define ESA_PCIARB 0x010
#define ESA_HURRICANE 0x011
#define ESA_SPW_RMAP 0x012
#define ESA_AHBUART 0x013
#define ESA_SPWA 0x014
#define ESA_BOSCHCAN 0x015
#define ESA_IRQ2 0x016
#define ESA_AHBSTAT 0x017
#define ESA_WPROT 0x018
#define ESA_WPROT2 0x019
#define ESA_PDEC3AMBA 0x020
#define ESA_PTME3AMBA 0x021
/* OpenChip device ID defines */
#define OPENCHIP_APBGPIO 0x001
#define OPENCHIP_APBI2C 0x002
#define OPENCHIP_APBSPI 0x003
#define OPENCHIP_APBCHARLCD 0x004
#define OPENCHIP_APBPWM 0x005
#define OPENCHIP_APBPS2 0x006
#define OPENCHIP_APBMMCSD 0x007
#define OPENCHIP_APBNAND 0x008
#define OPENCHIP_APBLPC 0x009
#define OPENCHIP_APBCF 0x00a
#define OPENCHIP_APBSYSACE 0x00b
#define OPENCHIP_APB1WIRE 0x00c
#define OPENCHIP_APBJTAG 0x00d
#define OPENCHIP_APBSUI 0x00e
/* Various contributions device ID defines */
#define CONTRIB_CORE1 0x001
#define CONTRIB_CORE2 0x002
/* Gleichmann Electronics device ID defines */
#define GLEICHMANN_CUSTOM 0x001
#define GLEICHMANN_GEOLCD01 0x002
#define GLEICHMANN_DAC 0x003
#define GLEICHMANN_HPI 0x004
#define GLEICHMANN_SPI 0x005
#define GLEICHMANN_HIFC 0x006
#define GLEICHMANN_ADCDAC 0x007
#define GLEICHMANN_SPIOC 0x008
#define GLEICHMANN_AC97 0x009
/* Sun Microsystems device ID defines */
#define SUN_T1 0x001
#define SUN_S1 0x011
/* Orbita device ID defines */
#define ORBITA_1553B 0x001
#define ORBITA_429 0x002
#define ORBITA_SPI 0x003
#define ORBITA_I2C 0x004
#define ORBITA_SMARTCARD 0x064
#define ORBITA_SDCARD 0x065
#define ORBITA_UART16550 0x066
#define ORBITA_CRYPTO 0x067
#define ORBITA_SYSIF 0x068
#define ORBITA_PIO 0x069
#define ORBITA_RTC 0x0c8
#define ORBITA_COLORLCD 0x12c
#define ORBITA_PCI 0x190
#define ORBITA_DSP 0x1f4
#define ORBITA_USBHOST 0x258
#define ORBITA_USBDEV 0x2bc
/* NASA device ID defines */
#define NASA_EP32 0x001
/* CAL device ID defines */
#define CAL_DDRCTRL 0x188
/* Actel Corporation device ID defines */
#define ACTEL_COREMP7 0x001
/* AppleCore device ID defines */
#define APPLECORE_UTLEON3 0x001
#define APPLECORE_UTLEON3DSU 0x002
/* Opencores device id's */
#define OPENCORES_PCIBR 0x4
#define OPENCORES_ETHMAC 0x5
#endif
......@@ -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 */
......
......@@ -60,7 +60,6 @@
* Supported commands
*/
#define CONFIG_CMD_REGINFO
#define CONFIG_CMD_AMBAPP
#define CONFIG_CMD_PING
#define CONFIG_CMD_DIAG
#define CONFIG_CMD_IRQ
......@@ -311,40 +310,38 @@
/***** Gaisler GRLIB IP-Cores Config ********/
/* AMBA Plug & Play info display on startup */
/*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/
#define CONFIG_SYS_GRLIB_SDRAM 0
/* No SDRAM Configuration */
#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
/* See, GRLIB Docs (grip.pdf) on how to set up
* These the memory controller registers.
*/
#define CONFIG_SYS_GRLIB_MEMCFG1 (0x10f800ff | (1<<11))
#define CONFIG_SYS_GRLIB_ESA_MCTRL1
#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1 (0x10f800ff | (1<<11))
#if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM_NOSRAM
#define CONFIG_SYS_GRLIB_MEMCFG2 0x82206000
#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x82206000
#else
#define CONFIG_SYS_GRLIB_MEMCFG2 0x82205260
#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2 0x82205260
#endif
#define CONFIG_SYS_GRLIB_MEMCFG3 0x0809a000
#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3 0x0809a000
#define CONFIG_SYS_GRLIB_FT_MEMCFG1 (0x10f800ff | (1<<11))
/* GRLIB FT-MCTRL configuration */
#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1 (0x10f800ff | (1<<11))
#if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM_NOSRAM
#define CONFIG_SYS_GRLIB_FT_MEMCFG2 0x82206000
#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2 0x82206000
#else
#define CONFIG_SYS_GRLIB_FT_MEMCFG2 0x82205260
#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2 0x82205260
#endif
#define CONFIG_SYS_GRLIB_FT_MEMCFG3 0x0809a000
#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3 0x0809a000
/* no DDR controller */
#define CONFIG_SYS_GRLIB_DDR_CFG 0x00000000
#undef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
/* no DDR2 Controller */
#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000
#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000
/* Calculate scaler register value from default baudrate */
#define CONFIG_SYS_GRLIB_APBUART_SCALER \
((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
/* Identification string */
#define CONFIG_IDENT_STRING "GAISLER LEON3 GR-CPCI-AX2000"
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -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
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
/* 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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册