msm: kgsl: Add support to toggle GPU GX CPR loop enable

Add support to toggle GPU GX CPR loop enable to recover
from the GX CPR stall issue.

Change-Id: Ic9f303e213ee8164fa1f97d946c396a4f59301d3
Signed-off-by: Hareesh Gundu <hareeshg@codeaurora.org>
This commit is contained in:
Hareesh Gundu 2020-05-04 15:43:34 +05:30
commit d39ef48f2b
3 changed files with 52 additions and 0 deletions

View file

@ -971,6 +971,7 @@ static const struct adreno_a6xx_core adreno_gpu_core_a619_variant = {
.vbif_count = ARRAY_SIZE(a615_gbif_regs),
.hang_detect_cycles = 0x3fffff,
.protected_regs = a630_protected_regs,
.gx_cpr_toggle = true,
};
static const struct adreno_reglist a620_hwcg_regs[] = {

View file

@ -3,6 +3,7 @@
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/soc/qcom/llcc-qcom.h>
@ -1091,6 +1092,51 @@ static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev)
return adj;
}
#define GPU_CPR_FSM_CTL_OFFSET 0x4
void a6xx_gx_cpr_toggle(struct kgsl_device *device)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
const struct adreno_a6xx_core *a6xx_core = to_a6xx_core(adreno_dev);
static void __iomem *gx_cpr_virt;
struct resource *res;
u32 val = 0;
if (!a6xx_core->gx_cpr_toggle)
return;
if (!gx_cpr_virt) {
res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM,
"gx_cpr");
if (res == NULL)
return;
gx_cpr_virt = devm_ioremap_resource(&device->pdev->dev, res);
if (!gx_cpr_virt) {
dev_err(device->dev, "Failed to map GX CPR\n");
return;
}
}
/*
* Toggle(disable -> enable) closed loop functionality to recover
* CPR measurements stall happened under certain conditions.
*/
val = readl_relaxed(gx_cpr_virt + GPU_CPR_FSM_CTL_OFFSET);
/* Make sure memory is updated before access */
rmb();
writel_relaxed(val & 0xfffffff0, gx_cpr_virt + GPU_CPR_FSM_CTL_OFFSET);
/* make sure register write committed */
wmb();
/* Wait for small time before we enable GX CPR */
udelay(5);
writel_relaxed(val | 0x00000001, gx_cpr_virt + GPU_CPR_FSM_CTL_OFFSET);
/* make sure register write committed */
wmb();
}
/**
* a6xx_reset() - Helper function to reset the GPU
@ -1124,6 +1170,9 @@ static int a6xx_reset(struct kgsl_device *device, int fault)
kgsl_pwrctrl_change_state(device, KGSL_STATE_ACTIVE);
/* Toggle GX CPR on demand */
a6xx_gx_cpr_toggle(device);
/*
* If active_cnt is zero, there is no need to keep the GPU active. So,
* we should transition to SLUMBER.

View file

@ -66,6 +66,8 @@ struct adreno_a6xx_core {
const struct a6xx_protected_regs *protected_regs;
/** @disable_tseskip: True if TSESkip logic is disabled */
bool disable_tseskip;
/** @gx_cpr_toggle: True to toggle GX CPR FSM to avoid CPR stalls */
bool gx_cpr_toggle;
/** @highest_bank_bit: The bit of the highest DDR bank */
u32 highest_bank_bit;
};