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

Commit cdf175a6 authored by Jordan Crouse's avatar Jordan Crouse Committed by Harshdeep Dhatt
Browse files

msm: kgsl: Only access and map the shadermem for a3xx snapshot



The "kgsl_3d0_shader_mem" resource is only used for a3xx snapshot, yet
we check for it and print a message on every single target. Luckily we
were already mapping the object on demand in the snapshot code so it
is easy enough to move the resource check there as well (and use one of
the fancy new devm_ functions to boot).

While we are kicking around in there, we don't need a special regread
function for shadermem because memcpy_fromio does the same task in
a better way. Removing the regread gives us the chance to tighten
the adreno_regread code to our benefit as well.

Change-Id: Ic0dedbadd93d4f96528e9e75a1325c37a5b0ea90
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent 66e38d99
Loading
Loading
Loading
Loading
+13 −61
Original line number Original line Diff line number Diff line
@@ -50,7 +50,6 @@ static struct adreno_device device_3d0 = {
			.irq_name = "kgsl_3d0_irq",
			.irq_name = "kgsl_3d0_irq",
		},
		},
		.iomemname = "kgsl_3d0_reg_memory",
		.iomemname = "kgsl_3d0_reg_memory",
		.shadermemname = "kgsl_3d0_shader_memory",
		.ftbl = &adreno_functable,
		.ftbl = &adreno_functable,
	},
	},
	.ft_policy = KGSL_FT_DEFAULT_POLICY,
	.ft_policy = KGSL_FT_DEFAULT_POLICY,
@@ -2974,55 +2973,11 @@ static int adreno_suspend_context(struct kgsl_device *device)
	return adreno_idle(device);
	return adreno_idle(device);
}
}


/**
 * adreno_read - General read function to read adreno device memory
 * @device - Pointer to the GPU device struct (for adreno device)
 * @base - Base address (kernel virtual) where the device memory is mapped
 * @offsetwords - Offset in words from the base address, of the memory that
 * is to be read
 * @value - Value read from the device memory
 * @mem_len - Length of the device memory mapped to the kernel
 */
static void adreno_read(struct kgsl_device *device, void __iomem *base,
		unsigned int offsetwords, unsigned int *value,
		unsigned int mem_len)
{

	void __iomem *reg;

	/* Make sure we're not reading from invalid memory */
	if (WARN(offsetwords * sizeof(uint32_t) >= mem_len,
		"Out of bounds register read: 0x%x/0x%x\n",
			offsetwords, mem_len >> 2))
		return;

	reg = (base + (offsetwords << 2));

	if (!in_interrupt())
		kgsl_pre_hwaccess(device);

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

static void adreno_retry_rbbm_read(struct kgsl_device *device,
static void adreno_retry_rbbm_read(struct kgsl_device *device,
		void __iomem *base, unsigned int offsetwords,
		void __iomem *base, unsigned int offsetwords,
		unsigned int *value, unsigned int mem_len)
		unsigned int *value, unsigned int mem_len)
{
{
	int i;
	int i;
	void __iomem *reg;

	/* Make sure we're not reading from invalid memory */
	if (WARN(offsetwords * sizeof(uint32_t) >= mem_len,
		"Out of bounds register read: 0x%x/0x%x\n",
		offsetwords, mem_len >> 2))
		return;

	reg = (base + (offsetwords << 2));


	/*
	/*
	 * If 0xdeafbead was transient, second read is expected to return the
	 * If 0xdeafbead was transient, second read is expected to return the
@@ -3030,7 +2985,7 @@ static void adreno_retry_rbbm_read(struct kgsl_device *device,
	 * 0xdeafbead, read it enough times to guarantee that.
	 * 0xdeafbead, read it enough times to guarantee that.
	 */
	 */
	for (i = 0; i < 16; i++) {
	for (i = 0; i < 16; i++) {
		*value = readl_relaxed(reg);
		*value = readl_relaxed(device->reg_virt + (offsetwords << 2));
		/*
		/*
		 * Read barrier needed so that register is read from hardware
		 * Read barrier needed so that register is read from hardware
		 * every iteration
		 * every iteration
@@ -3064,8 +3019,18 @@ static bool adreno_is_rbbm_batch_reg(struct kgsl_device *device,
static void adreno_regread(struct kgsl_device *device, unsigned int offsetwords,
static void adreno_regread(struct kgsl_device *device, unsigned int offsetwords,
	unsigned int *value)
	unsigned int *value)
{
{
	adreno_read(device, device->reg_virt, offsetwords, value,
	/* Make sure we're not reading from invalid memory */
						device->reg_len);
	if (WARN(offsetwords * sizeof(uint32_t) >= device->reg_len,
		"Out of bounds register read: 0x%x/0x%x\n",
			offsetwords, device->reg_len >> 2))
		return;

	if (!in_interrupt())
		kgsl_pre_hwaccess(device);

	*value = readl_relaxed(device->reg_virt + (offsetwords << 2));
	/* Order this read with respect to the following memory accesses */
	rmb();


	if ((*value == 0xdeafbead) &&
	if ((*value == 0xdeafbead) &&
		adreno_is_rbbm_batch_reg(device, offsetwords))
		adreno_is_rbbm_batch_reg(device, offsetwords))
@@ -3073,19 +3038,6 @@ static void adreno_regread(struct kgsl_device *device, unsigned int offsetwords,
			value, device->reg_len);
			value, device->reg_len);
}
}


/**
 * adreno_shadermem_regread - Used to read GPU (adreno) shader memory
 * @device - GPU device whose shader memory is to be read
 * @offsetwords - Offset in words, of the shader memory address to be read
 * @value - Pointer to where the read shader mem value is to be stored
 */
void adreno_shadermem_regread(struct kgsl_device *device,
	unsigned int offsetwords, unsigned int *value)
{
	adreno_read(device, device->shader_mem_virt, offsetwords, value,
					device->shader_mem_len);
}

static void adreno_regwrite(struct kgsl_device *device,
static void adreno_regwrite(struct kgsl_device *device,
				unsigned int offsetwords,
				unsigned int offsetwords,
				unsigned int value)
				unsigned int value)
+0 −4
Original line number Original line Diff line number Diff line
@@ -1046,10 +1046,6 @@ int adreno_set_constraint(struct kgsl_device *device,
				struct kgsl_context *context,
				struct kgsl_context *context,
				struct kgsl_device_constraint *constraint);
				struct kgsl_device_constraint *constraint);


void adreno_shadermem_regread(struct kgsl_device *device,
						unsigned int offsetwords,
						unsigned int *value);

void adreno_snapshot(struct kgsl_device *device,
void adreno_snapshot(struct kgsl_device *device,
		struct kgsl_snapshot *snapshot,
		struct kgsl_snapshot *snapshot,
		struct kgsl_context *context);
		struct kgsl_context *context);
+15 −17
Original line number Original line Diff line number Diff line
@@ -104,13 +104,9 @@ static size_t a3xx_snapshot_shader_memory(struct kgsl_device *device,
	u8 *buf, size_t remain, void *priv)
	u8 *buf, size_t remain, void *priv)
{
{
	struct kgsl_snapshot_debug *header = (struct kgsl_snapshot_debug *)buf;
	struct kgsl_snapshot_debug *header = (struct kgsl_snapshot_debug *)buf;
	unsigned int i;
	void *data = buf + sizeof(*header);
	unsigned int *data = (unsigned int *)(buf + sizeof(*header));
	unsigned int shader_read_len = SHADER_MEMORY_SIZE;
	unsigned int shader_read_len = SHADER_MEMORY_SIZE;


	if (shader_read_len > (device->shader_mem_len >> 2))
		shader_read_len = (device->shader_mem_len >> 2);

	if (remain < DEBUG_SECTION_SZ(shader_read_len)) {
	if (remain < DEBUG_SECTION_SZ(shader_read_len)) {
		SNAPSHOT_ERR_NOMEM(device, "SHADER MEMORY");
		SNAPSHOT_ERR_NOMEM(device, "SHADER MEMORY");
		return 0;
		return 0;
@@ -120,21 +116,23 @@ static size_t a3xx_snapshot_shader_memory(struct kgsl_device *device,
	header->size = shader_read_len;
	header->size = shader_read_len;


	/* Map shader memory to kernel, for dumping */
	/* Map shader memory to kernel, for dumping */
	if (device->shader_mem_virt == NULL)
	if (IS_ERR_OR_NULL(device->shader_mem_virt)) {
		device->shader_mem_virt = devm_ioremap(device->dev,
		struct resource *res;
					device->shader_mem_phys,

					device->shader_mem_len);
		res = platform_get_resource_byname(device->pdev,

			IORESOURCE_MEM, "kgsl_3d0_shader_memory");
	if (device->shader_mem_virt == NULL) {

		dev_err(device->dev,
		if (res)
			     "Unable to map shader memory region\n");
			device->shader_mem_virt =
		return 0;
				devm_ioremap_resource(&device->pdev->dev, res);
	}
	}


	/* Now, dump shader memory to snapshot */
	if (IS_ERR_OR_NULL(device->shader_mem_virt)) {
	for (i = 0; i < shader_read_len; i++)
		dev_err(device->dev, "Unable to map the shader memory\n");
		adreno_shadermem_regread(device, i, &data[i]);
		return 0;
	}


	memcpy_fromio(data, device->shader_mem_virt, shader_read_len << 2);


	return DEBUG_SECTION_SZ(shader_read_len);
	return DEBUG_SECTION_SZ(shader_read_len);
}
}
+0 −29
Original line number Original line Diff line number Diff line
@@ -4973,7 +4973,6 @@ int kgsl_request_irq(struct platform_device *pdev, const char *name,
int kgsl_device_platform_probe(struct kgsl_device *device)
int kgsl_device_platform_probe(struct kgsl_device *device)
{
{
	int status = -EINVAL;
	int status = -EINVAL;
	struct resource *res;
	int cpu;
	int cpu;


	status = _register_device(device);
	status = _register_device(device);
@@ -4986,34 +4985,6 @@ int kgsl_device_platform_probe(struct kgsl_device *device)
	if (status)
	if (status)
		goto error;
		goto error;


	/*
	 * Check if a shadermemname is defined, and then get shader memory
	 * details including shader memory starting physical address
	 * and shader memory length
	 */
	if (device->shadermemname != NULL) {
		res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM,
						device->shadermemname);

		if (res == NULL) {
			dev_warn(device->dev,
				      "Shader memory: platform_get_resource_byname failed\n");
		}

		else {
			device->shader_mem_phys = res->start;
			device->shader_mem_len = resource_size(res);
		}

		if (!devm_request_mem_region(device->dev,
					device->shader_mem_phys,
					device->shader_mem_len,
						device->name)) {
			dev_warn(device->dev,
				      "request_mem_region_failed\n");
		}
	}

	if (!devm_request_mem_region(device->dev, device->reg_phys,
	if (!devm_request_mem_region(device->dev, device->reg_phys,
				device->reg_len, device->name)) {
				device->reg_len, device->name)) {
		dev_err(device->dev, "request_mem_region failed\n");
		dev_err(device->dev, "request_mem_region failed\n");
+0 −6
Original line number Original line Diff line number Diff line
@@ -247,18 +247,12 @@ struct kgsl_device {
	/* Kernel virtual address for GPU shader memory */
	/* Kernel virtual address for GPU shader memory */
	void __iomem *shader_mem_virt;
	void __iomem *shader_mem_virt;


	/* Starting physical address for GPU shader memory */
	unsigned long shader_mem_phys;

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


	/* GPU shader memory size */
	unsigned int shader_mem_len;
	struct kgsl_memdesc memstore;
	struct kgsl_memdesc memstore;
	struct kgsl_memdesc scratch;
	struct kgsl_memdesc scratch;
	const char *iomemname;
	const char *iomemname;
	const char *shadermemname;


	struct kgsl_mmu mmu;
	struct kgsl_mmu mmu;
	struct gmu_core_device gmu_core;
	struct gmu_core_device gmu_core;