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

Commit 0bdd3093 authored by Anusha Koduru's avatar Anusha Koduru Committed by Gerrit - the friendly Code Review server
Browse files

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



Apply per pipe BW limit check based on HFlip/VFlip. Some
targets have different limits for BW based on usecase.

Change-Id: Ie23dba396b47ffb3fb910e746e4a992fe6d78ab9
Signed-off-by: default avatarAnusha Koduru <kanusha@codeaurora.org>
parent 443cb5e0
Loading
Loading
Loading
Loading
+16 −2
Original line number Original line 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
				applied in scenarios where panel interface can
				be more tolerant to memory latency such as
				be more tolerant to memory latency such as
				command mode panels.
				command mode panels.
- qcom,max-bandwidth-per-pipe-kbps: This value indicates the max bandwidth in KB
- qcom,max-bandwidth-per-pipe-kbps: A two dimensional array indicating the max
				that a single pipe can support without underflow.
				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
- qcom,max-bw-settings:         This two dimension array indicates the max bandwidth
				in KB that has to be supported when particular
				in KB that has to be supported when particular
				scenarios are involved such as camera, flip.
				scenarios are involved such as camera, flip.
@@ -612,6 +624,8 @@ Example:


		qcom,max-bandwidth-low-kbps = <2300000>;
		qcom,max-bandwidth-low-kbps = <2300000>;
		qcom,max-bandwidth-high-kbps = <3000000>;
		qcom,max-bandwidth-high-kbps = <3000000>;
		qcom,max-bandwidth-per-pipe-kbps = <4 2100000>,
						   <8 1800000>;
		qcom,max-bw-settings = <1 2300000>,
		qcom,max-bw-settings = <1 2300000>,
				       <2 1700000>,
				       <2 1700000>,
				       <4 2300000>,
				       <4 2300000>,
+4 −0
Original line number Original line Diff line number Diff line
@@ -432,6 +432,10 @@ struct mdss_data_type {
	u32 bw_mode_bitmap;
	u32 bw_mode_bitmap;
	u32 max_bw_settings_cnt;
	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 bcolor0;
	u32 bcolor1;
	u32 bcolor1;
	u32 bcolor2;
	u32 bcolor2;
+58 −5
Original line number Original line 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;
	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)
static int mdss_mdp_parse_dt_misc(struct platform_device *pdev)
{
{
	struct mdss_data_type *mdata = platform_get_drvdata(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)
	if (rc)
		pr_debug("max bandwidth (high) property not specified\n");
		pr_debug("max bandwidth (high) property not specified\n");


	rc = of_property_read_u32(pdev->dev.of_node,
	mdss_mdp_parse_per_pipe_bandwidth(pdev);
		"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_max_bandwidth(pdev);
	mdss_mdp_parse_max_bandwidth(pdev);


+61 −1
Original line number Original line Diff line number Diff line
@@ -1402,6 +1402,61 @@ int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl,
	return 0;
	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,
int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf,
		struct mdss_mdp_pipe *pipe)
		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 */
	/* convert bandwidth to kb */
	pipe_bw = DIV_ROUND_UP_ULL(pipe_bw, 1000);
	pipe_bw = DIV_ROUND_UP_ULL(pipe_bw, 1000);



	if (!mdata->max_per_pipe_bw_settings)
		threshold = mdata->max_bw_per_pipe;
		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);
	pr_debug("bw=%llu threshold=%u\n", pipe_bw, threshold);


	if (threshold && pipe_bw > threshold) {
	if (threshold && pipe_bw > threshold) {