summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/leon2/cchip
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2007-09-06 13:17:16 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2007-09-06 13:17:16 +0000
commitee8933f26dfac31eb6103289d7b37312a43f0bf3 (patch)
tree91d5fcb444e6d58f83b5720ef7a6afd13baddca5 /c/src/lib/libbsp/sparc/leon2/cchip
parent2007-09-06 Daniel Hellstrom <daniel@gaisler.com> (diff)
downloadrtems-ee8933f26dfac31eb6103289d7b37312a43f0bf3.tar.bz2
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.
Diffstat (limited to 'c/src/lib/libbsp/sparc/leon2/cchip')
-rw-r--r--c/src/lib/libbsp/sparc/leon2/cchip/cchip.c355
1 files changed, 355 insertions, 0 deletions
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 );*/
+}