From dbfff92937663ab71c12988f80340093b706b12b Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Sat, 8 Aug 2020 13:58:35 -0600 Subject: [PATCH 1/3] msm: kgsl: Turn off gpu interrupts during stall-on-fault Disable gpu interrupt inline instead of changing power states as gmu based targets do not implement the power state machine. Make sure we skip turning off the gpu interrupt during reset after stall on fault. Change-Id: I49c1702005f88eab523f00b25923c9c65193c7ca Signed-off-by: Harshdeep Dhatt --- drivers/gpu/msm/adreno_a6xx_gmu.c | 10 +++------- drivers/gpu/msm/kgsl_iommu.c | 7 ++++++- drivers/gpu/msm/kgsl_pwrctrl.c | 2 +- drivers/gpu/msm/kgsl_pwrctrl.h | 8 ++++++++ 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index e7b2f5124748..ebe85967ec35 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -2821,25 +2821,21 @@ error: void a6xx_enable_gpu_irq(struct adreno_device *adreno_dev) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); - struct kgsl_pwrctrl *pwr = &device->pwrctrl; + + kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON); adreno_irqctrl(adreno_dev, 1); - enable_irq(pwr->interrupt_num); - - trace_kgsl_irq(device, 1); } void a6xx_disable_gpu_irq(struct adreno_device *adreno_dev) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); - struct kgsl_pwrctrl *pwr = &device->pwrctrl; - disable_irq(pwr->interrupt_num); + kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); if (a6xx_gmu_gx_is_on(device)) adreno_irqctrl(adreno_dev, 0); - trace_kgsl_irq(device, 0); } static int a6xx_gpu_boot(struct adreno_device *adreno_dev) diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index aa12bafebc0a..71619ddcfd6b 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -649,7 +649,12 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, * The device mutex must be held to change power state */ mutex_lock(&device->mutex); - kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE); + + if (gmu_core_isenabled(device)) + kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); + else + kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE); + mutex_unlock(&device->mutex); } diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index 504cde5aea09..e07c165a3fb1 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -1330,7 +1330,7 @@ static int kgsl_pwrctrl_pwrrail(struct kgsl_device *device, int state) return status; } -static void kgsl_pwrctrl_irq(struct kgsl_device *device, int state) +void kgsl_pwrctrl_irq(struct kgsl_device *device, int state) { struct kgsl_pwrctrl *pwr = &device->pwrctrl; diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h index 483ab3464576..eeae3cec3568 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.h +++ b/drivers/gpu/msm/kgsl_pwrctrl.h @@ -228,4 +228,12 @@ int kgsl_pwrctrl_axi(struct kgsl_device *device, int state); * off state if the active_cnt is 0 and the hardware is idle. */ void kgsl_idle_check(struct work_struct *work); + +/** + * kgsl_pwrctrl_irq - Enable or disable gpu interrupts + * @device: Handle to the kgsl device + * @state: Variable to decide whether interrupts need to be enabled or disabled + * + */ +void kgsl_pwrctrl_irq(struct kgsl_device *device, int state); #endif /* __KGSL_PWRCTRL_H */ From a8f76a631de90c6c9c11f1f67c36ca33f256a3d3 Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Sat, 8 Aug 2020 14:23:09 -0600 Subject: [PATCH 2/3] msm: kgsl: Fix KGSL_PROP_PWRCTRL property for gmu based targets This property is used to enable dcvs or disable both dcvs and slumber using kgsl power state transitions. Since gmu or rgmu based targets don't use the power states, add and use gmu core flag to enable and disable slumber for those targets. Change-Id: Iace3af9427c7b84509c9041604972cf14e7cd675 Signed-off-by: Harshdeep Dhatt --- drivers/gpu/msm/adreno.c | 32 +++++++++++++++++++++++++----- drivers/gpu/msm/adreno_a6xx_gmu.c | 4 ++++ drivers/gpu/msm/adreno_a6xx_rgmu.c | 4 ++++ drivers/gpu/msm/kgsl_gmu_core.h | 1 + 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 3a5f8a08cb64..ab4aa761f4c5 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -2572,6 +2572,27 @@ int adreno_set_constraint(struct kgsl_device *device, return status; } +static void adreno_force_on(struct adreno_device *adreno_dev) +{ + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + + if (gmu_core_isenabled(device)) { + + set_bit(GMU_DISABLE_SLUMBER, &device->gmu_core.flags); + + if (!adreno_active_count_get(adreno_dev)) + adreno_active_count_put(adreno_dev); + + return; + } + + kgsl_pwrctrl_change_state(device, KGSL_STATE_ACTIVE); + + device->pwrctrl.ctrl_flags = KGSL_PWR_ON; + + adreno_fault_detect_stop(adreno_dev); +} + static int adreno_setproperty(struct kgsl_device_private *dev_priv, unsigned int type, void __user *value, @@ -2596,7 +2617,11 @@ static int adreno_setproperty(struct kgsl_device_private *dev_priv, mutex_lock(&device->mutex); if (enable) { - device->pwrctrl.ctrl_flags = 0; + if (gmu_core_isenabled(device)) + clear_bit(GMU_DISABLE_SLUMBER, + &device->gmu_core.flags); + else + device->pwrctrl.ctrl_flags = 0; if (!adreno_active_count_get(adreno_dev)) { adreno_fault_detect_start(adreno_dev); @@ -2605,10 +2630,7 @@ static int adreno_setproperty(struct kgsl_device_private *dev_priv, kgsl_pwrscale_enable(device); } else { - kgsl_pwrctrl_change_state(device, - KGSL_STATE_ACTIVE); - device->pwrctrl.ctrl_flags = KGSL_PWR_ON; - adreno_fault_detect_stop(adreno_dev); + adreno_force_on(adreno_dev); kgsl_pwrscale_disable(device, true); } diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index ebe85967ec35..db703d1a32fb 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -3108,6 +3108,9 @@ static void gmu_idle_check(struct work_struct *work) mutex_lock(&device->mutex); + if (test_bit(GMU_DISABLE_SLUMBER, &device->gmu_core.flags)) + goto done; + if (!atomic_read(&device->active_cnt)) { if (test_bit(GMU_PRIV_GPU_STARTED, &gmu->flags)) a6xx_power_off(adreno_dev); @@ -3116,6 +3119,7 @@ static void gmu_idle_check(struct work_struct *work) jiffies + device->pwrctrl.interval_timeout); } +done: mutex_unlock(&device->mutex); } diff --git a/drivers/gpu/msm/adreno_a6xx_rgmu.c b/drivers/gpu/msm/adreno_a6xx_rgmu.c index 2e086d3bd3d0..22e496d2bfa8 100644 --- a/drivers/gpu/msm/adreno_a6xx_rgmu.c +++ b/drivers/gpu/msm/adreno_a6xx_rgmu.c @@ -849,12 +849,16 @@ static void rgmu_idle_check(struct work_struct *work) mutex_lock(&device->mutex); + if (test_bit(GMU_DISABLE_SLUMBER, &device->gmu_core.flags)) + goto done; + if (!atomic_read(&device->active_cnt)) a6xx_power_off(adreno_dev); else mod_timer(&device->idle_timer, jiffies + device->pwrctrl.interval_timeout); +done: mutex_unlock(&device->mutex); } diff --git a/drivers/gpu/msm/kgsl_gmu_core.h b/drivers/gpu/msm/kgsl_gmu_core.h index dd2685c6f1a5..e955d475cc90 100644 --- a/drivers/gpu/msm/kgsl_gmu_core.h +++ b/drivers/gpu/msm/kgsl_gmu_core.h @@ -39,6 +39,7 @@ enum gmu_core_flags { GMU_DCVS_REPLAY, GMU_ENABLED, GMU_RSCC_SLEEP_SEQ_DONE, + GMU_DISABLE_SLUMBER, }; /* From c56b6599e3a7b2bace74f8845b954fd8657e1650 Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Tue, 11 Aug 2020 18:24:19 -0600 Subject: [PATCH 3/3] msm: kgsl: Kick dcvs in idle thread for gmu targets This ensures that dcvs runs while the gpu is still actively working on the same submission for longer than the idle timer. Change-Id: I85f2ff21dc19a9e589d6ed918bebea4c42b2a39d Signed-off-by: Harshdeep Dhatt --- drivers/gpu/msm/adreno_a6xx_gmu.c | 1 + drivers/gpu/msm/adreno_a6xx_rgmu.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index db703d1a32fb..92bda0fbac27 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -3115,6 +3115,7 @@ static void gmu_idle_check(struct work_struct *work) if (test_bit(GMU_PRIV_GPU_STARTED, &gmu->flags)) a6xx_power_off(adreno_dev); } else { + kgsl_pwrscale_update(device); mod_timer(&device->idle_timer, jiffies + device->pwrctrl.interval_timeout); } diff --git a/drivers/gpu/msm/adreno_a6xx_rgmu.c b/drivers/gpu/msm/adreno_a6xx_rgmu.c index 22e496d2bfa8..55f1ac8d9c3e 100644 --- a/drivers/gpu/msm/adreno_a6xx_rgmu.c +++ b/drivers/gpu/msm/adreno_a6xx_rgmu.c @@ -852,11 +852,13 @@ static void rgmu_idle_check(struct work_struct *work) if (test_bit(GMU_DISABLE_SLUMBER, &device->gmu_core.flags)) goto done; - if (!atomic_read(&device->active_cnt)) + if (!atomic_read(&device->active_cnt)) { a6xx_power_off(adreno_dev); - else + } else { + kgsl_pwrscale_update(device); mod_timer(&device->idle_timer, jiffies + device->pwrctrl.interval_timeout); + } done: mutex_unlock(&device->mutex);