Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:08

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*  LEON2 AT697 PCI Host Driver.
0004  * 
0005  *  COPYRIGHT (c) 2008.
0006  *  Cobham Gaisler AB.
0007  *
0008  *  Configures the AT697 PCI core and initialize,
0009  *   - the PCI Library (pci.c)
0010  *   - the general part of the PCI Bus driver (pci_bus.c)
0011  *  
0012  *  System interrupt assigned to PCI interrupt (INTA#..INTD#) is by
0013  *  default taken from Plug and Play, but may be overridden by the 
0014  *  driver resources INTA#..INTD#.
0015  *
0016  * Redistribution and use in source and binary forms, with or without
0017  * modification, are permitted provided that the following conditions
0018  * are met:
0019  * 1. Redistributions of source code must retain the above copyright
0020  *    notice, this list of conditions and the following disclaimer.
0021  * 2. Redistributions in binary form must reproduce the above copyright
0022  *    notice, this list of conditions and the following disclaimer in the
0023  *    documentation and/or other materials provided with the distribution.
0024  *
0025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0035  * POSSIBILITY OF SUCH DAMAGE.
0036  */
0037 
0038 /* Configurable parameters
0039  * =======================
0040  *  INT[A..D]#         Select system IRQ (can be tranlated into I/O interrupt)
0041  *  INT[A..D]#_PIO     Select PIO used to generate I/O interrupt
0042  *
0043  * Notes
0044  * =====
0045  *  IRQ must not be enabled before all PCI boards have been enabled, the
0046  *  IRQ is therefore enabled first in init2. The init2() for this driver
0047  *  is assumed to be executed earlier that all boards and their devices
0048  *  driver's init2() function.
0049  *
0050  */
0051 
0052 #include <rtems/bspIo.h>
0053 #include <stdlib.h>
0054 #include <string.h>
0055 #include <stdio.h>
0056 #include <libcpu/byteorder.h>
0057 #include <libcpu/access.h>
0058 #include <pci.h>
0059 #include <pci/cfg.h>
0060 
0061 #include <drvmgr/drvmgr.h>
0062 #include <drvmgr/pci_bus.h>
0063 #include <drvmgr/leon2_amba_bus.h>
0064 
0065 #include <bsp/at697_pci.h>
0066 #include <leon.h>
0067 
0068 /* Configuration options */
0069 
0070 #define SYSTEM_MAINMEM_START    0x40000000
0071 #define SYSTEM_MAINMEM_START2   0x60000000
0072 
0073 /* Interrupt assignment. Set to other value than 0xff in order to 
0074  * override defaults and plug&play information
0075  */
0076 #ifndef AT697_INTA_SYSIRQ
0077  #define AT697_INTA_SYSIRQ 0xff
0078 #endif
0079 #ifndef AT697_INTB_SYSIRQ
0080  #define AT697_INTB_SYSIRQ 0xff
0081 #endif
0082 #ifndef AT697_INTC_SYSIRQ
0083  #define AT697_INTC_SYSIRQ 0xff
0084 #endif
0085 #ifndef AT697_INTD_SYSIRQ
0086  #define AT697_INTD_SYSIRQ 0xff
0087 #endif
0088 
0089 #ifndef AT697_INTA_PIO
0090  #define AT697_INTA_PIO 0xff
0091 #endif
0092 #ifndef AT697_INTB_PIO
0093  #define AT697_INTB_PIO 0xff
0094 #endif
0095 #ifndef AT697_INTC_PIO
0096  #define AT697_INTC_PIO 0xff
0097 #endif
0098 #ifndef AT697_INTD_PIO
0099  #define AT697_INTD_PIO 0xff
0100 #endif
0101 
0102 
0103 /* AT697 PCI */
0104 #define AT697_PCI_REG_ADR 0x80000100
0105 
0106 /* PCI Window used */
0107 #define PCI_MEM_START 0xa0000000
0108 #define PCI_MEM_END   0xf0000000
0109 #define PCI_MEM_SIZE  (PCI_MEM_END - PCI_MEM_START)
0110 
0111 /* #define DEBUG 1 */
0112 
0113 #ifdef DEBUG
0114 #define DBG(x...) printf(x)
0115 #else
0116 #define DBG(x...) 
0117 #endif
0118 
0119 struct at697pci_regs {
0120     volatile unsigned int pciid1;        /* 0x80000100 - PCI Device identification register 1         */
0121     volatile unsigned int pcisc;         /* 0x80000104 - PCI Status & Command                         */
0122     volatile unsigned int pciid2;        /* 0x80000108 - PCI Device identification register 2         */
0123     volatile unsigned int pcibhlc;       /* 0x8000010c - BIST, Header type, Cache line size register  */
0124     volatile unsigned int mbar1;         /* 0x80000110 - Memory Base Address Register 1               */
0125     volatile unsigned int mbar2;         /* 0x80000114 - Memory Base Address Register 2               */
0126     volatile unsigned int iobar3;        /* 0x80000118 - IO Base Address Register 3                   */
0127     volatile unsigned int dummy1[4];     /* 0x8000011c - 0x80000128                                   */ 
0128     volatile unsigned int pcisid;        /* 0x8000012c - Subsystem identification register            */
0129     volatile unsigned int dummy2;        /* 0x80000130                                                */
0130     volatile unsigned int pcicp;         /* 0x80000134 - PCI capabilities pointer register            */
0131     volatile unsigned int dummy3;        /* 0x80000138                                                */
0132     volatile unsigned int pcili;         /* 0x8000013c - PCI latency interrupt register               */
0133     volatile unsigned int pcirt;         /* 0x80000140 - PCI retry, trdy config                       */
0134     volatile unsigned int pcicw;         /* 0x80000144 - PCI configuration write register             */
0135     volatile unsigned int pcisa;         /* 0x80000148 - PCI Initiator Start Address                  */
0136     volatile unsigned int pciiw;         /* 0x8000014c - PCI Initiator Write Register                 */
0137     volatile unsigned int pcidma;        /* 0x80000150 - PCI DMA configuration register               */
0138     volatile unsigned int pciis;         /* 0x80000154 - PCI Initiator Status Register                */
0139     volatile unsigned int pciic;         /* 0x80000158 - PCI Initiator Configuration                  */
0140     volatile unsigned int pcitpa;        /* 0x8000015c - PCI Target Page Address Register             */   
0141     volatile unsigned int pcitsc;        /* 0x80000160 - PCI Target Status-Command Register           */
0142     volatile unsigned int pciite;        /* 0x80000164 - PCI Interrupt Enable Register                */
0143     volatile unsigned int pciitp;        /* 0x80000168 - PCI Interrupt Pending Register               */
0144     volatile unsigned int pciitf;        /* 0x8000016c - PCI Interrupt Force Register                 */
0145     volatile unsigned int pcid;          /* 0x80000170 - PCI Data Register                            */   
0146     volatile unsigned int pcibe;         /* 0x80000174 - PCI Burst End Register                       */
0147     volatile unsigned int pcidmaa;       /* 0x80000178 - PCI DMA Address Register                     */
0148 };
0149 
0150 /* PCI Interrupt assignment. Connects an PCI interrupt pin (INTA#..INTD#)
0151  * to a system interrupt number.
0152  */
0153 unsigned char at697_pci_irq_table[4] =
0154 {
0155     /* INTA# */ AT697_INTA_SYSIRQ,
0156     /* INTB# */ AT697_INTB_SYSIRQ,
0157     /* INTC# */ AT697_INTC_SYSIRQ,
0158     /* INTD# */ AT697_INTD_SYSIRQ
0159 };
0160 
0161 /* PCI Interrupt PIO assignment. Selects which GPIO pin will be used to
0162  * generate the system IRQ.
0163  *
0164  * PCI IRQ -> GPIO -> 4 x I/O select -> System IRQ
0165  *              ^- pio_table              ^- irq_select
0166  */
0167 unsigned char at697_pci_irq_pio_table[4] =
0168 {
0169     /* INTA# */ AT697_INTA_PIO,
0170     /* INTB# */ AT697_INTB_PIO,
0171     /* INTC# */ AT697_INTC_PIO,
0172     /* INTD# */ AT697_INTD_PIO
0173 };
0174 
0175 /* Driver private data struture */
0176 struct at697pci_priv {
0177     struct drvmgr_dev   *dev;
0178     struct at697pci_regs    *regs;
0179     int         minor;
0180 
0181     uint32_t        bar1_pci_adr;
0182     uint32_t        bar2_pci_adr;
0183 
0184     struct drvmgr_map_entry maps_up[3];
0185     struct drvmgr_map_entry maps_down[2];
0186     struct pcibus_config    config;
0187 };
0188 
0189 struct at697pci_priv *at697pcipriv = NULL;
0190 static int at697pci_minor = 0;
0191 
0192 int at697pci_init1(struct drvmgr_dev *dev);
0193 int at697pci_init2(struct drvmgr_dev *dev);
0194 
0195 /* AT697 PCI DRIVER */
0196 
0197 struct drvmgr_drv_ops at697pci_ops = 
0198 {
0199     .init = {at697pci_init1, at697pci_init2, NULL, NULL},
0200     .remove = NULL,
0201     .info = NULL
0202 };
0203 
0204 struct leon2_amba_dev_id at697pci_ids[] = 
0205 {
0206     {LEON2_AMBA_AT697PCI_ID},
0207     {0}     /* Mark end of table */
0208 };
0209 
0210 struct leon2_amba_drv_info at697pci_info =
0211 {
0212     {
0213         DRVMGR_OBJ_DRV,         /* Driver */
0214         NULL,               /* Next driver */
0215         NULL,               /* Device list */
0216         DRIVER_LEON2_AMBA_AT697PCI, /* Driver ID */
0217         "AT697PCI_DRV",         /* Driver Name */
0218         DRVMGR_BUS_TYPE_LEON2_AMBA, /* Bus Type */
0219         &at697pci_ops,
0220         NULL,               /* Funcs */
0221         0,              /* No devices yet */
0222         sizeof(struct at697pci_priv),   /* let drvmgr alloc private */
0223     },
0224     &at697pci_ids[0]
0225 };
0226 
0227 void at697pci_register_drv(void)
0228 {
0229     DBG("Registering AT697 PCI driver\n");
0230     drvmgr_drv_register(&at697pci_info.general);
0231 }
0232 
0233 /*  The configuration access functions uses the DMA functionality of the
0234  *  AT697 pci controller to be able access all slots
0235  */
0236 
0237 static int at697pci_cfg_r32(pci_dev_t dev, int offset, uint32_t *val)
0238 {
0239     struct at697pci_regs *regs;
0240     volatile unsigned int data = 0;
0241     unsigned int address;
0242     int bus = PCI_DEV_BUS(dev);
0243     int slot = PCI_DEV_SLOT(dev);
0244     int func = PCI_DEV_FUNC(dev);
0245     int retval;
0246 
0247     if (slot > 15 || (offset & ~0xfc)) {
0248         *val = 0xffffffff;
0249         return PCISTS_EINVAL;
0250     }
0251 
0252     regs = at697pcipriv->regs;
0253 
0254     regs->pciitp = 0xff; /* clear interrupts */ 
0255 
0256     if ( bus == 0 ) {
0257         /* PCI Access - TYPE 0 */
0258         address = (1<<(16+slot)) | (func << 8) | offset;
0259     } else {
0260         /* PCI access - TYPE 1 */
0261         address = ((bus & 0xff) << 16) | ((slot & 0x1f) << 11) |
0262                 (func << 8) | offset | 1;
0263     }
0264     regs->pcisa = address;
0265     regs->pcidma = 0xa01;
0266     regs->pcidmaa = (unsigned int) &data;
0267 
0268     while (regs->pciitp == 0)
0269         ;
0270 
0271     regs->pciitp = 0xff; /* clear interrupts */ 
0272 
0273     if (regs->pcisc & 0x20000000)  { /* Master Abort */
0274         regs->pcisc |= 0x20000000;
0275         *val = 0xffffffff;
0276         retval = PCISTS_MSTABRT;
0277     } else {
0278         *val = data;
0279         retval = PCISTS_OK;
0280     }
0281 
0282     DBG("pci_read - bus: %d, dev: %d, fn: %d, off: %d => addr: %x, val: %x\n",
0283         bus, slot, func, offset,  address, *val); 
0284 
0285     return retval;
0286 }
0287 
0288 static int at697pci_cfg_r16(pci_dev_t dev, int ofs, uint16_t *val)
0289 {
0290     uint32_t v;
0291     int retval;
0292 
0293     if (ofs & 1)
0294         return PCISTS_EINVAL;
0295 
0296     retval = at697pci_cfg_r32(dev, ofs & ~0x3, &v);
0297     *val = 0xffff & (v >> (8*(ofs & 0x3)));
0298 
0299     return retval;
0300 }
0301 
0302 static int at697pci_cfg_r8(pci_dev_t dev, int ofs, uint8_t *val)
0303 {
0304     uint32_t v;
0305     int retval;
0306 
0307     retval = at697pci_cfg_r32(dev, ofs & ~0x3, &v);
0308 
0309     *val = 0xff & (v >> (8*(ofs & 3)));
0310 
0311     return retval;
0312 }
0313 
0314 static int at697pci_cfg_w32(pci_dev_t dev, int offset, uint32_t val)
0315 {
0316     struct at697pci_regs *regs;
0317     volatile unsigned int tmp_val = val;
0318     unsigned int address;
0319     int bus = PCI_DEV_BUS(dev);
0320     int slot = PCI_DEV_SLOT(dev);
0321     int func = PCI_DEV_FUNC(dev);
0322     int retval;
0323 
0324     if (slot > 15 || (offset & ~0xfc))
0325         return PCISTS_EINVAL;
0326 
0327     regs = at697pcipriv->regs;
0328 
0329     regs->pciitp = 0xff; /* clear interrupts */
0330 
0331     if ( bus == 0 ) {
0332         /* PCI Access - TYPE 0 */
0333         address = (1<<(16+slot)) | (func << 8) | offset;
0334     } else {
0335         /* PCI access - TYPE 1 */
0336         address = ((bus & 0xff) << 16) | ((slot & 0x1f) << 11) |
0337                 (func << 8) | offset | 1;
0338     }
0339     regs->pcisa = address;
0340     regs->pcidma = 0xb01;
0341     regs->pcidmaa = (unsigned int) &tmp_val;
0342 
0343     while (regs->pciitp == 0)
0344         ;
0345 
0346     if (regs->pcisc & 0x20000000)  { /* Master Abort */
0347         regs->pcisc |= 0x20000000;
0348         retval = PCISTS_MSTABRT;
0349     } else
0350         retval = PCISTS_OK;
0351 
0352     regs->pciitp = 0xff; /* clear interrupts */
0353 
0354     DBG("pci_write - bus: %d, dev: %d, fn: %d, off: %d => addr: %x, val: %x\n",
0355         bus, slot, func, offset, address, val);
0356 
0357     return retval;
0358 }
0359 
0360 static int at697pci_cfg_w16(pci_dev_t dev, int ofs, uint16_t val)
0361 {
0362     uint32_t v;
0363     int retval;
0364 
0365     if (ofs & 1)
0366         return PCISTS_EINVAL;
0367 
0368     retval = at697pci_cfg_r32(dev, ofs & ~0x3, &v);
0369     if (retval != PCISTS_OK)
0370         return retval;
0371 
0372     v = (v & ~(0xffff << (8*(ofs&3)))) | ((0xffff&val) << (8*(ofs&3)));
0373 
0374     return at697pci_cfg_w32(dev, ofs & ~0x3, v);
0375 }
0376 
0377 static int at697pci_cfg_w8(pci_dev_t dev, int ofs, uint8_t val)
0378 {
0379     uint32_t v;
0380 
0381     at697pci_cfg_r32(dev, ofs & ~0x3, &v);
0382 
0383     v = (v & ~(0xff << (8*(ofs&3)))) | ((0xff&val) << (8*(ofs&3)));
0384 
0385     return at697pci_cfg_w32(dev, ofs & ~0x3, v);
0386 }
0387 
0388 /* Return the assigned system IRQ number that corresponds to the PCI
0389  * "Interrupt Pin" information from configuration space.
0390  *
0391  * The IRQ information is stored in the at697_pci_irq_table configurable
0392  * by the user.
0393  *
0394  * Returns the "system IRQ" for the PCI INTA#..INTD# pin in irq_pin. Returns
0395  * 0xff if not assigned.
0396  */
0397 static uint8_t at697pci_bus0_irq_map(pci_dev_t dev, int irq_pin)
0398 {
0399     uint8_t sysIrqNr = 0; /* not assigned */
0400     int irq_group;
0401 
0402     if ( (irq_pin >= 1) && (irq_pin <= 4) ) {
0403         /* Use default IRQ decoding on PCI BUS0 according slot numbering */
0404         irq_group = PCI_DEV_SLOT(dev) & 0x3;
0405         irq_pin = ((irq_pin - 1) + irq_group) & 0x3;
0406         /* Valid PCI "Interrupt Pin" number */
0407         sysIrqNr = at697_pci_irq_table[irq_pin];
0408     }
0409     return sysIrqNr;
0410 }
0411 
0412 static int at697pci_translate(uint32_t *address, int type, int dir)
0413 {
0414     /* No address translation implmented at this point */
0415     return 0;
0416 }
0417 
0418 extern struct pci_memreg_ops pci_memreg_sparc_be_ops;
0419 
0420 /* AT697 Big-Endian PCI access routines */
0421 static struct pci_access_drv at697pci_access_drv = {
0422     .cfg =
0423     {
0424         at697pci_cfg_r8,
0425         at697pci_cfg_r16,
0426         at697pci_cfg_r32,
0427         at697pci_cfg_w8,
0428         at697pci_cfg_w16,
0429         at697pci_cfg_w32,
0430     },
0431     .io =
0432     {   /* AT697 only supports non-standard Big-Endian PCI Bus */
0433         _ld8,
0434         _ld_be16,
0435         _ld_be32,
0436         _st8,
0437         _st_be16,
0438         _st_be32,
0439 
0440     },
0441     .memreg = &pci_memreg_sparc_be_ops,
0442     .translate = at697pci_translate,
0443 };
0444 
0445 /* Initializes the AT697PCI core hardware
0446  *
0447  */
0448 static int at697pci_hw_init(struct at697pci_priv *priv)
0449 {
0450     struct at697pci_regs *regs = priv->regs;
0451     unsigned short vendor = regs->pciid1 >> 16;
0452 
0453     /* Must match ATMEL or ESA ID */
0454     if ( !((vendor == 0x1202) || (vendor == 0x1E0F)) ) {
0455         /* No AT697 PCI, quit */
0456         return -1;
0457     }
0458 
0459     /* If not in system slot we are not host and we must abort.
0460      * This is a host only driver.
0461      */
0462     if ((regs->pciis & 0x1000) != 0) {
0463         return -1;
0464     }
0465 
0466     /* Reset PCI Core */
0467     regs->pciic = 0xffffffff;
0468 
0469     /* Mask PCI interrupts */
0470     regs->pciite = 0;
0471 
0472     /* Map parts of AT697 main memory into PCI (for DMA) */
0473     regs->mbar1  = priv->bar1_pci_adr;
0474     regs->mbar2  = priv->bar2_pci_adr;
0475     regs->pcitpa = (priv->bar1_pci_adr & 0xff000000) |
0476                    ((priv->bar2_pci_adr>>16) & 0xff00);
0477 
0478     /* Enable PCI master and target memory command response  */
0479     regs->pcisc |= 0x40 | 0x6;
0480 
0481     /* Set latency timer to 64 */
0482     regs->pcibhlc = 0x00004000;
0483 
0484     /* Set Inititator configuration so that AHB slave accesses generate memory read/write commands */
0485     regs->pciic = 0x41;
0486 
0487     return 0;
0488 }
0489 
0490 /* Initializes the AT697PCI core and driver, must be called before calling init_pci() 
0491  *
0492  * Return values
0493  *  0             Successful initalization
0494  *  -1            Error during initialization.
0495  */
0496 static int at697pci_init(struct at697pci_priv *priv)
0497 {
0498     int pin;
0499     union drvmgr_key_value *value;
0500     char keyname_sysirq[6];
0501     char keyname_pio[10];
0502 
0503     /* PCI core, init private structure */
0504     priv->regs = (struct at697pci_regs *) AT697_PCI_REG_ADR;
0505 
0506     /* Init PCI interrupt assignment table to all use the interrupt routed
0507      * through the GPIO core.
0508      *
0509      * INT[A..D]# selects system IRQ (and I/O interrupt)
0510      * INT[A..D]#_PIO selects PIO used to generate I/O interrupt
0511      */
0512     strcpy(keyname_sysirq, "INTX#");
0513     strcpy(keyname_pio, "INTX#_PIO");
0514     for (pin=1; pin<5; pin++) {
0515         if ( at697_pci_irq_table[pin-1] == 0xff ) {
0516             /* User may override hardcoded IRQ setup */
0517             keyname_sysirq[3] = 'A' + (pin-1);
0518             value = drvmgr_dev_key_get(priv->dev,
0519                     keyname_sysirq, DRVMGR_KT_INT);
0520             if ( value )
0521                 at697_pci_irq_table[pin-1] = value->i;
0522         }
0523         if ( at697_pci_irq_pio_table[pin-1] == 0xff ) {
0524             /* User may override hardcoded IRQ setup */
0525             keyname_pio[3] = 'A' + (pin-1);
0526             value = drvmgr_dev_key_get(priv->dev,
0527                         keyname_pio, DRVMGR_KT_INT);
0528             if ( value )
0529                 at697_pci_irq_pio_table[pin-1] = value->i;
0530         }
0531     }
0532 
0533     /* Use GRPCI target BAR1 and BAR2 to map CPU RAM to PCI, this is to
0534      * make it possible for PCI peripherals to do DMA directly to CPU memory
0535      *
0536      * Defualt is to map system RAM at pci address 0x40000000 and system
0537      * SDRAM to pci address 0x60000000
0538      */
0539     value = drvmgr_dev_key_get(priv->dev, "tgtbar1", DRVMGR_KT_INT);
0540     if (value)
0541         priv->bar1_pci_adr = value->i;
0542     else
0543         priv->bar1_pci_adr = SYSTEM_MAINMEM_START; /* default */
0544 
0545     value = drvmgr_dev_key_get(priv->dev, "tgtbar2", DRVMGR_KT_INT);
0546     if (value)
0547         priv->bar2_pci_adr = value->i;
0548     else
0549         priv->bar2_pci_adr = SYSTEM_MAINMEM_START2; /* default */
0550 
0551     /* Init the PCI Core */
0552     if ( at697pci_hw_init(priv) ) {
0553         return -3;
0554     }
0555 
0556     /* Down streams translation table */
0557     priv->maps_down[0].name = "AMBA -> PCI MEM Window";
0558     priv->maps_down[0].size = 0xF0000000 - 0xA0000000;
0559     priv->maps_down[0].from_adr = (void *)0xA0000000;
0560     priv->maps_down[0].to_adr = (void *)0xA0000000;
0561     /* End table */
0562     priv->maps_down[1].size = 0;
0563 
0564     /* Up streams translation table, 2x16Mb mapped 1:1  */
0565     priv->maps_up[0].name = "Target BAR0 -> AMBA";
0566     priv->maps_up[0].size = 0x01000000; /* 16Mb BAR1 */
0567     priv->maps_up[0].from_adr = (void *)priv->bar1_pci_adr;
0568     priv->maps_up[0].to_adr = (void *)priv->bar1_pci_adr;
0569     priv->maps_up[1].name = "Target BAR1 -> AMBA";
0570     priv->maps_up[1].size = 0x01000000; /* 16Mb BAR2 */
0571     priv->maps_up[1].from_adr = (void *)priv->bar2_pci_adr;
0572     priv->maps_up[1].to_adr = (void *)priv->bar2_pci_adr;
0573     /* End table */
0574     priv->maps_up[2].size = 0;
0575 
0576     return 0;
0577 }
0578 
0579 /* Called when a core is found with the AMBA device and vendor ID 
0580  * given in at697pci_ids[].
0581  */
0582 int at697pci_init1(struct drvmgr_dev *dev)
0583 {
0584     struct at697pci_priv *priv;
0585     struct pci_auto_setup at697pci_auto_cfg;
0586 
0587     DBG("AT697PCI[%d] on bus %s\n", dev->minor_drv,
0588         dev->parent->dev->name);
0589 
0590     if ( at697pci_minor != 0 ) {
0591         DBG("Driver only supports one PCI core\n");
0592         return DRVMGR_FAIL;
0593     }
0594 
0595     at697pcipriv = priv = dev->priv;
0596     if ( !priv )
0597         return DRVMGR_NOMEM;
0598 
0599     priv->dev = dev;
0600     priv->minor = at697pci_minor++;
0601 
0602     if (at697pci_init(priv)) {
0603         DBG("Failed to initialize at697pci driver\n");
0604         return DRVMGR_EIO;
0605     }
0606 
0607     /* Host is always Big-Endian */
0608     pci_endian = PCI_BIG_ENDIAN;
0609 
0610     if (pci_access_drv_register(&at697pci_access_drv)) {
0611         /* Access routines registration failed */
0612         return DRVMGR_FAIL;
0613     }
0614 
0615     /* Prepare memory MAP */
0616     at697pci_auto_cfg.options = 0;
0617     at697pci_auto_cfg.mem_start = 0;
0618     at697pci_auto_cfg.mem_size = 0;
0619     at697pci_auto_cfg.memio_start = PCI_MEM_START;
0620     at697pci_auto_cfg.memio_size = PCI_MEM_SIZE;
0621     at697pci_auto_cfg.io_start = 0;
0622     at697pci_auto_cfg.io_size = 0;
0623     at697pci_auto_cfg.irq_map = at697pci_bus0_irq_map;
0624     at697pci_auto_cfg.irq_route = NULL; /* use standard routing */
0625     pci_config_register(&at697pci_auto_cfg);
0626 
0627     if (pci_config_init()) {
0628         /* PCI configuration failed */
0629         return DRVMGR_FAIL;
0630     }
0631 
0632     priv->config.maps_down = &priv->maps_down[0];
0633     priv->config.maps_up = &priv->maps_up[0];
0634     return pcibus_register(dev, &priv->config);
0635 }
0636 
0637 int at697pci_init2(struct drvmgr_dev *dev)
0638 {
0639 #if 0
0640     struct at697pci_priv *priv = dev->priv;
0641 #endif
0642     int pin, irq, pio, ioport;
0643     LEON_Register_Map *regs = (LEON_Register_Map *)0x80000000;
0644 
0645     /* Enable interrupts now that init1 has been reached for all devices
0646      * on the bus.
0647      */
0648 
0649     for (pin=1; pin<5; pin++) {
0650         irq = at697_pci_irq_table[pin-1];
0651         pio = at697_pci_irq_pio_table[pin-1];
0652         if ( (pio < 16) && (irq >= 4) && (irq <= 7) ) {
0653             /* AT697 I/O IRQ, we know how to set up this 
0654              *
0655              * IRQ 4 -> I/O 0
0656              * IRQ 5 -> I/O 1
0657              * IRQ 6 -> I/O 2
0658              * IRQ 7 -> I/O 3
0659              */
0660             ioport = irq - 4;
0661 
0662             /* First disable interrupts */
0663             regs->PIO_Interrupt &= ~(0xff << (ioport * 8));
0664             /* Set PIO as input pin */
0665             regs->PIO_Direction &= ~(1 << pio);
0666             /* Set Low Level sensitivity */
0667             regs->PIO_Interrupt |= ((0x80 | pio) << (ioport * 8));
0668         }
0669     }
0670 
0671     /* Unmask Interrupt */
0672     /*priv->regs->pciite = 0xff;*/
0673 
0674     return DRVMGR_OK;
0675 }