aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c34
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.h3
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_encoder.c1
3 files changed, 38 insertions, 0 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 93ee0020c9b1..96175d48a902 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -25,6 +25,7 @@
25#include "rcar_du_plane.h" 25#include "rcar_du_plane.h"
26#include "rcar_du_regs.h" 26#include "rcar_du_regs.h"
27#include "rcar_du_vsp.h" 27#include "rcar_du_vsp.h"
28#include "rcar_lvds.h"
28 29
29static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg) 30static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
30{ 31{
@@ -656,8 +657,27 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
656 struct drm_crtc_state *old_state) 657 struct drm_crtc_state *old_state)
657{ 658{
658 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); 659 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
660 struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(crtc->state);
661 struct rcar_du_device *rcdu = rcrtc->group->dev;
659 662
660 rcar_du_crtc_get(rcrtc); 663 rcar_du_crtc_get(rcrtc);
664
665 /*
666 * On D3/E3 the dot clock is provided by the LVDS encoder attached to
667 * the DU channel. We need to enable its clock output explicitly if
668 * the LVDS output is disabled.
669 */
670 if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) &&
671 rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
672 struct rcar_du_encoder *encoder =
673 rcdu->encoders[RCAR_DU_OUTPUT_LVDS0 + rcrtc->index];
674 const struct drm_display_mode *mode =
675 &crtc->state->adjusted_mode;
676
677 rcar_lvds_clk_enable(encoder->base.bridge,
678 mode->clock * 1000);
679 }
680
661 rcar_du_crtc_start(rcrtc); 681 rcar_du_crtc_start(rcrtc);
662} 682}
663 683
@@ -665,10 +685,24 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
665 struct drm_crtc_state *old_state) 685 struct drm_crtc_state *old_state)
666{ 686{
667 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); 687 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
688 struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(old_state);
689 struct rcar_du_device *rcdu = rcrtc->group->dev;
668 690
669 rcar_du_crtc_stop(rcrtc); 691 rcar_du_crtc_stop(rcrtc);
670 rcar_du_crtc_put(rcrtc); 692 rcar_du_crtc_put(rcrtc);
671 693
694 if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) &&
695 rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
696 struct rcar_du_encoder *encoder =
697 rcdu->encoders[RCAR_DU_OUTPUT_LVDS0 + rcrtc->index];
698
699 /*
700 * Disable the LVDS clock output, see
701 * rcar_du_crtc_atomic_enable().
702 */
703 rcar_lvds_clk_disable(encoder->base.bridge);
704 }
705
672 spin_lock_irq(&crtc->dev->event_lock); 706 spin_lock_irq(&crtc->dev->event_lock);
673 if (crtc->state->event) { 707 if (crtc->state->event) {
674 drm_crtc_send_vblank_event(crtc, crtc->state->event); 708 drm_crtc_send_vblank_event(crtc, crtc->state->event);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index 6c187d0bf7c2..1327cd0df90a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -22,6 +22,7 @@ struct device;
22struct drm_device; 22struct drm_device;
23struct drm_property; 23struct drm_property;
24struct rcar_du_device; 24struct rcar_du_device;
25struct rcar_du_encoder;
25 26
26#define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK BIT(0) /* Per-CRTC IRQ and clock */ 27#define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK BIT(0) /* Per-CRTC IRQ and clock */
27#define RCAR_DU_FEATURE_VSP1_SOURCE BIT(1) /* Has inputs from VSP1 */ 28#define RCAR_DU_FEATURE_VSP1_SOURCE BIT(1) /* Has inputs from VSP1 */
@@ -81,6 +82,8 @@ struct rcar_du_device {
81 struct rcar_du_crtc crtcs[RCAR_DU_MAX_CRTCS]; 82 struct rcar_du_crtc crtcs[RCAR_DU_MAX_CRTCS];
82 unsigned int num_crtcs; 83 unsigned int num_crtcs;
83 84
85 struct rcar_du_encoder *encoders[RCAR_DU_OUTPUT_MAX];
86
84 struct rcar_du_group groups[RCAR_DU_MAX_GROUPS]; 87 struct rcar_du_group groups[RCAR_DU_MAX_GROUPS];
85 struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS]; 88 struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS];
86 89
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
index ed7ccee705cb..8ee4e762f4e5 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
@@ -41,6 +41,7 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
41 if (renc == NULL) 41 if (renc == NULL)
42 return -ENOMEM; 42 return -ENOMEM;
43 43
44 rcdu->encoders[output] = renc;
44 renc->output = output; 45 renc->output = output;
45 encoder = rcar_encoder_to_drm_encoder(renc); 46 encoder = rcar_encoder_to_drm_encoder(renc);
46 47