msm: msm_bus: Interleaving related corrections

Fix the division of bandwidth between slaves with multiple ports.
Since, interleaving changes involve exposing multiple ports for
a given master, config functions need to be changed for
halting/unhalting the right ports.

Signed-off-by: Gagan Mac <gmac@codeaurora.org>
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
index bb53dd3..e3b7676 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
@@ -511,7 +511,7 @@
 	curr = client->curr;
 	pdata = client->pdata;
 
-	if ((index < 0) || (index > pdata->num_usecases)) {
+	if ((index < 0) || (index >= pdata->num_usecases)) {
 		MSM_BUS_ERR("Client %u passed invalid index: %d\n",
 			(uint32_t)client, index);
 		ret = -ENXIO;
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
index e8d529b..87d38b9 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
@@ -22,9 +22,6 @@
 #include <mach/rpm.h>
 #include "msm_bus_core.h"
 
-#define GET_RATE(clk, nports) \
-	((clk % nports) ? ((clk + nports - 1) / nports) : (clk / nports))
-
 enum {
 	SLAVE_NODE,
 	MASTER_NODE,
@@ -288,19 +285,18 @@
 	} else {
 		nodeclk = &slave->nodeclk[ctx];
 		if (nodeclk->clk && (!((ctx == ACTIVE_CTX) ^ cl_active_flag))) {
-			rate = GET_RATE(*pclk, slave->node_info->num_sports);
+			rate = *pclk;
 			MSM_BUS_DBG("AXI_clks: id: %d set-clk: %lu "
 			"bwsum_hz: %lu\n" , slave->node_info->priv_id, rate,
 			bwsum_hz);
-			if (nodeclk->rate != *pclk) {
+			if (nodeclk->rate != rate) {
 				nodeclk->dirty = true;
 				nodeclk->rate = rate;
 			}
 		}
 		if (!status && slave->memclk.clk &&
 			(!((ctx == ACTIVE_CTX) ^ cl_active_flag))) {
-			rate = GET_RATE(*slave->link_info.sel_clk,
-				slave->node_info->num_sports);
+			rate = *slave->link_info.sel_clk;
 			if (slave->memclk.rate != rate) {
 				slave->memclk.rate = rate;
 				slave->memclk.dirty = true;
@@ -471,7 +467,7 @@
 	struct msm_bus_halt_vector hvector = {0, 0};
 	struct msm_rpm_iv_pair rpm_data[2];
 	struct msm_bus_inode_info *info = NULL;
-	uint8_t mport, i;
+	uint8_t mport;
 	uint32_t haltid = 0;
 	int status = 0;
 	struct msm_bus_fabric *fabric = to_msm_bus_fabric(fabdev);
@@ -483,26 +479,23 @@
 	}
 
 	haltid = fabric->pdata->haltid;
-	for (i = 0; i < info->node_info->num_mports; i++) {
-		mport = info->node_info->masterp[i];
-		MSM_BUS_MASTER_HALT(hvector.haltmask, hvector.haltval, mport);
-		rpm_data[0].id = haltid;
-		rpm_data[0].value = hvector.haltval;
-		rpm_data[1].id = haltid + 1;
-		rpm_data[1].value = hvector.haltmask;
+	mport = info->node_info->masterp[0];
+	MSM_BUS_MASTER_HALT(hvector.haltmask, hvector.haltval, mport);
+	rpm_data[0].id = haltid;
+	rpm_data[0].value = hvector.haltval;
+	rpm_data[1].id = haltid + 1;
+	rpm_data[1].value = hvector.haltmask;
 
-		MSM_FAB_DBG("ctx: %d, id: %d, value: %d\n",
-				MSM_RPM_CTX_SET_0,
-				rpm_data[0].id, rpm_data[0].value);
-		MSM_FAB_DBG("ctx: %d, id: %d, value: %d\n",
-				MSM_RPM_CTX_SET_0,
-				rpm_data[1].id, rpm_data[1].value);
+	MSM_FAB_DBG("ctx: %d, id: %d, value: %d\n",
+		MSM_RPM_CTX_SET_0, rpm_data[0].id, rpm_data[0].value);
+	MSM_FAB_DBG("ctx: %d, id: %d, value: %d\n",
+		MSM_RPM_CTX_SET_0, rpm_data[1].id, rpm_data[1].value);
 
-		if (fabric->pdata->rpm_enabled)
-			status = msm_rpm_set(MSM_RPM_CTX_SET_0, rpm_data, 2);
-		if (status)
-			MSM_BUS_ERR("msm_rpm_set returned: %d\n", status);
-	}
+	if (fabric->pdata->rpm_enabled)
+		status = msm_rpm_set(MSM_RPM_CTX_SET_0, rpm_data, 2);
+	if (status)
+		MSM_BUS_ERR("msm_rpm_set returned: %d\n", status);
+
 	return status;
 }
 
@@ -516,7 +509,7 @@
 	struct msm_bus_halt_vector hvector = {0, 0};
 	struct msm_rpm_iv_pair rpm_data[2];
 	struct msm_bus_inode_info *info = NULL;
-	uint8_t mport, i;
+	uint8_t mport;
 	uint32_t haltid = 0;
 	int status = 0;
 	struct msm_bus_fabric *fabric = to_msm_bus_fabric(fabdev);
@@ -528,27 +521,23 @@
 	}
 
 	haltid = fabric->pdata->haltid;
-	for (i = 0; i < info->node_info->num_mports; i++) {
-		mport = info->node_info->masterp[i];
-		MSM_BUS_MASTER_UNHALT(hvector.haltmask, hvector.haltval,
-			mport);
-		rpm_data[0].id = haltid;
-		rpm_data[0].value = hvector.haltval;
-		rpm_data[1].id = haltid + 1;
-		rpm_data[1].value = hvector.haltmask;
+	mport = info->node_info->masterp[0];
+	MSM_BUS_MASTER_UNHALT(hvector.haltmask, hvector.haltval,
+		mport);
+	rpm_data[0].id = haltid;
+	rpm_data[0].value = hvector.haltval;
+	rpm_data[1].id = haltid + 1;
+	rpm_data[1].value = hvector.haltmask;
 
-		MSM_FAB_DBG("unalt: ctx: %d, id: %d, value: %d\n",
-				MSM_RPM_CTX_SET_SLEEP,
-				rpm_data[0].id, rpm_data[0].value);
-		MSM_FAB_DBG("unhalt: ctx: %d, id: %d, value: %d\n",
-				MSM_RPM_CTX_SET_SLEEP,
-				rpm_data[1].id, rpm_data[1].value);
+	MSM_FAB_DBG("unalt: ctx: %d, id: %d, value: %d\n",
+		MSM_RPM_CTX_SET_SLEEP, rpm_data[0].id, rpm_data[0].value);
+	MSM_FAB_DBG("unhalt: ctx: %d, id: %d, value: %d\n",
+		MSM_RPM_CTX_SET_SLEEP, rpm_data[1].id, rpm_data[1].value);
 
-		if (fabric->pdata->rpm_enabled)
-			status = msm_rpm_set(MSM_RPM_CTX_SET_0, rpm_data, 2);
-		if (status)
-			MSM_BUS_ERR("msm_rpm_set returned: %d\n", status);
-	}
+	if (fabric->pdata->rpm_enabled)
+		status = msm_rpm_set(MSM_RPM_CTX_SET_0, rpm_data, 2);
+	if (status)
+		MSM_BUS_ERR("msm_rpm_set returned: %d\n", status);
 
 	return status;
 }
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_rpm.c b/arch/arm/mach-msm/msm_bus/msm_bus_rpm.c
index bfefe9e..b9b8192 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_rpm.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_rpm.c
@@ -187,10 +187,20 @@
 	int index, i, j;
 	struct commit_data *sel_cd = (struct commit_data *)sel_cdata;
 
+	add_bw /= info->node_info->num_mports;
 	for (i = 0; i < hop->node_info->num_tiers; i++) {
 		for (j = 0; j < info->node_info->num_mports; j++) {
 
 			uint16_t hop_tier;
+			/*
+			 * For interleaved gateway ports and slave ports,
+			 * there is one-one mapping between gateway port and
+			 * the slave port
+			 */
+			if (info->node_info->gateway && i != j &&
+				(hop->node_info->num_sports > 1))
+				continue;
+
 			if (!hop->node_info->tier)
 				hop_tier = MSM_BUS_BW_TIER2 - 1;
 			else
@@ -213,7 +223,18 @@
 					tier = master_tiers[0];
 				else
 					tier = MSM_BUS_BW_TIER2;
-				tieredbw += add_bw/info->node_info->num_mports;
+
+				/*
+				 * Make sure gateway to slave port bandwidth
+				 * is not divided when slave is interleaved
+				 */
+				if (info->node_info->gateway
+					&& hop->node_info->num_sports > 1)
+					tieredbw += add_bw;
+				else
+					tieredbw += add_bw/
+						hop->node_info->num_sports;
+
 				/* If bw is 0, update tier to default */
 				if (!tieredbw)
 					tier = MSM_BUS_BW_TIER2;
@@ -269,7 +290,7 @@
 	 * Since bwsum is uint16, the values need to be adjusted to
 	 * be copied to value field of rpm-data, which is 32 bits.
 	 */
-	for (i = 0; i < fab_pdata->nslaves; i += 2) {
+	for (i = 0; i < (fab_pdata->nslaves - 1); i += 2) {
 		rpm_data[index].id = offset + index;
 		rpm_data[index].value = RPM_SHIFT(*(cd->bwsum + i + 1)) |
 			*(cd->bwsum + i);