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

Commit 1817bbf5 authored by Hareesh Gundu's avatar Hareesh Gundu Committed by Gerrit - the friendly Code Review server
Browse files

msm: kgsl: Poll a6x crashdumper register memory for status



Use a6x crashdumper register memory end location to know
the crashdumper status completion. This will avoid AHB
traffic while crashdumper was active in snapshot dumping
and fixes the slave timeout issue.

Change-Id: Ic24e75557297c6a1a3f2ad7893f4d8d308f9943c
Signed-off-by: default avatarHareesh Gundu <hareeshg@codeaurora.org>
parent d1d92738
Loading
Loading
Loading
Loading
+39 −13
Original line number Diff line number Diff line
@@ -574,6 +574,7 @@ static struct a6xx_shader_block a6xx_shader_blocks[] = {
static struct kgsl_memdesc *a6xx_capturescript;
static struct kgsl_memdesc *a6xx_crashdump_registers;
static bool crash_dump_valid;
static u32 *a6xx_cd_reg_end;

static struct reg_list {
	const unsigned int *regs;
@@ -1565,7 +1566,7 @@ static size_t a6xx_snapshot_sqe(struct kgsl_device *device, u8 *buf,
static void _a6xx_do_crashdump(struct kgsl_device *device)
{
	u32 val = 0;
	int ret;
	ktime_t timeout;

	crash_dump_valid = false;

@@ -1580,9 +1581,6 @@ static void _a6xx_do_crashdump(struct kgsl_device *device)
	if (a6xx_is_smmu_stalled(device))
		return;

	memset(a6xx_crashdump_registers->hostptr, 0xaa,
			a6xx_crashdump_registers->size);

	/* Turn on APRIV for legacy targets so we can access the buffers */
	if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV))
		kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 1);
@@ -1593,20 +1591,29 @@ static void _a6xx_do_crashdump(struct kgsl_device *device)
			upper_32_bits(a6xx_capturescript->gpuaddr));
	kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1);

	/* wait 100 ms before starting the loop */
	 schedule_timeout_interruptible(HZ/10);
	timeout = ktime_add_ms(ktime_get(), CP_CRASH_DUMPER_TIMEOUT);

	might_sleep();

	for (;;) {
		/* make sure we're reading the latest value */
		rmb();
		if ((*a6xx_cd_reg_end) != 0xaaaaaaaa)
			break;

		if (ktime_compare(ktime_get(), timeout) > 0)
			break;

		/* Wait 1msec to avoid unnecessary looping */
		usleep_range(100, 1000);
	}

	 /* Read every 10ms for 900ms */
	 ret = readl_poll_timeout(device->reg_virt +
			 (A6XX_CP_CRASH_DUMP_STATUS << 2),
			  val, val & 0x02, 10000, 900 * 1000);
	if (ret)
	kgsl_regread(device, A6XX_CP_CRASH_DUMP_STATUS, &val);

	if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV))
		kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 0);

	if (ret) {
	if (!(val & 0x2)) {
		dev_err(device->dev, "Crash dump timed out: 0x%X\n", val);
		return;
	}
@@ -1901,6 +1908,10 @@ void a6xx_snapshot(struct adreno_device *adreno_dev,

		/* registers dumped through DBG AHB */
		a6xx_snapshot_dbgahb_regs(device, snapshot);

		if (!a6xx_is_smmu_stalled(device))
			memset(a6xx_crashdump_registers->hostptr, 0xaa,
					a6xx_crashdump_registers->size);
	}

	if (adreno_is_a660(adreno_dev)) {
@@ -2209,6 +2220,11 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev)
				sizeof(unsigned int);
	}

	/* 16 bytes (2 qwords) for last entry in CD script */
	script_size += 16;
	/* Increment data size to store last entry in CD */
	data_size += sizeof(unsigned int);

	/* Now allocate the script and data buffers */

	/* The script buffers needs 2 extra qwords on the end */
@@ -2271,6 +2287,16 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev)

	ptr += _a6xx_crashdump_init_non_ctx_dbgahb(ptr, &offset);

	/* Save CD register end pointer to check CD status completion */
	a6xx_cd_reg_end = a6xx_crashdump_registers->hostptr + offset;

	memset(a6xx_crashdump_registers->hostptr, 0xaa,
			a6xx_crashdump_registers->size);

	/* Program the capturescript to read the last register entry */
	*ptr++ = a6xx_crashdump_registers->gpuaddr + offset;
	*ptr++ = (((uint64_t) A6XX_CP_CRASH_DUMP_STATUS) << 44) | (uint64_t) 1;

	*ptr++ = 0;
	*ptr++ = 0;
}