Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 86453e34 authored by Jordan Crouse's avatar Jordan Crouse Committed by Jeremy Gebben
Browse files

msm: kgsl: Suport microcode jumptables and bootstrap for A420



Add the bits and pieces to support fast jumptables and microcode
bootstrap for the A420 target.

Change-Id: Ic0dedbadcd5bff3f691d02ae6a281832a2a3e664
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: default avatarVladimir Razgulin <vrazguli@codeaurora.org>
parent c0df4dc2
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -199,5 +199,12 @@ static const struct adreno_gpulist {
		.gmem_size = (SZ_1M + SZ_512K),
		.sync_lock_pm4_ver = NO_VER,
		.sync_lock_pfp_ver = NO_VER,
		.pm4_jt_idx = 0x901,
		.pm4_jt_addr = 0x300,
		.pfp_jt_idx = 0x401,
		.pfp_jt_addr = 0x400,
		.pm4_bstrp_size = 0x06,
		.pfp_bstrp_size = 0x28,
		.pfp_bstrp_ver = 0x4ff091,
	},
};
+59 −11
Original line number Diff line number Diff line
@@ -324,17 +324,27 @@ static int _ringbuffer_bootstrap_ucode(struct adreno_ringbuffer *rb,
	pfp_size = (adreno_dev->pfp_fw_size - pfp_idx);

	/*
	 * Below set of commands register with PFP that 6f is the
	 * opcode for bootstrapping
	 * Overwrite the first entry in the jump table with the special
	 * bootstrap opcode
	 */
	adreno_writereg(adreno_dev, ADRENO_REG_CP_PFP_UCODE_ADDR, 0x200);
	adreno_writereg(adreno_dev, ADRENO_REG_CP_PFP_UCODE_DATA, 0x6f0005);

	if (adreno_is_a4xx(adreno_dev)) {
		adreno_writereg(adreno_dev, ADRENO_REG_CP_PFP_UCODE_ADDR,
			0x400);
		adreno_writereg(adreno_dev, ADRENO_REG_CP_PFP_UCODE_DATA,
			 0x6f0009);
		bootstrap_size = (pm4_size + pfp_size + 5 + 6);
	} else {
		adreno_writereg(adreno_dev, ADRENO_REG_CP_PFP_UCODE_ADDR,
			0x200);
		adreno_writereg(adreno_dev, ADRENO_REG_CP_PFP_UCODE_DATA,
			 0x6f0005);
		bootstrap_size = (pm4_size + pfp_size + 5);
	}

	/* clear ME_HALT to start micro engine */
	adreno_writereg(adreno_dev, ADRENO_REG_CP_ME_CNTL, 0);

	bootstrap_size = (pm4_size + pfp_size + 5);

	cmds = adreno_ringbuffer_allocspace(rb, NULL, bootstrap_size);
	if (cmds == NULL)
			return -ENOMEM;
@@ -349,12 +359,50 @@ static int _ringbuffer_bootstrap_ucode(struct adreno_ringbuffer *rb,
	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, pfp_addr);
	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, pm4_size);
	GSL_RB_WRITE(rb->device, cmds, cmds_gpu, pm4_addr);
	for (i = pfp_idx; i < adreno_dev->pfp_fw_size; i++)
		GSL_RB_WRITE(rb->device, cmds, cmds_gpu, adreno_dev->pfp_fw[i]);

/**
 * Theory of operation:
 *
 * In A4x, we cannot have the PFP executing instructions while its instruction
 * RAM is loading. We load the PFP's instruction RAM using type-0 writes
 * from the ME.
 *
 * To make sure the PFP is not fetching instructions at the same time,
 * we put it in a one-instruction loop:
 *    mvc (ME), (ringbuffer)
 * which executes repeatedly until all of the data has been moved from
 * the ring buffer to the ME.
 */
	if (adreno_is_a4xx(adreno_dev)) {
		for (i = pm4_idx; i < adreno_dev->pm4_fw_size; i++)
		GSL_RB_WRITE(rb->device, cmds, cmds_gpu, adreno_dev->pm4_fw[i]);
			GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
					adreno_dev->pm4_fw[i]);
		for (i = pfp_idx; i < adreno_dev->pfp_fw_size; i++)
			GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
					adreno_dev->pfp_fw[i]);

		GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
			cp_type3_packet(CP_REG_RMW, (3)));
		GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
					0x20000000 + A4XX_CP_RB_WPTR);
		GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0xffffffff);
		GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 2);
		GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
			cp_type3_packet(CP_INTERRUPT, (1)));
		GSL_RB_WRITE(rb->device, cmds, cmds_gpu, 0);
		rb->wptr = rb->wptr - 2;
		adreno_ringbuffer_submit(rb);
		rb->wptr = rb->wptr + 2;
	} else {
		for (i = pfp_idx; i < adreno_dev->pfp_fw_size; i++)
			GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
					adreno_dev->pfp_fw[i]);
		for (i = pm4_idx; i < adreno_dev->pm4_fw_size; i++)
			GSL_RB_WRITE(rb->device, cmds, cmds_gpu,
					adreno_dev->pm4_fw[i]);
		adreno_ringbuffer_submit(rb);
	}

	/* idle device to validate bootstrap */
	return adreno_idle(device);
}