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

Commit 2fc171b7 authored by Harshdeep Dhatt's avatar Harshdeep Dhatt
Browse files

msm: kgsl: Dump isense registers in a650 snapshot



This helps with debugging isense related issues.

Change-Id: I30cdfadd3bb9b91473edee862e91b59b4c111351
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent e0bc14c6
Loading
Loading
Loading
Loading
+40 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2002,2007-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved.
 */
#include <linux/module.h>
#include <linux/uaccess.h>
@@ -1229,6 +1229,24 @@ static void adreno_rscc_probe(struct kgsl_device *device)
		dev_warn(device->dev, "rscc ioremap failed\n");
}

static void adreno_isense_probe(struct kgsl_device *device)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct resource *res;

	res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM,
			"isense_cntl");
	if (res == NULL)
		return;

	adreno_dev->isense_base = res->start - device->reg_phys;
	adreno_dev->isense_len = resource_size(res);
	adreno_dev->isense_virt = devm_ioremap(device->dev, res->start,
					adreno_dev->isense_len);
	if (adreno_dev->isense_virt == NULL)
		dev_warn(device->dev, "isense ioremap failed\n");
}

static void adreno_efuse_read_soc_hw_rev(struct adreno_device *adreno_dev)
{
	unsigned int val;
@@ -1355,6 +1373,8 @@ static int adreno_probe(struct platform_device *pdev)
	adreno_cx_misc_probe(device);

	adreno_rscc_probe(device);

	adreno_isense_probe(device);
	/*
	 * qcom,iommu-secure-id is used to identify MMUs that can handle secure
	 * content but that is only part of the story - the GPU also has to be
@@ -3244,6 +3264,25 @@ void adreno_rscc_regread(struct adreno_device *adreno_dev,
	rmb();
}

void adreno_isense_regread(struct adreno_device *adreno_dev,
	unsigned int offsetwords, unsigned int *value)
{
	unsigned int isense_offset;

	isense_offset = (offsetwords << 2);
	if (!adreno_dev->isense_virt ||
		(isense_offset >= adreno_dev->isense_len))
		return;

	*value =  __raw_readl(adreno_dev->isense_virt + isense_offset);

	/*
	 * ensure this read finishes before the next one.
	 * i.e. act like normal readl()
	 */
	rmb();
}

void adreno_cx_misc_regwrite(struct adreno_device *adreno_dev,
	unsigned int offsetwords, unsigned int value)
{
+8 −0
Original line number Diff line number Diff line
@@ -445,6 +445,9 @@ enum gpu_coresight_sources {
 * @rscc_base: Base physical address of the RSCC
 * @rscc_len: Length of the RSCC register block
 * @rscc_virt: Pointer where RSCC block is mapped
 * @isense_base: Base physical address of isense block
 * @isense_len: Length of the isense register block
 * @isense_virt: Pointer where isense block is mapped
 * @gpucore: Pointer to the adreno_gpu_core structure
 * @pfp_fw: Buffer which holds the pfp ucode
 * @pfp_fw_size: Size of pfp ucode buffer
@@ -530,6 +533,9 @@ struct adreno_device {
	unsigned long rscc_base;
	unsigned int rscc_len;
	void __iomem *rscc_virt;
	unsigned long isense_base;
	unsigned int isense_len;
	void __iomem *isense_virt;
	const struct adreno_gpu_core *gpucore;
	struct adreno_firmware fw[2];
	size_t gpmu_cmds_size;
@@ -1191,6 +1197,8 @@ void adreno_cx_misc_regrmw(struct adreno_device *adreno_dev,
		unsigned int mask, unsigned int bits);
void adreno_rscc_regread(struct adreno_device *adreno_dev,
		unsigned int offsetwords, unsigned int *value);
void adreno_isense_regread(struct adreno_device *adreno_dev,
		unsigned int offsetwords, unsigned int *value);


#define ADRENO_TARGET(_name, _id) \
+60 −0
Original line number Diff line number Diff line
@@ -116,6 +116,17 @@ static const unsigned int a650_rscc_registers[] = {
	0x3915B, 0x3915B,
};

static const unsigned int a650_isense_registers[] = {
	0x22C00, 0x22C19, 0x22C26, 0x22C2D, 0x22C2F, 0x22C36, 0x22C40, 0x22C44,
	0x22C50, 0x22C57, 0x22C60, 0x22C67, 0x22C80, 0x22C87, 0x22D25, 0x22D2A,
	0x22D2C, 0x22D32, 0x22D3E, 0x22D3F, 0x22D4E, 0x22D55, 0x22D58, 0x22D60,
	0x22D64, 0x22D64, 0x22D66, 0x22D66, 0x22D68, 0x22D6B, 0x22D6E, 0x22D76,
	0x22D78, 0x22D78, 0x22D80, 0x22D87, 0x22D90, 0x22D97, 0x22DA0, 0x22DA0,
	0x22DB0, 0x22DB7, 0x22DC0, 0x22DC2, 0x22DC4, 0x22DE3, 0x2301A, 0x2301A,
	0x2301D, 0x2302A, 0x23120, 0x23121, 0x23133, 0x23133, 0x23156, 0x23157,
	0x23165, 0x23165, 0x2316D, 0x2316D, 0x23180, 0x23191,
};

static const struct sel_reg {
	unsigned int host_reg;
	unsigned int cd_reg;
@@ -1581,6 +1592,49 @@ size_t a6xx_snapshot_rscc_registers(struct kgsl_device *device, u8 *buf,
	return (count * 8) + sizeof(*header);
}

size_t a6xx_snapshot_isense_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;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	/* 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, "ISENSE 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;

			adreno_isense_regread(adreno_dev,
				k - (adreno_dev->isense_base >> 2), &val);
			*data++ = k;
			*data++ = val;
		}
	}

	header->count = count;

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

/*
 * a6xx_snapshot() - A6XX GPU snapshot function
 * @adreno_dev: Device being snapshotted
@@ -1618,6 +1672,12 @@ void a6xx_snapshot(struct adreno_device *adreno_dev,

		kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
			snapshot, a6xx_snapshot_rscc_registers, &r);

		r.regs = a650_isense_registers;
		r.count = ARRAY_SIZE(a650_isense_registers) / 2;

		kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
			snapshot, a6xx_snapshot_isense_registers, &r);
	} else if (adreno_is_a615_family(adreno_dev) ||
			adreno_is_a630(adreno_dev)) {
		adreno_snapshot_registers(device, snapshot,