Message ID | 20231114-msm8909-cpufreq-v3-0-926097a6e5c1@kernkonzept.com |
---|---|
Headers | show |
Series | cpufreq: qcom-nvmem: Fix power domain scaling | expand |
On Tue, 14 Nov 2023 at 11:08, Stephan Gerhold <stephan.gerhold@kernkonzept.com> wrote: > > From the Linux point of view, the power domains used by the CPU must > stay always-on. This is because we still need the CPU to keep running > until the last instruction, which will typically be a firmware call that > shuts down the CPU cleanly. > > At the moment the power domain votes (enable + performance state) are > dropped during system suspend, which means the CPU could potentially > malfunction while entering suspend. > > We need to distinguish between two different setups used with > qcom-cpufreq-nvmem: > > 1. CPR power domain: The backing regulator used by CPR should stay > always-on in Linux; it is typically disabled automatically by > hardware when the CPU enters a deep idle state. However, we > should pause the CPR state machine during system suspend. > > 2. RPMPD: The power domains used by the CPU should stay always-on > in Linux (also across system suspend). The CPU typically only > uses the *_AO ("active-only") variants of the power domains in > RPMPD. For those, the RPM firmware will automatically drop > the votes internally when the CPU enters a deep idle state. > > Make this work correctly by calling device_set_awake_path() on the > virtual genpd devices, so that the votes are maintained across system > suspend. The power domain drivers need to set GENPD_FLAG_ACTIVE_WAKEUP > to opt into staying on during system suspend. > > For now we only set this for the RPMPD case. For CPR, not setting it > will ensure the state machine is still paused during system suspend, > while the backing regulator will stay on with "regulator-always-on". > > Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Kind regards Uffe > --- > This patch can be merged independently from the pmdomain one for RPMPD. > Both are needed to actually preserve the votes during system suspend but > there is no compile-time dependency. > --- > drivers/cpufreq/qcom-cpufreq-nvmem.c | 27 +++++++++++++++++++++++++++ > 1 file changed, 27 insertions(+) > > diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c > index d239a45ed497..ea05d9d67490 100644 > --- a/drivers/cpufreq/qcom-cpufreq-nvmem.c > +++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c > @@ -23,6 +23,7 @@ > #include <linux/nvmem-consumer.h> > #include <linux/of.h> > #include <linux/platform_device.h> > +#include <linux/pm.h> > #include <linux/pm_domain.h> > #include <linux/pm_opp.h> > #include <linux/pm_runtime.h> > @@ -426,6 +427,18 @@ static const struct qcom_cpufreq_match_data match_data_ipq8074 = { > .get_version = qcom_cpufreq_ipq8074_name_version, > }; > > +static void qcom_cpufreq_suspend_virt_devs(struct qcom_cpufreq_drv *drv, unsigned int cpu) > +{ > + const char * const *name = drv->data->genpd_names; > + int i; > + > + if (!drv->cpus[cpu].virt_devs) > + return; > + > + for (i = 0; *name; i++, name++) > + device_set_awake_path(drv->cpus[cpu].virt_devs[i]); > +} > + > static void qcom_cpufreq_put_virt_devs(struct qcom_cpufreq_drv *drv, unsigned int cpu) > { > const char * const *name = drv->data->genpd_names; > @@ -578,11 +591,25 @@ static void qcom_cpufreq_remove(struct platform_device *pdev) > } > } > > +static int qcom_cpufreq_suspend(struct device *dev) > +{ > + struct qcom_cpufreq_drv *drv = dev_get_drvdata(dev); > + unsigned int cpu; > + > + for_each_possible_cpu(cpu) > + qcom_cpufreq_suspend_virt_devs(drv, cpu); > + > + return 0; > +} > + > +static DEFINE_SIMPLE_DEV_PM_OPS(qcom_cpufreq_pm_ops, qcom_cpufreq_suspend, NULL); > + > static struct platform_driver qcom_cpufreq_driver = { > .probe = qcom_cpufreq_probe, > .remove_new = qcom_cpufreq_remove, > .driver = { > .name = "qcom-cpufreq-nvmem", > + .pm = pm_sleep_ptr(&qcom_cpufreq_pm_ops), > }, > }; > > > -- > 2.39.2 >
On Thu, 23 Nov 2023 at 08:39, Viresh Kumar <viresh.kumar@linaro.org> wrote: > > On 14-11-23, 11:07, Stephan Gerhold wrote: > > The power domain scaling setup for QCS404 and MSM8909 in > > cpufreq-com-nvmem does not work correctly at the moment because the > > genpd core ignores all the performance state votes that are specified in > > the CPU OPP table. This happens because nothing in the driver makes the > > genpd core aware that the power domains are actively being consumed by > > the CPU. > > > > Fix this by marking the devices as runtime active. Also mark the devices > > to be in the "awake path" during system suspend so that performance > > state votes necessary for the CPU are preserved during system suspend. > > > > While all the patches in this series are needed for full functionality, > > the cpufreq and pmdomain patches can be merged independently. There is > > no compile-time dependency between those two. > > > > Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com> > > --- > > Changes in v3: > > - Drop patches with MSM8909 definitions that were applied already > > - Add extra patch to fix system suspend properly by using > > device_set_awake_path() instead of dev_pm_syscore_device() > > - Set GENPD_FLAG_ACTIVE_WAKEUP for rpmpd so that performance state votes > > needed by the CPU are preserved during suspend > > - Link to v2: https://lore.kernel.org/r/20231018-msm8909-cpufreq-v2-0-0962df95f654@kernkonzept.com > > Applied. Thanks. > > I picked the pmdomain patch too, lemme know if that needs to go via > some other tree. Usually I should pick the pmdomain patches. Although, I thought it may be better to keep this series together. Assuming you are going to send these as fixes for 6.7-rc[n]? In that case, I can just rebase my tree on a later rc if I find any problems. Kind regards Uffe
The power domain scaling setup for QCS404 and MSM8909 in cpufreq-com-nvmem does not work correctly at the moment because the genpd core ignores all the performance state votes that are specified in the CPU OPP table. This happens because nothing in the driver makes the genpd core aware that the power domains are actively being consumed by the CPU. Fix this by marking the devices as runtime active. Also mark the devices to be in the "awake path" during system suspend so that performance state votes necessary for the CPU are preserved during system suspend. While all the patches in this series are needed for full functionality, the cpufreq and pmdomain patches can be merged independently. There is no compile-time dependency between those two. Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com> --- Changes in v3: - Drop patches with MSM8909 definitions that were applied already - Add extra patch to fix system suspend properly by using device_set_awake_path() instead of dev_pm_syscore_device() - Set GENPD_FLAG_ACTIVE_WAKEUP for rpmpd so that performance state votes needed by the CPU are preserved during suspend - Link to v2: https://lore.kernel.org/r/20231018-msm8909-cpufreq-v2-0-0962df95f654@kernkonzept.com Changes in v2: - Reword commit messages based on discussion with Uffe - Use generic power domain name "perf" (Uffe) - Fix pm_runtime error handling (Uffe) - Add allocation cleanup patch as preparation - Fix ordering of qcom,msm8909 compatible (Konrad) - cpufreq-dt-platdev blocklist/dt-bindings patches were applied already - Link to v1: https://lore.kernel.org/r/20230912-msm8909-cpufreq-v1-0-767ce66b544b@kernkonzept.com --- Stephan Gerhold (3): cpufreq: qcom-nvmem: Enable virtual power domain devices cpufreq: qcom-nvmem: Preserve PM domain votes in system suspend pmdomain: qcom: rpmpd: Set GENPD_FLAG_ACTIVE_WAKEUP drivers/cpufreq/qcom-cpufreq-nvmem.c | 73 ++++++++++++++++++++++++++++++++++-- drivers/pmdomain/qcom/rpmpd.c | 1 + 2 files changed, 71 insertions(+), 3 deletions(-) --- base-commit: b85ea95d086471afb4ad062012a4d73cd328fa86 change-id: 20230906-msm8909-cpufreq-dff238de9ff3 Best regards,