Skip to content
Merged
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
35 changes: 28 additions & 7 deletions drivers/dma/dma-axi-dmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@
#define AXI_DMAC_REG_START_TRANSFER 0x408
#define AXI_DMAC_REG_FLAGS 0x40c
#define AXI_DMAC_REG_DEST_ADDRESS 0x410
#define AXI_DMAC_REG_DEST_ADDRESS_HIGH 0x490
#define AXI_DMAC_REG_SRC_ADDRESS 0x414
#define AXI_DMAC_REG_SRC_ADDRESS_HIGH 0x494
#define AXI_DMAC_REG_X_LENGTH 0x418
#define AXI_DMAC_REG_Y_LENGTH 0x41c
#define AXI_DMAC_REG_DEST_STRIDE 0x420
Expand Down Expand Up @@ -236,11 +238,9 @@
unsigned int flags = 0;
unsigned int val;

if (!chan->hw_sg) {
val = axi_dmac_read(dmac, AXI_DMAC_REG_START_TRANSFER);
if (val) /* Queue is full, wait for the next SOT IRQ */
return;
}
val = axi_dmac_read(dmac, AXI_DMAC_REG_START_TRANSFER);
if (val) /* Queue is full, wait for the next SOT IRQ */
return;

desc = chan->next_desc;

Expand All @@ -250,6 +250,7 @@
return;
list_move_tail(&vdesc->node, &chan->active_descs);
desc = to_axi_dmac_desc(vdesc);
chan->next_desc = desc;
}
sg = &desc->sg[desc->num_submitted];

Expand All @@ -268,20 +269,21 @@
else
chan->next_desc = NULL;
flags |= AXI_DMAC_FLAG_LAST;
} else {
chan->next_desc = desc;
}

sg->hw->id = axi_dmac_read(dmac, AXI_DMAC_REG_TRANSFER_ID);

if (!chan->hw_sg) {
if (axi_dmac_dest_is_mem(chan)) {
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, sg->hw->dest_addr);
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS_HIGH,
sg->hw->dest_addr >> 32);
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, sg->hw->dst_stride);
}

if (axi_dmac_src_is_mem(chan)) {
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, sg->hw->src_addr);
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS_HIGH, sg->hw->src_addr >> 32);
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, sg->hw->src_stride);
}
}
Expand Down Expand Up @@ -827,7 +829,7 @@
desc->sg[0].hw->y_len = 0;
}

if (flags & DMA_CYCLIC)

Check warning on line 832 in drivers/dma/dma-axi-dmac.c

View workflow job for this annotation

GitHub Actions / build_gcc_arm / build

kernel_smatch: bit shifter 'DMA_CYCLIC' used for logical '&'
desc->cyclic = true;

return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
Expand Down Expand Up @@ -1019,6 +1021,9 @@
static int axi_dmac_detect_caps(struct axi_dmac *dmac, unsigned int version)
{
struct axi_dmac_chan *chan = &dmac->chan;
struct device *dev = dmac->dma_dev.dev;
u32 mask;
int ret;

axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, AXI_DMAC_FLAG_CYCLIC);
if (axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS) == AXI_DMAC_FLAG_CYCLIC)
Expand Down Expand Up @@ -1053,6 +1058,22 @@
return -ENODEV;
}

if (axi_dmac_dest_is_mem(chan)) {
axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS_HIGH, 0xffffffff);
mask = axi_dmac_read(dmac, AXI_DMAC_REG_DEST_ADDRESS_HIGH);
} else {
axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS_HIGH, 0xffffffff);
mask = axi_dmac_read(dmac, AXI_DMAC_REG_SRC_ADDRESS_HIGH);
}

mask = 32 + fls(mask);

ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(mask));
if (ret) {
dev_err(dev, "DMA mask set error %d\n", ret);
return ret;
}

if (version >= ADI_AXI_PCORE_VER(4, 2, 'a'))
chan->hw_partial_xfer = true;

Expand Down
Loading