diff --git a/drivers/gpu/msm/a6xx_reg.h b/drivers/gpu/msm/a6xx_reg.h index bb6bbcc1c861..e2f83dd96f6b 100644 --- a/drivers/gpu/msm/a6xx_reg.h +++ b/drivers/gpu/msm/a6xx_reg.h @@ -1075,6 +1075,8 @@ #define A6XX_GPU_CC_GX_DOMAIN_MISC 0x24542 #define A6XX_GPU_CC_GX_DOMAIN_MISC3 0x24563 +/* GPU CPR registers */ +#define A6XX_GPU_CPR_FSM_CTL 0x26801 /* GPU RSC sequencer registers */ #define A6XX_GPU_RSCC_RSC_STATUS0_DRV0 0x00004 diff --git a/drivers/gpu/msm/adreno_a6xx_gmu.c b/drivers/gpu/msm/adreno_a6xx_gmu.c index 9d13bcf33efe..e2f8c0015c8e 100644 --- a/drivers/gpu/msm/adreno_a6xx_gmu.c +++ b/drivers/gpu/msm/adreno_a6xx_gmu.c @@ -1702,11 +1702,27 @@ static void a6xx_gmu_pwrctrl_suspend(struct adreno_device *adreno_dev) dev_err(&gmu->pdev->dev, "suspend fail: gx enable %d\n", ret); + /* + * Toggle the loop_en bit, across disabling the gx gdsc, + * with a delay of 10 XO cycles before disabling gx + * gdsc. This is to prevent CPR measurements from + * failing. + */ + if (adreno_is_a660(adreno_dev)) { + gmu_core_regrmw(device, A6XX_GPU_CPR_FSM_CTL, + 1, 0); + ndelay(520); + } + ret = regulator_disable(gmu->gx_gdsc); if (ret) dev_err(&gmu->pdev->dev, "suspend fail: gx disable %d\n", ret); + if (adreno_is_a660(adreno_dev)) + gmu_core_regrmw(device, A6XX_GPU_CPR_FSM_CTL, + 1, 1); + if (a6xx_gmu_gx_is_on(device)) dev_err(&gmu->pdev->dev, "gx is stuck on\n");