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

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

Merge "msm: mdss: specify HFlip and VFlip per pipe BW limit"

parents 6c79692d 0bdd3093
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -427,8 +427,20 @@ Fudge Factors: Fudge factors are used to boost demand for
				applied in scenarios where panel interface can
				be more tolerant to memory latency such as
				command mode panels.
- qcom,max-bandwidth-per-pipe-kbps: This value indicates the max bandwidth in KB
				that a single pipe can support without underflow.
- qcom,max-bandwidth-per-pipe-kbps: A two dimensional array indicating the max
				bandwidth in KB that a single pipe can support
				without underflow for various usecases. The
				first parameter indicates the usecase and the
				second parameter gives the max bw allowed for
				the usecase. Following are the enum values for
				modes in different cases:
				For default case, mode = 1
				camera usecase, mode = 2
				hflip usecase, mode = 4
				vflip usecase, mode = 8
				First parameter/mode value need to match enum,
				mdss_mdp_max_bw_mode, present in
				include/uapi/linux/msm_mdp.h.
- qcom,max-bw-settings:         This two dimension array indicates the max bandwidth
				in KB that has to be supported when particular
				scenarios are involved such as camera, flip.
@@ -612,6 +624,8 @@ Example:

		qcom,max-bandwidth-low-kbps = <2300000>;
		qcom,max-bandwidth-high-kbps = <3000000>;
		qcom,max-bandwidth-per-pipe-kbps = <4 2100000>,
						   <8 1800000>;
		qcom,max-bw-settings = <1 2300000>,
				       <2 1700000>,
				       <4 2300000>,
+4 −0
Original line number Diff line number Diff line
@@ -432,6 +432,10 @@ struct mdss_data_type {
	u32 bw_mode_bitmap;
	u32 max_bw_settings_cnt;

	struct mdss_max_bw_settings *max_per_pipe_bw_settings;
	u32 mdss_per_pipe_bw_cnt;
	u32 min_bw_per_pipe;

	u32 bcolor0;
	u32 bcolor1;
	u32 bcolor2;
+58 −5
Original line number Diff line number Diff line
@@ -2992,6 +2992,63 @@ static void mdss_mdp_parse_max_bandwidth(struct platform_device *pdev)
	mdata->max_bw_settings_cnt = max_bw_settings_cnt;
}

static void mdss_mdp_parse_per_pipe_bandwidth(struct platform_device *pdev)
{

	struct mdss_data_type *mdata = platform_get_drvdata(pdev);
	struct mdss_max_bw_settings *max_bw_per_pipe_settings;
	int max_bw_settings_cnt = 0;
	const u32 *max_bw_settings;
	u32 max_bw, min_bw, threshold, i = 0;

	max_bw_settings = of_get_property(pdev->dev.of_node,
			"qcom,max-bandwidth-per-pipe-kbps",
			&max_bw_settings_cnt);

	if (!max_bw_settings || !max_bw_settings_cnt) {
		pr_debug("MDSS per pipe max bandwidth settings not found\n");
		return;
	}

	/* Support targets where a common per pipe max bw is provided */
	if ((max_bw_settings_cnt / sizeof(u32)) == 1) {
		mdata->max_bw_per_pipe = be32_to_cpu(max_bw_settings[0]);
		mdata->max_per_pipe_bw_settings = NULL;
		pr_debug("Common per pipe max bandwidth provided\n");
		return;
	}

	max_bw_settings_cnt /= 2 * sizeof(u32);

	max_bw_per_pipe_settings = devm_kzalloc(&pdev->dev,
		    sizeof(struct mdss_max_bw_settings) * max_bw_settings_cnt,
		    GFP_KERNEL);
	if (!max_bw_per_pipe_settings) {
		pr_err("Memory allocation failed for max_bw_settings\n");
		return;
	}

	mdss_mdp_parse_max_bw_array(max_bw_settings, max_bw_per_pipe_settings,
					max_bw_settings_cnt);
	mdata->max_per_pipe_bw_settings = max_bw_per_pipe_settings;
	mdata->mdss_per_pipe_bw_cnt = max_bw_settings_cnt;

	/* Calculate min and max allowed per pipe BW */
	min_bw = mdata->max_bw_high;
	max_bw = 0;

	while (i < max_bw_settings_cnt) {
		threshold = mdata->max_per_pipe_bw_settings[i].mdss_max_bw_val;
		if (threshold > max_bw)
			max_bw = threshold;
		if (threshold < min_bw)
			min_bw = threshold;
		++i;
	}
	mdata->max_bw_per_pipe = max_bw;
	mdata->min_bw_per_pipe = min_bw;
}

static int mdss_mdp_parse_dt_misc(struct platform_device *pdev)
{
	struct mdss_data_type *mdata = platform_get_drvdata(pdev);
@@ -3120,11 +3177,7 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev)
	if (rc)
		pr_debug("max bandwidth (high) property not specified\n");

	rc = of_property_read_u32(pdev->dev.of_node,
		"qcom,max-bandwidth-per-pipe-kbps", &mdata->max_bw_per_pipe);
	if (rc)
		pr_debug("max bandwidth (per pipe) property not specified\n");

	mdss_mdp_parse_per_pipe_bandwidth(pdev);

	mdss_mdp_parse_max_bandwidth(pdev);

+61 −1
Original line number Diff line number Diff line
@@ -1402,6 +1402,61 @@ int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl,
	return 0;
}

static u32 mdss_mdp_get_bw_by_mode(struct mdss_max_bw_settings *settings,
					int count, int key)
{
	u32 value = 0, i = 0;

	while (i < count) {
		if (settings[i].mdss_max_bw_mode == key) {
			value = settings[i].mdss_max_bw_val;
			break;
		}
		++i;
	}
	return value;
}

static u32 mdss_mdp_get_max_pipe_bw(struct mdss_mdp_pipe *pipe)
{

	struct mdss_data_type *mdata = pipe->mixer_left->ctl->mdata;
	struct mdss_mdp_ctl *ctl = pipe->mixer_left->ctl;
	u32 flags = 0, threshold = 0, panel_orientation;

	panel_orientation = ctl->mfd->panel_orientation;

	/* Check for panel orienatation */
	panel_orientation = ctl->mfd->panel_orientation;
	if (panel_orientation & MDP_FLIP_LR)
		flags |= MDSS_MAX_BW_LIMIT_HFLIP;
	if (panel_orientation & MDP_FLIP_UD)
		flags |= MDSS_MAX_BW_LIMIT_VFLIP;

	/* check for Hflip/Vflip in pipe */
	if (pipe->flags & MDP_FLIP_LR)
		flags |= MDSS_MAX_BW_LIMIT_HFLIP;
	if (pipe->flags & MDP_FLIP_UD)
		flags |= MDSS_MAX_BW_LIMIT_VFLIP;

	if ((flags & MDSS_MAX_BW_LIMIT_HFLIP) &&
			(flags &  MDSS_MAX_BW_LIMIT_VFLIP)) {
		threshold = mdata->min_bw_per_pipe;
	} else if (flags & MDSS_MAX_BW_LIMIT_HFLIP) {
		threshold = mdss_mdp_get_bw_by_mode(
					mdata->max_per_pipe_bw_settings,
					mdata->mdss_per_pipe_bw_cnt,
					MDSS_MAX_BW_LIMIT_HFLIP);
	} else if (flags & MDSS_MAX_BW_LIMIT_VFLIP) {
		threshold = mdss_mdp_get_bw_by_mode(
					mdata->max_per_pipe_bw_settings,
					mdata->mdss_per_pipe_bw_cnt,
					MDSS_MAX_BW_LIMIT_VFLIP);
	}

	return threshold ? threshold : mdata->max_bw_per_pipe;
}

int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf,
		struct mdss_mdp_pipe *pipe)
{
@@ -1427,7 +1482,12 @@ int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf,
	/* convert bandwidth to kb */
	pipe_bw = DIV_ROUND_UP_ULL(pipe_bw, 1000);


	if (!mdata->max_per_pipe_bw_settings)
		threshold = mdata->max_bw_per_pipe;
	else
		threshold = mdss_mdp_get_max_pipe_bw(pipe);

	pr_debug("bw=%llu threshold=%u\n", pipe_bw, threshold);

	if (threshold && pipe_bw > threshold) {