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-701 PCI Target driver.
0004  * 
0005  *  COPYRIGHT (c) 2008.
0006  *  Cobham Gaisler AB.
0007  *
0008  *  Configures the GR-701 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  *  gr701_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 #include <pci/access.h>
0048 
0049 #include <grlib/ambapp.h>
0050 
0051 #include <grlib/ambapp.h>
0052 #include <drvmgr/drvmgr.h>
0053 #include <grlib/ambapp_bus.h>
0054 #include <drvmgr/pci_bus.h>
0055 #include <grlib/bspcommon.h>
0056 #include <grlib/genirq.h>
0057 
0058 #include <grlib/gr_701.h>
0059 
0060 #include <grlib/grlib_impl.h>
0061 
0062 /* Offset from 0x80000000 (dual bus version) */
0063 #define AHB1_BASE_ADDR 0x80000000
0064 #define AHB1_IOAREA_BASE_ADDR 0x80100000
0065 
0066 /* #define DEBUG 1 */
0067 
0068 #ifdef DEBUG
0069 #define DBG(x...) printk(x)
0070 #else
0071 #define DBG(x...) 
0072 #endif
0073 
0074 int gr701_init1(struct drvmgr_dev *dev);
0075 int gr701_init2(struct drvmgr_dev *dev);
0076 void gr701_interrupt(void *arg);
0077 
0078 #define READ_REG(address) (*(volatile unsigned int *)address)
0079 
0080 /* PCI bride reg layout on AMBA side */
0081 struct amba_bridge_regs {
0082     volatile unsigned int bar0;
0083     volatile unsigned int bar1;
0084     volatile unsigned int bar2;
0085     volatile unsigned int bar3;
0086     volatile unsigned int bar4;/* 0x10 */
0087     
0088     volatile unsigned int unused[4*3-1];
0089     
0090     volatile unsigned int ambabars[1]; /* 0x40 */
0091 };
0092 
0093 /* PCI bride reg layout on PCI side */
0094 struct pci_bridge_regs {
0095     volatile unsigned int bar0;
0096     volatile unsigned int bar1;
0097     volatile unsigned int bar2;
0098     volatile unsigned int bar3;
0099     volatile unsigned int bar4; /* 0x10 */
0100 
0101     volatile unsigned int ilevel;
0102     volatile unsigned int ipend;
0103     volatile unsigned int iforce;
0104     volatile unsigned int istatus;
0105     volatile unsigned int iclear;
0106     volatile unsigned int imask;
0107 };
0108 
0109 /* Private data structure for driver */
0110 struct gr701_priv {
0111     /* Driver management */
0112     struct drvmgr_dev       *dev;
0113     char                prefix[16];
0114     SPIN_DECLARE(devlock);
0115 
0116     struct pci_bridge_regs      *pcib;
0117     struct amba_bridge_regs     *ambab;
0118 
0119     /* PCI */
0120     pci_dev_t           pcidev;
0121     struct pci_dev_info     *devinfo;   
0122 
0123     /* IRQ */
0124     genirq_t            genirq;
0125     int             interrupt_cnt;
0126 
0127     /* GR-701 Address translation */
0128     struct drvmgr_map_entry     bus_maps_up[2];
0129     struct drvmgr_map_entry     bus_maps_down[2];
0130 
0131     /* AMBA Plug&Play information on GR-701 */
0132     struct ambapp_bus       abus;
0133     struct ambapp_mmap      amba_maps[3];
0134         struct ambapp_config        config;
0135 };
0136 
0137 int ambapp_gr701_int_register(
0138     struct drvmgr_dev *dev,
0139     int irq,
0140     const char *info,
0141     drvmgr_isr handler,
0142     void *arg);
0143 int ambapp_gr701_int_unregister(
0144     struct drvmgr_dev *dev,
0145     int irq,
0146     drvmgr_isr isr,
0147     void *arg);
0148 int ambapp_gr701_int_unmask(
0149     struct drvmgr_dev *dev,
0150     int irq);
0151 int ambapp_gr701_int_mask(
0152     struct drvmgr_dev *dev,
0153     int irq);
0154 int ambapp_gr701_int_clear(
0155     struct drvmgr_dev *dev,
0156     int irq);
0157 int ambapp_gr701_get_params(
0158     struct drvmgr_dev *dev,
0159     struct drvmgr_bus_params *params);
0160 
0161 struct ambapp_ops ambapp_gr701_ops = {
0162     .int_register = ambapp_gr701_int_register,
0163     .int_unregister = ambapp_gr701_int_unregister,
0164     .int_unmask = ambapp_gr701_int_unmask,
0165     .int_mask = ambapp_gr701_int_mask,
0166     .int_clear = ambapp_gr701_int_clear,
0167     .get_params = ambapp_gr701_get_params
0168 };
0169 
0170 struct drvmgr_drv_ops gr701_ops = 
0171 {
0172     .init = {gr701_init1, gr701_init2, NULL, NULL},
0173     .remove = NULL,
0174     .info = NULL
0175 };
0176 
0177 struct pci_dev_id_match gr701_ids[] = 
0178 {
0179     PCIID_DEVVEND(PCIID_VENDOR_GAISLER, PCIID_DEVICE_GR_701),
0180     PCIID_END_TABLE /* Mark end of table */
0181 };
0182 
0183 struct pci_drv_info gr701_info =
0184 {
0185     {
0186         DRVMGR_OBJ_DRV,         /* Driver */
0187         NULL,               /* Next driver */
0188         NULL,               /* Device list */
0189         DRIVER_PCI_GAISLER_GR701_ID,    /* Driver ID */
0190         "GR-701_DRV",           /* Driver Name */
0191         DRVMGR_BUS_TYPE_PCI,        /* Bus Type */
0192         &gr701_ops,
0193         NULL,               /* Funcs */
0194         0,              /* No devices yet */
0195         0,
0196     },
0197     &gr701_ids[0]
0198 };
0199 
0200 /* Driver resources configuration for the AMBA bus on the GR-701 board.
0201  * It is declared weak so that the user may override it from the project file,
0202  * if the default settings are not enough.
0203  *
0204  * The configuration consists of an array of configuration pointers, each
0205  * pointer determine the configuration of one GR-701 board. Pointer
0206  * zero is for board0, pointer 1 for board1 and so on.
0207  *
0208  * The array must end with a NULL pointer.
0209  */
0210 struct drvmgr_bus_res *gr701_resources[] __attribute__((weak)) =
0211 {
0212     NULL
0213 };
0214 
0215 void gr701_register_drv(void)
0216 {
0217     DBG("Registering GR-701 PCI driver\n");
0218     drvmgr_drv_register(&gr701_info.general);
0219 }
0220 
0221 void gr701_interrupt(void *arg)
0222 {
0223     struct gr701_priv *priv = arg;
0224     unsigned int status;
0225     int irq = 0;
0226     SPIN_ISR_IRQFLAGS(irqflags);
0227 
0228     SPIN_LOCK(&priv->devlock, irqflags);
0229     while ( (status=priv->pcib->istatus) != 0 ) {
0230         priv->interrupt_cnt++;  /* An interrupt was generated */
0231         irq = status;
0232         genirq_doirq(priv->genirq, irq);
0233         /* ACK interrupt */
0234         priv->pcib->istatus = 0;
0235     }
0236     SPIN_UNLOCK(&priv->devlock, irqflags);
0237 
0238     /* ACK interrupt, this is because PCI is Level, so the IRQ Controller still drives the IRQ. */
0239     if ( irq )
0240         drvmgr_interrupt_clear(priv->dev, 0);
0241 }
0242 
0243 static int gr701_hw_init(struct gr701_priv *priv)
0244 {
0245     uint32_t com1;
0246     struct pci_bridge_regs *pcib;
0247     struct amba_bridge_regs *ambab;
0248     int mst;
0249     unsigned int pci_freq_hz;
0250     pci_dev_t pcidev = priv->pcidev;
0251     struct pci_dev_info *devinfo = priv->devinfo;
0252 
0253     /* Set up PCI ==> AMBA */
0254     priv->pcib = pcib = (void *)devinfo->resources[0].address;
0255     pcib->bar0 = 0xfc000000;
0256 
0257     /* Set up GR701 AMBA Masters connection to PCI */
0258     priv->ambab = ambab = (struct amba_bridge_regs *)(
0259         devinfo->resources[1].address + 0x400);
0260 
0261     /* Init all msters, max 16 */
0262     for (mst=0; mst<16; mst++) {
0263         ambab->ambabars[mst] = 0x40000000;
0264         if (READ_REG(&ambab->ambabars[mst]) != 0x40000000)
0265             break;
0266     }
0267 
0268     /* Setup Address translation for AMBA bus, assume that PCI BAR
0269      * are mapped 1:1 to CPU.
0270      */
0271 
0272     priv->amba_maps[0].size = 0x04000000;
0273     priv->amba_maps[0].local_adr = devinfo->resources[1].address;
0274     priv->amba_maps[0].remote_adr = 0xfc000000;
0275 
0276     /* Mark end of table */
0277     priv->amba_maps[1].size=0;
0278     priv->amba_maps[1].local_adr = 0;
0279     priv->amba_maps[1].remote_adr = 0;
0280 
0281     /* Setup DOWN-streams address translation */
0282     priv->bus_maps_down[0].name = "PCI BAR1 -> AMBA";
0283     priv->bus_maps_down[0].size = priv->amba_maps[0].size;
0284     priv->bus_maps_down[0].from_adr = (void *)devinfo->resources[1].address;
0285     priv->bus_maps_down[0].to_adr = (void *)0xfc000000;
0286 
0287     /* Setup UP-streams address translation */
0288     priv->bus_maps_up[0].name = "AMBA PCIF Window";
0289     priv->bus_maps_up[0].size = 0x10000000;
0290     priv->bus_maps_up[0].from_adr = (void *)0xe0000000;
0291     priv->bus_maps_up[0].to_adr = (void *)0x40000000;
0292 
0293     /* Mark end of translation tables */
0294     priv->bus_maps_down[1].size = 0;
0295     priv->bus_maps_up[1].size = 0;
0296 
0297     /* Enable I/O and Mem accesses */
0298     pci_cfg_r32(pcidev, PCIR_COMMAND, &com1);
0299     com1 |= PCIM_CMD_PORTEN | PCIM_CMD_MEMEN;
0300     pci_cfg_w32(pcidev, PCIR_COMMAND, com1);
0301 
0302     /* Start AMBA PnP scan at first AHB bus */
0303     ambapp_scan(&priv->abus, devinfo->resources[1].address + 0x3f00000,
0304             NULL, &priv->amba_maps[0]);
0305 
0306     /* Frequency is the same as the PCI bus frequency */
0307     drvmgr_freq_get(priv->dev, 0, &pci_freq_hz);
0308 
0309     /* Initialize Frequency of AMBA bus */
0310     ambapp_freq_init(&priv->abus, NULL, pci_freq_hz);
0311 
0312     /* Init IRQ controller (avoid IRQ generation) */
0313     pcib->imask = 0x0000;
0314     pcib->ipend = 0;
0315     pcib->iclear = 0xffff;
0316     pcib->iforce = 0;
0317     pcib->ilevel = 0x0;
0318 
0319     /* Successfully registered the GR-701 board */
0320     return 0;
0321 }
0322 
0323 static void gr701_hw_init2(struct gr701_priv *priv)
0324 {
0325     /* Enable PCI Master (for DMA) */
0326     pci_master_enable(priv->pcidev);
0327 }
0328 
0329 /* Called when a PCI target is found with the PCI device and vendor ID 
0330  * given in gr701_ids[].
0331  */
0332 int gr701_init1(struct drvmgr_dev *dev)
0333 {
0334     struct gr701_priv *priv;
0335     struct pci_dev_info *devinfo;
0336     uint32_t bar0, bar1, bar0_size, bar1_size;
0337     int resources_cnt;
0338     int sc;
0339 
0340     priv = grlib_calloc(1, sizeof(*priv));
0341     if ( !priv )
0342         return DRVMGR_NOMEM;
0343 
0344     dev->priv = priv;
0345     priv->dev = dev;
0346 
0347     /* Determine number of configurations */
0348     resources_cnt = get_resarray_count(gr701_resources);
0349 
0350     /* Generate Device prefix */
0351     strcpy(priv->prefix, "/dev/gr701_0");
0352     priv->prefix[11] += dev->minor_drv;
0353     sc = mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO);
0354     _Assert_Unused_variable_equals(sc, 0);
0355     priv->prefix[12] = '/';
0356     priv->prefix[13] = '\0';
0357 
0358     priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo;
0359     priv->pcidev = devinfo->pcidev;
0360     bar0 = devinfo->resources[0].address;
0361     bar0_size = devinfo->resources[0].size;
0362     bar1 = devinfo->resources[1].address;
0363     bar1_size = devinfo->resources[1].size;
0364     printk("\n\n--- GR-701[%d] ---\n", dev->minor_drv);
0365     printk(" PCI BUS: 0x%x, SLOT: 0x%x, FUNCTION: 0x%x\n",
0366         PCI_DEV_EXPAND(priv->pcidev));
0367     printk(" PCI VENDOR: 0x%04x, DEVICE: 0x%04x\n\n\n",
0368         devinfo->id.vendor, devinfo->id.device);
0369     printk(" PCI BAR[0]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0370         bar0, bar0 + bar0_size - 1);
0371     printk(" PCI BAR[1]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0372         bar1, bar1 + bar1_size - 1);
0373     printk(" IRQ: %d\n\n\n", devinfo->irq);
0374 
0375     /* all neccessary space assigned to GR-701 target? */
0376     if ((bar0_size == 0) || (bar1_size == 0))
0377         return DRVMGR_ENORES;
0378 
0379     /* Initialize spin-lock for this PCI perihperal device. This is to
0380      * protect the Interrupt Controller Registers. The genirq layer is
0381          * protecting its own internals and ISR dispatching.
0382          */
0383     SPIN_INIT(&priv->devlock, priv->prefix);
0384 
0385     priv->genirq = genirq_init(16);
0386     if ( priv->genirq == NULL ) {
0387         free(priv);
0388         dev->priv = NULL;
0389         return DRVMGR_FAIL;
0390     }
0391 
0392     if ( gr701_hw_init(priv) ) {
0393         genirq_destroy(priv->genirq);
0394         free(priv);
0395         dev->priv = NULL;
0396         printk(" Failed to initialize GR-701 HW\n");
0397         return DRVMGR_FAIL;
0398     }
0399 
0400     /* Init amba bus */
0401     priv->config.abus = &priv->abus;
0402     priv->config.ops = &ambapp_gr701_ops;
0403     priv->config.maps_up = &priv->bus_maps_up[0];
0404     priv->config.maps_down = &priv->bus_maps_down[0];
0405     if ( priv->dev->minor_drv < resources_cnt ) {
0406         priv->config.resources = gr701_resources[priv->dev->minor_drv];
0407     } else {
0408         priv->config.resources = NULL;
0409     }
0410 
0411     /* Create and register AMBA PnP bus. */
0412     return ambapp_bus_register(dev, &priv->config);
0413 }
0414 
0415 /* Called when a PCI target is found with the PCI device and vendor ID 
0416  * given in gr701_ids[].
0417  */
0418 int gr701_init2(struct drvmgr_dev *dev)
0419 {
0420     struct gr701_priv *priv = dev->priv;
0421 
0422     /* Clear any old interrupt requests */
0423     drvmgr_interrupt_clear(dev, 0);
0424 
0425     /* Enable System IRQ so that GR-701 PCI target interrupt goes through.
0426      *
0427      * It is important to enable it in stage init2. If interrupts were
0428      * enabled in init1 this might hang the system when more than one PCI
0429      * board is connected, this is because PCI interrupts might be shared
0430      * and PCI target 2 have not initialized and might therefore drive
0431      * interrupt already when entering init1().
0432      */
0433     drvmgr_interrupt_register(dev, 0, "gr701", gr701_interrupt, priv);
0434 
0435     gr701_hw_init2(priv);
0436 
0437     return DRVMGR_OK;
0438 }
0439 
0440 int ambapp_gr701_int_register(
0441     struct drvmgr_dev *dev,
0442     int irq,
0443     const char *info,
0444     drvmgr_isr handler,
0445     void *arg)
0446 {
0447     struct gr701_priv *priv = dev->parent->dev->priv;
0448     SPIN_IRQFLAGS(irqflags);
0449     int status;
0450     void *h;
0451 
0452     h = genirq_alloc_handler(handler, arg);
0453     if ( h == NULL )
0454         return DRVMGR_FAIL;
0455 
0456     SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0457 
0458     status = genirq_register(priv->genirq, irq, h);
0459     if ( status == 0 ) {
0460         /* Clear IRQ for first registered handler */
0461         priv->pcib->iclear = (1<<irq);
0462     } else if ( status == 1 )
0463         status = 0;
0464 
0465     if (status != 0) {
0466         SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0467         genirq_free_handler(h);
0468         return DRVMGR_FAIL;
0469     }
0470 
0471     status = genirq_enable(priv->genirq, irq, handler, arg);
0472     if ( status == 0 ) {
0473         /* Enable IRQ for first enabled handler only */
0474         priv->pcib->imask |= (1<<irq); /* unmask interrupt source */
0475     } else if ( status == 1 )
0476         status = DRVMGR_OK;
0477 
0478     SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0479 
0480     return status;
0481 }
0482 
0483 int ambapp_gr701_int_unregister(
0484     struct drvmgr_dev *dev,
0485     int irq,
0486     drvmgr_isr isr,
0487     void *arg)
0488 {
0489     struct gr701_priv *priv = dev->parent->dev->priv;
0490     SPIN_IRQFLAGS(irqflags);
0491     int status;
0492     void *handler;
0493 
0494     SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0495 
0496     status = genirq_disable(priv->genirq, irq, isr, arg);
0497     if ( status == 0 ) {
0498         /* Disable IRQ only when no enabled handler exists */
0499         priv->pcib->imask &= ~(1<<irq); /* mask interrupt source */
0500     }
0501 
0502     handler = genirq_unregister(priv->genirq, irq, isr, arg);
0503     if ( handler == NULL )
0504         status = DRVMGR_FAIL;
0505     else
0506         status = DRVMGR_OK;
0507 
0508     SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0509 
0510     if (handler)
0511         genirq_free_handler(handler);
0512 
0513     return status;
0514 }
0515 
0516 int ambapp_gr701_int_unmask(
0517     struct drvmgr_dev *dev,
0518     int irq)
0519 {
0520     struct gr701_priv *priv = dev->parent->dev->priv;
0521     SPIN_IRQFLAGS(irqflags);
0522 
0523     DBG("GR-701 IRQ %d: enable\n", irq);
0524 
0525     if ( genirq_check(priv->genirq, irq) )
0526         return DRVMGR_FAIL;
0527 
0528     SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0529 
0530     /* Enable IRQ */
0531     priv->pcib->imask |= (1<<irq); /* unmask interrupt source */
0532 
0533     SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0534 
0535     return DRVMGR_OK;
0536 }
0537 
0538 int ambapp_gr701_int_mask(
0539     struct drvmgr_dev *dev,
0540     int irq)
0541 {
0542     struct gr701_priv *priv = dev->parent->dev->priv;
0543     SPIN_IRQFLAGS(irqflags);
0544 
0545     DBG("GR-701 IRQ %d: disable\n", irq);
0546 
0547     if ( genirq_check(priv->genirq, irq) )
0548         return DRVMGR_FAIL;
0549 
0550     SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0551 
0552     /* Disable IRQ */
0553     priv->pcib->imask &= ~(1<<irq); /* mask interrupt source */
0554 
0555     SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0556 
0557     return DRVMGR_OK;
0558 }
0559 
0560 int ambapp_gr701_int_clear(
0561     struct drvmgr_dev *dev,
0562     int irq)
0563 {
0564     struct gr701_priv *priv = dev->parent->dev->priv;
0565 
0566     if ( genirq_check(priv->genirq, irq) )
0567         return DRVMGR_FAIL;
0568 
0569     priv->pcib->iclear = (1<<irq);
0570 
0571     return DRVMGR_OK;
0572 }
0573 
0574 int ambapp_gr701_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params)
0575 {
0576     struct gr701_priv *priv = dev->parent->dev->priv;
0577 
0578     /* Device name prefix pointer, skip /dev */
0579     params->dev_prefix = &priv->prefix[5];
0580 
0581     return 0;
0582 }
0583 
0584 void gr701_print_dev(struct drvmgr_dev *dev, int options)
0585 {
0586     struct gr701_priv *priv = dev->priv;
0587     struct pci_dev_info *devinfo = priv->devinfo;
0588     unsigned int freq_hz;
0589     uint32_t bar0, bar1, bar0_size, bar1_size;
0590 
0591     /* Print */
0592     printf("--- GR-701 [bus 0x%x, dev 0x%x, fun 0x%x] ---\n",
0593         PCI_DEV_EXPAND(priv->pcidev));
0594     bar0 = devinfo->resources[0].address;
0595     bar0_size = devinfo->resources[0].size;
0596     bar1 = devinfo->resources[1].address;
0597     bar1_size = devinfo->resources[1].size;
0598 
0599     printf(" PCI BAR[0]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0600         bar0, bar0 + bar0_size - 1);
0601     printf(" PCI BAR[1]: 0x%" PRIx32 " - 0x%" PRIx32 "\n",
0602         bar1, bar1 + bar1_size - 1);
0603     printf(" IRQ:             %d\n", devinfo->irq);
0604 
0605     /* Frequency is the same as the PCI bus frequency */
0606     drvmgr_freq_get(dev, 0, &freq_hz);
0607 
0608     printf(" FREQ:            %u Hz\n", freq_hz);
0609     printf(" IMASK:           0x%08x\n", priv->pcib->imask);
0610     printf(" IPEND:           0x%08x\n", priv->pcib->ipend);
0611 
0612     /* Print amba config */
0613     if ( options & GR701_OPTIONS_AMBA ) {
0614         ambapp_print(&priv->abus, 10);
0615     }
0616 
0617 #if 0
0618     /* Print IRQ handlers and their arguments */
0619     if ( options & GR701_OPTIONS_IRQ ) {
0620         int i;
0621         for(i=0; i<16; i++) {
0622             printf(" IRQ[%02d]:         0x%x, arg: 0x%x\n", 
0623                 i, (unsigned int)priv->isrs[i].handler, (unsigned int)priv->isrs[i].arg);
0624         }
0625     }
0626 #endif
0627 }
0628 
0629 void gr701_print(int options)
0630 {
0631     struct pci_drv_info *drv = &gr701_info;
0632     struct drvmgr_dev *dev;
0633 
0634     dev = drv->general.dev;
0635     while(dev) {
0636         gr701_print_dev(dev, options);
0637         dev = dev->next_in_drv;
0638     }
0639 }