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: Hui Li <hul@codeaurora.org>
This commit is contained in:
Hui Li 2021-04-14 13:44:03 +08:00 • committed by Gerrit - the friendly Code Review server
commit fdbcd27bd3
2 changed files with 21 additions and 20 deletions

View file

@ -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;

View file

@ -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");