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

5
Last change on this file since 75e1009f was a7267241, checked in by Sebastian Huber <sebastian.huber@…>, on 11/26/18 at 14:44:25

bsps/sparc: Add and use <grlib_impl.h>

Reduce copy and paste.

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