msm: kgsl: Handle the very first gmu boot failure

The very first boot starts from the INIT state. If the
gmu fails to boot here, set the state to KGSL_STATE_RESET
to effect a RESET -> INIT transition where we reset the
GMU.

Change-Id: I0fddf745d299b855aab0c1989997dcab5e77954a
Signed-off-by: Harshdeep Dhatt <hdhatt@codeaurora.org>
This commit is contained in:
Harshdeep Dhatt 2019-08-08 20:58:55 -06:00
commit b35f0ac1f7

View file

@ -1695,13 +1695,23 @@ static int _init(struct kgsl_device *device)
int status = 0;
switch (device->state) {
case KGSL_STATE_RESET:
if (gmu_core_isenabled(device)) {
/*
* If we fail a INIT -> AWARE transition, we will
* transition back to INIT. However, we must hard reset
* the GMU as we go back to INIT. This is done by
* forcing a RESET -> INIT transition.
*/
gmu_core_suspend(device);
kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
}
break;
case KGSL_STATE_NAP:
/* Force power on to do the stop */
status = kgsl_pwrctrl_enable(device);
/* fall through */
case KGSL_STATE_ACTIVE:
/* fall through */
case KGSL_STATE_RESET:
kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
del_timer_sync(&device->idle_timer);
kgsl_pwrscale_midframe_timer_cancel(device);
@ -1813,12 +1823,6 @@ _aware(struct kgsl_device *device)
status = gmu_core_start(device);
break;
case KGSL_STATE_INIT:
/* 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;
/* The following 3 cases shouldn't occur, but don't panic. */
@ -1832,20 +1836,23 @@ _aware(struct kgsl_device *device)
break;
case KGSL_STATE_SLUMBER:
status = kgsl_pwrctrl_enable(device);
if (status && gmu_core_isenabled(device))
/*
* SLUMBER -> AWARE failed which means GMU boot failed.
* Make sure we reset the GMU while transitioning back
* to SLUMBER.
*/
kgsl_pwrctrl_set_state(device, KGSL_STATE_RESET);
break;
default:
status = -EINVAL;
}
if (!status)
if (status && gmu_core_isenabled(device))
/*
* If a SLUMBER/INIT -> AWARE fails, we transition back to
* SLUMBER/INIT state. We must hard reset the GMU while
* transitioning back to SLUMBER/INIT. A RESET -> AWARE
* transition is different. It happens when dispatcher is
* attempting reset/recovery as part of fault handling. If it
* fails, we should still transition back to RESET in case
* we want to attempt another reset/recovery.
*/
kgsl_pwrctrl_set_state(device, KGSL_STATE_RESET);
else
kgsl_pwrctrl_set_state(device, KGSL_STATE_AWARE);
return status;