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

Commit 08939e92 authored by Adrian Salido-Moreno's avatar Adrian Salido-Moreno Committed by Gerrit - the friendly Code Review server
Browse files

msm: mdss: refactor device tree pipe parsing logic



Current logic is not properly scalable and hard to maintain, and makes
assumption on the order of pipe numbers. Simplify the logic in order
to be more generic and combine common code into a single helper
function which is easier to maintain.

CRs-Fixed: 987777
Change-Id: Ieb2dccee116e155476fca953bf583f0869968b59
Signed-off-by: default avatarAdrian Salido-Moreno <adrianm@codeaurora.org>
parent 399febd1
Loading
Loading
Loading
Loading
+90 −250
Original line number Original line Diff line number Diff line
@@ -80,10 +80,6 @@ struct msm_mdp_interface mdp5 = {
	.get_format_params = mdss_mdp_get_format_params,
	.get_format_params = mdss_mdp_get_format_params,
};
};


#define DEFAULT_TOTAL_RGB_PIPES 3
#define DEFAULT_TOTAL_VIG_PIPES 3
#define DEFAULT_TOTAL_DMA_PIPES 2

#define IB_QUOTA 2000000000
#define IB_QUOTA 2000000000
#define AB_QUOTA 2000000000
#define AB_QUOTA 2000000000


@@ -2384,7 +2380,7 @@ int mdss_mdp_parse_dt_hw_settings(struct platform_device *pdev)
	vbif_arr = of_get_property(pdev->dev.of_node, "qcom,vbif-settings",
	vbif_arr = of_get_property(pdev->dev.of_node, "qcom,vbif-settings",
			&vbif_len);
			&vbif_len);
	if (!vbif_arr || (vbif_len & 1)) {
	if (!vbif_arr || (vbif_len & 1)) {
		pr_warn("MDSS VBIF settings not found\n");
		pr_debug("MDSS VBIF settings not found\n");
		vbif_len = 0;
		vbif_len = 0;
	}
	}
	vbif_len /= 2 * sizeof(u32);
	vbif_len /= 2 * sizeof(u32);
@@ -2400,7 +2396,7 @@ int mdss_mdp_parse_dt_hw_settings(struct platform_device *pdev)
	mdp_arr = of_get_property(pdev->dev.of_node, "qcom,mdp-settings",
	mdp_arr = of_get_property(pdev->dev.of_node, "qcom,mdp-settings",
			&mdp_len);
			&mdp_len);
	if (!mdp_arr || (mdp_len & 1)) {
	if (!mdp_arr || (mdp_len & 1)) {
		pr_warn("MDSS MDP settings not found\n");
		pr_debug("MDSS MDP settings not found\n");
		mdp_len = 0;
		mdp_len = 0;
	}
	}
	mdp_len /= 2 * sizeof(u32);
	mdp_len /= 2 * sizeof(u32);
@@ -2628,267 +2624,86 @@ static void mdss_mdp_parse_dt_pipe_panic_ctrl(struct platform_device *pdev,
}
}


static int mdss_mdp_parse_dt_pipe_helper(struct platform_device *pdev,
static int mdss_mdp_parse_dt_pipe_helper(struct platform_device *pdev,
		u32 npipes,
		u32 ptype, char *ptypestr,
		u32 nfids)
		struct mdss_mdp_pipe **out_plist,
		size_t len,
		u8 priority_base)
{
{
	u32 dma_off;
	u32 *offsets = NULL, *ftch_id = NULL, *xin_id = NULL;
	u32 len;
	uint32_t setup_cnt = 0;
	int rc = 0, i;
	struct mdss_data_type *mdata = platform_get_drvdata(pdev);
	struct mdss_data_type *mdata = platform_get_drvdata(pdev);
	u32 offsets[MDSS_MDP_MAX_SSPP];
	u32 ftch_id[MDSS_MDP_MAX_SSPP];
	u32 xin_id[MDSS_MDP_MAX_SSPP];
	u32 pnums[MDSS_MDP_MAX_SSPP];
	struct mdss_mdp_pipe *pipe_list;
	char prop_name[64];
	int i, cnt, rc;

	if (!out_plist)
		return -EINVAL;


	offsets = kcalloc(npipes, sizeof(u32), GFP_KERNEL);
	for (i = 0, cnt = 0; i < MDSS_MDP_MAX_SSPP && cnt < len; i++) {
	if (!offsets)
		if (ptype == get_pipe_type_from_num(i)) {
		return -ENOMEM;
			pnums[cnt] = i;

			cnt++;
	ftch_id = kcalloc(npipes, sizeof(u32), GFP_KERNEL);
	if (!ftch_id) {
		rc = -ENOMEM;
		goto ftch_alloc_fail;
	}

	xin_id = kcalloc(npipes, sizeof(u32), GFP_KERNEL);
	if (!xin_id) {
		rc = -ENOMEM;
		goto xin_alloc_fail;
	}

	if (mdata->nvig_pipes) {
		mdata->vig_pipes = devm_kzalloc(&mdata->pdev->dev,
				    (sizeof(struct mdss_mdp_pipe)
				     * mdata->nvig_pipes), GFP_KERNEL);
		if (!mdata->vig_pipes) {
			rc = -ENOMEM;
			goto vig_alloc_fail;
		}
		if (nfids) {
			rc = mdss_mdp_parse_dt_handler(pdev,
					"qcom,mdss-pipe-vig-fetch-id", ftch_id,
					mdata->nvig_pipes);
			if (rc)
				goto parse_fail;
		}

		rc = mdss_mdp_parse_dt_handler(pdev,
				"qcom,mdss-pipe-vig-xin-id", xin_id,
				mdata->nvig_pipes);
		if (rc)
			goto parse_fail;

		rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-vig-off",
				offsets, mdata->nvig_pipes);
		if (rc)
			goto parse_fail;

		len = min_t(int, DEFAULT_TOTAL_VIG_PIPES,
			    (int)mdata->nvig_pipes);
		rc = mdss_mdp_pipe_addr_setup(mdata, mdata->vig_pipes, offsets,
					ftch_id, xin_id, MDSS_MDP_PIPE_TYPE_VIG,
					MDSS_MDP_SSPP_VIG0, len, 0);
		if (rc)
			goto parse_fail;

		setup_cnt += len;
	}

	if (mdata->nrgb_pipes) {
		mdata->rgb_pipes = devm_kzalloc(&mdata->pdev->dev,
				(sizeof(struct mdss_mdp_pipe) *
				 mdata->nrgb_pipes), GFP_KERNEL);
		if (!mdata->rgb_pipes) {
			rc = -ENOMEM;
			goto rgb_alloc_fail;
		}

		if (nfids) {
			rc = mdss_mdp_parse_dt_handler(pdev,
					"qcom,mdss-pipe-rgb-fetch-id",
					ftch_id + mdata->nvig_pipes,
					mdata->nrgb_pipes);
			if (rc)
				goto parse_fail;
		}

		rc = mdss_mdp_parse_dt_handler(pdev,
				"qcom,mdss-pipe-rgb-xin-id",
				xin_id + mdata->nvig_pipes, mdata->nrgb_pipes);
		if (rc)
			goto parse_fail;

		rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-rgb-off",
				offsets + mdata->nvig_pipes, mdata->nrgb_pipes);
		if (rc)
			goto parse_fail;

		len = min_t(int, DEFAULT_TOTAL_RGB_PIPES,
			    (int)mdata->nrgb_pipes);
		rc = mdss_mdp_pipe_addr_setup(mdata, mdata->rgb_pipes,
				offsets + mdata->nvig_pipes,
				ftch_id + mdata->nvig_pipes,
				xin_id + mdata->nvig_pipes,
				MDSS_MDP_PIPE_TYPE_RGB,
				MDSS_MDP_SSPP_RGB0, len, mdata->nvig_pipes);
		if (rc)
			goto parse_fail;

		setup_cnt += len;
	}

	if (mdata->ndma_pipes) {
		mdata->dma_pipes = devm_kzalloc(&mdata->pdev->dev,
			sizeof(struct mdss_mdp_pipe) * mdata->ndma_pipes,
			GFP_KERNEL);
		if (!mdata->dma_pipes) {
			pr_err("no mem for dma_pipes: kzalloc fail\n");
			rc = -ENOMEM;
			goto dma_alloc_fail;
		}

		dma_off = mdata->nvig_pipes + mdata->nrgb_pipes;

		if (nfids) {
			rc = mdss_mdp_parse_dt_handler(pdev,
				"qcom,mdss-pipe-dma-fetch-id",
				ftch_id + dma_off, mdata->ndma_pipes);
			if (rc)
				goto parse_fail;
		}

		rc = mdss_mdp_parse_dt_handler(pdev,
			"qcom,mdss-pipe-dma-xin-id",
			xin_id + dma_off, mdata->ndma_pipes);
		if (rc)
			goto parse_fail;

		rc = mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-dma-off",
			offsets + dma_off, mdata->ndma_pipes);
		if (rc)
			goto parse_fail;

		len = mdata->ndma_pipes;
		rc = mdss_mdp_pipe_addr_setup(mdata, mdata->dma_pipes,
			offsets + dma_off, ftch_id + dma_off, xin_id + dma_off,
			MDSS_MDP_PIPE_TYPE_DMA, MDSS_MDP_SSPP_DMA0, len,
			mdata->nvig_pipes + mdata->nrgb_pipes);
		if (rc)
			goto parse_fail;

		setup_cnt += len;
		}
		}

	if (mdata->nvig_pipes > DEFAULT_TOTAL_VIG_PIPES) {
		rc = mdss_mdp_pipe_addr_setup(mdata,
			mdata->vig_pipes + DEFAULT_TOTAL_VIG_PIPES,
			offsets + DEFAULT_TOTAL_VIG_PIPES,
			ftch_id + DEFAULT_TOTAL_VIG_PIPES,
			xin_id + DEFAULT_TOTAL_VIG_PIPES,
			MDSS_MDP_PIPE_TYPE_VIG, setup_cnt,
			mdata->nvig_pipes - DEFAULT_TOTAL_VIG_PIPES,
			DEFAULT_TOTAL_VIG_PIPES);
		if (rc)
			goto parse_fail;

		setup_cnt += mdata->nvig_pipes - DEFAULT_TOTAL_VIG_PIPES;
	}
	}


	if (mdata->nrgb_pipes > DEFAULT_TOTAL_RGB_PIPES) {
	if (cnt < len)
		rc = mdss_mdp_pipe_addr_setup(mdata,
		pr_warn("Invalid %s pipe count: %zu, max supported: %d\n",
			mdata->rgb_pipes + DEFAULT_TOTAL_RGB_PIPES,
				ptypestr, len, cnt);
			offsets + mdata->nvig_pipes + DEFAULT_TOTAL_RGB_PIPES,
	if (cnt == 0) {
			ftch_id + mdata->nvig_pipes + DEFAULT_TOTAL_RGB_PIPES,
		*out_plist = NULL;
			xin_id + mdata->nvig_pipes + DEFAULT_TOTAL_RGB_PIPES,
			MDSS_MDP_PIPE_TYPE_RGB, setup_cnt,
			mdata->nrgb_pipes - DEFAULT_TOTAL_RGB_PIPES,
			mdata->nvig_pipes + DEFAULT_TOTAL_RGB_PIPES);
		if (rc)
			goto parse_fail;


		setup_cnt += mdata->nrgb_pipes - DEFAULT_TOTAL_RGB_PIPES;
		return 0;
	}
	}


	if (mdata->nvig_pipes) {
	pipe_list = devm_kzalloc(&pdev->dev,
		rc = mdss_mdp_parse_dt_pipe_clk_ctrl(pdev,
			(sizeof(struct mdss_mdp_pipe) * cnt), GFP_KERNEL);
				"qcom,mdss-pipe-vig-clk-ctrl-offsets",
	if (!pipe_list)
				mdata->vig_pipes,
		return -ENOMEM;
				mdata->nvig_pipes);
		if (rc)
			goto parse_fail;
	}


	if (mdata->nrgb_pipes) {
	if (mdata->has_pixel_ram || (ptype == MDSS_MDP_PIPE_TYPE_CURSOR)) {
		rc = mdss_mdp_parse_dt_pipe_clk_ctrl(pdev,
		for (i = 0; i < cnt; i++)
				"qcom,mdss-pipe-rgb-clk-ctrl-offsets",
			ftch_id[i] = -1;
				mdata->rgb_pipes,
	} else {
				mdata->nrgb_pipes);
		snprintf(prop_name, sizeof(prop_name),
				"qcom,mdss-pipe-%s-fetch-id", ptypestr);
		rc = mdss_mdp_parse_dt_handler(pdev, prop_name, ftch_id,
				cnt);
		if (rc)
		if (rc)
			goto parse_fail;
			goto parse_fail;
	}
	}


	if (mdata->ndma_pipes) {
	snprintf(prop_name, sizeof(prop_name),
		rc = mdss_mdp_parse_dt_pipe_clk_ctrl(pdev,
			"qcom,mdss-pipe-%s-xin-id", ptypestr);
			"qcom,mdss-pipe-dma-clk-ctrl-offsets", mdata->dma_pipes,
	rc = mdss_mdp_parse_dt_handler(pdev, prop_name, xin_id, cnt);
			mdata->ndma_pipes);
	if (rc)
	if (rc)
		goto parse_fail;
		goto parse_fail;
	}


	if (mdata->ncursor_pipes) {
	snprintf(prop_name, sizeof(prop_name),
		mdata->cursor_pipes = devm_kzalloc(&mdata->pdev->dev,
			"qcom,mdss-pipe-%s-off", ptypestr);
			sizeof(struct mdss_mdp_pipe) * mdata->ncursor_pipes,
	rc = mdss_mdp_parse_dt_handler(pdev, prop_name, offsets, cnt);
			GFP_KERNEL);

		if (!mdata->cursor_pipes) {
			pr_err("no mem for cursor_pipes: kzalloc fail\n");
			rc = -ENOMEM;
			goto cursor_alloc_fail;
		}
		rc = mdss_mdp_parse_dt_handler(pdev,
			"qcom,mdss-pipe-cursor-off", offsets,
			mdata->ncursor_pipes);
	if (rc)
	if (rc)
		goto parse_fail;
		goto parse_fail;


		rc = mdss_mdp_parse_dt_handler(pdev,
	rc = mdss_mdp_pipe_addr_setup(mdata, pipe_list, offsets, ftch_id,
			"qcom,mdss-pipe-cursor-xin-id", xin_id,
			xin_id, ptype, pnums, cnt, priority_base);
			mdata->ncursor_pipes);
	if (rc)
	if (rc)
		goto parse_fail;
		goto parse_fail;


		rc = mdss_mdp_parse_dt_pipe_clk_ctrl(pdev,
	snprintf(prop_name, sizeof(prop_name),
			"qcom,mdss-pipe-cursor-clk-ctrl-offsets",
			"qcom,mdss-pipe-%s-clk-ctrl-offsets", ptypestr);
			mdata->cursor_pipes, mdata->ncursor_pipes);
	rc = mdss_mdp_parse_dt_pipe_clk_ctrl(pdev, prop_name,
			pipe_list, cnt);
	if (rc)
	if (rc)
		goto parse_fail;
		goto parse_fail;


		/* set the fetch id to an invalid value */
	*out_plist = pipe_list;
		for (i = 0; i < mdata->ncursor_pipes; i++)
			ftch_id[i] = -1;
		rc = mdss_mdp_pipe_addr_setup(mdata, mdata->cursor_pipes,
			offsets, ftch_id, xin_id, MDSS_MDP_PIPE_TYPE_CURSOR,
			MDSS_MDP_SSPP_CURSOR0, mdata->ncursor_pipes, 0);
		if (rc)
			goto parse_fail;
		pr_info("dedicated vp cursors detected, num=%d\n",
			mdata->ncursor_pipes);
	}
	goto parse_done;


	return cnt;
parse_fail:
parse_fail:
	kfree(mdata->cursor_pipes);
	devm_kfree(&pdev->dev, pipe_list);
cursor_alloc_fail:

	kfree(mdata->cursor_pipes);
dma_alloc_fail:
	kfree(mdata->rgb_pipes);
rgb_alloc_fail:
	kfree(mdata->vig_pipes);
vig_alloc_fail:
	kfree(xin_id);
xin_alloc_fail:
	kfree(ftch_id);
ftch_alloc_fail:
	kfree(offsets);
parse_done:
	return rc;
	return rc;
}
}


@@ -2942,9 +2757,34 @@ static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev)
		return -EINVAL;
		return -EINVAL;
	}
	}


	rc = mdss_mdp_parse_dt_pipe_helper(pdev, npipes, nfids);
	rc = mdss_mdp_parse_dt_pipe_helper(pdev, MDSS_MDP_PIPE_TYPE_VIG, "vig",
	if (rc)
			&mdata->vig_pipes, mdata->nvig_pipes, 0);
	if (IS_ERR_VALUE(rc))
		goto parse_fail;
	mdata->nvig_pipes = rc;

	rc = mdss_mdp_parse_dt_pipe_helper(pdev, MDSS_MDP_PIPE_TYPE_RGB, "rgb",
			&mdata->rgb_pipes, mdata->nrgb_pipes,
			mdata->nvig_pipes);
	if (IS_ERR_VALUE(rc))
		goto parse_fail;
		goto parse_fail;
	mdata->nrgb_pipes = rc;

	rc = mdss_mdp_parse_dt_pipe_helper(pdev, MDSS_MDP_PIPE_TYPE_DMA, "dma",
			&mdata->dma_pipes, mdata->ndma_pipes,
			mdata->nvig_pipes + mdata->nrgb_pipes);
	if (IS_ERR_VALUE(rc))
		goto parse_fail;
	mdata->ndma_pipes = rc;

	rc = mdss_mdp_parse_dt_pipe_helper(pdev, MDSS_MDP_PIPE_TYPE_CURSOR,
			"cursor", &mdata->cursor_pipes, mdata->ncursor_pipes,
			0);
	if (IS_ERR_VALUE(rc))
		goto parse_fail;
	mdata->ncursor_pipes = rc;

	rc = 0;


	mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-sw-reset-off",
	mdss_mdp_parse_dt_handler(pdev, "qcom,mdss-pipe-sw-reset-off",
		&sw_reset_offset, 1);
		&sw_reset_offset, 1);
@@ -4025,7 +3865,7 @@ static int mdss_mdp_parse_dt_prop_len(struct platform_device *pdev,
	of_find_property(pdev->dev.of_node, prop_name, &len);
	of_find_property(pdev->dev.of_node, prop_name, &len);


	if (len < 1) {
	if (len < 1) {
		pr_info("prop %s : doesn't exist in device tree\n",
		pr_debug("prop %s : doesn't exist in device tree\n",
			prop_name);
			prop_name);
		return 0;
		return 0;
	}
	}
+2 −2
Original line number Original line Diff line number Diff line
@@ -1520,8 +1520,8 @@ void mdss_mdp_smp_unreserve(struct mdss_mdp_pipe *pipe);
void mdss_mdp_smp_release(struct mdss_mdp_pipe *pipe);
void mdss_mdp_smp_release(struct mdss_mdp_pipe *pipe);


int mdss_mdp_pipe_addr_setup(struct mdss_data_type *mdata,
int mdss_mdp_pipe_addr_setup(struct mdss_data_type *mdata,
	struct mdss_mdp_pipe *head, u32 *offsets, u32 *ftch_y_id, u32 *xin_id,
	struct mdss_mdp_pipe *head, u32 *offsets, u32 *ftch_id, u32 *xin_id,
	u32 type, u32 num_base, u32 len, u8 priority_base);
	u32 type, const int *pnums, u32 len, u8 priority_base);
int mdss_mdp_mixer_addr_setup(struct mdss_data_type *mdata, u32 *mixer_offsets,
int mdss_mdp_mixer_addr_setup(struct mdss_data_type *mdata, u32 *mixer_offsets,
		u32 *dspp_offsets, u32 *pingpong_offsets, u32 type, u32 len);
		u32 *dspp_offsets, u32 *pingpong_offsets, u32 type, u32 len);
int mdss_mdp_ctl_addr_setup(struct mdss_data_type *mdata, u32 *ctl_offsets,
int mdss_mdp_ctl_addr_setup(struct mdss_data_type *mdata, u32 *ctl_offsets,
+3 −3
Original line number Original line Diff line number Diff line
@@ -2022,7 +2022,7 @@ static int mdss_mdp_format_setup(struct mdss_mdp_pipe *pipe)


int mdss_mdp_pipe_addr_setup(struct mdss_data_type *mdata,
int mdss_mdp_pipe_addr_setup(struct mdss_data_type *mdata,
	struct mdss_mdp_pipe *head, u32 *offsets, u32 *ftch_id, u32 *xin_id,
	struct mdss_mdp_pipe *head, u32 *offsets, u32 *ftch_id, u32 *xin_id,
	u32 type, u32 num_base, u32 len, u8 priority_base)
	u32 type, const int *pnums, u32 len, u8 priority_base)
{
{
	u32 i;
	u32 i;


@@ -2035,8 +2035,8 @@ int mdss_mdp_pipe_addr_setup(struct mdss_data_type *mdata,
		head[i].type = type;
		head[i].type = type;
		head[i].ftch_id  = ftch_id[i];
		head[i].ftch_id  = ftch_id[i];
		head[i].xin_id = xin_id[i];
		head[i].xin_id = xin_id[i];
		head[i].num = i + num_base;
		head[i].num = pnums[i];
		head[i].ndx = BIT(i + num_base);
		head[i].ndx = BIT(pnums[i]);
		head[i].priority = i + priority_base;
		head[i].priority = i + priority_base;
		head[i].base = mdata->mdss_io.base + offsets[i];
		head[i].base = mdata->mdss_io.base + offsets[i];
		pr_info("type:%d ftchid:%d xinid:%d num:%d ndx:0x%x prio:%d\n",
		pr_info("type:%d ftchid:%d xinid:%d num:%d ndx:0x%x prio:%d\n",