diff --git a/techpack/display/msm/msm_atomic.c b/techpack/display/msm/msm_atomic.c index 6c80d242e001..eb92af6caea5 100644 --- a/techpack/display/msm/msm_atomic.c +++ b/techpack/display/msm/msm_atomic.c @@ -732,6 +732,10 @@ retry: * mark our set of crtc's as busy: */ + if (!atomic_cmpxchg_acquire(&priv->pm_req_set, 1, 0)) + pm_qos_update_request(&priv->pm_irq_req, 100); + mod_delayed_work(system_unbound_wq, &priv->pm_unreq_dwork, HZ / 10); + /* Start Atomic */ spin_lock(&priv->pending_crtcs_event.lock); ret = wait_event_interruptible_locked(priv->pending_crtcs_event, diff --git a/techpack/display/msm/msm_drv.c b/techpack/display/msm/msm_drv.c index 74a20330ca9d..a9b644f2d55c 100644 --- a/techpack/display/msm/msm_drv.c +++ b/techpack/display/msm/msm_drv.c @@ -860,6 +860,16 @@ static void msm_idle_init(struct drm_device *ddev) spin_lock_init(&idle->lock); } +static void msm_drm_pm_unreq(struct work_struct *work) +{ + struct msm_drm_private *priv = container_of(to_delayed_work(work), + typeof(*priv), + pm_unreq_dwork); + + pm_qos_update_request(&priv->pm_irq_req, PM_QOS_DEFAULT_VALUE); + atomic_set_release(&priv->pm_req_set, 0); +} + static int msm_drm_init(struct device *dev, struct drm_driver *drv) { struct platform_device *pdev = to_platform_device(dev); @@ -898,6 +908,9 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) INIT_LIST_HEAD(&priv->client_event_list); INIT_LIST_HEAD(&priv->inactive_list); + priv->pm_req_set = (atomic_t)ATOMIC_INIT(0); + INIT_DELAYED_WORK(&priv->pm_unreq_dwork, msm_drm_pm_unreq); + ret = sde_power_resource_init(pdev, &priv->phandle); if (ret) { pr_err("sde power resource init failed\n"); @@ -1243,8 +1256,13 @@ static void msm_irq_preinstall(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; struct msm_kms *kms = priv->kms; + struct sde_kms *sde_kms = to_sde_kms(kms); BUG_ON(!kms); kms->funcs->irq_preinstall(kms); + priv->pm_irq_req.type = PM_QOS_REQ_AFFINE_IRQ; + priv->pm_irq_req.irq = sde_kms->irq_num; + pm_qos_add_request(&priv->pm_irq_req, PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); } static int msm_irq_postinstall(struct drm_device *dev) @@ -1261,6 +1279,8 @@ static void msm_irq_uninstall(struct drm_device *dev) struct msm_kms *kms = priv->kms; BUG_ON(!kms); kms->funcs->irq_uninstall(kms); + flush_delayed_work(&priv->pm_unreq_dwork); + pm_qos_remove_request(&priv->pm_irq_req); } static int msm_enable_vblank(struct drm_device *dev, unsigned int pipe) diff --git a/techpack/display/msm/msm_drv.h b/techpack/display/msm/msm_drv.h index 6a44666e5e5e..ac106b0a19fc 100644 --- a/techpack/display/msm/msm_drv.h +++ b/techpack/display/msm/msm_drv.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -722,6 +723,10 @@ struct msm_drm_private { ktime_t complete_commit_time; struct msm_idle idle; + + struct pm_qos_request pm_irq_req; + struct delayed_work pm_unreq_dwork; + atomic_t pm_req_set; }; /* get struct msm_kms * from drm_device * */