source: rtems/bsps/sparc/shared/pci/gr_rasta_adcdac.c @ a7267241

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