Commit 5faf23ec authored by Karen Xie's avatar Karen Xie

XDMA: increase nxt_adj to 0x3F (max. allowed) and fixed nxt_adj setting when...

XDMA: increase nxt_adj to 0x3F (max. allowed) and fixed nxt_adj setting when last descriptor does not fall on the page boundary
parent 7500f76f
......@@ -549,14 +549,13 @@ static int xdma_engine_stop(struct xdma_engine *engine)
} else {
w |= (u32)XDMA_CTRL_IE_DESC_STOPPED;
w |= (u32)XDMA_CTRL_IE_DESC_COMPLETED;
}
dbg_tfr("Stopping SG DMA %s engine; writing 0x%08x to 0x%p.\n",
engine->name, w, (u32 *)&engine->regs->control);
write_register(w, &engine->regs->control,
(unsigned long)(&engine->regs->control) -
(unsigned long)(&engine->regs));
(unsigned long)(&engine->regs->control) -
(unsigned long)(&engine->regs));
/* dummy read of status register to flush all previous writes */
dbg_tfr("%s(%s) done\n", __func__, engine->name);
return 0;
......@@ -2438,9 +2437,6 @@ static int transfer_desc_init(struct xdma_transfer *transfer, int count)
struct xdma_desc *desc_virt = transfer->desc_virt;
dma_addr_t desc_bus = transfer->desc_bus;
int i;
int adj = count - 1;
int extra_adj;
u32 temp_control;
if (count > XDMA_TRANSFER_MAX_DESC) {
pr_err("Engine cannot transfer more than %d descriptors\n",
......@@ -2457,31 +2453,14 @@ static int transfer_desc_init(struct xdma_transfer *transfer, int count)
desc_virt[i].next_lo = cpu_to_le32(PCI_DMA_L(desc_bus));
desc_virt[i].next_hi = cpu_to_le32(PCI_DMA_H(desc_bus));
desc_virt[i].bytes = cpu_to_le32(0);
/* any adjacent descriptors? */
if (adj > 0) {
extra_adj = adj - 1;
if (extra_adj > MAX_EXTRA_ADJ)
extra_adj = MAX_EXTRA_ADJ;
adj--;
} else {
extra_adj = 0;
}
temp_control = DESC_MAGIC | (extra_adj << 8);
desc_virt[i].control = cpu_to_le32(temp_control);
desc_virt[i].control = cpu_to_le32(DESC_MAGIC);
}
/* { i = number - 1 } */
/* zero the last descriptor next pointer */
desc_virt[i].next_lo = cpu_to_le32(0);
desc_virt[i].next_hi = cpu_to_le32(0);
desc_virt[i].bytes = cpu_to_le32(0);
temp_control = DESC_MAGIC;
desc_virt[i].control = cpu_to_le32(temp_control);
desc_virt[i].control = cpu_to_le32(DESC_MAGIC);
return 0;
}
......@@ -2528,27 +2507,14 @@ static void xdma_desc_link(struct xdma_desc *first, struct xdma_desc *second,
/* xdma_desc_adjacent -- Set how many descriptors are adjacent to this one */
static void xdma_desc_adjacent(struct xdma_desc *desc, int next_adjacent)
{
int extra_adj = 0;
/* remember reserved and control bits */
u32 control = le32_to_cpu(desc->control) & 0x0000f0ffUL;
u32 max_adj_4k = 0;
u32 control = le32_to_cpu(desc->control) & 0xffffc0ffUL;
if (next_adjacent > 0) {
extra_adj = next_adjacent - 1;
if (extra_adj > MAX_EXTRA_ADJ)
extra_adj = MAX_EXTRA_ADJ;
max_adj_4k =
(0x1000 - ((le32_to_cpu(desc->next_lo)) & 0xFFF)) / 32 -
1;
if (extra_adj > max_adj_4k)
extra_adj = max_adj_4k;
if (extra_adj < 0) {
pr_warn("extra_adj<0, converting it to 0\n");
extra_adj = 0;
}
}
/* merge adjacent and control field */
control |= 0xAD4B0000UL | (extra_adj << 8);
if (next_adjacent)
next_adjacent = next_adjacent - 1;
if (next_adjacent > MAX_EXTRA_ADJ)
next_adjacent = MAX_EXTRA_ADJ;
control |= (next_adjacent << 8);
/* write control and next_adjacent */
desc->control = cpu_to_le32(control);
}
......@@ -3226,14 +3192,12 @@ static int transfer_init(struct xdma_engine *engine, struct xdma_request_cb *req
dbg_sg("xfer= %p transfer->desc_bus = 0x%llx.\n",xfer, (u64)xfer->desc_bus);
transfer_build(engine, req, xfer , desc_max);
/* Contiguous descriptors cannot cross PAGE boundry. Adjust max accordingly */
desc_align = engine->desc_idx + desc_max - 1;
desc_align = desc_align % 128;
if (desc_align < (desc_max - 1)) {
desc_align = desc_max - desc_align - 1;
}
else
desc_align = desc_max;
/* Contiguous descriptors cannot cross PAGE boundry
* The 1st descriptor may start in the middle of the page,
* calculate the 1st block of adj desc accordingly */
desc_align = 128 - (engine->desc_idx % 128) - 1;
if (desc_align > (desc_max - 1))
desc_align = desc_max - 1;
xfer->desc_adjacent = desc_align;
......@@ -3250,7 +3214,10 @@ static int transfer_init(struct xdma_engine *engine, struct xdma_request_cb *req
engine->desc_used += desc_max ;
/* fill in adjacent numbers */
for (i = 0; i < xfer->desc_num; i++)
for (i = 0; i < xfer->desc_num && desc_align; i++, desc_align--)
xdma_desc_adjacent(xfer->desc_virt + i, desc_align);
for (; i < xfer->desc_num; i++)
xdma_desc_adjacent(xfer->desc_virt + i, xfer->desc_num - i - 1);
spin_unlock_irqrestore(&engine->lock, flags);
......
......@@ -58,7 +58,7 @@
* .REG_IRQ_OUT (reg_irq_from_ch[(channel*2) +: 2]),
*/
#define XDMA_ENG_IRQ_NUM (1)
#define MAX_EXTRA_ADJ (15)
#define MAX_EXTRA_ADJ 0x3F
#define RX_STATUS_EOP (1)
/* Target internal components on XDMA control BAR */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment