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

Commit 37331aa1 authored by Suman Tatiraju's avatar Suman Tatiraju
Browse files

msm: kgsl: report an error if gfx power rail cannot be turned on



Make sure we return an error to the caller if the power rail cannot
be turned on during gpu start.

Change-Id: Ifeead23d7dd1664ce172a8be3e0a2215350b0839
Signed-off-by: default avatarSuman Tatiraju <sumant@codeaurora.org>
parent 5698cb80
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -1698,9 +1698,6 @@ static int adreno_init(struct kgsl_device *device)
	int i;
	int ret;

	/* Make a high priority workqueue for starting the GPU */
	adreno_wq = alloc_workqueue("adreno", 0, 1);

	kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);
	/*
	 * initialization only needs to be done once initially until
@@ -1710,8 +1707,12 @@ static int adreno_init(struct kgsl_device *device)
		return 0;

	/* Power up the device */
	kgsl_pwrctrl_enable(device);
	ret = kgsl_pwrctrl_enable(device);
	if (ret)
		return ret;

	/* Make a high priority workqueue for starting the GPU */
	adreno_wq = alloc_workqueue("adreno", 0, 1);

	/* Identify the specific GPU */
	adreno_identify_gpu(adreno_dev);
@@ -1825,7 +1826,9 @@ static int _adreno_start(struct adreno_device *adreno_dev)
	adreno_clear_gpu_fault(adreno_dev);

	/* Power up the device */
	kgsl_pwrctrl_enable(device);
	status = kgsl_pwrctrl_enable(device);
	if (status)
		goto error_rail_off;

	/* Set the bit to indicate that we've just powered on */
	set_bit(ADRENO_DEVICE_PWRON, &adreno_dev->priv);
@@ -1887,6 +1890,7 @@ error_mmu_off:

error_clk_off:
	kgsl_pwrctrl_disable(device);
error_rail_off:
	/* set the state back to original state */
	kgsl_pwrctrl_change_state(device, state);

+33 −12
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ static struct clk_pair clks[KGSL_MAX_CLKS] = {
static void kgsl_pwrctrl_clk(struct kgsl_device *device, int state,
					int requested_state);
static void kgsl_pwrctrl_axi(struct kgsl_device *device, int state);
static void kgsl_pwrctrl_pwrrail(struct kgsl_device *device, int state);
static int kgsl_pwrctrl_pwrrail(struct kgsl_device *device, int state);
static void kgsl_pwrctrl_set_state(struct kgsl_device *device,
				unsigned int state);
static void kgsl_pwrctrl_request_state(struct kgsl_device *device,
@@ -875,12 +875,14 @@ static void kgsl_pwrctrl_axi(struct kgsl_device *device, int state)
	}
}

static void kgsl_pwrctrl_pwrrail(struct kgsl_device *device, int state)
static int kgsl_pwrctrl_pwrrail(struct kgsl_device *device, int state)
{
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	int status_gpu = 0;
	int status_cx = 0;

	if (test_bit(KGSL_PWRFLAGS_POWER_ON, &pwr->ctrl_flags))
		return;
		return 0;

	if (state == KGSL_PWRFLAGS_OFF) {
		if (test_and_clear_bit(KGSL_PWRFLAGS_POWER_ON,
@@ -894,25 +896,39 @@ static void kgsl_pwrctrl_pwrrail(struct kgsl_device *device, int state)
	} else if (state == KGSL_PWRFLAGS_ON) {
		if (!test_and_set_bit(KGSL_PWRFLAGS_POWER_ON,
			&pwr->power_flags)) {
			trace_kgsl_rail(device, state);
			if (pwr->gpu_reg) {
				int status = regulator_enable(pwr->gpu_reg);
				if (status)
				status_gpu = regulator_enable(pwr->gpu_reg);
				if (status_gpu)
					KGSL_DRV_ERR(device,
							"core regulator_enable "
							"failed: %d\n",
							status);
							status_gpu);
			}
			if (pwr->gpu_cx) {
				int status = regulator_enable(pwr->gpu_cx);
				if (status)
				status_cx = regulator_enable(pwr->gpu_cx);
				if (status_cx)
					KGSL_DRV_ERR(device,
							"cx regulator_enable "
							"failed: %d\n",
							status);
							status_cx);
			}
			if (status_gpu || status_cx) {
				/*
				 * If only one rail succeeded, disable it
				 * before we bail out.
				 */
				if (pwr->gpu_reg && !status_gpu)
					regulator_disable(pwr->gpu_reg);
				if (pwr->gpu_cx && !status_cx)
					regulator_disable(pwr->gpu_cx);
				clear_bit(KGSL_PWRFLAGS_POWER_ON,
					&pwr->power_flags);
			} else
				trace_kgsl_rail(device, state);
		}
	}

	return status_gpu || status_cx;
}

void kgsl_pwrctrl_irq(struct kgsl_device *device, int state)
@@ -1465,10 +1481,11 @@ int kgsl_pwrctrl_change_state(struct kgsl_device *device, int state)
}
EXPORT_SYMBOL(kgsl_pwrctrl_change_state);

void kgsl_pwrctrl_enable(struct kgsl_device *device)
int kgsl_pwrctrl_enable(struct kgsl_device *device)
{
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	int level;
	int status;

	if (pwr->wakeup_maxpwrlevel) {
		level = pwr->max_pwrlevel;
@@ -1480,9 +1497,13 @@ void kgsl_pwrctrl_enable(struct kgsl_device *device)
		kgsl_pwrctrl_pwrlevel_change(device, level);

	/* Order pwrrail/clk sequence based upon platform */
	kgsl_pwrctrl_pwrrail(device, KGSL_PWRFLAGS_ON);
	status = kgsl_pwrctrl_pwrrail(device, KGSL_PWRFLAGS_ON);
	if (status)
		return status;
	kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON, KGSL_STATE_ACTIVE);
	kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON);

	return status;
}
EXPORT_SYMBOL(kgsl_pwrctrl_enable);

+1 −1
Original line number Diff line number Diff line
@@ -126,7 +126,7 @@ void kgsl_pwrctrl_buslevel_update(struct kgsl_device *device,
	bool on);
int kgsl_pwrctrl_init_sysfs(struct kgsl_device *device);
void kgsl_pwrctrl_uninit_sysfs(struct kgsl_device *device);
void kgsl_pwrctrl_enable(struct kgsl_device *device);
int kgsl_pwrctrl_enable(struct kgsl_device *device);
void kgsl_pwrctrl_disable(struct kgsl_device *device);
bool kgsl_pwrctrl_isenabled(struct kgsl_device *device);
int kgsl_pwrctrl_change_state(struct kgsl_device *device, int state);