From a373fb659f80d41d07bee328738836a8a6b1f64c Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Thu, 11 Jul 2019 13:46:38 +0530 Subject: [PATCH] msm: kgsl: Ensure GPU gdscs are off in SLUMBER and during hard reset Poll gdsc status to ensure it's off before transitioning to SLUMBER and during hard reset. This is needed to make sure that next wake-up is indeed a fresh start and doesn't fail (especially during recovery from fault) because of stale state. Change-Id: I064038c59315a9b8aa10c7dd4a45354f0f5e5447 Signed-off-by: Deepak Kumar --- drivers/gpu/msm/adreno.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index e30933ce93e6..3afbb50e60d3 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -3971,6 +3971,9 @@ static void adreno_iommu_sync(struct kgsl_device *device, bool sync) struct scm_desc desc = {0}; int ret; + if (!ADRENO_QUIRK(ADRENO_DEVICE(device), ADRENO_QUIRK_IOMMU_SYNC)) + return; + if (sync == true) { mutex_lock(&kgsl_mmu_sync); desc.args[0] = true; @@ -3987,25 +3990,29 @@ static void adreno_iommu_sync(struct kgsl_device *device, bool sync) } } -static void _regulator_disable(struct kgsl_regulator *regulator, bool poll) +static void +_regulator_disable(struct kgsl_regulator *regulator, unsigned int timeout) { - unsigned long wait_time = jiffies + msecs_to_jiffies(200); + unsigned long wait_time; if (IS_ERR_OR_NULL(regulator->reg)) return; regulator_disable(regulator->reg); - if (poll == false) - return; + wait_time = jiffies + msecs_to_jiffies(timeout); + /* Poll for regulator status to ensure it's OFF */ while (!time_after(jiffies, wait_time)) { if (!regulator_is_enabled(regulator->reg)) return; - cpu_relax(); + usleep_range(10, 100); } - KGSL_CORE_ERR("regulator '%s' still on after 200ms\n", regulator->name); + if (!regulator_is_enabled(regulator->reg)) + return; + + KGSL_CORE_ERR("regulator '%s' disable timed out\n", regulator->name); } static void adreno_regulator_disable_poll(struct kgsl_device *device) @@ -4013,18 +4020,13 @@ static void adreno_regulator_disable_poll(struct kgsl_device *device) struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct kgsl_pwrctrl *pwr = &device->pwrctrl; int i; - - /* Fast path - hopefully we don't need this quirk */ - if (!ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_IOMMU_SYNC)) { - for (i = KGSL_MAX_REGULATORS - 1; i >= 0; i--) - _regulator_disable(&pwr->regulators[i], false); - return; - } + unsigned int timeout = + ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_IOMMU_SYNC) ? 200 : 5000; adreno_iommu_sync(device, true); - for (i = 0; i < KGSL_MAX_REGULATORS; i++) - _regulator_disable(&pwr->regulators[i], true); + for (i = KGSL_MAX_REGULATORS - 1; i >= 0; i--) + _regulator_disable(&pwr->regulators[i], timeout); adreno_iommu_sync(device, false); }