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

Commit 184460e9 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdp: reserve cdm block only for output yuv format"

parents e452c61b a010acca
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3391,6 +3391,7 @@ static int mdss_mdp_cdm_addr_setup(struct mdss_data_type *mdata,
		head[i].base = (mdata->mdss_io.base) + cdm_offsets[i];
		atomic_set(&head[i].kref.refcount, 0);
		mutex_init(&head[i].lock);
		init_completion(&head[i].free_comp);
		pr_debug("%s: cdm off (%d) = %p\n", __func__, i, head[i].base);
	}

+25 −11
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ static u32 cdm_cdwn2_offsite_h_coeff[] = {0x000b0005, 0x01db01eb, 0x00e40046};
static u32 cdm_cdwn2_cosite_v_coeff[] = {0x00080004};
static u32 cdm_cdwn2_offsite_v_coeff[] = {0x00060002};

#define VSYNC_TIMEOUT_US 16000

/**
 * @mdss_mdp_cdm_alloc() - Allocates a cdm block by parsing the list of
 *			     available cdm blocks.
@@ -66,6 +68,7 @@ static void mdss_mdp_cdm_free(struct kref *kref)
	if (!cdm)
		return;

	complete_all(&cdm->free_comp);
	pr_debug("free cdm_num = %d\n", cdm->num);

}
@@ -84,6 +87,28 @@ struct mdss_mdp_cdm *mdss_mdp_cdm_init(struct mdss_mdp_ctl *ctl, u32 intf_type)

	cdm = mdss_mdp_cdm_alloc(mdata);

	/**
	 * give hdmi interface priority to alloc the cdm block. It will wait
	 * for one vsync cycle to allow wfd to finish its job and try to reserve
	 * the block the again.
	 */
	if (!cdm && (intf_type == MDP_CDM_CDWN_OUTPUT_HDMI)) {
		/* always wait for first cdm block */
		cdm = mdata->cdm_off;
		if (cdm) {
			reinit_completion(&cdm->free_comp);
			/*
			 * no need to check the return status of completion
			 * timeout. Next cdm_alloc call will try to reserve
			 * the cdm block and returns failure if allocation
			 * fails.
			 */
			wait_for_completion_timeout(&cdm->free_comp,
				usecs_to_jiffies(VSYNC_TIMEOUT_US));
			cdm = mdss_mdp_cdm_alloc(mdata);
		}
	}

	if (!cdm) {
		pr_err("%s: Unable to allocate cdm\n", __func__);
		return ERR_PTR(-EBUSY);
@@ -352,17 +377,6 @@ int mdss_mdp_cdm_destroy(struct mdss_mdp_cdm *cdm)
		return -EINVAL;
	}

	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
	mutex_lock(&cdm->lock);
	/* Disable HDMI packer */
	writel_relaxed(0x0, cdm->base + MDSS_MDP_REG_CDM_HDMI_PACK_OP_MODE);

	/* Put CDM in bypass */
	writel_relaxed(0x0, cdm->mdata->mdp_base + MDSS_MDP_MDP_OUT_CTL_0);

	mutex_unlock(&cdm->lock);
	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);

	kref_put(&cdm->kref, mdss_mdp_cdm_free);

	return rc;
+2 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 * Copyright (c) 2014,2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -59,6 +59,7 @@ struct mdss_mdp_cdm {
	u32 out_intf;
	bool is_bypassed;
	struct mdp_cdm_cfg setup;
	struct completion free_comp;
};

struct mdss_mdp_cdm *mdss_mdp_cdm_init(struct mdss_mdp_ctl *ctl,
+26 −18
Original line number Diff line number Diff line
@@ -1695,19 +1695,10 @@ static inline bool mdss_mdp_video_need_pixel_drop(u32 vic)
}

static int mdss_mdp_video_cdm_setup(struct mdss_mdp_cdm *cdm,
				   struct mdss_panel_info *pinfo)
	struct mdss_panel_info *pinfo, struct mdss_mdp_format_params *fmt)
{
	struct mdss_mdp_format_params *fmt;
	struct mdp_cdm_cfg setup;

	fmt = mdss_mdp_get_format_params(pinfo->out_format);

	if (!fmt) {
		pr_err("%s: format %d not supported\n", __func__,
		       pinfo->out_format);
		return -EINVAL;
	}
	setup.out_format = pinfo->out_format;
	if (fmt->is_yuv)
		setup.csc_type = MDSS_MDP_CSC_RGB2YUV_601FR;
	else
@@ -1737,6 +1728,7 @@ static int mdss_mdp_video_cdm_setup(struct mdss_mdp_cdm *cdm,
		return -EINVAL;
	}

	setup.out_format = pinfo->out_format;
	setup.mdp_csc_bit_depth = MDP_CDM_CSC_8BIT;
	setup.output_width = pinfo->xres + pinfo->lcdc.xres_pad;
	setup.output_height = pinfo->yres + pinfo->lcdc.yres_pad;
@@ -1770,6 +1762,7 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl,
{
	struct intf_timing_params *itp = &ctx->itp;
	u32 dst_bpp;
	struct mdss_mdp_format_params *fmt;
	struct mdss_data_type *mdata = ctl->mdata;
	struct dsc_desc *dsc = NULL;

@@ -1803,18 +1796,33 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl,
	}

	if (mdss_mdp_is_cdm_supported(mdata, ctl->intf_type, 0)) {
		ctl->cdm = mdss_mdp_cdm_init(ctl, MDP_CDM_CDWN_OUTPUT_HDMI);

		fmt = mdss_mdp_get_format_params(pinfo->out_format);
		if (!fmt) {
			pr_err("%s: format %d not supported\n", __func__,
			       pinfo->out_format);
			return -EINVAL;
		}
		if (fmt->is_yuv) {
			ctl->cdm =
			mdss_mdp_cdm_init(ctl, MDP_CDM_CDWN_OUTPUT_HDMI);
			if (!IS_ERR_OR_NULL(ctl->cdm)) {
			if (mdss_mdp_video_cdm_setup(ctl->cdm, pinfo)) {
				if (mdss_mdp_video_cdm_setup(ctl->cdm,
					pinfo, fmt)) {
					pr_err("%s: setting up cdm failed\n",
					       __func__);
					return -EINVAL;
				}
				ctl->flush_bits |= BIT(26);
			} else {
			pr_err("%s: failed to initialize cdm\n", __func__);
				pr_err("%s: failed to initialize cdm\n",
					__func__);
				return -EINVAL;
			}
		} else {
			pr_debug("%s: Format is not YUV,cdm not required\n",
				 __func__);
		}
	} else {
		pr_debug("%s: cdm not supported\n", __func__);
	}
+12 −17
Original line number Diff line number Diff line
@@ -155,17 +155,10 @@ static int mdss_mdp_writeback_addr_setup(struct mdss_mdp_writeback_ctx *ctx,
}

static int mdss_mdp_writeback_cdm_setup(struct mdss_mdp_writeback_ctx *ctx,
					struct mdss_mdp_cdm *cdm, u32 format)
	struct mdss_mdp_cdm *cdm, struct mdss_mdp_format_params *fmt)
{
	struct mdss_mdp_format_params *fmt;
	struct mdp_cdm_cfg setup;

	fmt = mdss_mdp_get_format_params(format);
	if (!fmt) {
		pr_err("%s: format %d not supported\n", __func__, format);
		return -EINVAL;
	}

	switch (fmt->chroma_sample) {
	case MDSS_MDP_CHROMA_RGB:
		setup.horz_downsampling_type = MDP_CDM_CDWN_DISABLE;
@@ -185,7 +178,7 @@ static int mdss_mdp_writeback_cdm_setup(struct mdss_mdp_writeback_ctx *ctx,
		return -EINVAL;
	}

	setup.out_format = format;
	setup.out_format = fmt->format;
	setup.mdp_csc_bit_depth = MDP_CDM_CSC_8BIT;
	setup.output_width = ctx->width;
	setup.output_height = ctx->height;
@@ -248,10 +241,9 @@ static int mdss_mdp_writeback_format_setup(struct mdss_mdp_writeback_ctx *ctx,
	chroma_samp = fmt->chroma_sample;

	if (ctl->cdm) {

		rc = mdss_mdp_writeback_cdm_setup(ctx, ctl->cdm, format);
		rc = mdss_mdp_writeback_cdm_setup(ctx, ctl->cdm, fmt);
		if (rc) {
			pr_err("%s: CDM configuration failed with error %d\n",
			pr_err("%s: CDM config failed with error %d\n",
				__func__, rc);
			return rc;
		}
@@ -826,6 +818,7 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl)
	struct mdss_mdp_writeback *wb;
	u32 mem_sel;
	u32 mixer_type = MDSS_MDP_MIXER_TYPE_UNUSED;
	struct mdss_mdp_format_params *fmt = NULL;
	bool is_rot;

	pr_debug("start ctl=%d\n", ctl->num);
@@ -849,6 +842,10 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl)
		return -EINVAL;
	}

	fmt = mdss_mdp_get_format_params(ctl->dst_format);
	if (!fmt)
		return -EINVAL;

	is_rot = (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR) ? true : false;

	if (ctl->mixer_left) {
@@ -862,15 +859,13 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl)
	}

	if (mdss_mdp_is_cdm_supported(ctl->mdata, ctl->intf_type,
				mixer_type)) {
		mixer_type) && fmt->is_yuv) {
		ctl->cdm = mdss_mdp_cdm_init(ctl, MDP_CDM_CDWN_OUTPUT_WB);
		if (IS_ERR_OR_NULL(ctl->cdm)) {
			pr_err("%s failed to init cdm\n", __func__);
			pr_err("cdm block already in use\n");
			ctl->cdm = NULL;
			return -EBUSY;
		}
	} else {
		ctl->cdm = NULL;
		pr_debug("%s: cdm not supported\n", __func__);
	}
	ctl->priv_data = ctx;
	ctx->wb_num = wb->num;