source: rtems/c/src/lib/libbsp/sparc/leon2/cchip/cchip.c @ 44b06ca

4.104.115
Last change on this file since 44b06ca was 44b06ca, checked in by Ralf Corsepius <ralf.corsepius@…>, on 11/29/09 at 15:33:28

Whitespace removal.

  • Property mode set to 100644
File size: 8.4 KB
Line 
1/*
2 * $Id$
3 */
4
5#include <bsp.h>
6#include <rtems/bspIo.h>
7#include <rtems.h>
8#include <string.h>
9
10#include <rtems.h>
11#include <leon.h>
12#include <ambapp.h>
13#include <pci.h>
14
15#include <b1553brm_pci.h>
16#include <occan_pci.h>
17#include <grspw_pci.h>
18#include <apbuart_pci.h>
19
20#include <cchip.h>
21
22/*
23#define DEBUG
24#define DEBUG_IRQS
25*/
26#define BOARD_INFO
27/*#define PRINT_SPURIOUS*/
28
29/* AT697 Register MAP */
30static LEON_Register_Map *regs = (LEON_Register_Map *)0x80000000;
31
32/* initializes interrupt management for companionship board */
33void cchip1_irq_init(void);
34
35/* register interrupt handler (called from drivers) */
36void cchip1_set_isr(void *handler, int irqno, void *arg);
37
38#define READ_REG(address) _READ_REG((unsigned int)address)
39static __inline__ unsigned int _READ_REG(unsigned int addr) {
40        unsigned int tmp;
41        asm("lda [%1]1, %0 "
42          : "=r"(tmp)
43          : "r"(addr)
44        );
45        return tmp;
46}
47
48/* PCI bride reg layout on AMBA side */
49typedef struct {
50        unsigned int bar0;
51        unsigned int bar1;
52        unsigned int bar2;
53        unsigned int bar3;
54        unsigned int bar4;/* 0x10 */
55
56        unsigned int unused[4*3-1];
57
58        unsigned int ambabars[1]; /* 0x40 */
59} amba_bridge_regs;
60
61/* PCI bride reg layout on PCI side */
62typedef struct {
63        unsigned int bar0;
64        unsigned int bar1;
65        unsigned int bar2;
66        unsigned int bar3;
67        unsigned int bar4; /* 0x10 */
68
69        unsigned int ilevel;
70        unsigned int ipend;
71        unsigned int iforce;
72        unsigned int istatus;
73        unsigned int iclear;
74        unsigned int imask;
75} pci_bridge_regs;
76
77typedef struct {
78        pci_bridge_regs  *pcib;
79        amba_bridge_regs *ambab;
80
81        /* AT697 PCI */
82        unsigned int bars[5];
83        int bus, dev, fun;
84
85        /* AMBA bus */
86        amba_confarea_type amba_bus;
87        struct amba_mmap amba_maps[2];
88
89        /* FT AHB SRAM */
90        int ftsram_size; /* kb */
91        unsigned int ftsram_start;
92        unsigned int ftsram_end;
93
94} cchip1;
95
96cchip1 cc1;
97
98int init_pcif(void){
99        unsigned int com1;
100        int i,bus,dev,fun;
101        pci_bridge_regs *pcib;
102        amba_bridge_regs *ambab;
103        int amba_master_cnt;
104        amba_confarea_type *abus;
105
106  if ( BSP_pciFindDevice(0x1AC8, 0x0701, 0, &bus, &dev, &fun) == 0 ) {
107    ;
108  }else if (BSP_pciFindDevice(0x16E3, 0x0210, 0, &bus, &dev, &fun) == 0) {
109    ;
110  } else {
111    /* didn't find any Companionship board on the PCI bus. */
112    return -1;
113  }
114
115  /* found Companionship PCI board, Set it up: */
116
117        pci_read_config_dword(bus, dev, fun, 0x10, &cc1.bars[0]);
118        pci_read_config_dword(bus, dev, fun, 0x14, &cc1.bars[1]);
119        pci_read_config_dword(bus, dev, fun, 0x18, &cc1.bars[2]);
120        pci_read_config_dword(bus, dev, fun, 0x1c, &cc1.bars[3]);
121        pci_read_config_dword(bus, dev, fun, 0x20, &cc1.bars[4]);
122
123#ifdef DEBUG
124        for(i=0; i<5; i++){
125                printk("PCI: BAR%d: 0x%x\n\r",i,cc1.bars[i]);
126        }
127#endif
128
129        /* Set up PCI ==> AMBA */
130        pcib = (void *)cc1.bars[0];
131        pcib->bar0 = 0xfc000000;
132/*      pcib->bar1 = 0xff000000;*/
133#ifdef BOARD_INFO
134        printk("Found CCHIP1 Board at 0x%lx\n\r",(unsigned int)pcib);
135#endif
136
137        /* AMBA MAP cc1.bars[1] (in CPU) ==> 0xf0000000(remote amba address) */
138        cc1.amba_maps[0].size = 0x04000000;
139        cc1.amba_maps[0].cpu_adr = cc1.bars[1];
140        cc1.amba_maps[0].remote_amba_adr = 0xfc000000;
141
142        /* Mark end of table */
143        cc1.amba_maps[1].size=0;
144        cc1.amba_maps[1].cpu_adr = 0;
145        cc1.amba_maps[1].remote_amba_adr = 0;
146
147        /* Enable I/O and Mem accesses */
148        pci_read_config_dword(bus, dev, fun, 0x4, &com1);
149        com1 |= 0x3;
150        pci_write_config_dword(bus, dev, fun, 0x4, com1);
151        pci_read_config_dword(bus, dev, fun, 0x4, &com1);
152
153        /* Set up AMBA Masters ==> PCI */
154        ambab = (void *)(cc1.bars[1]+0x400);
155#ifdef DEBUG
156        printk("AMBA: PCIBAR[%d]: 0x%x, 0x%x\n\r",0,ambab->bar0,pcib->bar0);
157        printk("AMBA: PCIBAR[%d]: 0x%x, 0x%x\n\r",1,ambab->bar1,pcib->bar1);
158        printk("AMBA: PCIBAR[%d]: 0x%x, 0x%x\n\r",2,ambab->bar2,pcib->bar2);
159#endif
160        ambab->ambabars[0] = 0x40000000; /* 0xe0000000(AMBA) ==> 0x40000000(PCI) ==> 0x40000000(AT697 AMBA) */
161
162        /* Scan bus for AMBA devices */
163        abus = &cc1.amba_bus;
164        memset(abus,0,sizeof(amba_confarea_type));
165        amba_scan(abus,cc1.bars[1]+0x3f00000,&cc1.amba_maps[0]);
166
167        /* Get number of amba masters */
168        amba_master_cnt = abus->ahbmst.devnr;
169#ifdef BOARD_INFO
170        printk("Found %d AMBA masters\n\r",amba_master_cnt);
171#endif
172        for(i=1; i<amba_master_cnt; i++){
173                ambab->ambabars[i] = 0x40000000;
174        }
175
176        /* Enable PCI Master */
177   pci_read_config_dword(bus, dev, fun, 0x4, &com1);
178   com1 |= 0x4;
179   pci_write_config_dword(bus, dev, fun, 0x4, com1);
180   pci_read_config_dword(bus, dev, fun, 0x4, &com1);
181
182        cc1.pcib  = pcib;
183        cc1.ambab = ambab;
184        cc1.bus = bus;
185        cc1.dev = dev;
186        cc1.fun = fun;
187
188        return 0;
189}
190
191#ifndef GAISLER_FTAHBRAM
192 #define GAISLER_FTAHBRAM 0x50
193#endif
194int init_onboard_sram(void){
195        amba_ahb_device ahb;
196        amba_apb_device apb;
197        unsigned int conf, size;
198
199        /* Find SRAM controller
200         * 1. AHB slave interface
201         * 2. APB slave interface
202         */
203        if ( amba_find_apbslv(&cc1.amba_bus,VENDOR_GAISLER,GAISLER_FTAHBRAM,&apb) != 1 ){
204                printk("On Board FT SRAM not found (APB)\n");
205                return -1;
206        }
207
208        if ( amba_find_ahbslv(&cc1.amba_bus,VENDOR_GAISLER,GAISLER_FTAHBRAM,&ahb) != 1 ){
209                printk("On Board FT SRAM not found (AHB)\n");
210                return -1;
211        }
212
213        /* We have found the controller.
214         * Get it going.
215         *
216         * Get size of SRAM
217         */
218        conf = *(unsigned int *)apb.start;
219        size = (conf >>10) & 0x7;
220
221        /* 2^x kb */
222        cc1.ftsram_size = 1<<size;
223        cc1.ftsram_start = ahb.start[0];
224        cc1.ftsram_end = size*1024 + cc1.ftsram_start;
225#ifdef BOARD_INFO
226        printk("Found FT AHB SRAM %dkb at 0x%lx\n",cc1.ftsram_size,cc1.ftsram_start);
227#endif
228        return 0;
229}
230
231int cchip1_register(void){
232
233        /* Init AT697 PCI Controller */
234        init_pci();
235
236        /* Find & init CChip board .
237         * Also scan AMBA Plug&Play info for us.
238         */
239        if ( init_pcif() ){
240                printk("Failed to initialize CCHIP board\n\r");
241                return -1;
242        }
243
244        /* Set interrupt common board stuff */
245        cchip1_irq_init();
246
247        /* Find on board SRAM */
248        if ( init_onboard_sram() ){
249                printk("Failed to register On Board SRAM. It is needed by b1553BRM\n");
250                return -1;
251        }
252
253        /* Register interrupt install functions */
254        b1553brm_pci_int_reg = cchip1_set_isr;
255        occan_pci_int_reg = cchip1_set_isr;
256        grspw_pci_int_reg = cchip1_set_isr;
257        apbuart_pci_int_reg = cchip1_set_isr;
258
259        /* register the BRM PCI driver, use 16k FTSRAM... */
260        if ( b1553brm_pci_register(&cc1.amba_bus,0,0,3,cc1.ftsram_start,0xffa00000) ){
261                printk("Failed to register BRM PCI driver\n");
262                return -1;
263        }
264
265        /* register the BRM PCI driver, no DMA memory... */
266        if ( occan_pci_register(&cc1.amba_bus) ){
267                printk("Failed to register OC_CAN PCI driver\n");
268                return -1;
269        }
270
271        /* register the GRSPW PCI driver, use malloc... */
272        if ( grspw_pci_register(&cc1.amba_bus,0,0xe0000000) ){
273                printk("Failed to register GRSPW PCI driver\n");
274                return -1;
275        }
276
277        /* register the APBUART PCI driver, no DMA memory */
278        if ( apbuart_pci_register(&cc1.amba_bus) ){
279                printk("Failed to register APBUART PCI driver\n");
280                return -1;
281        }
282
283        return 0;
284}
285
286static rtems_isr cchip1_interrupt_dispatcher(rtems_vector_number v);
287static unsigned int cchip1_spurious_cnt;
288
289typedef struct {
290        unsigned int (*handler)(int irqno, void *arg);
291        void *arg;
292} int_handler;
293
294static int_handler int_handlers[16];
295
296void cchip1_irq_init(void){
297
298        /* Configure AT697 ioport bit 7 to input pci irq */
299  regs->PIO_Direction &= ~(1<<7);
300  regs->PIO_Interrupt  = 0x87;          /* level sensitive */
301
302  /* Set up irq controller (mask all IRQs) */
303        cc1.pcib->imask = 0x0000;
304        cc1.pcib->ipend = 0;
305        cc1.pcib->iclear = 0xffff;
306        cc1.pcib->iforce = 0;
307        cc1.pcib->ilevel = 0x0;
308
309        memset(int_handlers,0,sizeof(int_handlers));
310
311        /* Reset spurious counter */
312        cchip1_spurious_cnt = 0;
313
314        /* Register interrupt handler */
315        set_vector(cchip1_interrupt_dispatcher,LEON_TRAP_TYPE(CCHIP_IRQ),1);
316}
317
318void cchip1_set_isr(void *handler, int irqno, void *arg){
319        int_handlers[irqno].handler = handler;
320        int_handlers[irqno].arg = arg;
321#ifdef DEBUG
322        printk("Registering IRQ %d to 0x%lx(%d,0x%lx)\n\r",irqno,(unsigned int)handler,irqno,(unsigned int)arg);
323#endif
324        cc1.pcib->imask |= 1<<irqno; /* Enable the registered IRQ */
325}
326
327static rtems_isr cchip1_interrupt_dispatcher(rtems_vector_number v){
328        unsigned int pending = READ_REG(&cc1.pcib->ipend);
329        unsigned int (*handler)(int irqno, void *arg);
330        unsigned int clr = pending;
331        int irq=1;
332
333        if ( !pending ){
334#ifdef PRINT_SPURIOUS
335                printk("Spurious IRQ %d: %d\n",v,cchip1_spurious_cnt);
336#endif
337                cchip1_spurious_cnt++;
338                return;
339        }
340#ifdef DEBUG_IRQS
341  printk("CCIRQ: 0x%x\n",(unsigned int)pending);
342#endif
343        /* IRQ 0 doesn't exist */
344        irq=1;
345        pending = pending>>1;
346
347        while ( pending ){
348                if ( (pending & 1) && (handler=int_handlers[irq].handler) ){
349                        handler(irq,int_handlers[irq].arg);
350                }
351                irq++;
352                pending = pending>>1;
353        }
354
355        cc1.pcib->iclear = clr;
356
357        /*LEON_Clear_interrupt( brd->irq );*/
358}
Note: See TracBrowser for help on using the repository browser.