From: Bjorn Andersson <bjorn.andersson@linaro.org>
To: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>,
Nitin Rawat <quic_nitirawa@quicinc.com>,
Asutosh Das <quic_asutoshd@quicinc.com>
Cc: Andy Gross <agross@kernel.org>,
Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@kernel.org>, Rob Herring <robh+dt@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Alim Akhtar <alim.akhtar@samsung.com>,
Avri Altman <avri.altman@wdc.com>,
"James E.J. Bottomley" <jejb@linux.ibm.com>,
"Martin K. Petersen" <martin.petersen@oracle.com>,
Bean Huo <beanhuo@micron.com>,
Bart Van Assche <bvanassche@acm.org>,
Srinivas Kandagatla <srinivas.kandagatla@linaro.org>,
Taniya Das <tdas@codeaurora.org>,
linux-arm-msm@vger.kernel.org, linux-clk@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-scsi@vger.kernel.org
Subject: Re: [RFC PATCH 4/4] ufs: set power domain performance state when scaling gears
Date: Fri, 1 Apr 2022 12:47:09 -0700 [thread overview]
Message-ID: <YkdWvVVp4RloGjkC@ripper> (raw)
In-Reply-To: <20220401145820.1003826-5-krzysztof.kozlowski@linaro.org>
On Fri 01 Apr 07:58 PDT 2022, Krzysztof Kozlowski wrote:
> Scaling gears requires not only scaling clocks, but also voltage levels,
> e.g. via performance states.
>
> USe the provided OPP table, to set proper OPP frequency which through
> required-opps will trigger performance state change.
>
This looks quite nice! Just two questions about the path looking forward.
If we where to extend the opp core to allow specifying the clock rate
for some N first clocks (similar to how e.g. regulators are handled) it
seems possible to extend this to replace the freq-table property as
well. Would you agree?
The other missing required feature (in this area) from the upstream UFS
driver is the ability of voting for interconnect bandwidth. Based on
your path it would be trivial to specify different values for the votes
for each speed, but looking at downstream [1] (each row represents the
vote for the two paths in KB/s) indicates a more complex relationship
between gear and voted bandwidth.
This was the reason I suggested that perhaps we need to key the
opp-table based on the gear? But I don't think there would be any issue
detecting this in runtime...
[1] https://github.com/MiCode/kernel_devicetree/blob/zeus-s-oss/qcom/waipio.dtsi#L1982
Regards,
Bjorn
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> ---
> drivers/scsi/ufs/ufshcd-pltfrm.c | 6 +++++
> drivers/scsi/ufs/ufshcd.c | 42 +++++++++++++++++++++++++-------
> drivers/scsi/ufs/ufshcd.h | 3 +++
> 3 files changed, 42 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
> index cca4b2181a81..c8f19b54be92 100644
> --- a/drivers/scsi/ufs/ufshcd-pltfrm.c
> +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
> @@ -360,6 +360,12 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
> goto dealloc_host;
> }
>
> + if (devm_pm_opp_of_add_table(dev))
> + dev_dbg(dev, "no OPP table (%d), no performance state control\n",
> + err);
> + else
> + hba->use_pm_opp = true;
> +
> ufshcd_init_lanes_per_dir(hba);
>
> err = ufshcd_init(hba, mmio_base, irq);
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index 3f9caafa91bf..84912db86da8 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -1164,11 +1164,16 @@ static int ufshcd_wait_for_doorbell_clr(struct ufs_hba *hba,
> static int ufshcd_scale_gear(struct ufs_hba *hba, bool scale_up)
> {
> int ret = 0;
> + struct ufs_clk_info *clki;
> + unsigned long pm_opp_target_rate;
> struct ufs_pa_layer_attr new_pwr_info;
>
> + clki = list_first_entry(&hba->clk_list_head, struct ufs_clk_info, list);
> +
> if (scale_up) {
> memcpy(&new_pwr_info, &hba->clk_scaling.saved_pwr_info.info,
> sizeof(struct ufs_pa_layer_attr));
> + pm_opp_target_rate = clki->max_freq;
> } else {
> memcpy(&new_pwr_info, &hba->pwr_info,
> sizeof(struct ufs_pa_layer_attr));
> @@ -1184,6 +1189,13 @@ static int ufshcd_scale_gear(struct ufs_hba *hba, bool scale_up)
> new_pwr_info.gear_tx = hba->clk_scaling.min_gear;
> new_pwr_info.gear_rx = hba->clk_scaling.min_gear;
> }
> + pm_opp_target_rate = clki->min_freq;
> + }
> +
> + if (hba->use_pm_opp && scale_up) {
> + ret = dev_pm_opp_set_rate(hba->dev, pm_opp_target_rate);
> + if (ret)
> + return ret;
> }
>
> /* check if the power mode needs to be changed or not? */
> @@ -1194,6 +1206,11 @@ static int ufshcd_scale_gear(struct ufs_hba *hba, bool scale_up)
> hba->pwr_info.gear_tx, hba->pwr_info.gear_rx,
> new_pwr_info.gear_tx, new_pwr_info.gear_rx);
>
> + if (ret && hba->use_pm_opp && scale_up)
> + dev_pm_opp_set_rate(hba->dev, hba->devfreq->previous_freq);
> + else if (hba->use_pm_opp && !scale_up)
> + ret = dev_pm_opp_set_rate(hba->dev, pm_opp_target_rate);
> +
> return ret;
> }
>
> @@ -1435,9 +1452,11 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba)
> if (list_empty(clk_list))
> return 0;
>
> - clki = list_first_entry(clk_list, struct ufs_clk_info, list);
> - dev_pm_opp_add(hba->dev, clki->min_freq, 0);
> - dev_pm_opp_add(hba->dev, clki->max_freq, 0);
> + if (!hba->use_pm_opp) {
> + clki = list_first_entry(clk_list, struct ufs_clk_info, list);
> + dev_pm_opp_add(hba->dev, clki->min_freq, 0);
> + dev_pm_opp_add(hba->dev, clki->max_freq, 0);
> + }
>
> ufshcd_vops_config_scaling_param(hba, &hba->vps->devfreq_profile,
> &hba->vps->ondemand_data);
> @@ -1449,8 +1468,10 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba)
> ret = PTR_ERR(devfreq);
> dev_err(hba->dev, "Unable to register with devfreq %d\n", ret);
>
> - dev_pm_opp_remove(hba->dev, clki->min_freq);
> - dev_pm_opp_remove(hba->dev, clki->max_freq);
> + if (!hba->use_pm_opp) {
> + dev_pm_opp_remove(hba->dev, clki->min_freq);
> + dev_pm_opp_remove(hba->dev, clki->max_freq);
> + }
> return ret;
> }
>
> @@ -1462,7 +1483,6 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba)
> static void ufshcd_devfreq_remove(struct ufs_hba *hba)
> {
> struct list_head *clk_list = &hba->clk_list_head;
> - struct ufs_clk_info *clki;
>
> if (!hba->devfreq)
> return;
> @@ -1470,9 +1490,13 @@ static void ufshcd_devfreq_remove(struct ufs_hba *hba)
> devfreq_remove_device(hba->devfreq);
> hba->devfreq = NULL;
>
> - clki = list_first_entry(clk_list, struct ufs_clk_info, list);
> - dev_pm_opp_remove(hba->dev, clki->min_freq);
> - dev_pm_opp_remove(hba->dev, clki->max_freq);
> + if (!hba->use_pm_opp) {
> + struct ufs_clk_info *clki;
> +
> + clki = list_first_entry(clk_list, struct ufs_clk_info, list);
> + dev_pm_opp_remove(hba->dev, clki->min_freq);
> + dev_pm_opp_remove(hba->dev, clki->max_freq);
> + }
> }
>
> static void __ufshcd_suspend_clkscaling(struct ufs_hba *hba)
> diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
> index 88c20f3608c2..3bd02095897f 100644
> --- a/drivers/scsi/ufs/ufshcd.h
> +++ b/drivers/scsi/ufs/ufshcd.h
> @@ -776,6 +776,8 @@ struct ufs_hba_monitor {
> * @auto_bkops_enabled: to track whether bkops is enabled in device
> * @vreg_info: UFS device voltage regulator information
> * @clk_list_head: UFS host controller clocks list node head
> + * @use_pm_opp: whether OPP table is provided and scaling gears should trigger
> + * setting OPP
> * @pwr_info: holds current power mode
> * @max_pwr_info: keeps the device max valid pwm
> * @clk_scaling_lock: used to serialize device commands and clock scaling
> @@ -894,6 +896,7 @@ struct ufs_hba {
> bool auto_bkops_enabled;
> struct ufs_vreg_info vreg_info;
> struct list_head clk_list_head;
> + bool use_pm_opp;
>
> /* Number of requests aborts */
> int req_abort_count;
> --
> 2.32.0
>
next prev parent reply other threads:[~2022-04-01 19:44 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-01 14:58 [RFC PATCH 0/4] ufs: set power domain performance state when scaling gears Krzysztof Kozlowski
2022-04-01 14:58 ` [RFC PATCH 1/4] dt-bindings: clock: qcom,gcc-sdm845: add parent power domain Krzysztof Kozlowski
[not found] ` <20220401232451.1B7A9C340F3@smtp.kernel.org>
2022-04-02 9:09 ` Krzysztof Kozlowski
2022-04-01 14:58 ` [RFC PATCH 2/4] dt-bindings: ufs: common: allow OPP table Krzysztof Kozlowski
2022-04-04 21:39 ` Rob Herring
2022-04-01 14:58 ` [RFC PATCH 3/4] arm64: dts: qcom: sdm845: control RPMHPD performance states with UFS Krzysztof Kozlowski
2022-04-04 0:02 ` Dmitry Baryshkov
2022-04-05 17:13 ` Bjorn Andersson
2022-04-01 14:58 ` [RFC PATCH 4/4] ufs: set power domain performance state when scaling gears Krzysztof Kozlowski
2022-04-01 19:47 ` Bjorn Andersson [this message]
2022-04-03 17:46 ` Krzysztof Kozlowski
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=YkdWvVVp4RloGjkC@ripper \
--to=bjorn.andersson@linaro.org \
--cc=agross@kernel.org \
--cc=alim.akhtar@samsung.com \
--cc=avri.altman@wdc.com \
--cc=beanhuo@micron.com \
--cc=bvanassche@acm.org \
--cc=devicetree@vger.kernel.org \
--cc=jejb@linux.ibm.com \
--cc=krzk+dt@kernel.org \
--cc=krzysztof.kozlowski@linaro.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=mturquette@baylibre.com \
--cc=quic_asutoshd@quicinc.com \
--cc=quic_nitirawa@quicinc.com \
--cc=robh+dt@kernel.org \
--cc=sboyd@kernel.org \
--cc=srinivas.kandagatla@linaro.org \
--cc=tdas@codeaurora.org \
/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).