source: rtems/c/src/lib/libbsp/sparc/leon2/cchip/cchip.c @ 133f3cce

4.115
Last change on this file since 133f3cce was 133f3cce, checked in by Toma Radu <radustoma@…>, on 12/03/13 at 20:26:51

leon2: improve doxygen

Add doxygen to the cchip.c & leon_open_eth.c files.

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