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

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

Merge "msm: kgsl: Correctly check for batch register offset"

parents 76435aab 1d5e292c
Loading
Loading
Loading
Loading
+20 −69
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,
@@ -3016,55 +3015,10 @@ 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,
		unsigned int offsetwords, unsigned int *value)
		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
@@ -3072,7 +3026,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
@@ -3089,12 +3043,13 @@ static bool adreno_is_rbbm_batch_reg(struct kgsl_device *device,
{
{
	if (adreno_is_a650(ADRENO_DEVICE(device)) ||
	if (adreno_is_a650(ADRENO_DEVICE(device)) ||
		adreno_is_a620v1(ADRENO_DEVICE(device))) {
		adreno_is_a620v1(ADRENO_DEVICE(device))) {
		if (((offsetwords > 0x0) && (offsetwords < 0x3FF)) ||
		if (((offsetwords >= 0x0) && (offsetwords <= 0x3FF)) ||
			((offsetwords > 0x4FA) && (offsetwords < 0x53F)) ||
		((offsetwords >= 0x4FA) && (offsetwords <= 0x53F)) ||
			((offsetwords > 0x556) && (offsetwords < 0x5FF)) ||
		((offsetwords >= 0x556) && (offsetwords <= 0x5FF)) ||
			((offsetwords > 0xF400) && (offsetwords < 0xFFFF)))
		((offsetwords >= 0xF400) && (offsetwords <= 0xFFFF)))
			return  true;
			return  true;
	}
	}

	return false;
	return false;
}
}


@@ -3106,26 +3061,22 @@ 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))
		adreno_retry_rbbm_read(device, device->reg_virt, offsetwords,
		adreno_retry_rbbm_read(device, offsetwords, value);
			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,
+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;