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);