diff options
author | Maxime Ripard <maxime.ripard@free-electrons.com> | 2017-10-17 11:06:12 +0200 |
---|---|---|
committer | Maxime Ripard <maxime.ripard@free-electrons.com> | 2017-10-17 19:49:13 +0200 |
commit | 45e88f994add84d8cd3864d36064ea1ed1b08cdf (patch) | |
tree | 07b6fabc682b762f4ac5ecb5473cc39209f24a3b /drivers/gpu/drm/sun4i/sun4i_crtc.c | |
parent | 961c645cf00c8be82b05ad10068179a86fdbc181 (diff) |
drm/sun4i: tcon: Don't rely on encoders to enable the TCON
So far, we've required all the TCON-connected encoders to call the TCON
enable and disable functions.
This was made this way because in the RGB/LVDS case, the TCON is the CRTC
and the encoder. However, in all the other cases (HDMI, TV, DSI, etc.), we
have another encoder down the road that needs to be programmed.
We also needed to know which channel the encoder is connected to, which is
encoder-specific.
The CRTC's enable and disable callbacks can work just fine for our use
case, and we can get the channel to use just by looking at the type of
encoder, since that is fixed. Implement those callbacks, which will
remove some of the encoder boilerplate.
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Link: https://patchwork.freedesktop.org/patch/msgid/90b4396e19b3eca61b2ebfdae0672074b88ad74d.1508231063.git-series.maxime.ripard@free-electrons.com
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun4i_crtc.c')
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_crtc.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c index d097c6f93ad0..e86baa3746af 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c @@ -30,6 +30,22 @@ #include "sunxi_engine.h" #include "sun4i_tcon.h" +/* + * While this isn't really working in the DRM theory, in practice we + * can only ever have one encoder per TCON since we have a mux in our + * TCON. + */ +static struct drm_encoder *sun4i_crtc_get_encoder(struct drm_crtc *crtc) +{ + struct drm_encoder *encoder; + + drm_for_each_encoder(encoder, crtc->dev) + if (encoder->crtc == crtc) + return encoder; + + return NULL; +} + static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { @@ -72,11 +88,12 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc, static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { + struct drm_encoder *encoder = sun4i_crtc_get_encoder(crtc); struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); DRM_DEBUG_DRIVER("Disabling the CRTC\n"); - sun4i_tcon_disable(scrtc->tcon); + sun4i_tcon_set_status(scrtc->tcon, encoder, false); if (crtc->state->event && !crtc->state->active) { spin_lock_irq(&crtc->dev->event_lock); @@ -90,11 +107,12 @@ static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc, static void sun4i_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { + struct drm_encoder *encoder = sun4i_crtc_get_encoder(crtc); struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); DRM_DEBUG_DRIVER("Enabling the CRTC\n"); - sun4i_tcon_enable(scrtc->tcon); + sun4i_tcon_set_status(scrtc->tcon, encoder, true); } static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = { |