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 <kamaagra@codeaurora.org>
This commit is contained in:
Kamal Agrawal 2021-01-18 11:37:02 +05:30
commit f8d51faf58
3 changed files with 13 additions and 6 deletions

View file

@ -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 <linux/component.h>
#include <linux/delay.h>
@ -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

View file

@ -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,
};

View file

@ -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 <linux/clk/qcom.h>
@ -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, &reg);
/* 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)