mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-03 12:24:45 +08:00
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: Nickey Yang <nickey.yang@rock-chips.com> Reviewed-by: Jose Abreu <joabreu@synopsys.com> Signed-off-by: Archit Taneja <architt@codeaurora.org> Link: http://patchwork.freedesktop.org/patch/msgid/1490081777-2232-1-git-send-email-nickey.yang@rock-chips.com
This commit is contained in:
parent
94bb4dc132
commit
9aa1eca095
@ -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);
|
||||
}
|
||||
|
||||
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,
|
||||
const 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_config_AVI(hdmi, mode);
|
||||
hdmi_config_vendor_specific_infoframe(hdmi, mode);
|
||||
} else {
|
||||
dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
|
||||
}
|
||||
|
@ -854,6 +854,10 @@ enum {
|
||||
HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10,
|
||||
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 */
|
||||
HDMI_PHY_CONF0_PDZ_MASK = 0x80,
|
||||
HDMI_PHY_CONF0_PDZ_OFFSET = 7,
|
||||
|
Loading…
Reference in New Issue
Block a user