source: rtems/c/src/lib/libbsp/sparc/shared/pci/grpci2.c @ 3e3fb0d

4.115
Last change on this file since 3e3fb0d was 46e41c98, checked in by Daniel Hellstrom <daniel@…>, on 12/16/11 at 13:10:57

LEON: replaced old BSP PCI layer with new generic libpci PCI layer

The old code used a limited PCI configuration library, which was
duplicated into LEON2 and LEON3 BSP pci.c together with respective
Host controller PCI interface.

The LEON2 BSP had support for AT697 PCI, and LEON3 for GRPCI PCI
Host controller. With this update new PCI Host drivers are added,
and all support the new generic PCI Library:

  • AT697 PCI (LEON2 only)
  • GRPCI (LEON2-GRLIB and LEON3)
  • GRPCI2 (LEON2-GRLIB and LEON3)
  • Actel PCIF GRLIB Wrapper (LEON3 only)

The LEON2 BSP is defined as big-endian PCI in bsp.h, since the
AT697 supports only big-endian PCI.

  • Property mode set to 100644
File size: 23.6 KB
Line 
1/*  GRLIB GRPCI2 PCI HOST driver.
2 *
3 *  COPYRIGHT (c) 2011
4 *  Cobham Gaisler AB.
5 *
6 *  The license and distribution terms for this file may be
7 *  found in found in the file LICENSE in this distribution or at
8 *  http://www.rtems.com/license/LICENSE.
9 */
10
11/* Configures the GRPCI2 core and initialize,
12 *  - the PCI Library (pci.c)
13 *  - the general part of the PCI Bus driver (pci_bus.c)
14 * 
15 * System interrupt assigned to PCI interrupt (INTA#..INTD#) is by
16 * default taken from Plug and Play, but may be overridden by the
17 * driver resources INTA#..INTD#. GRPCI2 handles differently depending
18 * on the design (4 different ways).
19 *
20 * GRPCI2 IRQ implementation notes
21 * -------------------------------
22 * Since the Driver Manager pci_bus layer implements IRQ by calling
23 * pci_interrupt_* which translates into BSP_shared_interrupt_*, and the
24 * root-bus also relies on BSP_shared_interrupt_*, it is safe for the GRPCI2
25 * driver to use the drvmgr_interrupt_* routines since they will be
26 * accessing the same routines in the end. Otherwise the GRPCI2 driver must
27 * have used the pci_interrupt_* routines.
28 */
29
30#include <stdlib.h>
31#include <stdio.h>
32#include <string.h>
33#include <rtems/bspIo.h>
34#include <libcpu/byteorder.h>
35#include <libcpu/access.h>
36#include <pci.h>
37#include <pci/cfg.h>
38
39#include <drvmgr/drvmgr.h>
40#include <drvmgr/ambapp_bus.h>
41#include <ambapp.h>
42#include <drvmgr/pci_bus.h>
43#include <grpci2.h>
44
45#ifndef IRQ_GLOBAL_PREPARE
46 #define IRQ_GLOBAL_PREPARE(level) rtems_interrupt_level level
47#endif
48
49#ifndef IRQ_GLOBAL_DISABLE
50 #define IRQ_GLOBAL_DISABLE(level) rtems_interrupt_disable(level)
51#endif
52
53#ifndef IRQ_GLOBAL_ENABLE
54 #define IRQ_GLOBAL_ENABLE(level) rtems_interrupt_enable(level)
55#endif
56
57/* If defined to 1 - byte twisting is enabled by default */
58#define DEFAULT_BT_ENABLED 0
59
60/* Interrupt assignment. Set to other value than 0xff in order to
61 * override defaults and plug&play information
62 */
63#ifndef GRPCI2_INTA_SYSIRQ
64 #define GRPCI2_INTA_SYSIRQ 0xff
65#endif
66#ifndef GRPCI2_INTB_SYSIRQ
67 #define GRPCI2_INTB_SYSIRQ 0xff
68#endif
69#ifndef GRPCI2_INTC_SYSIRQ
70 #define GRPCI2_INTC_SYSIRQ 0xff
71#endif
72#ifndef GRPCI2_INTD_SYSIRQ
73 #define GRPCI2_INTD_SYSIRQ 0xff
74#endif
75
76/*#define DEBUG 1*/
77
78#ifdef DEBUG
79#define DBG(x...) printk(x)
80#else
81#define DBG(x...)
82#endif
83
84#define PCI_INVALID_VENDORDEVICEID      0xffffffff
85#define PCI_MULTI_FUNCTION              0x80
86
87/*
88 * GRPCI2 APB Register MAP
89 */
90struct grpci2_regs {
91        volatile unsigned int ctrl;             /* 0x00 */
92        volatile unsigned int sts_cap;          /* 0x04 */
93        int res1;                               /* 0x08 */
94        volatile unsigned int io_map;           /* 0x0C */
95        volatile unsigned int dma_ctrl;         /* 0x10 */
96        volatile unsigned int dma_bdbase;       /* 0x14 */
97        int res2[2];                            /* 0x18 */
98        volatile unsigned int bars[6];          /* 0x20 */
99        int res3[2];                            /* 0x38 */
100        volatile unsigned int ahbmst_map[16];   /* 0x40 */
101};
102
103#define CTRL_BUS_BIT 16
104
105#define CTRL_SI (1<<27)
106#define CTRL_PE (1<<26)
107#define CTRL_EI (1<<25)
108#define CTRL_ER (1<<24)
109#define CTRL_BUS (0xff<<CTRL_BUS_BIT)
110#define CTRL_HOSTINT 0xf
111
112#define STS_HOST_BIT    31
113#define STS_MST_BIT     30
114#define STS_TAR_BIT     29
115#define STS_DMA_BIT     28
116#define STS_DI_BIT      27
117#define STS_HI_BIT      26
118#define STS_IRQMODE_BIT 24
119#define STS_TRACE_BIT   23
120#define STS_CFGERRVALID_BIT 20
121#define STS_CFGERR_BIT  19
122#define STS_INTTYPE_BIT 12
123#define STS_INTSTS_BIT  8
124#define STS_FDEPTH_BIT  2
125#define STS_FNUM_BIT    0
126
127#define STS_HOST        (1<<STS_HOST_BIT)
128#define STS_MST         (1<<STS_MST_BIT)
129#define STS_TAR         (1<<STS_TAR_BIT)
130#define STS_DMA         (1<<STS_DMA_BIT)
131#define STS_DI          (1<<STS_DI_BIT)
132#define STS_HI          (1<<STS_HI_BIT)
133#define STS_IRQMODE     (0x3<<STS_IRQMODE_BIT)
134#define STS_TRACE       (1<<STS_TRACE_BIT)
135#define STS_CFGERRVALID (1<<STS_CFGERRVALID_BIT)
136#define STS_CFGERR      (1<<STS_CFGERR_BIT)
137#define STS_INTTYPE     (0x3f<<STS_INTTYPE_BIT)
138#define STS_INTSTS      (0xf<<STS_INTSTS_BIT)
139#define STS_FDEPTH      (0x7<<STS_FDEPTH_BIT)
140#define STS_FNUM        (0x3<<STS_FNUM_BIT)
141
142#define STS_ISYSERR     (1<<17)
143#define STS_IDMA        (1<<16)
144#define STS_IDMAERR     (1<<15)
145#define STS_IMSTABRT    (1<<14)
146#define STS_ITGTABRT    (1<<13)
147#define STS_IPARERR     (1<<12)
148
149struct grpci2_bd_chan {
150        volatile unsigned int ctrl;     /* 0x00 DMA Control */
151        volatile unsigned int nchan;    /* 0x04 Next DMA Channel Address */
152        volatile unsigned int nbd;      /* 0x08 Next Data Descriptor in channel */
153        volatile unsigned int res;      /* 0x0C Reserved */
154};
155
156#define BD_CHAN_EN              0x80000000
157#define BD_CHAN_TYPE            0x00300000
158#define BD_CHAN_BDCNT           0x0000ffff
159#define BD_CHAN_EN_BIT          31
160#define BD_CHAN_TYPE_BIT        20
161#define BD_CHAN_BDCNT_BIT       0
162
163struct grpci2_bd_data {
164        volatile unsigned int ctrl;     /* 0x00 DMA Data Control */
165        volatile unsigned int pci_adr;  /* 0x04 PCI Start Address */
166        volatile unsigned int ahb_adr;  /* 0x08 AHB Start address */
167        volatile unsigned int next;     /* 0x0C Next Data Descriptor in channel */
168};
169
170#define BD_DATA_EN              0x80000000
171#define BD_DATA_IE              0x40000000
172#define BD_DATA_DR              0x20000000
173#define BD_DATA_TYPE            0x00300000
174#define BD_DATA_ER              0x00080000
175#define BD_DATA_LEN             0x0000ffff
176#define BD_DATA_EN_BIT          31
177#define BD_DATA_IE_BIT          30
178#define BD_DATA_DR_BIT          29
179#define BD_DATA_TYPE_BIT        20
180#define BD_DATA_ER_BIT          19
181#define BD_DATA_LEN_BIT         0
182
183/* GRPCI2 Capability */
184struct grpci2_cap_first {
185        unsigned int ctrl;
186        unsigned int pci2ahb_map[6];
187        unsigned int ext2ahb_map;
188        unsigned int io_map;
189        unsigned int pcibar_size[6];
190};
191#define CAP9_CTRL_OFS 0
192#define CAP9_BAR_OFS 0x4
193#define CAP9_IOMAP_OFS 0x20
194#define CAP9_BARSIZE_OFS 0x24
195
196struct grpci2_priv *grpci2priv = NULL;
197
198/* PCI Interrupt assignment. Connects an PCI interrupt pin (INTA#..INTD#)
199 * to a system interrupt number.
200 */
201unsigned char grpci2_pci_irq_table[4] =
202{
203        /* INTA# */     GRPCI2_INTA_SYSIRQ,
204        /* INTB# */     GRPCI2_INTB_SYSIRQ,
205        /* INTC# */     GRPCI2_INTC_SYSIRQ,
206        /* INTD# */     GRPCI2_INTD_SYSIRQ
207};
208
209/* Start of workspace/dynamical area */
210extern unsigned int _end;
211#define DMA_START ((unsigned int) &_end)
212
213/* Default BAR mapping, set BAR0 256MB 1:1 mapped base of CPU RAM */
214struct grpci2_pcibar_cfg grpci2_default_bar_mapping[6] = {
215        /* BAR0 */ {DMA_START, DMA_START, 0x10000000},
216        /* BAR1 */ {0, 0, 0},
217        /* BAR2 */ {0, 0, 0},
218        /* BAR3 */ {0, 0, 0},
219        /* BAR4 */ {0, 0, 0},
220        /* BAR5 */ {0, 0, 0},
221};
222
223/* Driver private data struture */
224struct grpci2_priv {
225        struct drvmgr_dev       *dev;
226        struct grpci2_regs              *regs;
227        char                            irq;
228        char                            irq_mode; /* IRQ Mode from CAPSTS REG */
229        char                            bt_enabled;
230        unsigned int                    irq_mask;
231
232        struct grpci2_pcibar_cfg        *barcfg;
233
234        unsigned int                    pci_area;
235        unsigned int                    pci_area_end;
236        unsigned int                    pci_io;   
237        unsigned int                    pci_conf;
238        unsigned int                    pci_conf_end;
239
240        uint32_t                        devVend; /* Host PCI Device/Vendor ID */
241
242        struct drvmgr_map_entry         maps_up[7];
243        struct drvmgr_map_entry         maps_down[2];
244        struct pcibus_config            config;
245};
246
247int grpci2_init1(struct drvmgr_dev *dev);
248int grpci2_init3(struct drvmgr_dev *dev);
249
250/* GRPCI2 DRIVER */
251
252struct drvmgr_drv_ops grpci2_ops =
253{
254        .init = {grpci2_init1, NULL, grpci2_init3, NULL},
255        .remove = NULL,
256        .info = NULL
257};
258
259struct amba_dev_id grpci2_ids[] =
260{
261        {VENDOR_GAISLER, GAISLER_GRPCI2},
262        {0, 0}          /* Mark end of table */
263};
264
265struct amba_drv_info grpci2_info =
266{
267        {
268                DRVMGR_OBJ_DRV,                 /* Driver */
269                NULL,                           /* Next driver */
270                NULL,                           /* Device list */
271                DRIVER_AMBAPP_GAISLER_GRPCI2_ID,/* Driver ID */
272                "GRPCI2_DRV",                   /* Driver Name */
273                DRVMGR_BUS_TYPE_AMBAPP,         /* Bus Type */
274                &grpci2_ops,
275                NULL,                           /* Funcs */
276                0,                              /* No devices yet */
277                sizeof(struct grpci2_priv),     /* Make drvmgr alloc private */
278        },
279        &grpci2_ids[0]
280};
281
282void grpci2_register_drv(void)
283{
284        DBG("Registering GRPCI2 driver\n");
285        drvmgr_drv_register(&grpci2_info.general);
286}
287
288int grpci2_cfg_r32(pci_dev_t dev, int ofs, uint32_t *val)
289{
290        struct grpci2_priv *priv = grpci2priv;
291        volatile uint32_t *pci_conf;
292        unsigned int tmp, devfn;
293        IRQ_GLOBAL_PREPARE(oldLevel);
294        int retval, bus = PCI_DEV_BUS(dev);
295
296        if ((unsigned int)ofs & 0xffffff03) {
297                retval = PCISTS_EINVAL;
298                goto out2;
299        }
300
301        if (PCI_DEV_SLOT(dev) > 15) {
302                retval = PCISTS_MSTABRT;
303                goto out;
304        }
305
306        /* GRPCI2 can access "non-standard" devices on bus0 (on AD11.AD16),
307         * we skip them.
308         */
309        if (bus == 0 && PCI_DEV_SLOT(dev) != 0)
310                devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
311        else
312                devfn = PCI_DEV_DEVFUNC(dev);
313
314        pci_conf = (volatile uint32_t *) (priv->pci_conf | (devfn << 8) | ofs);
315
316        IRQ_GLOBAL_DISABLE(oldLevel); /* protect regs */
317
318        /* Select bus */
319        priv->regs->ctrl = (priv->regs->ctrl & ~(0xff<<16)) | (bus<<16);
320        /* clear old status */
321        priv->regs->sts_cap = (STS_CFGERR | STS_CFGERRVALID);
322
323        tmp = *pci_conf;
324
325        /* Wait until GRPCI2 signals that CFG access is done, it should be
326         * done instantaneously unless a DMA operation is ongoing...
327         */
328        while ((priv->regs->sts_cap & STS_CFGERRVALID) == 0)
329                ;
330
331        if (priv->regs->sts_cap & STS_CFGERR) {
332                retval = PCISTS_MSTABRT;
333        } else {
334                /* Bus always little endian (unaffected by byte-swapping) */
335                *val = CPU_swap_u32(tmp);
336                retval = PCISTS_OK;
337        }
338
339        IRQ_GLOBAL_ENABLE(oldLevel);
340
341out:
342        if (retval != PCISTS_OK)
343                *val = 0xffffffff;
344
345        DBG("pci_read: [%x:%x:%x] reg: 0x%x => addr: 0x%x, val: 0x%x  (%d)\n",
346                PCI_DEV_EXPAND(dev), ofs, pci_conf, *val, retval);
347
348out2:
349        return retval;
350}
351
352int grpci2_cfg_r16(pci_dev_t dev, int ofs, uint16_t *val)
353{
354        uint32_t v;
355        int retval;
356
357        if (ofs & 1)
358                return PCISTS_EINVAL;
359
360        retval = grpci2_cfg_r32(dev, ofs & ~0x3, &v);
361        *val = 0xffff & (v >> (8*(ofs & 0x3)));
362
363        return retval;
364}
365
366int grpci2_cfg_r8(pci_dev_t dev, int ofs, uint8_t *val)
367{
368        uint32_t v;
369        int retval;
370
371        retval = grpci2_cfg_r32(dev, ofs & ~0x3, &v);
372
373        *val = 0xff & (v >> (8*(ofs & 3)));
374
375        return retval;
376}
377
378int grpci2_cfg_w32(pci_dev_t dev, int ofs, uint32_t val)
379{
380        struct grpci2_priv *priv = grpci2priv;
381        volatile uint32_t *pci_conf;
382        uint32_t value, devfn;
383        int retval, bus = PCI_DEV_BUS(dev);
384        IRQ_GLOBAL_PREPARE(oldLevel);
385
386        if ((unsigned int)ofs & 0xffffff03)
387                return PCISTS_EINVAL;
388
389        if (PCI_DEV_SLOT(dev) > 15)
390                return PCISTS_MSTABRT;
391
392        value = CPU_swap_u32(val);
393
394        /* GRPCI2 can access "non-standard" devices on bus0 (on AD11.AD16),
395         * we skip them.
396         */
397        if (bus == 0 && PCI_DEV_SLOT(dev) != 0)
398                devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
399        else
400                devfn = PCI_DEV_DEVFUNC(dev);
401
402        pci_conf = (volatile uint32_t *) (priv->pci_conf | (devfn << 8) | ofs);
403
404        IRQ_GLOBAL_DISABLE(oldLevel); /* protect regs */
405
406        /* Select bus */
407        priv->regs->ctrl = (priv->regs->ctrl & ~(0xff<<16)) | (bus<<16);
408        /* clear old status */
409        priv->regs->sts_cap = (STS_CFGERR | STS_CFGERRVALID);
410
411        *pci_conf = value;
412
413        /* Wait until GRPCI2 signals that CFG access is done, it should be
414         * done instantaneously unless a DMA operation is ongoing...
415         */
416        while ((priv->regs->sts_cap & STS_CFGERRVALID) == 0)
417                ;
418
419        if (priv->regs->sts_cap & STS_CFGERR)
420                retval = PCISTS_MSTABRT;
421        else
422                retval = PCISTS_OK;
423
424        IRQ_GLOBAL_ENABLE(oldLevel);
425
426        DBG("pci_write - [%x:%x:%x] reg: 0x%x => addr: 0x%x, val: 0x%x  (%d)\n",
427                PCI_DEV_EXPAND(dev), ofs, pci_conf, value, retval);
428
429        return retval;
430}
431
432int grpci2_cfg_w16(pci_dev_t dev, int ofs, uint16_t val)
433{
434        uint32_t v;
435        int retval;
436
437        if (ofs & 1)
438                return PCISTS_EINVAL;
439
440        retval = grpci2_cfg_r32(dev, ofs & ~0x3, &v);
441        if (retval != PCISTS_OK)
442                return retval;
443
444        v = (v & ~(0xffff << (8*(ofs&3)))) | ((0xffff&val) << (8*(ofs&3)));
445
446        return grpci2_cfg_w32(dev, ofs & ~0x3, v);
447}
448
449int grpci2_cfg_w8(pci_dev_t dev, int ofs, uint8_t val)
450{
451        uint32_t v;
452        int retval;
453
454        retval = grpci2_cfg_r32(dev, ofs & ~0x3, &v);
455        if (retval != PCISTS_OK)
456                return retval;
457
458        v = (v & ~(0xff << (8*(ofs&3)))) | ((0xff&val) << (8*(ofs&3)));
459
460        return grpci2_cfg_w32(dev, ofs & ~0x3, v);
461}
462
463/* Return the assigned system IRQ number that corresponds to the PCI
464 * "Interrupt Pin" information from configuration space.
465 *
466 * The IRQ information is stored in the grpci2_pci_irq_table configurable
467 * by the user.
468 *
469 * Returns the "system IRQ" for the PCI INTA#..INTD# pin in irq_pin. Returns
470 * 0xff if not assigned.
471 */
472uint8_t grpci2_bus0_irq_map(pci_dev_t dev, int irq_pin)
473{
474        uint8_t sysIrqNr = 0; /* not assigned */
475        int irq_group;
476
477        if ( (irq_pin >= 1) && (irq_pin <= 4) ) {
478                /* Use default IRQ decoding on PCI BUS0 according slot numbering */
479                irq_group = PCI_DEV_SLOT(dev) & 0x3;
480                irq_pin = ((irq_pin - 1) + irq_group) & 0x3;
481                /* Valid PCI "Interrupt Pin" number */
482                sysIrqNr = grpci2_pci_irq_table[irq_pin];
483        }
484        return sysIrqNr;
485}
486
487int grpci2_translate(uint32_t *address, int type, int dir)
488{
489        uint32_t adr, start, end;
490        struct grpci2_priv *priv = grpci2priv;
491        int i;
492
493        if (type == 1) {
494                /* I/O */
495                if (dir != 0) {
496                        /* The PCI bus can not access the CPU bus from I/O
497                         * because GRPCI2 core does not support I/O BARs
498                         */
499                        return -1;
500                }
501
502                /* We have got a PCI IO BAR address that the CPU want to access.
503                 * Check that it is within the PCI I/O window, I/O adresses
504                 * are NOT mapped 1:1 with GRPCI2 driver... translation needed.
505                 */
506                adr = *(uint32_t *)address;
507                if (adr < 0x100 || adr > 0x10000)
508                        return -1;
509                *address = adr + priv->pci_io;
510        } else {
511                /* MEMIO and MEM.
512                 * Memory space is mapped 1:1 so no translation is needed.
513                 * Check that address is within accessible windows.
514                 */
515                adr = *(uint32_t *)address;
516                if (dir == 0) {
517                        /* PCI BAR to AMBA-CPU address.. check that it is
518                         * located within GRPCI2 PCI Memory Window
519                         * adr = PCI address.
520                         */
521                        if (adr < priv->pci_area || adr >= priv->pci_area_end)
522                                return -1;
523                } else {
524                        /* We have a CPU address and want to get access to it
525                         * from PCI space, typically when doing DMA into CPU
526                         * RAM. The GRPCI2 core may have multiple target BARs
527                         * that PCI masters can access, the BARs are user
528                         * configurable in the following ways:
529                         *  BAR_SIZE, PCI_BAR Address and MAPPING (AMBA ADR)
530                         *
531                         * The below code tries to find a BAR for which the
532                         * AMBA bar may have been mapped onto, and translate
533                         * the AMBA-CPU address into a PCI address using the
534                         * given mapping.
535                         *
536                         * adr = AMBA address.
537                         */
538                        for(i=0; i<6; i++) {
539                                start = priv->barcfg[i].ahbadr;
540                                end = priv->barcfg[i].ahbadr +
541                                        priv->barcfg[i].barsize;
542                                if (adr >= start && adr < end) {
543                                        /* BAR match: Translate address */
544                                        *address = (adr - start) +
545                                                priv->barcfg[i].pciadr;
546                                        return 0;
547                                }
548                        }
549                        return -1;
550                }
551        }
552
553        return 0;
554}
555
556extern struct pci_memreg_ops pci_memreg_sparc_le_ops;
557extern struct pci_memreg_ops pci_memreg_sparc_be_ops;
558
559/* GRPCI2 PCI access routines, default to Little-endian PCI Bus */
560struct pci_access_drv grpci2_access_drv = {
561        .cfg =
562        {
563                grpci2_cfg_r8,
564                grpci2_cfg_r16,
565                grpci2_cfg_r32,
566                grpci2_cfg_w8,
567                grpci2_cfg_w16,
568                grpci2_cfg_w32,
569        },
570        .io =
571        {
572                _ld8,
573                _ld_le16,
574                _ld_le32,
575                _st8,
576                _st_le16,
577                _st_le32,
578        },
579        .memreg = &pci_memreg_sparc_le_ops,
580        .translate = grpci2_translate,
581};
582
583struct pci_io_ops grpci2_io_ops_be =
584{
585        _ld8,
586        _ld_be16,
587        _ld_be32,
588        _st8,
589        _st_be16,
590        _st_be32,
591};
592
593/* PCI Error Interrupt handler, called when there may be a PCI Target/Master
594 * Abort.
595 */
596void grpci2_err_isr(void *arg)
597{
598        struct grpci2_priv *priv = arg;
599        unsigned int sts = priv->regs->sts_cap;
600
601        if (sts & (STS_IMSTABRT | STS_ITGTABRT | STS_IPARERR | STS_ISYSERR)) {
602                /* A PCI error IRQ ... Error handler unimplemented
603                 * add your code here...
604                 */
605                if (sts & STS_IMSTABRT) {
606                        printk("GRPCI2: unhandled Master Abort IRQ\n");
607                }
608                if (sts & STS_ITGTABRT) {
609                        printk("GRPCI2: unhandled Target Abort IRQ\n");
610                }
611                if (sts & STS_IPARERR) {
612                        printk("GRPCI2: unhandled Parity Error IRQ\n");
613                }
614                if (sts & STS_ISYSERR) {
615                        printk("GRPCI2: unhandled System Error IRQ\n");
616                }
617        }
618}
619
620int grpci2_hw_init(struct grpci2_priv *priv)
621{
622        struct grpci2_regs *regs = priv->regs;
623        int i;
624        uint8_t capptr;
625        uint32_t data, io_map, ahbadr, pciadr, size;
626        pci_dev_t host = PCI_DEV(0, 0, 0);
627        struct grpci2_pcibar_cfg *barcfg = priv->barcfg;
628
629        /* Reset any earlier setup */
630        regs->ctrl = 0;
631        regs->sts_cap = ~0; /* Clear Status */
632        regs->dma_ctrl = 0;
633        regs->dma_bdbase = 0;
634
635        /* Translate I/O accesses 1:1, (will not work for PCI 2.3) */
636        regs->io_map = priv->pci_io & 0xffff0000;
637
638        /* set 1:1 mapping between AHB -> PCI memory space, for all Masters
639         * Each AHB master has it's own mapping registers. Max 16 AHB masters.
640         */
641        for (i=0; i<16; i++)
642                regs->ahbmst_map[i] = priv->pci_area;
643
644        /* Get the GRPCI2 Host PCI ID */
645        grpci2_cfg_r32(host, PCI_VENDOR_ID, &priv->devVend);
646
647        /* Get address to first (always defined) capability structure */
648        grpci2_cfg_r8(host, PCI_CAP_PTR, &capptr);
649        if (capptr == 0)
650                return -1;
651
652        /* Enable/Disable Byte twisting */
653        grpci2_cfg_r32(host, capptr+CAP9_IOMAP_OFS, &io_map);
654        io_map = (io_map & ~0x1) | (priv->bt_enabled ? 1 : 0);
655        grpci2_cfg_w32(host, capptr+CAP9_IOMAP_OFS, io_map);
656
657        /* Setup the Host's PCI Target BARs for others to access (DMA) */
658        for (i=0; i<6; i++) {
659                /* Make sure address is properly aligned */
660                size = ~(barcfg[i].barsize-1);
661                barcfg[i].pciadr &= size;
662                barcfg[i].ahbadr &= size;
663
664                pciadr = barcfg[i].pciadr;
665                ahbadr = barcfg[i].ahbadr;
666                size |= PCI_BASE_ADDRESS_MEM_PREFETCH;
667
668                grpci2_cfg_w32(host, capptr+CAP9_BARSIZE_OFS+i*4, size);
669                grpci2_cfg_w32(host, capptr+CAP9_BAR_OFS+i*4, ahbadr);
670                grpci2_cfg_w32(host, PCI_BASE_ADDRESS_0+i*4, pciadr);
671        }
672
673        /* set as bus master and enable pci memory responses */ 
674        grpci2_cfg_r32(host, PCI_COMMAND, &data);
675        data |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
676        grpci2_cfg_w32(host, PCI_COMMAND, data);
677
678        /* Enable Error respone (CPU-TRAP) on illegal memory access */
679        regs->ctrl = CTRL_ER | CTRL_PE;
680
681        /* Successful */
682        return 0;
683}
684
685/* Initializes the GRPCI2 core and driver, must be called before calling
686 * init_pci()
687 *
688 * Return values
689 *  0             Successful initalization
690 *  -1            Error during initialization, for example "PCI core not found".
691 *  -2            Error PCI controller not HOST (targets not supported)
692 *  -3            Error due to GRPCI2 hardware initialization
693 */
694int grpci2_init(struct grpci2_priv *priv)
695{
696        struct ambapp_apb_info *apb;
697        struct ambapp_ahb_info *ahb;
698        int pin, i, j;
699        union drvmgr_key_value *value;
700        char keyname[6];
701        struct amba_dev_info *ainfo = priv->dev->businfo;
702        struct grpci2_pcibar_cfg *barcfg;
703        unsigned int size;
704
705        /* Find PCI core from Plug&Play information */
706        apb = ainfo->info.apb_slv;
707        ahb = ainfo->info.ahb_slv;
708
709        /* Found PCI core, init private structure */
710        priv->irq = apb->irq;
711        priv->regs = (struct grpci2_regs *)apb->start;
712        priv->bt_enabled = DEFAULT_BT_ENABLED;
713        priv->irq_mode = (priv->regs->sts_cap & STS_IRQMODE) >> STS_IRQMODE_BIT;
714
715        /* Calculate the PCI windows
716         *  AMBA->PCI Window:                       AHB SLAVE AREA0
717         *  AMBA->PCI I/O cycles Window:            AHB SLAVE AREA1 Lower half
718         *  AMBA->PCI Configuration cycles Window:  AHB SLAVE AREA1 Upper half
719         */
720        priv->pci_area     = ahb->start[0];
721        priv->pci_area_end = ahb->start[0] + ahb->mask[0];
722        priv->pci_io       = ahb->start[1];
723        priv->pci_conf     = ahb->start[1] + 0x10000;
724        priv->pci_conf_end = priv->pci_conf + 0x10000;
725
726        /* On systems where PCI I/O area and configuration area is apart of the
727         * "PCI Window" the PCI Window stops at the start of the PCI I/O area
728         */
729        if ((priv->pci_io > priv->pci_area) &&
730            (priv->pci_io < (priv->pci_area_end-1))) {
731                priv->pci_area_end = priv->pci_io;
732        }
733
734        /* Init PCI interrupt assignment table to all use the interrupt routed
735         * through the GRPCI2 core.
736         */
737        strcpy(keyname, "INTX#");
738        for (pin=1; pin<5; pin++) {
739                if (grpci2_pci_irq_table[pin-1] == 0xff) {
740                        if (priv->irq_mode < 2) {
741                                /* PCI Interrupts are shared */
742                                grpci2_pci_irq_table[pin-1] = priv->irq;
743                        } else {
744                                /* Unique IRQ per PCI INT Pin */
745                                grpci2_pci_irq_table[pin-1] = priv->irq + pin-1;
746                        }
747
748                        /* User may override Both hardcoded IRQ setup and Plug & Play IRQ */
749                        keyname[3] = 'A' + (pin-1);
750                        value = drvmgr_dev_key_get(priv->dev, keyname, KEY_TYPE_INT);
751                        if (value)
752                                grpci2_pci_irq_table[pin-1] = value->i;
753                }
754
755                /* Remember which IRQs are enabled */
756                if (grpci2_pci_irq_table[pin-1] != 0)
757                        priv->irq_mask |= 1 << (pin-1);
758        }
759
760        /* User may override DEFAULT_BT_ENABLED to enable/disable byte twisting */
761        value = drvmgr_dev_key_get(priv->dev, "byteTwisting", KEY_TYPE_INT);
762        if (value)
763                priv->bt_enabled = value->i;
764
765        /* Let user Configure the 6 target BARs */
766        value = drvmgr_dev_key_get(priv->dev, "tgtBarCfg", KEY_TYPE_POINTER);
767        if (value)
768                priv->barcfg = value->ptr;
769        else
770                priv->barcfg = grpci2_default_bar_mapping;
771
772        /* This driver only support HOST systems, we check that it can act as a
773         * PCI Master and that it is in the Host slot. */
774        if ((priv->regs->sts_cap&STS_HOST) || !(priv->regs->sts_cap&STS_MST))
775                return -2; /* Target not supported */
776
777        /* Init the PCI Core */
778        if (grpci2_hw_init(priv))
779                return -3;
780
781        /* Down streams translation table */
782        priv->maps_down[0].name = "AMBA -> PCI MEM Window";
783        priv->maps_down[0].size = priv->pci_area_end - priv->pci_area;
784        priv->maps_down[0].from_adr = (void *)priv->pci_area;
785        priv->maps_down[0].to_adr = (void *)priv->pci_area;
786        /* End table */
787        priv->maps_down[1].size = 0;
788
789        /* Up streams translation table */
790        /* Setup the Host's PCI Target BARs for others to access (DMA) */
791        barcfg = priv->barcfg;
792        for (i=0,j=0; i<6; i++) {
793                size = barcfg[i].barsize;
794                if (size == 0)
795                        continue;
796
797                /* Make sure address is properly aligned */
798                priv->maps_up[j].name = "Target BAR[I] -> AMBA";
799                priv->maps_up[j].size = size;
800                priv->maps_up[j].from_adr = (void *)
801                                        (barcfg[i].pciadr & ~(size - 1));
802                priv->maps_up[j].to_adr = (void *)
803                                        (barcfg[i].ahbadr & ~(size - 1));
804                j++;
805        }
806
807        /* End table */
808        priv->maps_up[j].size = 0;
809
810        return 0;
811}
812
813/* Called when a core is found with the AMBA device and vendor ID
814 * given in grpci2_ids[]. IRQ, Console does not work here
815 */
816int grpci2_init1(struct drvmgr_dev *dev)
817{
818        int status;
819        struct grpci2_priv *priv;
820        struct pci_auto_setup grpci2_auto_cfg;
821
822        DBG("GRPCI2[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
823
824        if (grpci2priv) {
825                DBG("Driver only supports one PCI core\n");
826                return DRVMGR_FAIL;
827        }
828
829        if ((strcmp(dev->parent->dev->drv->name, "AMBAPP_GRLIB_DRV") != 0) &&
830            (strcmp(dev->parent->dev->drv->name, "AMBAPP_LEON2_DRV") != 0)) {
831                /* We only support GRPCI2 driver on local bus */
832                return DRVMGR_FAIL;
833        }
834
835        priv = dev->priv;
836        if (!priv)
837                return DRVMGR_NOMEM;
838
839        priv->dev = dev;
840        grpci2priv = priv;
841
842        /* Initialize GRPCI2 Hardware */
843        status = grpci2_init(priv);
844        if (status) {
845                printf("Failed to initialize grpci2 driver %d\n", status);
846                return -1;
847        }
848
849        /* Register the PCI core at the PCI layers */
850
851        if (priv->bt_enabled == 0) {
852                /* Host is Big-Endian */
853                pci_endian = PCI_BIG_ENDIAN;
854
855                memcpy(&grpci2_access_drv.io, &grpci2_io_ops_be,
856                                                sizeof(grpci2_io_ops_be));
857                grpci2_access_drv.memreg = &pci_memreg_sparc_be_ops;
858        }
859
860        if (pci_access_drv_register(&grpci2_access_drv)) {
861                /* Access routines registration failed */
862                return DRVMGR_FAIL;
863        }
864
865        /* Prepare memory MAP */
866        grpci2_auto_cfg.options = 0;
867        grpci2_auto_cfg.mem_start = 0;
868        grpci2_auto_cfg.mem_size = 0;
869        grpci2_auto_cfg.memio_start = priv->pci_area;
870        grpci2_auto_cfg.memio_size = priv->pci_area_end - priv->pci_area;
871        grpci2_auto_cfg.io_start = 0x100; /* avoid PCI address 0 */
872        grpci2_auto_cfg.io_size = 0x10000 - 0x100; /* lower 64kB I/O 16 */
873        grpci2_auto_cfg.irq_map = grpci2_bus0_irq_map;
874        grpci2_auto_cfg.irq_route = NULL; /* use standard routing */
875        pci_config_register(&grpci2_auto_cfg);
876
877        if (pci_config_init()) {
878                /* PCI configuration failed */
879                return DRVMGR_FAIL;
880        }
881
882        /* Initialize/Register Driver Manager PCI Bus */
883        priv->config.maps_down = &priv->maps_down[0];
884        priv->config.maps_up = &priv->maps_up[0];
885        return pcibus_register(dev, &priv->config);
886}
887
888int grpci2_init3(struct drvmgr_dev *dev)
889{
890        struct grpci2_priv *priv = dev->priv;
891
892        /* Install and Enable PCI Error interrupt handler */
893        drvmgr_interrupt_register(dev, 0, "grpci2", grpci2_err_isr, priv);
894
895        /* Unmask Error IRQ and all PCI interrupts at PCI Core. For this to be
896         * safe every PCI board have to be resetted (no IRQ generation) before
897         * Global IRQs are enabled (Init is reached or similar)
898         */
899        priv->regs->ctrl |= (CTRL_EI | priv->irq_mask);
900
901        return DRVMGR_OK;
902}
Note: See TracBrowser for help on using the repository browser.