From fdbcd27bd39eea2ce0504e08387a3456871eaf51 Mon Sep 17 00:00:00 2001 From: Hui Li Date: Wed, 14 Apr 2021 13:44:03 +0800 Subject: [PATCH] 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 --- drivers/gpu/msm/adreno_a6xx.c | 35 ++++++++++++++++++------------- drivers/gpu/msm/adreno_a6xx_gmu.c | 6 ------ 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c index 3e083976592c..82d5368e96f7 100644 --- a/drivers/gpu/msm/adreno_a6xx.c +++ b/drivers/gpu/msm/adreno_a6xx.c @@ -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; diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index 4601c83ce447..14a9383ddce6 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -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");