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

Commit eceda36b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Ioremap the CX debug register block"

parents b2c52af5 9ed8cf97
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -5,14 +5,17 @@ Qualcomm Technologies, Inc. Adreno GPU
Required properties:
- label:		A string used as a descriptive name for the device.
- compatible:		Must be "qcom,kgsl-3d0" and "qcom,kgsl-3d"
- reg:			Specifies the register base address and size. The second interval
			specifies the shader memory base address and size.
- reg:			Specifies the register base address and size, the shader memory
			base address and size (if it exists), and the base address and size
			of the CX_DBGC block (if it exists).
- reg-names:		Resource names used for the physical address of device registers
			and shader memory. "kgsl_3d0_reg_memory" gives the physical address
			and length of device registers while "kgsl_3d0_shader_memory" gives
			physical address and length of device shader memory.  If
			specified, "qfprom_memory" gives the range for the efuse
			registers used for various configuration options.
			registers used for various configuration options. If specified,
			"kgsl_3d0_cx_dbgc_memory" gives the physical address and length
			of the CX DBGC block.
- interrupts:		Interrupt mapping for GPU IRQ.
- interrupt-names:	String property to describe the name of the interrupt.
- qcom,id:		An integer used as an identification number for the device.
+76 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/of_device.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/io.h>
#include <soc/qcom/scm.h>

#include <linux/msm-bus-board.h>
@@ -1033,6 +1034,28 @@ adreno_ocmem_free(struct adreno_device *adreno_dev)
}
#endif

static void adreno_cx_dbgc_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,
					   "kgsl_3d0_cx_dbgc_memory");

	if (res == NULL)
		return;

	adreno_dev->cx_dbgc_base = res->start - device->reg_phys;
	adreno_dev->cx_dbgc_len = resource_size(res);
	adreno_dev->cx_dbgc_virt = devm_ioremap(device->dev,
					device->reg_phys +
						adreno_dev->cx_dbgc_base,
					adreno_dev->cx_dbgc_len);

	if (adreno_dev->cx_dbgc_virt == NULL)
		KGSL_DRV_WARN(device, "cx_dbgc ioremap failed\n");
}

static int adreno_probe(struct platform_device *pdev)
{
	struct kgsl_device *device;
@@ -1083,6 +1106,9 @@ static int adreno_probe(struct platform_device *pdev)
		return status;
	}

	/* Probe for the optional CX_DBGC block */
	adreno_cx_dbgc_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
@@ -2792,6 +2818,56 @@ static void adreno_gmu_regread(struct kgsl_device *device,
	rmb();
}

bool adreno_is_cx_dbgc_register(struct kgsl_device *device,
		unsigned int offsetwords)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	return adreno_dev->cx_dbgc_virt &&
		(offsetwords >= (adreno_dev->cx_dbgc_base >> 2)) &&
		(offsetwords < (adreno_dev->cx_dbgc_base +
				adreno_dev->cx_dbgc_len) >> 2);
}

void adreno_cx_dbgc_regread(struct kgsl_device *device,
	unsigned int offsetwords, unsigned int *value)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	unsigned int cx_dbgc_offset;

	if (!adreno_is_cx_dbgc_register(device, offsetwords))
		return;

	cx_dbgc_offset = (offsetwords << 2) - adreno_dev->cx_dbgc_base;
	*value = __raw_readl(adreno_dev->cx_dbgc_virt + cx_dbgc_offset);

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

void adreno_cx_dbgc_regwrite(struct kgsl_device *device,
	unsigned int offsetwords, unsigned int value)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	unsigned int cx_dbgc_offset;

	if (!adreno_is_cx_dbgc_register(device, offsetwords))
		return;

	cx_dbgc_offset = (offsetwords << 2) - adreno_dev->cx_dbgc_base;
	trace_kgsl_regwrite(device, offsetwords, value);

	/*
	 * ensure previous writes post before this one,
	 * i.e. act like normal writel()
	 */
	wmb();
	__raw_writel(value, adreno_dev->cx_dbgc_virt + cx_dbgc_offset);
}

/**
 * adreno_waittimestamp - sleep while waiting for the specified timestamp
 * @device - pointer to a KGSL device structure
+10 −0
Original line number Diff line number Diff line
@@ -437,6 +437,9 @@ struct adreno_device {
	unsigned int chipid;
	unsigned long gmem_base;
	unsigned long gmem_size;
	unsigned long cx_dbgc_base;
	unsigned int cx_dbgc_len;
	void __iomem *cx_dbgc_virt;
	const struct adreno_gpu_core *gpucore;
	struct adreno_firmware fw[2];
	size_t gpmu_cmds_size;
@@ -1063,6 +1066,13 @@ int adreno_efuse_read_u32(struct adreno_device *adreno_dev, unsigned int offset,
		unsigned int *val);
void adreno_efuse_unmap(struct adreno_device *adreno_dev);

bool adreno_is_cx_dbgc_register(struct kgsl_device *device,
		unsigned int offset);
void adreno_cx_dbgc_regread(struct kgsl_device *adreno_device,
		unsigned int offsetwords, unsigned int *value);
void adreno_cx_dbgc_regwrite(struct kgsl_device *device,
		unsigned int offsetwords, unsigned int value);

#define ADRENO_TARGET(_name, _id) \
static inline int adreno_is_##_name(struct adreno_device *adreno_dev) \
{ \