diff options
| -rw-r--r-- | drivers/gpu/drm/arm/hdlcd_crtc.c | 23 | ||||
| -rw-r--r-- | drivers/gpu/drm/arm/hdlcd_drv.c | 48 | ||||
| -rw-r--r-- | drivers/gpu/drm/arm/hdlcd_drv.h | 3 |
3 files changed, 39 insertions, 35 deletions
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index fef1b04c2aab..d1e8d31e37ee 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c | |||
| @@ -33,8 +33,17 @@ | |||
| 33 | * | 33 | * |
| 34 | */ | 34 | */ |
| 35 | 35 | ||
| 36 | static void hdlcd_crtc_cleanup(struct drm_crtc *crtc) | ||
| 37 | { | ||
| 38 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | ||
| 39 | |||
| 40 | /* stop the controller on cleanup */ | ||
| 41 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); | ||
| 42 | drm_crtc_cleanup(crtc); | ||
| 43 | } | ||
| 44 | |||
| 36 | static const struct drm_crtc_funcs hdlcd_crtc_funcs = { | 45 | static const struct drm_crtc_funcs hdlcd_crtc_funcs = { |
| 37 | .destroy = drm_crtc_cleanup, | 46 | .destroy = hdlcd_crtc_cleanup, |
| 38 | .set_config = drm_atomic_helper_set_config, | 47 | .set_config = drm_atomic_helper_set_config, |
| 39 | .page_flip = drm_atomic_helper_page_flip, | 48 | .page_flip = drm_atomic_helper_page_flip, |
| 40 | .reset = drm_atomic_helper_crtc_reset, | 49 | .reset = drm_atomic_helper_crtc_reset, |
| @@ -155,8 +164,8 @@ static void hdlcd_crtc_disable(struct drm_crtc *crtc) | |||
| 155 | if (!crtc->primary->fb) | 164 | if (!crtc->primary->fb) |
| 156 | return; | 165 | return; |
| 157 | 166 | ||
| 158 | clk_disable_unprepare(hdlcd->clk); | ||
| 159 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); | 167 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); |
| 168 | clk_disable_unprepare(hdlcd->clk); | ||
| 160 | drm_crtc_vblank_off(crtc); | 169 | drm_crtc_vblank_off(crtc); |
| 161 | } | 170 | } |
| 162 | 171 | ||
| @@ -294,16 +303,6 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) | |||
| 294 | return plane; | 303 | return plane; |
| 295 | } | 304 | } |
| 296 | 305 | ||
| 297 | void hdlcd_crtc_suspend(struct drm_crtc *crtc) | ||
| 298 | { | ||
| 299 | hdlcd_crtc_disable(crtc); | ||
| 300 | } | ||
| 301 | |||
| 302 | void hdlcd_crtc_resume(struct drm_crtc *crtc) | ||
| 303 | { | ||
| 304 | hdlcd_crtc_enable(crtc); | ||
| 305 | } | ||
| 306 | |||
| 307 | int hdlcd_setup_crtc(struct drm_device *drm) | 306 | int hdlcd_setup_crtc(struct drm_device *drm) |
| 308 | { | 307 | { |
| 309 | struct hdlcd_drm_private *hdlcd = drm->dev_private; | 308 | struct hdlcd_drm_private *hdlcd = drm->dev_private; |
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index b987c63ba8d6..21b1427fc918 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c | |||
| @@ -84,11 +84,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) | |||
| 84 | goto setup_fail; | 84 | goto setup_fail; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | pm_runtime_enable(drm->dev); | ||
| 88 | |||
| 89 | pm_runtime_get_sync(drm->dev); | ||
| 90 | ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); | 87 | ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); |
| 91 | pm_runtime_put_sync(drm->dev); | ||
| 92 | if (ret < 0) { | 88 | if (ret < 0) { |
| 93 | DRM_ERROR("failed to install IRQ handler\n"); | 89 | DRM_ERROR("failed to install IRQ handler\n"); |
| 94 | goto irq_fail; | 90 | goto irq_fail; |
| @@ -357,6 +353,8 @@ static int hdlcd_drm_bind(struct device *dev) | |||
| 357 | return -ENOMEM; | 353 | return -ENOMEM; |
| 358 | 354 | ||
| 359 | drm->dev_private = hdlcd; | 355 | drm->dev_private = hdlcd; |
| 356 | dev_set_drvdata(dev, drm); | ||
| 357 | |||
| 360 | hdlcd_setup_mode_config(drm); | 358 | hdlcd_setup_mode_config(drm); |
| 361 | ret = hdlcd_load(drm, 0); | 359 | ret = hdlcd_load(drm, 0); |
| 362 | if (ret) | 360 | if (ret) |
| @@ -366,14 +364,18 @@ static int hdlcd_drm_bind(struct device *dev) | |||
| 366 | if (ret) | 364 | if (ret) |
| 367 | goto err_unload; | 365 | goto err_unload; |
| 368 | 366 | ||
| 369 | dev_set_drvdata(dev, drm); | ||
| 370 | |||
| 371 | ret = component_bind_all(dev, drm); | 367 | ret = component_bind_all(dev, drm); |
| 372 | if (ret) { | 368 | if (ret) { |
| 373 | DRM_ERROR("Failed to bind all components\n"); | 369 | DRM_ERROR("Failed to bind all components\n"); |
| 374 | goto err_unregister; | 370 | goto err_unregister; |
| 375 | } | 371 | } |
| 376 | 372 | ||
| 373 | ret = pm_runtime_set_active(dev); | ||
| 374 | if (ret) | ||
| 375 | goto err_pm_active; | ||
| 376 | |||
| 377 | pm_runtime_enable(dev); | ||
| 378 | |||
| 377 | ret = drm_vblank_init(drm, drm->mode_config.num_crtc); | 379 | ret = drm_vblank_init(drm, drm->mode_config.num_crtc); |
| 378 | if (ret < 0) { | 380 | if (ret < 0) { |
| 379 | DRM_ERROR("failed to initialise vblank\n"); | 381 | DRM_ERROR("failed to initialise vblank\n"); |
| @@ -399,16 +401,16 @@ err_fbdev: | |||
| 399 | drm_mode_config_cleanup(drm); | 401 | drm_mode_config_cleanup(drm); |
| 400 | drm_vblank_cleanup(drm); | 402 | drm_vblank_cleanup(drm); |
| 401 | err_vblank: | 403 | err_vblank: |
| 404 | pm_runtime_disable(drm->dev); | ||
| 405 | err_pm_active: | ||
| 402 | component_unbind_all(dev, drm); | 406 | component_unbind_all(dev, drm); |
| 403 | err_unregister: | 407 | err_unregister: |
| 404 | drm_dev_unregister(drm); | 408 | drm_dev_unregister(drm); |
| 405 | err_unload: | 409 | err_unload: |
| 406 | pm_runtime_get_sync(drm->dev); | ||
| 407 | drm_irq_uninstall(drm); | 410 | drm_irq_uninstall(drm); |
| 408 | pm_runtime_put_sync(drm->dev); | ||
| 409 | pm_runtime_disable(drm->dev); | ||
| 410 | of_reserved_mem_device_release(drm->dev); | 411 | of_reserved_mem_device_release(drm->dev); |
| 411 | err_free: | 412 | err_free: |
| 413 | dev_set_drvdata(dev, NULL); | ||
| 412 | drm_dev_unref(drm); | 414 | drm_dev_unref(drm); |
| 413 | 415 | ||
| 414 | return ret; | 416 | return ret; |
| @@ -495,30 +497,34 @@ MODULE_DEVICE_TABLE(of, hdlcd_of_match); | |||
| 495 | static int __maybe_unused hdlcd_pm_suspend(struct device *dev) | 497 | static int __maybe_unused hdlcd_pm_suspend(struct device *dev) |
| 496 | { | 498 | { |
| 497 | struct drm_device *drm = dev_get_drvdata(dev); | 499 | struct drm_device *drm = dev_get_drvdata(dev); |
| 498 | struct drm_crtc *crtc; | 500 | struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL; |
| 499 | 501 | ||
| 500 | if (pm_runtime_suspended(dev)) | 502 | if (!hdlcd) |
| 501 | return 0; | 503 | return 0; |
| 502 | 504 | ||
| 503 | drm_modeset_lock_all(drm); | 505 | drm_kms_helper_poll_disable(drm); |
| 504 | list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) | 506 | |
| 505 | hdlcd_crtc_suspend(crtc); | 507 | hdlcd->state = drm_atomic_helper_suspend(drm); |
| 506 | drm_modeset_unlock_all(drm); | 508 | if (IS_ERR(hdlcd->state)) { |
| 509 | drm_kms_helper_poll_enable(drm); | ||
| 510 | return PTR_ERR(hdlcd->state); | ||
| 511 | } | ||
| 512 | |||
| 507 | return 0; | 513 | return 0; |
| 508 | } | 514 | } |
| 509 | 515 | ||
| 510 | static int __maybe_unused hdlcd_pm_resume(struct device *dev) | 516 | static int __maybe_unused hdlcd_pm_resume(struct device *dev) |
| 511 | { | 517 | { |
| 512 | struct drm_device *drm = dev_get_drvdata(dev); | 518 | struct drm_device *drm = dev_get_drvdata(dev); |
| 513 | struct drm_crtc *crtc; | 519 | struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL; |
| 514 | 520 | ||
| 515 | if (!pm_runtime_suspended(dev)) | 521 | if (!hdlcd) |
| 516 | return 0; | 522 | return 0; |
| 517 | 523 | ||
| 518 | drm_modeset_lock_all(drm); | 524 | drm_atomic_helper_resume(drm, hdlcd->state); |
| 519 | list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) | 525 | drm_kms_helper_poll_enable(drm); |
| 520 | hdlcd_crtc_resume(crtc); | 526 | pm_runtime_set_active(dev); |
| 521 | drm_modeset_unlock_all(drm); | 527 | |
| 522 | return 0; | 528 | return 0; |
| 523 | } | 529 | } |
| 524 | 530 | ||
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h index aa234784f053..e7cea8233958 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.h +++ b/drivers/gpu/drm/arm/hdlcd_drv.h | |||
| @@ -13,6 +13,7 @@ struct hdlcd_drm_private { | |||
| 13 | struct list_head event_list; | 13 | struct list_head event_list; |
| 14 | struct drm_crtc crtc; | 14 | struct drm_crtc crtc; |
| 15 | struct drm_plane *plane; | 15 | struct drm_plane *plane; |
| 16 | struct drm_atomic_state *state; | ||
| 16 | #ifdef CONFIG_DEBUG_FS | 17 | #ifdef CONFIG_DEBUG_FS |
| 17 | atomic_t buffer_underrun_count; | 18 | atomic_t buffer_underrun_count; |
| 18 | atomic_t bus_error_count; | 19 | atomic_t bus_error_count; |
| @@ -36,7 +37,5 @@ static inline u32 hdlcd_read(struct hdlcd_drm_private *hdlcd, unsigned int reg) | |||
| 36 | 37 | ||
| 37 | int hdlcd_setup_crtc(struct drm_device *dev); | 38 | int hdlcd_setup_crtc(struct drm_device *dev); |
| 38 | void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd); | 39 | void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd); |
| 39 | void hdlcd_crtc_suspend(struct drm_crtc *crtc); | ||
| 40 | void hdlcd_crtc_resume(struct drm_crtc *crtc); | ||
| 41 | 40 | ||
| 42 | #endif /* __HDLCD_DRV_H__ */ | 41 | #endif /* __HDLCD_DRV_H__ */ |
