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