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

Commit 956f90ab authored by Dhaval Patel's avatar Dhaval Patel
Browse files

msm: mdss: support reduced dspp and WB interfaces



MDSS driver has condition check for 1:1 mapping for dspp to
interface and WB to ctrl. This check is not valid for all MDP
version hardware.  It can support less dspp compared to number
of interfaces. It can also support less number of WB paths
compared to controllers. This change enables MDSS driver
to handle such hardware conditions.

Change-Id: Ic08e274c73cc41e80245a0d3d4ae7b854bd5a2d3
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
parent 82f65cf9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -199,6 +199,8 @@ struct mdss_data_type {

	struct mdss_mdp_ctl *ctl_off;
	u32 nctl;
	u32 nwb;
	u32 ndspp;

	struct mdss_mdp_dp_intf *dp_off;
	u32 ndp;
+12 −13
Original line number Diff line number Diff line
@@ -1132,7 +1132,7 @@ int mdss_hw_init(struct mdss_data_type *mdata)
		}
	}

	for (i = 0; i < mdata->nmixers_intf; i++) {
	for (i = 0; i < mdata->ndspp; i++) {
		offset = mdata->mixer_intf[i].dspp_base +
				MDSS_MDP_REG_DSPP_HIST_LUT_BASE;
		for (j = 0; j < ENHIST_LUT_ENTRIES; j++)
@@ -2065,7 +2065,7 @@ ftch_alloc_fail:
static int mdss_mdp_parse_dt_mixer(struct platform_device *pdev)
{

	u32 nmixers, ndspp, npingpong;
	u32 nmixers, npingpong;
	int rc = 0;
	u32 *mixer_offsets = NULL, *dspp_offsets = NULL,
	    *pingpong_offsets = NULL;
@@ -2076,7 +2076,7 @@ static int mdss_mdp_parse_dt_mixer(struct platform_device *pdev)
				"qcom,mdss-mixer-intf-off");
	mdata->nmixers_wb = mdss_mdp_parse_dt_prop_len(pdev,
				"qcom,mdss-mixer-wb-off");
	ndspp = mdss_mdp_parse_dt_prop_len(pdev,
	mdata->ndspp = mdss_mdp_parse_dt_prop_len(pdev,
				"qcom,mdss-dspp-off");
	npingpong = mdss_mdp_parse_dt_prop_len(pdev,
				"qcom,mdss-pingpong-off");
@@ -2089,8 +2089,8 @@ static int mdss_mdp_parse_dt_mixer(struct platform_device *pdev)
		return -EINVAL;
	}

	if (mdata->nmixers_intf != ndspp) {
		pr_err("device tree err: unequal no of dspp and intf mixers\n");
	if (mdata->nmixers_intf < mdata->ndspp) {
		pr_err("device tree err: no of dspp are greater than intf mixers\n");
		return -EINVAL;
	}

@@ -2105,7 +2105,7 @@ static int mdss_mdp_parse_dt_mixer(struct platform_device *pdev)
		return -ENOMEM;
	}

	dspp_offsets = kzalloc(sizeof(u32) * ndspp, GFP_KERNEL);
	dspp_offsets = kzalloc(sizeof(u32) * mdata->ndspp, GFP_KERNEL);
	if (!dspp_offsets) {
		pr_err("no mem assigned: kzalloc fail\n");
		rc = -ENOMEM;
@@ -2129,7 +2129,7 @@ static int mdss_mdp_parse_dt_mixer(struct platform_device *pdev)
		goto parse_done;

	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-dspp-off",
		dspp_offsets, ndspp);
		dspp_offsets, mdata->ndspp);
	if (rc)
		goto parse_done;

@@ -2162,7 +2162,6 @@ dspp_alloc_fail:

static int mdss_mdp_parse_dt_ctl(struct platform_device *pdev)
{
	u32 nwb;
	int rc = 0;
	u32 *ctl_offsets = NULL, *wb_offsets = NULL;

@@ -2170,11 +2169,11 @@ static int mdss_mdp_parse_dt_ctl(struct platform_device *pdev)

	mdata->nctl = mdss_mdp_parse_dt_prop_len(pdev,
			"qcom,mdss-ctl-off");
	nwb =  mdss_mdp_parse_dt_prop_len(pdev,
	mdata->nwb =  mdss_mdp_parse_dt_prop_len(pdev,
			"qcom,mdss-wb-off");

	if (mdata->nctl != nwb) {
		pr_err("device tree err: unequal number of ctl and wb\n");
	if (mdata->nctl < mdata->nwb) {
		pr_err("device tree err: number of ctl greater than wb\n");
		rc = -EINVAL;
		goto parse_done;
	}
@@ -2185,7 +2184,7 @@ static int mdss_mdp_parse_dt_ctl(struct platform_device *pdev)
		return -ENOMEM;
	}

	wb_offsets = kzalloc(sizeof(u32) * nwb, GFP_KERNEL);
	wb_offsets = kzalloc(sizeof(u32) * mdata->nwb, GFP_KERNEL);
	if (!wb_offsets) {
		pr_err("no more mem for writeback offsets\n");
		rc = -ENOMEM;
@@ -2198,7 +2197,7 @@ static int mdss_mdp_parse_dt_ctl(struct platform_device *pdev)
		goto parse_done;

	rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-wb-off",
		wb_offsets, nwb);
		wb_offsets, mdata->nwb);
	if (rc)
		goto parse_done;

+12 −0
Original line number Diff line number Diff line
@@ -585,6 +585,18 @@ static inline void mdss_update_sd_client(struct mdss_data_type *mdata,
		atomic_add_unless(&mdss_res->sd_client_count, -1, 0);
}

static inline int mdss_mdp_get_wb_ctl_support(struct mdss_data_type *mdata,
							bool rotator_session)
{
	/*
	 * Initial control paths are used for primary and external
	 * interfaces and remaining control paths are used for WB
	 * interfaces.
	 */
	return rotator_session ? (mdata->nctl - mdata->nmixers_wb) :
				(mdata->nctl - mdata->nwb);
}

irqreturn_t mdss_mdp_isr(int irq, void *ptr);
int mdss_iommu_attach(struct mdss_data_type *mdata);
int mdss_iommu_dettach(struct mdss_data_type *mdata);
+15 −6
Original line number Diff line number Diff line
@@ -1382,7 +1382,8 @@ struct mdss_mdp_mixer *mdss_mdp_wb_mixer_alloc(int rotator)
{
	struct mdss_mdp_ctl *ctl = NULL;
	struct mdss_mdp_mixer *mixer = NULL;
	u32 offset = mdss_res->nctl - mdss_res->nmixers_wb;
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
	u32 offset = mdss_mdp_get_wb_ctl_support(mdata, true);

	ctl = mdss_mdp_ctl_alloc(mdss_res, offset);
	if (!ctl) {
@@ -1701,12 +1702,17 @@ static int mdss_mdp_ctl_setup_wfd(struct mdss_mdp_ctl *ctl)
struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata,
				       struct msm_fb_data_type *mfd)
{
	int ret = 0;
	int ret = 0, offset;
	struct mdss_mdp_ctl *ctl;
	struct mdss_data_type *mdata = mfd_to_mdata(mfd);
	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);

	ctl = mdss_mdp_ctl_alloc(mdata, MDSS_MDP_CTL0);
	if (pdata->panel_info.type == WRITEBACK_PANEL)
		offset = mdss_mdp_get_wb_ctl_support(mdata, false);
	else
		offset = MDSS_MDP_CTL0;

	ctl = mdss_mdp_ctl_alloc(mdata, offset);
	if (!ctl) {
		pr_err("unable to allocate ctl\n");
		return ERR_PTR(-ENOMEM);
@@ -2534,6 +2540,7 @@ int mdss_mdp_mixer_addr_setup(struct mdss_data_type *mdata,
		head[i].ref_cnt = 0;
		head[i].num = i;
		if (type == MDSS_MDP_MIXER_TYPE_INTF) {
			if (mdata->ndspp > i)
				head[i].dspp_base = mdata->mdss_io.base +
						dspp_offsets[i];
			head[i].pingpong_base = mdata->mdss_io.base +
@@ -2575,6 +2582,7 @@ int mdss_mdp_ctl_addr_setup(struct mdss_data_type *mdata,
	struct mutex *shared_lock = NULL;
	u32 i;
	u32 size = len;
	u32 offset = mdss_mdp_get_wb_ctl_support(mdata, false);

	if (mdata->wfd_mode == MDSS_MDP_WFD_SHARED) {
		size++;
@@ -2599,6 +2607,7 @@ int mdss_mdp_ctl_addr_setup(struct mdss_data_type *mdata,
	for (i = 0; i < len; i++) {
		head[i].num = i;
		head[i].base = (mdata->mdss_io.base) + ctl_offsets[i];
		if (i >= offset && wb_offsets[i - offset])
			head[i].wb_base = (mdata->mdss_io.base) + wb_offsets[i];
		head[i].ref_cnt = 0;
	}
+23 −4
Original line number Diff line number Diff line
@@ -472,7 +472,10 @@ int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx,
	case MDSS_MDP_BLOCK_WB:
		if (blk_idx < mdata->nctl) {
			ctl = mdata->ctl_off + blk_idx;
			if (ctl->wb_base)
				base = ctl->wb_base + MDSS_MDP_REG_WB_CSC_BASE;
			else
				ret = -EINVAL;
		} else {
			ret = -EINVAL;
		}
@@ -1400,6 +1403,9 @@ static char __iomem *mdss_mdp_get_dspp_addr_off(u32 dspp_num)
	if (mdata->nmixers_intf <= dspp_num) {
		pr_err("Invalid dspp_num=%d\n", dspp_num);
		return ERR_PTR(-EINVAL);
	} else if (mdata->ndspp <= dspp_num) {
		pr_err("destination not supported dspp_num=%d", dspp_num);
		return ERR_PTR(-EINVAL);
	}
	mixer = mdata->mixer_intf + dspp_num;
	return mixer->dspp_base;
@@ -1428,6 +1434,10 @@ static int pp_hist_setup(u32 *op, u32 block, struct mdss_mdp_mixer *mix)
			op_flags |= BIT(17);
		hist_info = &mdss_pp_res->dspp_hist[mix->num];
		base = mdss_mdp_get_dspp_addr_off(PP_BLOCK(block));
		if (IS_ERR(base)) {
			ret = -EPERM;
			goto error;
		}
		kick_base = MDSS_MDP_REG_DSPP_HIST_CTL_BASE;
	} else if (PP_LOCAT(block) == MDSS_PP_SSPP_CFG && is_hist_v1) {
		pipe = mdss_mdp_pipe_get(mdata, BIT(PP_BLOCK(block)));
@@ -1579,6 +1589,8 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
		(dspp_num >= mdata->nmixers_intf))
		return -EINVAL;
	base = mdss_mdp_get_dspp_addr_off(dspp_num);
	if (IS_ERR(base))
		return -EINVAL;

	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);

@@ -1923,9 +1935,10 @@ int mdss_mdp_pp_init(struct device *dev)
					mutex_init(&hist[i].hist_mutex);
					spin_lock_init(&hist[i].hist_lock);
					hist[i].intr_shift = (i * 4) + 12;
					hist[i].base =
					hist[i].base = i < mdata->ndspp ?
						mdss_mdp_get_dspp_addr_off(i) +
						MDSS_MDP_REG_DSPP_HIST_CTL_BASE;
						MDSS_MDP_REG_DSPP_HIST_CTL_BASE
						: NULL;
					init_completion(&hist[i].comp);
					init_completion(&hist[i].first_kick);
				}
@@ -1978,7 +1991,7 @@ static int pp_get_dspp_num(u32 disp_num, u32 *dspp_num)
		if (mixer_id[i] < mdata->nmixers_intf)
			break;
	}
	if (i >= mixer_cnt)
	if (i >= mixer_cnt || mixer_id[i] > mdata->ndspp)
		return -EPERM;
	*dspp_num = mixer_id[i];
	return 0;
@@ -3672,6 +3685,12 @@ int mdss_mdp_hist_collect(struct mdp_histogram_data *hist)
		}
		for (i = 0; i < hist_cnt; i++) {
			dspp_num = mixer_id[i];
			if (dspp_num > mdata->ndspp) {
				pr_err("%s, hist destination not supported",
					__func__);
				ret = -EPERM;
				goto hist_collect_exit;
			}
			ctl_base = mdss_mdp_get_dspp_addr_off(dspp_num) +
				MDSS_MDP_REG_DSPP_HIST_CTL_BASE;
			exp_sum = (mdata->mixer_intf[dspp_num].width *