source: rtems/c/src/lib/libbsp/sparc/shared/pci/gr_rasta_io.c @ 80b9c8ac

4.11
Last change on this file since 80b9c8ac was 80b9c8ac, checked in by Daniel Hellstrom <daniel@…>, on Dec 20, 2013 at 1:03:10 PM

GR-RASTA-IO: updated for new version

From this driver's point of view the major new thing is that the
GRPCI peripheral PCI bridge has been updated to GRPCI2, the second
version. This means that both Big and Little Endian systems are now
supported and autodetected on runtime.

  • Property mode set to 100644
File size: 23.6 KB
Line 
1/*  GR-RASTA-IO PCI Target driver.
2 *
3 *  COPYRIGHT (c) 2008.
4 *  Cobham Gaisler AB.
5 *
6 *  Configures the GR-RASTA-IO interface PCI board.
7 *  This driver provides a AMBA PnP bus by using the general part
8 *  of the AMBA PnP bus driver (ambapp_bus.c).
9 *
10 *  Driver resources for the AMBA PnP bus provided can be set using
11 *  gr_rasta_io_set_resources().
12 *
13 *  The license and distribution terms for this file may be
14 *  found in found in the file LICENSE in this distribution or at
15 *  http://www.rtems.com/license/LICENSE.
16 */
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <sys/types.h>
22#include <sys/stat.h>
23
24#include <bsp.h>
25#include <rtems/bspIo.h>
26#include <pci.h>
27
28#include <ambapp.h>
29#include <grlib.h>
30#include <drvmgr/drvmgr.h>
31#include <drvmgr/ambapp_bus.h>
32#include <drvmgr/pci_bus.h>
33#include <genirq.h>
34
35#include <gr_rasta_io.h>
36
37/* Determines which PCI address the AHB masters will access, it should be
38 * set so that the masters can access the CPU RAM. Default is base of CPU RAM,
39 * CPU RAM is mapped 1:1 to PCI space.
40 */
41extern unsigned int _RAM_START;
42#define AHBMST2PCIADR (((unsigned int)&_RAM_START) & 0xf0000000)
43
44/* Offset from 0x80000000 (dual bus version) */
45#define AHB1_BASE_ADDR 0x80000000
46#define AHB1_IOAREA_BASE_ADDR 0x80100000
47#define AHB1_IOAREA_OFS (AHB1_IOAREA_BASE_ADDR - AHB1_BASE_ADDR)
48
49/* Second revision constants (GRPCI2) */
50#define GRPCI2_BAR0_TO_AHB_MAP 0x04  /* Fixme */
51#define GRPCI2_BAR1_TO_AHB_MAP 0x08  /* Fixme */
52#define GRPCI2_PCI_CONFIG      0x20  /* Fixme */
53
54
55/* #define DEBUG 1 */
56
57#ifdef DEBUG
58#define DBG(x...) printk(x)
59#else
60#define DBG(x...)
61#endif
62
63/* PCI ID */
64#define PCIID_VENDOR_GAISLER            0x1AC8
65
66int gr_rasta_io_init1(struct drvmgr_dev *dev);
67int gr_rasta_io_init2(struct drvmgr_dev *dev);
68
69struct grpci_regs {
70        volatile unsigned int cfg_stat;
71        volatile unsigned int bar0;
72        volatile unsigned int page0;
73        volatile unsigned int bar1;
74        volatile unsigned int page1;
75        volatile unsigned int iomap;
76        volatile unsigned int stat_cmd;
77};
78
79struct grpci2_regs {
80        volatile unsigned int ctrl;
81        volatile unsigned int statcap;
82        volatile unsigned int pcimstprefetch;
83        volatile unsigned int ahbtopciiomap;
84        volatile unsigned int dmactrl;
85        volatile unsigned int dmadesc;
86        volatile unsigned int dmachanact;
87        volatile unsigned int reserved;
88        volatile unsigned int pcibartoahb[6];
89        volatile unsigned int reserved2[2];
90        volatile unsigned int ahbtopcimemmap[16];
91        volatile unsigned int trcctrl;
92        volatile unsigned int trccntmode;
93        volatile unsigned int trcadpat;
94        volatile unsigned int trcadmask;
95        volatile unsigned int trcctrlsigpat;
96        volatile unsigned int trcctrlsigmask;
97        volatile unsigned int trcadstate;
98        volatile unsigned int trcctrlsigstate;
99};
100
101struct gr_rasta_io_ver {
102        const unsigned int      amba_freq_hz;   /* The frequency */
103        const unsigned int      amba_ioarea;    /* The address where the PnP IOAREA starts at */
104};
105
106/* Private data structure for driver */
107struct gr_rasta_io_priv {
108        /* Driver management */
109        struct drvmgr_dev       *dev;
110        char                            prefix[16];
111
112        /* PCI */
113        pci_dev_t                       pcidev;
114        struct pci_dev_info             *devinfo;
115        uint32_t                        ahbmst2pci_map;
116
117        /* IRQ */
118        genirq_t                        genirq;
119
120        /* GR-RASTA-IO */
121        struct gr_rasta_io_ver          *version;
122        struct irqmp_regs               *irq;
123        struct grpci_regs               *grpci;
124        struct grpci2_regs              *grpci2;
125        struct drvmgr_map_entry         bus_maps_down[3];
126        struct drvmgr_map_entry         bus_maps_up[2];
127
128        /* AMBA Plug&Play information on GR-RASTA-IO */
129        struct ambapp_bus               abus;
130        struct ambapp_mmap              amba_maps[4];
131        struct ambapp_config            config;
132};
133
134struct gr_rasta_io_ver gr_rasta_io_ver0 = {
135        .amba_freq_hz           = 30000000,
136        .amba_ioarea            = 0x80100000,
137};
138
139struct gr_rasta_io_ver gr_rasta_io_ver1 = {
140        .amba_freq_hz           = 50000000,
141        .amba_ioarea            = 0x80100000,
142};
143
144int ambapp_rasta_io_int_register(
145        struct drvmgr_dev *dev,
146        int irq,
147        const char *info,
148        drvmgr_isr handler,
149        void *arg);
150int ambapp_rasta_io_int_unregister(
151        struct drvmgr_dev *dev,
152        int irq,
153        drvmgr_isr handler,
154        void *arg);
155int ambapp_rasta_io_int_unmask(
156        struct drvmgr_dev *dev,
157        int irq);
158int ambapp_rasta_io_int_mask(
159        struct drvmgr_dev *dev,
160        int irq);
161int ambapp_rasta_io_int_clear(
162        struct drvmgr_dev *dev,
163        int irq);
164int ambapp_rasta_io_get_params(
165        struct drvmgr_dev *dev,
166        struct drvmgr_bus_params *params);
167
168struct ambapp_ops ambapp_rasta_io_ops = {
169        .int_register = ambapp_rasta_io_int_register,
170        .int_unregister = ambapp_rasta_io_int_unregister,
171        .int_unmask = ambapp_rasta_io_int_unmask,
172        .int_mask = ambapp_rasta_io_int_mask,
173        .int_clear = ambapp_rasta_io_int_clear,
174        .get_params = ambapp_rasta_io_get_params
175};
176
177struct drvmgr_drv_ops gr_rasta_io_ops = 
178{
179        .init = {gr_rasta_io_init1, gr_rasta_io_init2, NULL, NULL},
180        .remove = NULL,
181        .info = NULL
182};
183
184struct pci_dev_id_match gr_rasta_io_ids[] = 
185{
186        PCIID_DEVVEND(PCIID_VENDOR_GAISLER, PCIID_DEVICE_GR_RASTA_IO),
187        PCIID_DEVVEND(PCIID_VENDOR_GAISLER_OLD, PCIID_DEVICE_GR_RASTA_IO_OLD),
188        PCIID_END_TABLE /* Mark end of table */
189};
190
191struct pci_drv_info gr_rasta_io_info =
192{
193        {
194                DRVMGR_OBJ_DRV,                 /* Driver */
195                NULL,                           /* Next driver */
196                NULL,                           /* Device list */
197                DRIVER_PCI_GAISLER_RASTAIO_ID,  /* Driver ID */
198                "GR-RASTA-IO_DRV",              /* Driver Name */
199                DRVMGR_BUS_TYPE_PCI,            /* Bus Type */
200                &gr_rasta_io_ops,
201                NULL,                           /* Funcs */
202                0,                              /* No devices yet */
203                0,
204        },
205        &gr_rasta_io_ids[0]
206};
207
208/* Driver resources configuration for the AMBA bus on the GR-RASTA-IO board.
209 * It is declared weak so that the user may override it from the project file,
210 * if the default settings are not enough.
211 *
212 * The configuration consists of an array of configuration pointers, each
213 * pointer determine the configuration of one GR-RASTA-IO board. Pointer
214 * zero is for board0, pointer 1 for board1 and so on.
215 *
216 * The array must end with a NULL pointer.
217 */
218struct drvmgr_bus_res *gr_rasta_io_resources[] __attribute__((weak)) =
219{
220        NULL
221};
222int gr_rasta_io_resources_cnt = 0;
223
224void gr_rasta_io_register_drv(void)
225{
226        DBG("Registering GR-RASTA-IO PCI driver\n");
227        drvmgr_drv_register(&gr_rasta_io_info.general);
228}
229
230void gr_rasta_io_isr (void *arg)
231{
232        struct gr_rasta_io_priv *priv = arg;
233        unsigned int status, tmp;
234        int irq;
235        tmp = status = priv->irq->ipend;
236
237        /* DBG("GR-RASTA-IO: IRQ 0x%x\n",status); */
238
239        for(irq=0; irq<16; irq++) {
240                if ( status & (1<<irq) ) {
241                        genirq_doirq(priv->genirq, irq);
242                        priv->irq->iclear = (1<<irq);
243                        status &= ~(1<<irq);
244                        if ( status == 0 )
245                                break;
246                }
247        }
248
249        /* ACK interrupt, this is because PCI is Level, so the IRQ Controller still drives the IRQ. */
250        if ( tmp ) 
251                drvmgr_interrupt_clear(priv->dev, 0);
252
253        DBG("RASTA-IO-IRQ: 0x%x\n", tmp);
254}
255
256/* PCI Hardware (Revision 0 and 1) initialization */
257int gr_rasta_io_hw_init(struct gr_rasta_io_priv *priv)
258{
259        unsigned int *page0 = NULL;
260        struct ambapp_dev *tmp;
261        int status;
262        struct ambapp_ahb_info *ahb;
263        struct pci_dev_info *devinfo = priv->devinfo;
264        uint32_t bar0, bar0_size;
265
266        bar0 = devinfo->resources[0].address;
267        bar0_size = devinfo->resources[0].size;
268        page0 = (unsigned int *)(bar0 + bar0_size/2); 
269
270        /* Point PAGE0 to start of Plug and Play information */
271        *page0 = priv->version->amba_ioarea & 0xff000000;
272
273#if 0
274        {
275                uint32_t data;
276                /* set parity error response */
277                pci_cfg_r32(priv->pcidev, PCI_COMMAND, &data);
278                pci_cfg_w32(priv->pcidev, PCI_COMMAND, (data|PCI_COMMAND_PARITY));
279        }
280#endif
281
282        /* Setup cache line size. Default cache line size will result in
283         * poor performance (256 word fetches), 0xff will set it according
284         * to the max size of the PCI FIFO.
285         */
286        pci_cfg_w8(priv->pcidev, PCI_CACHE_LINE_SIZE, 0xff);
287
288        /* Scan AMBA Plug&Play */
289
290        /* AMBA MAP bar0 (in CPU) ==> 0x80000000(remote amba address) */
291        priv->amba_maps[0].size = bar0_size/2;
292        priv->amba_maps[0].local_adr = bar0;
293        priv->amba_maps[0].remote_adr = AHB1_BASE_ADDR;
294
295        /* AMBA MAP bar1 (in CPU) ==> 0x40000000(remote amba address) */
296        priv->amba_maps[1].size = devinfo->resources[1].size;
297        priv->amba_maps[1].local_adr = devinfo->resources[1].address;
298        priv->amba_maps[1].remote_adr = 0x40000000;
299
300        /* Addresses not matching with map be untouched */
301        priv->amba_maps[2].size = 0xfffffff0;
302        priv->amba_maps[2].local_adr = 0;
303        priv->amba_maps[2].remote_adr = 0;
304
305        /* Mark end of table */
306        priv->amba_maps[3].size=0;
307        priv->amba_maps[3].local_adr = 0;
308        priv->amba_maps[3].remote_adr = 0;
309
310        /* Start AMBA PnP scan at first AHB bus */
311        ambapp_scan(&priv->abus,
312                        bar0 + (priv->version->amba_ioarea & ~0xff000000),
313                        NULL, &priv->amba_maps[0]);
314
315        /* Initialize Frequency of AMBA bus */
316        ambapp_freq_init(&priv->abus, NULL, priv->version->amba_freq_hz);
317
318        /* Point PAGE0 to start of APB area */
319        *page0 = AHB1_BASE_ADDR;       
320
321        /* Find GRPCI controller */
322        tmp = (void *)ambapp_for_each(&priv->abus,
323                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
324                                        VENDOR_GAISLER, GAISLER_PCIFBRG,
325                                        ambapp_find_by_idx, NULL);
326        if ( !tmp ) {
327                return -3;
328        }
329        priv->grpci = (struct grpci_regs *)((struct ambapp_apb_info *)tmp->devinfo)->start;
330
331        /* Set GRPCI mmap so that AMBA masters can access CPU-RAM over
332         * the PCI window.
333         */
334        priv->grpci->cfg_stat = (priv->grpci->cfg_stat & 0x0fffffff) |
335                                (priv->ahbmst2pci_map & 0xf0000000);
336        priv->grpci->page1 = 0x40000000;
337
338        /* Find IRQ controller, Clear all current IRQs */
339        tmp = (void *)ambapp_for_each(&priv->abus,
340                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
341                                        VENDOR_GAISLER, GAISLER_IRQMP,
342                                        ambapp_find_by_idx, NULL);
343        if ( !tmp ) {
344                return -4;
345        }
346        priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
347        /* Set up GR-RASTA-IO irq controller */
348        priv->irq->mask[0] = 0;
349        priv->irq->iclear = 0xffff;
350        priv->irq->ilevel = 0;
351
352        /* DOWN streams translation table */
353        priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
354        priv->bus_maps_down[0].size = priv->amba_maps[0].size;
355        priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
356        priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
357
358        priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA";
359        priv->bus_maps_down[1].size = priv->amba_maps[1].size;
360        priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr;
361        priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr;
362
363        /* Mark end of translation table */
364        priv->bus_maps_down[2].size = 0;
365
366        /* Find GRPCI controller AHB Slave interface */
367        tmp = (void *)ambapp_for_each(&priv->abus,
368                                        (OPTIONS_ALL|OPTIONS_AHB_SLVS),
369                                        VENDOR_GAISLER, GAISLER_PCIFBRG,
370                                        ambapp_find_by_idx, NULL);
371        if ( !tmp ) {
372                return -5;
373        }
374        ahb = (struct ambapp_ahb_info *)tmp->devinfo;
375
376        /* UP streams translation table */
377        priv->bus_maps_up[0].name = "AMBA GRPCI Window";
378        priv->bus_maps_up[0].size = ahb->mask[0]; /* AMBA->PCI Window on GR-RASTA-IO board */
379        priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
380        priv->bus_maps_up[0].to_adr = (void *)
381                                        (priv->ahbmst2pci_map & 0xf0000000);
382
383        /* Mark end of translation table */
384        priv->bus_maps_up[1].size = 0;
385
386        /* Successfully registered the RASTA board */
387        return 0;
388}
389
390/* PCI Hardware (Revision 1) initialization */
391int gr_rasta_io2_hw_init(struct gr_rasta_io_priv *priv)
392{
393        int i;
394        uint32_t data;
395        unsigned int ctrl;
396        uint8_t tmp2;
397        struct ambapp_dev *tmp;
398        int status;
399        struct ambapp_ahb_info *ahb;
400        uint8_t cap_ptr;
401        pci_dev_t pcidev = priv->pcidev;
402        struct pci_dev_info *devinfo = priv->devinfo;
403        unsigned int pci_freq_hz;
404
405        /* Check capabilities list bit */
406        pci_cfg_r8(pcidev, PCI_STATUS, &tmp2);
407
408        if (!((tmp2 >> 4) & 1)) {
409                /* Capabilities list not available which it should be in the
410                 * GRPCI2
411                 */
412                return -3;
413        }
414
415        /* Read capabilities pointer */
416        pci_cfg_r8(pcidev, PCI_CAP_PTR, &cap_ptr);
417
418        /* Set AHB address mappings for target PCI bars
419         * BAR0: 16MB  : Mapped to I/O at 0x80000000
420         * BAR1: 256MB : Mapped to MEM at 0x40000000
421         */
422        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR0_TO_AHB_MAP, AHB1_BASE_ADDR);
423        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR1_TO_AHB_MAP, 0x40000000);
424
425        /* Set PCI bus to be same endianess as PCI system */
426        pci_cfg_r32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, &data);
427        if (pci_endian == PCI_BIG_ENDIAN)
428                data = data & 0xFFFFFFFE;
429        else
430                data = data | 0x00000001;
431        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, data);
432
433#if 0
434        /* set parity error response */
435        pci_cfg_r32(pcidev, PCI_COMMAND, &data);
436        pci_cfg_w32(pcidev, PCI_COMMAND, (data|PCI_COMMAND_PARITY));
437#endif
438
439        /* Scan AMBA Plug&Play */
440
441        /* AMBA MAP bar0 (in PCI) ==> 0x40000000 (remote amba address) */
442        priv->amba_maps[0].size = devinfo->resources[0].size;
443        priv->amba_maps[0].local_adr = devinfo->resources[0].address;
444        priv->amba_maps[0].remote_adr = AHB1_BASE_ADDR;
445
446        /* AMBA MAP bar0 (in PCI) ==> 0x80000000 (remote amba address) */
447        priv->amba_maps[1].size = devinfo->resources[1].size;
448        priv->amba_maps[1].local_adr = devinfo->resources[1].address;
449        priv->amba_maps[1].remote_adr = 0x40000000;
450
451        /* Addresses not matching with map be untouched */
452        priv->amba_maps[2].size = 0xfffffff0;
453        priv->amba_maps[2].local_adr = 0;
454        priv->amba_maps[2].remote_adr = 0;
455
456        /* Mark end of table */
457        priv->amba_maps[3].size=0;
458
459        /* Start AMBA PnP scan at first AHB bus */
460        ambapp_scan(
461                &priv->abus,
462                devinfo->resources[0].address + AHB1_IOAREA_OFS,
463                NULL,
464                &priv->amba_maps[0]);
465
466        /* Initialize Frequency of AMBA bus. The AMBA bus runs at same
467         * frequency as PCI bus
468         */
469        ambapp_freq_init(&priv->abus, NULL, priv->version->amba_freq_hz);
470
471        /* Find IRQ controller, Clear all current IRQs */
472        tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
473                                (OPTIONS_ALL|OPTIONS_APB_SLVS),
474                                VENDOR_GAISLER, GAISLER_IRQMP,
475                                ambapp_find_by_idx, NULL);
476        if ( !tmp ) {
477                return -4;
478        }
479        priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
480        /* Set up GR-RASTA-SPW-ROUTER irq controller */
481        priv->irq->mask[0] = 0;
482        priv->irq->iclear = 0xffff;
483        priv->irq->ilevel = 0;
484
485        priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
486        priv->bus_maps_down[0].size = priv->amba_maps[0].size;
487        priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
488        priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
489        priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA";
490        priv->bus_maps_down[1].size = priv->amba_maps[1].size;
491        priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr;
492        priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr;
493        priv->bus_maps_down[2].size = 0;
494
495        /* Find GRPCI2 controller AHB Slave interface */
496        tmp = (void *)ambapp_for_each(&priv->abus,
497                                        (OPTIONS_ALL|OPTIONS_AHB_SLVS),
498                                        VENDOR_GAISLER, GAISLER_GRPCI2,
499                                        ambapp_find_by_idx, NULL);
500        if ( !tmp ) {
501                return -5;
502        }
503        ahb = (struct ambapp_ahb_info *)tmp->devinfo;
504        priv->bus_maps_up[0].name = "AMBA GRPCI2 Window";
505        priv->bus_maps_up[0].size = ahb->mask[0]; /* AMBA->PCI Window on GR-RASTA-SPW-ROUTER board */
506        priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
507        priv->bus_maps_up[0].to_adr = (void *)
508                                (priv->ahbmst2pci_map & ~(ahb->mask[0]-1));
509        priv->bus_maps_up[1].size = 0;
510
511        /* Find GRPCI2 controller APB Slave interface */
512        tmp = (void *)ambapp_for_each(&priv->abus,
513                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
514                                        VENDOR_GAISLER, GAISLER_GRPCI2,
515                                        ambapp_find_by_idx, NULL);
516        if ( !tmp ) {
517                return -6;
518        }
519        priv->grpci2 = (struct grpci2_regs *)
520                ((struct ambapp_apb_info *)tmp->devinfo)->start;
521
522        /* Set AHB to PCI mapping for all AMBA AHB masters */
523        for(i = 0; i < 16; i++) {
524                priv->grpci2->ahbtopcimemmap[i] = priv->ahbmst2pci_map &
525                                                        ~(ahb->mask[0]-1);
526        }
527
528        /* Make sure dirq(0) sampling is enabled */
529        ctrl = priv->grpci2->ctrl;
530        ctrl = (ctrl & 0xFFFFFF0F) | (1 << 4);
531        priv->grpci2->ctrl = ctrl;
532
533        /* Successfully registered the RASTA-SPW-ROUTER board */
534        return 0;
535}
536
537int gr_rasta_io_hw_init2(struct gr_rasta_io_priv *priv)
538{
539        /* Enable DMA by enabling PCI target as master */
540        pci_master_enable(priv->pcidev);
541
542        return DRVMGR_OK;
543}
544
545/* Called when a PCI target is found with the PCI device and vendor ID
546 * given in gr_rasta_io_ids[].
547 */
548int gr_rasta_io_init1(struct drvmgr_dev *dev)
549{
550        struct gr_rasta_io_priv *priv;
551        struct pci_dev_info *devinfo;
552        int status;
553        uint32_t bar0, bar1, bar0_size, bar1_size;
554        union drvmgr_key_value *value;
555
556        priv = malloc(sizeof(struct gr_rasta_io_priv));
557        if ( !priv )
558                return DRVMGR_NOMEM;
559
560        memset(priv, 0, sizeof(*priv));
561        dev->priv = priv;
562        priv->dev = dev;
563
564        /* Determine number of configurations */
565        if ( gr_rasta_io_resources_cnt == 0 ) {
566                while ( gr_rasta_io_resources[gr_rasta_io_resources_cnt] )
567                        gr_rasta_io_resources_cnt++;
568        }
569
570        /* Generate Device prefix */
571
572        strcpy(priv->prefix, "/dev/rastaio0");
573        priv->prefix[12] += dev->minor_drv;
574        mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO);
575        priv->prefix[13] = '/';
576        priv->prefix[14] = '\0';
577
578        priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo;
579        priv->pcidev = devinfo->pcidev;
580        bar0 = devinfo->resources[0].address;
581        bar0_size = devinfo->resources[0].size;
582        bar1 = devinfo->resources[1].address;
583        bar1_size = devinfo->resources[1].size;
584        printf("\n\n--- GR-RASTA-IO[%d] ---\n", dev->minor_drv);
585        printf(" PCI BUS: 0x%x, SLOT: 0x%x, FUNCTION: 0x%x\n",
586                PCI_DEV_EXPAND(priv->pcidev));
587        printf(" PCI VENDOR: 0x%04x, DEVICE: 0x%04x\n",
588                devinfo->id.vendor, devinfo->id.device);
589        printf(" PCI BAR[0]: 0x%lx - 0x%lx\n", bar0, bar0 + bar0_size - 1);
590        printf(" PCI BAR[1]: 0x%lx - 0x%lx\n", bar1, bar1 + bar1_size - 1);
591        printf(" IRQ: %d\n\n\n", devinfo->irq);
592
593        /* all neccessary space assigned to GR-RASTA-IO target? */
594        if ((bar0_size == 0) || (bar1_size == 0))
595                return DRVMGR_ENORES;
596
597        /* Let user override which PCI address the AHB masters of the
598         * GR-RASTA-IO board access when doing DMA to CPU RAM. The AHB masters
599         * access the PCI Window of the AMBA bus, the MSB 4-bits of that address
600         * is translated according this config option before the address
601         * goes out on the PCI bus.
602         * Only the 4 MSB bits have an effect;
603         */
604        value = drvmgr_dev_key_get(priv->dev, "ahbmst2pci", KEY_TYPE_INT);
605        if (value)
606                priv->ahbmst2pci_map = value->i;
607        else
608                priv->ahbmst2pci_map = AHBMST2PCIADR; /* default */     
609
610        priv->genirq = genirq_init(16);
611        if ( priv->genirq == NULL ) {
612                free(priv);
613                dev->priv = NULL;
614                return DRVMGR_FAIL;
615        }
616
617        /* Select version of GR-RASTA-IO board */
618        switch (devinfo->rev) {
619                case 0:
620                        priv->version = &gr_rasta_io_ver0;
621                        status = gr_rasta_io_hw_init(priv);
622                        break;
623                case 1:
624                        priv->version = &gr_rasta_io_ver1;
625                        status = gr_rasta_io_hw_init(priv);
626                        break;
627                case 2:
628                        priv->version = &gr_rasta_io_ver1; /* same cfg as 1 */
629                        status = gr_rasta_io2_hw_init(priv);
630                        break;
631                default:
632                        return -2;
633        }
634
635        if ( status != 0 ) {
636                genirq_destroy(priv->genirq);
637                free(priv);
638                dev->priv = NULL;
639                printf(" Failed to initialize GR-RASTA-IO HW: %d\n", status);
640                return DRVMGR_FAIL;
641        }
642
643        /* Init amba bus */
644        priv->config.abus = &priv->abus;
645        priv->config.ops = &ambapp_rasta_io_ops;
646        priv->config.maps_up = &priv->bus_maps_up[0];
647        priv->config.maps_down = &priv->bus_maps_down[0];
648        if ( priv->dev->minor_drv < gr_rasta_io_resources_cnt ) {
649                priv->config.resources = gr_rasta_io_resources[priv->dev->minor_drv];
650        } else {
651                priv->config.resources = NULL;
652        }
653
654        /* Create and register AMBA PnP bus. */
655        return ambapp_bus_register(dev, &priv->config);
656}
657
658int gr_rasta_io_init2(struct drvmgr_dev *dev)
659{
660        struct gr_rasta_io_priv *priv = dev->priv;
661
662        /* Clear any old interrupt requests */
663        drvmgr_interrupt_clear(dev, 0);
664
665        /* Enable System IRQ so that GR-RASTA-IO PCI target interrupt goes
666         * through.
667         *
668         * It is important to enable it in stage init2. If interrupts were
669         * enabled in init1 this might hang the system when more than one
670         * PCI board is connected, this is because PCI interrupts might
671         * be shared and PCI board 2 have not initialized and
672         * might therefore drive interrupt already when entering init1().
673         */
674        drvmgr_interrupt_register(
675                dev,
676                0,
677                "gr_rasta_io",
678                gr_rasta_io_isr,
679                (void *)priv);
680
681        return gr_rasta_io_hw_init2(priv);
682}
683
684int ambapp_rasta_io_int_register(
685        struct drvmgr_dev *dev,
686        int irq,
687        const char *info,
688        drvmgr_isr handler,
689        void *arg)
690{
691        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
692        rtems_interrupt_level level;
693        int status;
694
695        rtems_interrupt_disable(level);
696
697        status = genirq_register(priv->genirq, irq, handler, arg);
698        if ( status == 0 ) {
699                /* Clear IRQ for first registered handler */
700                priv->irq->iclear = (1<<irq);
701        } else if ( status == 1 )
702                status = 0;
703
704        if (status != 0) {
705                rtems_interrupt_enable(level);
706                return DRVMGR_FAIL;
707        }
708
709        status = genirq_enable(priv->genirq, irq, handler, arg);
710        if ( status == 0 ) {
711                /* Enable IRQ for first enabled handler only */
712                priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
713        } else if ( status == 1 )
714                status = 0;
715
716        rtems_interrupt_enable(level);
717
718        return status;
719}
720
721int ambapp_rasta_io_int_unregister(
722        struct drvmgr_dev *dev,
723        int irq,
724        drvmgr_isr isr,
725        void *arg)
726{
727        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
728        rtems_interrupt_level level;
729        int status;
730
731        rtems_interrupt_disable(level);
732
733        status = genirq_disable(priv->genirq, irq, isr, arg);
734        if ( status == 0 ) {
735                /* Disable IRQ only when no enabled handler exists */
736                priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
737        }
738
739        status = genirq_unregister(priv->genirq, irq, isr, arg);
740        if ( status != 0 )
741                status = DRVMGR_FAIL;
742
743        rtems_interrupt_enable(level);
744
745        return status;
746}
747
748int ambapp_rasta_io_int_unmask(
749        struct drvmgr_dev *dev,
750        int irq)
751{
752        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
753        rtems_interrupt_level level;
754
755        DBG("RASTA-IO IRQ %d: unmask\n", irq);
756
757        if ( genirq_check(priv->genirq, irq) )
758                return DRVMGR_EINVAL;
759
760        rtems_interrupt_disable(level);
761
762        /* Enable IRQ for first enabled handler only */
763        priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
764
765        rtems_interrupt_enable(level);
766
767        return DRVMGR_OK;
768}
769
770int ambapp_rasta_io_int_mask(
771        struct drvmgr_dev *dev,
772        int irq)
773{
774        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
775        rtems_interrupt_level level;
776
777        DBG("RASTA-IO IRQ %d: mask\n", irq);
778
779        if ( genirq_check(priv->genirq, irq) )
780                return DRVMGR_EINVAL;
781
782        rtems_interrupt_disable(level);
783
784        /* Disable/mask IRQ */
785        priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
786
787        rtems_interrupt_enable(level);
788
789        return DRVMGR_OK;
790}
791
792int ambapp_rasta_io_int_clear(
793        struct drvmgr_dev *dev,
794        int irq)
795{
796        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
797
798        if ( genirq_check(priv->genirq, irq) )
799                return DRVMGR_EINVAL;
800
801        priv->irq->iclear = (1<<irq);
802
803        return DRVMGR_OK;
804}
805
806int ambapp_rasta_io_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
807{
808        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
809
810        /* Device name prefix pointer, skip /dev */
811        params->dev_prefix = &priv->prefix[5];
812
813        return 0;
814}
815
816void gr_rasta_io_print_dev(struct drvmgr_dev *dev, int options)
817{
818        struct gr_rasta_io_priv *priv = dev->priv;
819        struct pci_dev_info *devinfo = priv->devinfo;
820        uint32_t bar0, bar1, bar0_size, bar1_size;
821
822        /* Print */
823        printf("--- GR-RASTA-IO [bus 0x%x, dev 0x%x, fun 0x%x] ---\n",
824                PCI_DEV_EXPAND(priv->pcidev));
825
826        bar0 = devinfo->resources[0].address;
827        bar0_size = devinfo->resources[0].size;
828        bar1 = devinfo->resources[1].address;
829        bar1_size = devinfo->resources[1].size;
830
831        printf(" PCI BAR[0]: 0x%lx - 0x%lx\n", bar0, bar0 + bar0_size - 1);
832        printf(" PCI BAR[1]: 0x%lx - 0x%lx\n", bar1, bar1 + bar1_size - 1);
833        printf(" IRQ REGS:        0x%x\n", (unsigned int)priv->irq);
834        printf(" IRQ:             %d\n", devinfo->irq);
835        printf(" PCI REVISION:    %d\n", devinfo->rev);
836        printf(" FREQ:            %d Hz\n", priv->version->amba_freq_hz);
837        printf(" IMASK:           0x%08x\n", priv->irq->mask[0]);
838        printf(" IPEND:           0x%08x\n", priv->irq->ipend);
839
840        /* Print amba config */
841        if ( options & RASTA_IO_OPTIONS_AMBA ) {
842                ambapp_print(&priv->abus, 10);
843        }
844
845#if 0
846        /* Print IRQ handlers and their arguments */
847        if ( options & RASTA_IO_OPTIONS_IRQ ) {
848                int i;
849                for(i=0; i<16; i++) {
850                        printf(" IRQ[%02d]:         0x%x, arg: 0x%x\n",
851                                i, (unsigned int)priv->isrs[i].handler, (unsigned int)priv->isrs[i].arg);
852                }
853        }
854#endif
855}
856
857void gr_rasta_io_print(int options)
858{
859        struct pci_drv_info *drv = &gr_rasta_io_info;
860        struct drvmgr_dev *dev;
861
862        dev = drv->general.dev;
863        while(dev) {
864                gr_rasta_io_print_dev(dev, options);
865                dev = dev->next_in_drv;
866        }
867}
Note: See TracBrowser for help on using the repository browser.