aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/sun4i/sun4i_crtc.c
diff options
context:
space:
mode:
authorMaxime Ripard2017-10-17 11:06:12 +0200
committerMaxime Ripard2017-10-17 19:49:13 +0200
commit45e88f994add84d8cd3864d36064ea1ed1b08cdf (patch)
tree07b6fabc682b762f4ac5ecb5473cc39209f24a3b /drivers/gpu/drm/sun4i/sun4i_crtc.c
parent961c645cf00c8be82b05ad10068179a86fdbc181 (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.c22
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 = {