Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dmaengine: dw: Take HC_LLP flag into account for noLLP auto-config

Full multi-block transfers functionality is enabled in DW DMA
controller only if CHx_MULTI_BLK_EN is set. But LLP-based transfers
can be executed only if hardcode channel x LLP register feature isn't
enabled, which can be switched on at the IP core synthesis for
optimization. If it's enabled then the LLP register is hardcoded to
zero, so the blocks chaining based on the LLPs is unsupported.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20200723005848.31907-7-Sergey.Semin@baikalelectronics.ru
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Serge Semin and committed by
Vinod Koul
ef3e515a 3b6d694e

+11 -1
+10 -1
drivers/dma/dw/core.c
··· 1178 1178 */ 1179 1179 dwc->block_size = 1180 1180 (4 << ((pdata->block_size >> 4 * i) & 0xf)) - 1; 1181 + 1182 + /* 1183 + * According to the DW DMA databook the true scatter- 1184 + * gether LLPs aren't available if either multi-block 1185 + * config is disabled (CHx_MULTI_BLK_EN == 0) or the 1186 + * LLP register is hard-coded to zeros 1187 + * (CHx_HC_LLP == 1). 1188 + */ 1181 1189 dwc->nollp = 1182 - (dwc_params >> DWC_PARAMS_MBLK_EN & 0x1) == 0; 1190 + (dwc_params >> DWC_PARAMS_MBLK_EN & 0x1) == 0 || 1191 + (dwc_params >> DWC_PARAMS_HC_LLP & 0x1) == 1; 1183 1192 } else { 1184 1193 dwc->block_size = pdata->block_size; 1185 1194 dwc->nollp = !pdata->multi_block[i];
+1
drivers/dma/dw/regs.h
··· 125 125 126 126 /* Bitfields in DWC_PARAMS */ 127 127 #define DWC_PARAMS_MBLK_EN 11 /* multi block transfer */ 128 + #define DWC_PARAMS_HC_LLP 13 /* set LLP register to zero */ 128 129 129 130 /* bursts size */ 130 131 enum dw_dma_msize {