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

Commit 31bb0355 authored by Deepak Kumar's avatar Deepak Kumar
Browse files

msm: kgsl: Suspend GMU on recovery failure



On GMU recovery failure, kgsl clears the GMU_FAULT bit
and also restores the kgsl state to orginal state from
which GMU/GPU wake up was triggered to make sure any
attempt to wake GMU/GPU after this is treated as a fresh
start/hard reset. But on recovery failure, GMU HS, clocks
and IRQ are still ON/enabled because of which any attempt
of GMU/GPU wakeup results in multiple warnings from GMU
start as HS, clocks and IRQ are still ON while doing a
fresh start i.e. wake up from SLUMBER.

Suspend the GMU on recovery failure to make sure next
attempt to wake up GMU/GPU is indeed a fresh start/
hard reset.

Change-Id: Ib0ffa8e19bbcf6ace1c438ec04275f7aabddce1b
Signed-off-by: default avatarDeepak Kumar <dkumar@codeaurora.org>
parent 9fed2226
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -1318,7 +1318,7 @@ static int gmu_disable_gdsc(struct gmu_device *gmu)
	return -ETIMEDOUT;
}

static int gmu_suspend(struct kgsl_device *device)
int gmu_suspend(struct kgsl_device *device)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
@@ -1404,6 +1404,7 @@ int gmu_start(struct kgsl_device *device)
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct gmu_device *gmu = &device->gmu;
	unsigned int boot_state = GMU_WARM_BOOT;

	switch (device->state) {
	case KGSL_STATE_INIT:
@@ -1440,12 +1441,21 @@ int gmu_start(struct kgsl_device *device)
		gmu_enable_clks(gmu);
		gmu_irq_enable(device);

		/*
		 * If unrecovered is set that means last
		 * wakeup from SLUMBER state failed. Use GMU
		 * and HFI boot state as COLD as this is a
		 * boot after RESET.
		 */
		if (gmu->unrecovered)
			boot_state = GMU_COLD_BOOT;

		ret = gpudev->rpmh_gpu_pwrctrl(adreno_dev, GMU_FW_START,
				GMU_WARM_BOOT, 0);
				boot_state, 0);
		if (ret)
			goto error_gmu;

		ret = hfi_start(gmu, GMU_WARM_BOOT);
		ret = hfi_start(gmu, boot_state);
		if (ret)
			goto error_gmu;

@@ -1491,6 +1501,8 @@ int gmu_start(struct kgsl_device *device)
		break;
	}

	/* Clear unrecovered as GMU start is successful */
	gmu->unrecovered = false;
	return ret;

error_gmu:
+3 −0
Original line number Diff line number Diff line
@@ -212,6 +212,7 @@ enum gpu_idle_level {
 * @ccl: CNOC BW scaling client
 * @idle_level: Minimal GPU idle power level
 * @fault_count: GMU fault count
 * @unrecovered: Indicates whether GMU recovery failed or not
 */
struct gmu_device {
	unsigned int ver;
@@ -246,6 +247,7 @@ struct gmu_device {
	unsigned int ccl;
	unsigned int idle_level;
	unsigned int fault_count;
	bool unrecovered;
};

void gmu_snapshot(struct kgsl_device *device);
@@ -255,6 +257,7 @@ void gmu_remove(struct kgsl_device *device);
int allocate_gmu_image(struct gmu_device *gmu, unsigned int size);
int gmu_start(struct kgsl_device *device);
void gmu_stop(struct kgsl_device *device);
int gmu_suspend(struct kgsl_device *device);
int gmu_dcvs_set(struct gmu_device *gmu, unsigned int gpu_pwrlevel,
		unsigned int bus_level);
#endif /* __KGSL_GMU_H */
+19 −0
Original line number Diff line number Diff line
@@ -2798,6 +2798,25 @@ _aware(struct kgsl_device *device)
				WARN_ONCE(1, "Failed to recover GMU\n");
				if (device->snapshot)
					device->snapshot->recovered = false;
				/*
				 * On recovery failure, we are clearing
				 * GMU_FAULT bit and also not keeping
				 * the state as RESET to make sure any
				 * attempt to wake GMU/GPU after this
				 * is treated as a fresh start. But on
				 * recovery failure, GMU HS, clocks and
				 * IRQs are still ON/enabled because of
				 * which next GMU/GPU wakeup results in
				 * multiple warnings from GMU start as HS,
				 * clocks and IRQ were ON while doing a
				 * fresh start i.e. wake from SLUMBER.
				 *
				 * Suspend the GMU on recovery failure
				 * to make sure next attempt to wake up
				 * GMU/GPU is indeed a fresh start.
				 */
				gmu_suspend(device);
				gmu->unrecovered = true;
				kgsl_pwrctrl_set_state(device, state);
			} else {
				if (device->snapshot)