source: rtems/c/src/lib/libbsp/sparc/shared/pci/gr_rasta_io.c @ 4d3e70f4

4.115
Last change on this file since 4d3e70f4 was 4d3e70f4, checked in by Daniel Hellstrom <daniel@…>, on 04/13/15 at 09:26:52

DRVMGR: KEY_TYPE now a enum drvmgr_kt

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