diff options
Diffstat (limited to 'bsps/sparc/shared/pci/gr_rasta_adcdac.c')
-rw-r--r-- | bsps/sparc/shared/pci/gr_rasta_adcdac.c | 699 |
1 files changed, 699 insertions, 0 deletions
diff --git a/bsps/sparc/shared/pci/gr_rasta_adcdac.c b/bsps/sparc/shared/pci/gr_rasta_adcdac.c new file mode 100644 index 0000000000..6d1f8f130f --- /dev/null +++ b/bsps/sparc/shared/pci/gr_rasta_adcdac.c @@ -0,0 +1,699 @@ +/* GR-RASTA-ADCDAC PCI Target driver. + * + * COPYRIGHT (c) 2008. + * Cobham Gaisler AB. + * + * Configures the GR-RASTA-ADCDAC interface PCI board. + * This driver provides a AMBA PnP bus by using the general part + * of the AMBA PnP bus driver (ambapp_bus.c). + * + * Driver resources for the AMBA PnP bus provided can be set using + * gr_rasta_adcdac_set_resources(). + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <bsp.h> +#include <rtems/bspIo.h> +#include <rtems/score/isrlock.h> /* spin-lock */ +#include <pci.h> + +#include <ambapp.h> +#include <grlib.h> +#include <drvmgr/drvmgr.h> +#include <drvmgr/ambapp_bus.h> +#include <drvmgr/pci_bus.h> +#include <drvmgr/bspcommon.h> +#include <bsp/genirq.h> + +#include <bsp/gr_rasta_adcdac.h> + +/* map via rtems_interrupt_lock_* API: */ +#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock) +#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name) +#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level) +#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level) +#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level) +#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level) +#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k +#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k) + +/*#define DEBUG 1*/ + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +/* Determines which PCI address the AHB masters will access, it should be + * set so that the masters can access the CPU RAM. Default is base of CPU RAM, + * CPU RAM is mapped 1:1 to PCI space. + */ +extern unsigned int _RAM_START; +#define AHBMST2PCIADR (((unsigned int)&_RAM_START) & 0xf0000000) + +/* PCI ID */ +#define PCIID_VENDOR_GAISLER 0x1AC8 +#define PCIID_DEVICE_GR_RASTA_ADCDAC 0x0014 + +int gr_rasta_adcdac_init1(struct drvmgr_dev *dev); +int gr_rasta_adcdac_init2(struct drvmgr_dev *dev); +void gr_rasta_adcdac_isr (void *arg); + +struct grpci_regs { + volatile unsigned int cfg_stat; + volatile unsigned int bar0; + volatile unsigned int page0; + volatile unsigned int bar1; + volatile unsigned int page1; + volatile unsigned int iomap; + volatile unsigned int stat_cmd; +}; + +struct gr_rasta_adcdac_ver { + const unsigned int amba_freq_hz; /* The frequency */ + const unsigned int amba_ioarea; /* The address where the PnP IOAREA starts at */ +}; + +/* Private data structure for driver */ +struct gr_rasta_adcdac_priv { + /* Driver management */ + struct drvmgr_dev *dev; + char prefix[20]; + SPIN_DECLARE(devlock); + + /* PCI */ + pci_dev_t pcidev; + struct pci_dev_info *devinfo; + uint32_t ahbmst2pci_map; + + /* IRQ */ + genirq_t genirq; + + /* GR-RASTA-ADCDAC */ + struct gr_rasta_adcdac_ver *version; + struct irqmp_regs *irq; + struct grpci_regs *grpci; + struct drvmgr_map_entry bus_maps_down[3]; + struct drvmgr_map_entry bus_maps_up[2]; + + /* AMBA Plug&Play information on GR-RASTA-ADCDAC */ + struct ambapp_bus abus; + struct ambapp_mmap amba_maps[4]; + struct ambapp_config config; +}; + +struct gr_rasta_adcdac_ver gr_rasta_adcdac_ver0 = { + .amba_freq_hz = 50000000, + .amba_ioarea = 0x80100000, +}; + +int ambapp_rasta_adcdac_int_register( + struct drvmgr_dev *dev, + int irq, + const char *info, + drvmgr_isr handler, + void *arg); +int ambapp_rasta_adcdac_int_unregister( + struct drvmgr_dev *dev, + int irq, + drvmgr_isr isr, + void *arg); +int ambapp_rasta_adcdac_int_unmask( + struct drvmgr_dev *dev, + int irq); +int ambapp_rasta_adcdac_int_mask( + struct drvmgr_dev *dev, + int irq); +int ambapp_rasta_adcdac_int_clear( + struct drvmgr_dev *dev, + int irq); +int ambapp_rasta_adcdac_get_params( + struct drvmgr_dev *dev, + struct drvmgr_bus_params *params); + +struct ambapp_ops ambapp_rasta_adcdac_ops = { + .int_register = ambapp_rasta_adcdac_int_register, + .int_unregister = ambapp_rasta_adcdac_int_unregister, + .int_unmask = ambapp_rasta_adcdac_int_unmask, + .int_mask = ambapp_rasta_adcdac_int_mask, + .int_clear = ambapp_rasta_adcdac_int_clear, + .get_params = ambapp_rasta_adcdac_get_params +}; + +struct drvmgr_drv_ops gr_rasta_adcdac_ops = +{ .init = {gr_rasta_adcdac_init1, gr_rasta_adcdac_init2, NULL, NULL}, + .remove = NULL, + .info = NULL +}; + +struct pci_dev_id_match gr_rasta_adcdac_ids[] = +{ + PCIID_DEVVEND(PCIID_VENDOR_GAISLER, PCIID_DEVICE_GR_RASTA_ADCDAC), + PCIID_END_TABLE /* Mark end of table */ +}; + +struct pci_drv_info gr_rasta_adcdac_info = +{ + { + DRVMGR_OBJ_DRV, /* Driver */ + NULL, /* Next driver */ + NULL, /* Device list */ + DRIVER_PCI_GAISLER_RASTAADCDAC_ID,/* Driver ID */ + "GR-RASTA-ADCDAC_DRV", /* Driver Name */ + DRVMGR_BUS_TYPE_PCI, /* Bus Type */ + &gr_rasta_adcdac_ops, + NULL, /* Funcs */ + 0, /* No devices yet */ + 0, + }, + &gr_rasta_adcdac_ids[0] +}; + +/* Driver resources configuration for the AMBA bus on the GR-RASTA-ADCDAC board. + * It is declared weak so that the user may override it from the project file, + * if the default settings are not enough. + * + * The configuration consists of an array of configuration pointers, each + * pointer determine the configuration of one GR-RASTA-ADCDAC board. Pointer + * zero is for board0, pointer 1 for board1 and so on. + * + * The array must end with a NULL pointer. + */ +struct drvmgr_bus_res *gr_rasta_adcdac_resources[] __attribute__((weak)) = +{ + NULL +}; + +void gr_rasta_adcdac_register_drv(void) +{ + DBG("Registering GR-RASTA-ADCDAC PCI driver\n"); + drvmgr_drv_register(&gr_rasta_adcdac_info.general); +} + +void gr_rasta_adcdac_isr (void *arg) +{ + struct gr_rasta_adcdac_priv *priv = arg; + unsigned int status, tmp; + int irq; + SPIN_ISR_IRQFLAGS(irqflags); + + tmp = status = priv->irq->ipend; + + /* DBG("GR-RASTA-ADCDAC: IRQ 0x%x\n",status); */ + + SPIN_LOCK(&priv->devlock, irqflags); + for(irq=0; irq<16; irq++) { + if ( status & (1<<irq) ) { + genirq_doirq(priv->genirq, irq); + priv->irq->iclear = (1<<irq); + status &= ~(1<<irq); + if ( status == 0 ) + break; + } + } + SPIN_UNLOCK(&priv->devlock, irqflags); + + /* ACK interrupt, this is because PCI is Level, so the IRQ Controller still drives the IRQ. */ + if ( tmp ) + drvmgr_interrupt_clear(priv->dev, 0); + + DBG("RASTA-ADCDAC-IRQ: 0x%x\n", tmp); +} + +static int gr_rasta_adcdac_hw_init1(struct gr_rasta_adcdac_priv *priv) +{ + uint32_t data; + unsigned int *page0 = NULL; + struct ambapp_dev *tmp; + struct ambapp_ahb_info *ahb; + struct pci_dev_info *devinfo = priv->devinfo; + uint32_t bar0, bar0_size; + + /* Select version of GR-RASTA-ADCDAC board */ + switch (devinfo->rev) { + case 0: + priv->version = &gr_rasta_adcdac_ver0; + break; + default: + return -2; + } + + bar0 = devinfo->resources[0].address; + bar0_size = devinfo->resources[0].size; + page0 = (unsigned int *)(bar0 + bar0_size/2); + + /* Point PAGE0 to start of Plug and Play information */ + *page0 = priv->version->amba_ioarea & 0xf0000000; + + /* set parity error response */ + pci_cfg_r32(priv->pcidev, PCIR_COMMAND, &data); + pci_cfg_w32(priv->pcidev, PCIR_COMMAND, (data|PCIM_CMD_PERRESPEN)); + + /* Setup cache line size. Default cache line size will result in + * poor performance (256 word fetches), 0xff will set it according + * to the max size of the PCI FIFO. + */ + pci_cfg_w8(priv->pcidev, PCIR_CACHELNSZ, 0xff); + + /* Scan AMBA Plug&Play */ + + /* AMBA MAP bar0 (in CPU) ==> 0x80000000(remote amba address) */ + priv->amba_maps[0].size = bar0_size/2; + priv->amba_maps[0].local_adr = bar0; + priv->amba_maps[0].remote_adr = 0x80000000; + + /* AMBA MAP bar1 (in CPU) ==> 0x40000000(remote amba address) */ + priv->amba_maps[1].size = devinfo->resources[1].size; + priv->amba_maps[1].local_adr = devinfo->resources[1].address; + priv->amba_maps[1].remote_adr = 0x40000000; + + /* Addresses not matching with map be untouched */ + priv->amba_maps[2].size = 0xfffffff0; + priv->amba_maps[2].local_adr = 0; + priv->amba_maps[2].remote_adr = 0; + + /* Mark end of table */ + priv->amba_maps[3].size=0; + priv->amba_maps[3].local_adr = 0; + priv->amba_maps[3].remote_adr = 0; + + /* Start AMBA PnP scan at first AHB bus */ + /*ambapp_scan(priv->bar0 + (priv->version->amba_ioarea & ~0xf0000000), + NULL, &priv->amba_maps[0], NULL, &priv->abus.root, NULL);*/ + ambapp_scan(&priv->abus, + bar0 + (priv->version->amba_ioarea & ~0xf0000000), + NULL, &priv->amba_maps[0]); + + /* Initialize Frequency of AMBA bus */ + ambapp_freq_init(&priv->abus, NULL, priv->version->amba_freq_hz); + + /* Point PAGE0 to start of APB area */ + *page0 = 0x80000000; + + /* Find GRPCI controller */ + tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus, + (OPTIONS_ALL|OPTIONS_APB_SLVS), + VENDOR_GAISLER, GAISLER_PCIFBRG, + ambapp_find_by_idx, NULL); + if ( !tmp ) { + return -3; + } + priv->grpci = (struct grpci_regs *)((struct ambapp_apb_info *)tmp->devinfo)->start; + + /* Set GRPCI mmap so that AMBA masters can access CPU-RAM over + * the PCI window. + */ + priv->grpci->cfg_stat = (priv->grpci->cfg_stat & 0x0fffffff) | + (priv->ahbmst2pci_map & 0xf0000000); + priv->grpci->page1 = 0x40000000; + + /* Find IRQ controller */ + tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus, + (OPTIONS_ALL|OPTIONS_APB_SLVS), + VENDOR_GAISLER, GAISLER_IRQMP, + ambapp_find_by_idx, NULL); + if ( !tmp ) { + return -4; + } + priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start; + /* Set up GR-RASTA-ADCDAC irq controller */ + priv->irq->iclear = 0xffff; + priv->irq->ilevel = 0; + priv->irq->mask[0] = 0; + + /* DOWN streams translation table */ + priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA"; + priv->bus_maps_down[0].size = priv->amba_maps[0].size; + priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr; + priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr; + + priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA"; + priv->bus_maps_down[1].size = priv->amba_maps[1].size; + priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr; + priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr; + + /* Mark end of translation table */ + priv->bus_maps_down[2].size = 0; + + /* Find GRPCI controller AHB Slave interface */ + tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus, + (OPTIONS_ALL|OPTIONS_AHB_SLVS), + VENDOR_GAISLER, GAISLER_PCIFBRG, + ambapp_find_by_idx, NULL); + if ( !tmp ) { + return -5; + } + ahb = (struct ambapp_ahb_info *)tmp->devinfo; + + /* UP streams translation table */ + priv->bus_maps_up[0].name = "AMBA GRPCI Window"; + priv->bus_maps_up[0].size = ahb->mask[0]; /* AMBA->PCI Window on GR-RASTA-ADCDAC board */ + priv->bus_maps_up[0].from_adr = (void *)ahb->start[0]; + priv->bus_maps_up[0].to_adr = (void *) + (priv->ahbmst2pci_map & 0xf0000000); + + /* Mark end of translation table */ + priv->bus_maps_up[1].size = 0; + + /* Successfully registered the RASTA board */ + return 0; +} + +static int gr_rasta_adcdac_hw_init2(struct gr_rasta_adcdac_priv *priv) +{ + /* Enable DMA by enabling PCI target as master */ + pci_master_enable(priv->pcidev); + + return DRVMGR_OK; +} + +/* Called when a PCI target is found with the PCI device and vendor ID + * given in gr_rasta_adcdac_ids[]. + */ +int gr_rasta_adcdac_init1(struct drvmgr_dev *dev) +{ + struct gr_rasta_adcdac_priv *priv; + struct pci_dev_info *devinfo; + int status; + uint32_t bar0, bar1, bar0_size, bar1_size; + union drvmgr_key_value *value; + int resources_cnt; + + priv = malloc(sizeof(struct gr_rasta_adcdac_priv)); + if ( !priv ) + return DRVMGR_NOMEM; + + memset(priv, 0, sizeof(*priv)); + dev->priv = priv; + priv->dev = dev; + + /* Determine number of configurations */ + resources_cnt = get_resarray_count(gr_rasta_adcdac_resources); + + /* Generate Device prefix */ + + strcpy(priv->prefix, "/dev/rastaadcdac0"); + priv->prefix[16] += dev->minor_drv; + mkdir(priv->prefix, S_IRWXU | S_IRWXG | S_IRWXO); + priv->prefix[17] = '/'; + priv->prefix[18] = '\0'; + + priv->devinfo = devinfo = (struct pci_dev_info *)dev->businfo; + priv->pcidev = devinfo->pcidev; + bar0 = devinfo->resources[0].address; + bar0_size = devinfo->resources[0].size; + bar1 = devinfo->resources[1].address; + bar1_size = devinfo->resources[1].size; + printf("\n\n--- GR-RASTA-ADCDAC[%d] ---\n", dev->minor_drv); + printf(" PCI BUS: 0x%x, SLOT: 0x%x, FUNCTION: 0x%x\n", + PCI_DEV_EXPAND(priv->pcidev)); + printf(" PCI VENDOR: 0x%04x, DEVICE: 0x%04x\n", + devinfo->id.vendor, devinfo->id.device); + printf(" PCI BAR[0]: 0x%lx - 0x%lx\n", bar0, bar0 + bar0_size - 1); + printf(" PCI BAR[1]: 0x%lx - 0x%lx\n", bar1, bar1 + bar1_size - 1); + printf(" IRQ: %d\n\n\n", devinfo->irq); + + /* all neccessary space assigned to GR-RASTA-ADCDAC target? */ + if ((bar0_size == 0) || (bar1_size == 0)) + return DRVMGR_ENORES; + + /* Initialize spin-lock for this PCI perihperal device. This is to + * protect the Interrupt Controller Registers. The genirq layer is + * protecting its own internals and ISR dispatching. + */ + SPIN_INIT(&priv->devlock, priv->prefix); + + /* Let user override which PCI address the AHB masters of the + * RASTA-ADCDAC board access when doing DMA to CPU RAM. The AHB masters + * access the PCI Window of the AMBA bus, the MSB 4-bits of that address + * is translated according this config option before the address + * goes out on the PCI bus. + * Only the 4 MSB bits have an effect; + */ + value = drvmgr_dev_key_get(priv->dev, "ahbmst2pci", DRVMGR_KT_INT); + if (value) + priv->ahbmst2pci_map = value->i; + else + priv->ahbmst2pci_map = AHBMST2PCIADR; /* default */ + + priv->genirq = genirq_init(16); + if ( priv->genirq == NULL ) { + free(priv); + dev->priv = NULL; + return DRVMGR_FAIL; + } + + if ( (status = gr_rasta_adcdac_hw_init1(priv)) != 0 ) { + genirq_destroy(priv->genirq); + free(priv); + dev->priv = NULL; + printf(" Failed to initialize GR-RASTA-ADCDAC HW: %d\n", status); + return DRVMGR_FAIL; + } + + /* Init amba bus */ + priv->config.abus = &priv->abus; + priv->config.ops = &ambapp_rasta_adcdac_ops; + priv->config.maps_up = &priv->bus_maps_up[0]; + priv->config.maps_down = &priv->bus_maps_down[0]; + if ( priv->dev->minor_drv < resources_cnt ) { + priv->config.resources = gr_rasta_adcdac_resources[priv->dev->minor_drv]; + } else { + priv->config.resources = NULL; + } + + /* Create and register AMBA PnP bus. */ + return ambapp_bus_register(dev, &priv->config); +} + +int gr_rasta_adcdac_init2(struct drvmgr_dev *dev) +{ + struct gr_rasta_adcdac_priv *priv = dev->priv; + + /* Clear any old interrupt requests */ + drvmgr_interrupt_clear(dev, 0); + + /* Enable System IRQ so that GR-RASTA-ADCDAC PCI target interrupt + * goes through. + * + * It is important to enable it in stage init2. If interrupts were + * enabled in init1 this might hang the system when more than one + * PCI board is connected, this is because PCI interrupts might + * be shared and PCI board 2 have not initialized and might + * therefore drive interrupt already when entering init1(). + */ + drvmgr_interrupt_register( + dev, + 0, + "gr_rasta_adcdac", + gr_rasta_adcdac_isr, + (void *)priv); + + return gr_rasta_adcdac_hw_init2(priv); +} + +int ambapp_rasta_adcdac_int_register( + struct drvmgr_dev *dev, + int irq, + const char *info, + drvmgr_isr handler, + void *arg) +{ + struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv; + SPIN_IRQFLAGS(irqflags); + int status; + void *h; + + h = genirq_alloc_handler(handler, arg); + if ( h == NULL ) + return DRVMGR_FAIL; + + SPIN_LOCK_IRQ(&priv->devlock, irqflags); + + status = genirq_register(priv->genirq, irq, h); + if ( status == 0 ) { + /* Clear IRQ for first registered handler */ + priv->irq->iclear = (1<<irq); + } else if ( status == 1 ) + status = 0; + + if (status != 0) { + SPIN_UNLOCK_IRQ(&priv->devlock, irqflags); + genirq_free_handler(h); + return DRVMGR_FAIL; + } + + status = genirq_enable(priv->genirq, irq, handler, arg); + if ( status == 0 ) { + /* Enable IRQ for first enabled handler only */ + priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */ + } else if ( status == 1 ) + status = 0; + + SPIN_UNLOCK_IRQ(&priv->devlock, irqflags); + + return status; +} + +int ambapp_rasta_adcdac_int_unregister( + struct drvmgr_dev *dev, + int irq, + drvmgr_isr isr, + void *arg) +{ + struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv; + SPIN_IRQFLAGS(irqflags); + int status; + void *handler; + + SPIN_LOCK_IRQ(&priv->devlock, irqflags); + + status = genirq_disable(priv->genirq, irq, isr, arg); + if ( status == 0 ) { + /* Disable IRQ only when no enabled handler exists */ + priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */ + } + + handler = genirq_unregister(priv->genirq, irq, isr, arg); + if ( handler == NULL ) + status = DRVMGR_FAIL; + else + status = DRVMGR_OK; + + SPIN_UNLOCK_IRQ(&priv->devlock, irqflags); + + if (handler) + genirq_free_handler(handler); + + return status; +} + +int ambapp_rasta_adcdac_int_unmask( + struct drvmgr_dev *dev, + int irq) +{ + struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv; + SPIN_IRQFLAGS(irqflags); + + DBG("RASTA-ADCDAC IRQ %d: unmask\n", irq); + + if ( genirq_check(priv->genirq, irq) ) + return DRVMGR_EINVAL; + + SPIN_LOCK_IRQ(&priv->devlock, irqflags); + + /* Enable IRQ for first enabled handler only */ + priv->irq->mask[0] |= (1<<irq); /* unmask interrupt source */ + + SPIN_UNLOCK_IRQ(&priv->devlock, irqflags); + + return DRVMGR_OK; +} + +int ambapp_rasta_adcdac_int_mask( + struct drvmgr_dev *dev, + int irq) +{ + struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv; + SPIN_IRQFLAGS(irqflags); + + DBG("RASTA-ADCDAC IRQ %d: mask\n", irq); + + if ( genirq_check(priv->genirq, irq) ) + return DRVMGR_EINVAL; + + SPIN_LOCK_IRQ(&priv->devlock, irqflags); + + /* Disable/mask IRQ */ + priv->irq->mask[0] &= ~(1<<irq); /* mask interrupt source */ + + SPIN_UNLOCK_IRQ(&priv->devlock, irqflags); + + return DRVMGR_OK; +} + +int ambapp_rasta_adcdac_int_clear( + struct drvmgr_dev *dev, + int irq) +{ + struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv; + + if ( genirq_check(priv->genirq, irq) ) + return DRVMGR_FAIL; + + priv->irq->iclear = (1<<irq); + + return DRVMGR_OK; +} + +int ambapp_rasta_adcdac_get_params(struct drvmgr_dev *dev, struct drvmgr_bus_params *params) +{ + struct gr_rasta_adcdac_priv *priv = dev->parent->dev->priv; + + /* Device name prefix pointer, skip /dev */ + params->dev_prefix = &priv->prefix[5]; + + return 0; +} + +void gr_rasta_adcdac_print_dev(struct drvmgr_dev *dev, int options) +{ + struct gr_rasta_adcdac_priv *priv = dev->priv; + struct pci_dev_info *devinfo = priv->devinfo; + uint32_t bar0, bar1, bar0_size, bar1_size; + + /* Print */ + printf("--- GR-RASTA-ADCDAC [bus 0x%x, dev 0x%x, fun 0x%x] ---\n", + PCI_DEV_EXPAND(priv->pcidev)); + + bar0 = devinfo->resources[0].address; + bar0_size = devinfo->resources[0].size; + bar1 = devinfo->resources[1].address; + bar1_size = devinfo->resources[1].size; + + printf(" PCI BAR[0]: 0x%lx - 0x%lx\n", bar0, bar0 + bar0_size - 1); + printf(" PCI BAR[1]: 0x%lx - 0x%lx\n", bar1, bar1 + bar1_size - 1); + printf(" IRQ REGS: 0x%x\n", (unsigned int)priv->irq); + printf(" IRQ: %d\n", devinfo->irq); + printf(" PCI REVISION: %d\n", devinfo->rev); + printf(" FREQ: %d Hz\n", priv->version->amba_freq_hz); + printf(" IMASK: 0x%08x\n", priv->irq->mask[0]); + printf(" IPEND: 0x%08x\n", priv->irq->ipend); + + /* Print amba config */ + if ( options & RASTA_ADCDAC_OPTIONS_AMBA ) { + ambapp_print(&priv->abus, 10); + } +#if 0 + /* Print IRQ handlers and their arguments */ + if ( options & RASTA_ADCDAC_OPTIONS_IRQ ) { + int i; + for(i=0; i<16; i++) { + printf(" IRQ[%02d]: 0x%x, arg: 0x%x\n", + i, (unsigned int)priv->isrs[i].handler, (unsigned int)priv->isrs[i].arg); + } + } +#endif +} + +void gr_rasta_adcdac_print(int options) +{ + struct pci_drv_info *drv = &gr_rasta_adcdac_info; + struct drvmgr_dev *dev; + + dev = drv->general.dev; + while(dev) { + gr_rasta_adcdac_print_dev(dev, options); + dev = dev->next_in_drv; + } +} |