source: rtems/bsps/sparc/shared/pci/gr_rasta_io.c @ 75e1009f

Last change on this file since 75e1009f 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: 24.2 KB
Line 
1/*  GR-RASTA-IO PCI Target driver.
2 *
3 *  COPYRIGHT (c) 2008.
4 *  Cobham Gaisler AB.
5 *
6 *  Configures the GR-RASTA-IO 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_io_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_io.h>
37
38#include <grlib_impl.h>
39
40/* Determines which PCI address the AHB masters will access, it should be
41 * set so that the masters can access the CPU RAM. Default is base of CPU RAM,
42 * CPU RAM is mapped 1:1 to PCI space.
43 */
44extern unsigned int _RAM_START;
45#define AHBMST2PCIADR (((unsigned int)&_RAM_START) & 0xf0000000)
46
47/* Offset from 0x80000000 (dual bus version) */
48#define AHB1_BASE_ADDR 0x80000000
49#define AHB1_IOAREA_BASE_ADDR 0x80100000
50#define AHB1_IOAREA_OFS (AHB1_IOAREA_BASE_ADDR - AHB1_BASE_ADDR)
51
52/* Second revision constants (GRPCI2) */
53#define GRPCI2_BAR0_TO_AHB_MAP 0x04  /* Fixme */
54#define GRPCI2_BAR1_TO_AHB_MAP 0x08  /* Fixme */
55#define GRPCI2_PCI_CONFIG      0x20  /* Fixme */
56
57
58/* #define DEBUG 1 */
59
60#ifdef DEBUG
61#define DBG(x...) printk(x)
62#else
63#define DBG(x...)
64#endif
65
66/* PCI ID */
67#define PCIID_VENDOR_GAISLER            0x1AC8
68
69int gr_rasta_io_init1(struct drvmgr_dev *dev);
70int gr_rasta_io_init2(struct drvmgr_dev *dev);
71void gr_rasta_io_isr (void *arg);
72
73struct grpci_regs {
74        volatile unsigned int cfg_stat;
75        volatile unsigned int bar0;
76        volatile unsigned int page0;
77        volatile unsigned int bar1;
78        volatile unsigned int page1;
79        volatile unsigned int iomap;
80        volatile unsigned int stat_cmd;
81};
82
83struct grpci2_regs {
84        volatile unsigned int ctrl;
85        volatile unsigned int statcap;
86        volatile unsigned int pcimstprefetch;
87        volatile unsigned int ahbtopciiomap;
88        volatile unsigned int dmactrl;
89        volatile unsigned int dmadesc;
90        volatile unsigned int dmachanact;
91        volatile unsigned int reserved;
92        volatile unsigned int pcibartoahb[6];
93        volatile unsigned int reserved2[2];
94        volatile unsigned int ahbtopcimemmap[16];
95        volatile unsigned int trcctrl;
96        volatile unsigned int trccntmode;
97        volatile unsigned int trcadpat;
98        volatile unsigned int trcadmask;
99        volatile unsigned int trcctrlsigpat;
100        volatile unsigned int trcctrlsigmask;
101        volatile unsigned int trcadstate;
102        volatile unsigned int trcctrlsigstate;
103};
104
105struct gr_rasta_io_ver {
106        const unsigned int      amba_freq_hz;   /* The frequency */
107        const unsigned int      amba_ioarea;    /* The address where the PnP IOAREA starts at */
108};
109
110/* Private data structure for driver */
111struct gr_rasta_io_priv {
112        /* Driver management */
113        struct drvmgr_dev               *dev;
114        char                            prefix[16];
115        SPIN_DECLARE(devlock);
116
117        /* PCI */
118        pci_dev_t                       pcidev;
119        struct pci_dev_info             *devinfo;
120        uint32_t                        ahbmst2pci_map;
121
122        /* IRQ */
123        genirq_t                        genirq;
124
125        /* GR-RASTA-IO */
126        struct gr_rasta_io_ver          *version;
127        struct irqmp_regs               *irq;
128        struct grpci_regs               *grpci;
129        struct grpci2_regs              *grpci2;
130        struct drvmgr_map_entry         bus_maps_down[3];
131        struct drvmgr_map_entry         bus_maps_up[2];
132
133        /* AMBA Plug&Play information on GR-RASTA-IO */
134        struct ambapp_bus               abus;
135        struct ambapp_mmap              amba_maps[4];
136        struct ambapp_config            config;
137};
138
139struct gr_rasta_io_ver gr_rasta_io_ver0 = {
140        .amba_freq_hz           = 30000000,
141        .amba_ioarea            = 0x80100000,
142};
143
144struct gr_rasta_io_ver gr_rasta_io_ver1 = {
145        .amba_freq_hz           = 50000000,
146        .amba_ioarea            = 0x80100000,
147};
148
149int ambapp_rasta_io_int_register(
150        struct drvmgr_dev *dev,
151        int irq,
152        const char *info,
153        drvmgr_isr handler,
154        void *arg);
155int ambapp_rasta_io_int_unregister(
156        struct drvmgr_dev *dev,
157        int irq,
158        drvmgr_isr handler,
159        void *arg);
160int ambapp_rasta_io_int_unmask(
161        struct drvmgr_dev *dev,
162        int irq);
163int ambapp_rasta_io_int_mask(
164        struct drvmgr_dev *dev,
165        int irq);
166int ambapp_rasta_io_int_clear(
167        struct drvmgr_dev *dev,
168        int irq);
169int ambapp_rasta_io_get_params(
170        struct drvmgr_dev *dev,
171        struct drvmgr_bus_params *params);
172
173struct ambapp_ops ambapp_rasta_io_ops = {
174        .int_register = ambapp_rasta_io_int_register,
175        .int_unregister = ambapp_rasta_io_int_unregister,
176        .int_unmask = ambapp_rasta_io_int_unmask,
177        .int_mask = ambapp_rasta_io_int_mask,
178        .int_clear = ambapp_rasta_io_int_clear,
179        .get_params = ambapp_rasta_io_get_params
180};
181
182struct drvmgr_drv_ops gr_rasta_io_ops = 
183{
184        .init = {gr_rasta_io_init1, gr_rasta_io_init2, NULL, NULL},
185        .remove = NULL,
186        .info = NULL
187};
188
189struct pci_dev_id_match gr_rasta_io_ids[] = 
190{
191        PCIID_DEVVEND(PCIID_VENDOR_GAISLER, PCIID_DEVICE_GR_RASTA_IO),
192        PCIID_DEVVEND(PCIID_VENDOR_GAISLER_OLD, PCIID_DEVICE_GR_RASTA_IO_OLD),
193        PCIID_END_TABLE /* Mark end of table */
194};
195
196struct pci_drv_info gr_rasta_io_info =
197{
198        {
199                DRVMGR_OBJ_DRV,                 /* Driver */
200                NULL,                           /* Next driver */
201                NULL,                           /* Device list */
202                DRIVER_PCI_GAISLER_RASTAIO_ID,  /* Driver ID */
203                "GR-RASTA-IO_DRV",              /* Driver Name */
204                DRVMGR_BUS_TYPE_PCI,            /* Bus Type */
205                &gr_rasta_io_ops,
206                NULL,                           /* Funcs */
207                0,                              /* No devices yet */
208                0,
209        },
210        &gr_rasta_io_ids[0]
211};
212
213/* Driver resources configuration for the AMBA bus on the GR-RASTA-IO board.
214 * It is declared weak so that the user may override it from the project file,
215 * if the default settings are not enough.
216 *
217 * The configuration consists of an array of configuration pointers, each
218 * pointer determine the configuration of one GR-RASTA-IO board. Pointer
219 * zero is for board0, pointer 1 for board1 and so on.
220 *
221 * The array must end with a NULL pointer.
222 */
223struct drvmgr_bus_res *gr_rasta_io_resources[] __attribute__((weak)) =
224{
225        NULL
226};
227
228void gr_rasta_io_register_drv(void)
229{
230        DBG("Registering GR-RASTA-IO PCI driver\n");
231        drvmgr_drv_register(&gr_rasta_io_info.general);
232}
233
234void gr_rasta_io_isr (void *arg)
235{
236        struct gr_rasta_io_priv *priv = arg;
237        unsigned int status, tmp;
238        int irq;
239        SPIN_ISR_IRQFLAGS(irqflags);
240
241        tmp = status = priv->irq->ipend;
242
243        /* DBG("GR-RASTA-IO: IRQ 0x%x\n",status); */
244
245        SPIN_LOCK(&priv->devlock, irqflags);
246        for(irq=0; irq<16; irq++) {
247                if ( status & (1<<irq) ) {
248                        genirq_doirq(priv->genirq, irq);
249                        priv->irq->iclear = (1<<irq);
250                        status &= ~(1<<irq);
251                        if ( status == 0 )
252                                break;
253                }
254        }
255        SPIN_UNLOCK(&priv->devlock, irqflags);
256
257        /* ACK interrupt, this is because PCI is Level, so the IRQ Controller still drives the IRQ. */
258        if ( tmp ) 
259                drvmgr_interrupt_clear(priv->dev, 0);
260
261        DBG("RASTA-IO-IRQ: 0x%x\n", tmp);
262}
263
264/* PCI Hardware (Revision 0 and 1) initialization */
265static int gr_rasta_io_hw_init(struct gr_rasta_io_priv *priv)
266{
267        unsigned int *page0 = NULL;
268        struct ambapp_dev *tmp;
269        struct ambapp_ahb_info *ahb;
270        struct pci_dev_info *devinfo = priv->devinfo;
271        uint32_t bar0, bar0_size;
272
273        bar0 = devinfo->resources[0].address;
274        bar0_size = devinfo->resources[0].size;
275        page0 = (unsigned int *)(bar0 + bar0_size/2); 
276
277        /* Point PAGE0 to start of Plug and Play information */
278        *page0 = priv->version->amba_ioarea & 0xff000000;
279
280#if 0
281        {
282                uint32_t data;
283                /* set parity error response */
284                pci_cfg_r32(priv->pcidev, PCIR_COMMAND, &data);
285                pci_cfg_w32(priv->pcidev, PCIR_COMMAND, (data|PCIM_CMD_PERRESPEN));
286        }
287#endif
288
289        /* Setup cache line size. Default cache line size will result in
290         * poor performance (256 word fetches), 0xff will set it according
291         * to the max size of the PCI FIFO.
292         */
293        pci_cfg_w8(priv->pcidev, PCIR_CACHELNSZ, 0xff);
294
295        /* Scan AMBA Plug&Play */
296
297        /* AMBA MAP bar0 (in CPU) ==> 0x80000000(remote amba address) */
298        priv->amba_maps[0].size = bar0_size/2;
299        priv->amba_maps[0].local_adr = bar0;
300        priv->amba_maps[0].remote_adr = AHB1_BASE_ADDR;
301
302        /* AMBA MAP bar1 (in CPU) ==> 0x40000000(remote amba address) */
303        priv->amba_maps[1].size = devinfo->resources[1].size;
304        priv->amba_maps[1].local_adr = devinfo->resources[1].address;
305        priv->amba_maps[1].remote_adr = 0x40000000;
306
307        /* Addresses not matching with map be untouched */
308        priv->amba_maps[2].size = 0xfffffff0;
309        priv->amba_maps[2].local_adr = 0;
310        priv->amba_maps[2].remote_adr = 0;
311
312        /* Mark end of table */
313        priv->amba_maps[3].size=0;
314        priv->amba_maps[3].local_adr = 0;
315        priv->amba_maps[3].remote_adr = 0;
316
317        /* Start AMBA PnP scan at first AHB bus */
318        ambapp_scan(&priv->abus,
319                        bar0 + (priv->version->amba_ioarea & ~0xff000000),
320                        NULL, &priv->amba_maps[0]);
321
322        /* Initialize Frequency of AMBA bus */
323        ambapp_freq_init(&priv->abus, NULL, priv->version->amba_freq_hz);
324
325        /* Point PAGE0 to start of APB area */
326        *page0 = AHB1_BASE_ADDR;       
327
328        /* Find GRPCI controller */
329        tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
330                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
331                                        VENDOR_GAISLER, GAISLER_PCIFBRG,
332                                        ambapp_find_by_idx, NULL);
333        if ( !tmp ) {
334                return -3;
335        }
336        priv->grpci = (struct grpci_regs *)((struct ambapp_apb_info *)tmp->devinfo)->start;
337
338        /* Set GRPCI mmap so that AMBA masters can access CPU-RAM over
339         * the PCI window.
340         */
341        priv->grpci->cfg_stat = (priv->grpci->cfg_stat & 0x0fffffff) |
342                                (priv->ahbmst2pci_map & 0xf0000000);
343        priv->grpci->page1 = 0x40000000;
344
345        /* Find IRQ controller, Clear all current IRQs */
346        tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
347                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
348                                        VENDOR_GAISLER, GAISLER_IRQMP,
349                                        ambapp_find_by_idx, NULL);
350        if ( !tmp ) {
351                return -4;
352        }
353        priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
354        /* Set up GR-RASTA-IO irq controller */
355        priv->irq->mask[0] = 0;
356        priv->irq->iclear = 0xffff;
357        priv->irq->ilevel = 0;
358
359        /* DOWN streams translation table */
360        priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
361        priv->bus_maps_down[0].size = priv->amba_maps[0].size;
362        priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
363        priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
364
365        priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA";
366        priv->bus_maps_down[1].size = priv->amba_maps[1].size;
367        priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr;
368        priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr;
369
370        /* Mark end of translation table */
371        priv->bus_maps_down[2].size = 0;
372
373        /* Find GRPCI controller AHB Slave interface */
374        tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
375                                        (OPTIONS_ALL|OPTIONS_AHB_SLVS),
376                                        VENDOR_GAISLER, GAISLER_PCIFBRG,
377                                        ambapp_find_by_idx, NULL);
378        if ( !tmp ) {
379                return -5;
380        }
381        ahb = (struct ambapp_ahb_info *)tmp->devinfo;
382
383        /* UP streams translation table */
384        priv->bus_maps_up[0].name = "AMBA GRPCI Window";
385        priv->bus_maps_up[0].size = ahb->mask[0]; /* AMBA->PCI Window on GR-RASTA-IO board */
386        priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
387        priv->bus_maps_up[0].to_adr = (void *)
388                                        (priv->ahbmst2pci_map & 0xf0000000);
389
390        /* Mark end of translation table */
391        priv->bus_maps_up[1].size = 0;
392
393        /* Successfully registered the RASTA board */
394        return 0;
395}
396
397/* PCI Hardware (Revision 1) initialization */
398static int gr_rasta_io2_hw_init(struct gr_rasta_io_priv *priv)
399{
400        int i;
401        uint32_t data;
402        unsigned int ctrl;
403        uint8_t tmp2;
404        struct ambapp_dev *tmp;
405        struct ambapp_ahb_info *ahb;
406        uint8_t cap_ptr;
407        pci_dev_t pcidev = priv->pcidev;
408        struct pci_dev_info *devinfo = priv->devinfo;
409
410        /* Check capabilities list bit */
411        pci_cfg_r8(pcidev, PCIR_STATUS, &tmp2);
412
413        if (!((tmp2 >> 4) & 1)) {
414                /* Capabilities list not available which it should be in the
415                 * GRPCI2
416                 */
417                return -3;
418        }
419
420        /* Read capabilities pointer */
421        pci_cfg_r8(pcidev, PCIR_CAP_PTR, &cap_ptr);
422
423        /* Set AHB address mappings for target PCI bars
424         * BAR0: 16MB  : Mapped to I/O at 0x80000000
425         * BAR1: 256MB : Mapped to MEM at 0x40000000
426         */
427        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR0_TO_AHB_MAP, AHB1_BASE_ADDR);
428        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR1_TO_AHB_MAP, 0x40000000);
429
430        /* Set PCI bus to be same endianess as PCI system */
431        pci_cfg_r32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, &data);
432        if (pci_endian == PCI_BIG_ENDIAN)
433                data = data & 0xFFFFFFFE;
434        else
435                data = data | 0x00000001;
436        pci_cfg_w32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, data);
437
438#if 0
439        /* set parity error response */
440        pci_cfg_r32(pcidev, PCIR_COMMAND, &data);
441        pci_cfg_w32(pcidev, PCIR_COMMAND, (data|PCIM_CMD_PERRESPEN));
442#endif
443
444        /* Scan AMBA Plug&Play */
445
446        /* AMBA MAP bar0 (in PCI) ==> 0x40000000 (remote amba address) */
447        priv->amba_maps[0].size = devinfo->resources[0].size;
448        priv->amba_maps[0].local_adr = devinfo->resources[0].address;
449        priv->amba_maps[0].remote_adr = AHB1_BASE_ADDR;
450
451        /* AMBA MAP bar0 (in PCI) ==> 0x80000000 (remote amba address) */
452        priv->amba_maps[1].size = devinfo->resources[1].size;
453        priv->amba_maps[1].local_adr = devinfo->resources[1].address;
454        priv->amba_maps[1].remote_adr = 0x40000000;
455
456        /* Addresses not matching with map be untouched */
457        priv->amba_maps[2].size = 0xfffffff0;
458        priv->amba_maps[2].local_adr = 0;
459        priv->amba_maps[2].remote_adr = 0;
460
461        /* Mark end of table */
462        priv->amba_maps[3].size=0;
463
464        /* Start AMBA PnP scan at first AHB bus */
465        ambapp_scan(
466                &priv->abus,
467                devinfo->resources[0].address + AHB1_IOAREA_OFS,
468                NULL,
469                &priv->amba_maps[0]);
470
471        /* Initialize Frequency of AMBA bus. The AMBA bus runs at same
472         * frequency as PCI bus
473         */
474        ambapp_freq_init(&priv->abus, NULL, priv->version->amba_freq_hz);
475
476        /* Find IRQ controller, Clear all current IRQs */
477        tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
478                                (OPTIONS_ALL|OPTIONS_APB_SLVS),
479                                VENDOR_GAISLER, GAISLER_IRQMP,
480                                ambapp_find_by_idx, NULL);
481        if ( !tmp ) {
482                return -4;
483        }
484        priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
485        /* Set up GR-RASTA-SPW-ROUTER irq controller */
486        priv->irq->mask[0] = 0;
487        priv->irq->iclear = 0xffff;
488        priv->irq->ilevel = 0;
489
490        priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
491        priv->bus_maps_down[0].size = priv->amba_maps[0].size;
492        priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
493        priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
494        priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA";
495        priv->bus_maps_down[1].size = priv->amba_maps[1].size;
496        priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr;
497        priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr;
498        priv->bus_maps_down[2].size = 0;
499
500        /* Find GRPCI2 controller AHB Slave interface */
501        tmp = (void *)ambapp_for_each(&priv->abus,
502                                        (OPTIONS_ALL|OPTIONS_AHB_SLVS),
503                                        VENDOR_GAISLER, GAISLER_GRPCI2,
504                                        ambapp_find_by_idx, NULL);
505        if ( !tmp ) {
506                return -5;
507        }
508        ahb = (struct ambapp_ahb_info *)tmp->devinfo;
509        priv->bus_maps_up[0].name = "AMBA GRPCI2 Window";
510        priv->bus_maps_up[0].size = ahb->mask[0]; /* AMBA->PCI Window on GR-RASTA-SPW-ROUTER board */
511        priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
512        priv->bus_maps_up[0].to_adr = (void *)
513                                (priv->ahbmst2pci_map & ~(ahb->mask[0]-1));
514        priv->bus_maps_up[1].size = 0;
515
516        /* Find GRPCI2 controller APB Slave interface */
517        tmp = (void *)ambapp_for_each(&priv->abus,
518                                        (OPTIONS_ALL|OPTIONS_APB_SLVS),
519                                        VENDOR_GAISLER, GAISLER_GRPCI2,
520                                        ambapp_find_by_idx, NULL);
521        if ( !tmp ) {
522                return -6;
523        }
524        priv->grpci2 = (struct grpci2_regs *)
525                ((struct ambapp_apb_info *)tmp->devinfo)->start;
526
527        /* Set AHB to PCI mapping for all AMBA AHB masters */
528        for(i = 0; i < 16; i++) {
529                priv->grpci2->ahbtopcimemmap[i] = priv->ahbmst2pci_map &
530                                                        ~(ahb->mask[0]-1);
531        }
532
533        /* Make sure dirq(0) sampling is enabled */
534        ctrl = priv->grpci2->ctrl;
535        ctrl = (ctrl & 0xFFFFFF0F) | (1 << 4);
536        priv->grpci2->ctrl = ctrl;
537
538        /* Successfully registered the RASTA-SPW-ROUTER board */
539        return 0;
540}
541
542static int gr_rasta_io_hw_init2(struct gr_rasta_io_priv *priv)
543{
544        /* Enable DMA by enabling PCI target as master */
545        pci_master_enable(priv->pcidev);
546
547        return DRVMGR_OK;
548}
549
550/* Called when a PCI target is found with the PCI device and vendor ID
551 * given in gr_rasta_io_ids[].
552 */
553int gr_rasta_io_init1(struct drvmgr_dev *dev)
554{
555        struct gr_rasta_io_priv *priv;
556        struct pci_dev_info *devinfo;
557        int status;
558        uint32_t bar0, bar1, bar0_size, bar1_size;
559        union drvmgr_key_value *value;
560        int resources_cnt;
561
562        priv = grlib_calloc(1, sizeof(*priv));
563        if ( !priv )
564                return DRVMGR_NOMEM;
565
566        dev->priv = priv;
567        priv->dev = dev;
568
569        /* Determine number of configurations */
570        resources_cnt = get_resarray_count(gr_rasta_io_resources);
571
572        /* Generate Device prefix */
573
574        strcpy(priv->prefix, "/dev/rastaio0");
575        priv->prefix[12] += dev->minor_drv;
576        mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO);
577        priv->prefix[13] = '/';
578        priv->prefix[14] = '\0';
579
580        priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo;
581        priv->pcidev = devinfo->pcidev;
582        bar0 = devinfo->resources[0].address;
583        bar0_size = devinfo->resources[0].size;
584        bar1 = devinfo->resources[1].address;
585        bar1_size = devinfo->resources[1].size;
586        printk("\n\n--- GR-RASTA-IO[%d] ---\n", dev->minor_drv);
587        printk(" PCI BUS: 0x%x, SLOT: 0x%x, FUNCTION: 0x%x\n",
588                PCI_DEV_EXPAND(priv->pcidev));
589        printk(" PCI VENDOR: 0x%04x, DEVICE: 0x%04x\n",
590                devinfo->id.vendor, devinfo->id.device);
591        printk(" PCI BAR[0]: 0x%lx - 0x%lx\n", bar0, bar0 + bar0_size - 1);
592        printk(" PCI BAR[1]: 0x%lx - 0x%lx\n", bar1, bar1 + bar1_size - 1);
593        printk(" IRQ: %d\n\n\n", devinfo->irq);
594
595        /* all neccessary space assigned to GR-RASTA-IO target? */
596        if ((bar0_size == 0) || (bar1_size == 0))
597                return DRVMGR_ENORES;
598
599        /* Initialize spin-lock for this PCI peripheral device. This is to
600         * protect the Interrupt Controller Registers. The genirq layer is
601         * protecting its own internals and ISR dispatching.
602         */
603        SPIN_INIT(&priv->devlock, priv->prefix);
604
605        /* Let user override which PCI address the AHB masters of the
606         * GR-RASTA-IO board access when doing DMA to CPU RAM. The AHB masters
607         * access the PCI Window of the AMBA bus, the MSB 4-bits of that address
608         * is translated according this config option before the address
609         * goes out on the PCI bus.
610         * Only the 4 MSB bits have an effect;
611         */
612        value = drvmgr_dev_key_get(priv->dev, "ahbmst2pci", DRVMGR_KT_INT);
613        if (value)
614                priv->ahbmst2pci_map = value->i;
615        else
616                priv->ahbmst2pci_map = AHBMST2PCIADR; /* default */     
617
618        priv->genirq = genirq_init(16);
619        if ( priv->genirq == NULL ) {
620                free(priv);
621                dev->priv = NULL;
622                return DRVMGR_FAIL;
623        }
624
625        /* Select version of GR-RASTA-IO board */
626        switch (devinfo->rev) {
627                case 0:
628                        priv->version = &gr_rasta_io_ver0;
629                        status = gr_rasta_io_hw_init(priv);
630                        break;
631                case 1:
632                        priv->version = &gr_rasta_io_ver1;
633                        status = gr_rasta_io_hw_init(priv);
634                        break;
635                case 2:
636                        priv->version = &gr_rasta_io_ver1; /* same cfg as 1 */
637                        status = gr_rasta_io2_hw_init(priv);
638                        break;
639                default:
640                        return -2;
641        }
642
643        if ( status != 0 ) {
644                genirq_destroy(priv->genirq);
645                free(priv);
646                dev->priv = NULL;
647                printk(" Failed to initialize GR-RASTA-IO HW: %d\n", status);
648                return DRVMGR_FAIL;
649        }
650
651        /* Init amba bus */
652        priv->config.abus = &priv->abus;
653        priv->config.ops = &ambapp_rasta_io_ops;
654        priv->config.maps_up = &priv->bus_maps_up[0];
655        priv->config.maps_down = &priv->bus_maps_down[0];
656        if ( priv->dev->minor_drv < resources_cnt ) {
657                priv->config.resources = gr_rasta_io_resources[priv->dev->minor_drv];
658        } else {
659                priv->config.resources = NULL;
660        }
661
662        /* Create and register AMBA PnP bus. */
663        return ambapp_bus_register(dev, &priv->config);
664}
665
666int gr_rasta_io_init2(struct drvmgr_dev *dev)
667{
668        struct gr_rasta_io_priv *priv = dev->priv;
669
670        /* Clear any old interrupt requests */
671        drvmgr_interrupt_clear(dev, 0);
672
673        /* Enable System IRQ so that GR-RASTA-IO PCI target interrupt goes
674         * through.
675         *
676         * It is important to enable it in stage init2. If interrupts were
677         * enabled in init1 this might hang the system when more than one
678         * PCI board is connected, this is because PCI interrupts might
679         * be shared and PCI board 2 have not initialized and
680         * might therefore drive interrupt already when entering init1().
681         */
682        drvmgr_interrupt_register(
683                dev,
684                0,
685                "gr_rasta_io",
686                gr_rasta_io_isr,
687                (void *)priv);
688
689        return gr_rasta_io_hw_init2(priv);
690}
691
692int ambapp_rasta_io_int_register(
693        struct drvmgr_dev *dev,
694        int irq,
695        const char *info,
696        drvmgr_isr handler,
697        void *arg)
698{
699        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
700        SPIN_IRQFLAGS(irqflags);
701        int status;
702        void *h;
703
704        h = genirq_alloc_handler(handler, arg);
705        if ( h == NULL )
706                return DRVMGR_FAIL;
707
708        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
709
710        status = genirq_register(priv->genirq, irq, h);
711        if ( status == 0 ) {
712                /* Clear IRQ for first registered handler */
713                priv->irq->iclear = (1<<irq);
714        } else if ( status == 1 )
715                status = 0;
716
717        if (status != 0) {
718                SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
719                genirq_free_handler(h);
720                return DRVMGR_FAIL;
721        }
722
723        status = genirq_enable(priv->genirq, irq, handler, arg);
724        if ( status == 0 ) {
725                /* Enable IRQ for first enabled handler only */
726                priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
727        } else if ( status == 1 )
728                status = 0;
729
730        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
731
732        return status;
733}
734
735int ambapp_rasta_io_int_unregister(
736        struct drvmgr_dev *dev,
737        int irq,
738        drvmgr_isr isr,
739        void *arg)
740{
741        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
742        SPIN_IRQFLAGS(irqflags);
743        int status;
744        void *handler;
745
746        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
747
748        status = genirq_disable(priv->genirq, irq, isr, arg);
749        if ( status == 0 ) {
750                /* Disable IRQ only when no enabled handler exists */
751                priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
752        }
753
754        handler = genirq_unregister(priv->genirq, irq, isr, arg);
755        if ( handler == NULL )
756                status = DRVMGR_FAIL;
757        else
758                status = DRVMGR_OK;
759
760        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
761
762        if (handler)
763                genirq_free_handler(handler);
764
765        return status;
766}
767
768int ambapp_rasta_io_int_unmask(
769        struct drvmgr_dev *dev,
770        int irq)
771{
772        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
773        SPIN_IRQFLAGS(irqflags);
774
775        DBG("RASTA-IO IRQ %d: unmask\n", irq);
776
777        if ( genirq_check(priv->genirq, irq) )
778                return DRVMGR_EINVAL;
779
780        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
781
782        /* Enable IRQ for first enabled handler only */
783        priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
784
785        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
786
787        return DRVMGR_OK;
788}
789
790int ambapp_rasta_io_int_mask(
791        struct drvmgr_dev *dev,
792        int irq)
793{
794        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
795        SPIN_IRQFLAGS(irqflags);
796
797        DBG("RASTA-IO IRQ %d: mask\n", irq);
798
799        if ( genirq_check(priv->genirq, irq) )
800                return DRVMGR_EINVAL;
801
802        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
803
804        /* Disable/mask IRQ */
805        priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
806
807        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
808
809        return DRVMGR_OK;
810}
811
812int ambapp_rasta_io_int_clear(
813        struct drvmgr_dev *dev,
814        int irq)
815{
816        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
817
818        if ( genirq_check(priv->genirq, irq) )
819                return DRVMGR_EINVAL;
820
821        priv->irq->iclear = (1<<irq);
822
823        return DRVMGR_OK;
824}
825
826int ambapp_rasta_io_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
827{
828        struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
829
830        /* Device name prefix pointer, skip /dev */
831        params->dev_prefix = &priv->prefix[5];
832
833        return 0;
834}
835
836void gr_rasta_io_print_dev(struct drvmgr_dev *dev, int options)
837{
838        struct gr_rasta_io_priv *priv = dev->priv;
839        struct pci_dev_info *devinfo = priv->devinfo;
840        uint32_t bar0, bar1, bar0_size, bar1_size;
841
842        /* Print */
843        printf("--- GR-RASTA-IO [bus 0x%x, dev 0x%x, fun 0x%x] ---\n",
844                PCI_DEV_EXPAND(priv->pcidev));
845
846        bar0 = devinfo->resources[0].address;
847        bar0_size = devinfo->resources[0].size;
848        bar1 = devinfo->resources[1].address;
849        bar1_size = devinfo->resources[1].size;
850
851        printf(" PCI BAR[0]: 0x%lx - 0x%lx\n", bar0, bar0 + bar0_size - 1);
852        printf(" PCI BAR[1]: 0x%lx - 0x%lx\n", bar1, bar1 + bar1_size - 1);
853        printf(" IRQ REGS:        0x%x\n", (unsigned int)priv->irq);
854        printf(" IRQ:             %d\n", devinfo->irq);
855        printf(" PCI REVISION:    %d\n", devinfo->rev);
856        printf(" FREQ:            %d Hz\n", priv->version->amba_freq_hz);
857        printf(" IMASK:           0x%08x\n", priv->irq->mask[0]);
858        printf(" IPEND:           0x%08x\n", priv->irq->ipend);
859
860        /* Print amba config */
861        if ( options & RASTA_IO_OPTIONS_AMBA ) {
862                ambapp_print(&priv->abus, 10);
863        }
864
865#if 0
866        /* Print IRQ handlers and their arguments */
867        if ( options & RASTA_IO_OPTIONS_IRQ ) {
868                int i;
869                for(i=0; i<16; i++) {
870                        printf(" IRQ[%02d]:         0x%x, arg: 0x%x\n",
871                                i, (unsigned int)priv->isrs[i].handler, (unsigned int)priv->isrs[i].arg);
872                }
873        }
874#endif
875}
876
877void gr_rasta_io_print(int options)
878{
879        struct pci_drv_info *drv = &gr_rasta_io_info;
880        struct drvmgr_dev *dev;
881
882        dev = drv->general.dev;
883        while(dev) {
884                gr_rasta_io_print_dev(dev, options);
885                dev = dev->next_in_drv;
886        }
887}
Note: See TracBrowser for help on using the repository browser.