aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/arm/hdlcd_crtc.c23
-rw-r--r--drivers/gpu/drm/arm/hdlcd_drv.c48
-rw-r--r--drivers/gpu/drm/arm/hdlcd_drv.h3
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
36static 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
36static const struct drm_crtc_funcs hdlcd_crtc_funcs = { 45static 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
297void hdlcd_crtc_suspend(struct drm_crtc *crtc)
298{
299 hdlcd_crtc_disable(crtc);
300}
301
302void hdlcd_crtc_resume(struct drm_crtc *crtc)
303{
304 hdlcd_crtc_enable(crtc);
305}
306
307int hdlcd_setup_crtc(struct drm_device *drm) 306int 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);
401err_vblank: 403err_vblank:
404 pm_runtime_disable(drm->dev);
405err_pm_active:
402 component_unbind_all(dev, drm); 406 component_unbind_all(dev, drm);
403err_unregister: 407err_unregister:
404 drm_dev_unregister(drm); 408 drm_dev_unregister(drm);
405err_unload: 409err_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);
411err_free: 412err_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);
495static int __maybe_unused hdlcd_pm_suspend(struct device *dev) 497static 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
510static int __maybe_unused hdlcd_pm_resume(struct device *dev) 516static 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
37int hdlcd_setup_crtc(struct drm_device *dev); 38int hdlcd_setup_crtc(struct drm_device *dev);
38void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd); 39void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd);
39void hdlcd_crtc_suspend(struct drm_crtc *crtc);
40void hdlcd_crtc_resume(struct drm_crtc *crtc);
41 40
42#endif /* __HDLCD_DRV_H__ */ 41#endif /* __HDLCD_DRV_H__ */