Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

raised ZYNQMP_DMA_NUM_DESCS from 32 to 10000 and replace spin_lock_bh with spin_lock_irqsave #1

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 24 additions & 17 deletions drivers/dma/xilinx/zynqmp_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
ZYNQMP_DMA_DST_DSCR_DONE)

/* Max number of descriptors per channel */
#define ZYNQMP_DMA_NUM_DESCS 32
#define ZYNQMP_DMA_NUM_DESCS 10000

/* Max transfer size per descriptor */
#define ZYNQMP_DMA_MAX_TRANS_LEN 0x40000000
Expand Down Expand Up @@ -375,9 +375,10 @@ static dma_cookie_t zynqmp_dma_tx_submit(struct dma_async_tx_descriptor *tx)
struct zynqmp_dma_chan *chan = to_chan(tx->chan);
struct zynqmp_dma_desc_sw *desc, *new;
dma_cookie_t cookie;
unsigned long irqflags;

new = tx_to_desc(tx);
spin_lock_bh(&chan->lock);
spin_lock_irqsave(&chan->lock, irqflags);
cookie = dma_cookie_assign(tx);

if (!list_empty(&chan->pending_list)) {
Expand All @@ -393,7 +394,7 @@ static dma_cookie_t zynqmp_dma_tx_submit(struct dma_async_tx_descriptor *tx)
}

list_add_tail(&new->node, &chan->pending_list);
spin_unlock_bh(&chan->lock);
spin_unlock_irqrestore(&chan->lock, irqflags);

return cookie;
}
Expand All @@ -408,12 +409,13 @@ static struct zynqmp_dma_desc_sw *
zynqmp_dma_get_descriptor(struct zynqmp_dma_chan *chan)
{
struct zynqmp_dma_desc_sw *desc;
unsigned long irqflags;

spin_lock_bh(&chan->lock);
spin_lock_irqsave(&chan->lock, irqflags);
desc = list_first_entry(&chan->free_list,
struct zynqmp_dma_desc_sw, node);
list_del(&desc->node);
spin_unlock_bh(&chan->lock);
spin_unlock_irqrestore(&chan->lock, irqflags);

INIT_LIST_HEAD(&desc->tx_list);
/* Clear the src and dst descriptor memory */
Expand Down Expand Up @@ -643,10 +645,11 @@ static void zynqmp_dma_complete_descriptor(struct zynqmp_dma_chan *chan)
static void zynqmp_dma_issue_pending(struct dma_chan *dchan)
{
struct zynqmp_dma_chan *chan = to_chan(dchan);
unsigned long irqflags;

spin_lock_bh(&chan->lock);
spin_lock_irqsave(&chan->lock, irqflags);
zynqmp_dma_start_transfer(chan);
spin_unlock_bh(&chan->lock);
spin_unlock_irqrestore(&chan->lock, irqflags);
}

/**
Expand All @@ -667,10 +670,11 @@ static void zynqmp_dma_free_descriptors(struct zynqmp_dma_chan *chan)
static void zynqmp_dma_free_chan_resources(struct dma_chan *dchan)
{
struct zynqmp_dma_chan *chan = to_chan(dchan);
unsigned long irqflags;

spin_lock_bh(&chan->lock);
spin_lock_irqsave(&chan->lock, irqflags);
zynqmp_dma_free_descriptors(chan);
spin_unlock_bh(&chan->lock);
spin_unlock_irqrestore(&chan->lock, irqflags);
dma_free_coherent(chan->dev,
(2 * ZYNQMP_DMA_DESC_SIZE(chan) * ZYNQMP_DMA_NUM_DESCS),
chan->desc_pool_v, chan->desc_pool_p);
Expand Down Expand Up @@ -776,11 +780,12 @@ static void zynqmp_dma_do_tasklet(unsigned long data)
static int zynqmp_dma_device_terminate_all(struct dma_chan *dchan)
{
struct zynqmp_dma_chan *chan = to_chan(dchan);
unsigned long irqflags;

spin_lock_bh(&chan->lock);
spin_lock_irqsave(&chan->lock, irqflags);
writel(ZYNQMP_DMA_IDS_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IDS);
zynqmp_dma_free_descriptors(chan);
spin_unlock_bh(&chan->lock);
spin_unlock_irqrestore(&chan->lock, irqflags);

return 0;
}
Expand All @@ -804,19 +809,20 @@ static struct dma_async_tx_descriptor *zynqmp_dma_prep_memcpy(
void *desc = NULL, *prev = NULL;
size_t copy;
u32 desc_cnt;
unsigned long irqflags;

chan = to_chan(dchan);

desc_cnt = DIV_ROUND_UP(len, ZYNQMP_DMA_MAX_TRANS_LEN);

spin_lock_bh(&chan->lock);
spin_lock_irqsave(&chan->lock, irqflags);
if (desc_cnt > chan->desc_free_cnt) {
spin_unlock_bh(&chan->lock);
spin_unlock_irqrestore(&chan->lock, irqflags);
dev_dbg(chan->dev, "chan %p descs are not available\n", chan);
return NULL;
}
chan->desc_free_cnt = chan->desc_free_cnt - desc_cnt;
spin_unlock_bh(&chan->lock);
spin_unlock_irqrestore(&chan->lock, irqflags);

do {
/* Allocate and populate the descriptor */
Expand Down Expand Up @@ -865,19 +871,20 @@ static struct dma_async_tx_descriptor *zynqmp_dma_prep_sg(
dma_addr_t dma_dst, dma_src;
u32 desc_cnt = 0, i;
struct scatterlist *sg;
unsigned long irqflags;

for_each_sg(src_sg, sg, src_sg_len, i)
desc_cnt += DIV_ROUND_UP(sg_dma_len(sg),
ZYNQMP_DMA_MAX_TRANS_LEN);

spin_lock_bh(&chan->lock);
spin_lock_irqsave(&chan->lock, irqflags);
if (desc_cnt > chan->desc_free_cnt) {
spin_unlock_bh(&chan->lock);
spin_unlock_irqrestore(&chan->lock, irqflags);
dev_dbg(chan->dev, "chan %p descs are not available\n", chan);
return NULL;
}
chan->desc_free_cnt = chan->desc_free_cnt - desc_cnt;
spin_unlock_bh(&chan->lock);
spin_unlock_irqrestore(&chan->lock, irqflags);

dst_avail = sg_dma_len(dst_sg);
src_avail = sg_dma_len(src_sg);
Expand Down