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

Commit 346ea25e authored by Vinod Koul's avatar Vinod Koul
Browse files

Merge branch 'topic/qcom' into for-linus

parents 05890d55 749d0d4b
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -395,6 +395,13 @@ where to put them)
	  when DMA_CTRL_REUSE is already set
	- Terminating the channel

  * DMA_PREP_CMD
    - If set, the client driver tells DMA controller that passed data in DMA
      API is command data.
    - Interpretation of command data is DMA controller specific. It can be
      used for issuing commands to other peripherals/register reads/register
      writes for which the descriptor should be in different format from
      normal data descriptors.

General Design Notes
--------------------
+5 −1
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ struct bam_desc_hw {
#define DESC_FLAG_EOT BIT(14)
#define DESC_FLAG_EOB BIT(13)
#define DESC_FLAG_NWD BIT(12)
#define DESC_FLAG_CMD BIT(11)

struct bam_async_desc {
	struct virt_dma_desc vd;
@@ -645,6 +646,9 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan,
		unsigned int curr_offset = 0;

		do {
			if (flags & DMA_PREP_CMD)
				desc->flags |= cpu_to_le16(DESC_FLAG_CMD);

			desc->addr = cpu_to_le32(sg_dma_address(sg) +
						 curr_offset);

@@ -960,7 +964,7 @@ static void bam_start_dma(struct bam_chan *bchan)

	/* set any special flags on the last descriptor */
	if (async_desc->num_desc == async_desc->xfer_len)
		desc[async_desc->xfer_len - 1].flags =
		desc[async_desc->xfer_len - 1].flags |=
					cpu_to_le16(async_desc->flags);
	else
		desc[async_desc->xfer_len - 1].flags |=
+36 −1
Original line number Diff line number Diff line
@@ -411,7 +411,40 @@ hidma_prep_dma_memcpy(struct dma_chan *dmach, dma_addr_t dest, dma_addr_t src,
		return NULL;

	hidma_ll_set_transfer_params(mdma->lldev, mdesc->tre_ch,
				     src, dest, len, flags);
				     src, dest, len, flags,
				     HIDMA_TRE_MEMCPY);

	/* Place descriptor in prepared list */
	spin_lock_irqsave(&mchan->lock, irqflags);
	list_add_tail(&mdesc->node, &mchan->prepared);
	spin_unlock_irqrestore(&mchan->lock, irqflags);

	return &mdesc->desc;
}

static struct dma_async_tx_descriptor *
hidma_prep_dma_memset(struct dma_chan *dmach, dma_addr_t dest, int value,
		size_t len, unsigned long flags)
{
	struct hidma_chan *mchan = to_hidma_chan(dmach);
	struct hidma_desc *mdesc = NULL;
	struct hidma_dev *mdma = mchan->dmadev;
	unsigned long irqflags;

	/* Get free descriptor */
	spin_lock_irqsave(&mchan->lock, irqflags);
	if (!list_empty(&mchan->free)) {
		mdesc = list_first_entry(&mchan->free, struct hidma_desc, node);
		list_del(&mdesc->node);
	}
	spin_unlock_irqrestore(&mchan->lock, irqflags);

	if (!mdesc)
		return NULL;

	hidma_ll_set_transfer_params(mdma->lldev, mdesc->tre_ch,
				     value, dest, len, flags,
				     HIDMA_TRE_MEMSET);

	/* Place descriptor in prepared list */
	spin_lock_irqsave(&mchan->lock, irqflags);
@@ -776,6 +809,7 @@ static int hidma_probe(struct platform_device *pdev)
	pm_runtime_get_sync(dmadev->ddev.dev);

	dma_cap_set(DMA_MEMCPY, dmadev->ddev.cap_mask);
	dma_cap_set(DMA_MEMSET, dmadev->ddev.cap_mask);
	if (WARN_ON(!pdev->dev.dma_mask)) {
		rc = -ENXIO;
		goto dmafree;
@@ -786,6 +820,7 @@ static int hidma_probe(struct platform_device *pdev)
	dmadev->dev_trca = trca;
	dmadev->trca_resource = trca_resource;
	dmadev->ddev.device_prep_dma_memcpy = hidma_prep_dma_memcpy;
	dmadev->ddev.device_prep_dma_memset = hidma_prep_dma_memset;
	dmadev->ddev.device_alloc_chan_resources = hidma_alloc_chan_resources;
	dmadev->ddev.device_free_chan_resources = hidma_free_chan_resources;
	dmadev->ddev.device_tx_status = hidma_tx_status;
+6 −1
Original line number Diff line number Diff line
@@ -28,6 +28,11 @@
#define HIDMA_TRE_DEST_LOW_IDX		4
#define HIDMA_TRE_DEST_HI_IDX		5

enum tre_type {
	HIDMA_TRE_MEMCPY = 3,
	HIDMA_TRE_MEMSET = 4,
};

struct hidma_tre {
	atomic_t allocated;		/* if this channel is allocated	    */
	bool queued;			/* flag whether this is pending     */
@@ -150,7 +155,7 @@ void hidma_ll_start(struct hidma_lldev *llhndl);
int hidma_ll_disable(struct hidma_lldev *lldev);
int hidma_ll_enable(struct hidma_lldev *llhndl);
void hidma_ll_set_transfer_params(struct hidma_lldev *llhndl, u32 tre_ch,
	dma_addr_t src, dma_addr_t dest, u32 len, u32 flags);
	dma_addr_t src, dma_addr_t dest, u32 len, u32 flags, u32 txntype);
void hidma_ll_setup_irq(struct hidma_lldev *lldev, bool msi);
int hidma_ll_setup(struct hidma_lldev *lldev);
struct hidma_lldev *hidma_ll_init(struct device *dev, u32 max_channels,
+4 −7
Original line number Diff line number Diff line
@@ -105,10 +105,6 @@ enum ch_state {
	HIDMA_CH_STOPPED = 4,
};

enum tre_type {
	HIDMA_TRE_MEMCPY = 3,
};

enum err_code {
	HIDMA_EVRE_STATUS_COMPLETE = 1,
	HIDMA_EVRE_STATUS_ERROR = 4,
@@ -174,8 +170,7 @@ int hidma_ll_request(struct hidma_lldev *lldev, u32 sig, const char *dev_name,
	tre->err_info = 0;
	tre->lldev = lldev;
	tre_local = &tre->tre_local[0];
	tre_local[HIDMA_TRE_CFG_IDX] = HIDMA_TRE_MEMCPY;
	tre_local[HIDMA_TRE_CFG_IDX] |= (lldev->chidx & 0xFF) << 8;
	tre_local[HIDMA_TRE_CFG_IDX] = (lldev->chidx & 0xFF) << 8;
	tre_local[HIDMA_TRE_CFG_IDX] |= BIT(16);	/* set IEOB */
	*tre_ch = i;
	if (callback)
@@ -607,7 +602,7 @@ int hidma_ll_disable(struct hidma_lldev *lldev)

void hidma_ll_set_transfer_params(struct hidma_lldev *lldev, u32 tre_ch,
				  dma_addr_t src, dma_addr_t dest, u32 len,
				  u32 flags)
				  u32 flags, u32 txntype)
{
	struct hidma_tre *tre;
	u32 *tre_local;
@@ -626,6 +621,8 @@ void hidma_ll_set_transfer_params(struct hidma_lldev *lldev, u32 tre_ch,
	}

	tre_local = &tre->tre_local[0];
	tre_local[HIDMA_TRE_CFG_IDX] &= ~GENMASK(7, 0);
	tre_local[HIDMA_TRE_CFG_IDX] |= txntype;
	tre_local[HIDMA_TRE_LEN_IDX] = len;
	tre_local[HIDMA_TRE_SRC_LOW_IDX] = lower_32_bits(src);
	tre_local[HIDMA_TRE_SRC_HI_IDX] = upper_32_bits(src);
Loading