source: rtems/c/src/lib/libbsp/sparc/shared/pci/grpci.c @ 4a7d1026

4.115
Last change on this file since 4a7d1026 was 4a7d1026, checked in by Daniel Hellstrom <daniel@…>, on 04/13/15 at 08:25:52

sparc bsps: updated license to rtems.org

  • Property mode set to 100644
File size: 18.0 KB
Line 
1/*  GRLIB GRPCI PCI HOST driver.
2 *
3 *  COPYRIGHT (c) 2008.
4 *  Cobham Gaisler AB.
5 *
6 *  Configures the GRPCI core and initialize,
7 *   - the PCI Library (pci.c)
8 *   - the general part of the PCI Bus driver (pci_bus.c)
9 * 
10 *  System interrupt assigned to PCI interrupt (INTA#..INTD#) is by
11 *  default taken from Plug and Play, but may be overridden by the
12 *  driver resources INTA#..INTD#.
13 *
14 *  The license and distribution terms for this file may be
15 *  found in found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#include <stdlib.h>
20#include <stdio.h>
21#include <string.h>
22#include <rtems/bspIo.h>
23#include <libcpu/byteorder.h>
24#include <libcpu/access.h>
25#include <pci.h>
26#include <pci/cfg.h>
27
28#include <drvmgr/drvmgr.h>
29#include <drvmgr/ambapp_bus.h>
30#include <ambapp.h>
31#include <drvmgr/pci_bus.h>
32#include <bsp/grpci.h>
33
34#define DMAPCI_ADDR 0x80000500
35
36/* Configuration options */
37#define SYSTEM_MAINMEM_START 0x40000000
38
39/* If defined to 1 - byte twisting is enabled by default */
40#define DEFAULT_BT_ENABLED 0
41
42/* Interrupt assignment. Set to other value than 0xff in order to
43 * override defaults and plug&play information
44 */
45#ifndef GRPCI_INTA_SYSIRQ
46 #define GRPCI_INTA_SYSIRQ 0xff
47#endif
48#ifndef GRPCI_INTB_SYSIRQ
49 #define GRPCI_INTB_SYSIRQ 0xff
50#endif
51#ifndef GRPCI_INTC_SYSIRQ
52 #define GRPCI_INTC_SYSIRQ 0xff
53#endif
54#ifndef GRPCI_INTD_SYSIRQ
55 #define GRPCI_INTD_SYSIRQ 0xff
56#endif
57
58#define PAGE0_BTEN_BIT    0
59#define PAGE0_BTEN        (1<<PAGE0_BTEN_BIT)
60
61#define CFGSTAT_HOST_BIT  13
62#define CFGSTAT_HOST      (1<<CFGSTAT_HOST_BIT)
63
64/*#define DEBUG 1*/
65
66#ifdef DEBUG
67#define DBG(x...) printk(x)
68#else
69#define DBG(x...)
70#endif
71
72/*
73 * Bit encode for PCI_CONFIG_HEADER_TYPE register
74 */
75struct grpci_regs {
76        volatile unsigned int cfg_stat;
77        volatile unsigned int bar0;
78        volatile unsigned int page0;
79        volatile unsigned int bar1;
80        volatile unsigned int page1;
81        volatile unsigned int iomap;
82        volatile unsigned int stat_cmd;
83        volatile unsigned int irq;
84};
85
86#define HOST_TGT PCI_DEV(0xff, 0, 0)
87
88struct grpci_priv *grpcipriv = NULL;
89static int grpci_minor = 0;
90static unsigned int *pcidma = (unsigned int *)DMAPCI_ADDR;
91
92/* PCI Interrupt assignment. Connects an PCI interrupt pin (INTA#..INTD#)
93 * to a system interrupt number.
94 */
95unsigned char grpci_pci_irq_table[4] =
96{
97        /* INTA# */     GRPCI_INTA_SYSIRQ,
98        /* INTB# */     GRPCI_INTB_SYSIRQ,
99        /* INTC# */     GRPCI_INTC_SYSIRQ,
100        /* INTD# */     GRPCI_INTD_SYSIRQ
101};
102
103/* Driver private data struture */
104struct grpci_priv {
105        struct drvmgr_dev       *dev;
106        struct grpci_regs               *regs;
107        int                             irq;
108        int                             minor;
109
110        uint32_t                        bar1_pci_adr;
111        uint32_t                        bar1_size;
112
113        int                             bt_enabled;
114        unsigned int                    pci_area;
115        unsigned int                    pci_area_end;
116        unsigned int                    pci_io;   
117        unsigned int                    pci_conf;
118        unsigned int                    pci_conf_end;
119
120        uint32_t                        devVend; /* Host PCI Vendor/Device ID */
121
122        struct drvmgr_map_entry maps_up[2];
123        struct drvmgr_map_entry maps_down[2];
124        struct pcibus_config    config;
125};
126
127int grpci_init1(struct drvmgr_dev *dev);
128
129/* GRPCI DRIVER */
130
131struct drvmgr_drv_ops grpci_ops =
132{
133        .init = {grpci_init1, NULL, NULL, NULL},
134        .remove = NULL,
135        .info = NULL
136};
137
138struct amba_dev_id grpci_ids[] =
139{
140        {VENDOR_GAISLER, GAISLER_PCIFBRG},
141        {0, 0}          /* Mark end of table */
142};
143
144struct amba_drv_info grpci_info =
145{
146        {
147                DRVMGR_OBJ_DRV,                 /* Driver */
148                NULL,                           /* Next driver */
149                NULL,                           /* Device list */
150                DRIVER_AMBAPP_GAISLER_GRPCI_ID, /* Driver ID */
151                "GRPCI_DRV",                    /* Driver Name */
152                DRVMGR_BUS_TYPE_AMBAPP,         /* Bus Type */
153                &grpci_ops,
154                NULL,                           /* Funcs */
155                0,                              /* No devices yet */
156                sizeof(struct grpci_priv),      /* Make drvmgr alloc private */
157        },
158        &grpci_ids[0]
159};
160
161void grpci_register_drv(void)
162{
163        DBG("Registering GRPCI driver\n");
164        drvmgr_drv_register(&grpci_info.general);
165}
166
167static int grpci_cfg_r32(pci_dev_t dev, int ofs, uint32_t *val)
168{
169        struct grpci_priv *priv = grpcipriv;
170        volatile uint32_t *pci_conf;
171        uint32_t devfn;
172        int retval;
173        int bus = PCI_DEV_BUS(dev);
174
175        if (ofs & 3)
176                return PCISTS_EINVAL;
177
178        if (PCI_DEV_SLOT(dev) > 15) {
179                *val = 0xffffffff;
180                return PCISTS_OK;
181        }
182
183        /* GRPCI can access "non-standard" devices on bus0 (on AD11.AD16),
184         * but we skip them.
185         */
186        if (dev == HOST_TGT)
187                bus = devfn = 0;
188        else if (bus == 0)
189                devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
190        else
191                devfn = PCI_DEV_DEVFUNC(dev);
192
193        /* Select bus */
194        priv->regs->cfg_stat = (priv->regs->cfg_stat & ~(0xf<<23)) | (bus<<23);
195
196        pci_conf = (volatile uint32_t *)(priv->pci_conf | (devfn << 8) | ofs);
197
198        if (priv->bt_enabled) {
199                *val =  CPU_swap_u32(*pci_conf);
200        } else {
201                *val = *pci_conf;
202        }
203
204        if (priv->regs->cfg_stat & 0x100) {
205                *val = 0xffffffff;
206                retval = PCISTS_MSTABRT;
207        } else
208                retval = PCISTS_OK;
209
210        DBG("pci_read: [%x:%x:%x] reg: 0x%x => addr: 0x%x, val: 0x%x\n",
211                PCI_DEV_EXPAND(dev), ofs, pci_conf, *val);
212
213        return retval;
214}
215
216
217static int grpci_cfg_r16(pci_dev_t dev, int ofs, uint16_t *val)
218{
219        uint32_t v;
220        int retval;
221
222        if (ofs & 1)
223                return PCISTS_EINVAL;
224
225        retval = grpci_cfg_r32(dev, ofs & ~0x3, &v);
226        *val = 0xffff & (v >> (8*(ofs & 0x3)));
227
228        return retval;
229}
230
231static int grpci_cfg_r8(pci_dev_t dev, int ofs, uint8_t *val)
232{
233        uint32_t v;
234        int retval;
235
236        retval = grpci_cfg_r32(dev, ofs & ~0x3, &v);
237
238        *val = 0xff & (v >> (8*(ofs & 3)));
239
240        return retval;
241}
242
243static int grpci_cfg_w32(pci_dev_t dev, int ofs, uint32_t val)
244{
245        struct grpci_priv *priv = grpcipriv;
246        volatile uint32_t *pci_conf;
247        uint32_t value, devfn = PCI_DEV_DEVFUNC(dev);
248        int bus = PCI_DEV_BUS(dev);
249
250        if (ofs & 0x3)
251                return PCISTS_EINVAL;
252
253        if (PCI_DEV_SLOT(dev) > 15)
254                return PCISTS_MSTABRT;
255
256        /* GRPCI can access "non-standard" devices on bus0 (on AD11.AD16),
257         * but we skip them.
258         */
259        if (dev == HOST_TGT)
260                bus = devfn = 0;
261        else if (bus == 0)
262                devfn = PCI_DEV_DEVFUNC(dev) + PCI_DEV(0, 6, 0);
263        else
264                devfn = PCI_DEV_DEVFUNC(dev);
265
266        /* Select bus */
267        priv->regs->cfg_stat = (priv->regs->cfg_stat & ~(0xf<<23)) | (bus<<23);
268
269        pci_conf = (volatile uint32_t *)(priv->pci_conf | (devfn << 8) | ofs);
270
271        if ( priv->bt_enabled ) {
272                value = CPU_swap_u32(val);
273        } else {
274                value = val;
275        }
276
277        *pci_conf = value;
278
279        DBG("pci_write - [%x:%x:%x] reg: 0x%x => addr: 0x%x, val: 0x%x\n",
280                PCI_DEV_EXPAND(dev), ofs, pci_conf, value);
281
282        return PCISTS_OK;
283}
284
285static int grpci_cfg_w16(pci_dev_t dev, int ofs, uint16_t val)
286{
287        uint32_t v;
288        int retval;
289
290        if (ofs & 1)
291                return PCISTS_EINVAL;
292
293        retval = grpci_cfg_r32(dev, ofs & ~0x3, &v);
294        if (retval != PCISTS_OK)
295                return retval;
296
297        v = (v & ~(0xffff << (8*(ofs&3)))) | ((0xffff&val) << (8*(ofs&3)));
298
299        return grpci_cfg_w32(dev, ofs & ~0x3, v);
300}
301
302static int grpci_cfg_w8(pci_dev_t dev, int ofs, uint8_t val)
303{
304        uint32_t v;
305        int retval;
306
307        retval = grpci_cfg_r32(dev, ofs & ~0x3, &v);
308        if (retval != PCISTS_OK)
309                return retval;
310
311        v = (v & ~(0xff << (8*(ofs&3)))) | ((0xff&val) << (8*(ofs&3)));
312
313        return grpci_cfg_w32(dev, ofs & ~0x3, v);
314}
315
316/* Return the assigned system IRQ number that corresponds to the PCI
317 * "Interrupt Pin" information from configuration space.
318 *
319 * The IRQ information is stored in the grpci_pci_irq_table configurable
320 * by the user.
321 *
322 * Returns the "system IRQ" for the PCI INTA#..INTD# pin in irq_pin. Returns
323 * 0xff if not assigned.
324 */
325static uint8_t grpci_bus0_irq_map(pci_dev_t dev, int irq_pin)
326{
327        uint8_t sysIrqNr = 0; /* not assigned */
328        int irq_group;
329
330        if ( (irq_pin >= 1) && (irq_pin <= 4) ) {
331                /* Use default IRQ decoding on PCI BUS0 according slot numbering */
332                irq_group = PCI_DEV_SLOT(dev) & 0x3;
333                irq_pin = ((irq_pin - 1) + irq_group) & 0x3;
334                /* Valid PCI "Interrupt Pin" number */
335                sysIrqNr = grpci_pci_irq_table[irq_pin];
336        }
337        return sysIrqNr;
338}
339
340static int grpci_translate(uint32_t *address, int type, int dir)
341{
342        uint32_t adr;
343        struct grpci_priv *priv = grpcipriv;
344
345        if (type == 1) {
346                /* I/O */
347                if (dir != 0) {
348                        /* The PCI bus can not access the CPU bus from I/O
349                         * because GRPCI core does not support I/O BARs
350                         */
351                        return -1;
352                }
353
354                /* We have got a PCI BAR address that the CPU want to access...
355                 * Check that it is within the PCI I/O window, I/O adresses
356                 * are mapped 1:1 with GRPCI driver... no translation needed.
357                 */
358                adr = *(uint32_t *)address;
359                if (adr < priv->pci_io || adr >= priv->pci_conf)
360                        return -1;
361        } else {
362                /* MEMIO and MEM.
363                 * Memory space is mapped 1:1 so no translation is needed.
364                 * Check that address is within accessible windows.
365                 */
366                adr = *(uint32_t *)address;
367                if (dir == 0) {
368                        /* PCI BAR to AMBA-CPU address.. check that it is
369                         * located within GRPCI PCI Memory Window
370                         * adr = PCI address.
371                         */
372                        if (adr < priv->pci_area || adr >= priv->pci_area_end)
373                                return -1;
374                } else {
375                        /* We have a CPU address and want to get access to it
376                         * from PCI space, typically when doing DMA into CPU
377                         * RAM. The GRPCI core has two target BARs that PCI
378                         * masters can access, we check here that the address
379                         * is accessible from PCI.
380                         * adr = AMBA address.
381                         */
382                        if (adr < priv->bar1_pci_adr ||
383                            adr >= (priv->bar1_pci_adr + priv->bar1_size))
384                                return -1;
385                }
386        }
387
388        return 0;
389}
390
391extern struct pci_memreg_ops pci_memreg_sparc_le_ops;
392extern struct pci_memreg_ops pci_memreg_sparc_be_ops;
393
394/* GRPCI PCI access routines, default to Little-endian PCI Bus */
395struct pci_access_drv grpci_access_drv = {
396        .cfg =
397        {
398                grpci_cfg_r8,
399                grpci_cfg_r16,
400                grpci_cfg_r32,
401                grpci_cfg_w8,
402                grpci_cfg_w16,
403                grpci_cfg_w32,
404        },
405        .io =
406        {
407                _ld8,
408                _ld_le16,
409                _ld_le32,
410                _st8,
411                _st_le16,
412                _st_le32,
413        },
414        .memreg = &pci_memreg_sparc_le_ops,
415        .translate = grpci_translate,
416};
417
418struct pci_io_ops grpci_io_ops_be =
419{
420        _ld8,
421        _ld_be16,
422        _ld_be32,
423        _st8,
424        _st_be16,
425        _st_be32,
426};
427
428static int grpci_hw_init(struct grpci_priv *priv)
429{
430        volatile unsigned int *mbar0, *page0;
431        uint32_t data, addr, mbar0size;
432        pci_dev_t host = HOST_TGT;
433
434        mbar0 = (volatile unsigned int *)priv->pci_area;
435
436        if ( !priv->bt_enabled && ((priv->regs->page0 & PAGE0_BTEN) == PAGE0_BTEN) ) {
437                /* Byte twisting is on, turn it off */
438                grpci_cfg_w32(host, PCIR_BAR(0), 0xffffffff);
439                grpci_cfg_r32(host, PCIR_BAR(0), &addr);
440                /* Setup bar0 to nonzero value */
441                grpci_cfg_w32(host, PCIR_BAR(0),
442                                CPU_swap_u32(0x80000000));
443                /* page0 is accessed through upper half of bar0 */
444                addr = (~CPU_swap_u32(addr)+1)>>1;
445                mbar0size = addr*2;
446                DBG("GRPCI: Size of MBAR0: 0x%x, MBAR0: 0x%x(lower) 0x%x(upper)\n",mbar0size,((unsigned int)mbar0),((unsigned int)mbar0)+mbar0size/2);
447                page0 = &mbar0[mbar0size/8];
448                DBG("GRPCI: PAGE0 reg address: 0x%x (0x%x)\n",((unsigned int)mbar0)+mbar0size/2,page0);
449                priv->regs->cfg_stat = (priv->regs->cfg_stat & (~0xf0000000)) | 0x80000000;    /* Setup mmap reg so we can reach bar0 */
450                *page0 = 0<<PAGE0_BTEN_BIT;                                         /* Disable bytetwisting ... */
451        }
452
453        /* Get the GRPCI Host PCI ID */
454        grpci_cfg_r32(host, PCIR_VENDOR, &priv->devVend);
455
456        /* set 1:1 mapping between AHB -> PCI memory */
457        priv->regs->cfg_stat = (priv->regs->cfg_stat & 0x0fffffff) | priv->pci_area;
458
459        /* determine size of target BAR1 */
460        grpci_cfg_w32(host, PCIR_BAR(1), 0xffffffff);
461        grpci_cfg_r32(host, PCIR_BAR(1), &addr);
462        priv->bar1_size = (~(addr & ~0xf)) + 1;
463
464        /* and map system RAM at pci address 0x40000000 */
465        priv->bar1_pci_adr &= ~(priv->bar1_size - 1); /* Fix alignment of BAR1 */
466        grpci_cfg_w32(host, PCIR_BAR(1), priv->bar1_pci_adr);
467        priv->regs->page1 = priv->bar1_pci_adr;
468
469        /* Translate I/O accesses 1:1 */
470        priv->regs->iomap = priv->pci_io & 0xffff0000;
471
472        /* Setup Latency Timer and cache line size. Default cache line
473         * size will result in poor performance (256 word fetches), 0xff
474         * will set it according to the max size of the PCI FIFO.
475         */
476        grpci_cfg_w8(host, PCIR_CACHELNSZ, 0xff);
477        grpci_cfg_w8(host, PCIR_LATTIMER, 0x40);
478
479        /* set as bus master and enable pci memory responses */ 
480        grpci_cfg_r32(host, PCIR_COMMAND, &data);
481        data |= (PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
482        grpci_cfg_w32(host, PCIR_COMMAND, data);
483
484        /* unmask all PCI interrupts at PCI Core, not all GRPCI cores support
485         * this
486         */
487        priv->regs->irq = 0xf0000;
488
489        /* Successful */
490        return 0;
491}
492
493/* Initializes the GRPCI core and driver, must be called before calling init_pci()
494 *
495 * Return values
496 *  0             Successful initalization
497 *  -1            Error during initialization, for example "PCI core not found".
498 *  -2            Error PCI controller not HOST (targets not supported)
499 *  -3            Error due to GRPCI hardware initialization
500 *  -4            Error registering driver to PCI layer
501 */
502static int grpci_init(struct grpci_priv *priv)
503{
504        struct ambapp_apb_info *apb;
505        struct ambapp_ahb_info *ahb;
506        int pin;
507        union drvmgr_key_value *value;
508        char keyname[6];
509        struct amba_dev_info *ainfo = priv->dev->businfo;
510
511        /* Find PCI core from Plug&Play information */
512        apb = ainfo->info.apb_slv;
513        ahb = ainfo->info.ahb_slv;
514
515        /* Found PCI core, init private structure */
516        priv->irq = apb->irq;
517        priv->regs = (struct grpci_regs *)apb->start;
518        priv->bt_enabled = DEFAULT_BT_ENABLED;
519
520        /* Calculate the PCI windows
521         *  AMBA->PCI Window:                       AHB SLAVE AREA0
522         *  AMBA->PCI I/O cycles Window:            AHB SLAVE AREA1 Lower half
523         *  AMBA->PCI Configuration cycles Window:  AHB SLAVE AREA1 Upper half
524         */
525        priv->pci_area     = ahb->start[0];
526        priv->pci_area_end = ahb->start[0] + ahb->mask[0];
527        priv->pci_io       = ahb->start[1];
528        priv->pci_conf     = ahb->start[1] + (ahb->mask[1] >> 1);
529        priv->pci_conf_end = ahb->start[1] + ahb->mask[1];
530
531        /* On systems where PCI I/O area and configuration area is apart of the "PCI Window"
532         * the PCI Window stops at the start of the PCI I/O area
533         */
534        if ( (priv->pci_io > priv->pci_area) && (priv->pci_io < (priv->pci_area_end-1)) ) {
535                priv->pci_area_end = priv->pci_io;
536        }
537
538        /* Init PCI interrupt assignment table to all use the interrupt routed through
539         * the GRPCI core.
540         */
541        strcpy(keyname, "INTX#");
542        for (pin=1; pin<5; pin++) {
543                if ( grpci_pci_irq_table[pin-1] == 0xff ) {
544                        grpci_pci_irq_table[pin-1] = priv->irq;
545
546                        /* User may override Both hardcoded IRQ setup and Plug & Play IRQ */
547                        keyname[3] = 'A' + (pin-1);
548                        value = drvmgr_dev_key_get(priv->dev, keyname, KEY_TYPE_INT);
549                        if ( value )
550                                grpci_pci_irq_table[pin-1] = value->i;
551                }
552        }
553
554        /* User may override DEFAULT_BT_ENABLED to enable/disable byte twisting */
555        value = drvmgr_dev_key_get(priv->dev, "byteTwisting", KEY_TYPE_INT);
556        if ( value )
557                priv->bt_enabled = value->i;
558
559        /* Use GRPCI target BAR1 to map CPU RAM to PCI, this is to make it
560         * possible for PCI peripherals to do DMA directly to CPU memory.
561         */
562        value = drvmgr_dev_key_get(priv->dev, "tgtbar1", KEY_TYPE_INT);
563        if (value)
564                priv->bar1_pci_adr = value->i;
565        else
566                priv->bar1_pci_adr = SYSTEM_MAINMEM_START; /* default */
567
568        /* This driver only support HOST systems, we check for HOST */
569        if ( !(priv->regs->cfg_stat & CFGSTAT_HOST) ) {
570                /* Target not supported */
571                return -2;
572        }
573
574        /* Init the PCI Core */
575        if ( grpci_hw_init(priv) ) {
576                return -3;
577        }
578
579        /* Down streams translation table */
580        priv->maps_down[0].name = "AMBA -> PCI MEM Window";
581        priv->maps_down[0].size = priv->pci_area_end - priv->pci_area;
582        priv->maps_down[0].from_adr = (void *)priv->pci_area;
583        priv->maps_down[0].to_adr = (void *)priv->pci_area;
584        /* End table */
585        priv->maps_down[1].size = 0;
586
587        /* Up streams translation table */
588        priv->maps_up[0].name = "Target BAR1 -> AMBA";
589        priv->maps_up[0].size = priv->bar1_size;
590        priv->maps_up[0].from_adr = (void *)priv->bar1_pci_adr;
591        priv->maps_up[0].to_adr = (void *)priv->bar1_pci_adr;
592        /* End table */
593        priv->maps_up[1].size = 0;
594
595        return 0;
596}
597
598/* Called when a core is found with the AMBA device and vendor ID
599 * given in grpci_ids[]. IRQ, Console does not work here
600 */
601int grpci_init1(struct drvmgr_dev *dev)
602{
603        int status;
604        struct grpci_priv *priv;
605        struct pci_auto_setup grpci_auto_cfg;
606
607        DBG("GRPCI[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
608
609        if ( grpci_minor != 0 ) {
610                DBG("Driver only supports one PCI core\n");
611                return DRVMGR_FAIL;
612        }
613
614        if ( (strcmp(dev->parent->dev->drv->name, "AMBAPP_GRLIB_DRV") != 0) &&
615             (strcmp(dev->parent->dev->drv->name, "AMBAPP_LEON2_DRV") != 0) ) {
616                /* We only support GRPCI driver on local bus */
617                return DRVMGR_FAIL;
618        }
619
620        priv = dev->priv;
621        if ( !priv )
622                return DRVMGR_NOMEM;
623
624        priv->dev = dev;
625        priv->minor = grpci_minor++;
626
627        grpcipriv = priv;
628        status = grpci_init(priv);
629        if (status) {
630                printf("Failed to initialize grpci driver %d\n", status);
631                return DRVMGR_FAIL;
632        }
633
634
635        /* Register the PCI core at the PCI layers */
636
637        if (priv->bt_enabled == 0) {
638                /* Host is Big-Endian */
639                pci_endian = PCI_BIG_ENDIAN;
640
641                memcpy(&grpci_access_drv.io, &grpci_io_ops_be,
642                                                sizeof(grpci_io_ops_be));
643                grpci_access_drv.memreg = &pci_memreg_sparc_be_ops;
644        }
645
646        if (pci_access_drv_register(&grpci_access_drv)) {
647                /* Access routines registration failed */
648                return DRVMGR_FAIL;
649        }
650
651        /* Prepare memory MAP */
652        grpci_auto_cfg.options = 0;
653        grpci_auto_cfg.mem_start = 0;
654        grpci_auto_cfg.mem_size = 0;
655        grpci_auto_cfg.memio_start = priv->pci_area;
656        grpci_auto_cfg.memio_size = priv->pci_area_end - priv->pci_area;
657        grpci_auto_cfg.io_start = priv->pci_io;
658        grpci_auto_cfg.io_size = priv->pci_conf - priv->pci_io;
659        grpci_auto_cfg.irq_map = grpci_bus0_irq_map;
660        grpci_auto_cfg.irq_route = NULL; /* use standard routing */
661        pci_config_register(&grpci_auto_cfg);
662
663        if (pci_config_init()) {
664                /* PCI configuration failed */
665                return DRVMGR_FAIL;
666        }
667
668        priv->config.maps_down = &priv->maps_down[0];
669        priv->config.maps_up = &priv->maps_up[0];
670        return pcibus_register(dev, &priv->config);
671}
672
673/* DMA functions which uses GRPCIs optional DMA controller (len in words) */
674int grpci_dma_to_pci(
675        unsigned int ahb_addr,
676        unsigned int pci_addr,
677        unsigned int len)
678{
679    int ret = 0;
680
681    pcidma[0] = 0x82;
682    pcidma[1] = ahb_addr;
683    pcidma[2] = pci_addr;
684    pcidma[3] = len;
685    pcidma[0] = 0x83;       
686
687    while ( (pcidma[0] & 0x4) == 0)
688        ;
689
690    if (pcidma[0] & 0x8) { /* error */
691        ret = -1;
692    }
693
694    pcidma[0] |= 0xC;
695    return ret;
696
697}
698
699int grpci_dma_from_pci(
700        unsigned int ahb_addr,
701        unsigned int pci_addr,
702        unsigned int len)
703{
704    int ret = 0;
705
706    pcidma[0] = 0x80;
707    pcidma[1] = ahb_addr;
708    pcidma[2] = pci_addr;
709    pcidma[3] = len;
710    pcidma[0] = 0x81;       
711
712    while ( (pcidma[0] & 0x4) == 0)
713        ;
714
715    if (pcidma[0] & 0x8) { /* error */
716        ret = -1;
717    }
718
719    pcidma[0] |= 0xC;
720    return ret;
721
722}
Note: See TracBrowser for help on using the repository browser.