Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 81e0028e authored by Narender Ankam's avatar Narender Ankam Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarNarender Ankam <nankam@codeaurora.org>
Signed-off-by: default avatarRamendra Kumar <ramendra@codeaurora.org>
parent 63e2cba4
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -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;
+3 −1
Original line number Diff line number Diff line
@@ -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 */
+83 −1
Original line number Diff line number Diff line
@@ -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",
+2 −0
Original line number Diff line number Diff line
@@ -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;