Skip to content

Commit 3f63297

Browse files
LUO Haowenvinodkoul
authored andcommitted
dmaengine: dw-edma: Fix multiple times setting of the CYCLE_STATE and CYCLE_BIT bits for HDMA.
Others have submitted this issue (https://lore.kernel.org/dmaengine/ [email protected]/), but it has not been fixed yet. Therefore, more supplementary information is provided here. As mentioned in the "PCS-CCS-CB-TCB" Producer-Consumer Synchronization of "DesignWare Cores PCI Express Controller Databook, version 6.00a": 1. The Consumer CYCLE_STATE (CCS) bit in the register only needs to be initialized once; the value will update automatically to be ~CYCLE_BIT (CB) in the next chunk. 2. The Consumer CYCLE_BIT bit in the register is loaded from the LL element and tested against CCS. When CB = CCS, the data transfer is executed. Otherwise not. The current logic sets customer (HDMA) CS and CB bits to 1 in each chunk while setting the producer (software) CB of odd chunks to 0 and even chunks to 1 in the linked list. This is leading to a mismatch between the producer CB and consumer CS bits. This issue can be reproduced by setting the transmission data size to exceed one chunk. By the way, in the EDMA using the same "PCS-CCS-CB-TCB" mechanism, the CS bit is only initialized once and this issue was not found. Refer to drivers/dma/dw-edma/dw-edma-v0-core.c:dw_edma_v0_core_start. So fix this issue by initializing the CYCLE_STATE and CYCLE_BIT bits only once. Fixes: e74c395 ("dmaengine: dw-edma: Add support for native HDMA") Signed-off-by: LUO Haowen <[email protected]> Reviewed-by: Frank Li <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent ee66bc2 commit 3f63297

1 file changed

Lines changed: 3 additions & 3 deletions

File tree

drivers/dma/dw-edma/dw-hdma-v0-core.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,10 @@ static void dw_hdma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
252252
lower_32_bits(chunk->ll_region.paddr));
253253
SET_CH_32(dw, chan->dir, chan->id, llp.msb,
254254
upper_32_bits(chunk->ll_region.paddr));
255+
/* Set consumer cycle */
256+
SET_CH_32(dw, chan->dir, chan->id, cycle_sync,
257+
HDMA_V0_CONSUMER_CYCLE_STAT | HDMA_V0_CONSUMER_CYCLE_BIT);
255258
}
256-
/* Set consumer cycle */
257-
SET_CH_32(dw, chan->dir, chan->id, cycle_sync,
258-
HDMA_V0_CONSUMER_CYCLE_STAT | HDMA_V0_CONSUMER_CYCLE_BIT);
259259

260260
dw_hdma_v0_sync_ll_data(chunk);
261261

0 commit comments

Comments
 (0)