Message ID | 85a5484bc1f3dd53ce6f92700ad8b35f30a0b096.1571812029.git.baolin.wang@linaro.org |
---|---|
State | New |
Headers | show |
Series | dmaengine: sprd: Add wrap address support for link-list mode | expand |
On 23-10-19, 14:31, Baolin Wang wrote: > From: Eric Long <eric.long@unisoc.com> > > 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. This fails to apply, can you please rebase and resend! Thanks -- ~Vinod
On Thu, 14 Nov 2019 at 12:50, Vinod Koul <vkoul@kernel.org> wrote: > > On 23-10-19, 14:31, Baolin Wang wrote: > > From: Eric Long <eric.long@unisoc.com> > > > > 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. > > This fails to apply, can you please rebase and resend! Sure, sorry for the trouble. Will rebase and resend. Thanks. -- Baolin Wang Best Regards
diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c index 32402c2..9a31a315 100644 --- a/drivers/dma/sprd-dma.c +++ b/drivers/dma/sprd-dma.c @@ -99,6 +99,7 @@ /* DMA_CHN_WARP_* register definition */ #define SPRD_DMA_HIGH_ADDR_MASK GENMASK(31, 28) #define SPRD_DMA_LOW_ADDR_MASK GENMASK(31, 0) +#define SPRD_DMA_WRAP_ADDR_MASK GENMASK(27, 0) #define SPRD_DMA_HIGH_ADDR_OFFSET 4 /* SPRD_DMA_CHN_INTC register definition */ @@ -118,6 +119,8 @@ #define SPRD_DMA_SWT_MODE_OFFSET 26 #define SPRD_DMA_REQ_MODE_OFFSET 24 #define SPRD_DMA_REQ_MODE_MASK GENMASK(1, 0) +#define SPRD_DMA_WRAP_SEL_DEST BIT(23) +#define SPRD_DMA_WRAP_EN BIT(22) #define SPRD_DMA_FIX_SEL_OFFSET 21 #define SPRD_DMA_FIX_EN_OFFSET 20 #define SPRD_DMA_LLIST_END BIT(19) @@ -804,6 +807,8 @@ static int sprd_dma_fill_desc(struct dma_chan *chan, temp |= req_mode << SPRD_DMA_REQ_MODE_OFFSET; temp |= fix_mode << SPRD_DMA_FIX_SEL_OFFSET; temp |= fix_en << SPRD_DMA_FIX_EN_OFFSET; + temp |= schan->linklist.wrap_addr ? + SPRD_DMA_WRAP_EN | SPRD_DMA_WRAP_SEL_DEST : 0; temp |= slave_cfg->src_maxburst & SPRD_DMA_FRG_LEN_MASK; hw->frg_len = temp; @@ -831,6 +836,12 @@ static int sprd_dma_fill_desc(struct dma_chan *chan, hw->llist_ptr = lower_32_bits(llist_ptr); hw->src_blk_step = (upper_32_bits(llist_ptr) << SPRD_DMA_LLIST_HIGH_SHIFT) & SPRD_DMA_LLIST_HIGH_MASK; + + if (schan->linklist.wrap_addr) { + hw->wrap_ptr |= schan->linklist.wrap_addr & + SPRD_DMA_WRAP_ADDR_MASK; + hw->wrap_to |= dst & SPRD_DMA_WRAP_ADDR_MASK; + } } else { hw->llist_ptr = 0; hw->src_blk_step = 0; @@ -939,9 +950,11 @@ static int sprd_dma_fill_linklist_desc(struct dma_chan *chan, schan->linklist.phy_addr = ll_cfg->phy_addr; schan->linklist.virt_addr = ll_cfg->virt_addr; + schan->linklist.wrap_addr = ll_cfg->wrap_addr; } else { schan->linklist.phy_addr = 0; schan->linklist.virt_addr = 0; + schan->linklist.wrap_addr = 0; } /* diff --git a/include/linux/dma/sprd-dma.h b/include/linux/dma/sprd-dma.h index ab82df6..d09c6f6 100644 --- a/include/linux/dma/sprd-dma.h +++ b/include/linux/dma/sprd-dma.h @@ -118,6 +118,9 @@ enum sprd_dma_int_type { * struct sprd_dma_linklist - DMA link-list address structure * @virt_addr: link-list virtual address to configure link-list node * @phy_addr: link-list physical address to link DMA transfer + * @wrap_addr: the wrap address for link-list mode, which means once the + * transfer address reaches the wrap address, the next transfer address + * will jump to the address specified by wrap_to register. * * The Spreadtrum DMA controller supports the link-list mode, that means slaves * can supply several groups configurations (each configuration represents one @@ -181,6 +184,7 @@ enum sprd_dma_int_type { struct sprd_dma_linklist { unsigned long virt_addr; phys_addr_t phy_addr; + phys_addr_t wrap_addr; }; #endif