From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="gAfvNJSW" Received: from mail-yb1-xb32.google.com (mail-yb1-xb32.google.com [IPv6:2607:f8b0:4864:20::b32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2704A268F for ; Wed, 22 Nov 2023 01:48:38 -0800 (PST) Received: by mail-yb1-xb32.google.com with SMTP id 3f1490d57ef6-da7238b3eb4so6497505276.1 for ; Wed, 22 Nov 2023 01:48:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1700646517; x=1701251317; darn=vger.kernel.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=ygGpIikdffA3zI0CSmuuy6nPAmKVPCLvFv3JJHDPC+E=; b=gAfvNJSWoLkbMqMzI/YXVFmLGb5aBqNH6/wkfVxdHTvi9hcIK/F9rdqB/q6iTEFDVi eqgVotjwqGXVLOBCGGYNb2ICRJXFdAF4wvGY6Du8Tly4z5IGpTdt7BcBdkbwKtewpOfv RQo5nURaG2j7XjpR9prVU13m8dveW+14a63hVBwlmPufLx6SvrpOWogFMox+QpfGCLCN WD4nn9Hxy8IXzW9faZqs5cA03kazH4qsL2m0+FzraG/Lytyr1LLl+PlC6UNEj/nborJ0 S8U3Wgr7AAbFIXr2Ifsqi4zkCS6bdNZC6p8wmg3fwHRpRhXVKYS57I7I/DDqs656Mrdg cN8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700646517; x=1701251317; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=ygGpIikdffA3zI0CSmuuy6nPAmKVPCLvFv3JJHDPC+E=; b=RB46kG8zVQhCeboVmu/ckst2wh4l+9L/fiLcy8/JogXXMee+eIhb/MyQHuhzr45XOX M7fcc840VICYLEoxufPzud2jfV6D2QfoeMrD8q+/eHGA44DZ2r8+tboCPi3QTPniKwPB 1Dpsu7Ywidbd1uAgHwemI+66yYB/tiqXNSPc2pDvx6VydwBsVKkUL3YiwjpAX7FBKEJD vSj8jBwNZq6PTWFYI9tchzfn3OzBFe2byJMVtAZD2ax2IAwXGjZH/OmSPifFDNHw/xtH v+tTLr2HC8cyFE9aj5kKZN15n6YI3HpcbLaVJ39Yd9GTBFi8HF4ufhOyA+aOChwIZHhS DcVg== X-Gm-Message-State: AOJu0Yw65g/JB0rNeN2zxsCULMeDAwaZyhLjlUDKPl7sXoFK7f4+KeeA c01cJn5ehpCbPi2sQucAootG5gTDOXuSKgZlZE6sZg== X-Google-Smtp-Source: AGHT+IHg3xtWznL7RoXEO+Wk8qVQlDpVyn+jAxEz7GbXdU/LSx4+N+Ut3/07i5p33DnA24H7agc2O3KIwSPgMDwgTH4= X-Received: by 2002:a25:374c:0:b0:db0:6cde:3859 with SMTP id e73-20020a25374c000000b00db06cde3859mr1535108yba.41.1700646517145; Wed, 22 Nov 2023 01:48:37 -0800 (PST) Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 References: <20231114-msm8909-cpufreq-v3-0-926097a6e5c1@kernkonzept.com> <20231114-msm8909-cpufreq-v3-2-926097a6e5c1@kernkonzept.com> In-Reply-To: <20231114-msm8909-cpufreq-v3-2-926097a6e5c1@kernkonzept.com> From: Ulf Hansson Date: Wed, 22 Nov 2023 10:48:01 +0100 Message-ID: Subject: Re: [PATCH v3 2/3] cpufreq: qcom-nvmem: Preserve PM domain votes in system suspend To: Stephan Gerhold Cc: Viresh Kumar , Andy Gross , Bjorn Andersson , Konrad Dybcio , Ilia Lin , "Rafael J. Wysocki" , Rob Herring , Krzysztof Kozlowski , Conor Dooley , linux-pm@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Stephan Gerhold Content-Type: text/plain; charset="UTF-8" On Tue, 14 Nov 2023 at 11:08, Stephan Gerhold 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 Reviewed-by: Ulf Hansson 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 > #include > #include > +#include > #include > #include > #include > @@ -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 >