Loading Documentation/dmaengine/provider.txt +7 −0 Original line number Diff line number Diff line Loading @@ -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 -------------------- Loading drivers/dma/qcom/bam_dma.c +5 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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 |= Loading drivers/dma/qcom/hidma.c +36 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; Loading drivers/dma/qcom/hidma.h +6 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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, Loading drivers/dma/qcom/hidma_ll.c +4 −7 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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) Loading Loading @@ -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; Loading @@ -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 Loading
Documentation/dmaengine/provider.txt +7 −0 Original line number Diff line number Diff line Loading @@ -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 -------------------- Loading
drivers/dma/qcom/bam_dma.c +5 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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 |= Loading
drivers/dma/qcom/hidma.c +36 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; Loading
drivers/dma/qcom/hidma.h +6 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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, Loading
drivers/dma/qcom/hidma_ll.c +4 −7 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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) Loading Loading @@ -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; Loading @@ -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