From 85de65358993f5f51120fc8cfac632392193754f Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Thu, 27 Feb 2020 13:45:12 -0700 Subject: [PATCH] msm: kgsl: Make OOB timeouts easier to debug Instead of a vague message and a mask use actual string names and a nice WARN() to make it easier for mere mortals to debug OOB timeouts. Also remove a unneeded global function and replace it with a smaller local function. Change-Id: Ic0dedbad470326854e8565d651d477cf54401f07 Signed-off-by: Jordan Crouse --- drivers/gpu/msm/adreno_a6xx_gmu.c | 61 +++++++++++++++++++----------- drivers/gpu/msm/adreno_a6xx_rgmu.c | 11 +++++- drivers/gpu/msm/kgsl_gmu_core.c | 21 ---------- drivers/gpu/msm/kgsl_gmu_core.h | 1 - 4 files changed, 48 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index 3d166f3df0aa..5825a90b80a6 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -563,6 +563,19 @@ static int load_gmu_fw(struct kgsl_device *device) return 0; } +static const char *oob_to_str(enum oob_request req) +{ + if (req == oob_gpu) + return "oob_gpu"; + else if (req == oob_perfcntr) + return "oob_perfcntr"; + else if (req == oob_boot_slumber) + return "oob_boot_slumber"; + else if (req == oob_dcvs) + return "oob_dcvs"; + return "unknown"; +} + /* * a6xx_gmu_oob_set() - Set OOB interrupt to GMU. * @device: Pointer to kgsl device @@ -576,30 +589,31 @@ static int a6xx_gmu_oob_set(struct kgsl_device *device, int ret = 0; int set, check; - if (!adreno_is_a630(adreno_dev) && !adreno_is_a615_family(adreno_dev)) { - set = BIT(30 - req * 2); - check = BIT(31 - req); - - if (req >= 6) { - dev_err(&gmu->pdev->dev, - "OOB_set(0x%x) invalid\n", set); - return -EINVAL; - } - } else { + if (adreno_is_a630(adreno_dev) || adreno_is_a615_family(adreno_dev)) { set = BIT(req + 16); check = BIT(req + 24); + } else { + /* + * The legacy targets have special bits that aren't supported on + * newer implementations + */ + if (req >= oob_boot_slumber) { + dev_err(&gmu->pdev->dev, + "Unsupported OOB request %s\n", + oob_to_str(req)); + return -EINVAL; + } + + set = BIT(30 - req * 2); + check = BIT(31 - req); } gmu_core_regwrite(device, A6XX_GMU_HOST2GMU_INTR_SET, set); - if (timed_poll_check(device, - A6XX_GMU_GMU2HOST_INTR_INFO, - check, - GPU_START_TIMEOUT, - check)) { + if (timed_poll_check(device, A6XX_GMU_GMU2HOST_INTR_INFO, check, + GPU_START_TIMEOUT, check)) { ret = -ETIMEDOUT; - dev_err(&gmu->pdev->dev, - "OOB_set(0x%x) timed out\n", set); + WARN(1, "OOB request %s timed out\n", oob_to_str(req)); } gmu_core_regwrite(device, A6XX_GMU_GMU2HOST_INTR_CLR, check); @@ -620,15 +634,16 @@ static void a6xx_gmu_oob_clear(struct kgsl_device *device, struct gmu_device *gmu = KGSL_GMU_DEVICE(device); int clear; - if (!adreno_is_a630(adreno_dev) && !adreno_is_a615_family(adreno_dev)) { + if (adreno_is_a630(adreno_dev) || adreno_is_a615_family(adreno_dev)) { + clear = BIT(req + 24); + } else { clear = BIT(31 - req * 2); - if (req >= 6) { - dev_err(&gmu->pdev->dev, - "OOB_clear(0x%x) invalid\n", clear); + if (req >= oob_boot_slumber) { + dev_err(&gmu->pdev->dev, "Unsupported OOB clear %s\n", + oob_to_str(req)); return; } - } else - clear = BIT(req + 24); + } gmu_core_regwrite(device, A6XX_GMU_HOST2GMU_INTR_SET, clear); trace_kgsl_gmu_oob_clear(clear); diff --git a/drivers/gpu/msm/adreno_a6xx_rgmu.c b/drivers/gpu/msm/adreno_a6xx_rgmu.c index 1cac86b8623a..af229d91f81d 100644 --- a/drivers/gpu/msm/adreno_a6xx_rgmu.c +++ b/drivers/gpu/msm/adreno_a6xx_rgmu.c @@ -84,6 +84,15 @@ irqreturn_t oob_irq_handler(int irq, void *data) return IRQ_HANDLED; } +static const char *oob_to_str(enum oob_request req) +{ + if (req == oob_gpu) + return "oob_gpu"; + else if (req == oob_perfcntr) + return "oob_perfcntr"; + return "unknown"; +} + /* * a6xx_rgmu_oob_set() - Set OOB interrupt to RGMU * @adreno_dev: Pointer to adreno device @@ -112,7 +121,7 @@ static int a6xx_rgmu_oob_set(struct kgsl_device *device, gmu_core_regread(device, A6XX_RGMU_CX_PCC_DEBUG, &status); dev_err(&rgmu->pdev->dev, "Timed out while setting OOB req:%s status:0x%x\n", - gmu_core_oob_type_str(req), status); + oob_to_str(req), status); return ret; } diff --git a/drivers/gpu/msm/kgsl_gmu_core.c b/drivers/gpu/msm/kgsl_gmu_core.c index a7580afb9442..87df810bd63a 100644 --- a/drivers/gpu/msm/kgsl_gmu_core.c +++ b/drivers/gpu/msm/kgsl_gmu_core.c @@ -16,27 +16,6 @@ static const struct of_device_id gmu_match_table[] = { {}, }; -struct oob_entry { - enum oob_request req; - const char *str; -}; - -const char *gmu_core_oob_type_str(enum oob_request req) -{ - int i; - struct oob_entry table[] = { - { oob_gpu, "oob_gpu"}, - { oob_perfcntr, "oob_perfcntr"}, - { oob_boot_slumber, "oob_boot_slumber"}, - { oob_dcvs, "oob_dcvs"}, - }; - - for (i = 0; i < ARRAY_SIZE(table); i++) - if (req == table[i].req) - return table[i].str; - return "UNKNOWN"; -} - void __init gmu_core_register(void) { const struct of_device_id *match; diff --git a/drivers/gpu/msm/kgsl_gmu_core.h b/drivers/gpu/msm/kgsl_gmu_core.h index 461dee3208e2..b35e573c9be2 100644 --- a/drivers/gpu/msm/kgsl_gmu_core.h +++ b/drivers/gpu/msm/kgsl_gmu_core.h @@ -205,7 +205,6 @@ void gmu_core_blkwrite(struct kgsl_device *device, unsigned int offsetwords, const void *buffer, size_t size); void gmu_core_regrmw(struct kgsl_device *device, unsigned int offsetwords, unsigned int mask, unsigned int bits); -const char *gmu_core_oob_type_str(enum oob_request req); int gmu_core_dev_oob_set(struct kgsl_device *device, enum oob_request req); void gmu_core_dev_oob_clear(struct kgsl_device *device, enum oob_request req); int gmu_core_dev_hfi_start_msg(struct kgsl_device *device);