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

Last change on this file since 11f3b9a was 11f3b9a, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 26, 2018 at 2:55:38 PM

bsps/sparc: Add grlib_malloc(), grlib_calloc()

This avoids a dependency to errno in device driver code.

  • Property mode set to 100644
File size: 18.6 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 = grlib_calloc(1, sizeof(*priv));
384        if ( !priv )
385                return DRVMGR_NOMEM;
386
387        dev->priv = priv;
388        priv->dev = dev;
389
390        /* Determine number of configurations */
391        resources_cnt = get_resarray_count(gr_rasta_adcdac_resources);
392
393        /* Generate Device prefix */
394
395        strcpy(priv->prefix, "/dev/rastaadcdac0");
396        priv->prefix[16] += dev->minor_drv;
397        mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO);
398        priv->prefix[17] = '/';
399        priv->prefix[18] = '\0';
400
401        priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo;
402        priv->pcidev = devinfo->pcidev;
403        bar0 = devinfo->resources[0].address;
404        bar0_size = devinfo->resources[0].size;
405        bar1 = devinfo->resources[1].address;
406        bar1_size = devinfo->resources[1].size;
407        printk("\n\n--- GR-RASTA-ADCDAC[%d] ---\n", dev->minor_drv);
408        printk(" PCI BUS: 0x%x, SLOT: 0x%x, FUNCTION: 0x%x\n",
409                PCI_DEV_EXPAND(priv->pcidev));
410        printk(" PCI VENDOR: 0x%04x, DEVICE: 0x%04x\n",
411                devinfo->id.vendor, devinfo->id.device);
412        printk(" PCI BAR[0]: 0x%lx - 0x%lx\n", bar0, bar0 + bar0_size - 1);
413        printk(" PCI BAR[1]: 0x%lx - 0x%lx\n", bar1, bar1 + bar1_size - 1);
414        printk(" IRQ: %d\n\n\n", devinfo->irq);
415
416        /* all neccessary space assigned to GR-RASTA-ADCDAC target? */
417        if ((bar0_size == 0) || (bar1_size == 0))
418                return DRVMGR_ENORES;
419
420        /* Initialize spin-lock for this PCI perihperal device. This is to
421         * protect the Interrupt Controller Registers. The genirq layer is
422         * protecting its own internals and ISR dispatching.
423         */
424        SPIN_INIT(&priv->devlock, priv->prefix);
425
426        /* Let user override which PCI address the AHB masters of the
427         * RASTA-ADCDAC board access when doing DMA to CPU RAM. The AHB masters
428         * access the PCI Window of the AMBA bus, the MSB 4-bits of that address
429         * is translated according this config option before the address
430         * goes out on the PCI bus.
431         * Only the 4 MSB bits have an effect;
432         */
433        value = drvmgr_dev_key_get(priv->dev, "ahbmst2pci", DRVMGR_KT_INT);
434        if (value)
435                priv->ahbmst2pci_map = value->i;
436        else
437                priv->ahbmst2pci_map = AHBMST2PCIADR; /* default */
438
439        priv->genirq = genirq_init(16);
440        if ( priv->genirq == NULL ) {
441                free(priv);
442                dev->priv = NULL;
443                return DRVMGR_FAIL;
444        }
445
446        if ( (status = gr_rasta_adcdac_hw_init1(priv)) != 0 ) {
447                genirq_destroy(priv->genirq);
448                free(priv);
449                dev->priv = NULL;
450                printk(" Failed to initialize GR-RASTA-ADCDAC HW: %d\n", status);
451                return DRVMGR_FAIL;
452        }
453
454        /* Init amba bus */
455        priv->config.abus = &priv->abus;
456        priv->config.ops = &ambapp_rasta_adcdac_ops;
457        priv->config.maps_up = &priv->bus_maps_up[0];
458        priv->config.maps_down = &priv->bus_maps_down[0];
459        if ( priv->dev->minor_drv < resources_cnt ) {
460                priv->config.resources = gr_rasta_adcdac_resources[priv->dev->minor_drv];
461        } else {
462                priv->config.resources = NULL;
463        }
464
465        /* Create and register AMBA PnP bus. */
466        return ambapp_bus_register(dev, &priv->config);
467}
468
469int gr_rasta_adcdac_init2(struct drvmgr_dev *dev)
470{
471        struct gr_rasta_adcdac_priv *priv = dev->priv;
472
473        /* Clear any old interrupt requests */
474        drvmgr_interrupt_clear(dev, 0);
475
476        /* Enable System IRQ so that GR-RASTA-ADCDAC PCI target interrupt
477         * goes through.
478         *
479         * It is important to enable it in stage init2. If interrupts were
480         * enabled in init1 this might hang the system when more than one
481         * PCI board is connected, this is because PCI interrupts might
482         * be shared and PCI board 2 have not initialized and might
483         * therefore drive interrupt already when entering init1().
484         */
485        drvmgr_interrupt_register(
486                dev,
487                0,
488                "gr_rasta_adcdac",
489                gr_rasta_adcdac_isr, 
490                (void *)priv);
491
492        return gr_rasta_adcdac_hw_init2(priv);
493}
494
495int ambapp_rasta_adcdac_int_register(
496        struct drvmgr_dev *dev,
497        int irq,
498        const char *info,
499        drvmgr_isr handler,
500        void *arg)
501{
502        struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv;
503        SPIN_IRQFLAGS(irqflags);
504        int status;
505        void *h;
506
507        h = genirq_alloc_handler(handler, arg);
508        if ( h == NULL )
509                return DRVMGR_FAIL;
510
511        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
512
513        status = genirq_register(priv->genirq, irq, h);
514        if ( status == 0 ) {
515                /* Clear IRQ for first registered handler */
516                priv->irq->iclear = (1<<irq);
517        } else if ( status == 1 )
518                status = 0;
519
520        if (status != 0) {
521                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
522                genirq_free_handler(h);
523                return DRVMGR_FAIL;
524        }
525
526        status = genirq_enable(priv->genirq, irq, handler, arg);
527        if ( status == 0 ) {
528                /* Enable IRQ for first enabled handler only */
529                priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
530        } else if ( status == 1 )
531                status = 0;
532
533        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
534
535        return status;
536}
537
538int ambapp_rasta_adcdac_int_unregister(
539        struct drvmgr_dev *dev,
540        int irq,
541        drvmgr_isr isr,
542        void *arg)
543{
544        struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv;
545        SPIN_IRQFLAGS(irqflags);
546        int status;
547        void *handler;
548
549        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
550
551        status = genirq_disable(priv->genirq, irq, isr, arg);
552        if ( status == 0 ) {
553                /* Disable IRQ only when no enabled handler exists */
554                priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
555        }
556
557        handler = genirq_unregister(priv->genirq, irq, isr, arg);
558        if ( handler == NULL )
559                status = DRVMGR_FAIL;
560        else
561                status = DRVMGR_OK;
562
563        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
564
565        if (handler)
566                genirq_free_handler(handler);
567
568        return status;
569}
570
571int ambapp_rasta_adcdac_int_unmask(
572        struct drvmgr_dev *dev,
573        int irq)
574{
575        struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv;
576        SPIN_IRQFLAGS(irqflags);
577
578        DBG("RASTA-ADCDAC IRQ %d: unmask\n", irq);
579
580        if ( genirq_check(priv->genirq, irq) )
581                return DRVMGR_EINVAL;
582
583        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
584
585        /* Enable IRQ for first enabled handler only */
586        priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
587
588        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
589
590        return DRVMGR_OK;
591}
592
593int ambapp_rasta_adcdac_int_mask(
594        struct drvmgr_dev *dev,
595        int irq)
596{
597        struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv;
598        SPIN_IRQFLAGS(irqflags);
599
600        DBG("RASTA-ADCDAC IRQ %d: mask\n", irq);
601
602        if ( genirq_check(priv->genirq, irq) )
603                return DRVMGR_EINVAL;
604
605        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
606
607        /* Disable/mask IRQ */
608        priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
609
610        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
611
612        return DRVMGR_OK;
613}
614
615int ambapp_rasta_adcdac_int_clear(
616        struct drvmgr_dev *dev,
617        int irq)
618{
619        struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv;
620
621        if ( genirq_check(priv->genirq, irq) )
622                return DRVMGR_FAIL;
623
624        priv->irq->iclear = (1<<irq);
625
626        return DRVMGR_OK;
627}
628
629int ambapp_rasta_adcdac_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
630{
631        struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv;
632
633        /* Device name prefix pointer, skip /dev */
634        params->dev_prefix = &priv->prefix[5];
635
636        return 0;
637}
638
639void gr_rasta_adcdac_print_dev(struct drvmgr_dev *dev, int options)
640{
641        struct gr_rasta_adcdac_priv *priv = dev->priv;
642        struct pci_dev_info *devinfo = priv->devinfo;
643        uint32_t bar0, bar1, bar0_size, bar1_size;
644
645        /* Print */
646        printf("--- GR-RASTA-ADCDAC [bus 0x%x, dev 0x%x, fun 0x%x] ---\n",
647                PCI_DEV_EXPAND(priv->pcidev));
648
649        bar0 = devinfo->resources[0].address;
650        bar0_size = devinfo->resources[0].size;
651        bar1 = devinfo->resources[1].address;
652        bar1_size = devinfo->resources[1].size;
653
654        printf(" PCI BAR[0]: 0x%lx - 0x%lx\n", bar0, bar0 + bar0_size - 1);
655        printf(" PCI BAR[1]: 0x%lx - 0x%lx\n", bar1, bar1 + bar1_size - 1);
656        printf(" IRQ REGS:        0x%x\n", (unsigned int)priv->irq);
657        printf(" IRQ:             %d\n", devinfo->irq);
658        printf(" PCI REVISION:    %d\n", devinfo->rev);
659        printf(" FREQ:            %d Hz\n", priv->version->amba_freq_hz);
660        printf(" IMASK:           0x%08x\n", priv->irq->mask[0]);
661        printf(" IPEND:           0x%08x\n", priv->irq->ipend);
662
663        /* Print amba config */
664        if ( options & RASTA_ADCDAC_OPTIONS_AMBA ) {
665                ambapp_print(&priv->abus, 10);
666        }
667#if 0
668        /* Print IRQ handlers and their arguments */
669        if ( options & RASTA_ADCDAC_OPTIONS_IRQ ) {
670                int i;
671                for(i=0; i<16; i++) {
672                        printf(" IRQ[%02d]:         0x%x, arg: 0x%x\n",
673                                i, (unsigned int)priv->isrs[i].handler, (unsigned int)priv->isrs[i].arg);
674                }
675        }
676#endif
677}
678
679void gr_rasta_adcdac_print(int options)
680{
681        struct pci_drv_info *drv = &gr_rasta_adcdac_info;
682        struct drvmgr_dev *dev;
683
684        dev = drv->general.dev;
685        while(dev) {
686                gr_rasta_adcdac_print_dev(dev, options);
687                dev = dev->next_in_drv;
688        }
689}
Note: See TracBrowser for help on using the repository browser.