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

Commit 55577fae authored by Jayant Shekhar's avatar Jayant Shekhar Committed by Matt Wagantall
Browse files

msm: mdss: Add support to select max MDP bandwidth



MDSS currently has fixed maximum bandwidth enabled in DT file.
But there are scenarios where this maximum bandwidth support
can change to enhance performance. Based on scenarios such as
camera use, or flip involved declare the max bandwidth for
usecase in DT and change accordingly based on usecase.

Change-Id: Icc85d75d7a60fe6f934a1fbd9d5077b620b2993d
Signed-off-by: default avatarJayant Shekhar <jshekhar@codeaurora.org>
parent 3aeecfe8
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -421,6 +421,22 @@ Fudge Factors: Fudge factors are used to boost demand for
				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-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.
				The first parameter indicate the
				scenario/usecase and second paramter indicate
				the maximum bandwidth for that 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,mdss-has-panic-ctrl: Boolean property to indicate if panic/robust signal
				control feature is available or not.
- qcom,mdss-en-svs-high: Boolean property to indicate if this target needs to
@@ -602,6 +618,11 @@ Example:

		qcom,max-bandwidth-low-kbps = <2300000>;
		qcom,max-bandwidth-high-kbps = <3000000>;
		qcom,max-bw-settings = <1 2300000>,
				       <2 1700000>,
				       <4 2300000>,
				       <8 2000000>;

		qcom,max-mixer-width = <2048>;
		qcom,max-pipe-width = <2048>;
		qcom,max-clk-rate = <320000000>;
+9 −0
Original line number Diff line number Diff line
@@ -64,6 +64,11 @@ struct mdss_hw_settings {
	u32 val;
};

struct mdss_max_bw_settings {
	u32 mdss_max_bw_mode;
	u32 mdss_max_bw_val;
};

struct mdss_debug_inf {
	void *debug_data;
	void (*debug_enable_clock)(int on);
@@ -393,6 +398,10 @@ struct mdss_data_type {

	struct mutex mdp_bus_lock;
	u32 bus_ref_cnt;

	struct mdss_max_bw_settings *max_bw_settings;
	u32 bw_mode_bitmap;
	u32 max_bw_settings_cnt;
};
extern struct mdss_data_type *mdss_res;

+64 −0
Original line number Diff line number Diff line
@@ -1419,10 +1419,29 @@ static ssize_t mdss_mdp_show_capabilities(struct device *dev,
	return cnt;
}

static ssize_t mdss_mdp_store_max_limit_bw(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t len)
{
	struct mdss_data_type *mdata = dev_get_drvdata(dev);
	u32 data = 0;

	if (1 != sscanf(buf, "%d", &data)) {
		pr_info("Not able scan to bw_mode_bitmap\n");
	} else {
		mdata->bw_mode_bitmap = data;
		pr_debug("limit use case, bw_mode_bitmap = %d\n", data);
	}

	return len;
}

static DEVICE_ATTR(caps, S_IRUGO, mdss_mdp_show_capabilities, NULL);
static DEVICE_ATTR(bw_mode_bitmap, S_IRUGO | S_IWUSR | S_IWGRP, NULL,
		mdss_mdp_store_max_limit_bw);

static struct attribute *mdp_fs_attrs[] = {
	&dev_attr_caps.attr,
	&dev_attr_bw_mode_bitmap.attr,
	NULL
};

@@ -2814,6 +2833,48 @@ static void mdss_mdp_parse_vbif_qos(struct platform_device *pdev)
	}
}

static void mdss_mdp_parse_max_bw_array(const u32 *arr,
		struct mdss_max_bw_settings *max_bw_settings, int count)
{
	int i;
	for (i = 0; i < count; i++) {
		max_bw_settings->mdss_max_bw_mode = be32_to_cpu(arr[i*2]);
		max_bw_settings->mdss_max_bw_val = be32_to_cpu(arr[(i*2)+1]);
		max_bw_settings++;
	}
}

static void mdss_mdp_parse_max_bandwidth(struct platform_device *pdev)
{
	struct mdss_data_type *mdata = platform_get_drvdata(pdev);
	struct mdss_max_bw_settings *max_bw_settings;
	int max_bw_settings_cnt = 0;
	const u32 *max_bw;

	max_bw = of_get_property(pdev->dev.of_node, "qcom,max-bw-settings",
			&max_bw_settings_cnt);

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

	max_bw_settings_cnt /= 2 * sizeof(u32);

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

	mdss_mdp_parse_max_bw_array(max_bw, max_bw_settings,
			max_bw_settings_cnt);

	mdata->max_bw_settings = max_bw_settings;
	mdata->max_bw_settings_cnt = max_bw_settings_cnt;
}

static int mdss_mdp_parse_dt_misc(struct platform_device *pdev)
{
	struct mdss_data_type *mdata = platform_get_drvdata(pdev);
@@ -2947,6 +3008,9 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev)
	if (rc)
		pr_debug("max bandwidth (per pipe) property not specified\n");


	mdss_mdp_parse_max_bandwidth(pdev);

	mdata->nclk_lvl = mdss_mdp_parse_dt_prop_len(pdev,
					"qcom,mdss-clk-levels");

+79 −1
Original line number Diff line number Diff line
@@ -1211,13 +1211,83 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl,
			*(perf->bw_vote_mode), perf->bw_writeback);
}

static u32 mdss_check_for_flip(struct mdss_mdp_ctl *ctl)
{
	u32 i, panel_orientation;
	struct mdss_mdp_pipe *pipe;
	u32 flags = 0;

	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;

	for (i = 0; i < MAX_PIPES_PER_LM; i++) {
		if ((flags & MDSS_MAX_BW_LIMIT_HFLIP) &&
				(flags & MDSS_MAX_BW_LIMIT_VFLIP))
			return flags;

		if (ctl->mixer_left && ctl->mixer_left->stage_pipe[i]) {
			pipe = ctl->mixer_left->stage_pipe[i];
			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 (ctl->mixer_right && ctl->mixer_right->stage_pipe[i]) {
			pipe = ctl->mixer_right->stage_pipe[i];
			if (pipe->flags & MDP_FLIP_LR)
				flags |= MDSS_MAX_BW_LIMIT_HFLIP;
			if (pipe->flags & MDP_FLIP_UD)
				flags |= MDSS_MAX_BW_LIMIT_VFLIP;
		}
	}

	return flags;
}

static int mdss_mdp_set_threshold_max_bandwidth(struct mdss_mdp_ctl *ctl)
{
	u32 mode, threshold = 0, max = INT_MAX;
	u32 i = 0;
	struct mdss_max_bw_settings *max_bw_settings =
		ctl->mdata->max_bw_settings;

	if (!ctl->mdata->max_bw_settings_cnt && !ctl->mdata->max_bw_settings)
		return 0;

	mode = ctl->mdata->bw_mode_bitmap;

	if (!((mode & MDSS_MAX_BW_LIMIT_HFLIP) &&
				(mode & MDSS_MAX_BW_LIMIT_VFLIP)))
		mode |= mdss_check_for_flip(ctl);

	pr_debug("final mode = %d, bw_mode_bitmap = %d\n", mode,
			ctl->mdata->bw_mode_bitmap);

	/* Select BW mode with smallest limit */
	while (mode) {
		if (mode & BIT(0)) {
			threshold = max_bw_settings[i].mdss_max_bw_val;
			if (threshold < max)
				max = threshold;
		}
		mode >>= 1;
		i++;
	}

	return max;
}

int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl,
		struct mdss_mdp_pipe **left_plist, int left_cnt,
		struct mdss_mdp_pipe **right_plist, int right_cnt)
{
	struct mdss_data_type *mdata = ctl->mdata;
	struct mdss_mdp_perf_params perf;
	u32 bw, threshold, i, mode_switch;
	u32 bw, threshold, i, mode_switch, max_bw;
	u64 bw_sum_of_intfs = 0;
	bool is_video_mode;

@@ -1250,6 +1320,14 @@ int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl,
	threshold = (is_video_mode ||
		mdss_mdp_video_mode_intf_connected(ctl)) ?
		mdata->max_bw_low : mdata->max_bw_high;

	max_bw = mdss_mdp_set_threshold_max_bandwidth(ctl);

	if (max_bw && (max_bw < threshold))
		threshold = max_bw;

	pr_debug("final threshold bw limit = %d\n", threshold);

	if (bw > threshold) {
		ctl->bw_pending = 0;
		pr_debug("exceeds bandwidth: %ukb > %ukb\n", bw, threshold);
+7 −0
Original line number Diff line number Diff line
@@ -192,6 +192,13 @@ enum {
	NUM_HSIC_PARAM,
};

enum mdss_mdp_max_bw_mode {
	MDSS_MAX_BW_LIMIT_DEFAULT = 0x1,
	MDSS_MAX_BW_LIMIT_CAMERA = 0x2,
	MDSS_MAX_BW_LIMIT_HFLIP = 0x4,
	MDSS_MAX_BW_LIMIT_VFLIP = 0x8,
};

#define MDSS_MDP_ROT_ONLY		0x80
#define MDSS_MDP_RIGHT_MIXER		0x100
#define MDSS_MDP_DUAL_PIPE		0x200