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

Commit eeaec1bf authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Restart a6xx gpu only once"

parents 9ba8f095 76b95281
Loading
Loading
Loading
Loading
+8 −22
Original line number Diff line number Diff line
@@ -1128,8 +1128,7 @@ static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev)
static int a6xx_reset(struct kgsl_device *device, int fault)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	int ret = -EINVAL;
	int i = 0;
	int ret;

	/* Use the regular reset sequence for No GMU */
	if (!gmu_core_isenabled(device))
@@ -1141,33 +1140,20 @@ static int a6xx_reset(struct kgsl_device *device, int fault)
	/* since device is officially off now clear start bit */
	clear_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv);

	/* Keep trying to start the device until it works */
	for (i = 0; i < NUM_TIMES_RESET_RETRY; i++) {
	ret = adreno_start(device, 0);
		if (!ret)
			break;

		msleep(20);
	}

	if (ret)
		return ret;

	if (i != 0)
		dev_warn(device->dev,
			      "Device hard reset tried %d tries\n", i);
	kgsl_pwrctrl_change_state(device, KGSL_STATE_ACTIVE);

	/*
	 * If active_cnt is non-zero then the system was active before
	 * going into a reset - put it back in that state
	 * If active_cnt is zero, there is no need to keep the GPU active. So,
	 * we should transition to SLUMBER.
	 */
	if (!atomic_read(&device->active_cnt))
		kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER);

	if (atomic_read(&device->active_cnt))
		kgsl_pwrctrl_change_state(device, KGSL_STATE_ACTIVE);
	else
		kgsl_pwrctrl_change_state(device, KGSL_STATE_NAP);

	return ret;
	return 0;
}

static void a6xx_cp_hw_err_callback(struct adreno_device *adreno_dev, int bit)
+3 −0
Original line number Diff line number Diff line
@@ -1542,6 +1542,9 @@ static int gmu_suspend(struct kgsl_device *device)
		regulator_set_mode(gmu->cx_gdsc, REGULATOR_MODE_NORMAL);

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

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

	return 0;
}

+32 −61
Original line number Diff line number Diff line
@@ -2635,12 +2635,22 @@ 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);
	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);
@@ -2747,7 +2757,6 @@ static int
_aware(struct kgsl_device *device)
{
	int status = 0;
	unsigned int state = device->state;

	switch (device->state) {
	case KGSL_STATE_RESET:
@@ -2757,12 +2766,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. */
@@ -2774,65 +2777,26 @@ _aware(struct kgsl_device *device)
		kgsl_pwrscale_midframe_timer_cancel(device);
		break;
	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);
			/* Cannot recover GMU failure GPU will not power on */

			if (WARN_ONCE(status, "Failed to recover GMU\n")) {
				if (device->snapshot)
					device->snapshot->recovered = false;
	if (status && gmu_core_isenabled(device))
	/*
				 * 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.
	 * 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_irq(device, KGSL_PWRFLAGS_OFF);
				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);
			return status;
		}

		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
	} else {
		kgsl_pwrctrl_set_state(device, KGSL_STATE_RESET);
	else
		kgsl_pwrctrl_set_state(device, KGSL_STATE_AWARE);
	}

	return status;
}

@@ -2921,6 +2885,13 @@ _slumber(struct kgsl_device *device)
		trace_gpu_frequency(0, 0);
		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER);
		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:
		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
		break;