From fc1216dd7c4233ed499f42a9e987f07e9057f798 Mon Sep 17 00:00:00 2001
From: Ingrid Gallardo <ingridg@codeaurora.org>
Date: Mon, 29 Aug 2016 20:34:59 -0700
Subject: [PATCH] msm: mdss: consider ib to commit the bw vote for mdp

For some use cases, the calculation of the ib
bandwidth prevails over the ab bandwidth. For
such use cases, we must consider the ib as well
as the ab before reducing/increasing the vote,
so the correct sequence to apply the bw vote
is executed along with the HW changes.
Current driver only considers the ab bw and
misses to consider the ib bw during the decision
of when to apply the bw vote.
This change includes ib into the consideration of
when to apply the bw vote.

CRs-Fixed: 1057105
Change-Id: I0822f2e60c4ac22b1636d1d5988ba322dafcdb49
Signed-off-by: Ingrid Gallardo <ingridg@codeaurora.org>
---
 drivers/video/fbdev/msm/mdss_mdp_ctl.c   | 75 ++++++++++++++++++------
 drivers/video/fbdev/msm/mdss_mdp_trace.h | 40 +++++++++++++
 2 files changed, 97 insertions(+), 18 deletions(-)

diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index abc048866313..5b43453cc002 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -2040,12 +2040,11 @@ static u64 mdss_mdp_ctl_calc_client_vote(struct mdss_data_type *mdata,
 	return bw_sum_of_intfs;
 }
 
-static void mdss_mdp_ctl_update_client_vote(struct mdss_data_type *mdata,
+/* apply any adjustments to the ib quota */
+static inline u64 __calc_bus_ib_quota(struct mdss_data_type *mdata,
 	struct mdss_mdp_perf_params *perf, bool nrt_client, u64 bw_vote)
 {
-	u64 bus_ab_quota, bus_ib_quota;
-
-	bus_ab_quota = max(bw_vote, mdata->perf_tune.min_bus_vote);
+	u64 bus_ib_quota;
 
 	if (test_bit(MDSS_QOS_PER_PIPE_IB, mdata->mdss_qos_map)) {
 		if (!nrt_client)
@@ -2071,6 +2070,18 @@ static void mdss_mdp_ctl_update_client_vote(struct mdss_data_type *mdata,
 		bus_ib_quota = apply_fudge_factor(bus_ib_quota,
 			&mdata->per_pipe_ib_factor);
 
+	return bus_ib_quota;
+}
+
+static void mdss_mdp_ctl_update_client_vote(struct mdss_data_type *mdata,
+	struct mdss_mdp_perf_params *perf, bool nrt_client, u64 bw_vote)
+{
+	u64 bus_ab_quota, bus_ib_quota;
+
+	bus_ab_quota = max(bw_vote, mdata->perf_tune.min_bus_vote);
+	bus_ib_quota = __calc_bus_ib_quota(mdata, perf, nrt_client, bw_vote);
+
+
 	bus_ab_quota = apply_fudge_factor(bus_ab_quota, &mdss_res->ab_factor);
 	ATRACE_INT("bus_quota", bus_ib_quota);
 
@@ -2232,6 +2243,46 @@ static bool is_traffic_shaper_enabled(struct mdss_data_type *mdata)
 	return false;
 }
 
+static bool __mdss_mdp_compare_bw(
+	struct mdss_mdp_ctl *ctl,
+	struct mdss_mdp_perf_params *new_perf,
+	struct mdss_mdp_perf_params *old_perf,
+	bool params_changed,
+	bool stop_req)
+{
+	struct mdss_data_type *mdata = ctl->mdata;
+	bool is_nrt = mdss_mdp_is_nrt_ctl_path(ctl);
+	u64 new_ib =
+		__calc_bus_ib_quota(mdata, new_perf, is_nrt, new_perf->bw_ctl);
+	u64 old_ib =
+		__calc_bus_ib_quota(mdata, old_perf, is_nrt, old_perf->bw_ctl);
+	u64 max_new_bw = max(new_perf->bw_ctl, new_ib);
+	u64 max_old_bw = max(old_perf->bw_ctl, old_ib);
+	bool update_bw = false;
+
+	/*
+	 * three cases for bus bandwidth update.
+	 * 1. new bandwidth vote (ab or ib) or writeback output vote
+	 *		are higher than current vote for update request.
+	 * 2. new bandwidth vote or writeback output vote are
+	 *		lower than current vote at end of commit or stop.
+	 * 3. end of writeback/rotator session - last chance to
+	 *		non-realtime remove vote.
+	 */
+	if ((params_changed && ((max_new_bw > max_old_bw) || /* ab and ib bw */
+			(new_perf->bw_writeback > old_perf->bw_writeback))) ||
+			(!params_changed && ((max_new_bw < max_old_bw) ||
+			(new_perf->bw_writeback < old_perf->bw_writeback))) ||
+			(stop_req && is_nrt))
+		update_bw = true;
+
+	trace_mdp_compare_bw(new_perf->bw_ctl, new_ib, new_perf->bw_writeback,
+		max_new_bw, old_perf->bw_ctl, old_ib, old_perf->bw_writeback,
+		max_old_bw, params_changed, update_bw);
+
+	return update_bw;
+}
+
 static void mdss_mdp_ctl_perf_update(struct mdss_mdp_ctl *ctl,
 		int params_changed, bool stop_req)
 {
@@ -2267,20 +2318,8 @@ static void mdss_mdp_ctl_perf_update(struct mdss_mdp_ctl *ctl,
 		else if (is_bw_released || params_changed)
 			mdss_mdp_perf_calc_ctl(ctl, new);
 
-		/*
-		 * three cases for bus bandwidth update.
-		 * 1. new bandwidth vote or writeback output vote
-		 *    are higher than current vote for update request.
-		 * 2. new bandwidth vote or writeback output vote are
-		 *    lower than current vote at end of commit or stop.
-		 * 3. end of writeback/rotator session - last chance to
-		 *    non-realtime remove vote.
-		 */
-		if ((params_changed && ((new->bw_ctl > old->bw_ctl) ||
-			(new->bw_writeback > old->bw_writeback))) ||
-		    (!params_changed && ((new->bw_ctl < old->bw_ctl) ||
-			(new->bw_writeback < old->bw_writeback))) ||
-			(stop_req && mdss_mdp_is_nrt_ctl_path(ctl))) {
+		if (__mdss_mdp_compare_bw(ctl, new, old, params_changed,
+				stop_req)) {
 
 			pr_debug("c=%d p=%d new_bw=%llu,old_bw=%llu\n",
 				ctl->num, params_changed, new->bw_ctl,
diff --git a/drivers/video/fbdev/msm/mdss_mdp_trace.h b/drivers/video/fbdev/msm/mdss_mdp_trace.h
index 85829fbba075..648e4fcd1cd2 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_trace.h
+++ b/drivers/video/fbdev/msm/mdss_mdp_trace.h
@@ -295,6 +295,46 @@ TRACE_EVENT(mdp_perf_update_bus,
 			__entry->ib_quota)
 );
 
+TRACE_EVENT(mdp_compare_bw,
+	TP_PROTO(unsigned long long new_ab, unsigned long long new_ib,
+		unsigned long long new_wb, unsigned long long new_max,
+		unsigned long long old_ab, unsigned long long old_ib,
+		unsigned long long old_wb, unsigned long long old_max,
+		u32 params_changed, bool update_bw),
+	TP_ARGS(new_ab, new_ib, new_wb, new_max,
+					old_ab, old_ib, old_wb, old_max,
+					params_changed, update_bw),
+	TP_STRUCT__entry(
+			__field(u64, new_ab)
+			__field(u64, new_ib)
+			__field(u64, new_wb)
+			__field(u64, new_max)
+			__field(u64, old_ab)
+			__field(u64, old_ib)
+			__field(u64, old_wb)
+			__field(u64, old_max)
+			__field(u32, params_changed)
+			__field(bool, update_bw)
+	),
+	TP_fast_assign(
+			__entry->new_ab = new_ab;
+			__entry->new_ib = new_ib;
+			__entry->new_wb = new_wb;
+			__entry->new_max = new_max;
+			__entry->old_ab = old_ab;
+			__entry->old_ib = old_ib;
+			__entry->old_wb = old_wb;
+			__entry->old_max = old_max;
+			__entry->params_changed = params_changed;
+			__entry->update_bw = update_bw;
+	),
+	TP_printk("[ab,ib,wb,max] new[%llu, %llu, %llu, %llu] old[%llu, %llu, %llu, %llu] parm:%d ret:%d",
+		__entry->new_ab, __entry->new_ib, __entry->new_wb,
+		__entry->new_max, __entry->old_ab, __entry->old_ib,
+		__entry->old_wb, __entry->old_max, __entry->params_changed,
+		__entry->update_bw)
+);
+
 TRACE_EVENT(mdp_misr_crc,
 	TP_PROTO(u32 block_id, u32 vsync_cnt, u32 crc),
 	TP_ARGS(block_id, vsync_cnt, crc),