Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2335d338 authored by Sascha Hauer's avatar Sascha Hauer
Browse files

Merge branch 'dmaengine-sdma' into dmaengine

parents f8a356ff 23889c63
Loading
Loading
Loading
Loading
+35 −25
Original line number Original line Diff line number Diff line
@@ -230,7 +230,7 @@ struct sdma_engine;
 * struct sdma_channel - housekeeping for a SDMA channel
 * struct sdma_channel - housekeeping for a SDMA channel
 *
 *
 * @sdma		pointer to the SDMA engine for this channel
 * @sdma		pointer to the SDMA engine for this channel
 * @channel		the channel number, matches dmaengine chan_id
 * @channel		the channel number, matches dmaengine chan_id + 1
 * @direction		transfer type. Needed for setting SDMA script
 * @direction		transfer type. Needed for setting SDMA script
 * @peripheral_type	Peripheral type. Needed for setting SDMA script
 * @peripheral_type	Peripheral type. Needed for setting SDMA script
 * @event_id0		aka dma request line
 * @event_id0		aka dma request line
@@ -301,6 +301,7 @@ struct sdma_firmware_header {


struct sdma_engine {
struct sdma_engine {
	struct device			*dev;
	struct device			*dev;
	struct device_dma_parameters	dma_parms;
	struct sdma_channel		channel[MAX_DMA_CHANNELS];
	struct sdma_channel		channel[MAX_DMA_CHANNELS];
	struct sdma_channel_control	*channel_control;
	struct sdma_channel_control	*channel_control;
	void __iomem			*regs;
	void __iomem			*regs;
@@ -798,7 +799,7 @@ static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx)


	cookie = sdma_assign_cookie(sdmac);
	cookie = sdma_assign_cookie(sdmac);


	sdma_enable_channel(sdma, tx->chan->chan_id);
	sdma_enable_channel(sdma, sdmac->channel);


	spin_unlock_irq(&sdmac->lock);
	spin_unlock_irq(&sdmac->lock);


@@ -811,10 +812,6 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
	struct imx_dma_data *data = chan->private;
	struct imx_dma_data *data = chan->private;
	int prio, ret;
	int prio, ret;


	/* No need to execute this for internal channel 0 */
	if (chan->chan_id == 0)
		return 0;

	if (!data)
	if (!data)
		return -EINVAL;
		return -EINVAL;


@@ -879,7 +876,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
	struct sdma_channel *sdmac = to_sdma_chan(chan);
	struct sdma_channel *sdmac = to_sdma_chan(chan);
	struct sdma_engine *sdma = sdmac->sdma;
	struct sdma_engine *sdma = sdmac->sdma;
	int ret, i, count;
	int ret, i, count;
	int channel = chan->chan_id;
	int channel = sdmac->channel;
	struct scatterlist *sg;
	struct scatterlist *sg;


	if (sdmac->status == DMA_IN_PROGRESS)
	if (sdmac->status == DMA_IN_PROGRESS)
@@ -924,10 +921,24 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
			ret =  -EINVAL;
			ret =  -EINVAL;
			goto err_out;
			goto err_out;
		}
		}
		if (sdmac->word_size == DMA_SLAVE_BUSWIDTH_4_BYTES)

		switch (sdmac->word_size) {
		case DMA_SLAVE_BUSWIDTH_4_BYTES:
			bd->mode.command = 0;
			bd->mode.command = 0;
		else
			if (count & 3 || sg->dma_address & 3)
			bd->mode.command = sdmac->word_size;
				return NULL;
			break;
		case DMA_SLAVE_BUSWIDTH_2_BYTES:
			bd->mode.command = 2;
			if (count & 1 || sg->dma_address & 1)
				return NULL;
			break;
		case DMA_SLAVE_BUSWIDTH_1_BYTE:
			bd->mode.command = 1;
			break;
		default:
			return NULL;
		}


		param = BD_DONE | BD_EXTD | BD_CONT;
		param = BD_DONE | BD_EXTD | BD_CONT;


@@ -963,7 +974,7 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
	struct sdma_channel *sdmac = to_sdma_chan(chan);
	struct sdma_channel *sdmac = to_sdma_chan(chan);
	struct sdma_engine *sdma = sdmac->sdma;
	struct sdma_engine *sdma = sdmac->sdma;
	int num_periods = buf_len / period_len;
	int num_periods = buf_len / period_len;
	int channel = chan->chan_id;
	int channel = sdmac->channel;
	int ret, i = 0, buf = 0;
	int ret, i = 0, buf = 0;


	dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);
	dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);
@@ -1237,7 +1248,6 @@ static int __init sdma_probe(struct platform_device *pdev)
	struct resource *iores;
	struct resource *iores;
	struct sdma_platform_data *pdata = pdev->dev.platform_data;
	struct sdma_platform_data *pdata = pdev->dev.platform_data;
	int i;
	int i;
	dma_cap_mask_t mask;
	struct sdma_engine *sdma;
	struct sdma_engine *sdma;


	sdma = kzalloc(sizeof(*sdma), GFP_KERNEL);
	sdma = kzalloc(sizeof(*sdma), GFP_KERNEL);
@@ -1280,6 +1290,9 @@ static int __init sdma_probe(struct platform_device *pdev)


	sdma->version = pdata->sdma_version;
	sdma->version = pdata->sdma_version;


	dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask);
	dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask);

	INIT_LIST_HEAD(&sdma->dma_device.channels);
	INIT_LIST_HEAD(&sdma->dma_device.channels);
	/* Initialize channel parameters */
	/* Initialize channel parameters */
	for (i = 0; i < MAX_DMA_CHANNELS; i++) {
	for (i = 0; i < MAX_DMA_CHANNELS; i++) {
@@ -1288,15 +1301,17 @@ static int __init sdma_probe(struct platform_device *pdev)
		sdmac->sdma = sdma;
		sdmac->sdma = sdma;
		spin_lock_init(&sdmac->lock);
		spin_lock_init(&sdmac->lock);


		dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask);
		dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask);

		sdmac->chan.device = &sdma->dma_device;
		sdmac->chan.device = &sdma->dma_device;
		sdmac->chan.chan_id = i;
		sdmac->channel = i;
		sdmac->channel = i;


		/* Add the channel to the DMAC list */
		/*
		list_add_tail(&sdmac->chan.device_node, &sdma->dma_device.channels);
		 * Add the channel to the DMAC list. Do not add channel 0 though
		 * because we need it internally in the SDMA driver. This also means
		 * that channel 0 in dmaengine counting matches sdma channel 1.
		 */
		if (i)
			list_add_tail(&sdmac->chan.device_node,
					&sdma->dma_device.channels);
	}
	}


	ret = sdma_init(sdma);
	ret = sdma_init(sdma);
@@ -1317,6 +1332,8 @@ static int __init sdma_probe(struct platform_device *pdev)
	sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic;
	sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic;
	sdma->dma_device.device_control = sdma_control;
	sdma->dma_device.device_control = sdma_control;
	sdma->dma_device.device_issue_pending = sdma_issue_pending;
	sdma->dma_device.device_issue_pending = sdma_issue_pending;
	sdma->dma_device.dev->dma_parms = &sdma->dma_parms;
	dma_set_max_seg_size(sdma->dma_device.dev, 65535);


	ret = dma_async_device_register(&sdma->dma_device);
	ret = dma_async_device_register(&sdma->dma_device);
	if (ret) {
	if (ret) {
@@ -1324,13 +1341,6 @@ static int __init sdma_probe(struct platform_device *pdev)
		goto err_init;
		goto err_init;
	}
	}


	/* request channel 0. This is an internal control channel
	 * to the SDMA engine and not available to clients.
	 */
	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);
	dma_request_channel(mask, NULL, NULL);

	dev_info(sdma->dev, "initialized\n");
	dev_info(sdma->dev, "initialized\n");


	return 0;
	return 0;