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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'fixes' of git://git.infradead.org/users/vkoul/slave-dma

Pull dmaengine fixes from Vinod Koul:
"We have couple of fixes for dmaengine queued up:
- dma mempcy fix for dma configuration of sun6i by Maxime
- pl330 fixes: First the fixing allocation for data buffers by Liviu
and then Jon's fixe for fifo width and usage"

* 'fixes' of git://git.infradead.org/users/vkoul/slave-dma:
dmaengine: Fix allocation size for PL330 data buffer depth.
dmaengine: pl330: Limit MFIFO usage for memcpy to avoid exhausting entries
dmaengine: pl330: Align DMA memcpy operations to MFIFO width
dmaengine: sun6i: Fix memcpy operation

+46 -38
+16 -7
drivers/dma/pl330.c
··· 271 271 #define DMAC_MODE_NS (1 << 0) 272 272 unsigned int mode; 273 273 unsigned int data_bus_width:10; /* In number of bits */ 274 - unsigned int data_buf_dep:10; 274 + unsigned int data_buf_dep:11; 275 275 unsigned int num_chan:4; 276 276 unsigned int num_peri:6; 277 277 u32 peri_ns; ··· 2336 2336 int burst_len; 2337 2337 2338 2338 burst_len = pl330->pcfg.data_bus_width / 8; 2339 - burst_len *= pl330->pcfg.data_buf_dep; 2339 + burst_len *= pl330->pcfg.data_buf_dep / pl330->pcfg.num_chan; 2340 2340 burst_len >>= desc->rqcfg.brst_size; 2341 2341 2342 2342 /* src/dst_burst_len can't be more than 16 */ ··· 2459 2459 /* Select max possible burst size */ 2460 2460 burst = pl330->pcfg.data_bus_width / 8; 2461 2461 2462 - while (burst > 1) { 2463 - if (!(len % burst)) 2464 - break; 2462 + /* 2463 + * Make sure we use a burst size that aligns with all the memcpy 2464 + * parameters because our DMA programming algorithm doesn't cope with 2465 + * transfers which straddle an entry in the DMA device's MFIFO. 2466 + */ 2467 + while ((src | dst | len) & (burst - 1)) 2465 2468 burst /= 2; 2466 - } 2467 2469 2468 2470 desc->rqcfg.brst_size = 0; 2469 2471 while (burst != (1 << desc->rqcfg.brst_size)) 2470 2472 desc->rqcfg.brst_size++; 2473 + 2474 + /* 2475 + * If burst size is smaller than bus width then make sure we only 2476 + * transfer one at a time to avoid a burst stradling an MFIFO entry. 2477 + */ 2478 + if (desc->rqcfg.brst_size * 8 < pl330->pcfg.data_bus_width) 2479 + desc->rqcfg.brst_len = 1; 2471 2480 2472 2481 desc->rqcfg.brst_len = get_burst_len(desc, len); 2473 2482 ··· 2741 2732 2742 2733 2743 2734 dev_info(&adev->dev, 2744 - "Loaded driver for PL330 DMAC-%d\n", adev->periphid); 2735 + "Loaded driver for PL330 DMAC-%x\n", adev->periphid); 2745 2736 dev_info(&adev->dev, 2746 2737 "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n", 2747 2738 pcfg->data_buf_dep, pcfg->data_bus_width / 8, pcfg->num_chan,
+30 -31
drivers/dma/sun6i-dma.c
··· 230 230 readl(pchan->base + DMA_CHAN_CUR_PARA)); 231 231 } 232 232 233 - static inline int convert_burst(u32 maxburst, u8 *burst) 233 + static inline s8 convert_burst(u32 maxburst) 234 234 { 235 235 switch (maxburst) { 236 236 case 1: 237 - *burst = 0; 238 - break; 237 + return 0; 239 238 case 8: 240 - *burst = 2; 241 - break; 239 + return 2; 242 240 default: 243 241 return -EINVAL; 244 242 } 245 - 246 - return 0; 247 243 } 248 244 249 - static inline int convert_buswidth(enum dma_slave_buswidth addr_width, u8 *width) 245 + static inline s8 convert_buswidth(enum dma_slave_buswidth addr_width) 250 246 { 251 247 if ((addr_width < DMA_SLAVE_BUSWIDTH_1_BYTE) || 252 248 (addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES)) 253 249 return -EINVAL; 254 250 255 - *width = addr_width >> 1; 256 - return 0; 251 + return addr_width >> 1; 257 252 } 258 253 259 254 static void *sun6i_dma_lli_add(struct sun6i_dma_lli *prev, ··· 279 284 struct dma_slave_config *config) 280 285 { 281 286 u8 src_width, dst_width, src_burst, dst_burst; 282 - int ret; 283 287 284 288 if (!config) 285 289 return -EINVAL; 286 290 287 - ret = convert_burst(config->src_maxburst, &src_burst); 288 - if (ret) 289 - return ret; 291 + src_burst = convert_burst(config->src_maxburst); 292 + if (src_burst) 293 + return src_burst; 290 294 291 - ret = convert_burst(config->dst_maxburst, &dst_burst); 292 - if (ret) 293 - return ret; 295 + dst_burst = convert_burst(config->dst_maxburst); 296 + if (dst_burst) 297 + return dst_burst; 294 298 295 - ret = convert_buswidth(config->src_addr_width, &src_width); 296 - if (ret) 297 - return ret; 299 + src_width = convert_buswidth(config->src_addr_width); 300 + if (src_width) 301 + return src_width; 298 302 299 - ret = convert_buswidth(config->dst_addr_width, &dst_width); 300 - if (ret) 301 - return ret; 303 + dst_width = convert_buswidth(config->dst_addr_width); 304 + if (dst_width) 305 + return dst_width; 302 306 303 307 lli->cfg = DMA_CHAN_CFG_SRC_BURST(src_burst) | 304 308 DMA_CHAN_CFG_SRC_WIDTH(src_width) | ··· 536 542 { 537 543 struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(chan->device); 538 544 struct sun6i_vchan *vchan = to_sun6i_vchan(chan); 539 - struct dma_slave_config *sconfig = &vchan->cfg; 540 545 struct sun6i_dma_lli *v_lli; 541 546 struct sun6i_desc *txd; 542 547 dma_addr_t p_lli; 543 - int ret; 548 + s8 burst, width; 544 549 545 550 dev_dbg(chan2dev(chan), 546 551 "%s; chan: %d, dest: %pad, src: %pad, len: %zu. flags: 0x%08lx\n", ··· 558 565 goto err_txd_free; 559 566 } 560 567 561 - ret = sun6i_dma_cfg_lli(v_lli, src, dest, len, sconfig); 562 - if (ret) 563 - goto err_dma_free; 568 + v_lli->src = src; 569 + v_lli->dst = dest; 570 + v_lli->len = len; 571 + v_lli->para = NORMAL_WAIT; 564 572 573 + burst = convert_burst(8); 574 + width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES); 565 575 v_lli->cfg |= DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | 566 576 DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | 567 577 DMA_CHAN_CFG_DST_LINEAR_MODE | 568 - DMA_CHAN_CFG_SRC_LINEAR_MODE; 578 + DMA_CHAN_CFG_SRC_LINEAR_MODE | 579 + DMA_CHAN_CFG_SRC_BURST(burst) | 580 + DMA_CHAN_CFG_SRC_WIDTH(width) | 581 + DMA_CHAN_CFG_DST_BURST(burst) | 582 + DMA_CHAN_CFG_DST_WIDTH(width); 569 583 570 584 sun6i_dma_lli_add(NULL, v_lli, p_lli, txd); 571 585 ··· 580 580 581 581 return vchan_tx_prep(&vchan->vc, &txd->vd, flags); 582 582 583 - err_dma_free: 584 - dma_pool_free(sdev->pool, v_lli, p_lli); 585 583 err_txd_free: 586 584 kfree(txd); 587 585 return NULL; ··· 913 915 sdc->slave.device_prep_dma_memcpy = sun6i_dma_prep_dma_memcpy; 914 916 sdc->slave.device_control = sun6i_dma_control; 915 917 sdc->slave.chancnt = NR_MAX_VCHANS; 918 + sdc->slave.copy_align = 4; 916 919 917 920 sdc->slave.dev = &pdev->dev; 918 921