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

Commit 43b874ab authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Don't dump GPMU registers on non GPMU devices"

parents 7c6796ef e09cf794
Loading
Loading
Loading
Loading
+76 −43
Original line number Original line Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -412,6 +412,15 @@ static const unsigned int a5xx_registers[] = {
	0xEC00, 0xEC05, 0xEC08, 0xECE9, 0xECF0, 0xECF0,
	0xEC00, 0xEC05, 0xEC08, 0xECE9, 0xECF0, 0xECF0,
	/* VPC CTX 1 */
	/* VPC CTX 1 */
	0xEA80, 0xEA80, 0xEA82, 0xEAA3, 0xEAA5, 0xEAC2,
	0xEA80, 0xEA80, 0xEA82, 0xEAA3, 0xEAA5, 0xEAC2,
};

/*
 * GPMU registers to dump for A5XX on snapshot.
 * Registers in pairs - first value is the start offset, second
 * is the stop offset (inclusive)
 */

static const unsigned int a5xx_gpmu_registers[] = {
	/* GPMU */
	/* GPMU */
	0xA800, 0xA8FF, 0xAC60, 0xAC60,
	0xA800, 0xA8FF, 0xAC60, 0xAC60,
};
};
@@ -664,24 +673,23 @@ static size_t a5xx_snapshot_pre_crashdump_regs(struct kgsl_device *device,
	return kgsl_snapshot_dump_registers(device, buf, remain, &pre_cdregs);
	return kgsl_snapshot_dump_registers(device, buf, remain, &pre_cdregs);
}
}


struct registers {
	const unsigned int *regs;
	size_t size;
};

static size_t a5xx_legacy_snapshot_registers(struct kgsl_device *device,
static size_t a5xx_legacy_snapshot_registers(struct kgsl_device *device,
		u8 *buf, size_t remain)
		u8 *buf, size_t remain, const unsigned int *regs, size_t size)
{
{
	struct kgsl_snapshot_registers regs = {
	struct kgsl_snapshot_registers snapshot_regs = {
		.regs = a5xx_registers,
		.regs = regs,
		.count = ARRAY_SIZE(a5xx_registers) / 2,
		.count = size / 2,
	};
	};


	return kgsl_snapshot_dump_registers(device, buf, remain, &regs);
	return kgsl_snapshot_dump_registers(device, buf, remain,
			&snapshot_regs);
}
}


static struct cdregs {
	const unsigned int *regs;
	unsigned int size;
} _a5xx_cd_registers[] = {
	{ a5xx_registers, ARRAY_SIZE(a5xx_registers) },
};

#define REG_PAIR_COUNT(_a, _i) \
#define REG_PAIR_COUNT(_a, _i) \
	(((_a)[(2 * (_i)) + 1] - (_a)[2 * (_i)]) + 1)
	(((_a)[(2 * (_i)) + 1] - (_a)[2 * (_i)]) + 1)


@@ -691,11 +699,13 @@ static size_t a5xx_snapshot_registers(struct kgsl_device *device, u8 *buf,
	struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
	struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
	unsigned int *data = (unsigned int *)(buf + sizeof(*header));
	unsigned int *data = (unsigned int *)(buf + sizeof(*header));
	unsigned int *src = (unsigned int *) registers.hostptr;
	unsigned int *src = (unsigned int *) registers.hostptr;
	unsigned int i, j, k;
	struct registers *regs = (struct registers *)priv;
	unsigned int j, k;
	unsigned int count = 0;
	unsigned int count = 0;


	if (crash_dump_valid == false)
	if (crash_dump_valid == false)
		return a5xx_legacy_snapshot_registers(device, buf, remain);
		return a5xx_legacy_snapshot_registers(device, buf, remain,
				regs->regs, regs->size);


	if (remain < sizeof(*header)) {
	if (remain < sizeof(*header)) {
		SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
		SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
@@ -704,9 +714,6 @@ static size_t a5xx_snapshot_registers(struct kgsl_device *device, u8 *buf,


	remain -= sizeof(*header);
	remain -= sizeof(*header);


	for (i = 0; i < ARRAY_SIZE(_a5xx_cd_registers); i++) {
		struct cdregs *regs = &_a5xx_cd_registers[i];

	for (j = 0; j < regs->size / 2; j++) {
	for (j = 0; j < regs->size / 2; j++) {
		unsigned int start = regs->regs[2 * j];
		unsigned int start = regs->regs[2 * j];
		unsigned int end = regs->regs[(2 * j) + 1];
		unsigned int end = regs->regs[(2 * j) + 1];
@@ -723,7 +730,6 @@ static size_t a5xx_snapshot_registers(struct kgsl_device *device, u8 *buf,
			*data++ = *src++;
			*data++ = *src++;
		}
		}
	}
	}
	}


out:
out:
	header->count = count;
	header->count = count;
@@ -861,6 +867,7 @@ void a5xx_snapshot(struct adreno_device *adreno_dev,
	struct adreno_snapshot_data *snap_data = gpudev->snapshot_data;
	struct adreno_snapshot_data *snap_data = gpudev->snapshot_data;
	unsigned int reg, i;
	unsigned int reg, i;
	struct adreno_ringbuffer *rb;
	struct adreno_ringbuffer *rb;
	struct registers regs;


	/* Disable Clock gating temporarily for the debug bus to work */
	/* Disable Clock gating temporarily for the debug bus to work */
	a5xx_hwcg_set(adreno_dev, false);
	a5xx_hwcg_set(adreno_dev, false);
@@ -877,8 +884,20 @@ void a5xx_snapshot(struct adreno_device *adreno_dev,
	/* Try to run the crash dumper */
	/* Try to run the crash dumper */
	_a5xx_do_crashdump(device);
	_a5xx_do_crashdump(device);


	regs.regs = a5xx_registers;
	regs.size = ARRAY_SIZE(a5xx_registers);

	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, snapshot,
			a5xx_snapshot_registers, &regs);

	if (ADRENO_FEATURE(adreno_dev, ADRENO_GPMU)) {
		regs.regs = a5xx_gpmu_registers;
		regs.size = ARRAY_SIZE(a5xx_gpmu_registers);

		kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
		kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
		snapshot, a5xx_snapshot_registers, NULL);
				snapshot, a5xx_snapshot_registers, &regs);
	}



	/* Dump SP TP HLSQ registers */
	/* Dump SP TP HLSQ registers */
	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, snapshot,
	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, snapshot,
@@ -1035,17 +1054,23 @@ void a5xx_crashdump_init(struct adreno_device *adreno_dev)
	 * To save the registers, we need 16 bytes per register pair for the
	 * To save the registers, we need 16 bytes per register pair for the
	 * script and a dword for each register int the data
	 * script and a dword for each register int the data
	 */
	 */
	for (i = 0; i < ARRAY_SIZE(_a5xx_cd_registers); i++) {
		struct cdregs *regs = &_a5xx_cd_registers[i];


	/* Each pair needs 16 bytes (2 qwords) */
	/* Each pair needs 16 bytes (2 qwords) */
		script_size += (regs->size / 2) * 16;
	script_size += (ARRAY_SIZE(a5xx_registers) / 2) * 16;


	/* Each register needs a dword in the data */
	/* Each register needs a dword in the data */
		for (j = 0; j < regs->size / 2; j++)
	for (j = 0; j < ARRAY_SIZE(a5xx_registers) / 2; j++)
			data_size += REG_PAIR_COUNT(regs->regs, j) *
		data_size += REG_PAIR_COUNT(a5xx_registers, j) *
			sizeof(unsigned int);
			sizeof(unsigned int);


	if (ADRENO_FEATURE(adreno_dev, ADRENO_GPMU)) {
		/* Each pair needs 16 bytes (2 qwords) */
		script_size += (ARRAY_SIZE(a5xx_gpmu_registers) / 2) * 16;

		/* Each register needs a dword in the data */
		for (j = 0; j < ARRAY_SIZE(a5xx_gpmu_registers) / 2; j++)
			data_size += REG_PAIR_COUNT(a5xx_gpmu_registers, j) *
				sizeof(unsigned int);
	}
	}


	/*
	/*
@@ -1083,13 +1108,21 @@ void a5xx_crashdump_init(struct adreno_device *adreno_dev)
	ptr = (uint64_t *) capturescript.hostptr;
	ptr = (uint64_t *) capturescript.hostptr;


	/* For the registers, program a read command for each pair */
	/* For the registers, program a read command for each pair */
	for (i = 0; i < ARRAY_SIZE(_a5xx_cd_registers); i++) {
		struct cdregs *regs = &_a5xx_cd_registers[i];


		for (j = 0; j < regs->size / 2; j++) {
	for (j = 0; j < ARRAY_SIZE(a5xx_registers) / 2; j++) {
			unsigned int r = REG_PAIR_COUNT(regs->regs, j);
		unsigned int r = REG_PAIR_COUNT(a5xx_registers, j);
		*ptr++ = registers.gpuaddr + offset;
		*ptr++ = (((uint64_t) a5xx_registers[2 * j]) << 44)
			| r;
		offset += r * sizeof(unsigned int);
	}

	if (ADRENO_FEATURE(adreno_dev, ADRENO_GPMU)) {
		for (j = 0; j < ARRAY_SIZE(a5xx_gpmu_registers) / 2; j++) {
			unsigned int r = REG_PAIR_COUNT(a5xx_gpmu_registers, j);
			*ptr++ = registers.gpuaddr + offset;
			*ptr++ = registers.gpuaddr + offset;
			*ptr++ = (((uint64_t) regs->regs[2 * j]) << 44) | r;
			*ptr++ = (((uint64_t) a5xx_gpmu_registers[2 * j]) << 44)
				| r;
			offset += r * sizeof(unsigned int);
			offset += r * sizeof(unsigned int);
		}
		}
	}
	}