diff options
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_panel.c | 64 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_panel.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_tx.c | 38 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_tx.h | 1 |
4 files changed, 101 insertions, 3 deletions
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_panel.c b/drivers/video/fbdev/msm/mdss_hdmi_panel.c index 7fecb08f9667..20afa08155c1 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_panel.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_panel.c @@ -140,7 +140,20 @@ enum { enum hdmi_colorimetry { HDMI_COLORIMETRY_DEFAULT, HDMI_COLORIMETRY_ITU_R_601, - HDMI_COLORIMETRY_ITU_R_709 + HDMI_COLORIMETRY_ITU_R_709, + HDMI_COLORIMETRY_EXTENDED +}; + +enum hdmi_ext_colorimetry { + HDMI_COLORIMETRY_XV_YCC_601, + HDMI_COLORIMETRY_XV_YCC_709, + HDMI_COLORIMETRY_S_YCC_601, + HDMI_COLORIMETRY_ADOBE_YCC_601, + HDMI_COLORIMETRY_ADOBE_RGB, + HDMI_COLORIMETRY_C_YCBCR_BT2020, + HDMI_COLORIMETRY_YCBCR_BT2020, + HDMI_COLORIMETRY_RESERVED + }; enum hdmi_quantization_range { @@ -833,6 +846,53 @@ end: return panel->vic; } +static int hdmi_panel_avi_update_colorimetry(void *input, + bool use_bt2020) +{ + struct hdmi_panel *panel = input; + struct mdss_panel_info *pinfo; + struct hdmi_video_config *vid_cfg; + struct hdmi_avi_infoframe_config *avi; + int rc = 0; + + if (!panel) { + DEV_ERR("%s: invalid hdmi panel\n", __func__); + rc = -EINVAL; + goto error; + } + + /* Configure AVI infoframe */ + rc = hdmi_panel_config_avi(panel); + if (rc) { + DEV_ERR("%s: failed to configure AVI\n", __func__); + goto error; + } + + pinfo = panel->data->pinfo; + vid_cfg = &panel->vid_cfg; + avi = &vid_cfg->avi_iframe; + + /* Update Colorimetry */ + avi->ext_colorimetry_info = 0; + + if (use_bt2020) { + avi->colorimetry_info = HDMI_COLORIMETRY_EXTENDED; + avi->ext_colorimetry_info = HDMI_COLORIMETRY_YCBCR_BT2020; + } else if (avi->pixel_format == MDP_Y_CBCR_H2V2) { + if (pinfo->yres < 720) + avi->colorimetry_info = HDMI_COLORIMETRY_ITU_R_601; + else + avi->colorimetry_info = HDMI_COLORIMETRY_ITU_R_709; + } else { + avi->colorimetry_info = HDMI_COLORIMETRY_DEFAULT; + } + + hdmi_panel_set_avi_infoframe(panel); + +error: + return rc; +} + static int hdmi_panel_power_on(void *input) { int rc = 0; @@ -959,6 +1019,8 @@ void *hdmi_panel_init(struct hdmi_panel_init_data *data) data->ops->off = hdmi_panel_power_off; data->ops->vendor = hdmi_panel_set_vendor_specific_infoframe; data->ops->update_fps = hdmi_panel_update_fps; + data->ops->update_colorimetry = + hdmi_panel_avi_update_colorimetry; } end: return panel; diff --git a/drivers/video/fbdev/msm/mdss_hdmi_panel.h b/drivers/video/fbdev/msm/mdss_hdmi_panel.h index e485822f8af0..04cd971e2db0 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_panel.h +++ b/drivers/video/fbdev/msm/mdss_hdmi_panel.h @@ -65,6 +65,7 @@ struct hdmi_panel_ops { int (*off)(void *input); void (*vendor)(void *input); int (*update_fps)(void *input, u32 fps); + int (*update_colorimetry)(void *input, bool use_bt2020); }; /** diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index 5c06e0636349..6c91ff353d5b 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c @@ -125,6 +125,8 @@ static int hdmi_tx_enable_pll_update(struct hdmi_tx_ctrl *hdmi_ctrl, static void hdmi_tx_hpd_polarity_setup(struct hdmi_tx_ctrl *hdmi_ctrl, bool polarity); static int hdmi_tx_notify_events(struct hdmi_tx_ctrl *hdmi_ctrl, int val); +static void hdmi_panel_update_colorimetry(struct hdmi_tx_ctrl *ctrl, + bool use_bt2020); static struct mdss_hw hdmi_tx_hw = { .hw_ndx = MDSS_HW_HDMI, @@ -1343,9 +1345,13 @@ static ssize_t hdmi_tx_sysfs_wta_hdr_stream(struct device *dev, hdr_op = hdmi_hdr_get_ops(ctrl->curr_hdr_state, ctrl->hdr_ctrl.hdr_state); - if (hdr_op == HDR_SEND_INFO) + if (hdr_op == HDR_SEND_INFO) { hdmi_panel_set_hdr_infoframe(ctrl); - else if (hdr_op == HDR_CLEAR_INFO) + if (ctrl->hdr_ctrl.hdr_stream.eotf) + hdmi_panel_update_colorimetry(ctrl, true); + else + hdmi_panel_update_colorimetry(ctrl, false); + } else if (hdr_op == HDR_CLEAR_INFO) hdmi_panel_clear_hdr_infoframe(ctrl); ctrl->curr_hdr_state = ctrl->hdr_ctrl.hdr_state; @@ -3130,6 +3136,34 @@ static void hdmi_panel_clear_hdr_infoframe(struct hdmi_tx_ctrl *ctrl) DSS_REG_W(io, HDMI_GEN_PKT_CTRL, packet_control); } +static void hdmi_panel_update_colorimetry(struct hdmi_tx_ctrl *hdmi_ctrl, + bool use_bt2020) +{ + void *pdata; + + if (!hdmi_ctrl) { + DEV_ERR("%s: invalid hdmi ctrl data\n", __func__); + return; + } + + pdata = hdmi_tx_get_fd(HDMI_TX_FEAT_PANEL); + if (!pdata) { + DEV_ERR("%s: invalid panel data\n", __func__); + return; + } + + /* If there is no change in colorimetry, just return */ + if (use_bt2020 && hdmi_ctrl->use_bt2020) + return; + else if (!use_bt2020 && !hdmi_ctrl->use_bt2020) + return; + + if (hdmi_ctrl->panel_ops.update_colorimetry) + hdmi_ctrl->panel_ops.update_colorimetry(pdata, use_bt2020); + + hdmi_ctrl->use_bt2020 = use_bt2020; +} + static int hdmi_tx_audio_info_setup(struct platform_device *pdev, struct msm_ext_disp_audio_setup_params *params) { diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.h b/drivers/video/fbdev/msm/mdss_hdmi_tx.h index a9effad08a0c..7eb749fde97d 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.h +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.h @@ -138,6 +138,7 @@ struct hdmi_tx_ctrl { bool power_data_enable[HDMI_TX_MAX_PM]; bool dc_support; bool dc_feature_on; + bool use_bt2020; void (*hdmi_tx_hpd_done)(void *data); void *downstream_data; |
