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

Commit 1d7e595f authored by George Shen's avatar George Shen Committed by Gerrit - the friendly Code Review server
Browse files

msm: kgsl: GMU OOB set and clear calls shall be paired



Unbalanced OOB set and clear function calls may cause undefined
GMU behavior and result in system failure.

Change-Id: Idc1aa69787726de701fe32a9578bbbe158d271a6
Signed-off-by: default avatarGeorge Shen <sqiao@codeaurora.org>
Signed-off-by: default avatarUrvashi Agrawal <urvaagra@codeaurora.org>
parent a1ba2bba
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -1848,11 +1848,6 @@ static int _adreno_start(struct adreno_device *adreno_dev)

error_mmu_off:
	kgsl_mmu_stop(&device->mmu);
	if (gpudev->oob_clear &&
			ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_HFI_USE_REG)) {
		gpudev->oob_clear(adreno_dev,
				OOB_BOOT_SLUMBER_CLEAR_MASK);
	}

error_pwr_off:
	/* set the state back to original state */
+16 −3
Original line number Diff line number Diff line
@@ -63,6 +63,9 @@ static const struct adreno_vbif_platform a6xx_vbif_platforms[] = {
	{ adreno_is_a615, a615_gbif },
};


static unsigned long a6xx_oob_state_bitmask;

struct kgsl_hwcg_reg {
	unsigned int off;
	unsigned int val;
@@ -1455,7 +1458,7 @@ static int a6xx_oob_set(struct adreno_device *adreno_dev,
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	int ret = 0;

	if (!kgsl_gmu_isenabled(device))
	if (!kgsl_gmu_isenabled(device) || !clear_mask)
		return 0;

	kgsl_gmu_regwrite(device, A6XX_GMU_HOST2GMU_INTR_SET, set_mask);
@@ -1471,6 +1474,8 @@ static int a6xx_oob_set(struct adreno_device *adreno_dev,

	kgsl_gmu_regwrite(device, A6XX_GMU_GMU2HOST_INTR_CLR, clear_mask);

	set_bit((fls(clear_mask) - 1), &a6xx_oob_state_bitmask);

	trace_kgsl_gmu_oob_set(set_mask);
	return ret;
}
@@ -1485,10 +1490,15 @@ static inline void a6xx_oob_clear(struct adreno_device *adreno_dev,
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);

	if (!kgsl_gmu_isenabled(device))
	if (!kgsl_gmu_isenabled(device) || !clear_mask)
		return;

	kgsl_gmu_regwrite(device, A6XX_GMU_HOST2GMU_INTR_SET, clear_mask);
	if (test_and_clear_bit(fls(clear_mask) - 1,
				&a6xx_oob_state_bitmask))
		kgsl_gmu_regwrite(device,
			A6XX_GMU_HOST2GMU_INTR_SET,
			clear_mask);

	trace_kgsl_gmu_oob_clear(clear_mask);
}

@@ -2314,6 +2324,9 @@ static int a6xx_rpmh_gpu_pwrctrl(struct adreno_device *adreno_dev,
		ret = a6xx_gmu_suspend(device);
		break;
	case GMU_FW_STOP:
		if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_HFI_USE_REG))
			a6xx_oob_clear(adreno_dev,
					OOB_BOOT_SLUMBER_CLEAR_MASK);
		ret = a6xx_rpmh_power_off_gpu(device);
		break;
	case GMU_DCVS_NOHFI: