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

drm/tegra: falcon: Pipeline firmware copy

The Falcon DMA engine allows queueing multiple operations for
improved performance. Do this to optimize firmware loading.
A performance improvement of 4x to 6x is observed.

Co-developed-by: Ivan Raul Guadarrama <iguadarrama@nvidia.com>
Signed-off-by: Ivan Raul Guadarrama <iguadarrama@nvidia.com>
Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Link: https://lore.kernel.org/r/20250205061027.1205748-1-mperttunen@nvidia.com

authored by

Mikko Perttunen and committed by
Thierry Reding
408ec8e4 61a85887

+20 -1
+19 -1
drivers/gpu/drm/tegra/falcon.c
··· 30 30 (value == 0), 10, 100000); 31 31 } 32 32 33 + static int falcon_dma_wait_not_full(struct falcon *falcon) 34 + { 35 + u32 value; 36 + 37 + return readl_poll_timeout(falcon->regs + FALCON_DMATRFCMD, value, 38 + !(value & FALCON_DMATRFCMD_FULL), 10, 100000); 39 + } 40 + 33 41 static int falcon_dma_wait_idle(struct falcon *falcon) 34 42 { 35 43 u32 value; ··· 52 44 enum falcon_memory target) 53 45 { 54 46 u32 cmd = FALCON_DMATRFCMD_SIZE_256B; 47 + int err; 55 48 56 49 if (target == FALCON_MEMORY_IMEM) 57 50 cmd |= FALCON_DMATRFCMD_IMEM; ··· 65 56 */ 66 57 cmd |= FALCON_DMATRFCMD_DMACTX(1); 67 58 59 + err = falcon_dma_wait_not_full(falcon); 60 + if (err < 0) 61 + return err; 62 + 68 63 falcon_writel(falcon, offset, FALCON_DMATRFMOFFS); 69 64 falcon_writel(falcon, base, FALCON_DMATRFFBOFFS); 70 65 falcon_writel(falcon, cmd, FALCON_DMATRFCMD); 71 66 72 - return falcon_dma_wait_idle(falcon); 67 + return 0; 73 68 } 74 69 75 70 static void falcon_copy_firmware_image(struct falcon *falcon, ··· 203 190 for (offset = 0; offset < falcon->firmware.code.size; offset += 256) 204 191 falcon_copy_chunk(falcon, falcon->firmware.code.offset + offset, 205 192 offset, FALCON_MEMORY_IMEM); 193 + 194 + /* wait for DMA to complete */ 195 + err = falcon_dma_wait_idle(falcon); 196 + if (err < 0) 197 + return err; 206 198 207 199 /* setup falcon interrupts */ 208 200 falcon_writel(falcon, FALCON_IRQMSET_EXT(0xff) |
+1
drivers/gpu/drm/tegra/falcon.h
··· 47 47 #define FALCON_DMATRFMOFFS 0x00001114 48 48 49 49 #define FALCON_DMATRFCMD 0x00001118 50 + #define FALCON_DMATRFCMD_FULL (1 << 0) 50 51 #define FALCON_DMATRFCMD_IDLE (1 << 1) 51 52 #define FALCON_DMATRFCMD_IMEM (1 << 4) 52 53 #define FALCON_DMATRFCMD_SIZE_256B (6 << 8)