Hung-Te Lin has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/44851 )
Change subject: soc/mediatek/mt8192: Add SPI flash controller DMA read function ......................................................................
Patch Set 1:
(1 comment)
Changing from PIO+DMA (boot time: 879,067) to full-DMA (871,016) saved 8051us ~ 8ms. Please replace the PIO+DMA with my version (full DMA).
https://review.coreboot.org/c/coreboot/+/44851/1/src/soc/mediatek/mt8192/fla... File src/soc/mediatek/mt8192/flash_controller.c:
https://review.coreboot.org/c/coreboot/+/44851/1/src/soc/mediatek/mt8192/fla... PS1, Line 142: size_t done = 0; : uintptr_t dma_buf = (uintptr_t)_dma_coherent; : size_t dma_buf_len = REGION_SIZE(dma_coherent); : u32 next; : : if (!IS_ALIGNED((uintptr_t)addr, SFLASH_DMA_ALIGN)) { : next = MIN(ALIGN_UP((uintptr_t)addr, SFLASH_DMA_ALIGN) - : (uintptr_t)addr, len); : if (pio_read(addr, buf, next)) : return -1; : done += next; : } : : while (len - done >= SFLASH_DMA_ALIGN) { : next = MIN(dma_buf_len, ALIGN_DOWN(len - done, : SFLASH_DMA_ALIGN)); : if (dma_read(addr + done, buf + done, next, dma_buf, : dma_buf_len)) : return -1; : done += next; : } : next = len - done; : if (next > 0 && pio_read(addr + done, buf + done, next)) : return -1;
can we replace this by purely DMA calls, eg: […]
I tested and this works well:
static int nor_read(const struct spi_flash *flash, u32 addr, size_t len, void *buf) { uintptr_t dma_buf = (uintptr_t)_dma_coherent; size_t dma_buf_len = REGION_SIZE(dma_coherent);
setbits8(&mt8192_nor->read_dual, SFLASH_READ_DUAL_EN); write8(&mt8192_nor->prgdata[3], SFLASH_1_1_2_READ);
u32 start = ALIGN_DOWN(addr, SFLASH_DMA_ALIGN); u32 skip = addr - start; u32 total = ALIGN_UP(skip + len, SFLASH_DMA_ALIGN); u32 drop = total - skip - len; u32 done, read_len, copy_len; uint8_t *dest = (uint8_t *)buf;
/* DMA: start [ skip | len | drop ]=total end */ for (done = 0; done < total; dest += copy_len) { read_len = MIN(dma_buf_len, total - done); if (dma_read(start + done, dma_buf, read_len, dma_buf_len)) return -1;
done += read_len;
// decide the range to copy into buffer if (done == total) read_len -= drop; /* Only drop in last iteration */
copy_len = read_len - skip; memcpy(dest, (uint8_t *)dma_buf + skip, copy_len);
if (skip) skip = 0; /* Only apply skip in first iteration. */ }
return 0; }