source: rtems/bsps/shared/grlib/pci/gr_rasta_adcdac.c @ 411c297

5
Last change on this file since 411c297 was 7eb606d3, checked in by Sebastian Huber <sebastian.huber@…>, on 12/22/18 at 17:31:04

grlib: Move source files

Update #3678.

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