From 59f2bbe3f404352df0664594532846a16a89d172 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 11 Dec 2019 12:54:01 -0700 Subject: [PATCH 1/2] msm: kgsl: Add a GMU core function to read the always on counter Add a GMU core function to read the always on counter from the generic KGSL code. Change-Id: Ic0dedbad1f81140ea9b891366d18b6f2d94bf149 Signed-off-by: Hareesh Gundu Signed-off-by: Jordan Crouse --- drivers/gpu/msm/adreno_a6xx_gmu.c | 6 ++++++ drivers/gpu/msm/adreno_a6xx_rgmu.c | 6 ++++++ drivers/gpu/msm/kgsl_gmu_core.c | 10 ++++++++++ drivers/gpu/msm/kgsl_gmu_core.h | 2 ++ 4 files changed, 24 insertions(+) diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index 6055cf4ed492..3d166f3df0aa 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -1762,6 +1762,11 @@ static bool a6xx_gmu_scales_bandwidth(struct kgsl_device *device) return (ADRENO_GPUREV(adreno_dev) >= ADRENO_REV_A640); } +static u64 a6xx_gmu_read_alwayson(struct kgsl_device *device) +{ + return a6xx_read_alwayson(ADRENO_DEVICE(device)); +} + struct gmu_dev_ops adreno_a6xx_gmudev = { .load_firmware = a6xx_gmu_load_firmware, .oob_set = a6xx_gmu_oob_set, @@ -1779,6 +1784,7 @@ struct gmu_dev_ops adreno_a6xx_gmudev = { .snapshot = a6xx_gmu_snapshot, .cooperative_reset = a6xx_gmu_cooperative_reset, .wait_for_active_transition = a6xx_gmu_wait_for_active_transition, + .read_alwayson = a6xx_gmu_read_alwayson, .gmu2host_intr_mask = HFI_IRQ_MASK, .gmu_ao_intr_mask = GMU_AO_INT_MASK, .scales_bandwidth = a6xx_gmu_scales_bandwidth, diff --git a/drivers/gpu/msm/adreno_a6xx_rgmu.c b/drivers/gpu/msm/adreno_a6xx_rgmu.c index c67b0048cd66..719c19a63b9b 100644 --- a/drivers/gpu/msm/adreno_a6xx_rgmu.c +++ b/drivers/gpu/msm/adreno_a6xx_rgmu.c @@ -559,6 +559,11 @@ static void a6xx_rgmu_snapshot(struct kgsl_device *device, ARRAY_SIZE(a6xx_rgmu_registers) / 2); } +static u64 a6xx_rgmu_read_alwayson(struct kgsl_device *device) +{ + return a6xx_read_alwayson(ADRENO_DEVICE(device)); +} + struct gmu_dev_ops adreno_a6xx_rgmudev = { .load_firmware = a6xx_rgmu_load_firmware, .oob_set = a6xx_rgmu_oob_set, @@ -573,6 +578,7 @@ struct gmu_dev_ops adreno_a6xx_rgmudev = { .ifpc_show = a6xx_rgmu_ifpc_show, .snapshot = a6xx_rgmu_snapshot, .halt_execution = a6xx_rgmu_halt_execution, + .read_alwayson = a6xx_rgmu_read_alwayson, .gmu2host_intr_mask = RGMU_OOB_IRQ_MASK, .gmu_ao_intr_mask = RGMU_AO_IRQ_MASK, }; diff --git a/drivers/gpu/msm/kgsl_gmu_core.c b/drivers/gpu/msm/kgsl_gmu_core.c index d8158e0c5910..a7580afb9442 100644 --- a/drivers/gpu/msm/kgsl_gmu_core.c +++ b/drivers/gpu/msm/kgsl_gmu_core.c @@ -355,3 +355,13 @@ int gmu_core_dev_wait_for_active_transition(struct kgsl_device *device) return 0; } + +u64 gmu_core_dev_read_alwayson(struct kgsl_device *device) +{ + struct gmu_dev_ops *ops = GMU_DEVICE_OPS(device); + + if (ops && ops->read_alwayson) + return ops->read_alwayson(device); + + return 0; +} diff --git a/drivers/gpu/msm/kgsl_gmu_core.h b/drivers/gpu/msm/kgsl_gmu_core.h index 655693a68205..461dee3208e2 100644 --- a/drivers/gpu/msm/kgsl_gmu_core.h +++ b/drivers/gpu/msm/kgsl_gmu_core.h @@ -135,6 +135,7 @@ struct gmu_dev_ops { void (*halt_execution)(struct kgsl_device *device); int (*wait_for_active_transition)(struct kgsl_device *device); bool (*scales_bandwidth)(struct kgsl_device *device); + u64 (*read_alwayson)(struct kgsl_device *device); const unsigned int gmu2host_intr_mask; const unsigned int gmu_ao_intr_mask; }; @@ -218,5 +219,6 @@ int gmu_core_dev_ifpc_store(struct kgsl_device *device, unsigned int val); void gmu_core_dev_prepare_stop(struct kgsl_device *device); int gmu_core_dev_wait_for_active_transition(struct kgsl_device *device); void gmu_core_dev_cooperative_reset(struct kgsl_device *device); +u64 gmu_core_dev_read_alwayson(struct kgsl_device *device); #endif /* __KGSL_GMU_CORE_H */ From c6393e3661c5c03662259cf03379030ba902a0b2 Mon Sep 17 00:00:00 2001 From: Sharat Masetty Date: Tue, 12 Nov 2019 13:54:35 +0530 Subject: [PATCH 2/2] msm: kgsl: Print always on counters if HFI timed out This patch adds some instrumentation to dump the always on counters in case the polling routine timed out waiting for a response from GMU after we send the HFI command. There are some cases where we suspect that the polling logic may be prematurely timing out. This patch should help throw more light into such cases. Change-Id: I055d529cca7bb242420cfc7e37f2b4ad5ac43195 Signed-off-by: Sharat Masetty --- drivers/gpu/msm/kgsl_hfi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/msm/kgsl_hfi.c b/drivers/gpu/msm/kgsl_hfi.c index d4affcda1b7d..ff67032061eb 100644 --- a/drivers/gpu/msm/kgsl_hfi.c +++ b/drivers/gpu/msm/kgsl_hfi.c @@ -266,7 +266,12 @@ static int poll_adreno_gmu_reg(struct adreno_device *adreno_dev, unsigned int mask, unsigned int timeout_ms) { unsigned int val; + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + struct gmu_device *gmu = KGSL_GMU_DEVICE(device); unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); + u64 ao_pre_poll, ao_post_poll; + + ao_pre_poll = gmu_core_dev_read_alwayson(device); while (time_is_after_jiffies(timeout)) { adreno_read_gmureg(adreno_dev, offset_name, &val); @@ -275,11 +280,16 @@ static int poll_adreno_gmu_reg(struct adreno_device *adreno_dev, usleep_range(10, 100); } + ao_post_poll = gmu_core_dev_read_alwayson(device); + /* Check one last time */ adreno_read_gmureg(adreno_dev, offset_name, &val); if ((val & mask) == expected_val) return 0; + dev_err(&gmu->pdev->dev, "kgsl hfi poll timeout: always on: %lld ms\n", + div_u64((ao_post_poll - ao_pre_poll) * 52, USEC_PER_SEC)); + return -ETIMEDOUT; }