2022-04-16 03:13:41

by Leo Yan

[permalink] [raw]
Subject: [PATCH v1 0/2] interconnect: qcom: icc-rpm: Fix setting clock rate

This patch set is to address two clock rate setting issues.

The first patch is to fix a potential cached clock rate mismatching
issue, the issue can lead to the clock rate is missed to be set. Note,
since this potential issue requires specific time window and certain
condition (consumers need to request the same bandwidth) to produce,
the patch is based on analysis but not a real trace log.

The second patch is an extension to cache clock rates for active and
sleep clocks separately, with this change it gives us possibility to set
active and sleep clock with different clock rates.

Another chagne for enabling active and sleep clocks for icc-rpm driver
will be sent out later, which is dependent on this patch set.


Leo Yan (2):
interconnect: qcom: icc-rpm: Fix for cached clock rate
interconnect: qcom: icc-rpm: Cache every clock rate

drivers/interconnect/qcom/icc-rpm.c | 14 +++++++++-----
drivers/interconnect/qcom/icc-rpm.h | 4 ++--
2 files changed, 11 insertions(+), 7 deletions(-)

--
2.25.1


2022-04-16 03:13:45

by Leo Yan

[permalink] [raw]
Subject: [PATCH v1 2/2] interconnect: qcom: icc-rpm: Cache every clock rate

The cached clock rate is used for all bus clocks, thus it has the
assumption that all interconnect clock rates are always same, this
causes trouble if we want to set different clock rates separately.

This patch is to allocate a clock rate array to cache every clock
rate.

Signed-off-by: Leo Yan <[email protected]>
---
drivers/interconnect/qcom/icc-rpm.c | 14 +++++++++-----
drivers/interconnect/qcom/icc-rpm.h | 2 +-
2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c
index e0309e246523..45d23aaeabf6 100644
--- a/drivers/interconnect/qcom/icc-rpm.c
+++ b/drivers/interconnect/qcom/icc-rpm.c
@@ -274,20 +274,19 @@ static int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
do_div(rate, qn->buswidth);
rate = min_t(u64, rate, LONG_MAX);

- if (qp->bus_clk_rate == rate)
- return 0;
-
for (i = 0; i < qp->num_clks; i++) {
+ if (qp->bus_clk_rate[i] == rate)
+ continue;
+
ret = clk_set_rate(qp->bus_clks[i].clk, rate);
if (ret) {
pr_err("%s clk_set_rate error: %d\n",
qp->bus_clks[i].id, ret);
return ret;
}
+ qp->bus_clk_rate[i] = rate;
}

- qp->bus_clk_rate = rate;
-
return 0;
}

@@ -332,6 +331,11 @@ int qnoc_probe(struct platform_device *pdev)
if (!qp)
return -ENOMEM;

+ qp->bus_clk_rate = devm_kcalloc(dev, cd_num, sizeof(*qp->bus_clk_rate),
+ GFP_KERNEL);
+ if (!qp->bus_clk_rate)
+ return -ENOMEM;
+
data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes),
GFP_KERNEL);
if (!data)
diff --git a/drivers/interconnect/qcom/icc-rpm.h b/drivers/interconnect/qcom/icc-rpm.h
index 4457fcc5b84c..f6c4ac960102 100644
--- a/drivers/interconnect/qcom/icc-rpm.h
+++ b/drivers/interconnect/qcom/icc-rpm.h
@@ -34,7 +34,7 @@ struct qcom_icc_provider {
enum qcom_icc_type type;
struct regmap *regmap;
unsigned int qos_offset;
- u64 bus_clk_rate;
+ u64 *bus_clk_rate;
struct clk_bulk_data bus_clks[];
};

--
2.25.1