/**
 * 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;
}
Beispiel #2
0
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;
}