Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/komeda: Add runtime_pm support

- 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>
Reviewed-by: Mihail Atanassov <mihail.atanassov@arm.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191212074756.14678-1-james.qian.wang@arm.com

+53 -53
+3
drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
··· 5 5 * 6 6 */ 7 7 #include <linux/clk.h> 8 + #include <linux/pm_runtime.h> 8 9 #include <linux/spinlock.h> 9 10 10 11 #include <drm/drm_atomic.h> ··· 275 274 komeda_crtc_atomic_enable(struct drm_crtc *crtc, 276 275 struct drm_crtc_state *old) 277 276 { 277 + pm_runtime_get_sync(crtc->dev->dev); 278 278 komeda_crtc_prepare(to_kcrtc(crtc)); 279 279 drm_crtc_vblank_on(crtc); 280 280 WARN_ON(drm_crtc_vblank_get(crtc)); ··· 374 372 drm_crtc_vblank_put(crtc); 375 373 drm_crtc_vblank_off(crtc); 376 374 komeda_crtc_unprepare(kcrtc); 375 + pm_runtime_put(crtc->dev->dev); 377 376 } 378 377 379 378 static void
+14 -41
drivers/gpu/drm/arm/display/komeda/komeda_dev.c
··· 10 10 #include <linux/of_graph.h> 11 11 #include <linux/of_reserved_mem.h> 12 12 #include <linux/platform_device.h> 13 + #include <linux/pm_runtime.h> 13 14 #include <linux/dma-mapping.h> 14 15 #ifdef CONFIG_DEBUG_FS 15 16 #include <linux/debugfs.h> ··· 28 27 29 28 seq_puts(sf, "\n====== Komeda register dump =========\n"); 30 29 30 + pm_runtime_get_sync(mdev->dev); 31 + 31 32 if (mdev->funcs->dump_register) 32 33 mdev->funcs->dump_register(mdev, sf); 33 34 34 35 for (i = 0; i < mdev->n_pipelines; i++) 35 36 komeda_pipeline_dump_register(mdev->pipelines[i], sf); 37 + 38 + pm_runtime_put(mdev->dev); 36 39 37 40 return 0; 38 41 } ··· 268 263 if (!mdev->iommu) 269 264 DRM_INFO("continue without IOMMU support!\n"); 270 265 271 - if (mdev->iommu && mdev->funcs->connect_iommu) { 272 - err = mdev->funcs->connect_iommu(mdev); 273 - if (err) { 274 - DRM_ERROR("connect iommu failed.\n"); 275 - mdev->iommu = NULL; 276 - goto disable_clk; 277 - } 278 - } 279 - 280 266 clk_disable_unprepare(mdev->aclk); 281 267 282 268 err = sysfs_create_group(&dev->kobj, &komeda_sysfs_attr_group); ··· 306 310 if (mdev->aclk) 307 311 clk_prepare_enable(mdev->aclk); 308 312 309 - if (mdev->iommu && mdev->funcs->disconnect_iommu) 310 - if (mdev->funcs->disconnect_iommu(mdev)) 311 - DRM_ERROR("disconnect iommu failed.\n"); 312 - mdev->iommu = NULL; 313 - 314 313 for (i = 0; i < mdev->n_pipelines; i++) { 315 314 komeda_pipeline_destroy(mdev, mdev->pipelines[i]); 316 315 mdev->pipelines[i] = NULL; ··· 334 343 335 344 int komeda_dev_resume(struct komeda_dev *mdev) 336 345 { 337 - int ret = 0; 338 - 339 346 clk_prepare_enable(mdev->aclk); 340 347 341 - if (mdev->iommu && mdev->funcs->connect_iommu) { 342 - ret = mdev->funcs->connect_iommu(mdev); 343 - if (ret < 0) { 348 + mdev->funcs->enable_irq(mdev); 349 + 350 + if (mdev->iommu && mdev->funcs->connect_iommu) 351 + if (mdev->funcs->connect_iommu(mdev)) 344 352 DRM_ERROR("connect iommu failed.\n"); 345 - goto disable_clk; 346 - } 347 - } 348 353 349 - ret = mdev->funcs->enable_irq(mdev); 350 - 351 - disable_clk: 352 - clk_disable_unprepare(mdev->aclk); 353 - 354 - return ret; 354 + return 0; 355 355 } 356 356 357 357 int komeda_dev_suspend(struct komeda_dev *mdev) 358 358 { 359 - int ret = 0; 360 - 361 - clk_prepare_enable(mdev->aclk); 362 - 363 - if (mdev->iommu && mdev->funcs->disconnect_iommu) { 364 - ret = mdev->funcs->disconnect_iommu(mdev); 365 - if (ret < 0) { 359 + if (mdev->iommu && mdev->funcs->disconnect_iommu) 360 + if (mdev->funcs->disconnect_iommu(mdev)) 366 361 DRM_ERROR("disconnect iommu failed.\n"); 367 - goto disable_clk; 368 - } 369 - } 370 362 371 - ret = mdev->funcs->disable_irq(mdev); 363 + mdev->funcs->disable_irq(mdev); 372 364 373 - disable_clk: 374 365 clk_disable_unprepare(mdev->aclk); 375 366 376 - return ret; 367 + return 0; 377 368 }
+36 -6
drivers/gpu/drm/arm/display/komeda/komeda_drv.c
··· 33 33 return; 34 34 35 35 komeda_kms_detach(mdrv->kms); 36 + 37 + if (pm_runtime_enabled(dev)) 38 + pm_runtime_disable(dev); 39 + else 40 + komeda_dev_suspend(mdrv->mdev); 41 + 36 42 komeda_dev_destroy(mdrv->mdev); 37 43 38 44 dev_set_drvdata(dev, NULL); ··· 60 54 goto free_mdrv; 61 55 } 62 56 57 + pm_runtime_enable(dev); 58 + if (!pm_runtime_enabled(dev)) 59 + komeda_dev_resume(mdrv->mdev); 60 + 63 61 mdrv->kms = komeda_kms_attach(mdrv->mdev); 64 62 if (IS_ERR(mdrv->kms)) { 65 63 err = PTR_ERR(mdrv->kms); ··· 75 65 return 0; 76 66 77 67 destroy_mdev: 68 + if (pm_runtime_enabled(dev)) 69 + pm_runtime_disable(dev); 70 + else 71 + komeda_dev_suspend(mdrv->mdev); 72 + 78 73 komeda_dev_destroy(mdrv->mdev); 79 74 80 75 free_mdrv: ··· 146 131 147 132 MODULE_DEVICE_TABLE(of, komeda_of_match); 148 133 134 + static int komeda_rt_pm_suspend(struct device *dev) 135 + { 136 + struct komeda_drv *mdrv = dev_get_drvdata(dev); 137 + 138 + return komeda_dev_suspend(mdrv->mdev); 139 + } 140 + 141 + static int komeda_rt_pm_resume(struct device *dev) 142 + { 143 + struct komeda_drv *mdrv = dev_get_drvdata(dev); 144 + 145 + return komeda_dev_resume(mdrv->mdev); 146 + } 147 + 149 148 static int __maybe_unused komeda_pm_suspend(struct device *dev) 150 149 { 151 150 struct komeda_drv *mdrv = dev_get_drvdata(dev); 152 - struct drm_device *drm = &mdrv->kms->base; 153 151 int res; 154 152 155 - res = drm_mode_config_helper_suspend(drm); 153 + res = drm_mode_config_helper_suspend(&mdrv->kms->base); 156 154 157 - komeda_dev_suspend(mdrv->mdev); 155 + if (!pm_runtime_status_suspended(dev)) 156 + komeda_dev_suspend(mdrv->mdev); 158 157 159 158 return res; 160 159 } ··· 176 147 static int __maybe_unused komeda_pm_resume(struct device *dev) 177 148 { 178 149 struct komeda_drv *mdrv = dev_get_drvdata(dev); 179 - struct drm_device *drm = &mdrv->kms->base; 180 150 181 - komeda_dev_resume(mdrv->mdev); 151 + if (!pm_runtime_status_suspended(dev)) 152 + komeda_dev_resume(mdrv->mdev); 182 153 183 - return drm_mode_config_helper_resume(drm); 154 + return drm_mode_config_helper_resume(&mdrv->kms->base); 184 155 } 185 156 186 157 static const struct dev_pm_ops komeda_pm_ops = { 187 158 SET_SYSTEM_SLEEP_PM_OPS(komeda_pm_suspend, komeda_pm_resume) 159 + SET_RUNTIME_PM_OPS(komeda_rt_pm_suspend, komeda_rt_pm_resume, NULL) 188 160 }; 189 161 190 162 static struct platform_driver komeda_platform_driver = {
-6
drivers/gpu/drm/arm/display/komeda/komeda_kms.c
··· 307 307 if (err) 308 308 goto free_component_binding; 309 309 310 - err = mdev->funcs->enable_irq(mdev); 311 - if (err) 312 - goto free_component_binding; 313 - 314 310 drm->irq_enabled = true; 315 311 316 312 drm_kms_helper_poll_init(drm); ··· 320 324 free_interrupts: 321 325 drm_kms_helper_poll_fini(drm); 322 326 drm->irq_enabled = false; 323 - mdev->funcs->disable_irq(mdev); 324 327 free_component_binding: 325 328 component_unbind_all(mdev->dev, drm); 326 329 cleanup_mode_config: ··· 341 346 drm_kms_helper_poll_fini(drm); 342 347 drm_atomic_helper_shutdown(drm); 343 348 drm->irq_enabled = false; 344 - mdev->funcs->disable_irq(mdev); 345 349 component_unbind_all(mdev->dev, drm); 346 350 drm_mode_config_cleanup(drm); 347 351 komeda_kms_cleanup_private_objs(kms);