From 2b2f29cc506d61709ea81ff6bae1dcad548f5b6f Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Wed, 12 Aug 2020 14:35:11 -0600 Subject: [PATCH 1/2] msm: kgsl: Fix gmu fence error during slumber There can exist a race where we clear the A6XX_RBBM_INT_0_MASK register while the gpu is going into IFPC. Fix this by clearing this register before clearing the OOB. Change-Id: I08e9dbccbfdbee93ba7ef35fbbc673938ee033da Signed-off-by: Harshdeep Dhatt --- drivers/gpu/msm/adreno_a6xx_gmu.c | 4 +++- drivers/gpu/msm/adreno_a6xx_rgmu.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index 92bda0fbac27..3ac50f63588b 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -3069,10 +3069,12 @@ static int a6xx_power_off(struct adreno_device *adreno_dev) if (adreno_is_a630(adreno_dev)) a630_vbif_halt(adreno_dev); + adreno_irqctrl(adreno_dev, 0); + a6xx_gmu_oob_clear(device, oob_gpu); no_gx_power: - a6xx_disable_gpu_irq(adreno_dev); + kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); a6xx_gmu_power_off(adreno_dev); diff --git a/drivers/gpu/msm/adreno_a6xx_rgmu.c b/drivers/gpu/msm/adreno_a6xx_rgmu.c index 55f1ac8d9c3e..a4b5a4daa8af 100644 --- a/drivers/gpu/msm/adreno_a6xx_rgmu.c +++ b/drivers/gpu/msm/adreno_a6xx_rgmu.c @@ -1056,6 +1056,8 @@ static int a6xx_power_off(struct adreno_device *adreno_dev) /* Save physical performance counter values before GPU power down*/ adreno_perfcounter_save(adreno_dev); + adreno_irqctrl(adreno_dev, 0); + a6xx_rgmu_prepare_stop(device); a6xx_rgmu_oob_clear(device, oob_gpu); @@ -1067,7 +1069,7 @@ no_gx_power: adreno_wait_for_halt_ack(device, ADRENO_REG_GBIF_HALT_ACK, A6XX_GBIF_CLIENT_HALT_MASK); - a6xx_disable_gpu_irq(adreno_dev); + kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); a6xx_rgmu_power_off(adreno_dev); From 65172415d18c437a8e1a4e3bd7aecb74786663ee Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Sat, 8 Aug 2020 14:43:24 -0600 Subject: [PATCH 2/2] msm: kgsl: Add suspend_context to gmu based targets This needs to be explicitly added to the new slumber entry sequence for gmu and rgmu based targets. Change-Id: I582067d065b1c58cab3d1d149292dd94e182bd66 Signed-off-by: Harshdeep Dhatt --- drivers/gpu/msm/adreno.c | 2 +- drivers/gpu/msm/adreno.h | 11 +++++++++++ drivers/gpu/msm/adreno_a6xx_gmu.c | 2 ++ drivers/gpu/msm/adreno_a6xx_rgmu.c | 2 ++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index ab4aa761f4c5..b4e8bbcea393 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -2927,7 +2927,7 @@ static int adreno_drain(struct kgsl_device *device) } /* Caller must hold the device mutex. */ -static int adreno_suspend_context(struct kgsl_device *device) +int adreno_suspend_context(struct kgsl_device *device) { /* process any profiling results that are available */ adreno_profile_process_results(ADRENO_DEVICE(device)); diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index c5ad9d41038d..5a4e39d1d075 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -1912,4 +1912,15 @@ void adreno_clear_dcvs_counters(struct adreno_device *adreno_dev); * Set the gmu fault and take snapshot when we hit a gmu fault */ void gmu_fault_snapshot(struct kgsl_device *device); + +/** + * adreno_suspend_context - Make sure device is idle + * @device: Pointer to the kgsl device + * + * This function processes the profiling results and checks if the + * device is idle so that it can be turned off safely + * + * Return: 0 on success or negative error on failure + */ +int adreno_suspend_context(struct kgsl_device *device); #endif /*__ADRENO_H */ diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index 3ac50f63588b..45ef842e329b 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -3048,6 +3048,8 @@ static int a6xx_power_off(struct adreno_device *adreno_dev) trace_kgsl_pwr_request_state(device, KGSL_STATE_SLUMBER); + adreno_suspend_context(device); + ret = a6xx_gmu_oob_set(device, oob_gpu); if (ret) { a6xx_gmu_oob_clear(device, oob_gpu); diff --git a/drivers/gpu/msm/adreno_a6xx_rgmu.c b/drivers/gpu/msm/adreno_a6xx_rgmu.c index a4b5a4daa8af..dd312269c080 100644 --- a/drivers/gpu/msm/adreno_a6xx_rgmu.c +++ b/drivers/gpu/msm/adreno_a6xx_rgmu.c @@ -1042,6 +1042,8 @@ static int a6xx_power_off(struct adreno_device *adreno_dev) trace_kgsl_pwr_request_state(device, KGSL_STATE_SLUMBER); + adreno_suspend_context(device); + ret = a6xx_rgmu_oob_set(device, oob_gpu); if (ret) { a6xx_rgmu_oob_clear(device, oob_gpu);