diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c index 2c16917ba1fd..8b02aa8aa96a 100644 --- a/drivers/interconnect/qcom/icc-rpm.c +++ b/drivers/interconnect/qcom/icc-rpm.c @@ -298,7 +298,8 @@ static int qcom_icc_bw_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, */ static void qcom_icc_bus_aggregate(struct icc_provider *provider, u64 *agg_clk_rate) { - u64 agg_avg_rate, agg_rate; + struct qcom_icc_provider *qp = to_qcom_provider(provider); + u64 agg_avg_rate, agg_peak_rate, agg_rate; struct qcom_icc_node *qn; struct icc_node *node; int i; @@ -315,8 +316,19 @@ static void qcom_icc_bus_aggregate(struct icc_provider *provider, u64 *agg_clk_r else agg_avg_rate = qn->sum_avg[i]; - agg_rate = max_t(u64, agg_avg_rate, qn->max_peak[i]); - do_div(agg_rate, qn->buswidth); + if (qp->ab_coeff) { + agg_avg_rate = agg_avg_rate * qp->ab_coeff; + agg_avg_rate = div_u64(agg_avg_rate, 100); + } + + if (qp->ib_coeff) { + agg_peak_rate = qn->max_peak[i] * 100; + agg_peak_rate = div_u64(qn->max_peak[i], qp->ib_coeff); + } else { + agg_peak_rate = qn->max_peak[i]; + } + + agg_rate = max_t(u64, agg_avg_rate, agg_peak_rate); agg_clk_rate[i] = max_t(u64, agg_clk_rate[i], agg_rate); } diff --git a/drivers/interconnect/qcom/icc-rpm.h b/drivers/interconnect/qcom/icc-rpm.h index eed3451af3e6..5e7d6a4fd2f3 100644 --- a/drivers/interconnect/qcom/icc-rpm.h +++ b/drivers/interconnect/qcom/icc-rpm.h @@ -44,6 +44,8 @@ struct rpm_clk_resource { * @type: the ICC provider type * @regmap: regmap for QoS registers read/write access * @qos_offset: offset to QoS registers + * @ab_coeff: a percentage-based coefficient for compensating the AB calculations + * @ib_coeff: an inverse-percentage-based coefficient for compensating the IB calculations * @bus_clk_rate: bus clock rate in Hz * @bus_clk_desc: a pointer to a rpm_clk_resource description of bus clocks * @bus_clk: a pointer to a HLOS-owned bus clock @@ -57,6 +59,8 @@ struct qcom_icc_provider { enum qcom_icc_type type; struct regmap *regmap; unsigned int qos_offset; + u16 ab_coeff; + u16 ib_coeff; u32 bus_clk_rate[QCOM_SMD_RPM_STATE_NUM]; const struct rpm_clk_resource *bus_clk_desc; struct clk *bus_clk; @@ -123,6 +127,8 @@ struct qcom_icc_desc { enum qcom_icc_type type; const struct regmap_config *regmap_cfg; unsigned int qos_offset; + u16 ab_coeff; + u16 ib_coeff; }; /* Valid for all bus types */