From 93f66037edbc5135becbb961e96131e3febf2708 Mon Sep 17 00:00:00 2001 From: Sharat Masetty Date: Thu, 17 Aug 2017 11:10:41 +0530 Subject: [PATCH 1/2] drm/msm: Set memory retention flags on the GPU core clock After enabling the GPU clocks, the GPU can pagefault when trying to access memory(example the ringbuffer). This patch addresses the pagefault issue by enabling the memory retention flags on the GPU core clock. Change-Id: Ibabecba77501d6a3b188b19c90c172de7d667c8c Signed-off-by: Sharat Masetty --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 45a38b247727..765c1c087c76 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -15,6 +15,7 @@ #include "msm_iommu.h" #include "msm_trace.h" #include "a5xx_gpu.h" +#include #define SECURE_VA_START 0xc0000000 #define SECURE_VA_SIZE SZ_256M @@ -1169,6 +1170,17 @@ static int a5xx_pm_resume(struct msm_gpu *gpu) { int ret; + /* + * Between suspend/resumes the GPU clocks need to be turned off + * but not a complete power down, typically between frames. Set the + * memory retention flags on the GPU core clock to retain memory + * across clock toggles. + */ + if (gpu->core_clk) { + clk_set_flags(gpu->core_clk, CLKFLAG_RETAIN_PERIPH); + clk_set_flags(gpu->core_clk, CLKFLAG_RETAIN_MEM); + } + /* Turn on the core power */ ret = msm_gpu_pm_resume(gpu); if (ret) @@ -1208,6 +1220,12 @@ static int a5xx_pm_suspend(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + /* Turn off the memory retention flag when not necessary */ + if (gpu->core_clk) { + clk_set_flags(gpu->core_clk, CLKFLAG_NORETAIN_PERIPH); + clk_set_flags(gpu->core_clk, CLKFLAG_NORETAIN_MEM); + } + /* Only do this next bit if we are about to go down */ if (gpu->active_cnt == 1) { /* Clear the VBIF pipe before shutting down */ From db67d1e70d564a932ed326e89ababf12449f9049 Mon Sep 17 00:00:00 2001 From: Sharat Masetty Date: Thu, 17 Aug 2017 11:20:48 +0530 Subject: [PATCH 2/2] drm/msm: Disable clocks when GPU is inactive This patch addresses an issue in the GPU init sequence where the clocks are turned on during the process but after the init is complete the clocks are not turned off. Due to this, the GPU clocks always have a refcount delta of 1 and never get disabled later even when explicitly requested. Change-Id: I40fa9a25cd86f5d39fbe6f6e3f83d6ab467d615f Signed-off-by: Sharat Masetty --- drivers/gpu/drm/msm/msm_gpu.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 9320437e923d..29834b1a36fb 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -863,7 +863,14 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, gpu->dev = drm; gpu->funcs = funcs; gpu->name = name; - gpu->inactive = true; + /* + * Set the inactive flag to false, so that when the retire worker + * kicks in from the init path, it knows that it has to turn off the + * clocks. This should be fine to do since this is the init sequence + * and we have an init_lock in msm_open() to protect against bad things + * from happening. + */ + gpu->inactive = false; INIT_LIST_HEAD(&gpu->active_list); INIT_WORK(&gpu->retire_work, retire_worker);