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

Commit b18514bd authored by Harshdeep Dhatt's avatar Harshdeep Dhatt Committed by Indira Biruduraju
Browse files

msm: kgsl: Remove the extra recovery hop



Currently, when we try to boot the gmu and it fails,
we force off the gmu gdsc followed by an inline
attempt to boot the gmu again. To do this, we go an
extra mile to do complex snapshot and power state
magic.

The same goal can be achieved by a simpler and
easier to maintain code path:

Set the state to KGSL_STATE_RESET upon gmu boot failure
so that the error path performs a RESET -> SLUMBER
transition. Here, we can reset the GMU so that next
SLUMBER exit can start afresh.

Change-Id: I4d3e75f40062e9fe5d71fe1e6010dfff75e09321
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent 84b56d3a
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -1534,6 +1534,9 @@ static int gmu_suspend(struct kgsl_device *device)
		regulator_set_mode(gmu->cx_gdsc, REGULATOR_MODE_NORMAL);
		regulator_set_mode(gmu->cx_gdsc, REGULATOR_MODE_NORMAL);


	dev_err(&gmu->pdev->dev, "Suspended GMU\n");
	dev_err(&gmu->pdev->dev, "Suspended GMU\n");

	clear_bit(GMU_FAULT, &device->gmu_core.flags);

	return 0;
	return 0;
}
}


+17 −53
Original line number Original line Diff line number Diff line
@@ -2747,7 +2747,6 @@ static int
_aware(struct kgsl_device *device)
_aware(struct kgsl_device *device)
{
{
	int status = 0;
	int status = 0;
	unsigned int state = device->state;


	switch (device->state) {
	switch (device->state) {
	case KGSL_STATE_RESET:
	case KGSL_STATE_RESET:
@@ -2774,65 +2773,23 @@ _aware(struct kgsl_device *device)
		kgsl_pwrscale_midframe_timer_cancel(device);
		kgsl_pwrscale_midframe_timer_cancel(device);
		break;
		break;
	case KGSL_STATE_SLUMBER:
	case KGSL_STATE_SLUMBER:
		/* if GMU already in FAULT */
		if (gmu_core_isenabled(device) &&
			test_bit(GMU_FAULT, &device->gmu_core.flags)) {
			status = -EINVAL;
			break;
		}

		status = kgsl_pwrctrl_enable(device);
		break;
	default:
		status = -EINVAL;
	}

	if (status) {
		if (gmu_core_isenabled(device)) {
			/* GMU hang recovery */
			kgsl_pwrctrl_set_state(device, KGSL_STATE_RESET);
			set_bit(GMU_FAULT, &device->gmu_core.flags);
		status = kgsl_pwrctrl_enable(device);
		status = kgsl_pwrctrl_enable(device);
			/* Cannot recover GMU failure GPU will not power on */
		if (status && gmu_core_isenabled(device))

			if (WARN_ONCE(status, "Failed to recover GMU\n")) {
				if (device->snapshot)
					device->snapshot->recovered = false;
			/*
			/*
				 * On recovery failure, we are clearing
			 * SLUMBER -> AWARE failed which means GMU boot failed.
				 * GMU_FAULT bit and also not keeping
			 * Make sure we reset the GMU while transitioning back
				 * the state as RESET to make sure any
			 * to SLUMBER.
				 * 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.
			 */
			 */
				kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
			kgsl_pwrctrl_set_state(device, KGSL_STATE_RESET);
				gmu_core_suspend(device);
				kgsl_pwrctrl_set_state(device, state);
			} else {
				if (device->snapshot)
					device->snapshot->recovered = true;
				kgsl_pwrctrl_set_state(device,
					KGSL_STATE_AWARE);
			}


			clear_bit(GMU_FAULT, &device->gmu_core.flags);
		break;
			return status;
	default:
		status = -EINVAL;
	}
	}


		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
	if (!status)
	} else {
		kgsl_pwrctrl_set_state(device, KGSL_STATE_AWARE);
		kgsl_pwrctrl_set_state(device, KGSL_STATE_AWARE);
	}

	return status;
	return status;
}
}


@@ -2921,6 +2878,13 @@ _slumber(struct kgsl_device *device)
		trace_gpu_frequency(0, 0);
		trace_gpu_frequency(0, 0);
		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER);
		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER);
		break;
		break;
	case KGSL_STATE_RESET:
		if (gmu_core_isenabled(device)) {
			 /* Reset the GMU if we failed to boot the GMU */
			gmu_core_suspend(device);
			kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER);
		}
		break;
	default:
	default:
		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
		break;
		break;