source: rtems/bsps/sparc/shared/pci/gr_rasta_spw_router.c @ c05d7a9d

Last change on this file since c05d7a9d 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: 18.7 KB
Line 
1/*  GR-RASTA-SPW-ROUTER PCI Target driver.
2 *
3 *  COPYRIGHT (c) 2011.
4 *  Cobham Gaisler AB.
5 *
6 *  The license and distribution terms for this file may be
7 *  found in found in the file LICENSE in this distribution or at
8 *  http://www.rtems.org/license/LICENSE.
9 *
10 *  Configures the GR-RASTA-SPW-ROUTER interface PCI board.
11 *  This driver provides a AMBA PnP bus by using the general part
12 *  of the AMBA PnP bus driver (ambapp_bus.c). Based on the
13 *  GR-RASTA-IO driver.
14 */
15
16#include <inttypes.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <sys/types.h>
21#include <sys/stat.h>
22
23#include <bsp.h>
24#include <rtems/bspIo.h>
25#include <pci.h>
26
27#include <ambapp.h>
28#include <grlib.h>
29#include <drvmgr/drvmgr.h>
30#include <drvmgr/ambapp_bus.h>
31#include <drvmgr/pci_bus.h>
32#include <drvmgr/bspcommon.h>
33#include <bsp/genirq.h>
34#include <bsp/gr_rasta_spw_router.h>
35
36#include <grlib_impl.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
49#define GRPCI2_BAR0_TO_AHB_MAP 0x04  /* Fixme */
50#define GRPCI2_PCI_CONFIG      0x20  /* Fixme */
51
52/* #define DEBUG 1 */
53
54#ifdef DEBUG
55#define DBG(x...) printk(x)
56#else
57#define DBG(x...)
58#endif
59
60/* PCI ID */
61#define PCIID_VENDOR_GAISLER            0x1AC8
62
63int gr_rasta_spw_router_init1(struct drvmgr_dev *dev);
64int gr_rasta_spw_router_init2(struct drvmgr_dev *dev);
65void gr_rasta_spw_router_isr(void *arg);
66
67struct grpci2_regs {
68        volatile unsigned int ctrl;
69        volatile unsigned int statcap;
70        volatile unsigned int pcimstprefetch;
71        volatile unsigned int ahbtopciiomap;
72        volatile unsigned int dmactrl;
73        volatile unsigned int dmadesc;
74        volatile unsigned int dmachanact;
75        volatile unsigned int reserved;
76        volatile unsigned int pcibartoahb[6];
77        volatile unsigned int reserved2[2];
78        volatile unsigned int ahbtopcimemmap[16];
79        volatile unsigned int trcctrl;
80        volatile unsigned int trccntmode;
81        volatile unsigned int trcadpat;
82        volatile unsigned int trcadmask;
83        volatile unsigned int trcctrlsigpat;
84        volatile unsigned int trcctrlsigmask;
85        volatile unsigned int trcadstate;
86        volatile unsigned int trcctrlsigstate;
87};
88
89struct gr_rasta_spw_router_ver {
90        const unsigned int      amba_freq_hz;   /* The frequency */
91        const unsigned int      amba_ioarea;    /* The address where the PnP IOAREA starts at */
92};
93
94/* Private data structure for driver */
95struct gr_rasta_spw_router_priv {
96        /* Driver management */
97        struct drvmgr_dev       *dev;
98        char                    prefix[20];
99        SPIN_DECLARE(devlock);
100
101        /* PCI */
102        pci_dev_t               pcidev;
103        struct pci_dev_info     *devinfo;
104        uint32_t                ahbmst2pci_map;
105
106        /* IRQ */
107        genirq_t                genirq;
108
109        /* GR-RASTA-SPW-ROUTER */
110        struct gr_rasta_spw_router_ver  *version;
111        struct irqmp_regs       *irq;
112        struct grpci2_regs      *grpci2;
113        struct drvmgr_map_entry bus_maps_up[2];
114        struct drvmgr_map_entry bus_maps_down[2];
115
116        /* AMBA Plug&Play information on GR-RASTA-SPW-ROUTER */
117        struct ambapp_bus       abus;
118        struct ambapp_mmap      amba_maps[3];
119        struct ambapp_config    config;
120};
121
122struct gr_rasta_spw_router_ver gr_rasta_spw_router_ver0 = {
123        .amba_freq_hz           = 50000000,
124        .amba_ioarea            = 0xfff00000,
125};
126
127int ambapp_rasta_spw_router_int_register(
128        struct drvmgr_dev *dev,
129        int irq,
130        const char *info,
131        drvmgr_isr handler,
132        void *arg);
133int ambapp_rasta_spw_router_int_unregister(
134        struct drvmgr_dev *dev,
135        int irq,
136        drvmgr_isr handler,
137        void *arg);
138int ambapp_rasta_spw_router_int_unmask(
139        struct drvmgr_dev *dev,
140        int irq);
141int ambapp_rasta_spw_router_int_mask(
142        struct drvmgr_dev *dev,
143        int irq);
144int ambapp_rasta_spw_router_int_clear(
145        struct drvmgr_dev *dev,
146        int irq);
147int ambapp_rasta_spw_router_get_params(
148        struct drvmgr_dev *dev,
149        struct drvmgr_bus_params *params);
150
151struct ambapp_ops ambapp_rasta_spw_router_ops = {
152        .int_register = ambapp_rasta_spw_router_int_register,
153        .int_unregister = ambapp_rasta_spw_router_int_unregister,
154        .int_unmask = ambapp_rasta_spw_router_int_unmask,
155        .int_mask = ambapp_rasta_spw_router_int_mask,
156        .int_clear = ambapp_rasta_spw_router_int_clear,
157        .get_params = ambapp_rasta_spw_router_get_params
158};
159
160struct drvmgr_drv_ops gr_rasta_spw_router_ops = 
161{
162        .init = {gr_rasta_spw_router_init1, gr_rasta_spw_router_init2, NULL, NULL},
163        .remove = NULL,
164        .info = NULL
165};
166
167struct pci_dev_id_match gr_rasta_spw_router_ids[] =
168{
169        PCIID_DEVVEND(PCIID_VENDOR_GAISLER, PCIID_DEVICE_GR_RASTA_SPW_RTR),
170        PCIID_END_TABLE /* Mark end of table */
171};
172
173struct pci_drv_info gr_rasta_spw_router_info =
174{
175        {
176                DRVMGR_OBJ_DRV,                 /* Driver */
177                NULL,                           /* Next driver */
178                NULL,                           /* Device list */
179                DRIVER_PCI_GAISLER_RASTA_SPW_ROUTER_ID, /* Driver ID */
180                "GR-RASTA-SPW_ROUTER_DRV",      /* Driver Name */
181                DRVMGR_BUS_TYPE_PCI,            /* Bus Type */
182                &gr_rasta_spw_router_ops,
183                NULL,                           /* Funcs */
184                0,                              /* No devices yet */
185                sizeof(struct gr_rasta_spw_router_priv),
186        },
187        &gr_rasta_spw_router_ids[0]
188};
189
190/* Driver resources configuration for the AMBA bus on the GR-RASTA-SPW-ROUTER board.
191 * It is declared weak so that the user may override it from the project file,
192 * if the default settings are not enough.
193 *
194 * The configuration consists of an array of configuration pointers, each
195 * pointer determine the configuration of one GR-RASTA-SPW-ROUTER board. Pointer
196 * zero is for board0, pointer 1 for board1 and so on.
197 *
198 * The array must end with a NULL pointer.
199 */
200struct drvmgr_bus_res *gr_rasta_spw_router_resources[] __attribute__((weak)) =
201{
202        NULL
203};
204
205void gr_rasta_spw_router_register_drv(void)
206{
207        DBG("Registering GR-RASTA-SPW-ROUTER PCI driver\n");
208        drvmgr_drv_register(&gr_rasta_spw_router_info.general);
209}
210
211void gr_rasta_spw_router_isr(void *arg)
212{
213        struct gr_rasta_spw_router_priv *priv = arg;
214        unsigned int status, tmp;
215        int irq;
216        SPIN_ISR_IRQFLAGS(irqflags);
217
218        tmp = status = priv->irq->ipend;
219
220        /* DBG("GR-RASTA-SPW-ROUTER: IRQ 0x%x\n",status); */
221
222        SPIN_LOCK(&priv->devlock, irqflags);
223        for(irq=0; irq<16; irq++) {
224                if ( status & (1<<irq) ) {
225                        genirq_doirq(priv->genirq, irq);
226                        priv->irq->iclear = (1<<irq);
227                        status &= ~(1<<irq);
228                        if ( status == 0 )
229                                break;
230                }
231        }
232        SPIN_UNLOCK(&priv->devlock, irqflags);
233
234        /* ACK interrupt, this is because PCI is Level, so the IRQ Controller
235         * still drives the IRQ
236         */
237        if ( tmp ) 
238                drvmgr_interrupt_clear(priv->dev, 0);
239
240        DBG("RASTA-SPW_ROUTER-IRQ: 0x%x\n", tmp);
241}
242
243static int gr_rasta_spw_router_hw_init(struct gr_rasta_spw_router_priv *priv)
244{
245        int i;
246        uint32_t data;
247        unsigned int ctrl;
248        uint8_t tmp2;
249        struct ambapp_dev *tmp;
250        struct ambapp_ahb_info *ahb;
251        uint8_t cap_ptr;
252        pci_dev_t pcidev = priv->pcidev;
253        struct pci_dev_info *devinfo = priv->devinfo;
254
255        /* Select version of GR-RASTA-SPW-ROUTER board. Currently only one
256         * version
257         */
258        switch (devinfo->rev) {
259                case 0:
260                        priv->version = &gr_rasta_spw_router_ver0;
261                        break;
262                default:
263                        return -2;
264        }
265
266        /* Check capabilities list bit */
267        pci_cfg_r8(pcidev, PCIR_STATUS, &tmp2);
268
269        if (!((tmp2 >> 4) & 1)) {
270                /* Capabilities list not available which it should be in the GRPCI2 */
271                return -3;
272        }
273
274        /* Read capabilities pointer */
275        pci_cfg_r8(pcidev, PCIR_CAP_PTR, &cap_ptr);
276
277        /* Set AHB address mappings for target PCI bars */
278        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR0_TO_AHB_MAP, 0xffe00000);  /* APB bus, AHB I/O bus 2 MB */ 
279
280        /* Set PCI bus to be big endian */
281        pci_cfg_r32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, &data);
282        data = data & 0xFFFFFFFE;
283        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, data);
284
285#if 0
286        /* set parity error response */
287        pci_cfg_r32(pcidev, PCIR_COMMAND, &data);
288        pci_cfg_w32(pcidev, PCIR_COMMAND, (data|PCIM_CMD_PERRESPEN));
289#endif
290
291        /* Scan AMBA Plug&Play */
292
293        /* AMBA MAP bar0 (in router) ==> 0xffe00000(remote amba address) */
294        priv->amba_maps[0].size = devinfo->resources[0].size;
295        priv->amba_maps[0].local_adr = devinfo->resources[0].address;
296        priv->amba_maps[0].remote_adr = 0xffe00000;
297
298        /* Addresses not matching with map be untouched */
299        priv->amba_maps[1].size = 0xfffffff0;
300        priv->amba_maps[1].local_adr = 0;
301        priv->amba_maps[1].remote_adr = 0;
302
303        /* Mark end of table */
304        priv->amba_maps[2].size=0;
305
306        /* Start AMBA PnP scan at first AHB bus */
307        ambapp_scan(
308                &priv->abus,
309                devinfo->resources[0].address + 0x100000,
310                NULL,
311                &priv->amba_maps[0]);
312
313        /* Initialize Frequency of AMBA bus */
314        ambapp_freq_init(&priv->abus, NULL, priv->version->amba_freq_hz);
315
316        /* Find IRQ controller, Clear all current IRQs */
317        tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
318                                (OPTIONS_ALL|OPTIONS_APB_SLVS),
319                                VENDOR_GAISLER, GAISLER_IRQMP,
320                                ambapp_find_by_idx, NULL);
321        if ( !tmp ) {
322                return -4;
323        }
324        priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
325        /* Set up GR-RASTA-SPW-ROUTER irq controller */
326        priv->irq->mask[0] = 0;
327        priv->irq->iclear = 0xffff;
328        priv->irq->ilevel = 0;
329
330        priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
331        priv->bus_maps_down[0].size = priv->amba_maps[0].size;
332        priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
333        priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
334        priv->bus_maps_down[1].size = 0;
335
336        /* Find GRPCI2 controller AHB Slave interface */
337        tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
338                                        (OPTIONS_ALL|OPTIONS_AHB_SLVS),
339                                        VENDOR_GAISLER, GAISLER_GRPCI2,
340                                        ambapp_find_by_idx, NULL);
341        if ( !tmp ) {
342                return -5;
343        }
344        ahb = (struct ambapp_ahb_info *)tmp->devinfo;
345        priv->bus_maps_up[0].name = "AMBA GRPCI2 Window";
346        priv->bus_maps_up[0].size = ahb->mask[0]; /* AMBA->PCI Window on GR-RASTA-SPW-ROUTER board */
347        priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
348        priv->bus_maps_up[0].to_adr = (void *)
349                                (priv->ahbmst2pci_map & ~(ahb->mask[0]-1));
350        priv->bus_maps_up[1].size = 0;
351
352        /* Find GRPCI2 controller APB Slave interface */
353        tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
354                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
355                                        VENDOR_GAISLER, GAISLER_GRPCI2,
356                                        ambapp_find_by_idx, NULL);
357        if ( !tmp ) {
358                return -6;
359        }
360        priv->grpci2 = (struct grpci2_regs *)
361                ((struct ambapp_apb_info *)tmp->devinfo)->start;
362
363        /* Set AHB to PCI mapping for all AMBA AHB masters */
364        for(i = 0; i < 16; i++) {
365                priv->grpci2->ahbtopcimemmap[i] = priv->ahbmst2pci_map &
366                                                        ~(ahb->mask[0]-1);
367        }
368
369        /* Make sure dirq(0) sampling is enabled */
370        ctrl = priv->grpci2->ctrl;
371        ctrl = (ctrl & 0xFFFFFF0F) | (1 << 4);
372        priv->grpci2->ctrl = ctrl;
373
374        /* Successfully registered the RASTA-SPW-ROUTER board */
375        return 0;
376}
377
378static int gr_rasta_spw_router_hw_init2(struct gr_rasta_spw_router_priv *priv)
379{
380        /* Enable DMA by enabling PCI target as master */
381        pci_master_enable(priv->pcidev);
382
383        return DRVMGR_OK;
384}
385
386/* Called when a PCI target is found with the PCI device and vendor ID
387 * given in gr_rasta_spw_router_ids[].
388 */
389int gr_rasta_spw_router_init1(struct drvmgr_dev *dev)
390{
391        struct gr_rasta_spw_router_priv *priv;
392        struct pci_dev_info *devinfo;
393        int status;
394        uint32_t bar0, bar0_size;
395        union drvmgr_key_value *value;
396        int resources_cnt;
397
398        priv = dev->priv;
399        if (!priv)
400                return DRVMGR_NOMEM;
401
402        memset(priv, 0, sizeof(*priv));
403        dev->priv = priv;
404        priv->dev = dev;
405
406        /* Determine number of configurations */
407        resources_cnt = get_resarray_count(gr_rasta_spw_router_resources);
408
409        /* Generate Device prefix */
410
411        strcpy(priv->prefix, "/dev/spwrouter0");
412        priv->prefix[14] += dev->minor_drv;
413        mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO);
414        priv->prefix[15] = '/';
415        priv->prefix[16] = '\0';
416
417        priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo;
418        priv->pcidev = devinfo->pcidev;
419        bar0 = devinfo->resources[0].address;
420        bar0_size = devinfo->resources[0].size;
421        printk("\n\n--- GR-RASTA-SPW-ROUTER[%d] ---\n", dev->minor_drv);
422        printk(" PCI BUS: 0x%x, SLOT: 0x%x, FUNCTION: 0x%x\n",
423                PCI_DEV_EXPAND(priv->pcidev));
424        printk(" PCI VENDOR: 0x%04x, DEVICE: 0x%04x\n",
425                devinfo->id.vendor, devinfo->id.device);
426        printk(" PCI BAR[0]: 0x%08" PRIx32 " - 0x%08" PRIx32 "\n",
427                bar0, bar0 + bar0_size - 1);
428        printk(" IRQ: %d\n\n\n", devinfo->irq);
429
430        /* all neccessary space assigned to GR-RASTA-SPW-ROUTER target? */
431        if (bar0_size == 0)
432                return DRVMGR_ENORES;
433
434        /* Initialize spin-lock for this PCI peripheral device. This is to
435         * protect the Interrupt Controller Registers. The genirq layer is
436         * protecting its own internals and ISR dispatching.
437         */
438        SPIN_INIT(&priv->devlock, priv->prefix);
439
440        /* Let user override which PCI address the AHB masters of the
441         * GR-RASTA-SPW board access when doing DMA to CPU RAM. The AHB masters
442         * access the PCI Window of the AMBA bus, the MSB 4-bits of that address
443         * is translated according this config option before the address
444         * goes out on the PCI bus.
445         * Only the 4 MSB bits have an effect;
446         */
447        value = drvmgr_dev_key_get(priv->dev, "ahbmst2pci", DRVMGR_KT_INT);
448        if (value)
449                priv->ahbmst2pci_map = value->i;
450        else
451                priv->ahbmst2pci_map = AHBMST2PCIADR; /* default */     
452
453        priv->genirq = genirq_init(16);
454        if ( priv->genirq == NULL )
455                return DRVMGR_FAIL;
456
457        if ((status = gr_rasta_spw_router_hw_init(priv)) != 0) {
458                genirq_destroy(priv->genirq);
459                printk(" Failed to initialize GR-RASTA-SPW-ROUTER HW: %d\n", status);
460                return DRVMGR_FAIL;
461        }
462
463        /* Init amba bus */
464        priv->config.abus = &priv->abus;
465        priv->config.ops = &ambapp_rasta_spw_router_ops;
466        priv->config.maps_up = &priv->bus_maps_up[0];
467        priv->config.maps_down = &priv->bus_maps_down[0];
468        if ( priv->dev->minor_drv < resources_cnt ) {
469                priv->config.resources = gr_rasta_spw_router_resources[priv->dev->minor_drv];
470        } else {
471                priv->config.resources = NULL;
472        }
473
474        /* Create and register AMBA PnP bus. */
475        return ambapp_bus_register(dev, &priv->config);
476}
477
478int gr_rasta_spw_router_init2(struct drvmgr_dev *dev)
479{
480        struct gr_rasta_spw_router_priv *priv = dev->priv;
481
482        /* Clear any old interrupt requests */
483        drvmgr_interrupt_clear(dev, 0);
484
485        /* Enable System IRQ so that GR-RASTA-SPW-ROUTER PCI target interrupt
486         * goes through.
487         *
488         * It is important to enable it in stage init2. If interrupts were
489         * enabled in init1 this might hang the system when more than one
490         * PCI board is connected, this is because PCI interrupts might
491         * be shared and PCI board 2 have not initialized and
492         * might therefore drive interrupt already when entering init1().
493         */
494        drvmgr_interrupt_register(
495                dev,
496                0,
497                "gr_rasta_spw_router",
498                gr_rasta_spw_router_isr,
499                (void *)priv);
500
501        return gr_rasta_spw_router_hw_init2(priv);
502}
503
504int ambapp_rasta_spw_router_int_register(
505        struct drvmgr_dev *dev,
506        int irq,
507        const char *info,
508        drvmgr_isr handler,
509        void *arg)
510{
511        struct gr_rasta_spw_router_priv *priv = dev->parent->dev->priv;
512        SPIN_IRQFLAGS(irqflags);
513        int status;
514        void *h;
515
516        h = genirq_alloc_handler(handler, arg);
517        if ( h == NULL )
518                return DRVMGR_FAIL;
519
520        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
521
522        status = genirq_register(priv->genirq, irq, h);
523        if (status == 0) {
524                /* Clear IRQ for first registered handler */
525                priv->irq->iclear = (1<<irq);
526        } else if (status == 1)
527                status = 0;
528
529        if (status != 0) {
530                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
531                genirq_free_handler(h);
532                return DRVMGR_FAIL;
533        }
534
535        status = genirq_enable(priv->genirq, irq, handler, arg);
536        if ( status == 0 ) {
537                /* Enable IRQ for first enabled handler only */
538                priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
539        } else if ( status == 1 )
540                status = 0;
541
542        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
543
544        return status;
545}
546
547int ambapp_rasta_spw_router_int_unregister(
548        struct drvmgr_dev *dev,
549        int irq,
550        drvmgr_isr isr,
551        void *arg)
552{
553        struct gr_rasta_spw_router_priv *priv = dev->parent->dev->priv;
554        SPIN_IRQFLAGS(irqflags);
555        int status;
556        void *handler;
557
558        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
559
560        status = genirq_disable(priv->genirq, irq, isr, arg);
561        if ( status == 0 ) {
562                /* Disable IRQ only when no enabled handler exists */
563                priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
564        }
565
566        handler = genirq_unregister(priv->genirq, irq, isr, arg);
567        if ( handler == NULL )
568                status = DRVMGR_FAIL;
569        else
570                status = DRVMGR_OK;
571
572        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
573
574        if (handler)
575                genirq_free_handler(handler);
576
577        return status;
578}
579
580int ambapp_rasta_spw_router_int_unmask(
581        struct drvmgr_dev *dev,
582        int irq)
583{
584        struct gr_rasta_spw_router_priv *priv = dev->parent->dev->priv;
585        SPIN_IRQFLAGS(irqflags);
586
587        DBG("RASTA-SPW-ROUTER IRQ %d: unmask\n", irq);
588
589        if ( genirq_check(priv->genirq, irq) )
590                return DRVMGR_EINVAL;
591
592        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
593
594        /* Enable IRQ for first enabled handler only */
595        priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
596
597        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
598
599        return DRVMGR_OK;
600}
601
602int ambapp_rasta_spw_router_int_mask(
603        struct drvmgr_dev *dev,
604        int irq)
605{
606        struct gr_rasta_spw_router_priv *priv = dev->parent->dev->priv;
607        SPIN_IRQFLAGS(irqflags);
608
609        DBG("RASTA-SPW-ROUTER IRQ %d: mask\n", irq);
610
611        if ( genirq_check(priv->genirq, irq) )
612                return DRVMGR_EINVAL;
613
614        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
615
616        /* Disable/mask IRQ */
617        priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
618
619        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
620
621        return DRVMGR_OK;
622}
623
624int ambapp_rasta_spw_router_int_clear(
625        struct drvmgr_dev *dev,
626        int irq)
627{
628        struct gr_rasta_spw_router_priv *priv = dev->parent->dev->priv;
629
630        if ( genirq_check(priv->genirq, irq) )
631                return DRVMGR_EINVAL;
632
633        priv->irq->iclear = (1<<irq);
634
635        return DRVMGR_OK;
636}
637
638int ambapp_rasta_spw_router_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
639{
640        struct gr_rasta_spw_router_priv *priv = dev->parent->dev->priv;
641
642        /* Device name prefix pointer, skip /dev */
643        params->dev_prefix = &priv->prefix[5];
644
645        return 0;
646}
647
648void gr_rasta_spw_router_print_dev(struct drvmgr_dev *dev, int options)
649{
650        struct gr_rasta_spw_router_priv *priv = dev->priv;
651        struct pci_dev_info *devinfo = priv->devinfo;
652        uint32_t bar0, bar0_size;
653
654        /* Print */
655        printf("--- GR-RASTA-SPW-ROUTER [bus 0x%x, dev 0x%x, fun 0x%x] ---\n",
656                PCI_DEV_EXPAND(priv->pcidev));
657
658        bar0 = devinfo->resources[0].address;
659        bar0_size = devinfo->resources[0].size;
660        printf(" PCI BAR[0]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
661                bar0, bar0 + bar0_size - 1);
662        printf(" IRQ REGS:        0x%" PRIxPTR "\n", (uintptr_t)priv->irq);
663        printf(" IRQ:             %d\n", devinfo->irq);
664        printf(" PCI REVISION:    %d\n", devinfo->rev);
665        printf(" FREQ:            %d Hz\n", priv->version->amba_freq_hz);
666        printf(" IMASK:           0x%08x\n", priv->irq->mask[0]);
667        printf(" IPEND:           0x%08x\n", priv->irq->ipend);
668
669        /* Print amba config */
670        if (options & RASTA_SPW_ROUTER_OPTIONS_AMBA)
671                ambapp_print(&priv->abus, 10);
672
673#if 0
674        /* Print IRQ handlers and their arguments */
675        if (options & RASTA_SPW_ROUTER_OPTIONS_IRQ) {
676                int i;
677                for(i = 0; i < 16; i++) {
678                        printf(" IRQ[%02d]:         0x%x, arg: 0x%x\n",
679                                i, (unsigned int)priv->isrs[i].handler,
680                                (unsigned int)priv->isrs[i].arg);
681                }
682        }
683#endif
684}
685
686void gr_rasta_spw_router_print(int options)
687{
688        struct pci_drv_info *drv = &gr_rasta_spw_router_info;
689        struct drvmgr_dev *dev;
690
691        dev = drv->general.dev;
692        while(dev) {
693                gr_rasta_spw_router_print_dev(dev, options);
694                dev = dev->next_in_drv;
695        }
696}
Note: See TracBrowser for help on using the repository browser.