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

Commit c48a6fe5 authored by Mohammed Mirza Mandayappurath Manzoor's avatar Mohammed Mirza Mandayappurath Manzoor
Browse files

msm: kgsl: Set isdb breakpoints before snapshot



When taking a scandump, set isdb breakpoints to have same data as snapshot.
Also provide a sysfs knob to control the breakpoint set.

Change-Id: I0d27cff15ff9f93c78e8b58899e794dfabcb8d79
Signed-off-by: default avatarMohammed Mirza Mandayappurath Manzoor <mmandaya@codeaurora.org>
parent a8667785
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -3682,6 +3682,13 @@ static void adreno_gpu_model(struct kgsl_device *device, char *str,
			 ADRENO_CHIPID_PATCH(adreno_dev->chipid) + 1);
}

static bool adreno_is_hwcg_on(struct kgsl_device *device)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	return test_bit(ADRENO_HWCG_CTRL, &adreno_dev->pwrctrl_flag);
}

static const struct kgsl_functable adreno_functable = {
	/* Mandatory functions */
	.regread = adreno_regread,
@@ -3726,6 +3733,7 @@ static const struct kgsl_functable adreno_functable = {
	.dispatcher_halt = adreno_dispatcher_halt,
	.dispatcher_unhalt = adreno_dispatcher_unhalt,
	.query_property_list = adreno_query_property_list,
	.is_hwcg_on = adreno_is_hwcg_on,
};

static struct platform_driver adreno_platform_driver = {
+48 −2
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 */

#include <linux/debugfs.h>
#include <linux/io.h>

#include "kgsl_debugfs.h"
#include "kgsl_device.h"
@@ -29,11 +30,56 @@ static int _strict_get(void *data, u64 *val)

DEFINE_DEBUGFS_ATTRIBUTE(_strict_fops, _strict_get, _strict_set, "%llu\n");

static void kgsl_qdss_gfx_register_probe(struct kgsl_device *device)
{
	struct resource *res;

	res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM,
							"qdss_gfx");

	if (res == NULL)
		return;

	device->qdss_gfx_virt = devm_ioremap(device->dev, res->start,
							resource_size(res));

	if (device->qdss_gfx_virt == NULL)
		dev_warn(device->dev, "qdss_gfx ioremap failed\n");
}

static int _isdb_set(void *data, u64 val)
{
	struct kgsl_device *device = data;

	if (device->qdss_gfx_virt == NULL)
		kgsl_qdss_gfx_register_probe(device);

	device->set_isdb_breakpoint = val ? true : false;
	return 0;
}

static int _isdb_get(void *data, u64 *val)
{
	struct kgsl_device *device = data;

	*val = device->set_isdb_breakpoint ? 1 : 0;
	return 0;
}

DEFINE_DEBUGFS_ATTRIBUTE(_isdb_fops, _isdb_get, _isdb_set, "%llu\n");

void kgsl_device_debugfs_init(struct kgsl_device *device)
{
	if (!IS_ERR_OR_NULL(kgsl_debugfs_dir))
	struct dentry *snapshot_dir;

	if (IS_ERR_OR_NULL(kgsl_debugfs_dir))
		return;

	device->d_debugfs = debugfs_create_dir(device->name,
						       kgsl_debugfs_dir);
	snapshot_dir = debugfs_create_dir("snapshot", kgsl_debugfs_dir);
	debugfs_create_file("break_isdb", 0644, snapshot_dir, device,
		&_isdb_fops);
}

void kgsl_device_debugfs_close(struct kgsl_device *device)
+5 −0
Original line number Diff line number Diff line
@@ -178,6 +178,7 @@ struct kgsl_functable {
	 */
	int (*query_property_list)(struct kgsl_device *device, u32 *list,
		u32 count);
	bool (*is_hwcg_on)(struct kgsl_device *device);
};

struct kgsl_ioctl {
@@ -246,6 +247,9 @@ struct kgsl_device {
	/* Starting physical address for GPU shader memory */
	unsigned long shader_mem_phys;

	/* Starting kernel virtual address for QDSS GFX DBG register block */
	void __iomem *qdss_gfx_virt;

	/* GPU shader memory size */
	unsigned int shader_mem_len;
	struct kgsl_memdesc memstore;
@@ -291,6 +295,7 @@ struct kgsl_device {
	u32 snapshot_faultcount;	/* Total number of faults since boot */
	bool force_panic;		/* Force panic after snapshot dump */
	bool prioritize_unrecoverable;	/* Overwrite with new GMU snapshots */
	bool set_isdb_breakpoint;	/* Set isdb registers before snapshot */

	/* Use CP Crash dumper to get GPU snapshot*/
	bool snapshot_crashdumper;
+43 −0
Original line number Diff line number Diff line
@@ -594,6 +594,47 @@ static void kgsl_free_snapshot(struct kgsl_snapshot *snapshot)
	dev_err(device->dev, "snapshot: objects released\n");
}

#define SP0_ISDB_ISDB_BRKPT_CFG 0x40014
#define SP0_ISDB_ISDB_EN 0x40004
#define SP0_ISDB_ISDB_CMD 0x4000C

static void isdb_write(void __iomem *base, u32 offset)
{
	/* To set the SCHBREAKTYPE bit */
	__raw_writel(0x800, base + SP0_ISDB_ISDB_BRKPT_CFG + offset);

	/*
	 * ensure the configurations are set before
	 * enabling ISDB
	 */
	wmb();
	/* To set the ISDBCLKON and ISDB_EN bits*/
	__raw_writel(0x03, base + SP0_ISDB_ISDB_EN + offset);

	/*
	 * ensure previous write to enable isdb posts
	 * before issuing the break command
	 */
	wmb();
	/*To issue ISDB_0_ISDB_CMD_BREAK*/
	__raw_writel(0x1, base + SP0_ISDB_ISDB_CMD + offset);
}

static void set_isdb_breakpoint_registers(struct kgsl_device *device)
{
	if (!device->set_isdb_breakpoint || !device->ftbl->is_hwcg_on(device)
					|| device->qdss_gfx_virt == NULL)
		return;

	/* Issue break command for all six SPs */
	isdb_write(device->qdss_gfx_virt, 0x0000);
	isdb_write(device->qdss_gfx_virt, 0x1000);
	isdb_write(device->qdss_gfx_virt, 0x2000);
	isdb_write(device->qdss_gfx_virt, 0x3000);
	isdb_write(device->qdss_gfx_virt, 0x4000);
	isdb_write(device->qdss_gfx_virt, 0x5000);
}

/**
 * kgsl_snapshot() - construct a device snapshot
 * @device: device to snapshot
@@ -611,6 +652,8 @@ void kgsl_device_snapshot(struct kgsl_device *device,
	struct timespec boot;
	phys_addr_t pa;

	set_isdb_breakpoint_registers(device);

	if (device->snapshot_memory.ptr == NULL) {
		dev_err(device->dev,
			     "snapshot: no snapshot memory available\n");