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

Commit d37f1d8d authored by Lynus Vaz's avatar Lynus Vaz
Browse files

msm: kgsl: Let normal register functions access GMU



Update the kgsl register read and write functions to also access the
GMU register range with suitable range checking. This will simplify
common code that accesses both GMU and non-GMU registers.

Change-Id: Iea02c721b4cf6cdbc42ecdd72a490cca34a261ee
Signed-off-by: default avatarLynus Vaz <lvaz@codeaurora.org>
parent dc62e315
Loading
Loading
Loading
Loading
+2 −47
Original line number Diff line number Diff line
@@ -1264,59 +1264,14 @@ static void a6xx_snapshot_debugbus(struct kgsl_device *device,
	}
}

static size_t a6xx_snapshot_dump_gmu_registers(struct kgsl_device *device,
		u8 *buf, size_t remain, void *priv)
{
	struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
	struct kgsl_snapshot_registers *regs = priv;
	unsigned int *data = (unsigned int *)(buf + sizeof(*header));
	int count = 0, j, k;

	/* Figure out how many registers we are going to dump */
	for (j = 0; j < regs->count; j++) {
		int start = regs->regs[j * 2];
		int end = regs->regs[j * 2 + 1];

		count += (end - start + 1);
	}

	if (remain < (count * 8) + sizeof(*header)) {
		SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
		return 0;
	}

	for (j = 0; j < regs->count; j++) {
		unsigned int start = regs->regs[j * 2];
		unsigned int end = regs->regs[j * 2 + 1];

		for (k = start; k <= end; k++) {
			unsigned int val;

			kgsl_gmu_regread(device, k, &val);
			*data++ = k;
			*data++ = val;
		}
	}

	header->count = count;

	/* Return the size of the section */
	return (count * 8) + sizeof(*header);
}

static void a6xx_snapshot_gmu(struct kgsl_device *device,
		struct kgsl_snapshot *snapshot)
{
	struct kgsl_snapshot_registers gmu_regs = {
		.regs = a6xx_gmu_registers,
		.count = ARRAY_SIZE(a6xx_gmu_registers) / 2,
	};

	if (!kgsl_gmu_isenabled(device))
		return;

	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
			snapshot, a6xx_snapshot_dump_gmu_registers, &gmu_regs);
	adreno_snapshot_registers(device, snapshot, a6xx_gmu_registers,
					ARRAY_SIZE(a6xx_gmu_registers) / 2);
}

/* a6xx_snapshot_sqe() - Dump SQE data in snapshot */
+4 −15
Original line number Diff line number Diff line
@@ -54,21 +54,10 @@ static void adreno_get_submit_time(struct adreno_device *adreno_dev,

	/* Read always on registers */
	if (!adreno_is_a3xx(adreno_dev)) {
		if (kgsl_gmu_isenabled(KGSL_DEVICE(adreno_dev))) {
			uint32_t val_lo, val_hi;

			adreno_read_gmureg(adreno_dev,
				ADRENO_REG_RBBM_ALWAYSON_COUNTER_LO, &val_lo);
			adreno_read_gmureg(adreno_dev,
				ADRENO_REG_RBBM_ALWAYSON_COUNTER_HI, &val_hi);

			time->ticks = (val_lo | ((uint64_t)val_hi << 32));
		} else {
		adreno_readreg64(adreno_dev,
			ADRENO_REG_RBBM_ALWAYSON_COUNTER_LO,
			ADRENO_REG_RBBM_ALWAYSON_COUNTER_HI,
			&time->ticks);
		}

		/* Mask hi bits as they may be incorrect on some targets */
		if (ADRENO_GPUREV(adreno_dev) >= 400 &&
+35 −4
Original line number Diff line number Diff line
@@ -532,18 +532,49 @@ static inline void kgsl_process_add_stats(struct kgsl_process_private *priv,
		priv->stats[type].max = priv->stats[type].cur;
}

static inline bool kgsl_is_register_offset(struct kgsl_device *device,
				unsigned int offsetwords)
{
	return ((offsetwords * sizeof(uint32_t)) < device->reg_len);
}

static inline bool kgsl_is_gmu_offset(struct kgsl_device *device,
				unsigned int offsetwords)
{
	struct gmu_device *gmu = &device->gmu;

	return (gmu->pdev &&
		(offsetwords >= gmu->gmu2gpu_offset) &&
		((offsetwords - gmu->gmu2gpu_offset) * sizeof(uint32_t) <
			gmu->reg_len));
}

static inline void kgsl_regread(struct kgsl_device *device,
				unsigned int offsetwords,
				unsigned int *value)
{
	if (kgsl_is_register_offset(device, offsetwords))
		device->ftbl->regread(device, offsetwords, value);
	else if (device->ftbl->gmu_regread &&
			kgsl_is_gmu_offset(device, offsetwords))
		device->ftbl->gmu_regread(device, offsetwords, value);
	else {
		WARN(1, "Out of bounds register read: 0x%x\n", offsetwords);
		*value = 0;
	}
}

static inline void kgsl_regwrite(struct kgsl_device *device,
				 unsigned int offsetwords,
				 unsigned int value)
{
	if (kgsl_is_register_offset(device, offsetwords))
		device->ftbl->regwrite(device, offsetwords, value);
	else if (device->ftbl->gmu_regwrite &&
			kgsl_is_gmu_offset(device, offsetwords))
		device->ftbl->gmu_regwrite(device, offsetwords, value);
	else
		WARN(1, "Out of bounds register write: 0x%x\n", offsetwords);
}

static inline void kgsl_gmu_regread(struct kgsl_device *device,
@@ -570,9 +601,9 @@ static inline void kgsl_regrmw(struct kgsl_device *device,
{
	unsigned int val = 0;

	device->ftbl->regread(device, offsetwords, &val);
	kgsl_regread(device, offsetwords, &val);
	val &= ~mask;
	device->ftbl->regwrite(device, offsetwords, val | bits);
	kgsl_regwrite(device, offsetwords, val | bits);
}

static inline void kgsl_gmu_regrmw(struct kgsl_device *device,