diff mbox series

drm/komeda: Add runtime_pm support

Message ID 20191212074756.14678-1-james.qian.wang@arm.com (mailing list archive)
State New, archived
Headers show
Series drm/komeda: Add runtime_pm support | expand

Commit Message

James Qian Wang Dec. 12, 2019, 7:48 a.m. UTC
- Add pm_runtime_get/put to crtc_enable/disable along with the real
  display usage
- Add runtime_get/put to register_show, since register_show() will
  access register, need to wakeup HW.
- For the case that PM is not enabled or configured, manually wakeup HW

Signed-off-by: james qian wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  3 +
 .../gpu/drm/arm/display/komeda/komeda_dev.c   | 55 +++++--------------
 .../gpu/drm/arm/display/komeda/komeda_drv.c   | 42 ++++++++++++--
 .../gpu/drm/arm/display/komeda/komeda_kms.c   |  6 --
 4 files changed, 53 insertions(+), 53 deletions(-)

Comments

Mihail Atanassov Dec. 23, 2019, 1:02 p.m. UTC | #1
On Thursday, 12 December 2019 07:48:13 GMT james qian wang (Arm Technology China) wrote:
> - Add pm_runtime_get/put to crtc_enable/disable along with the real
>   display usage
> - Add runtime_get/put to register_show, since register_show() will
>   access register, need to wakeup HW.
> - For the case that PM is not enabled or configured, manually wakeup HW
> 
> Signed-off-by: james qian wang (Arm Technology China) <james.qian.wang@arm.com>
> ---
>  .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  3 +
>  .../gpu/drm/arm/display/komeda/komeda_dev.c   | 55 +++++--------------
>  .../gpu/drm/arm/display/komeda/komeda_drv.c   | 42 ++++++++++++--
>  .../gpu/drm/arm/display/komeda/komeda_kms.c   |  6 --
>  4 files changed, 53 insertions(+), 53 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> index 1c452ea75999..56bd938961ee 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> @@ -5,6 +5,7 @@
>   *
>   */
>  #include <linux/clk.h>
> +#include <linux/pm_runtime.h>
>  #include <linux/spinlock.h>
>  
>  #include <drm/drm_atomic.h>
> @@ -274,6 +275,7 @@ static void
>  komeda_crtc_atomic_enable(struct drm_crtc *crtc,
>  			  struct drm_crtc_state *old)
>  {
> +	pm_runtime_get_sync(crtc->dev->dev);
>  	komeda_crtc_prepare(to_kcrtc(crtc));
>  	drm_crtc_vblank_on(crtc);
>  	WARN_ON(drm_crtc_vblank_get(crtc));
> @@ -372,6 +374,7 @@ komeda_crtc_atomic_disable(struct drm_crtc *crtc,
>  	drm_crtc_vblank_put(crtc);
>  	drm_crtc_vblank_off(crtc);
>  	komeda_crtc_unprepare(kcrtc);
> +	pm_runtime_put(crtc->dev->dev);
>  }
>  
>  static void
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> index 38b832804bad..1d767473ba8a 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> @@ -10,6 +10,7 @@
>  #include <linux/of_graph.h>
>  #include <linux/of_reserved_mem.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
>  #include <linux/dma-mapping.h>
>  #ifdef CONFIG_DEBUG_FS
>  #include <linux/debugfs.h>
> @@ -27,12 +28,16 @@ static int komeda_register_show(struct seq_file *sf, void *x)
>  
>  	seq_puts(sf, "\n====== Komeda register dump =========\n");
>  
> +	pm_runtime_get_sync(mdev->dev);
> +
>  	if (mdev->funcs->dump_register)
>  		mdev->funcs->dump_register(mdev, sf);
>  
>  	for (i = 0; i < mdev->n_pipelines; i++)
>  		komeda_pipeline_dump_register(mdev->pipelines[i], sf);
>  
> +	pm_runtime_put(mdev->dev);
> +
>  	return 0;
>  }
>  
> @@ -263,15 +268,6 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
>  	if (!mdev->iommu)
>  		DRM_INFO("continue without IOMMU support!\n");
>  
> -	if (mdev->iommu && mdev->funcs->connect_iommu) {
> -		err = mdev->funcs->connect_iommu(mdev);
> -		if (err) {
> -			DRM_ERROR("connect iommu failed.\n");
> -			mdev->iommu = NULL;
> -			goto disable_clk;
> -		}
> -	}
> -
>  	clk_disable_unprepare(mdev->aclk);
>  
>  	err = sysfs_create_group(&dev->kobj, &komeda_sysfs_attr_group);
> @@ -310,11 +306,6 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
>  	if (mdev->aclk)
>  		clk_prepare_enable(mdev->aclk);
>  
> -	if (mdev->iommu && mdev->funcs->disconnect_iommu)
> -		if (mdev->funcs->disconnect_iommu(mdev))
> -			DRM_ERROR("disconnect iommu failed.\n");
> -	mdev->iommu = NULL;
> -
>  	for (i = 0; i < mdev->n_pipelines; i++) {
>  		komeda_pipeline_destroy(mdev, mdev->pipelines[i]);
>  		mdev->pipelines[i] = NULL;
> @@ -343,44 +334,26 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
>  
>  int komeda_dev_resume(struct komeda_dev *mdev)
>  {
> -	int ret = 0;
> -
>  	clk_prepare_enable(mdev->aclk);
>  
> -	if (mdev->iommu && mdev->funcs->connect_iommu) {
> -		ret = mdev->funcs->connect_iommu(mdev);
> -		if (ret < 0) {
> -			DRM_ERROR("connect iommu failed.\n");
> -			goto disable_clk;
> -		}
> -	}
> -
> -	ret = mdev->funcs->enable_irq(mdev);
> +	mdev->funcs->enable_irq(mdev);
>  
> -disable_clk:
> -	clk_disable_unprepare(mdev->aclk);
> +	if (mdev->iommu && mdev->funcs->connect_iommu)
> +		if (mdev->funcs->connect_iommu(mdev))
> +			DRM_ERROR("connect iommu failed.\n");
>  
> -	return ret;
> +	return 0;
>  }
>  
>  int komeda_dev_suspend(struct komeda_dev *mdev)
>  {
> -	int ret = 0;
> -
> -	clk_prepare_enable(mdev->aclk);
> -
> -	if (mdev->iommu && mdev->funcs->disconnect_iommu) {
> -		ret = mdev->funcs->disconnect_iommu(mdev);
> -		if (ret < 0) {
> +	if (mdev->iommu && mdev->funcs->disconnect_iommu)
> +		if (mdev->funcs->disconnect_iommu(mdev))
>  			DRM_ERROR("disconnect iommu failed.\n");
> -			goto disable_clk;
> -		}
> -	}
>  
> -	ret = mdev->funcs->disable_irq(mdev);
> +	mdev->funcs->disable_irq(mdev);
>  
> -disable_clk:
>  	clk_disable_unprepare(mdev->aclk);
>  
> -	return ret;
> +	return 0;
>  }
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> index ad38bbc7431e..ea5cd1e17304 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> @@ -33,6 +33,12 @@ static void komeda_unbind(struct device *dev)
>  		return;
>  
>  	komeda_kms_detach(mdrv->kms);
> +
> +	if (pm_runtime_enabled(dev))
> +		pm_runtime_disable(dev);
> +	else
> +		komeda_dev_suspend(mdrv->mdev);
> +
>  	komeda_dev_destroy(mdrv->mdev);
>  
>  	dev_set_drvdata(dev, NULL);
> @@ -54,6 +60,10 @@ static int komeda_bind(struct device *dev)
>  		goto free_mdrv;
>  	}
>  
> +	pm_runtime_enable(dev);
> +	if (!pm_runtime_enabled(dev))
> +		komeda_dev_resume(mdrv->mdev);
> +
>  	mdrv->kms = komeda_kms_attach(mdrv->mdev);
>  	if (IS_ERR(mdrv->kms)) {
>  		err = PTR_ERR(mdrv->kms);
> @@ -65,6 +75,11 @@ static int komeda_bind(struct device *dev)
>  	return 0;
>  
>  destroy_mdev:
> +	if (pm_runtime_enabled(dev))
> +		pm_runtime_disable(dev);
> +	else
> +		komeda_dev_suspend(mdrv->mdev);
> +
>  	komeda_dev_destroy(mdrv->mdev);
>  
>  free_mdrv:
> @@ -131,15 +146,29 @@ static const struct of_device_id komeda_of_match[] = {
>  
>  MODULE_DEVICE_TABLE(of, komeda_of_match);
>  
> +static int komeda_rt_pm_suspend(struct device *dev)
> +{
> +	struct komeda_drv *mdrv = dev_get_drvdata(dev);
> +
> +	return komeda_dev_suspend(mdrv->mdev);
> +}
> +
> +static int komeda_rt_pm_resume(struct device *dev)
> +{
> +	struct komeda_drv *mdrv = dev_get_drvdata(dev);
> +
> +	return komeda_dev_resume(mdrv->mdev);
> +}
> +
>  static int __maybe_unused komeda_pm_suspend(struct device *dev)
>  {
>  	struct komeda_drv *mdrv = dev_get_drvdata(dev);
> -	struct drm_device *drm = &mdrv->kms->base;
>  	int res;
>  
> -	res = drm_mode_config_helper_suspend(drm);
> +	res = drm_mode_config_helper_suspend(&mdrv->kms->base);
>  
> -	komeda_dev_suspend(mdrv->mdev);
> +	if (!pm_runtime_status_suspended(dev))
> +		komeda_dev_suspend(mdrv->mdev);
>  
>  	return res;
>  }
> @@ -147,15 +176,16 @@ static int __maybe_unused komeda_pm_suspend(struct device *dev)
>  static int __maybe_unused komeda_pm_resume(struct device *dev)
>  {
>  	struct komeda_drv *mdrv = dev_get_drvdata(dev);
> -	struct drm_device *drm = &mdrv->kms->base;
>  
> -	komeda_dev_resume(mdrv->mdev);
> +	if (!pm_runtime_status_suspended(dev))
> +		komeda_dev_resume(mdrv->mdev);
>  
> -	return drm_mode_config_helper_resume(drm);
> +	return drm_mode_config_helper_resume(&mdrv->kms->base);
>  }
>  
>  static const struct dev_pm_ops komeda_pm_ops = {
>  	SET_SYSTEM_SLEEP_PM_OPS(komeda_pm_suspend, komeda_pm_resume)
> +	SET_RUNTIME_PM_OPS(komeda_rt_pm_suspend, komeda_rt_pm_resume, NULL)
>  };
>  
>  static struct platform_driver komeda_platform_driver = {
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> index e30a5b43caa9..9a7dcf92591a 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> @@ -307,10 +307,6 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
>  	if (err)
>  		goto free_component_binding;
>  
> -	err = mdev->funcs->enable_irq(mdev);
> -	if (err)
> -		goto free_component_binding;
> -
>  	drm->irq_enabled = true;
>  
>  	drm_kms_helper_poll_init(drm);
> @@ -324,7 +320,6 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
>  free_interrupts:
>  	drm_kms_helper_poll_fini(drm);
>  	drm->irq_enabled = false;
> -	mdev->funcs->disable_irq(mdev);
>  free_component_binding:
>  	component_unbind_all(mdev->dev, drm);
>  cleanup_mode_config:
> @@ -346,7 +341,6 @@ void komeda_kms_detach(struct komeda_kms_dev *kms)
>  	drm_kms_helper_poll_fini(drm);
>  	drm_atomic_helper_shutdown(drm);
>  	drm->irq_enabled = false;
> -	mdev->funcs->disable_irq(mdev);
>  	component_unbind_all(mdev->dev, drm);
>  	drm_mode_config_cleanup(drm);
>  	komeda_kms_cleanup_private_objs(kms);
> 

Reviewed-by: Mihail Atanassov <mihail.atanassov@arm.com>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 1c452ea75999..56bd938961ee 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -5,6 +5,7 @@ 
  *
  */
 #include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/spinlock.h>
 
 #include <drm/drm_atomic.h>
@@ -274,6 +275,7 @@  static void
 komeda_crtc_atomic_enable(struct drm_crtc *crtc,
 			  struct drm_crtc_state *old)
 {
+	pm_runtime_get_sync(crtc->dev->dev);
 	komeda_crtc_prepare(to_kcrtc(crtc));
 	drm_crtc_vblank_on(crtc);
 	WARN_ON(drm_crtc_vblank_get(crtc));
@@ -372,6 +374,7 @@  komeda_crtc_atomic_disable(struct drm_crtc *crtc,
 	drm_crtc_vblank_put(crtc);
 	drm_crtc_vblank_off(crtc);
 	komeda_crtc_unprepare(kcrtc);
+	pm_runtime_put(crtc->dev->dev);
 }
 
 static void
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 38b832804bad..1d767473ba8a 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -10,6 +10,7 @@ 
 #include <linux/of_graph.h>
 #include <linux/of_reserved_mem.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/dma-mapping.h>
 #ifdef CONFIG_DEBUG_FS
 #include <linux/debugfs.h>
@@ -27,12 +28,16 @@  static int komeda_register_show(struct seq_file *sf, void *x)
 
 	seq_puts(sf, "\n====== Komeda register dump =========\n");
 
+	pm_runtime_get_sync(mdev->dev);
+
 	if (mdev->funcs->dump_register)
 		mdev->funcs->dump_register(mdev, sf);
 
 	for (i = 0; i < mdev->n_pipelines; i++)
 		komeda_pipeline_dump_register(mdev->pipelines[i], sf);
 
+	pm_runtime_put(mdev->dev);
+
 	return 0;
 }
 
@@ -263,15 +268,6 @@  struct komeda_dev *komeda_dev_create(struct device *dev)
 	if (!mdev->iommu)
 		DRM_INFO("continue without IOMMU support!\n");
 
-	if (mdev->iommu && mdev->funcs->connect_iommu) {
-		err = mdev->funcs->connect_iommu(mdev);
-		if (err) {
-			DRM_ERROR("connect iommu failed.\n");
-			mdev->iommu = NULL;
-			goto disable_clk;
-		}
-	}
-
 	clk_disable_unprepare(mdev->aclk);
 
 	err = sysfs_create_group(&dev->kobj, &komeda_sysfs_attr_group);
@@ -310,11 +306,6 @@  void komeda_dev_destroy(struct komeda_dev *mdev)
 	if (mdev->aclk)
 		clk_prepare_enable(mdev->aclk);
 
-	if (mdev->iommu && mdev->funcs->disconnect_iommu)
-		if (mdev->funcs->disconnect_iommu(mdev))
-			DRM_ERROR("disconnect iommu failed.\n");
-	mdev->iommu = NULL;
-
 	for (i = 0; i < mdev->n_pipelines; i++) {
 		komeda_pipeline_destroy(mdev, mdev->pipelines[i]);
 		mdev->pipelines[i] = NULL;
@@ -343,44 +334,26 @@  void komeda_dev_destroy(struct komeda_dev *mdev)
 
 int komeda_dev_resume(struct komeda_dev *mdev)
 {
-	int ret = 0;
-
 	clk_prepare_enable(mdev->aclk);
 
-	if (mdev->iommu && mdev->funcs->connect_iommu) {
-		ret = mdev->funcs->connect_iommu(mdev);
-		if (ret < 0) {
-			DRM_ERROR("connect iommu failed.\n");
-			goto disable_clk;
-		}
-	}
-
-	ret = mdev->funcs->enable_irq(mdev);
+	mdev->funcs->enable_irq(mdev);
 
-disable_clk:
-	clk_disable_unprepare(mdev->aclk);
+	if (mdev->iommu && mdev->funcs->connect_iommu)
+		if (mdev->funcs->connect_iommu(mdev))
+			DRM_ERROR("connect iommu failed.\n");
 
-	return ret;
+	return 0;
 }
 
 int komeda_dev_suspend(struct komeda_dev *mdev)
 {
-	int ret = 0;
-
-	clk_prepare_enable(mdev->aclk);
-
-	if (mdev->iommu && mdev->funcs->disconnect_iommu) {
-		ret = mdev->funcs->disconnect_iommu(mdev);
-		if (ret < 0) {
+	if (mdev->iommu && mdev->funcs->disconnect_iommu)
+		if (mdev->funcs->disconnect_iommu(mdev))
 			DRM_ERROR("disconnect iommu failed.\n");
-			goto disable_clk;
-		}
-	}
 
-	ret = mdev->funcs->disable_irq(mdev);
+	mdev->funcs->disable_irq(mdev);
 
-disable_clk:
 	clk_disable_unprepare(mdev->aclk);
 
-	return ret;
+	return 0;
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
index ad38bbc7431e..ea5cd1e17304 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
@@ -33,6 +33,12 @@  static void komeda_unbind(struct device *dev)
 		return;
 
 	komeda_kms_detach(mdrv->kms);
+
+	if (pm_runtime_enabled(dev))
+		pm_runtime_disable(dev);
+	else
+		komeda_dev_suspend(mdrv->mdev);
+
 	komeda_dev_destroy(mdrv->mdev);
 
 	dev_set_drvdata(dev, NULL);
@@ -54,6 +60,10 @@  static int komeda_bind(struct device *dev)
 		goto free_mdrv;
 	}
 
+	pm_runtime_enable(dev);
+	if (!pm_runtime_enabled(dev))
+		komeda_dev_resume(mdrv->mdev);
+
 	mdrv->kms = komeda_kms_attach(mdrv->mdev);
 	if (IS_ERR(mdrv->kms)) {
 		err = PTR_ERR(mdrv->kms);
@@ -65,6 +75,11 @@  static int komeda_bind(struct device *dev)
 	return 0;
 
 destroy_mdev:
+	if (pm_runtime_enabled(dev))
+		pm_runtime_disable(dev);
+	else
+		komeda_dev_suspend(mdrv->mdev);
+
 	komeda_dev_destroy(mdrv->mdev);
 
 free_mdrv:
@@ -131,15 +146,29 @@  static const struct of_device_id komeda_of_match[] = {
 
 MODULE_DEVICE_TABLE(of, komeda_of_match);
 
+static int komeda_rt_pm_suspend(struct device *dev)
+{
+	struct komeda_drv *mdrv = dev_get_drvdata(dev);
+
+	return komeda_dev_suspend(mdrv->mdev);
+}
+
+static int komeda_rt_pm_resume(struct device *dev)
+{
+	struct komeda_drv *mdrv = dev_get_drvdata(dev);
+
+	return komeda_dev_resume(mdrv->mdev);
+}
+
 static int __maybe_unused komeda_pm_suspend(struct device *dev)
 {
 	struct komeda_drv *mdrv = dev_get_drvdata(dev);
-	struct drm_device *drm = &mdrv->kms->base;
 	int res;
 
-	res = drm_mode_config_helper_suspend(drm);
+	res = drm_mode_config_helper_suspend(&mdrv->kms->base);
 
-	komeda_dev_suspend(mdrv->mdev);
+	if (!pm_runtime_status_suspended(dev))
+		komeda_dev_suspend(mdrv->mdev);
 
 	return res;
 }
@@ -147,15 +176,16 @@  static int __maybe_unused komeda_pm_suspend(struct device *dev)
 static int __maybe_unused komeda_pm_resume(struct device *dev)
 {
 	struct komeda_drv *mdrv = dev_get_drvdata(dev);
-	struct drm_device *drm = &mdrv->kms->base;
 
-	komeda_dev_resume(mdrv->mdev);
+	if (!pm_runtime_status_suspended(dev))
+		komeda_dev_resume(mdrv->mdev);
 
-	return drm_mode_config_helper_resume(drm);
+	return drm_mode_config_helper_resume(&mdrv->kms->base);
 }
 
 static const struct dev_pm_ops komeda_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(komeda_pm_suspend, komeda_pm_resume)
+	SET_RUNTIME_PM_OPS(komeda_rt_pm_suspend, komeda_rt_pm_resume, NULL)
 };
 
 static struct platform_driver komeda_platform_driver = {
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
index e30a5b43caa9..9a7dcf92591a 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
@@ -307,10 +307,6 @@  struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
 	if (err)
 		goto free_component_binding;
 
-	err = mdev->funcs->enable_irq(mdev);
-	if (err)
-		goto free_component_binding;
-
 	drm->irq_enabled = true;
 
 	drm_kms_helper_poll_init(drm);
@@ -324,7 +320,6 @@  struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
 free_interrupts:
 	drm_kms_helper_poll_fini(drm);
 	drm->irq_enabled = false;
-	mdev->funcs->disable_irq(mdev);
 free_component_binding:
 	component_unbind_all(mdev->dev, drm);
 cleanup_mode_config:
@@ -346,7 +341,6 @@  void komeda_kms_detach(struct komeda_kms_dev *kms)
 	drm_kms_helper_poll_fini(drm);
 	drm_atomic_helper_shutdown(drm);
 	drm->irq_enabled = false;
-	mdev->funcs->disable_irq(mdev);
 	component_unbind_all(mdev->dev, drm);
 	drm_mode_config_cleanup(drm);
 	komeda_kms_cleanup_private_objs(kms);