Commit 506096a1 authored by Tomi Valkeinen's avatar Tomi Valkeinen

drm/omap: fix enabling/disabling of video pipeline

At the moment the omap_crtc_pre_apply() handles the enabling, disabling
and configuring of encoders and panels separately from the CRTC (i.e.
the overlay manager).

However, this doesn't work correctly. The encoder driver has to be in
control of its video input (i.e. the crtc) for correct operation.

This problem causes bugs with (at least) HDMI: the HDMI encoder supplies
pixel clock for DISPC, and DISPC supplies video stream for HDMI. The
current code first enables the HDMI encoder, and CRTC after that.
However, the encoder expects the video stream to start during the
encoder's enable, and if it doesn't, there will be sync lost errors.

The encoder enables its video source by calling src->enable(), and this
call goes to omapdrm (omap_crtc_enable), but omapdrm doesn't do anything
in that function. Similarly for disable, which goes to
omap_crtc_disable().

This patch moves the code to setup and enable/disable the crtc to
omap_crtc_enable. and omap_crtc_disable().
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: default avatarRob Clark <robdclark@gmail.com>
parent c7aef12f
......@@ -121,13 +121,25 @@ static void omap_crtc_start_update(struct omap_overlay_manager *mgr)
{
}
static void set_enabled(struct drm_crtc *crtc, bool enable);
static int omap_crtc_enable(struct omap_overlay_manager *mgr)
{
struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info);
dispc_mgr_set_timings(omap_crtc->channel,
&omap_crtc->timings);
set_enabled(&omap_crtc->base, true);
return 0;
}
static void omap_crtc_disable(struct omap_overlay_manager *mgr)
{
struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
set_enabled(&omap_crtc->base, false);
}
static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
......@@ -601,7 +613,6 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply)
omap_crtc->current_encoder = encoder;
if (!omap_crtc->enabled) {
set_enabled(&omap_crtc->base, false);
if (encoder)
omap_encoder_set_enabled(encoder, false);
} else {
......@@ -610,13 +621,7 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply)
omap_encoder_update(encoder, omap_crtc->mgr,
&omap_crtc->timings);
omap_encoder_set_enabled(encoder, true);
omap_crtc->full_update = false;
}
dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info);
dispc_mgr_set_timings(omap_crtc->channel,
&omap_crtc->timings);
set_enabled(&omap_crtc->base, true);
}
omap_crtc->full_update = false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment