/** * Initialize BAM DMA device * */ int sps_dma_device_init(u32 h) { struct bamdma_device *dev; struct sps_bam_props *props; u32 chan; int result = SPS_ERROR; mutex_lock(&bam_dma_lock); /* Find a free BAM-DMA device slot */ dev = NULL; if (bam_dma_dev[0].bam != NULL) { SPS_ERR("BAM-DMA BAM device already initialized."); goto exit_err; } else { dev = &bam_dma_dev[0]; } /* Record BAM */ memset(dev, 0, sizeof(*dev)); dev->h = h; dev->bam = sps_h2bam(h); if (dev->bam == NULL) { SPS_ERR("BAM-DMA BAM device is not found from the handle."); goto exit_err; } /* Map the BAM DMA device into virtual space, if necessary */ props = &dev->bam->props; dev->phys_addr = props->periph_phys_addr; if (props->periph_virt_addr != NULL) { dev->virt_addr = props->periph_virt_addr; dev->virtual_mapped = false; } else { if (props->periph_virt_size == 0) { SPS_ERR("Unable to map BAM DMA IO memory: %x %x", dev->phys_addr, props->periph_virt_size); goto exit_err; } dev->virt_addr = ioremap(dev->phys_addr, props->periph_virt_size); if (dev->virt_addr == NULL) { SPS_ERR("Unable to map BAM DMA IO memory: %x %x", dev->phys_addr, props->periph_virt_size); goto exit_err; } dev->virtual_mapped = true; } dev->hwio = (void *) dev->virt_addr; /* Is the BAM-DMA device locally controlled? */ if ((props->manage & SPS_BAM_MGR_DEVICE_REMOTE) == 0) { SPS_DBG("BAM-DMA is controlled locally: %x", dev->phys_addr); dev->local = true; } else { SPS_DBG("BAM-DMA is controlled remotely: %x", dev->phys_addr); dev->local = false; } /* * Enable the BAM DMA and determine the number of pipes/channels. * Leave the BAM-DMA enabled, since it is always a shared device. */ if (sps_dma_device_enable(dev)) goto exit_err; dev->num_pipes = dev->bam->props.num_pipes; /* Disable all channels */ if (dev->local) for (chan = 0; chan < (dev->num_pipes / 2); chan++) { dma_write_reg_field(dev->virt_addr, DMA_CHNL_CONFIG(chan), DMA_CHNL_ENABLE, 0); } result = 0; exit_err: if (result) { if (dev != NULL) { if (dev->virtual_mapped) iounmap(dev->virt_addr); dev->bam = NULL; } } mutex_unlock(&bam_dma_lock); return result; }
int sps_dma_device_init(u32 h) { struct bamdma_device *dev; struct sps_bam_props *props; u32 chan; int result = SPS_ERROR; mutex_lock(&bam_dma_lock); dev = NULL; if (bam_dma_dev[0].bam != NULL) { SPS_ERR("sps:BAM-DMA BAM device is already initialized."); goto exit_err; } else { dev = &bam_dma_dev[0]; } memset(dev, 0, sizeof(*dev)); dev->h = h; dev->bam = sps_h2bam(h); if (dev->bam == NULL) { SPS_ERR("sps:BAM-DMA BAM device is not found " "from the handle."); goto exit_err; } props = &dev->bam->props; dev->phys_addr = props->periph_phys_addr; if (props->periph_virt_addr != NULL) { dev->virt_addr = props->periph_virt_addr; dev->virtual_mapped = false; } else { if (props->periph_virt_size == 0) { SPS_ERR("sps:Unable to map BAM DMA IO memory: %x %x", dev->phys_addr, props->periph_virt_size); goto exit_err; } dev->virt_addr = ioremap(dev->phys_addr, props->periph_virt_size); if (dev->virt_addr == NULL) { SPS_ERR("sps:Unable to map BAM DMA IO memory: %x %x", dev->phys_addr, props->periph_virt_size); goto exit_err; } dev->virtual_mapped = true; } dev->hwio = (void *) dev->virt_addr; if ((props->manage & SPS_BAM_MGR_DEVICE_REMOTE) == 0) { SPS_DBG2("sps:BAM-DMA is controlled locally: %x", dev->phys_addr); dev->local = true; } else { SPS_DBG2("sps:BAM-DMA is controlled remotely: %x", dev->phys_addr); dev->local = false; } if (sps_dma_device_enable(dev)) goto exit_err; dev->num_pipes = dev->bam->props.num_pipes; if (dev->local) for (chan = 0; chan < (dev->num_pipes / 2); chan++) { dma_write_reg_field(dev->virt_addr, DMA_CHNL_CONFIG(chan), DMA_CHNL_ENABLE, 0); } result = 0; exit_err: if (result) { if (dev != NULL) { if (dev->virtual_mapped) iounmap(dev->virt_addr); dev->bam = NULL; } } mutex_unlock(&bam_dma_lock); return result; }