Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

interconnect: qcom: icc-rpm: Add AB/IB calculations coefficients

Presumably due to the hardware being so complex, some nodes (or busses)
have different (usually higher) requirements for bandwidth than what
the usual calculations would suggest.

Looking at the available downstream files, it seems like AB values are
adjusted per-bus and IB values are adjusted per-node.
With that in mind, introduce percentage-based coefficient struct members
and use them in the calculations.

One thing to note is that the IB coefficient is inverse (100/ib_percent)
which feels a bit backwards, but it's necessary for precision..

Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Link: https://lore.kernel.org/r/20230726-topic-icc_coeff-v4-1-c04b60caa467@linaro.org
Signed-off-by: Georgi Djakov <djakov@kernel.org>

authored by

Konrad Dybcio and committed by
Georgi Djakov
dd014803 0bb80ecc

+21 -3
+15 -3
drivers/interconnect/qcom/icc-rpm.c
··· 298 298 */ 299 299 static void qcom_icc_bus_aggregate(struct icc_provider *provider, u64 *agg_clk_rate) 300 300 { 301 - u64 agg_avg_rate, agg_rate; 301 + struct qcom_icc_provider *qp = to_qcom_provider(provider); 302 + u64 agg_avg_rate, agg_peak_rate, agg_rate; 302 303 struct qcom_icc_node *qn; 303 304 struct icc_node *node; 304 305 int i; ··· 316 315 else 317 316 agg_avg_rate = qn->sum_avg[i]; 318 317 319 - agg_rate = max_t(u64, agg_avg_rate, qn->max_peak[i]); 320 - do_div(agg_rate, qn->buswidth); 318 + if (qp->ab_coeff) { 319 + agg_avg_rate = agg_avg_rate * qp->ab_coeff; 320 + agg_avg_rate = div_u64(agg_avg_rate, 100); 321 + } 322 + 323 + if (qp->ib_coeff) { 324 + agg_peak_rate = qn->max_peak[i] * 100; 325 + agg_peak_rate = div_u64(qn->max_peak[i], qp->ib_coeff); 326 + } else { 327 + agg_peak_rate = qn->max_peak[i]; 328 + } 329 + 330 + agg_rate = max_t(u64, agg_avg_rate, agg_peak_rate); 321 331 322 332 agg_clk_rate[i] = max_t(u64, agg_clk_rate[i], agg_rate); 323 333 }
+6
drivers/interconnect/qcom/icc-rpm.h
··· 44 44 * @type: the ICC provider type 45 45 * @regmap: regmap for QoS registers read/write access 46 46 * @qos_offset: offset to QoS registers 47 + * @ab_coeff: a percentage-based coefficient for compensating the AB calculations 48 + * @ib_coeff: an inverse-percentage-based coefficient for compensating the IB calculations 47 49 * @bus_clk_rate: bus clock rate in Hz 48 50 * @bus_clk_desc: a pointer to a rpm_clk_resource description of bus clocks 49 51 * @bus_clk: a pointer to a HLOS-owned bus clock ··· 59 57 enum qcom_icc_type type; 60 58 struct regmap *regmap; 61 59 unsigned int qos_offset; 60 + u16 ab_coeff; 61 + u16 ib_coeff; 62 62 u32 bus_clk_rate[QCOM_SMD_RPM_STATE_NUM]; 63 63 const struct rpm_clk_resource *bus_clk_desc; 64 64 struct clk *bus_clk; ··· 127 123 enum qcom_icc_type type; 128 124 const struct regmap_config *regmap_cfg; 129 125 unsigned int qos_offset; 126 + u16 ab_coeff; 127 + u16 ib_coeff; 130 128 }; 131 129 132 130 /* Valid for all bus types */