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

Commit fdbcd27b authored by Hui Li's avatar Hui Li Committed by Gerrit - the friendly Code Review server
Browse files

msm: kgsl: set regulator mode before disable it on a640/a680



For a640/a680, we need to actually disable CX GDSC instead of
just return a enable state, the GMU oob set will timeout while
doing gmu idle check, therefor to really turn off CX GDSC
requires to set regulator mode first, and there are several
places to disable cx gdsc, move the set mode to
a6xx_cx_regulator_disable_wait.

Change-Id: Idb7d1b75f17426cc5cb6bb8054b2c2c4400f3db2
Signed-off-by: default avatarHui Li <hul@codeaurora.org>
parent 8f48489b
Loading
Loading
Loading
Loading
+21 −14
Original line number Diff line number Diff line
@@ -314,28 +314,15 @@ static unsigned int __get_gmu_wfi_config(struct adreno_device *adreno_dev)
	return 0x00000000;
}

bool a6xx_cx_regulator_disable_wait(struct regulator *reg,
static bool __disable_cx_regulator_wait(struct regulator *reg,
				struct kgsl_device *device, u32 timeout)
{
	ktime_t tout = ktime_add_us(ktime_get(), timeout * 1000);
	unsigned int val;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);

	if (IS_ERR_OR_NULL(reg))
		return true;

	regulator_disable(reg);

	/*
	 * Check logical enable state of CX GDSC using regulator_is_enabled()
	 * instead of checking physical state by CX_GDSCR register because
	 * in a640 and a680, CX_GDSCR will not be disabled from kernel. It can
	 * be turned off by AOP for CX Power collapse.
	 */
	if (adreno_is_a640(adreno_dev) || adreno_is_a680(adreno_dev))
		return !(regulator_is_enabled(gmu->cx_gdsc));

	for (;;) {
		if (adreno_is_a619_holi(adreno_dev))
			adreno_read_gmu_wrapper(adreno_dev,
@@ -360,6 +347,26 @@ bool a6xx_cx_regulator_disable_wait(struct regulator *reg,
	}
}

bool a6xx_cx_regulator_disable_wait(struct regulator *reg,
				struct kgsl_device *device, u32 timeout)
{
	bool ret;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	if (IS_ERR_OR_NULL(reg))
		return true;

	if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_CX_GDSC))
		regulator_set_mode(reg, REGULATOR_MODE_IDLE);

	ret = __disable_cx_regulator_wait(reg, device, timeout);

	if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_CX_GDSC))
		regulator_set_mode(reg, REGULATOR_MODE_NORMAL);

	return ret;
}

static void set_holi_sptprac_clock(struct adreno_device *adreno_dev, bool enable)
{
	u32 val = 0;
+0 −6
Original line number Diff line number Diff line
@@ -1761,15 +1761,9 @@ void a6xx_gmu_suspend(struct adreno_device *adreno_dev)

	clk_bulk_disable_unprepare(gmu->num_clks, gmu->clks);

	if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_CX_GDSC))
		regulator_set_mode(gmu->cx_gdsc, REGULATOR_MODE_IDLE);

	if (!a6xx_cx_regulator_disable_wait(gmu->cx_gdsc, device, 5000))
		dev_err(&gmu->pdev->dev, "GMU CX gdsc off timeout\n");

	if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_CX_GDSC))
		regulator_set_mode(gmu->cx_gdsc, REGULATOR_MODE_NORMAL);

	a6xx_rdpm_cx_freq_update(gmu, 0);

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