Commit 408ec8e4 authored by Mikko Perttunen's avatar Mikko Perttunen Committed by Thierry Reding
Browse files

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: default avatarIvan Raul Guadarrama <iguadarrama@nvidia.com>
Signed-off-by: default avatarIvan Raul Guadarrama <iguadarrama@nvidia.com>
Signed-off-by: default avatarMikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
Link: https://lore.kernel.org/r/20250205061027.1205748-1-mperttunen@nvidia.com
parent 61a85887
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -30,6 +30,14 @@ int falcon_wait_idle(struct falcon *falcon)
				  (value == 0), 10, 100000);
}

static int falcon_dma_wait_not_full(struct falcon *falcon)
{
	u32 value;

	return readl_poll_timeout(falcon->regs + FALCON_DMATRFCMD, value,
				  !(value & FALCON_DMATRFCMD_FULL), 10, 100000);
}

static int falcon_dma_wait_idle(struct falcon *falcon)
{
	u32 value;
@@ -44,6 +52,7 @@ static int falcon_copy_chunk(struct falcon *falcon,
			     enum falcon_memory target)
{
	u32 cmd = FALCON_DMATRFCMD_SIZE_256B;
	int err;

	if (target == FALCON_MEMORY_IMEM)
		cmd |= FALCON_DMATRFCMD_IMEM;
@@ -56,11 +65,15 @@ static int falcon_copy_chunk(struct falcon *falcon,
	 */
	cmd |= FALCON_DMATRFCMD_DMACTX(1);

	err = falcon_dma_wait_not_full(falcon);
	if (err < 0)
		return err;

	falcon_writel(falcon, offset, FALCON_DMATRFMOFFS);
	falcon_writel(falcon, base, FALCON_DMATRFFBOFFS);
	falcon_writel(falcon, cmd, FALCON_DMATRFCMD);

	return falcon_dma_wait_idle(falcon);
	return 0;
}

static void falcon_copy_firmware_image(struct falcon *falcon,
@@ -191,6 +204,11 @@ int falcon_boot(struct falcon *falcon)
		falcon_copy_chunk(falcon, falcon->firmware.code.offset + offset,
				  offset, FALCON_MEMORY_IMEM);

	/* wait for DMA to complete */
	err = falcon_dma_wait_idle(falcon);
	if (err < 0)
		return err;

	/* setup falcon interrupts */
	falcon_writel(falcon, FALCON_IRQMSET_EXT(0xff) |
			      FALCON_IRQMSET_SWGEN1 |
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@
#define FALCON_DMATRFMOFFS			0x00001114

#define FALCON_DMATRFCMD			0x00001118
#define FALCON_DMATRFCMD_FULL			(1 << 0)
#define FALCON_DMATRFCMD_IDLE			(1 << 1)
#define FALCON_DMATRFCMD_IMEM			(1 << 4)
#define FALCON_DMATRFCMD_SIZE_256B		(6 << 8)