summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorNarender Ankam <nankam@codeaurora.org>2019-11-12 14:32:03 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2020-03-03 02:33:46 -0800
commit81e0028ecab750a669960b2dcf99379cf612f5a7 (patch)
tree7dd17c8657621f2ae1bf5663e3c1c6ea4ddd7e6b /drivers
parent63e2cba42b91b0d2dcd8a9bdb3cb4eff112a95da (diff)
msm: mdss: mdp: update CDM CSC coefficients during HDR playback
On HDR playback, update CDM CSC coefficients from Rec709 to BT2020, so that RGB will be converted to YUV444 and then to YUV420 in BT2020 colorspace. Once HDR playback is done, reset CDM CSC coefficients to default Rec709 values. Change-Id: Ib3ab4fb61fc3392d76cf138cc4a20d4bc55ed016 Signed-off-by: Narender Ankam <nankam@codeaurora.org> Signed-off-by: Ramendra Kumar <ramendra@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.c33
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_cdm.c4
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_video.c84
-rw-r--r--drivers/video/fbdev/msm/mdss_panel.h2
4 files changed, 121 insertions, 2 deletions
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
index 6c91ff353d5b..9286f75d58f3 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
@@ -4399,6 +4399,38 @@ static int hdmi_tx_event_handler(struct mdss_panel_data *panel_data,
return rc;
}
+static enum mdss_mdp_csc_type mdss_hdmi_get_csc_type(
+ struct mdss_panel_data *panel_data)
+{
+ struct mdss_panel_info *pinfo;
+ struct mdp_hdr_stream_ctrl *hdr_ctrl;
+ struct mdp_hdr_stream *hdr_data;
+ enum mdss_mdp_csc_type csc_type = MDSS_MDP_CSC_RGB2YUV_709L;
+
+ struct hdmi_tx_ctrl *hdmi_ctrl =
+ hdmi_tx_get_drvdata_from_panel_data(panel_data);
+
+ if (!hdmi_ctrl) {
+ DEV_ERR("%s: invalid hdmi ctrl data\n", __func__);
+ goto error;
+ }
+
+ pinfo = &hdmi_ctrl->panel_data.panel_info;
+ hdr_ctrl = &hdmi_ctrl->hdr_ctrl;
+ hdr_data = &hdr_ctrl->hdr_stream;
+
+ if ((hdr_ctrl->hdr_state == HDR_ENABLE) &&
+ (hdr_data->eotf != 0))
+ csc_type = MDSS_MDP_CSC_RGB2YUV_2020L;
+ else if (pinfo->is_ce_mode)
+ csc_type = MDSS_MDP_CSC_RGB2YUV_709L;
+ else
+ csc_type = MDSS_MDP_CSC_RGB2YUV_709FR;
+
+error:
+ return csc_type;
+}
+
static int hdmi_tx_register_panel(struct hdmi_tx_ctrl *hdmi_ctrl)
{
int rc = 0;
@@ -4409,6 +4441,7 @@ static int hdmi_tx_register_panel(struct hdmi_tx_ctrl *hdmi_ctrl)
}
hdmi_ctrl->panel_data.event_handler = hdmi_tx_event_handler;
+ hdmi_ctrl->panel_data.get_csc_type = mdss_hdmi_get_csc_type;
if (!hdmi_ctrl->pdata.primary)
hdmi_ctrl->vic = DEFAULT_VIDEO_RESOLUTION;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_cdm.c b/drivers/video/fbdev/msm/mdss_mdp_cdm.c
index 9bc7c514fc65..7fede8fa1709 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_cdm.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_cdm.c
@@ -139,7 +139,9 @@ static int mdss_mdp_cdm_csc_setup(struct mdss_mdp_cdm *cdm,
if ((data->csc_type == MDSS_MDP_CSC_RGB2YUV_601L) ||
(data->csc_type == MDSS_MDP_CSC_RGB2YUV_601FR) ||
(data->csc_type == MDSS_MDP_CSC_RGB2YUV_709L) ||
- (data->csc_type == MDSS_MDP_CSC_RGB2YUV_709FR)) {
+ (data->csc_type == MDSS_MDP_CSC_RGB2YUV_709FR) ||
+ (data->csc_type == MDSS_MDP_CSC_RGB2YUV_2020L) ||
+ (data->csc_type == MDSS_MDP_CSC_RGB2YUV_2020FR)) {
op_mode |= BIT(2); /* DST_DATA_FORMAT = YUV */
op_mode &= ~BIT(1); /* SRC_DATA_FORMAT = RGB */
op_mode |= BIT(0); /* EN = 1 */
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
index f5f5ddf49e72..29fe0f861593 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
@@ -103,6 +103,9 @@ struct mdss_mdp_video_ctx {
u32 intf_irq_mask;
spinlock_t mdss_mdp_video_lock;
spinlock_t mdss_mdp_intf_intr_lock;
+
+ enum mdss_mdp_csc_type cdm_csc_type;
+ bool yuv_conv;
};
static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx,
@@ -1023,6 +1026,8 @@ static int mdss_mdp_video_ctx_stop(struct mdss_mdp_ctl *ctl,
mdss_mdp_set_intf_intr_callback(ctx, MDSS_MDP_INTF_IRQ_PROG_LINE,
NULL, NULL);
+ ctx->yuv_conv = false;
+
ctx->ref_cnt--;
end:
mutex_unlock(&ctl->offlock);
@@ -1645,6 +1650,75 @@ end:
return rc;
}
+static int mdss_mdp_update_csc_matrix(struct mdss_mdp_ctl *ctl)
+{
+ struct mdss_mdp_video_ctx *ctx;
+ struct mdss_data_type *mdata;
+ struct mdss_panel_data *pdata;
+ struct mdss_panel_info *pinfo;
+ struct mdss_mdp_format_params *fmt;
+ enum mdss_mdp_csc_type csc_type;
+ int rc = 0;
+
+ ctx = (struct mdss_mdp_video_ctx *) ctl->intf_ctx[MASTER_CTX];
+ if (!ctx) {
+ pr_err("%s: invalid ctx\n", __func__);
+ return -ENODEV;
+ }
+
+ mdata = ctl->mdata;
+ pdata = ctl->panel_data;
+ pinfo = &pdata->panel_info;
+
+ if (!mdss_mdp_is_cdm_supported(mdata, ctl->intf_type, 0)) {
+ pr_debug("%s: CDM is not supported\n", __func__);
+ goto error;
+ }
+
+ if (IS_ERR_OR_NULL(ctl->cdm)) {
+ pr_debug("%s: CDM is not initialized\n", __func__);
+ goto error;
+ }
+
+ if (!ctx->yuv_conv) {
+ pr_debug("%s: CDM not configured to convert to YUV yet\n",
+ __func__);
+ goto error;
+ }
+
+ fmt = mdss_mdp_get_format_params(pinfo->out_format);
+ if (fmt->is_yuv) {
+ csc_type = MDSS_MDP_CSC_RGB2YUV_709L;
+ if (pdata->get_csc_type)
+ csc_type = pdata->get_csc_type(pdata);
+
+ pr_debug("cdm_csc_type = %d csc_type = %d\n",
+ ctx->cdm_csc_type, csc_type);
+ if (ctx->cdm_csc_type != csc_type) {
+
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
+ rc = mdss_mdp_csc_setup(MDSS_MDP_BLOCK_CDM,
+ ctl->cdm->num, csc_type);
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
+
+ if (rc) {
+ pr_err("%s: CDM CSC setup failed, rc = %d\n",
+ __func__, rc);
+ goto error;
+ }
+
+ pr_debug("%s: updating csc %d to %d\n", __func__,
+ ctx->cdm_csc_type, csc_type);
+
+ ctx->cdm_csc_type = csc_type;
+ pinfo->csc_type = csc_type;
+ ctl->flush_bits |= BIT(26);
+ }
+ }
+error:
+ return rc;
+}
+
static int mdss_mdp_video_display(struct mdss_mdp_ctl *ctl, void *arg)
{
struct mdss_mdp_video_ctx *ctx;
@@ -1736,6 +1810,8 @@ static int mdss_mdp_video_display(struct mdss_mdp_ctl *ctl, void *arg)
CTL_INTF_EVENT_FLAG_DEFAULT);
}
+ rc = mdss_mdp_update_csc_matrix(ctl);
+
rc = mdss_mdp_video_avr_trigger_setup(ctl);
if (rc) {
pr_err("avr trigger setup failed\n");
@@ -1998,8 +2074,10 @@ static int mdss_mdp_video_cdm_setup(struct mdss_mdp_cdm *cdm,
return -EINVAL;
}
+ pinfo->csc_type = setup.csc_type;
+
setup.out_format = pinfo->out_format;
- setup.mdp_csc_bit_depth = MDP_CDM_CSC_8BIT;
+ setup.mdp_csc_bit_depth = MDP_CDM_CSC_10BIT;
setup.output_width = pinfo->xres + pinfo->lcdc.xres_pad;
setup.output_height = pinfo->yres + pinfo->lcdc.yres_pad;
return mdss_mdp_cdm_setup(cdm, &setup);
@@ -2156,6 +2234,10 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl,
__func__);
return -EINVAL;
}
+ if (fmt->is_yuv)
+ ctx->yuv_conv = true;
+
+ ctx->cdm_csc_type = pinfo->csc_type;
ctl->flush_bits |= BIT(26);
} else {
pr_err("%s: failed to initialize cdm\n",
diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h
index 6211191c378c..1e0ae618b501 100644
--- a/drivers/video/fbdev/msm/mdss_panel.h
+++ b/drivers/video/fbdev/msm/mdss_panel.h
@@ -801,6 +801,7 @@ struct mdss_panel_info {
u32 vic; /* video identification code */
u32 deep_color;
bool is_ce_mode; /* CE video format */
+ u8 csc_type;
struct mdss_rect roi;
struct mdss_dsi_dual_pu_roi dual_roi;
int pwm_pmic_gpio;
@@ -991,6 +992,7 @@ struct mdss_panel_data {
* and teardown.
*/
int (*event_handler) (struct mdss_panel_data *pdata, int e, void *arg);
+ enum mdss_mdp_csc_type (*get_csc_type)(struct mdss_panel_data *pdata);
struct device_node *(*get_fb_node)(struct platform_device *pdev);
struct list_head timings_list;