diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index 84bce33a3ac0..6ee6a797fed4 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -734,6 +734,9 @@ int a6xx_gmu_oob_set(struct kgsl_device *device, int ret = 0; int set, check; + if (req == oob_perfcntr && gmu->num_oob_perfcntr++) + return 0; + if (adreno_is_a630(adreno_dev) || adreno_is_a615_family(adreno_dev)) { set = BIT(req + 16); check = BIT(req + 24); @@ -757,6 +760,8 @@ int a6xx_gmu_oob_set(struct kgsl_device *device, if (timed_poll_check(device, A6XX_GMU_GMU2HOST_INTR_INFO, check, GPU_START_TIMEOUT, check)) { + if (req == oob_perfcntr) + gmu->num_oob_perfcntr--; gmu_fault_snapshot(device); ret = -ETIMEDOUT; WARN(1, "OOB request %s timed out\n", oob_to_str(req)); @@ -776,6 +781,9 @@ void a6xx_gmu_oob_clear(struct kgsl_device *device, struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev); int clear; + if (req == oob_perfcntr && --gmu->num_oob_perfcntr) + return; + if (adreno_is_a630(adreno_dev) || adreno_is_a615_family(adreno_dev)) { clear = BIT(req + 24); } else { diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.h b/drivers/gpu/msm/adreno_a6xx_gmu.h index 2aa8e90dde36..d39597683ec9 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.h +++ b/drivers/gpu/msm/adreno_a6xx_gmu.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #ifndef __ADRENO_A6XX_GMU_H #define __ADRENO_A6XX_GMU_H @@ -207,6 +207,8 @@ struct a6xx_gmu_device { void __iomem *rdpm_mx_virt; /** @log_stream_enable: GMU log streaming enable */ bool log_stream_enable; + /** @num_oob_perfcntr: Number of active oob_perfcntr requests */ + u32 num_oob_perfcntr; }; /* Helper function to get to a6xx gmu device from adreno device */ diff --git a/drivers/gpu/msm/adreno_a6xx_rgmu.c b/drivers/gpu/msm/adreno_a6xx_rgmu.c index 49d71e5318e5..854566f73976 100644 --- a/drivers/gpu/msm/adreno_a6xx_rgmu.c +++ b/drivers/gpu/msm/adreno_a6xx_rgmu.c @@ -146,6 +146,9 @@ static int a6xx_rgmu_oob_set(struct kgsl_device *device, struct a6xx_rgmu_device *rgmu = to_a6xx_rgmu(ADRENO_DEVICE(device)); int ret, set, check; + if (req == oob_perfcntr && rgmu->num_oob_perfcntr++) + return 0; + set = BIT(req + 16); check = BIT(req + 16); @@ -160,6 +163,8 @@ static int a6xx_rgmu_oob_set(struct kgsl_device *device, if (ret) { unsigned int status; + if (req == oob_perfcntr) + rgmu->num_oob_perfcntr--; 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", @@ -181,6 +186,11 @@ static int a6xx_rgmu_oob_set(struct kgsl_device *device, static void a6xx_rgmu_oob_clear(struct kgsl_device *device, enum oob_request req) { + struct a6xx_rgmu_device *rgmu = to_a6xx_rgmu(ADRENO_DEVICE(device)); + + if (req == oob_perfcntr && --rgmu->num_oob_perfcntr) + return; + gmu_core_regwrite(device, A6XX_GMU_HOST2GMU_INTR_SET, BIT(req + 24)); trace_kgsl_gmu_oob_clear(BIT(req + 24)); } diff --git a/drivers/gpu/msm/adreno_a6xx_rgmu.h b/drivers/gpu/msm/adreno_a6xx_rgmu.h index 6defcbc5ac46..cf36008ee085 100644 --- a/drivers/gpu/msm/adreno_a6xx_rgmu.h +++ b/drivers/gpu/msm/adreno_a6xx_rgmu.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ #ifndef __ADRENO_A6XX_RGMU_H #define __ADRENO_A6XX_RGMU_H @@ -58,6 +58,8 @@ struct a6xx_rgmu_device { unsigned int fault_count; /** @flags: rgmu internal flags */ unsigned long flags; + /** @num_oob_perfcntr: Number of active oob_perfcntr requests */ + u32 num_oob_perfcntr; }; /**