diff options
author | Chen-Yu Tsai | 2017-10-10 11:19:59 +0800 |
---|---|---|
committer | Maxime Ripard | 2017-10-11 09:52:50 +0200 |
commit | 67e326450d7af554e80fbbac73b2b65b6468afca (patch) | |
tree | 0ebc3729719c3c2d4c449873c6ed3ee1fc2a0b16 /drivers | |
parent | ad537fb2abb0a10e60f702cd1ff14666f54457e3 (diff) |
drm/sun4i: tcon: Add support for demuxing TCON output on A31
On systems with 2 TCONs such as the A31, it is possible to demux the
output of the TCONs to one encoder.
Add support for this for the A31.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171010032008.682-3-wens@csie.org
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_tcon.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 75124043d655..68751b999877 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -112,6 +112,27 @@ void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable) } EXPORT_SYMBOL(sun4i_tcon_enable_vblank); +/* + * This function is a helper for TCON output muxing. The TCON output + * muxing control register in earlier SoCs (without the TCON TOP block) + * are located in TCON0. This helper returns a pointer to TCON0's + * sun4i_tcon structure, or NULL if not found. + */ +static struct sun4i_tcon *sun4i_get_tcon0(struct drm_device *drm) +{ + struct sun4i_drv *drv = drm->dev_private; + struct sun4i_tcon *tcon; + + list_for_each_entry(tcon, &drv->tcon_list, list) + if (tcon->id == 0) + return tcon; + + dev_warn(drm->dev, + "TCON0 not found, display output muxing may not work\n"); + + return NULL; +} + void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel, struct drm_encoder *encoder) { @@ -777,6 +798,31 @@ static int sun5i_a13_tcon_set_mux(struct sun4i_tcon *tcon, return regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, val); } +static int sun6i_tcon_set_mux(struct sun4i_tcon *tcon, + struct drm_encoder *encoder) +{ + struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev); + u32 shift; + + if (!tcon0) + return -EINVAL; + + switch (encoder->encoder_type) { + case DRM_MODE_ENCODER_TMDS: + /* HDMI */ + shift = 8; + break; + default: + /* TODO A31 has MIPI DSI but A31s does not */ + return -EINVAL; + } + + regmap_update_bits(tcon0->regs, SUN4I_TCON_MUX_CTRL_REG, + 0x3 << shift, tcon->id << shift); + + return 0; +} + static const struct sun4i_tcon_quirks sun5i_a13_quirks = { .has_channel_1 = true, .set_mux = sun5i_a13_tcon_set_mux, @@ -785,6 +831,7 @@ static const struct sun4i_tcon_quirks sun5i_a13_quirks = { static const struct sun4i_tcon_quirks sun6i_a31_quirks = { .has_channel_1 = true, .needs_de_be_mux = true, + .set_mux = sun6i_tcon_set_mux, }; static const struct sun4i_tcon_quirks sun6i_a31s_quirks = { |