aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2015-02-18 08:47:27 -0500
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2015-03-03 09:16:11 -0500
commit845f46356ba490b654194b8d5c26032841719a78 (patch)
treeb243b4e4149ecfd49bac22be4a7ad556b4b163b6
parent920888a2d56f0ef7117bf3456cacb49c6801d8de (diff)
drm: rcar-du: Handle primary plane config through atomic plane ops
Use the new CRTC atomic transitional helpers drm_helper_crtc_mode_set() and drm_helper_crtc_mode_set_base() to implement the CRTC .mode_set and .mode_set_base operations. This delegates primary plane configuration to the plane .atomic_update and .atomic_disable operations, removing duplicate code from the CRTC implementation. There is now no code path available to the driver in which to drop the reference to the CRTC acquired in the .prepare() operation if an error then occurs. The driver thus now leaks a reference if an error occurs during mode set. So be it, this will be fixed in a further step of the atomic update transition. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c81
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c8
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.h3
3 files changed, 14 insertions, 78 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 3d862a894b17..169558a3ab40 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -105,7 +105,7 @@ static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
105 105
106static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) 106static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
107{ 107{
108 const struct drm_display_mode *mode = &rcrtc->crtc.mode; 108 const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
109 unsigned long mode_clock = mode->clock * 1000; 109 unsigned long mode_clock = mode->clock * 1000;
110 unsigned long clk; 110 unsigned long clk;
111 u32 value; 111 u32 value;
@@ -368,7 +368,6 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
368 * switching to atomic updates completely. 368 * switching to atomic updates completely.
369 */ 369 */
370 mutex_lock(&rcrtc->group->planes.lock); 370 mutex_lock(&rcrtc->group->planes.lock);
371 rcrtc->plane->enabled = true;
372 rcar_du_crtc_update_planes(crtc); 371 rcar_du_crtc_update_planes(crtc);
373 mutex_unlock(&rcrtc->group->planes.lock); 372 mutex_unlock(&rcrtc->group->planes.lock);
374 373
@@ -412,11 +411,6 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
412 rcar_du_crtc_wait_page_flip(rcrtc); 411 rcar_du_crtc_wait_page_flip(rcrtc);
413 drm_crtc_vblank_off(crtc); 412 drm_crtc_vblank_off(crtc);
414 413
415 mutex_lock(&rcrtc->group->planes.lock);
416 rcrtc->plane->enabled = false;
417 rcar_du_crtc_update_planes(crtc);
418 mutex_unlock(&rcrtc->group->planes.lock);
419
420 /* Select switch sync mode. This stops display operation and configures 414 /* Select switch sync mode. This stops display operation and configures
421 * the HSYNC and VSYNC signals as inputs. 415 * the HSYNC and VSYNC signals as inputs.
422 */ 416 */
@@ -492,58 +486,20 @@ static void rcar_du_crtc_mode_prepare(struct drm_crtc *crtc)
492 */ 486 */
493 rcar_du_crtc_get(rcrtc); 487 rcar_du_crtc_get(rcrtc);
494 488
495 /* Stop the CRTC and release the plane. Force the DPMS mode to off as a 489 /* Stop the CRTC, force the DPMS mode to off as a result. */
496 * result.
497 */
498 rcar_du_crtc_stop(rcrtc); 490 rcar_du_crtc_stop(rcrtc);
499 rcar_du_plane_release(rcrtc->plane);
500 491
501 rcrtc->dpms = DRM_MODE_DPMS_OFF; 492 rcrtc->dpms = DRM_MODE_DPMS_OFF;
493 rcrtc->outputs = 0;
502} 494}
503 495
504static int rcar_du_crtc_mode_set(struct drm_crtc *crtc, 496static void rcar_du_crtc_mode_set_nofb(struct drm_crtc *crtc)
505 struct drm_display_mode *mode,
506 struct drm_display_mode *adjusted_mode,
507 int x, int y,
508 struct drm_framebuffer *old_fb)
509{ 497{
510 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); 498 /* No-op. We should configure the display timings here, but as we're
511 struct rcar_du_device *rcdu = rcrtc->group->dev; 499 * called with the CRTC disabled clocks might be off, and we thus can't
512 const struct rcar_du_format_info *format; 500 * access the hardware. Let's just configure everything when enabling
513 int ret; 501 * the CRTC.
514
515 format = rcar_du_format_info(crtc->primary->fb->pixel_format);
516 if (format == NULL) {
517 dev_dbg(rcdu->dev, "mode_set: unsupported format %08x\n",
518 crtc->primary->fb->pixel_format);
519 ret = -EINVAL;
520 goto error;
521 }
522
523 ret = rcar_du_plane_reserve(rcrtc->plane, format);
524 if (ret < 0)
525 goto error;
526
527 rcrtc->plane->format = format;
528
529 rcrtc->plane->src_x = x;
530 rcrtc->plane->src_y = y;
531 rcrtc->plane->width = mode->hdisplay;
532 rcrtc->plane->height = mode->vdisplay;
533
534 rcar_du_plane_compute_base(rcrtc->plane, crtc->primary->fb);
535
536 rcrtc->outputs = 0;
537
538 return 0;
539
540error:
541 /* There's no rollback/abort operation to clean up in case of error. We
542 * thus need to release the reference to the CRTC acquired in prepare()
543 * here.
544 */ 502 */
545 rcar_du_crtc_put(rcrtc);
546 return ret;
547} 503}
548 504
549static void rcar_du_crtc_mode_commit(struct drm_crtc *crtc) 505static void rcar_du_crtc_mode_commit(struct drm_crtc *crtc)
@@ -558,25 +514,9 @@ static void rcar_du_crtc_mode_commit(struct drm_crtc *crtc)
558 rcrtc->dpms = DRM_MODE_DPMS_ON; 514 rcrtc->dpms = DRM_MODE_DPMS_ON;
559} 515}
560 516
561static int rcar_du_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
562 struct drm_framebuffer *old_fb)
563{
564 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
565
566 rcrtc->plane->src_x = x;
567 rcrtc->plane->src_y = y;
568
569 rcar_du_crtc_update_base(rcrtc);
570
571 return 0;
572}
573
574static void rcar_du_crtc_disable(struct drm_crtc *crtc) 517static void rcar_du_crtc_disable(struct drm_crtc *crtc)
575{ 518{
576 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
577
578 rcar_du_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 519 rcar_du_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
579 rcar_du_plane_release(rcrtc->plane);
580} 520}
581 521
582static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc) 522static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc)
@@ -608,8 +548,9 @@ static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
608 .mode_fixup = rcar_du_crtc_mode_fixup, 548 .mode_fixup = rcar_du_crtc_mode_fixup,
609 .prepare = rcar_du_crtc_mode_prepare, 549 .prepare = rcar_du_crtc_mode_prepare,
610 .commit = rcar_du_crtc_mode_commit, 550 .commit = rcar_du_crtc_mode_commit,
611 .mode_set = rcar_du_crtc_mode_set, 551 .mode_set = drm_helper_crtc_mode_set,
612 .mode_set_base = rcar_du_crtc_mode_set_base, 552 .mode_set_nofb = rcar_du_crtc_mode_set_nofb,
553 .mode_set_base = drm_helper_crtc_mode_set_base,
613 .disable = rcar_du_crtc_disable, 554 .disable = rcar_du_crtc_disable,
614 .atomic_begin = rcar_du_crtc_atomic_begin, 555 .atomic_begin = rcar_du_crtc_atomic_begin,
615 .atomic_flush = rcar_du_crtc_atomic_flush, 556 .atomic_flush = rcar_du_crtc_atomic_flush,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index 03995c15bbe3..d4682ac7db03 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -78,8 +78,8 @@ static int rcar_du_plane_reserve_check(struct rcar_du_plane *plane,
78 return ret; 78 return ret;
79} 79}
80 80
81int rcar_du_plane_reserve(struct rcar_du_plane *plane, 81static int rcar_du_plane_reserve(struct rcar_du_plane *plane,
82 const struct rcar_du_format_info *format) 82 const struct rcar_du_format_info *format)
83{ 83{
84 struct rcar_du_group *rgrp = plane->group; 84 struct rcar_du_group *rgrp = plane->group;
85 unsigned int i; 85 unsigned int i;
@@ -112,7 +112,7 @@ done:
112 return ret; 112 return ret;
113} 113}
114 114
115void rcar_du_plane_release(struct rcar_du_plane *plane) 115static void rcar_du_plane_release(struct rcar_du_plane *plane)
116{ 116{
117 struct rcar_du_group *rgrp = plane->group; 117 struct rcar_du_group *rgrp = plane->group;
118 118
@@ -363,7 +363,6 @@ static void rcar_du_plane_disable(struct rcar_du_plane *rplane)
363 363
364 mutex_lock(&rplane->group->planes.lock); 364 mutex_lock(&rplane->group->planes.lock);
365 rplane->enabled = false; 365 rplane->enabled = false;
366 rcar_du_crtc_update_planes(rplane->crtc);
367 mutex_unlock(&rplane->group->planes.lock); 366 mutex_unlock(&rplane->group->planes.lock);
368 367
369 rcar_du_plane_release(rplane); 368 rcar_du_plane_release(rplane);
@@ -411,7 +410,6 @@ static void rcar_du_plane_atomic_update(struct drm_plane *plane,
411 410
412 mutex_lock(&rplane->group->planes.lock); 411 mutex_lock(&rplane->group->planes.lock);
413 rplane->enabled = true; 412 rplane->enabled = true;
414 rcar_du_crtc_update_planes(rplane->crtc);
415 mutex_unlock(&rplane->group->planes.lock); 413 mutex_unlock(&rplane->group->planes.lock);
416} 414}
417 415
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
index 813b3212392a..55d2f55faece 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
@@ -73,8 +73,5 @@ void rcar_du_plane_setup(struct rcar_du_plane *plane);
73void rcar_du_plane_update_base(struct rcar_du_plane *plane); 73void rcar_du_plane_update_base(struct rcar_du_plane *plane);
74void rcar_du_plane_compute_base(struct rcar_du_plane *plane, 74void rcar_du_plane_compute_base(struct rcar_du_plane *plane,
75 struct drm_framebuffer *fb); 75 struct drm_framebuffer *fb);
76int rcar_du_plane_reserve(struct rcar_du_plane *plane,
77 const struct rcar_du_format_info *format);
78void rcar_du_plane_release(struct rcar_du_plane *plane);
79 76
80#endif /* __RCAR_DU_PLANE_H__ */ 77#endif /* __RCAR_DU_PLANE_H__ */