History

dmaengine: sprd: Add wrap address support for link-list mode

The Spreadtrum Audio compress offload mode will use 2-stage DMA transfer to save power. That means we can request 2 dma channels, one for source channel, and another one for destination channel. Once the source channel's transaction is done, it will trigger the destination channel's transaction automatically by hardware signal. In this case, the source channel will transfer data from IRAM buffer to the DSP fifo to decoding/encoding, once IRAM buffer is empty by transferring done, the destination channel will start to transfer data from DDR buffer to IRAM buffer. Since the destination channel will use link-list mode to fill the IRAM data, and IRAM buffer is allocated by 32K, and DDR buffer is larger to 2M, that means we need lots of link-list nodes to do a cyclic transfer, instead wasting lots of link-list memory, we can use wrap address support to reduce link-list node number, which means when the transfer address reaches the wrap address, the transfer address will jump to the wrap_to address specified by wrap_to register, and only 2 link-list nodes can do a cyclic transfer to transfer data from DDR to IRAM. Thus this patch adds wrap address to support this case. [Baolin Wang changes the commit message] Signed-off-by: Eric Long <eric.long@unisoc.com> Signed-off-by: Baolin Wang <baolin.wang@linaro.org> Link: https://lore.kernel.org/r/85a5484bc1f3dd53ce6f92700ad8b35f30a0b096.1571812029.git.baolin.wang@linaro.org Signed-off-by: Vinod Koul <vkoul@kernel.org>

Eric Long committed 7 years ago

Commit a7e335d1 parent bb5a4712 files · +17 −0Browse files

Unified · Split

2 files
  1. drivers/dma/sprd-dma.c +13 −0
  2. include/linux/dma/sprd-dma.h +4 −0
drivers/dma/sprd-dma.c+13−0
@@ -99,6 +99,7 @@ · 98 unmodified lines
99/* DMA_CHN_WARP_* register definition */99/* DMA_CHN_WARP_* register definition */
100#define SPRD_DMA_HIGH_ADDR_MASK GENMASK(31, 28)100#define SPRD_DMA_HIGH_ADDR_MASK GENMASK(31, 28)
101#define SPRD_DMA_LOW_ADDR_MASK GENMASK(31, 0)101#define SPRD_DMA_LOW_ADDR_MASK GENMASK(31, 0)
102#define SPRD_DMA_WRAP_ADDR_MASK GENMASK(27, 0)
102#define SPRD_DMA_HIGH_ADDR_OFFSET 4103#define SPRD_DMA_HIGH_ADDR_OFFSET 4
103 104
104/* SPRD_DMA_CHN_INTC register definition */105/* SPRD_DMA_CHN_INTC register definition */
@@ -118,6 +119,8 @@ · 13 unmodified lines
118#define SPRD_DMA_SWT_MODE_OFFSET 26119#define SPRD_DMA_SWT_MODE_OFFSET 26
119#define SPRD_DMA_REQ_MODE_OFFSET 24120#define SPRD_DMA_REQ_MODE_OFFSET 24
120#define SPRD_DMA_REQ_MODE_MASK GENMASK(1, 0)121#define SPRD_DMA_REQ_MODE_MASK GENMASK(1, 0)
122#define SPRD_DMA_WRAP_SEL_DEST BIT(23)
123#define SPRD_DMA_WRAP_EN BIT(22)
121#define SPRD_DMA_FIX_SEL_OFFSET 21124#define SPRD_DMA_FIX_SEL_OFFSET 21
122#define SPRD_DMA_FIX_EN_OFFSET 20125#define SPRD_DMA_FIX_EN_OFFSET 20
123#define SPRD_DMA_LLIST_END BIT(19)126#define SPRD_DMA_LLIST_END BIT(19)
@@ -804,6 +807,8 @@ static int sprd_dma_fill_desc(struct dma_chan *chan, · 680 unmodified lines
804 temp |= req_mode << SPRD_DMA_REQ_MODE_OFFSET;807 temp |= req_mode << SPRD_DMA_REQ_MODE_OFFSET;
805 temp |= fix_mode << SPRD_DMA_FIX_SEL_OFFSET;808 temp |= fix_mode << SPRD_DMA_FIX_SEL_OFFSET;
806 temp |= fix_en << SPRD_DMA_FIX_EN_OFFSET;809 temp |= fix_en << SPRD_DMA_FIX_EN_OFFSET;
810 temp |= schan->linklist.wrap_addr ?
811 SPRD_DMA_WRAP_EN | SPRD_DMA_WRAP_SEL_DEST : 0;
807 temp |= slave_cfg->src_maxburst & SPRD_DMA_FRG_LEN_MASK;812 temp |= slave_cfg->src_maxburst & SPRD_DMA_FRG_LEN_MASK;
808 hw->frg_len = temp;813 hw->frg_len = temp;
809 814
@@ -831,6 +836,12 @@ static int sprd_dma_fill_desc(struct dma_chan *chan, · 21 unmodified lines
831 hw->llist_ptr = lower_32_bits(llist_ptr);836 hw->llist_ptr = lower_32_bits(llist_ptr);
832 hw->src_blk_step = (upper_32_bits(llist_ptr) << SPRD_DMA_LLIST_HIGH_SHIFT) &837 hw->src_blk_step = (upper_32_bits(llist_ptr) << SPRD_DMA_LLIST_HIGH_SHIFT) &
833 SPRD_DMA_LLIST_HIGH_MASK;838 SPRD_DMA_LLIST_HIGH_MASK;
839
840 if (schan->linklist.wrap_addr) {
841 hw->wrap_ptr |= schan->linklist.wrap_addr &
842 SPRD_DMA_WRAP_ADDR_MASK;
843 hw->wrap_to |= dst & SPRD_DMA_WRAP_ADDR_MASK;
844 }
834 } else {845 } else {
835 hw->llist_ptr = 0;846 hw->llist_ptr = 0;
836 hw->src_blk_step = 0;847 hw->src_blk_step = 0;
@@ -939,9 +950,11 @@ sprd_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, · 102 unmodified lines
939 950
940 schan->linklist.phy_addr = ll_cfg->phy_addr;951 schan->linklist.phy_addr = ll_cfg->phy_addr;
941 schan->linklist.virt_addr = ll_cfg->virt_addr;952 schan->linklist.virt_addr = ll_cfg->virt_addr;
953 schan->linklist.wrap_addr = ll_cfg->wrap_addr;
942 } else {954 } else {
943 schan->linklist.phy_addr = 0;955 schan->linklist.phy_addr = 0;
944 schan->linklist.virt_addr = 0;956 schan->linklist.virt_addr = 0;
957 schan->linklist.wrap_addr = 0;
945 }958 }
946 959
947 /*960 /*
include/linux/dma/sprd-dma.h+4−0
@@ -118,6 +118,9 @@ enum sprd_dma_int_type { · 117 unmodified lines
118 * struct sprd_dma_linklist - DMA link-list address structure118 * struct sprd_dma_linklist - DMA link-list address structure
119 * @virt_addr: link-list virtual address to configure link-list node119 * @virt_addr: link-list virtual address to configure link-list node
120 * @phy_addr: link-list physical address to link DMA transfer120 * @phy_addr: link-list physical address to link DMA transfer
121 * @wrap_addr: the wrap address for link-list mode, which means once the
122 * transfer address reaches the wrap address, the next transfer address
123 * will jump to the address specified by wrap_to register.
121 *124 *
122 * The Spreadtrum DMA controller supports the link-list mode, that means slaves125 * The Spreadtrum DMA controller supports the link-list mode, that means slaves
123 * can supply several groups configurations (each configuration represents one126 * can supply several groups configurations (each configuration represents one
@@ -181,6 +184,7 @@ enum sprd_dma_int_type { · 57 unmodified lines
181struct sprd_dma_linklist {184struct sprd_dma_linklist {
182 unsigned long virt_addr;185 unsigned long virt_addr;
183 phys_addr_t phy_addr;186 phys_addr_t phy_addr;
187 phys_addr_t wrap_addr;
184};188};
185 189
186#endif190#endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t