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

5
Last change on this file since 56a7540 was 56a7540, checked in by Daniel Hellstrom <daniel@…>, on 01/23/18 at 09:12:36

leon: substitute printf with printk in driver init

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