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