aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2017-07-13 20:26:17 -0400
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2018-09-24 17:41:02 -0400
commit0bb63534fdf3bc9a82bcfe9f5c6a9653b8b2a3f1 (patch)
tree593260193c090a1222dc2d7fd97ca7b6d39ff73a /drivers/gpu
parentc25c0136119990c62c160d95592714833bc214a5 (diff)
drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get()
The rcar_du_crtc_get() function is always immediately followed by a call to rcar_du_crtc_setup(). Call the later from the former to simplify the code, and add a comment to explain how the get and put calls are balanced. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Tested-by: Jacopo Mondi <jacopo+renesas@jmondi.org> Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c107
1 files changed, 56 insertions, 51 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 6288b9ad9e24..c89751c26f9c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -66,39 +66,6 @@ static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
66 rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set); 66 rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
67} 67}
68 68
69static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
70{
71 int ret;
72
73 ret = clk_prepare_enable(rcrtc->clock);
74 if (ret < 0)
75 return ret;
76
77 ret = clk_prepare_enable(rcrtc->extclock);
78 if (ret < 0)
79 goto error_clock;
80
81 ret = rcar_du_group_get(rcrtc->group);
82 if (ret < 0)
83 goto error_group;
84
85 return 0;
86
87error_group:
88 clk_disable_unprepare(rcrtc->extclock);
89error_clock:
90 clk_disable_unprepare(rcrtc->clock);
91 return ret;
92}
93
94static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
95{
96 rcar_du_group_put(rcrtc->group);
97
98 clk_disable_unprepare(rcrtc->extclock);
99 clk_disable_unprepare(rcrtc->clock);
100}
101
102/* ----------------------------------------------------------------------------- 69/* -----------------------------------------------------------------------------
103 * Hardware Setup 70 * Hardware Setup
104 */ 71 */
@@ -546,6 +513,51 @@ static void rcar_du_crtc_setup(struct rcar_du_crtc *rcrtc)
546 drm_crtc_vblank_on(&rcrtc->crtc); 513 drm_crtc_vblank_on(&rcrtc->crtc);
547} 514}
548 515
516static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc)
517{
518 int ret;
519
520 /*
521 * Guard against double-get, as the function is called from both the
522 * .atomic_enable() and .atomic_begin() handlers.
523 */
524 if (rcrtc->initialized)
525 return 0;
526
527 ret = clk_prepare_enable(rcrtc->clock);
528 if (ret < 0)
529 return ret;
530
531 ret = clk_prepare_enable(rcrtc->extclock);
532 if (ret < 0)
533 goto error_clock;
534
535 ret = rcar_du_group_get(rcrtc->group);
536 if (ret < 0)
537 goto error_group;
538
539 rcar_du_crtc_setup(rcrtc);
540 rcrtc->initialized = true;
541
542 return 0;
543
544error_group:
545 clk_disable_unprepare(rcrtc->extclock);
546error_clock:
547 clk_disable_unprepare(rcrtc->clock);
548 return ret;
549}
550
551static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc)
552{
553 rcar_du_group_put(rcrtc->group);
554
555 clk_disable_unprepare(rcrtc->extclock);
556 clk_disable_unprepare(rcrtc->clock);
557
558 rcrtc->initialized = false;
559}
560
549static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc) 561static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
550{ 562{
551 bool interlaced; 563 bool interlaced;
@@ -639,16 +651,7 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
639{ 651{
640 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); 652 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
641 653
642 /* 654 rcar_du_crtc_get(rcrtc);
643 * If the CRTC has already been setup by the .atomic_begin() handler we
644 * can skip the setup stage.
645 */
646 if (!rcrtc->initialized) {
647 rcar_du_crtc_get(rcrtc);
648 rcar_du_crtc_setup(rcrtc);
649 rcrtc->initialized = true;
650 }
651
652 rcar_du_crtc_start(rcrtc); 655 rcar_du_crtc_start(rcrtc);
653} 656}
654 657
@@ -667,7 +670,6 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
667 } 670 }
668 spin_unlock_irq(&crtc->dev->event_lock); 671 spin_unlock_irq(&crtc->dev->event_lock);
669 672
670 rcrtc->initialized = false;
671 rcrtc->outputs = 0; 673 rcrtc->outputs = 0;
672} 674}
673 675
@@ -680,14 +682,17 @@ static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
680 682
681 /* 683 /*
682 * If a mode set is in progress we can be called with the CRTC disabled. 684 * If a mode set is in progress we can be called with the CRTC disabled.
683 * We then need to first setup the CRTC in order to configure planes. 685 * We thus need to first get and setup the CRTC in order to configure
684 * The .atomic_enable() handler will notice and skip the CRTC setup. 686 * planes. We must *not* put the CRTC in .atomic_flush(), as it must be
687 * kept awake until the .atomic_enable() call that will follow. The get
688 * operation in .atomic_enable() will in that case be a no-op, and the
689 * CRTC will be put later in .atomic_disable().
690 *
691 * If a mode set is not in progress the CRTC is enabled, and the
692 * following get call will be a no-op. There is thus no need to belance
693 * it in .atomic_flush() either.
685 */ 694 */
686 if (!rcrtc->initialized) { 695 rcar_du_crtc_get(rcrtc);
687 rcar_du_crtc_get(rcrtc);
688 rcar_du_crtc_setup(rcrtc);
689 rcrtc->initialized = true;
690 }
691 696
692 if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE)) 697 if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
693 rcar_du_vsp_atomic_begin(rcrtc); 698 rcar_du_vsp_atomic_begin(rcrtc);