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

5
Last change on this file since d60d303c was d60d303c, checked in by Sebastian Huber <sebastian.huber@…>, on 04/20/18 at 11:33:24

bsps/sparc: Move shared files to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

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