Commit 9aa1eca0 authored by Nickey Yang's avatar Nickey Yang Committed by Archit Taneja

drm: bridge: dw-hdmi: add HDMI vendor specific infoframe config

Vendor specific infoframe is mandatory for 4K2K resolution.
Without this, the HDMI protocol compliance fails.
Signed-off-by: default avatarNickey Yang <nickey.yang@rock-chips.com>
Reviewed-by: default avatarJose Abreu <joabreu@synopsys.com>
Signed-off-by: default avatarArchit Taneja <architt@codeaurora.org>
Link: http://patchwork.freedesktop.org/patch/msgid/1490081777-2232-1-git-send-email-nickey.yang@rock-chips.com
parent 94bb4dc1
...@@ -1240,6 +1240,58 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) ...@@ -1240,6 +1240,58 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
hdmi_writeb(hdmi, (frame.right_bar >> 8) & 0xff, HDMI_FC_AVISRB1); hdmi_writeb(hdmi, (frame.right_bar >> 8) & 0xff, HDMI_FC_AVISRB1);
} }
static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
struct drm_display_mode *mode)
{
struct hdmi_vendor_infoframe frame;
u8 buffer[10];
ssize_t err;
err = drm_hdmi_vendor_infoframe_from_display_mode(&frame, mode);
if (err < 0)
/*
* Going into that statement does not means vendor infoframe
* fails. It just informed us that vendor infoframe is not
* needed for the selected mode. Only 4k or stereoscopic 3D
* mode requires vendor infoframe. So just simply return.
*/
return;
err = hdmi_vendor_infoframe_pack(&frame, buffer, sizeof(buffer));
if (err < 0) {
dev_err(hdmi->dev, "Failed to pack vendor infoframe: %zd\n",
err);
return;
}
hdmi_mask_writeb(hdmi, 0, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET,
HDMI_FC_DATAUTO0_VSD_MASK);
/* Set the length of HDMI vendor specific InfoFrame payload */
hdmi_writeb(hdmi, buffer[2], HDMI_FC_VSDSIZE);
/* Set 24bit IEEE Registration Identifier */
hdmi_writeb(hdmi, buffer[4], HDMI_FC_VSDIEEEID0);
hdmi_writeb(hdmi, buffer[5], HDMI_FC_VSDIEEEID1);
hdmi_writeb(hdmi, buffer[6], HDMI_FC_VSDIEEEID2);
/* Set HDMI_Video_Format and HDMI_VIC/3D_Structure */
hdmi_writeb(hdmi, buffer[7], HDMI_FC_VSDPAYLOAD0);
hdmi_writeb(hdmi, buffer[8], HDMI_FC_VSDPAYLOAD1);
if (frame.s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
hdmi_writeb(hdmi, buffer[9], HDMI_FC_VSDPAYLOAD2);
/* Packet frame interpolation */
hdmi_writeb(hdmi, 1, HDMI_FC_DATAUTO1);
/* Auto packets per frame and line spacing */
hdmi_writeb(hdmi, 0x11, HDMI_FC_DATAUTO2);
/* Configures the Frame Composer On RDRB mode */
hdmi_mask_writeb(hdmi, 1, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET,
HDMI_FC_DATAUTO0_VSD_MASK);
}
static void hdmi_av_composer(struct dw_hdmi *hdmi, static void hdmi_av_composer(struct dw_hdmi *hdmi,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
...@@ -1489,6 +1541,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) ...@@ -1489,6 +1541,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
/* HDMI Initialization Step F - Configure AVI InfoFrame */ /* HDMI Initialization Step F - Configure AVI InfoFrame */
hdmi_config_AVI(hdmi, mode); hdmi_config_AVI(hdmi, mode);
hdmi_config_vendor_specific_infoframe(hdmi, mode);
} else { } else {
dev_dbg(hdmi->dev, "%s DVI mode\n", __func__); dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
} }
......
...@@ -854,6 +854,10 @@ enum { ...@@ -854,6 +854,10 @@ enum {
HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10, HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10,
HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1, HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1,
/* FC_DATAUTO0 field values */
HDMI_FC_DATAUTO0_VSD_MASK = 0x08,
HDMI_FC_DATAUTO0_VSD_OFFSET = 3,
/* PHY_CONF0 field values */ /* PHY_CONF0 field values */
HDMI_PHY_CONF0_PDZ_MASK = 0x80, HDMI_PHY_CONF0_PDZ_MASK = 0x80,
HDMI_PHY_CONF0_PDZ_OFFSET = 7, HDMI_PHY_CONF0_PDZ_OFFSET = 7,
......
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