]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
drm/msm: Call pm_runtime_enable/disable for newly created devices
authorArchit Taneja <architt@codeaurora.org>
Wed, 15 Jun 2016 12:34:31 +0000 (18:04 +0530)
committerRob Clark <robdclark@gmail.com>
Sat, 16 Jul 2016 14:08:58 +0000 (10:08 -0400)
With the new device hierarchy for MDP5, we need to enable runtime PM
for both the toplevel MDSS device and the MDP5 device itself. Enable
runtime PM for the new devices.

Since MDP4 and MDP5 now have different places where runtime PM is
enabled, remove the previous pm_runtime_enable/disable calls, and
squash them in the respective kms drivers.

The new device hierarchy (as expressed in the DT bindings) has the GDSC
tied only to the MDSS wrapper device. This GDSC needs to be enabled for
accessing any register in the MDSS sub-blocks. Once every driver is
runtime adapted, the GDSC will be enabled when any sub-block device
calls runtime_get because of the parent-child relationship with MDSS.

Until then, we call pm_runtime_get_sync() once for the MDSS device to
ensure the GDSC is never disabled. This will be removed once all the
drivers are runtime PM adapted.

The error handling paths become a bit tricky when we call these runtime
PM funcs. There doesn't seem to be any helper that checks if runtime PM
is enabled already. Add bool variables in mdp4_kms/mdp5_kms structs to
check if the driver had managed to call pm_runtime_enable before bailing
out.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c
drivers/gpu/drm/msm/msm_drv.c

index b6920917c4a98f9a18ea88fdb0bc3b6817a012c9..ba8df15605d7792893085787ac1275361321cedd 100644 (file)
@@ -158,6 +158,7 @@ static const char * const iommu_ports[] = {
 static void mdp4_destroy(struct msm_kms *kms)
 {
        struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+       struct device *dev = mdp4_kms->dev->dev;
        struct msm_mmu *mmu = mdp4_kms->mmu;
 
        if (mmu) {
@@ -169,6 +170,10 @@ static void mdp4_destroy(struct msm_kms *kms)
                msm_gem_put_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id);
        if (mdp4_kms->blank_cursor_bo)
                drm_gem_object_unreference_unlocked(mdp4_kms->blank_cursor_bo);
+
+       if (mdp4_kms->rpm_enabled)
+               pm_runtime_disable(dev);
+
        kfree(mdp4_kms);
 }
 
@@ -511,6 +516,9 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
        clk_set_rate(mdp4_kms->clk, config->max_clk);
        clk_set_rate(mdp4_kms->lut_clk, config->max_clk);
 
+       pm_runtime_enable(dev->dev);
+       mdp4_kms->rpm_enabled = true;
+
        /* make sure things are off before attaching iommu (bootloader could
         * have left things on, in which case we'll start getting faults if
         * we don't disable):
index c5d045d5680d74f5ef91715a1c00759fe8288a13..25fb83997119c17e5b2617710a2324b7dae1d1bb 100644 (file)
@@ -47,6 +47,8 @@ struct mdp4_kms {
 
        struct mdp_irq error_handler;
 
+       bool rpm_enabled;
+
        /* empty/blank cursor bo to use when cursor is "disabled" */
        struct drm_gem_object *blank_cursor_bo;
        uint32_t blank_cursor_iova;
index a0b974772cf685395900008e06cb492ecdd4ac15..5d6d9e146aaa0d164f8d5b5b4edecc87b15e33cd 100644 (file)
@@ -668,6 +668,9 @@ static void mdp5_destroy(struct platform_device *pdev)
                mdp5_smp_destroy(mdp5_kms->smp);
        if (mdp5_kms->cfg)
                mdp5_cfg_destroy(mdp5_kms->cfg);
+
+       if (mdp5_kms->rpm_enabled)
+               pm_runtime_disable(&pdev->dev);
 }
 
 static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
@@ -720,6 +723,9 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
         */
        clk_set_rate(mdp5_kms->core_clk, 200000000);
 
+       pm_runtime_enable(&pdev->dev);
+       mdp5_kms->rpm_enabled = true;
+
        read_mdp_hw_revision(mdp5_kms, &major, &minor);
 
        mdp5_kms->cfg = mdp5_cfg_init(mdp5_kms, major, minor);
index d214d50bbd4690ba2b8655a8e2414226952c7cb2..03738927be1010501f1275b5286712c92e1a23ed 100644 (file)
@@ -59,6 +59,8 @@ struct mdp5_kms {
         */
        spinlock_t resource_lock;
 
+       bool rpm_enabled;
+
        struct mdp_irq error_handler;
 };
 #define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base)
index 871c4424a82029ceb7ebb679e6c9012481e287aa..d444a6901fff869ddabb735630a64243091297db 100644 (file)
@@ -152,6 +152,10 @@ void msm_mdss_destroy(struct drm_device *dev)
        mdss->irqcontroller.domain = NULL;
 
        regulator_disable(mdss->vdd);
+
+       pm_runtime_put_sync(dev->dev);
+
+       pm_runtime_disable(dev->dev);
 }
 
 int msm_mdss_init(struct drm_device *dev)
@@ -215,6 +219,14 @@ int msm_mdss_init(struct drm_device *dev)
 
        priv->mdss = mdss;
 
+       pm_runtime_enable(dev->dev);
+
+       /*
+        * TODO: This is needed as the MDSS GDSC is only tied to MDSS's power
+        * domain. Remove this once runtime PM is adapted for all the devices.
+        */
+       pm_runtime_get_sync(dev->dev);
+
        return 0;
 fail_irq:
        regulator_disable(mdss->vdd);
index d650aaca60f80ef93d452f624c6437970b824da3..1c186901109208dd6c9d0e231e3757d76d6fae10 100644 (file)
@@ -215,10 +215,8 @@ static int msm_drm_uninit(struct device *dev)
        flush_workqueue(priv->atomic_wq);
        destroy_workqueue(priv->atomic_wq);
 
-       if (kms) {
-               pm_runtime_disable(dev);
+       if (kms)
                kms->funcs->destroy(kms);
-       }
 
        if (gpu) {
                mutex_lock(&ddev->struct_mutex);
@@ -410,7 +408,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
        }
 
        if (kms) {
-               pm_runtime_enable(dev);
                ret = kms->funcs->hw_init(kms);
                if (ret) {
                        dev_err(dev, "kms hw init failed: %d\n", ret);