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 |
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 --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);
- 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(-)