summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_panel.c64
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_panel.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.c38
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.h1
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;