aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/qcom_bam_dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/qcom_bam_dma.c')
-rw-r--r--drivers/dma/qcom_bam_dma.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c
index 82c923146e49..7a4bbb0f80a5 100644
--- a/drivers/dma/qcom_bam_dma.c
+++ b/drivers/dma/qcom_bam_dma.c
@@ -61,12 +61,17 @@ struct bam_desc_hw {
61#define DESC_FLAG_INT BIT(15) 61#define DESC_FLAG_INT BIT(15)
62#define DESC_FLAG_EOT BIT(14) 62#define DESC_FLAG_EOT BIT(14)
63#define DESC_FLAG_EOB BIT(13) 63#define DESC_FLAG_EOB BIT(13)
64#define DESC_FLAG_NWD BIT(12)
64 65
65struct bam_async_desc { 66struct bam_async_desc {
66 struct virt_dma_desc vd; 67 struct virt_dma_desc vd;
67 68
68 u32 num_desc; 69 u32 num_desc;
69 u32 xfer_len; 70 u32 xfer_len;
71
72 /* transaction flags, EOT|EOB|NWD */
73 u16 flags;
74
70 struct bam_desc_hw *curr_desc; 75 struct bam_desc_hw *curr_desc;
71 76
72 enum dma_transfer_direction dir; 77 enum dma_transfer_direction dir;
@@ -490,6 +495,14 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan,
490 if (!async_desc) 495 if (!async_desc)
491 goto err_out; 496 goto err_out;
492 497
498 if (flags & DMA_PREP_FENCE)
499 async_desc->flags |= DESC_FLAG_NWD;
500
501 if (flags & DMA_PREP_INTERRUPT)
502 async_desc->flags |= DESC_FLAG_EOT;
503 else
504 async_desc->flags |= DESC_FLAG_INT;
505
493 async_desc->num_desc = num_alloc; 506 async_desc->num_desc = num_alloc;
494 async_desc->curr_desc = async_desc->desc; 507 async_desc->curr_desc = async_desc->desc;
495 async_desc->dir = direction; 508 async_desc->dir = direction;
@@ -793,8 +806,11 @@ static void bam_start_dma(struct bam_chan *bchan)
793 else 806 else
794 async_desc->xfer_len = async_desc->num_desc; 807 async_desc->xfer_len = async_desc->num_desc;
795 808
796 /* set INT on last descriptor */ 809 /* set any special flags on the last descriptor */
797 desc[async_desc->xfer_len - 1].flags |= DESC_FLAG_INT; 810 if (async_desc->num_desc == async_desc->xfer_len)
811 desc[async_desc->xfer_len - 1].flags = async_desc->flags;
812 else
813 desc[async_desc->xfer_len - 1].flags |= DESC_FLAG_INT;
798 814
799 if (bchan->tail + async_desc->xfer_len > MAX_DESCRIPTORS) { 815 if (bchan->tail + async_desc->xfer_len > MAX_DESCRIPTORS) {
800 u32 partial = MAX_DESCRIPTORS - bchan->tail; 816 u32 partial = MAX_DESCRIPTORS - bchan->tail;