drm/msm: update HDMI AVI infoframe during HDR playback
Add support to update the HDMI AVI infoframe to use BT2020 encoding during HDR video playback. This is required as per the spec to ensure that the AVI infoframe correctly indicates the content being shown. Also make sure to change and restore the YCC quantization bits in case of override. Change-Id: Iadacc2fac6252b5f5cbfcc39a122118f738d3113 Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
This commit is contained in:
parent
5920f5fe3c
commit
86d73ba300
4 changed files with 148 additions and 8 deletions
|
@ -1970,6 +1970,123 @@ enable_packet_control:
|
|||
hdmi_write(hdmi, HDMI_GEN_PKT_CTRL, packet_control);
|
||||
}
|
||||
|
||||
static void sde_hdmi_update_colorimetry(struct sde_hdmi *display,
|
||||
bool use_bt2020)
|
||||
{
|
||||
struct hdmi *hdmi;
|
||||
struct drm_connector *connector;
|
||||
bool mode_is_yuv = false;
|
||||
struct drm_display_mode *mode;
|
||||
u32 mode_fmt_flags = 0;
|
||||
u8 checksum;
|
||||
u32 avi_info0 = 0;
|
||||
u32 avi_info1 = 0;
|
||||
u8 avi_iframe[HDMI_AVI_INFOFRAME_BUFFER_SIZE] = {0};
|
||||
u8 *avi_frame = &avi_iframe[HDMI_INFOFRAME_HEADER_SIZE];
|
||||
struct hdmi_avi_infoframe info;
|
||||
|
||||
if (!display) {
|
||||
SDE_ERROR("invalid input\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hdmi = display->ctrl.ctrl;
|
||||
|
||||
if (!hdmi) {
|
||||
SDE_ERROR("invalid input\n");
|
||||
return;
|
||||
}
|
||||
|
||||
connector = display->ctrl.ctrl->connector;
|
||||
|
||||
if (!connector) {
|
||||
SDE_ERROR("invalid input\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!connector->hdr_supported) {
|
||||
SDE_DEBUG("HDR is not supported\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If sink doesn't support BT2020, just return */
|
||||
if (!(connector->color_enc_fmt & DRM_EDID_COLORIMETRY_BT2020_YCC) ||
|
||||
!(connector->color_enc_fmt & DRM_EDID_COLORIMETRY_BT2020_RGB)) {
|
||||
SDE_DEBUG("BT2020 colorimetry is not supported\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If there is no change in colorimetry, just return */
|
||||
if (use_bt2020 && display->bt2020_colorimetry)
|
||||
return;
|
||||
else if (!use_bt2020 && !display->bt2020_colorimetry)
|
||||
return;
|
||||
|
||||
mode = &display->mode;
|
||||
/* Cache the format flags before clearing */
|
||||
mode_fmt_flags = mode->flags;
|
||||
/**
|
||||
* Clear the RGB/YUV format flags before calling upstream API
|
||||
* as the API also compares the flags and then returns a mode
|
||||
*/
|
||||
mode->flags &= ~SDE_DRM_MODE_FLAG_FMT_MASK;
|
||||
drm_hdmi_avi_infoframe_from_display_mode(&info, mode);
|
||||
/* Restore the format flags */
|
||||
mode->flags = mode_fmt_flags;
|
||||
|
||||
/* Mode should only support YUV and not both to set the flag */
|
||||
if ((mode->private_flags & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420)
|
||||
&& !(mode->private_flags & MSM_MODE_FLAG_COLOR_FORMAT_RGB444)) {
|
||||
mode_is_yuv = true;
|
||||
}
|
||||
|
||||
|
||||
if (!display->bt2020_colorimetry && use_bt2020) {
|
||||
/**
|
||||
* 1. Update colorimetry to use extended
|
||||
* 2. Change extended to use BT2020
|
||||
* 3. Change colorspace based on mode
|
||||
* 4. Use limited as BT2020 is always limited
|
||||
*/
|
||||
info.colorimetry = SDE_HDMI_USE_EXTENDED_COLORIMETRY;
|
||||
info.extended_colorimetry = SDE_HDMI_BT2020_COLORIMETRY;
|
||||
if (mode_is_yuv)
|
||||
info.colorspace = HDMI_COLORSPACE_YUV420;
|
||||
if (connector->yuv_qs)
|
||||
info.ycc_quantization_range =
|
||||
HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
|
||||
} else if (display->bt2020_colorimetry && !use_bt2020) {
|
||||
/**
|
||||
* 1. Update colorimetry to non-extended
|
||||
* 2. Change colorspace based on mode
|
||||
* 3. Restore quantization to full if QS
|
||||
* is enabled
|
||||
*/
|
||||
info.colorimetry = SDE_HDMI_DEFAULT_COLORIMETRY;
|
||||
if (mode_is_yuv)
|
||||
info.colorspace = HDMI_COLORSPACE_YUV420;
|
||||
if (connector->yuv_qs)
|
||||
info.ycc_quantization_range =
|
||||
HDMI_YCC_QUANTIZATION_RANGE_FULL;
|
||||
}
|
||||
|
||||
hdmi_avi_infoframe_pack(&info, avi_iframe, sizeof(avi_iframe));
|
||||
checksum = avi_iframe[HDMI_INFOFRAME_HEADER_SIZE - 1];
|
||||
avi_info0 = checksum |
|
||||
LEFT_SHIFT_BYTE(avi_frame[0]) |
|
||||
LEFT_SHIFT_WORD(avi_frame[1]) |
|
||||
LEFT_SHIFT_24BITS(avi_frame[2]);
|
||||
|
||||
avi_info1 = avi_frame[3] |
|
||||
LEFT_SHIFT_BYTE(avi_frame[4]) |
|
||||
LEFT_SHIFT_WORD(avi_frame[5]) |
|
||||
LEFT_SHIFT_24BITS(avi_frame[6]);
|
||||
|
||||
hdmi_write(hdmi, REG_HDMI_AVI_INFO(0), avi_info0);
|
||||
hdmi_write(hdmi, REG_HDMI_AVI_INFO(1), avi_info1);
|
||||
display->bt2020_colorimetry = use_bt2020;
|
||||
}
|
||||
|
||||
static void sde_hdmi_clear_hdr_infoframe(struct sde_hdmi *display)
|
||||
{
|
||||
struct hdmi *hdmi;
|
||||
|
@ -2340,14 +2457,22 @@ int sde_hdmi_pre_kickoff(struct drm_connector *connector,
|
|||
{
|
||||
struct sde_hdmi *hdmi_display = (struct sde_hdmi *)display;
|
||||
struct drm_msm_ext_panel_hdr_ctrl *hdr_ctrl;
|
||||
struct drm_msm_ext_panel_hdr_metadata *hdr_meta;
|
||||
u8 hdr_op;
|
||||
|
||||
if (!connector || !display || !params) {
|
||||
if (!connector || !display || !params ||
|
||||
!params->hdr_ctrl) {
|
||||
pr_err("Invalid params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdr_ctrl = params->hdr_ctrl;
|
||||
hdr_meta = &hdr_ctrl->hdr_meta;
|
||||
|
||||
if (!hdr_meta) {
|
||||
SDE_ERROR("Invalid params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdr_op = sde_hdmi_hdr_get_ops(hdmi_display->curr_hdr_state,
|
||||
hdr_ctrl->hdr_state);
|
||||
|
@ -2356,6 +2481,12 @@ int sde_hdmi_pre_kickoff(struct drm_connector *connector,
|
|||
if (connector->hdr_supported)
|
||||
sde_hdmi_panel_set_hdr_infoframe(display,
|
||||
&hdr_ctrl->hdr_meta);
|
||||
if (hdr_meta->eotf)
|
||||
sde_hdmi_update_colorimetry(hdmi_display,
|
||||
true);
|
||||
else
|
||||
sde_hdmi_update_colorimetry(hdmi_display,
|
||||
false);
|
||||
} else if (hdr_op == HDR_CLEAR_INFO)
|
||||
sde_hdmi_clear_hdr_infoframe(display);
|
||||
|
||||
|
|
|
@ -169,6 +169,7 @@ struct sde_hdmi {
|
|||
bool pll_update_enable;
|
||||
bool dc_enable;
|
||||
bool dc_feature_supported;
|
||||
bool bt2020_colorimetry;
|
||||
|
||||
struct delayed_work hdcp_cb_work;
|
||||
struct dss_io_data io[HDMI_TX_MAX_IO];
|
||||
|
@ -201,6 +202,15 @@ enum hdmi_tx_scdc_access_type {
|
|||
|
||||
#define HDMI_GEN_PKT_CTRL_CLR_MASK 0x7
|
||||
|
||||
/* for AVI program */
|
||||
#define HDMI_AVI_INFOFRAME_BUFFER_SIZE \
|
||||
(HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE)
|
||||
#define HDMI_VS_INFOFRAME_BUFFER_SIZE (HDMI_INFOFRAME_HEADER_SIZE + 6)
|
||||
|
||||
#define LEFT_SHIFT_BYTE(x) ((x) << 8)
|
||||
#define LEFT_SHIFT_WORD(x) ((x) << 16)
|
||||
#define LEFT_SHIFT_24BITS(x) ((x) << 24)
|
||||
|
||||
/* Maximum pixel clock rates for hdmi tx */
|
||||
#define HDMI_DEFAULT_MAX_PCLK_RATE 148500
|
||||
#define HDMI_TX_3_MAX_PCLK_RATE 297000
|
||||
|
|
|
@ -99,17 +99,10 @@ struct sde_hdmi_bridge {
|
|||
#define HDMI_TX_SCRAMBLER_TIMEOUT_MSEC 200
|
||||
|
||||
|
||||
/* for AVI program */
|
||||
#define HDMI_AVI_INFOFRAME_BUFFER_SIZE \
|
||||
(HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE)
|
||||
#define HDMI_VS_INFOFRAME_BUFFER_SIZE (HDMI_INFOFRAME_HEADER_SIZE + 6)
|
||||
#define HDMI_SPD_INFOFRAME_BUFFER_SIZE \
|
||||
(HDMI_INFOFRAME_HEADER_SIZE + HDMI_SPD_INFOFRAME_SIZE)
|
||||
#define HDMI_DEFAULT_VENDOR_NAME "unknown"
|
||||
#define HDMI_DEFAULT_PRODUCT_NAME "msm"
|
||||
#define LEFT_SHIFT_BYTE(x) ((x) << 8)
|
||||
#define LEFT_SHIFT_WORD(x) ((x) << 16)
|
||||
#define LEFT_SHIFT_24BITS(x) ((x) << 24)
|
||||
#define HDMI_AVI_IFRAME_LINE_NUMBER 1
|
||||
#define HDMI_VENDOR_IFRAME_LINE_NUMBER 3
|
||||
|
||||
|
|
|
@ -98,6 +98,12 @@
|
|||
#define HDMI_GET_LSB(x)(x & 0xff)
|
||||
|
||||
#define SDE_HDMI_VIC_640x480 0x1
|
||||
#define SDE_HDMI_YCC_QUANT_MASK (0x3 << 14)
|
||||
#define SDE_HDMI_COLORIMETRY_MASK (0x3 << 22)
|
||||
|
||||
#define SDE_HDMI_DEFAULT_COLORIMETRY 0x0
|
||||
#define SDE_HDMI_USE_EXTENDED_COLORIMETRY 0x3
|
||||
#define SDE_HDMI_BT2020_COLORIMETRY 0x6
|
||||
|
||||
/*
|
||||
* Bits 1:0 in HDMI_HW_DDC_CTRL that dictate how the HDCP 2.2 RxStatus will be
|
||||
|
|
Loading…
Add table
Reference in a new issue