From f8d51faf58912007fec98b8963c0784cd24aab69 Mon Sep 17 00:00:00 2001 From: Kamal Agrawal Date: Mon, 18 Jan 2021 11:37:02 +0530 Subject: [PATCH] msm: kgsl: Avoid slumber if interrupt is pending As part of slumber sequence, there is a hardware idle validation which checks for GPU idle. However, it is possible that GPU is idle but the interrupt is yet to be processed. Fix it by checking for pending interrupt. Change-Id: Ia3aef2827fc48bfad382e2369d8477aa67b163d9 Signed-off-by: Kamal Agrawal --- drivers/gpu/msm/adreno.c | 9 +++++++-- drivers/gpu/msm/adreno.h | 3 ++- drivers/gpu/msm/adreno_a6xx.c | 7 ++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 14a7c6ec8b03..d9b06663c7c2 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2002,2007-2021, The Linux Foundation. All rights reserved. */ #include #include @@ -2614,8 +2614,13 @@ static int adreno_setproperty(struct kgsl_device_private *dev_priv, bool adreno_irq_pending(struct adreno_device *adreno_dev) { unsigned int status; + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); - adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status); + if (gmu_core_isenabled(device)) + adreno_read_gmureg(adreno_dev, + ADRENO_REG_GMU_AO_RBBM_INT_UNMASKED_STATUS, &status); + else + adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status); /* * IRQ handler clears the RBBM INT0 status register immediately diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index 3d977e411805..4f89ac6cf490 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2008-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2008-2021, The Linux Foundation. All rights reserved. */ #ifndef __ADRENO_H #define __ADRENO_H @@ -701,6 +701,7 @@ enum adreno_regs { ADRENO_REG_GMU_AHB_FENCE_STATUS, ADRENO_REG_GMU_GMU2HOST_INTR_MASK, ADRENO_REG_GPMU_POWER_COUNTER_ENABLE, + ADRENO_REG_GMU_AO_RBBM_INT_UNMASKED_STATUS, ADRENO_REG_REGISTER_MAX, }; diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c index 57f4db260839..e010cfc0e28a 100644 --- a/drivers/gpu/msm/adreno_a6xx.c +++ b/drivers/gpu/msm/adreno_a6xx.c @@ -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. */ #include @@ -1194,9 +1194,8 @@ bool a6xx_hw_isidle(struct adreno_device *adreno_dev) } gmu_core_regread(device, A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS, ®); - /* Bit 23 is GPUBUSYIGNAHB */ - return (reg & BIT(23)) ? false : true; + return ((reg & BIT(23)) || adreno_irq_pending(adreno_dev)) ? false : true; } int a6xx_microcode_read(struct adreno_device *adreno_dev) @@ -2342,6 +2341,8 @@ static unsigned int a6xx_register_offsets[ADRENO_REG_REGISTER_MAX] = { A6XX_GMU_AHB_FENCE_STATUS), ADRENO_REG_DEFINE(ADRENO_REG_GMU_GMU2HOST_INTR_MASK, A6XX_GMU_GMU2HOST_INTR_MASK), + ADRENO_REG_DEFINE(ADRENO_REG_GMU_AO_RBBM_INT_UNMASKED_STATUS, + A6XX_GMU_RBBM_INT_UNMASKED_STATUS), }; static int cpu_gpu_lock(struct cpu_gpu_lock *lock)