From: Konrad Dybcio <konrad.dybcio@linaro.org>
To: Stephan Gerhold <stephan@gerhold.net>
Cc: Andy Gross <agross@kernel.org>,
Bjorn Andersson <andersson@kernel.org>,
Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@kernel.org>,
Georgi Djakov <djakov@kernel.org>, Leo Yan <leo.yan@linaro.org>,
Evan Green <evgreen@chromium.org>,
Rob Herring <robh+dt@kernel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
Conor Dooley <conor+dt@kernel.org>,
Marijn Suijten <marijn.suijten@somainline.org>,
linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-clk@vger.kernel.org, linux-pm@vger.kernel.org,
devicetree@vger.kernel.org
Subject: Re: [PATCH v4 17/22] interconnect: qcom: icc-rpm: Control bus rpmcc from icc
Date: Wed, 14 Jun 2023 00:40:11 +0200 [thread overview]
Message-ID: <4417edef-5d4d-e802-69fb-feeeb2304e44@linaro.org> (raw)
In-Reply-To: <ZIjTPyOfuVM7S1O1@gerhold.net>
On 13.06.2023 22:36, Stephan Gerhold wrote:
> On Tue, Jun 13, 2023 at 04:03:17PM +0200, Konrad Dybcio wrote:
>> The sole purpose of bus clocks that were previously registered with
>> rpmcc was to convey the aggregated bandwidth to RPM. There's no good
>> reason to keep them outside the interconnect framework, as it only
>> adds to the plentiful complexity.
>>
>> Add the required code to handle these clocks from within SMD RPM ICC.
>>
>> RPM-owned bus clocks are no longer considered a thing, but sadly we
>> have to allow for the existence of HLOS-owned bus clocks, as some
>> (mostly older) SoCs (ab)use these for bus scaling (e.g. MSM8998 and
>> &mmcc AHB_CLK_SRC).
>>
>> This in turn is trivially solved with a single *clk, which is filled
>> and used iff qp.bus_clk_desc is absent and we have a "bus" clock-names
>> entry in the DT node.
>>
>> This change should(tm) be fully compatible with all sorts of old
>> Device Trees as far as the interconnect functionality goes (modulo
>> abusing bus clock handles or wrongly using the qcom,icc.h binding,
>> but that's a mistake in and of itself).
>>
>> Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
>> ---
>> drivers/interconnect/qcom/icc-rpm.c | 119 ++++++++++++++++++++----------------
>> drivers/interconnect/qcom/icc-rpm.h | 13 ++--
>> drivers/interconnect/qcom/msm8996.c | 1 -
>> drivers/interconnect/qcom/sdm660.c | 1 -
>> 4 files changed, 71 insertions(+), 63 deletions(-)
>>
>> diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c
>> index b8ecf9538ab9..f9d0ecba5631 100644
>> --- a/drivers/interconnect/qcom/icc-rpm.c
>> +++ b/drivers/interconnect/qcom/icc-rpm.c
>> @@ -49,7 +49,7 @@
>> #define NOC_QOS_MODE_FIXED_VAL 0x0
>> #define NOC_QOS_MODE_BYPASS_VAL 0x2
>>
>> -#define ICC_BUS_CLK_MIN_RATE 19200000ULL
>> +#define ICC_BUS_CLK_MIN_RATE 19200ULL /* kHz */
>>
>> static int qcom_icc_set_qnoc_qos(struct icc_node *src)
>> {
>> @@ -338,11 +338,10 @@ static int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
>> struct qcom_icc_node *src_qn = NULL, *dst_qn = NULL;
>> struct icc_provider *provider;
>> u64 sum_bw;
>> - u64 rate;
>> + u64 active_rate, sleep_rate;
>> u64 agg_avg[QCOM_ICC_NUM_BUCKETS], agg_peak[QCOM_ICC_NUM_BUCKETS];
>> u64 max_agg_avg;
>> - int ret, i;
>> - int bucket;
>> + int ret;
>>
>> src_qn = src->data;
>> if (dst)
>> @@ -364,49 +363,59 @@ static int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
>> return ret;
>> }
>>
>> - for (i = 0; i < qp->num_bus_clks; i++) {
>> - /*
>> - * Use WAKE bucket for active clock, otherwise, use SLEEP bucket
>> - * for other clocks. If a platform doesn't set interconnect
>> - * path tags, by default use sleep bucket for all clocks.
>> - *
>> - * Note, AMC bucket is not supported yet.
>> - */
>> - if (!strcmp(qp->bus_clks[i].id, "bus_a"))
>> - bucket = QCOM_ICC_BUCKET_WAKE;
>> - else
>> - bucket = QCOM_ICC_BUCKET_SLEEP;
>> -
>> - rate = icc_units_to_bps(max(agg_avg[bucket], agg_peak[bucket]));
>> - do_div(rate, src_qn->buswidth);
>> - rate = min_t(u64, rate, LONG_MAX);
>> -
>> - /*
>> - * Downstream checks whether the requested rate is zero, but it makes little sense
>> - * to vote for a value that's below the lower threshold, so let's not do so.
>> - */
>> - if (bucket == QCOM_ICC_BUCKET_WAKE && qp->keep_alive)
>> - rate = max(ICC_BUS_CLK_MIN_RATE, rate);
>> -
>> - 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);
>> + /* Some providers don't have a bus clock to scale */
>> + if (!qp->bus_clk_desc && !qp->bus_clk)
>> + return 0;
>> +
>> + /* Intentionally keep the rates in kHz as that's what RPM accepts */
>> + active_rate = max(agg_avg[QCOM_SMD_RPM_ACTIVE_STATE],
>> + agg_peak[QCOM_SMD_RPM_ACTIVE_STATE]);
>> + do_div(active_rate, src_qn->buswidth);
>> +
>> + sleep_rate = max(agg_avg[QCOM_SMD_RPM_SLEEP_STATE],
>> + agg_peak[QCOM_SMD_RPM_SLEEP_STATE]);
>> + do_div(sleep_rate, src_qn->buswidth);
>> +
>> + /*
>> + * Downstream checks whether the requested rate is zero, but it makes little sense
>> + * to vote for a value that's below the lower threshold, so let's not do so.
>> + */
>> + if (qp->keep_alive)
>> + active_rate = max(ICC_BUS_CLK_MIN_RATE, active_rate);
>> +
>> + /* Some providers have a non-RPM-owned bus clock - convert kHz->Hz for the CCF */
>> + if (qp->bus_clk) {
>> + active_rate = max_t(u64, active_rate, sleep_rate);
>> + /* ARM32 caps clk_set_rate arg to u32.. Nothing we can do about that! */
>> + active_rate = min_t(u64, 1000ULL * active_rate, ULONG_MAX);
>> + return clk_set_rate(qp->bus_clk, active_rate);
>> + }
>> +
>> + /* RPM only accepts <=INT_MAX rates */
>> + active_rate = min_t(u32, active_rate, INT_MAX);
>> + sleep_rate = min_t(u32, sleep_rate, INT_MAX);
>
> Realized this by coincidence while playing with the code changes for the
> comment below: This doesn't work as intended similar to the ARM32 cap
> above but it's broken even on ARM64:
>
> Take this example:
>
> u64 active_rate = 4294967296ULL;
> active_rate = min_t(u32, active_rate, INT_MAX);
>
> This should result into active_rate = INT_MAX.
> But it actually results in rate = 0.
>
> Why?
>
> min_t(u32, rate, INT_MAX)
> = min((u32)rate, (u32)INT_MAX)
> = min((u32)4294967296ULL, (u32)INT_MAX)
> = min(0, INT_MAX)
> = 0
>
> This needs to be min_t(u64 to work properly :)
Yikes, right!
>
>> +
>> + if (active_rate != qp->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE]) {
>> + ret = qcom_icc_rpm_set_bus_rate(qp->bus_clk_desc, active_rate, true);
>> + if (ret)
>> return ret;
>> - }
>> - qp->bus_clk_rate[i] = rate;
>> +
>> + /* Cache the rate after we've successfully commited it to RPM */
>> + qp->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE] = active_rate;
>> + }
>> +
>> + if (sleep_rate != qp->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE]) {
>> + ret = qcom_icc_rpm_set_bus_rate(qp->bus_clk_desc, sleep_rate, false);
>> + if (ret)
>> + return ret;
>> +
>> + /* Cache the rate after we've successfully commited it to RPM */
>> + qp->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE] = sleep_rate;
>> }
>
> With my suggestion on the other patch to pass in the ctx/state number
> directly into qcom_icc_rpm_set_bus_rate() I wonder if it would be nicer
> to write as loop similar to the all others.
>
> It's a bit shorter, although the line wrapping for the keep_alive is
> also more ugly. I leave it up to you :)
>
> Not even compile tested this time!
I think it's more obvious when it's explicit for just two contexts.
Konrad
>
> Thanks,
> Stephan
>
> /*
> * Downstream checks whether the requested rate is zero, but it makes little sense
> * to vote for a value that's below the lower threshold, so let's not do so.
> */
> if (qp->keep_alive)
> agg_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE]
> = max(ICC_BUS_CLK_MIN_RATE, agg_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE]);
>
> /* Some providers have a non-RPM-owned bus clock - convert kHz->Hz for the CCF */
> if (qp->bus_clk) {
> rate = max_t(u64, agg_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE],
> agg_clk_rate[QCOM_SMD_RPM_SLEEP_STATE]);
> /* ARM32 caps clk_set_rate arg to u32.. Nothing we can do about that! */
> reate = min_t(u64, 1000ULL * rate, ULONG_MAX);
> return clk_set_rate(qp->bus_clk, rate);
> }
>
> for (i = 0; i < QCOM_SMD_RPM_STATE_NUM; i++) {
> /* RPM only accepts <=INT_MAX rates */
> rate = min_t(u64, active_rate, INT_MAX);
> if (rate == qp->bus_clk_rate[i])
> continue;
>
> ret = qcom_icc_rpm_set_bus_rate(qp->bus_clk_desc, rate, i);
> if (ret)
> return ret;
>
> /* Cache the rate after we've successfully commited it to RPM */
> qp->bus_clk_rate[i] = rate;
> }
next prev parent reply other threads:[~2023-06-13 22:40 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-13 14:03 [PATCH v4 00/22] Restructure RPM SMD ICC Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 01/22] dt-bindings: interconnect: Add Qcom RPM ICC bindings Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 02/22] soc: qcom: smd-rpm: Add QCOM_SMD_RPM_STATE_NUM Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 03/22] soc: qcom: smd-rpm: Use tabs for defines Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 04/22] clk: qcom: smd-rpm: Move some RPM resources to the common header Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 05/22] soc: qcom: smd-rpm: Move icc_smd_rpm registration to clk-smd-rpm Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 06/22] interconnect: qcom: icc-rpm: Introduce keep_alive Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 07/22] interconnect: qcom: Fold smd-rpm.h into icc-rpm.h Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 08/22] interconnect: qcom: smd-rpm: Add rpmcc handling skeleton code Konrad Dybcio
2023-06-13 20:10 ` Stephan Gerhold
2023-06-13 22:41 ` Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 09/22] interconnect: qcom: Add missing headers in icc-rpm.h Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 10/22] interconnect: qcom: Define RPM bus clocks Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 11/22] interconnect: qcom: sdm660: Hook up RPM bus clk definitions Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 12/22] interconnect: qcom: msm8996: " Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 13/22] interconnect: qcom: qcs404: " Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 14/22] interconnect: qcom: msm8939: " Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 15/22] interconnect: qcom: msm8916: " Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 16/22] interconnect: qcom: qcm2290: " Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 17/22] interconnect: qcom: icc-rpm: Control bus rpmcc from icc Konrad Dybcio
2023-06-13 20:36 ` Stephan Gerhold
2023-06-13 20:39 ` Stephan Gerhold
2023-06-13 22:40 ` Konrad Dybcio [this message]
2023-06-13 14:03 ` [PATCH v4 18/22] clk: qcom: smd-rpm: Separate out interconnect bus clocks Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 19/22] interconnect: qcom: icc-rpm: Fix bucket number Konrad Dybcio
2023-06-13 20:06 ` Stephan Gerhold
2023-06-13 14:03 ` [PATCH v4 20/22] interconnect: qcom: icc-rpm: Set bandwidth on both contexts Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 21/22] interconnect: qcom: icc-rpm: Set correct bandwidth through RPM bw req Konrad Dybcio
2023-06-13 14:03 ` [PATCH v4 22/22] interconnect: qcom: icc-rpm: Fix bandwidth calculations Konrad Dybcio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4417edef-5d4d-e802-69fb-feeeb2304e44@linaro.org \
--to=konrad.dybcio@linaro.org \
--cc=agross@kernel.org \
--cc=andersson@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=djakov@kernel.org \
--cc=evgreen@chromium.org \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=leo.yan@linaro.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=marijn.suijten@somainline.org \
--cc=mturquette@baylibre.com \
--cc=robh+dt@kernel.org \
--cc=sboyd@kernel.org \
--cc=stephan@gerhold.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).