diff options
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 34 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_drv.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 1 |
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 | ||
| 29 | static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg) | 30 | static 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; | |||
| 22 | struct drm_device; | 22 | struct drm_device; |
| 23 | struct drm_property; | 23 | struct drm_property; |
| 24 | struct rcar_du_device; | 24 | struct rcar_du_device; |
| 25 | struct 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 | ||
