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

Commit 49796115 authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Add qcom,gpu-quirk-two-pass-use-wfi



Add a quirk to set the TWOPASSUSEWFI bit in A5XX_PC_DBG_ECO_CNTL on
A5XX targets if the if the PFP firmware version is 0x77 or newer to
prevent corruption in certain use cases.

Targets that need the quirk will set the boolean in the DT.

Change-Id: Ic0dedbad9d2e0b59b1cc7fed3c2ce0cbdd5f2f48
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent 09deb55f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -116,6 +116,10 @@ Optional Properties:
				Force the GPU to use 32 bit data sizes even if
				it is capable of doing 64 bit.

- qcom,gpu-quirk-two-pass-use-wfi:
				Signal the GPU to set Set TWOPASSUSEWFI bit in
				A5XX_PC_DBG_ECO_CNTL (5XX only)

The following properties are optional as collecting data via coresight might
not be supported for every chipset. The documentation for coresight
properties can be found in:
+16 −0
Original line number Diff line number Diff line
@@ -916,11 +916,19 @@ static inline struct adreno_device *adreno_get_dev(struct platform_device *pdev)
	return of_id ? (struct adreno_device *) of_id->data : NULL;
}

static struct {
	unsigned int quirk;
	const char *prop;
} adreno_quirks[] = {
	 { ADRENO_QUIRK_TWO_PASS_USE_WFI, "qcom,gpu-quirk-two-pass-use-wfi" },
};

static int adreno_of_get_pdata(struct adreno_device *adreno_dev)
{
	struct platform_device *pdev = adreno_dev->dev.pdev;
	struct kgsl_device_platform_data *pdata = NULL;
	int ret = -EINVAL;
	int i;

	if (of_property_read_string(pdev->dev.of_node, "label", &pdev->name)) {
		KGSL_CORE_ERR("Unable to read 'label'\n");
@@ -936,6 +944,14 @@ static int adreno_of_get_pdata(struct adreno_device *adreno_dev)
		goto err;
	}

	/* Set up quirks and other boolean options */

	for (i = 0; i < ARRAY_SIZE(adreno_quirks); i++) {
		if (of_property_read_bool(pdev->dev.of_node,
			adreno_quirks[i].prop))
			adreno_dev->quirks |= adreno_quirks[i].quirk;
	}

	/* pwrlevel Data */
	ret = adreno_of_get_pwrlevels(pdev->dev.of_node, adreno_dev, pdata);
	if (ret)
+14 −0
Original line number Diff line number Diff line
@@ -64,6 +64,12 @@
#define ADRENO_FEATURE(_dev, _bit) \
	((_dev)->gpucore->features & (_bit))

/**
 * ADRENO_QUIRK - return true if the specified quirk is required by the GPU
 */
#define ADRENO_QUIRK(_dev, _bit) \
	((_dev)->quirks & (_bit))

/*
 * ADRENO_PREEMPT_STYLE - return preemption style
 */
@@ -105,6 +111,13 @@
/* Sync between SMMU operations and power collapse */
#define ADRENO_SYNC_SMMU_PC BIT(10)

/*
 * Adreno GPU quirks - control bits for various workarounds
 */

/* Set TWOPASSUSEWFI in PC_DBG_ECO_CNTL (5XX) */
#define ADRENO_QUIRK_TWO_PASS_USE_WFI BIT(0)

/* Flags to control command packet settings */
#define KGSL_CMD_FLAGS_NONE             0
#define KGSL_CMD_FLAGS_PMODE		BIT(0)
@@ -354,6 +367,7 @@ struct adreno_device {
	bool capturescript_working;

	unsigned int speed_bin;
	unsigned int quirks;
};

/**
+11 −5
Original line number Diff line number Diff line
@@ -1739,7 +1739,7 @@ static void a5xx_start(struct adreno_device *adreno_dev)
	struct kgsl_device *device = &adreno_dev->dev;
	struct kgsl_iommu *iommu = device->mmu.priv;
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	uint val = 0, i;
	unsigned int i;
	struct adreno_ringbuffer *rb;
	uint64_t def_ttbr0;
	uint32_t contextidr;
@@ -1866,10 +1866,16 @@ static void a5xx_start(struct adreno_device *adreno_dev)
	 * LD combine, bit[25] of SP_DBG_ECO_CNTL (sp chicken bit[17]) need to
	 * be set to 1, default is 0(enable)
	 */
	if (adreno_is_a530v1(adreno_dev)) {
		kgsl_regread(device, A5XX_SP_DBG_ECO_CNTL, &val);
		val = (val | 1 << 25);
		kgsl_regwrite(device, A5XX_SP_DBG_ECO_CNTL, val);
	if (adreno_is_a530v1(adreno_dev))
		kgsl_regrmw(device, A5XX_SP_DBG_ECO_CNTL, 0, (1 << 25));

	if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_TWO_PASS_USE_WFI)) {
		/*
		 * Set TWOPASSUSEWFI in A5XX_PC_DBG_ECO_CNTL for
		 * microcodes after v77
		 */
		if ((adreno_compare_pfp_version(adreno_dev, 0x5FF077) >= 0))
			kgsl_regrmw(device, A5XX_SP_DBG_ECO_CNTL, 0, (1 << 8));
	}

	/* Set the USE_RETENTION_FLOPS chicken bit */
+11 −0
Original line number Diff line number Diff line
@@ -511,6 +511,17 @@ static inline void kgsl_regwrite(struct kgsl_device *device,
	device->ftbl->regwrite(device, offsetwords, value);
}

static inline void kgsl_regrmw(struct kgsl_device *device,
		unsigned int offsetwords,
		unsigned int mask, unsigned int bits)
{
	unsigned int val = 0;

	device->ftbl->regread(device, offsetwords, &val);
	val &= ~mask;
	device->ftbl->regwrite(device, offsetwords, val | bits);
}

static inline int kgsl_idle(struct kgsl_device *device)
{
	return device->ftbl->idle(device);