diff options
Diffstat (limited to 'c')
-rw-r--r-- | c/src/lib/libbsp/sparc/leon2/ChangeLog | 5 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon2/cchip/cchip.c | 355 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon2/include/cchip.h | 23 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon2/include/rasta.h | 107 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon2/rasta/rasta.c | 384 |
5 files changed, 874 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/sparc/leon2/ChangeLog b/c/src/lib/libbsp/sparc/leon2/ChangeLog index e2f2ce9ecd..d9634edba8 100644 --- a/c/src/lib/libbsp/sparc/leon2/ChangeLog +++ b/c/src/lib/libbsp/sparc/leon2/ChangeLog @@ -1,5 +1,10 @@ 2007-09-06 Daniel Hellstrom <daniel@gaisler.com> + * cchip/cchip.c, include/cchip.h, include/rasta.h, + rasta/rasta.c: New files missed in previous commit. + +2007-09-06 Daniel Hellstrom <daniel@gaisler.com> + * Makefile.am, preinstall.am: Use the following new drivers from sparc/shared: PCI, b1553BRM, SpaceWire(GRSPW), CAN (GRCAN), Raw UART. diff --git a/c/src/lib/libbsp/sparc/leon2/cchip/cchip.c b/c/src/lib/libbsp/sparc/leon2/cchip/cchip.c new file mode 100644 index 0000000000..4fde54e007 --- /dev/null +++ b/c/src/lib/libbsp/sparc/leon2/cchip/cchip.c @@ -0,0 +1,355 @@ + +#include <bsp.h> +#include <rtems/bspIo.h> +#include <rtems.h> +#include <string.h> + +#include <rtems.h> +#include <leon.h> +#include <ambapp.h> +#include <pci.h> + +#include <b1553brm_pci.h> +#include <occan_pci.h> +#include <grspw_pci.h> +#include <apbuart_pci.h> + +#include <cchip.h> + +/* +#define DEBUG +#define DEBUG_IRQS +*/ +#define BOARD_INFO +/*#define PRINT_SPURIOUS*/ + +/* AT697 Register MAP */ +static LEON_Register_Map *regs = (LEON_Register_Map *)0x80000000; + +/* initializes interrupt management for companionship board */ +void cchip1_irq_init(void); + +/* register interrupt handler (called from drivers) */ +void cchip1_set_isr(void *handler, int irqno, void *arg); + +#define READ_REG(address) _READ_REG((unsigned int)address) +static __inline__ unsigned int _READ_REG(unsigned int addr) { + unsigned int tmp; + asm("lda [%1]1, %0 " + : "=r"(tmp) + : "r"(addr) + ); + return tmp; +} + +/* PCI bride reg layout on AMBA side */ +typedef struct { + unsigned int bar0; + unsigned int bar1; + unsigned int bar2; + unsigned int bar3; + unsigned int bar4;/* 0x10 */ + + unsigned int unused[4*3-1]; + + unsigned int ambabars[1]; /* 0x40 */ +} amba_bridge_regs; + +/* PCI bride reg layout on PCI side */ +typedef struct { + unsigned int bar0; + unsigned int bar1; + unsigned int bar2; + unsigned int bar3; + unsigned int bar4; /* 0x10 */ + + unsigned int ilevel; + unsigned int ipend; + unsigned int iforce; + unsigned int istatus; + unsigned int iclear; + unsigned int imask; +} pci_bridge_regs; + +typedef struct { + pci_bridge_regs *pcib; + amba_bridge_regs *ambab; + + /* AT697 PCI */ + unsigned int bars[5]; + int bus, dev, fun; + + /* AMBA bus */ + amba_confarea_type amba_bus; + struct amba_mmap amba_maps[2]; + + /* FT AHB SRAM */ + int ftsram_size; /* kb */ + unsigned int ftsram_start; + unsigned int ftsram_end; + +} cchip1; + +cchip1 cc1; + +int init_pcif(void){ + unsigned int com1; + int i,bus,dev,fun; + pci_bridge_regs *pcib; + amba_bridge_regs *ambab; + int amba_master_cnt; + amba_confarea_type *abus; + + if ( BSP_pciFindDevice(0x1AC8, 0x0701, 0, &bus, &dev, &fun) == 0 ) { + ; + }else if (BSP_pciFindDevice(0x16E3, 0x0210, 0, &bus, &dev, &fun) == 0) { + ; + } else { + /* didn't find any Companionship board on the PCI bus. */ + return -1; + } + + /* found Companionship PCI board, Set it up: */ + + pci_read_config_dword(bus, dev, fun, 0x10, &cc1.bars[0]); + pci_read_config_dword(bus, dev, fun, 0x14, &cc1.bars[1]); + pci_read_config_dword(bus, dev, fun, 0x18, &cc1.bars[2]); + pci_read_config_dword(bus, dev, fun, 0x1c, &cc1.bars[3]); + pci_read_config_dword(bus, dev, fun, 0x20, &cc1.bars[4]); + +#ifdef DEBUG + for(i=0; i<5; i++){ + printk("PCI: BAR%d: 0x%x\n\r",i,cc1.bars[i]); + } +#endif + + /* Set up PCI ==> AMBA */ + pcib = (void *)cc1.bars[0]; + pcib->bar0 = 0xfc000000; +/* pcib->bar1 = 0xff000000;*/ +#ifdef BOARD_INFO + printk("Found CCHIP1 Board at 0x%lx\n\r",(unsigned int)pcib); +#endif + + /* AMBA MAP cc1.bars[1] (in CPU) ==> 0xf0000000(remote amba address) */ + cc1.amba_maps[0].size = 0x04000000; + cc1.amba_maps[0].cpu_adr = cc1.bars[1]; + cc1.amba_maps[0].remote_amba_adr = 0xfc000000; + + /* Mark end of table */ + cc1.amba_maps[1].size=0; + cc1.amba_maps[1].cpu_adr = 0; + cc1.amba_maps[1].remote_amba_adr = 0; + + /* Enable I/O and Mem accesses */ + pci_read_config_dword(bus, dev, fun, 0x4, &com1); + com1 |= 0x3; + pci_write_config_dword(bus, dev, fun, 0x4, com1); + pci_read_config_dword(bus, dev, fun, 0x4, &com1); + + /* Set up AMBA Masters ==> PCI */ + ambab = (void *)(cc1.bars[1]+0x400); +#ifdef DEBUG + printk("AMBA: PCIBAR[%d]: 0x%x, 0x%x\n\r",0,ambab->bar0,pcib->bar0); + printk("AMBA: PCIBAR[%d]: 0x%x, 0x%x\n\r",1,ambab->bar1,pcib->bar1); + printk("AMBA: PCIBAR[%d]: 0x%x, 0x%x\n\r",2,ambab->bar2,pcib->bar2); +#endif + ambab->ambabars[0] = 0x40000000; /* 0xe0000000(AMBA) ==> 0x40000000(PCI) ==> 0x40000000(AT697 AMBA) */ + + /* Scan bus for AMBA devices */ + abus = &cc1.amba_bus; + memset(abus,0,sizeof(amba_confarea_type)); + amba_scan(abus,cc1.bars[1]+0x3f00000,&cc1.amba_maps[0]); + + /* Get number of amba masters */ + amba_master_cnt = abus->ahbmst.devnr; +#ifdef BOARD_INFO + printk("Found %d AMBA masters\n\r",amba_master_cnt); +#endif + for(i=1; i<amba_master_cnt; i++){ + ambab->ambabars[i] = 0x40000000; + } + + /* Enable PCI Master */ + pci_read_config_dword(bus, dev, fun, 0x4, &com1); + com1 |= 0x4; + pci_write_config_dword(bus, dev, fun, 0x4, com1); + pci_read_config_dword(bus, dev, fun, 0x4, &com1); + + cc1.pcib = pcib; + cc1.ambab = ambab; + cc1.bus = bus; + cc1.dev = dev; + cc1.fun = fun; + + return 0; +} + +#ifndef GAISLER_FTAHBRAM + #define GAISLER_FTAHBRAM 0x50 +#endif +int init_onboard_sram(){ + amba_ahb_device ahb; + amba_apb_device apb; + unsigned int conf, size; + + /* Find SRAM controller + * 1. AHB slave interface + * 2. APB slave interface + */ + if ( amba_find_apbslv(&cc1.amba_bus,VENDOR_GAISLER,GAISLER_FTAHBRAM,&apb) != 1 ){ + printk("On Board FT SRAM not found (APB)\n"); + return -1; + } + + if ( amba_find_ahbslv(&cc1.amba_bus,VENDOR_GAISLER,GAISLER_FTAHBRAM,&ahb) != 1 ){ + printk("On Board FT SRAM not found (AHB)\n"); + return -1; + } + + /* We have found the controller. + * Get it going. + * + * Get size of SRAM + */ + conf = *(unsigned int *)apb.start; + size = (conf >>10) & 0x7; + + /* 2^x kb */ + cc1.ftsram_size = 1<<size; + cc1.ftsram_start = ahb.start[0]; + cc1.ftsram_end = size*1024 + cc1.ftsram_start; +#ifdef BOARD_INFO + printk("Found FT AHB SRAM %dkb at 0x%lx\n",cc1.ftsram_size,cc1.ftsram_start); +#endif + return 0; +} + +int cchip1_register(void){ + + /* Init AT697 PCI Controller */ + init_pci(); + + /* Find & init CChip board . + * Also scan AMBA Plug&Play info for us. + */ + if ( init_pcif() ){ + printk("Failed to initialize CCHIP board\n\r"); + return -1; + } + + /* Set interrupt common board stuff */ + cchip1_irq_init(); + + /* Find on board SRAM */ + if ( init_onboard_sram() ){ + printk("Failed to register On Board SRAM. It is needed by b1553BRM\n"); + return -1; + } + + /* Register interrupt install functions */ + b1553brm_pci_int_reg = cchip1_set_isr; + occan_pci_int_reg = cchip1_set_isr; + grspw_pci_int_reg = cchip1_set_isr; + apbuart_pci_int_reg = cchip1_set_isr; + + /* register the BRM PCI driver, use 16k FTSRAM... */ + if ( b1553brm_pci_register(&cc1.amba_bus,0,0,3,cc1.ftsram_start,0xffa00000) ){ + printk("Failed to register BRM PCI driver\n"); + return -1; + } + + /* register the BRM PCI driver, no DMA memory... */ + if ( occan_pci_register(&cc1.amba_bus) ){ + printk("Failed to register OC_CAN PCI driver\n"); + return -1; + } + + /* register the GRSPW PCI driver, use malloc... */ + if ( grspw_pci_register(&cc1.amba_bus,0,0xe0000000) ){ + printk("Failed to register GRSPW PCI driver\n"); + return -1; + } + + /* register the APBUART PCI driver, no DMA memory */ + if ( apbuart_pci_register(&cc1.amba_bus) ){ + printk("Failed to register APBUART PCI driver\n"); + return -1; + } + + return 0; +} + +static rtems_isr cchip1_interrupt_dispatcher(rtems_vector_number v); +static unsigned int cchip1_spurious_cnt; + +typedef struct { + unsigned int (*handler)(int irqno, void *arg); + void *arg; +} int_handler; + +static int_handler int_handlers[16]; + +void cchip1_irq_init(void){ + + /* Configure AT697 ioport bit 7 to input pci irq */ + regs->PIO_Direction &= ~(1<<7); + regs->PIO_Interrupt = 0x87; /* level sensitive */ + + /* Set up irq controller (mask all IRQs) */ + cc1.pcib->imask = 0x0000; + cc1.pcib->ipend = 0; + cc1.pcib->iclear = 0xffff; + cc1.pcib->iforce = 0; + cc1.pcib->ilevel = 0x0; + + memset(int_handlers,0,sizeof(int_handlers)); + + /* Reset spurious counter */ + cchip1_spurious_cnt = 0; + + /* Register interrupt handler */ + set_vector(cchip1_interrupt_dispatcher,LEON_TRAP_TYPE(CCHIP_IRQ),1); +} + +void cchip1_set_isr(void *handler, int irqno, void *arg){ + int_handlers[irqno].handler = handler; + int_handlers[irqno].arg = arg; +#ifdef DEBUG + printk("Registering IRQ %d to 0x%lx(%d,0x%lx)\n\r",irqno,(unsigned int)handler,irqno,(unsigned int)arg); +#endif + cc1.pcib->imask |= 1<<irqno; /* Enable the registered IRQ */ +} + +static rtems_isr cchip1_interrupt_dispatcher(rtems_vector_number v){ + unsigned int pending = READ_REG(&cc1.pcib->ipend); + unsigned int (*handler)(int irqno, void *arg); + unsigned int clr = pending; + int irq=1; + + if ( !pending ){ +#ifdef PRINT_SPURIOUS + printk("Spurious IRQ %d: %d\n",v,cchip1_spurious_cnt); +#endif + cchip1_spurious_cnt++; + return; + } +#ifdef DEBUG_IRQS + printk("CCIRQ: 0x%x\n",(unsigned int)pending); +#endif + /* IRQ 0 doesn't exist */ + irq=1; + pending = pending>>1; + + while ( pending ){ + if ( (pending & 1) && (handler=int_handlers[irq].handler) ){ + handler(irq,int_handlers[irq].arg); + } + irq++; + pending = pending>>1; + } + + cc1.pcib->iclear = clr; + + /*LEON_Clear_interrupt( brd->irq );*/ +} diff --git a/c/src/lib/libbsp/sparc/leon2/include/cchip.h b/c/src/lib/libbsp/sparc/leon2/include/cchip.h new file mode 100644 index 0000000000..63a4a9ba25 --- /dev/null +++ b/c/src/lib/libbsp/sparc/leon2/include/cchip.h @@ -0,0 +1,23 @@ + +#ifndef __CCHIP_H__ +#define __CCHIP_H__ + +#include <b1553brm_pci.h> +#include <occan_pci.h> +#include <grspw_pci.h> +#include <apbuart_pci.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define CCHIP_IRQ 4 + +/* Register all drivers supported by the Companion Chip board */ +int cchip_register(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/c/src/lib/libbsp/sparc/leon2/include/rasta.h b/c/src/lib/libbsp/sparc/leon2/include/rasta.h new file mode 100644 index 0000000000..986bc2addc --- /dev/null +++ b/c/src/lib/libbsp/sparc/leon2/include/rasta.h @@ -0,0 +1,107 @@ +#ifndef __RASTA_H__ +#define __RASTA_H__ + +#include <bsp.h> + +#include <grcan.h> +#include <b1553brm_rasta.h> +#include <grspw.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern int rasta_register(void); + +/* Address of PCI bus on RASTA local AMBA bus */ +#define RASTA_PCI_BASE 0xe0000000 + +/* Address of SRAM on RASTA local AMBA bus */ +#define RASTA_LOCAL_SRAM 0x40000000 + +#define UART0_IRQNO 2 +#define UART1_IRQNO 3 +#define GRCAN_IRQNO 7 +#define SPW0_IRQNO 10 +#define SPW1_IRQNO 11 +#define SPW2_IRQNO 12 +#define BRM_IRQNO 13 + +#define GRCAN_IRQ (3<<GRCAN_IRQNO) +#define SPW0_IRQ (1<<SPW0_IRQNO) +#define SPW1_IRQ (1<<SPW1_IRQNO) +#define SPW2_IRQ (1<<SPW2_IRQNO) +#define SPW_IRQ (7<<SPW0_IRQNO) +#define BRM_IRQ (1<<BRM_IRQNO) +#define UART0_IRQ (1<<UART0_IRQNO) +#define UART1_IRQ (1<<UART1_IRQNO) + +/* + * The following defines the bits in the UART Control Registers. + * + */ +#define LEON_REG_UART_CONTROL_RTD 0x000000FF /* RX/TX data */ + +/* + * The following defines the bits in the LEON UART Status Registers. + */ +#define LEON_REG_UART_STATUS_DR 0x00000001 /* Data Ready */ +#define LEON_REG_UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */ +#define LEON_REG_UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */ +#define LEON_REG_UART_STATUS_BR 0x00000008 /* Break Error */ +#define LEON_REG_UART_STATUS_OE 0x00000010 /* RX Overrun Error */ +#define LEON_REG_UART_STATUS_PE 0x00000020 /* RX Parity Error */ +#define LEON_REG_UART_STATUS_FE 0x00000040 /* RX Framing Error */ +#define LEON_REG_UART_STATUS_ERR 0x00000078 /* Error Mask */ + + +/* + * The following defines the bits in the LEON UART Status Registers. + */ +#define LEON_REG_UART_CTRL_RE 0x00000001 /* Receiver enable */ +#define LEON_REG_UART_CTRL_TE 0x00000002 /* Transmitter enable */ +#define LEON_REG_UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */ +#define LEON_REG_UART_CTRL_TI 0x00000008 /* Transmitter interrupt enable */ +#define LEON_REG_UART_CTRL_PS 0x00000010 /* Parity select */ +#define LEON_REG_UART_CTRL_PE 0x00000020 /* Parity enable */ +#define LEON_REG_UART_CTRL_FL 0x00000040 /* Flow control enable */ +#define LEON_REG_UART_CTRL_LB 0x00000080 /* Loop Back enable */ + +#define UART_SET_SCALER 0 +#define UART_SET_CTRL 1 +#define UART_GET_STAT 2 +#define UART_CLR_STAT 3 + +struct uart_reg { + volatile unsigned int data; /* 0x00 */ + volatile unsigned int status; /* 0x04 */ + volatile unsigned int ctrl; /* 0x08 */ + volatile unsigned int scaler; /* 0x0C */ +}; + + +void uart_register(unsigned int baseaddr); +rtems_device_driver uart_initialize(rtems_device_major_number major, rtems_device_minor_number minor, void *arg); +rtems_device_driver uart_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg); +rtems_device_driver uart_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg); +rtems_device_driver uart_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg); +rtems_device_driver uart_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg); +rtems_device_driver uart_control(rtems_device_major_number major, rtems_device_minor_number minor, void *arg); + + +struct gpio_reg { + volatile unsigned int in_data; /* 0x00 */ + volatile unsigned int out_data; /* 0x04 */ + volatile unsigned int dir; /* 0x08 */ + volatile unsigned int imask; /* 0x0C */ + volatile unsigned int ipol; /* 0x10 */ + volatile unsigned int iedge; /* 0x14 */ +}; + +extern struct gpio_reg *gpio0, *gpio1; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/c/src/lib/libbsp/sparc/leon2/rasta/rasta.c b/c/src/lib/libbsp/sparc/leon2/rasta/rasta.c new file mode 100644 index 0000000000..542f4b5167 --- /dev/null +++ b/c/src/lib/libbsp/sparc/leon2/rasta/rasta.c @@ -0,0 +1,384 @@ +#include <rtems/bspIo.h> +#include <pci.h> +#include <rasta.h> +#include <ambapp.h> +#include <grcan_rasta.h> +#include <grspw_rasta.h> +#include <b1553brm_rasta.h> +#include <apbuart_rasta.h> + +#include <string.h> + +/* If RASTA_SRAM is defined SRAM will be used, else SDRAM */ +/*#define RASTA_SRAM 1*/ + +#define RASTA_IRQ 4 + +/* Offset from 0x80000000 (dual bus version) */ +#define AHB1_IOAREA_BASE_ADDR 0x80100000 +#define APB2_OFFSET 0x200000 +#define IRQ_OFFSET 0x200500 +#define GRHCAN_OFFSET 0x201000 +#define BRM_OFFSET 0x100000 +#define SPW_OFFSET 0xa00 +#define UART_OFFSET 0x200200 +#define GPIO0_OFF 0x200600 +#define GPIO1_OFF 0x200700 + +/* #define DEBUG 1 */ + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +/* +typedef struct { + volatile unsigned int ilevel; + volatile unsigned int ipend; + volatile unsigned int iforce; + volatile unsigned int iclear; + volatile unsigned int mpstat; + volatile unsigned int notused01; + volatile unsigned int notused02; + volatile unsigned int notused03; + volatile unsigned int notused10; + volatile unsigned int notused11; + volatile unsigned int notused12; + volatile unsigned int notused13; + volatile unsigned int notused20; + volatile unsigned int notused21; + volatile unsigned int notused22; + volatile unsigned int notused23; + volatile unsigned int mask[16]; + volatile unsigned int force[16]; +} LEON3_IrqCtrl_Regs_Map; +*/ +static int bus, dev, fun; + +LEON3_IrqCtrl_Regs_Map *irq = NULL; +LEON_Register_Map *regs = 0x80000000; + +struct gpio_reg *gpio0, *gpio1; + +/* static rtems_isr pci_interrupt_handler (rtems_vector_number v) { */ + +/* volatile unsigned int *pci_int = (volatile unsigned int *) 0x80000168; */ +/* volatile unsigned int *pci_mem = (volatile unsigned int *) 0xb0400000; */ + +/* if (*pci_int & 0x20) { */ + +/* *pci_int = 0x20; */ + +/* *pci_mem = 0; */ + +/* printk("pci died\n"); */ + +/* } */ + +/* } */ + +void *uart0_int_arg, *uart1_int_arg; +void *spw0_int_arg, *spw1_int_arg, *spw2_int_arg; +void *grcan_int_arg; +void *brm_int_arg; + +void (*uart0_int_handler)(int irq, void *arg) = NULL; +void (*uart1_int_handler)(int irq, void *arg) = NULL; +void (*spw0_int_handler)(int irq, void *arg) = NULL; +void (*spw1_int_handler)(int irq, void *arg) = NULL; +void (*spw2_int_handler)(int irq, void *arg) = NULL; +void (*grcan_int_handler)(int irq, void *arg) = NULL; +void (*brm_int_handler)(int irq, void *arg) = NULL; + +static rtems_isr rasta_interrupt_handler (rtems_vector_number v) +{ + unsigned int status; + + status = irq->ipend; + + if ( (status & GRCAN_IRQ) && grcan_int_handler ) { + grcan_int_handler(GRCAN_IRQNO,grcan_int_arg); + } + + if (status & SPW_IRQ) { + if ( (status & SPW0_IRQ) && spw0_int_handler ){ + spw0_int_handler(SPW0_IRQNO,spw0_int_arg); + } + + if ( (status & SPW1_IRQ) && spw1_int_handler ){ + spw1_int_handler(SPW1_IRQNO,spw1_int_arg); + } + + if ( (status & SPW2_IRQ) && spw2_int_handler ){ + spw2_int_handler(SPW2_IRQNO,spw2_int_arg); + } + } + if ((status & BRM_IRQ) && brm_int_handler ){ + brm_int_handler(BRM_IRQNO,brm_int_arg); + } + if ( (status & UART0_IRQ) && uart0_int_handler ) { + uart0_int_handler(UART0_IRQNO,uart0_int_arg); + } + if ( (status & UART1_IRQ) && uart1_int_handler) { + uart1_int_handler(UART1_IRQNO,uart1_int_arg); + } + + DBG("RASTA-IRQ: 0x%x\n",status); + irq->iclear = status; + +} + +void rasta_interrrupt_register(void *handler, int irqno, void *arg) +{ + DBG("RASTA: Registering irq %d\n",irqno); + if ( irqno == UART0_IRQNO ){ + DBG("RASTA: Registering uart0 handler: 0x%x, arg: 0x%x\n",handler,arg); + uart0_int_handler = handler; + uart0_int_arg = arg; + + /* unmask interrupt source */ + irq->iclear = UART0_IRQ; + irq->mask[0] |= UART0_IRQ; + } + + if ( irqno == UART1_IRQNO ){ + DBG("RASTA: Registering uart1 handler: 0x%x, arg: 0x%x\n",handler,arg); + uart1_int_handler = handler; + uart1_int_arg = arg; + + /* unmask interrupt source */ + irq->iclear = UART1_IRQ; + irq->mask[0] |= UART1_IRQ; + } + + if ( irqno == SPW0_IRQNO ){ + DBG("RASTA: Registering spw0 handler: 0x%x, arg: 0x%x\n",handler,arg); + spw0_int_handler = handler; + spw0_int_arg = arg; + + /* unmask interrupt source */ + irq->iclear = SPW0_IRQ; + irq->mask[0] |= SPW0_IRQ; + } + + if ( irqno == SPW1_IRQNO ){ + DBG("RASTA: Registering spw1 handler: 0x%x, arg: 0x%x\n",handler,arg); + spw1_int_handler = handler; + spw1_int_arg = arg; + + /* unmask interrupt source */ + irq->iclear = SPW1_IRQ; + irq->mask[0] |= SPW1_IRQ; + } + + if ( irqno == SPW2_IRQNO ){ + DBG("RASTA: Registering spw2 handler: 0x%x, arg: 0x%x\n",handler,arg); + spw2_int_handler = handler; + spw2_int_arg = arg; + + /* unmask interrupt source */ + irq->iclear = SPW2_IRQ; + irq->mask[0] |= SPW2_IRQ; + } + + if ( irqno == GRCAN_IRQNO ){ + DBG("RASTA: Registering GRCAN handler: 0x%x, arg: 0x%x\n",handler,arg); + grcan_int_handler = handler; + grcan_int_arg = arg; + + /* unmask interrupt source */ + irq->iclear = GRCAN_IRQ; + irq->mask[0] |= GRCAN_IRQ; + } + + if ( irqno == BRM_IRQNO ){ + DBG("RASTA: Registering BRM handler: 0x%x, arg: 0x%x\n",handler,arg); + brm_int_handler = handler; + brm_int_arg = arg; + + /* unmask interrupt source */ + irq->iclear = BRM_IRQ; + irq->mask[0] |= BRM_IRQ; + } +} + + +int rasta_get_gpio(amba_confarea_type *abus, int index, unsigned int *address, int *irq) +{ + amba_apb_device dev; + int cores; + + if ( !abus ) + return -1; + + /* Scan PnP info for GPIO port number 'index' */ + cores = amba_find_next_apbslv(abus,VENDOR_GAISLER,GAISLER_PIOPORT,&dev,index); + if ( cores < 1 ) + return -1; + + if ( address ) + *address = dev.start; + + if ( irq ) + *irq = dev.irq; + + return 0; +} + +/* AMBA Plug&Play information */ +static amba_confarea_type abus; +static struct amba_mmap amba_maps[3]; + +int rasta_register(void) +{ + unsigned int bar0, bar1, data; + + unsigned int *page0 = NULL; + unsigned int *apb_base = NULL; + int found=0; + + + DBG("Searching for RASTA board ..."); + + /* Search PCI vendor/device id. */ + if (BSP_pciFindDevice(0x1AC8, 0x0010, 0, &bus, &dev, &fun) == 0) { + found = 1; + } + + /* Search old PCI vendor/device id. */ + if ( (!found) && (BSP_pciFindDevice(0x16E3, 0x0210, 0, &bus, &dev, &fun) == 0) ) { + found = 1; + } + + /* Did we find a RASTA board? */ + if ( !found ) + return -1; + + DBG(" found it (dev/fun: %d/%d).\n", dev, fun); + + pci_read_config_dword(bus, dev, fun, 0x10, &bar0); + pci_read_config_dword(bus, dev, fun, 0x14, &bar1); + + page0 = bar0 + 0x400000; + *page0 = 0x80000000; /* Point PAGE0 to start of APB */ + + apb_base = bar0+APB2_OFFSET; + +/* apb_base[0] = 0x000002ff; + apb_base[1] = 0x8a205260; + apb_base[2] = 0x00184000; */ + + /* Configure memory controller */ +#ifdef RASTA_SRAM + apb_base[0] = 0x000002ff; + apb_base[1] = 0x00001260; + apb_base[2] = 0x000e8000; +#else + apb_base[0] = 0x000002ff; + apb_base[1] = 0x82206000; + apb_base[2] = 0x000e8000; +#endif + /* Set up rasta irq controller */ + irq = (LEON3_IrqCtrl_Regs_Map *) (bar0+IRQ_OFFSET); + irq->iclear = 0xffff; + irq->ilevel = 0; + irq->mask[0] = 0xffff & ~(UART0_IRQ|UART1_IRQ|SPW0_IRQ|SPW1_IRQ|SPW2_IRQ|GRCAN_IRQ|BRM_IRQ); + + /* Configure AT697 ioport bit 7 to input pci irq */ + regs->PIO_Direction &= ~(1<<7); + regs->PIO_Interrupt = 0x87; /* level sensitive */ + + apb_base[0x100] |= 0x40000000; /* Set GRPCI mmap 0x4 */ + apb_base[0x104] = 0x40000000; /* 0xA0000000; Point PAGE1 to RAM */ + + + /* set parity error response */ + pci_read_config_dword(bus, dev, fun, 0x4, &data); + pci_write_config_dword(bus, dev, fun, 0x4, data|0x40); + + + pci_master_enable(bus, dev, fun); + + /* install PCI interrupt vector */ + /* set_vector(pci_interrupt_handler,14+0x10, 1); */ + + + /* install interrupt vector */ + set_vector(rasta_interrupt_handler, RASTA_IRQ+0x10, 1); + + /* Scan AMBA Plug&Play */ + + /* AMBA MAP bar0 (in CPU) ==> 0x80000000(remote amba address) */ + amba_maps[0].size = 0x10000000; + amba_maps[0].cpu_adr = bar0; + amba_maps[0].remote_amba_adr = 0x80000000; + + /* AMBA MAP bar1 (in CPU) ==> 0x40000000(remote amba address) */ + amba_maps[1].size = 0x10000000; + amba_maps[1].cpu_adr = bar1; + amba_maps[1].remote_amba_adr = 0x40000000; + + /* Mark end of table */ + amba_maps[2].size=0; + amba_maps[2].cpu_adr = 0; + amba_maps[2].remote_amba_adr = 0; + + memset(&abus,0,sizeof(abus)); + + /* Start AMBA PnP scan at first AHB bus */ + amba_scan(&abus,bar0+(AHB1_IOAREA_BASE_ADDR&~0xf0000000),&amba_maps[0]); + + printk("Registering RASTA GRCAN driver\n\r"); + + /*grhcan_register(bar0 + GRHCAN_OFFSET, bar1);*/ + grcan_rasta_int_reg=rasta_interrrupt_register; + if ( grcan_rasta_ram_register(&abus,bar1+0x20000) ){ + printk("Failed to register RASTA GRCAN driver\n\r"); + return -1; + } + + printk("Registering RASTA BRM driver\n\r"); + + /*brm_register(bar0 + BRM_OFFSET, bar1);*/ + /* register the BRM RASTA driver, use 128k on RASTA SRAM... */ + b1553brm_rasta_int_reg=rasta_interrrupt_register; + if ( b1553brm_rasta_register(&abus,2,0,3,bar1,0x40000000) ){ + printk("Failed to register BRM RASTA driver\n"); + return -1; + } + + /* provide the spacewire driver with AMBA Plug&Play + * info so that it can find the GRSPW cores. + */ + grspw_rasta_int_reg=rasta_interrrupt_register; + if ( grspw_rasta_register(&abus,bar1) ){ + printk("Failed to register RASTA GRSPW driver\n\r"); + return -1; + } + + /* provide the spacewire driver with AMBA Plug&Play + * info so that it can find the GRSPW cores. + */ + apbuart_rasta_int_reg=rasta_interrrupt_register; + if ( apbuart_rasta_register(&abus) ){ + printk("Failed to register RASTA APBUART driver\n\r"); + return -1; + } + + /* Find GPIO0 address */ + if ( rasta_get_gpio(&abus,0,(unsigned int *)&gpio0,NULL) ){ + printk("Failed to get address for RASTA GPIO0\n\r"); + return -1; + } + + /* Find GPIO1 address */ + if ( rasta_get_gpio(&abus,1,(unsigned int *)&gpio1,NULL) ){ + printk("Failed to get address for RASTA GPIO1\n\r"); + return -1; + } + + /* Successfully registered the RASTA board */ + return 0; +} |