diff options
author | Vincent Abriou <vincent.abriou@st.com> | 2016-02-01 12:32:42 +0300 |
---|---|---|
committer | Vincent Abriou <vincent.abriou@st.com> | 2016-02-26 12:06:19 +0300 |
commit | 181975a2dcd5eb0caaa498f3870a0d7fc72711b2 (patch) | |
tree | 1dc9ce962b2a6237d677ad76a90396a97f1dc15a /drivers | |
parent | 50f2138a1c463eb5a256e3c19619753c70a0cbac (diff) | |
download | linux-181975a2dcd5eb0caaa498f3870a0d7fc72711b2.tar.xz |
drm/sti: reset infoframe transmission when HDMI is stopped
Clear all infoframe registers when the HDMI link is stopped.
Signed-off-by: Vincent Abriou <vincent.abriou@st.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/sti/sti_hdmi.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c index 8537852f0984..ff04ed2bb7a3 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.c +++ b/drivers/gpu/drm/sti/sti_hdmi.c @@ -65,6 +65,8 @@ #define HDMI_SW_DI_N_PKT_WORD5(x) XCAT(HDMI_SW_DI_, x, _PKT_WORD5) #define HDMI_SW_DI_N_PKT_WORD6(x) XCAT(HDMI_SW_DI_, x, _PKT_WORD6) +#define HDMI_SW_DI_MAX_WORD 7 + #define HDMI_IFRAME_DISABLED 0x0 #define HDMI_IFRAME_SINGLE_SHOT 0x1 #define HDMI_IFRAME_FIELD 0x2 @@ -241,6 +243,43 @@ static void hdmi_config(struct sti_hdmi *hdmi) hdmi_write(hdmi, conf, HDMI_CFG); } +/* + * Helper to reset info frame + * + * @hdmi: pointer on the hdmi internal structure + * @slot: infoframe to reset + */ +static void hdmi_infoframe_reset(struct sti_hdmi *hdmi, + u32 slot) +{ + u32 val, i; + u32 head_offset, pack_offset; + + switch (slot) { + case HDMI_IFRAME_SLOT_AVI: + head_offset = HDMI_SW_DI_N_HEAD_WORD(HDMI_IFRAME_SLOT_AVI); + pack_offset = HDMI_SW_DI_N_PKT_WORD0(HDMI_IFRAME_SLOT_AVI); + break; + case HDMI_IFRAME_SLOT_AUDIO: + head_offset = HDMI_SW_DI_N_HEAD_WORD(HDMI_IFRAME_SLOT_AUDIO); + pack_offset = HDMI_SW_DI_N_PKT_WORD0(HDMI_IFRAME_SLOT_AUDIO); + break; + default: + DRM_ERROR("unsupported infoframe slot: %#x\n", slot); + return; + } + + /* Disable transmission for the selected slot */ + val = hdmi_read(hdmi, HDMI_SW_DI_CFG); + val &= ~HDMI_IFRAME_CFG_DI_N(HDMI_IFRAME_MASK, slot); + hdmi_write(hdmi, val, HDMI_SW_DI_CFG); + + /* Reset info frame registers */ + hdmi_write(hdmi, 0x0, head_offset); + for (i = 0; i < HDMI_SW_DI_MAX_WORD; i += sizeof(u32)) + hdmi_write(hdmi, 0x0, pack_offset + i); +} + /** * Helper to concatenate infoframe in 32 bits word * @@ -468,6 +507,10 @@ static void sti_hdmi_disable(struct drm_bridge *bridge) /* Stop the phy */ hdmi->phy_ops->stop(hdmi); + /* Reset info frame transmission */ + hdmi_infoframe_reset(hdmi, HDMI_IFRAME_SLOT_AVI); + hdmi_infoframe_reset(hdmi, HDMI_IFRAME_SLOT_AUDIO); + /* Set the default channel data to be a dark red */ hdmi_write(hdmi, 0x0000, HDMI_DFLT_CHL0_DAT); hdmi_write(hdmi, 0x0000, HDMI_DFLT_CHL1_DAT); |