Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*  GR-RASTA-IO PCI Target driver.
0004  * 
0005  *  COPYRIGHT (c) 2008.
0006  *  Cobham Gaisler AB.
0007  *
0008  *  Configures the GR-RASTA-IO interface PCI board.
0009  *  This driver provides a AMBA PnP bus by using the general part
0010  *  of the AMBA PnP bus driver (ambapp_bus.c).
0011  *
0012  *  Driver resources for the AMBA PnP bus provided can be set using
0013  *  gr_rasta_io_set_resources().
0014  *
0015  * Redistribution and use in source and binary forms, with or without
0016  * modification, are permitted provided that the following conditions
0017  * are met:
0018  * 1. Redistributions of source code must retain the above copyright
0019  *    notice, this list of conditions and the following disclaimer.
0020  * 2. Redistributions in binary form must reproduce the above copyright
0021  *    notice, this list of conditions and the following disclaimer in the
0022  *    documentation and/or other materials provided with the distribution.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0027  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0028  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0029  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0030  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0031  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0032  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0033  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0034  * POSSIBILITY OF SUCH DAMAGE.
0035  */
0036 
0037 #include <inttypes.h>
0038 #include <stdio.h>
0039 #include <stdlib.h>
0040 #include <string.h>
0041 #include <sys/types.h>
0042 #include <sys/stat.h>
0043 
0044 #include <bsp.h>
0045 #include <rtems/bspIo.h>
0046 #include <pci.h>
0047 
0048 #include <grlib/ambapp.h>
0049 #include <grlib/grlib.h>
0050 #include <drvmgr/drvmgr.h>
0051 #include <grlib/ambapp_bus.h>
0052 #include <drvmgr/pci_bus.h>
0053 #include <grlib/bspcommon.h>
0054 #include <grlib/genirq.h>
0055 
0056 #include <grlib/gr_rasta_io.h>
0057 
0058 #include <grlib/grlib_impl.h>
0059 
0060 /* Determines which PCI address the AHB masters will access, it should be
0061  * set so that the masters can access the CPU RAM. Default is base of CPU RAM,
0062  * CPU RAM is mapped 1:1 to PCI space.
0063  */
0064 extern unsigned int _RAM_START;
0065 #define AHBMST2PCIADR (((unsigned int)&_RAM_START) & 0xf0000000)
0066 
0067 /* Offset from 0x80000000 (dual bus version) */
0068 #define AHB1_BASE_ADDR 0x80000000
0069 #define AHB1_IOAREA_BASE_ADDR 0x80100000
0070 #define AHB1_IOAREA_OFS (AHB1_IOAREA_BASE_ADDR - AHB1_BASE_ADDR)
0071 
0072 /* Second revision constants (GRPCI2) */
0073 #define GRPCI2_BAR0_TO_AHB_MAP 0x04  /* Fixme */
0074 #define GRPCI2_BAR1_TO_AHB_MAP 0x08  /* Fixme */
0075 #define GRPCI2_PCI_CONFIG      0x20  /* Fixme */
0076 
0077 
0078 /* #define DEBUG 1 */
0079 
0080 #ifdef DEBUG
0081 #define DBG(x...) printk(x)
0082 #else
0083 #define DBG(x...) 
0084 #endif
0085 
0086 /* PCI ID */
0087 #define PCIID_VENDOR_GAISLER        0x1AC8
0088 
0089 int gr_rasta_io_init1(struct drvmgr_dev *dev);
0090 int gr_rasta_io_init2(struct drvmgr_dev *dev);
0091 void gr_rasta_io_isr (void *arg);
0092 
0093 struct grpci_regs {
0094     volatile unsigned int cfg_stat;
0095     volatile unsigned int bar0;
0096     volatile unsigned int page0;
0097     volatile unsigned int bar1;
0098     volatile unsigned int page1;
0099     volatile unsigned int iomap;
0100     volatile unsigned int stat_cmd;
0101 };
0102 
0103 struct grpci2_regs {
0104     volatile unsigned int ctrl;
0105     volatile unsigned int statcap;
0106     volatile unsigned int pcimstprefetch;
0107     volatile unsigned int ahbtopciiomap;
0108     volatile unsigned int dmactrl;
0109     volatile unsigned int dmadesc;
0110     volatile unsigned int dmachanact;
0111     volatile unsigned int reserved;
0112     volatile unsigned int pcibartoahb[6];
0113     volatile unsigned int reserved2[2];
0114     volatile unsigned int ahbtopcimemmap[16];
0115     volatile unsigned int trcctrl;
0116     volatile unsigned int trccntmode;
0117     volatile unsigned int trcadpat;
0118     volatile unsigned int trcadmask;
0119     volatile unsigned int trcctrlsigpat;
0120     volatile unsigned int trcctrlsigmask;
0121     volatile unsigned int trcadstate;
0122     volatile unsigned int trcctrlsigstate;
0123 };
0124 
0125 struct gr_rasta_io_ver {
0126     const unsigned int  amba_freq_hz;   /* The frequency */
0127     const unsigned int  amba_ioarea;    /* The address where the PnP IOAREA starts at */
0128 };
0129 
0130 /* Private data structure for driver */
0131 struct gr_rasta_io_priv {
0132     /* Driver management */
0133     struct drvmgr_dev       *dev;
0134     char                prefix[16];
0135     SPIN_DECLARE(devlock);
0136 
0137     /* PCI */
0138     pci_dev_t           pcidev;
0139     struct pci_dev_info     *devinfo;
0140     uint32_t            ahbmst2pci_map;
0141 
0142     /* IRQ */
0143     genirq_t            genirq;
0144 
0145     /* GR-RASTA-IO */
0146     struct gr_rasta_io_ver      *version;
0147     struct irqmp_regs       *irq;
0148     struct grpci_regs       *grpci;
0149     struct grpci2_regs      *grpci2;
0150     struct drvmgr_map_entry     bus_maps_down[3];
0151     struct drvmgr_map_entry     bus_maps_up[2];
0152 
0153     /* AMBA Plug&Play information on GR-RASTA-IO */
0154     struct ambapp_bus       abus;
0155     struct ambapp_mmap      amba_maps[4];
0156         struct ambapp_config        config;
0157 };
0158 
0159 struct gr_rasta_io_ver gr_rasta_io_ver0 = {
0160     .amba_freq_hz       = 30000000,
0161     .amba_ioarea        = 0x80100000,
0162 };
0163 
0164 struct gr_rasta_io_ver gr_rasta_io_ver1 = {
0165     .amba_freq_hz       = 50000000,
0166     .amba_ioarea        = 0x80100000,
0167 };
0168 
0169 int ambapp_rasta_io_int_register(
0170     struct drvmgr_dev *dev,
0171     int irq,
0172     const char *info,
0173     drvmgr_isr handler,
0174     void *arg);
0175 int ambapp_rasta_io_int_unregister(
0176     struct drvmgr_dev *dev,
0177     int irq,
0178     drvmgr_isr handler,
0179     void *arg);
0180 int ambapp_rasta_io_int_unmask(
0181     struct drvmgr_dev *dev,
0182     int irq);
0183 int ambapp_rasta_io_int_mask(
0184     struct drvmgr_dev *dev,
0185     int irq);
0186 int ambapp_rasta_io_int_clear(
0187     struct drvmgr_dev *dev,
0188     int irq);
0189 int ambapp_rasta_io_get_params(
0190     struct drvmgr_dev *dev,
0191     struct drvmgr_bus_params *params);
0192 
0193 struct ambapp_ops ambapp_rasta_io_ops = {
0194     .int_register = ambapp_rasta_io_int_register,
0195     .int_unregister = ambapp_rasta_io_int_unregister,
0196     .int_unmask = ambapp_rasta_io_int_unmask,
0197     .int_mask = ambapp_rasta_io_int_mask,
0198     .int_clear = ambapp_rasta_io_int_clear,
0199     .get_params = ambapp_rasta_io_get_params
0200 };
0201 
0202 struct drvmgr_drv_ops gr_rasta_io_ops = 
0203 {
0204     .init = {gr_rasta_io_init1, gr_rasta_io_init2, NULL, NULL},
0205     .remove = NULL,
0206     .info = NULL
0207 };
0208 
0209 struct pci_dev_id_match gr_rasta_io_ids[] = 
0210 {
0211     PCIID_DEVVEND(PCIID_VENDOR_GAISLER, PCIID_DEVICE_GR_RASTA_IO),
0212     PCIID_DEVVEND(PCIID_VENDOR_GAISLER_OLD, PCIID_DEVICE_GR_RASTA_IO_OLD),
0213     PCIID_END_TABLE /* Mark end of table */
0214 };
0215 
0216 struct pci_drv_info gr_rasta_io_info =
0217 {
0218     {
0219         DRVMGR_OBJ_DRV,         /* Driver */
0220         NULL,               /* Next driver */
0221         NULL,               /* Device list */
0222         DRIVER_PCI_GAISLER_RASTAIO_ID,  /* Driver ID */
0223         "GR-RASTA-IO_DRV",      /* Driver Name */
0224         DRVMGR_BUS_TYPE_PCI,        /* Bus Type */
0225         &gr_rasta_io_ops,
0226         NULL,               /* Funcs */
0227         0,              /* No devices yet */
0228         0,
0229     },
0230     &gr_rasta_io_ids[0]
0231 };
0232 
0233 /* Driver resources configuration for the AMBA bus on the GR-RASTA-IO board.
0234  * It is declared weak so that the user may override it from the project file,
0235  * if the default settings are not enough.
0236  *
0237  * The configuration consists of an array of configuration pointers, each
0238  * pointer determine the configuration of one GR-RASTA-IO board. Pointer
0239  * zero is for board0, pointer 1 for board1 and so on.
0240  *
0241  * The array must end with a NULL pointer.
0242  */
0243 struct drvmgr_bus_res *gr_rasta_io_resources[] __attribute__((weak)) =
0244 {
0245     NULL
0246 };
0247 
0248 void gr_rasta_io_register_drv(void)
0249 {
0250     DBG("Registering GR-RASTA-IO PCI driver\n");
0251     drvmgr_drv_register(&gr_rasta_io_info.general);
0252 }
0253 
0254 void gr_rasta_io_isr (void *arg)
0255 {
0256     struct gr_rasta_io_priv *priv = arg;
0257     unsigned int status, tmp;
0258     int irq;
0259     SPIN_ISR_IRQFLAGS(irqflags);
0260 
0261     tmp = status = priv->irq->ipend;
0262 
0263     /* DBG("GR-RASTA-IO: IRQ 0x%x\n",status); */
0264 
0265     SPIN_LOCK(&priv->devlock, irqflags);
0266     for(irq=0; irq<16; irq++) {
0267         if ( status & (1<<irq) ) {
0268             genirq_doirq(priv->genirq, irq);
0269             priv->irq->iclear = (1<<irq);
0270             status &= ~(1<<irq);
0271             if ( status == 0 )
0272                 break;
0273         }
0274     }
0275     SPIN_UNLOCK(&priv->devlock, irqflags);
0276 
0277     /* ACK interrupt, this is because PCI is Level, so the IRQ Controller still drives the IRQ. */
0278     if ( tmp ) 
0279         drvmgr_interrupt_clear(priv->dev, 0);
0280 
0281     DBG("RASTA-IO-IRQ: 0x%x\n", tmp);
0282 }
0283 
0284 /* PCI Hardware (Revision 0 and 1) initialization */
0285 static int gr_rasta_io_hw_init(struct gr_rasta_io_priv *priv)
0286 {
0287     unsigned int *page0 = NULL;
0288     struct ambapp_dev *tmp;
0289     struct ambapp_ahb_info *ahb;
0290     struct pci_dev_info *devinfo = priv->devinfo;
0291     uint32_t bar0, bar0_size;
0292 
0293     bar0 = devinfo->resources[0].address;
0294     bar0_size = devinfo->resources[0].size;
0295     page0 = (unsigned int *)(bar0 + bar0_size/2); 
0296 
0297     /* Point PAGE0 to start of Plug and Play information */
0298     *page0 = priv->version->amba_ioarea & 0xff000000;
0299 
0300 #if 0
0301     {
0302         uint32_t data;
0303         /* set parity error response */
0304         pci_cfg_r32(priv->pcidev, PCIR_COMMAND, &data);
0305         pci_cfg_w32(priv->pcidev, PCIR_COMMAND, (data|PCIM_CMD_PERRESPEN));
0306     }
0307 #endif
0308 
0309     /* Setup cache line size. Default cache line size will result in
0310      * poor performance (256 word fetches), 0xff will set it according
0311      * to the max size of the PCI FIFO.
0312      */
0313     pci_cfg_w8(priv->pcidev, PCIR_CACHELNSZ, 0xff);
0314 
0315     /* Scan AMBA Plug&Play */
0316 
0317     /* AMBA MAP bar0 (in CPU) ==> 0x80000000(remote amba address) */
0318     priv->amba_maps[0].size = bar0_size/2;
0319     priv->amba_maps[0].local_adr = bar0;
0320     priv->amba_maps[0].remote_adr = AHB1_BASE_ADDR;
0321 
0322     /* AMBA MAP bar1 (in CPU) ==> 0x40000000(remote amba address) */
0323     priv->amba_maps[1].size = devinfo->resources[1].size;
0324     priv->amba_maps[1].local_adr = devinfo->resources[1].address;
0325     priv->amba_maps[1].remote_adr = 0x40000000;
0326 
0327     /* Addresses not matching with map be untouched */
0328     priv->amba_maps[2].size = 0xfffffff0;
0329     priv->amba_maps[2].local_adr = 0;
0330     priv->amba_maps[2].remote_adr = 0;
0331 
0332     /* Mark end of table */
0333     priv->amba_maps[3].size=0;
0334     priv->amba_maps[3].local_adr = 0;
0335     priv->amba_maps[3].remote_adr = 0;
0336 
0337     /* Start AMBA PnP scan at first AHB bus */
0338     ambapp_scan(&priv->abus,
0339             bar0 + (priv->version->amba_ioarea & ~0xff000000),
0340             NULL, &priv->amba_maps[0]);
0341 
0342     /* Initialize Frequency of AMBA bus */
0343     ambapp_freq_init(&priv->abus, NULL, priv->version->amba_freq_hz);
0344 
0345     /* Point PAGE0 to start of APB area */
0346     *page0 = AHB1_BASE_ADDR;    
0347 
0348     /* Find GRPCI controller */
0349     tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
0350                     (OPTIONS_ALL|OPTIONS_APB_SLVS),
0351                     VENDOR_GAISLER, GAISLER_PCIFBRG,
0352                     ambapp_find_by_idx, NULL);
0353     if ( !tmp ) {
0354         return -3;
0355     }
0356     priv->grpci = (struct grpci_regs *)((struct ambapp_apb_info *)tmp->devinfo)->start;
0357 
0358     /* Set GRPCI mmap so that AMBA masters can access CPU-RAM over
0359      * the PCI window.
0360      */
0361     priv->grpci->cfg_stat = (priv->grpci->cfg_stat & 0x0fffffff) |
0362                 (priv->ahbmst2pci_map & 0xf0000000);
0363     priv->grpci->page1 = 0x40000000;
0364 
0365     /* Find IRQ controller, Clear all current IRQs */
0366     tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
0367                     (OPTIONS_ALL|OPTIONS_APB_SLVS),
0368                     VENDOR_GAISLER, GAISLER_IRQMP,
0369                     ambapp_find_by_idx, NULL);
0370     if ( !tmp ) {
0371         return -4;
0372     }
0373     priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
0374     /* Set up GR-RASTA-IO irq controller */
0375     priv->irq->mask[0] = 0;
0376     priv->irq->iclear = 0xffff;
0377     priv->irq->ilevel = 0;
0378 
0379     /* DOWN streams translation table */
0380     priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
0381     priv->bus_maps_down[0].size = priv->amba_maps[0].size;
0382     priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
0383     priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
0384 
0385     priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA";
0386     priv->bus_maps_down[1].size = priv->amba_maps[1].size;
0387     priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr;
0388     priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr;
0389 
0390     /* Mark end of translation table */
0391     priv->bus_maps_down[2].size = 0;
0392 
0393     /* Find GRPCI controller AHB Slave interface */
0394     tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
0395                     (OPTIONS_ALL|OPTIONS_AHB_SLVS),
0396                     VENDOR_GAISLER, GAISLER_PCIFBRG,
0397                     ambapp_find_by_idx, NULL);
0398     if ( !tmp ) {
0399         return -5;
0400     }
0401     ahb = (struct ambapp_ahb_info *)tmp->devinfo;
0402 
0403     /* UP streams translation table */
0404     priv->bus_maps_up[0].name = "AMBA GRPCI Window";
0405     priv->bus_maps_up[0].size = ahb->mask[0]; /* AMBA->PCI Window on GR-RASTA-IO board */
0406     priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
0407     priv->bus_maps_up[0].to_adr = (void *)
0408                     (priv->ahbmst2pci_map & 0xf0000000);
0409 
0410     /* Mark end of translation table */
0411     priv->bus_maps_up[1].size = 0;
0412 
0413     /* Successfully registered the RASTA board */
0414     return 0;
0415 }
0416 
0417 /* PCI Hardware (Revision 1) initialization */
0418 static int gr_rasta_io2_hw_init(struct gr_rasta_io_priv *priv)
0419 {
0420     int i;
0421     uint32_t data;
0422     unsigned int ctrl;
0423     uint8_t tmp2;
0424     struct ambapp_dev *tmp;
0425     struct ambapp_ahb_info *ahb;
0426     uint8_t cap_ptr;
0427     pci_dev_t pcidev = priv->pcidev;
0428     struct pci_dev_info *devinfo = priv->devinfo;
0429 
0430     /* Check capabilities list bit */
0431     pci_cfg_r8(pcidev, PCIR_STATUS, &tmp2);
0432 
0433     if (!((tmp2 >> 4) & 1)) {
0434         /* Capabilities list not available which it should be in the
0435          * GRPCI2
0436          */
0437         return -3;
0438     }
0439 
0440     /* Read capabilities pointer */
0441     pci_cfg_r8(pcidev, PCIR_CAP_PTR, &cap_ptr);
0442 
0443     /* Set AHB address mappings for target PCI bars
0444      * BAR0: 16MB  : Mapped to I/O at 0x80000000
0445      * BAR1: 256MB : Mapped to MEM at 0x40000000
0446      */
0447     pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR0_TO_AHB_MAP, AHB1_BASE_ADDR);
0448     pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR1_TO_AHB_MAP, 0x40000000);
0449 
0450     /* Set PCI bus to be same endianess as PCI system */
0451     pci_cfg_r32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, &data);
0452     if (pci_endian == PCI_BIG_ENDIAN)
0453         data = data & 0xFFFFFFFE;
0454     else
0455         data = data | 0x00000001;
0456     pci_cfg_w32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, data);
0457 
0458 #if 0
0459     /* set parity error response */
0460     pci_cfg_r32(pcidev, PCIR_COMMAND, &data);
0461     pci_cfg_w32(pcidev, PCIR_COMMAND, (data|PCIM_CMD_PERRESPEN));
0462 #endif
0463 
0464     /* Scan AMBA Plug&Play */
0465 
0466     /* AMBA MAP bar0 (in PCI) ==> 0x40000000 (remote amba address) */
0467     priv->amba_maps[0].size = devinfo->resources[0].size;
0468     priv->amba_maps[0].local_adr = devinfo->resources[0].address;
0469     priv->amba_maps[0].remote_adr = AHB1_BASE_ADDR;
0470 
0471     /* AMBA MAP bar0 (in PCI) ==> 0x80000000 (remote amba address) */
0472     priv->amba_maps[1].size = devinfo->resources[1].size;
0473     priv->amba_maps[1].local_adr = devinfo->resources[1].address;
0474     priv->amba_maps[1].remote_adr = 0x40000000;
0475 
0476     /* Addresses not matching with map be untouched */
0477     priv->amba_maps[2].size = 0xfffffff0;
0478     priv->amba_maps[2].local_adr = 0;
0479     priv->amba_maps[2].remote_adr = 0;
0480 
0481     /* Mark end of table */
0482     priv->amba_maps[3].size=0;
0483 
0484     /* Start AMBA PnP scan at first AHB bus */
0485     ambapp_scan(
0486         &priv->abus,
0487         devinfo->resources[0].address + AHB1_IOAREA_OFS,
0488         NULL,
0489         &priv->amba_maps[0]);
0490 
0491     /* Initialize Frequency of AMBA bus. The AMBA bus runs at same
0492      * frequency as PCI bus
0493      */
0494     ambapp_freq_init(&priv->abus, NULL, priv->version->amba_freq_hz);
0495 
0496     /* Find IRQ controller, Clear all current IRQs */
0497     tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus,
0498                 (OPTIONS_ALL|OPTIONS_APB_SLVS),
0499                 VENDOR_GAISLER, GAISLER_IRQMP,
0500                 ambapp_find_by_idx, NULL);
0501     if ( !tmp ) {
0502         return -4;
0503     }
0504     priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start;
0505     /* Set up GR-RASTA-SPW-ROUTER irq controller */
0506     priv->irq->mask[0] = 0;
0507     priv->irq->iclear = 0xffff;
0508     priv->irq->ilevel = 0;
0509 
0510     priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA";
0511     priv->bus_maps_down[0].size = priv->amba_maps[0].size;
0512     priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr;
0513     priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr;
0514     priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA";
0515     priv->bus_maps_down[1].size = priv->amba_maps[1].size;
0516     priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr;
0517     priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr;
0518     priv->bus_maps_down[2].size = 0;
0519 
0520     /* Find GRPCI2 controller AHB Slave interface */
0521     tmp = (void *)ambapp_for_each(&priv->abus,
0522                     (OPTIONS_ALL|OPTIONS_AHB_SLVS),
0523                     VENDOR_GAISLER, GAISLER_GRPCI2,
0524                     ambapp_find_by_idx, NULL);
0525     if ( !tmp ) {
0526         return -5;
0527     }
0528     ahb = (struct ambapp_ahb_info *)tmp->devinfo;
0529     priv->bus_maps_up[0].name = "AMBA GRPCI2 Window";
0530     priv->bus_maps_up[0].size = ahb->mask[0]; /* AMBA->PCI Window on GR-RASTA-SPW-ROUTER board */
0531     priv->bus_maps_up[0].from_adr = (void *)ahb->start[0];
0532     priv->bus_maps_up[0].to_adr = (void *)
0533                 (priv->ahbmst2pci_map & ~(ahb->mask[0]-1));
0534     priv->bus_maps_up[1].size = 0;
0535 
0536     /* Find GRPCI2 controller APB Slave interface */
0537     tmp = (void *)ambapp_for_each(&priv->abus,
0538                     (OPTIONS_ALL|OPTIONS_APB_SLVS),
0539                     VENDOR_GAISLER, GAISLER_GRPCI2,
0540                     ambapp_find_by_idx, NULL);
0541     if ( !tmp ) {
0542         return -6;
0543     }
0544     priv->grpci2 = (struct grpci2_regs *)
0545         ((struct ambapp_apb_info *)tmp->devinfo)->start;
0546 
0547     /* Set AHB to PCI mapping for all AMBA AHB masters */
0548     for(i = 0; i < 16; i++) {
0549         priv->grpci2->ahbtopcimemmap[i] = priv->ahbmst2pci_map &
0550                             ~(ahb->mask[0]-1);
0551     }
0552 
0553     /* Make sure dirq(0) sampling is enabled */
0554     ctrl = priv->grpci2->ctrl;
0555     ctrl = (ctrl & 0xFFFFFF0F) | (1 << 4);
0556     priv->grpci2->ctrl = ctrl;
0557 
0558     /* Successfully registered the RASTA-SPW-ROUTER board */
0559     return 0;
0560 }
0561 
0562 static int gr_rasta_io_hw_init2(struct gr_rasta_io_priv *priv)
0563 {
0564     /* Enable DMA by enabling PCI target as master */
0565     pci_master_enable(priv->pcidev);
0566 
0567     return DRVMGR_OK;
0568 }
0569 
0570 /* Called when a PCI target is found with the PCI device and vendor ID 
0571  * given in gr_rasta_io_ids[].
0572  */
0573 int gr_rasta_io_init1(struct drvmgr_dev *dev)
0574 {
0575     struct gr_rasta_io_priv *priv;
0576     struct pci_dev_info *devinfo;
0577     int status;
0578     uint32_t bar0, bar1, bar0_size, bar1_size;
0579     union drvmgr_key_value *value;
0580     int resources_cnt;
0581     int sc;
0582 
0583     priv = grlib_calloc(1, sizeof(*priv));
0584     if ( !priv )
0585         return DRVMGR_NOMEM;
0586 
0587     dev->priv = priv;
0588     priv->dev = dev;
0589 
0590     /* Determine number of configurations */
0591     resources_cnt = get_resarray_count(gr_rasta_io_resources);
0592 
0593     /* Generate Device prefix */
0594 
0595     strcpy(priv->prefix, "/dev/rastaio0");
0596     priv->prefix[12] += dev->minor_drv;
0597     sc = mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO);
0598     _Assert_Unused_variable_equals(sc, 0);
0599     priv->prefix[13] = '/';
0600     priv->prefix[14] = '\0';
0601 
0602     priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo;
0603     priv->pcidev = devinfo->pcidev;
0604     bar0 = devinfo->resources[0].address;
0605     bar0_size = devinfo->resources[0].size;
0606     bar1 = devinfo->resources[1].address;
0607     bar1_size = devinfo->resources[1].size;
0608     printk("\n\n--- GR-RASTA-IO[%d] ---\n", dev->minor_drv);
0609     printk(" PCI BUS: 0x%x, SLOT: 0x%x, FUNCTION: 0x%x\n",
0610         PCI_DEV_EXPAND(priv->pcidev));
0611     printk(" PCI VENDOR: 0x%04x, DEVICE: 0x%04x\n",
0612         devinfo->id.vendor, devinfo->id.device);
0613     printk(" PCI BAR[0]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0614         bar0, bar0 + bar0_size - 1);
0615     printk(" PCI BAR[1]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0616         bar1, bar1 + bar1_size - 1);
0617     printk(" IRQ: %d\n\n\n", devinfo->irq);
0618 
0619     /* all neccessary space assigned to GR-RASTA-IO target? */
0620     if ((bar0_size == 0) || (bar1_size == 0))
0621         return DRVMGR_ENORES;
0622 
0623     /* Initialize spin-lock for this PCI peripheral device. This is to
0624      * protect the Interrupt Controller Registers. The genirq layer is
0625          * protecting its own internals and ISR dispatching.
0626          */
0627     SPIN_INIT(&priv->devlock, priv->prefix);
0628 
0629     /* Let user override which PCI address the AHB masters of the
0630      * GR-RASTA-IO board access when doing DMA to CPU RAM. The AHB masters
0631      * access the PCI Window of the AMBA bus, the MSB 4-bits of that address
0632      * is translated according this config option before the address
0633      * goes out on the PCI bus.
0634      * Only the 4 MSB bits have an effect;
0635      */
0636     value = drvmgr_dev_key_get(priv->dev, "ahbmst2pci", DRVMGR_KT_INT);
0637     if (value)
0638         priv->ahbmst2pci_map = value->i;
0639     else
0640         priv->ahbmst2pci_map = AHBMST2PCIADR; /* default */ 
0641 
0642     priv->genirq = genirq_init(16);
0643     if ( priv->genirq == NULL ) {
0644         free(priv);
0645         dev->priv = NULL;
0646         return DRVMGR_FAIL;
0647     }
0648 
0649     /* Select version of GR-RASTA-IO board */
0650     switch (devinfo->rev) {
0651         case 0:
0652             priv->version = &gr_rasta_io_ver0;
0653             status = gr_rasta_io_hw_init(priv);
0654             break;
0655         case 1:
0656             priv->version = &gr_rasta_io_ver1;
0657             status = gr_rasta_io_hw_init(priv);
0658             break;
0659         case 2:
0660             priv->version = &gr_rasta_io_ver1; /* same cfg as 1 */
0661             status = gr_rasta_io2_hw_init(priv);
0662             break;
0663         default:
0664             return -2;
0665     }
0666 
0667     if ( status != 0 ) {
0668         genirq_destroy(priv->genirq);
0669         free(priv);
0670         dev->priv = NULL;
0671         printk(" Failed to initialize GR-RASTA-IO HW: %d\n", status);
0672         return DRVMGR_FAIL;
0673     }
0674 
0675     /* Init amba bus */
0676     priv->config.abus = &priv->abus;
0677     priv->config.ops = &ambapp_rasta_io_ops;
0678     priv->config.maps_up = &priv->bus_maps_up[0];
0679     priv->config.maps_down = &priv->bus_maps_down[0];
0680     if ( priv->dev->minor_drv < resources_cnt ) {
0681         priv->config.resources = gr_rasta_io_resources[priv->dev->minor_drv];
0682     } else {
0683         priv->config.resources = NULL;
0684     }
0685 
0686     /* Create and register AMBA PnP bus. */
0687     return ambapp_bus_register(dev, &priv->config);
0688 }
0689 
0690 int gr_rasta_io_init2(struct drvmgr_dev *dev)
0691 {
0692     struct gr_rasta_io_priv *priv = dev->priv;
0693 
0694     /* Clear any old interrupt requests */
0695     drvmgr_interrupt_clear(dev, 0);
0696 
0697     /* Enable System IRQ so that GR-RASTA-IO PCI target interrupt goes
0698      * through.
0699      *
0700      * It is important to enable it in stage init2. If interrupts were
0701      * enabled in init1 this might hang the system when more than one
0702      * PCI board is connected, this is because PCI interrupts might
0703      * be shared and PCI board 2 have not initialized and
0704      * might therefore drive interrupt already when entering init1().
0705      */
0706     drvmgr_interrupt_register(
0707         dev,
0708         0,
0709         "gr_rasta_io",
0710         gr_rasta_io_isr,
0711         (void *)priv);
0712 
0713     return gr_rasta_io_hw_init2(priv);
0714 }
0715 
0716 int ambapp_rasta_io_int_register(
0717     struct drvmgr_dev *dev,
0718     int irq,
0719     const char *info,
0720     drvmgr_isr handler,
0721     void *arg)
0722 {
0723     struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
0724     SPIN_IRQFLAGS(irqflags);
0725     int status;
0726     void *h;
0727 
0728     h = genirq_alloc_handler(handler, arg);
0729     if ( h == NULL )
0730         return DRVMGR_FAIL;
0731 
0732     SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0733 
0734     status = genirq_register(priv->genirq, irq, h);
0735     if ( status == 0 ) {
0736         /* Clear IRQ for first registered handler */
0737         priv->irq->iclear = (1<<irq);
0738     } else if ( status == 1 )
0739         status = 0;
0740 
0741     if (status != 0) {
0742         SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0743         genirq_free_handler(h);
0744         return DRVMGR_FAIL;
0745     }
0746 
0747     status = genirq_enable(priv->genirq, irq, handler, arg);
0748     if ( status == 0 ) {
0749         /* Enable IRQ for first enabled handler only */
0750         priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
0751     } else if ( status == 1 )
0752         status = 0;
0753 
0754     SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0755 
0756     return status;
0757 }
0758 
0759 int ambapp_rasta_io_int_unregister(
0760     struct drvmgr_dev *dev,
0761     int irq,
0762     drvmgr_isr isr,
0763     void *arg)
0764 {
0765     struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
0766     SPIN_IRQFLAGS(irqflags);
0767     int status;
0768     void *handler;
0769 
0770     SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0771 
0772     status = genirq_disable(priv->genirq, irq, isr, arg);
0773     if ( status == 0 ) {
0774         /* Disable IRQ only when no enabled handler exists */
0775         priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
0776     }
0777 
0778     handler = genirq_unregister(priv->genirq, irq, isr, arg);
0779     if ( handler == NULL )
0780         status = DRVMGR_FAIL;
0781     else
0782         status = DRVMGR_OK;
0783 
0784     SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0785 
0786     if (handler)
0787         genirq_free_handler(handler);
0788 
0789     return status;
0790 }
0791 
0792 int ambapp_rasta_io_int_unmask(
0793     struct drvmgr_dev *dev,
0794     int irq)
0795 {
0796     struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
0797     SPIN_IRQFLAGS(irqflags);
0798 
0799     DBG("RASTA-IO IRQ %d: unmask\n", irq);
0800 
0801     if ( genirq_check(priv->genirq, irq) )
0802         return DRVMGR_EINVAL;
0803 
0804     SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0805 
0806     /* Enable IRQ for first enabled handler only */
0807     priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */
0808 
0809     SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0810 
0811     return DRVMGR_OK;
0812 }
0813 
0814 int ambapp_rasta_io_int_mask(
0815     struct drvmgr_dev *dev,
0816     int irq)
0817 {
0818     struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
0819     SPIN_IRQFLAGS(irqflags);
0820 
0821     DBG("RASTA-IO IRQ %d: mask\n", irq);
0822 
0823     if ( genirq_check(priv->genirq, irq) )
0824         return DRVMGR_EINVAL;
0825 
0826     SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0827 
0828     /* Disable/mask IRQ */
0829     priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */
0830 
0831     SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0832 
0833     return DRVMGR_OK;
0834 }
0835 
0836 int ambapp_rasta_io_int_clear(
0837     struct drvmgr_dev *dev,
0838     int irq)
0839 {
0840     struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
0841 
0842     if ( genirq_check(priv->genirq, irq) )
0843         return DRVMGR_EINVAL;
0844 
0845     priv->irq->iclear = (1<<irq);
0846 
0847     return DRVMGR_OK;
0848 }
0849 
0850 int ambapp_rasta_io_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
0851 {
0852     struct gr_rasta_io_priv *priv = dev->parent->dev->priv;
0853 
0854     /* Device name prefix pointer, skip /dev */
0855     params->dev_prefix = &priv->prefix[5];
0856 
0857     return 0;
0858 }
0859 
0860 void gr_rasta_io_print_dev(struct drvmgr_dev *dev, int options)
0861 {
0862     struct gr_rasta_io_priv *priv = dev->priv;
0863     struct pci_dev_info *devinfo = priv->devinfo;
0864     uint32_t bar0, bar1, bar0_size, bar1_size;
0865 
0866     /* Print */
0867     printf("--- GR-RASTA-IO [bus 0x%x, dev 0x%x, fun 0x%x] ---\n",
0868         PCI_DEV_EXPAND(priv->pcidev));
0869 
0870     bar0 = devinfo->resources[0].address;
0871     bar0_size = devinfo->resources[0].size;
0872     bar1 = devinfo->resources[1].address;
0873     bar1_size = devinfo->resources[1].size;
0874 
0875     printf(" PCI BAR[0]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0876         bar0, bar0 + bar0_size - 1);
0877     printf(" PCI BAR[1]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0878         bar1, bar1 + bar1_size - 1);
0879     printf(" IRQ REGS:        0x%" PRIxPTR "\n", (uintptr_t)priv->irq);
0880     printf(" IRQ:             %d\n", devinfo->irq);
0881     printf(" PCI REVISION:    %d\n", devinfo->rev);
0882     printf(" FREQ:            %d Hz\n", priv->version->amba_freq_hz);
0883     printf(" IMASK:           0x%08x\n", priv->irq->mask[0]);
0884     printf(" IPEND:           0x%08x\n", priv->irq->ipend);
0885 
0886     /* Print amba config */
0887     if ( options & RASTA_IO_OPTIONS_AMBA ) {
0888         ambapp_print(&priv->abus, 10);
0889     }
0890 
0891 #if 0
0892     /* Print IRQ handlers and their arguments */
0893     if ( options & RASTA_IO_OPTIONS_IRQ ) {
0894         int i;
0895         for(i=0; i<16; i++) {
0896             printf(" IRQ[%02d]:         0x%x, arg: 0x%x\n", 
0897                 i, (unsigned int)priv->isrs[i].handler, (unsigned int)priv->isrs[i].arg);
0898         }
0899     }
0900 #endif
0901 }
0902 
0903 void gr_rasta_io_print(int options)
0904 {
0905     struct pci_drv_info *drv = &gr_rasta_io_info;
0906     struct drvmgr_dev *dev;
0907 
0908     dev = drv->general.dev;
0909     while(dev) {
0910         gr_rasta_io_print_dev(dev, options);
0911         dev = dev->next_in_drv;
0912     }
0913 }