From 24e0abb5017cb6c90d7dbd905e0c249ffca5031e Mon Sep 17 00:00:00 2001 From: Joseph Burt Date: Tue, 1 Dec 2020 19:37:01 +0000 Subject: [PATCH 1/2] ipc: Fix page table size calculation This was too small, causing the ptable to be truncated and the ptable DMA transfer to fail on BDW for small buffers, where the minimum transfer is 4 bytes. Signed-off-by: Joseph Burt --- src/ipc/ipc-host-ptable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipc/ipc-host-ptable.c b/src/ipc/ipc-host-ptable.c index 80ab92417341..5eb6818fa8e8 100644 --- a/src/ipc/ipc-host-ptable.c +++ b/src/ipc/ipc-host-ptable.c @@ -110,7 +110,7 @@ static int ipc_get_page_descriptors(struct dma *dmac, uint8_t *page_table, /* source buffer size is always PAGE_SIZE bytes */ /* 20 bits for each page, round up to 32 */ - elem.size = (ring->pages * 5 * 16 + 31) / 32; + elem.size = 4 * ((ring->pages * 20 + 31) / 32); config.elem_array.elems = &elem; config.elem_array.count = 1; From 8c4b5a4b59d64029ebf0b0896d9788cb9b48f849 Mon Sep 17 00:00:00 2001 From: Joseph Burt Date: Tue, 1 Dec 2020 20:12:49 +0000 Subject: [PATCH 2/2] ipc: Use DMA attribute for min. ptable copy size This rounds up the page table DMA transfer size to DMA_ATTR_COPY_ALIGNMENT instead of a hard-coded 4 bytes. Signed-off-by: Joseph Burt --- src/ipc/ipc-host-ptable.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ipc/ipc-host-ptable.c b/src/ipc/ipc-host-ptable.c index 5eb6818fa8e8..b2bcc3fc138c 100644 --- a/src/ipc/ipc-host-ptable.c +++ b/src/ipc/ipc-host-ptable.c @@ -87,6 +87,7 @@ static int ipc_get_page_descriptors(struct dma *dmac, uint8_t *page_table, struct dma_sg_config config; struct dma_sg_elem elem; struct dma_chan_data *chan; + uint32_t dma_copy_align; int ret = 0; /* get DMA channel from DMAC */ @@ -109,8 +110,14 @@ static int ipc_get_page_descriptors(struct dma *dmac, uint8_t *page_table, elem.src = ring->phy_addr; /* source buffer size is always PAGE_SIZE bytes */ - /* 20 bits for each page, round up to 32 */ - elem.size = 4 * ((ring->pages * 20 + 31) / 32); + /* 20 bits for each page, round up to minimum DMA copy size */ + ret = dma_get_attribute(dmac, DMA_ATTR_COPY_ALIGNMENT, &dma_copy_align); + if (ret < 0) { + tr_err(&ipc_tr, "ipc_get_page_descriptors(): dma_get_attribute() failed"); + goto out; + } + elem.size = (ring->pages * 20 + 7) / 8; + elem.size = ALIGN_UP(elem.size, dma_copy_align); config.elem_array.elems = &elem; config.elem_array.count = 1;