From 22489b8feac295476372e007925654668664e180 Mon Sep 17 00:00:00 2001 From: Laurentiu Palcu Date: Thu, 12 Jul 2018 10:29:38 +0300 Subject: [PATCH] MLK-18873: drm: imx: dcss: request PM QoS only when VBLANK is on DCSS needs PM QoS in order to keep interrupt latency low. Otherwise, page flipping will not work smooth enough because CTXLD will not be triggered in time. Currently, PM QoS is requested all the time but that does not allow the CPUs to go idle. Hence, this leads to increased power consumption. This patch will change how PM QoS is requested by doing it only when VBLANK is enabled/disabled. The VBLANK interrupt is enabled just before a commit takes place and disabled after one second after last commit. This will allow DCSS to function properly and, also, allow CPUs to go idle whenever there's no buffer submitted. Exception to this is when DTRC is used (when DCSS is passed tiled buffers). In this case, PM QoS will always be active, even if no buffer is submitted, because DTRC banks need to be switched in CTXLD ISR, so that DCSS does not underrun. DTRC does not have the REPEAT feature, as the rest of DCSS does. Signed-off-by: Laurentiu Palcu --- drivers/gpu/drm/imx/dcss/dcss-crtc.c | 4 ++++ drivers/gpu/imx/dcss/dcss-common.c | 25 +++++++++++++++++-------- drivers/gpu/imx/dcss/dcss-prv.h | 1 + include/video/imx-dcss.h | 3 +++ 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/imx/dcss/dcss-crtc.c b/drivers/gpu/drm/imx/dcss/dcss-crtc.c index 7c7a89bea7d5..4611d20c029c 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-crtc.c +++ b/drivers/gpu/drm/imx/dcss/dcss-crtc.c @@ -106,6 +106,8 @@ static int dcss_enable_vblank(struct drm_crtc *crtc) dcss_crtc->irq_enabled = true; + dcss_req_pm_qos(dcss, true); + dcss_vblank_irq_enable(dcss, true); enable_irq(dcss_crtc->irq); @@ -123,6 +125,8 @@ static void dcss_disable_vblank(struct drm_crtc *crtc) dcss_vblank_irq_enable(dcss, false); + dcss_req_pm_qos(dcss, false); + dcss_crtc->irq_enabled = false; } diff --git a/drivers/gpu/imx/dcss/dcss-common.c b/drivers/gpu/imx/dcss/dcss-common.c index e55da669292a..4b3a667f6ef5 100644 --- a/drivers/gpu/imx/dcss/dcss-common.c +++ b/drivers/gpu/imx/dcss/dcss-common.c @@ -612,6 +612,23 @@ static int dcss_remove(struct platform_device *pdev) return 0; } +void dcss_req_pm_qos(struct dcss_soc *dcss, bool en) +{ + if (en && !dcss->pm_req_active) { + pm_qos_add_request(&dcss->pm_qos_req, + PM_QOS_CPU_DMA_LATENCY, 0); + dcss->pm_req_active = true; + return; + } + + if (dcss_dtrc_is_running(dcss, 1) || dcss_dtrc_is_running(dcss, 2)) + return; + + pm_qos_remove_request(&dcss->pm_qos_req); + dcss->pm_req_active = false; +} +EXPORT_SYMBOL(dcss_req_pm_qos); + #ifdef CONFIG_PM_SLEEP static int dcss_suspend(struct device *dev) { @@ -628,8 +645,6 @@ static int dcss_suspend(struct device *dev) dcss_clocks_enable(dcss, false); - pm_qos_remove_request(&dcss->pm_qos_req); - dcss_bus_freq(dcss, false); return 0; @@ -645,8 +660,6 @@ static int dcss_resume(struct device *dev) dcss_bus_freq(dcss, true); - pm_qos_add_request(&dcss->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0); - dcss_clocks_enable(dcss, true); dcss_blkctl_cfg(dcss); @@ -670,8 +683,6 @@ static int dcss_runtime_suspend(struct device *dev) dcss_clocks_enable(dcss, false); - pm_qos_remove_request(&dcss->pm_qos_req); - dcss_bus_freq(dcss, false); return 0; @@ -684,8 +695,6 @@ static int dcss_runtime_resume(struct device *dev) dcss_bus_freq(dcss, true); - pm_qos_add_request(&dcss->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0); - dcss_clocks_enable(dcss, true); dcss_blkctl_cfg(dcss); diff --git a/drivers/gpu/imx/dcss/dcss-prv.h b/drivers/gpu/imx/dcss/dcss-prv.h index e8c6f08f5184..4e5ddc2622d5 100644 --- a/drivers/gpu/imx/dcss/dcss-prv.h +++ b/drivers/gpu/imx/dcss/dcss-prv.h @@ -61,6 +61,7 @@ struct dcss_soc { bool clks_on; struct pm_qos_request pm_qos_req; + bool pm_req_active; }; /* BLKCTL */ diff --git a/include/video/imx-dcss.h b/include/video/imx-dcss.h index ee90bf2dd994..7afd03c91fdf 100644 --- a/include/video/imx-dcss.h +++ b/include/video/imx-dcss.h @@ -68,6 +68,9 @@ void dcss_trace_write(u64 tag); #define dcss_trace_module(mod_tag, val) dcss_trace_write((mod_tag) | (val)); +/* COMMON */ +void dcss_req_pm_qos(struct dcss_soc *dcss, bool en); + /* BLKCTL */ void dcss_blkctl_hdmi_secure_src_en(struct dcss_soc *dcss); -- 2.17.1