source: rtems/bsps/sparc/shared/pci/gr_rasta_io.c @ 8f5abea

Last change on this file since 8f5abea was c05d7a9d, checked in by Sebastian Huber <sebastian.huber@…>, on Dec 21, 2018 at 8:43:27 PM

bsps/sparc: Fix warnings

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