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@xxxxxxx> > --- > .../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@xxxxxxx> -- Mihail _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel