public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
From: Stephan Gerhold <stephan@gerhold.net>
To: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Cc: Andy Gross <agross@kernel.org>,
	Bjorn Andersson <andersson@kernel.org>,
	Konrad Dybcio <konrad.dybcio@linaro.org>,
	Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v5 03/10] soc: qcom: spm: add support for voltage regulator
Date: Thu, 7 Dec 2023 18:12:19 +0100	[thread overview]
Message-ID: <ZXH88_nwT_3g6MS9@gerhold.net> (raw)
In-Reply-To: <20231207130703.3322321-4-dmitry.baryshkov@linaro.org>

On Thu, Dec 07, 2023 at 04:06:56PM +0300, Dmitry Baryshkov wrote:
> The SPM / SAW2 device also provides a voltage regulator functionality
> with optional AVS (Adaptive Voltage Scaling) support. The exact register
> sequence and voltage ranges differs from device to device.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

There is some overlap here with the spmi_saw_set_vdd() functionality in
qcom_spmi-regulator.c, at least for the SoCs with SPMI PMICs (e.g.
MSM8974 etc). You don't add support for these in this patch series yet
but I think it would be good to clarify how we would expect to handle
those. In other words:

 - Would we handle them in qcom_spmi-regulator.c and keep the code in
   the spm.c driver only for the non-SPMI platforms?

 - Should we add this in a SSBI regulator driver instead for consistency?

 - Or should we move the existing functionality in qcom_spmi-regulator.c
   to here?

> ---
>  drivers/soc/qcom/spm.c | 221 ++++++++++++++++++++++++++++++++++++++++-
>  include/soc/qcom/spm.h |   9 ++
>  2 files changed, 225 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c
> index 2f0b1bfe7658..595e2afb2141 100644
> --- a/drivers/soc/qcom/spm.c
> +++ b/drivers/soc/qcom/spm.c
> [...]
> @@ -238,6 +273,181 @@ void spm_set_low_power_mode(struct spm_driver_data *drv,
>  	spm_register_write_sync(drv, SPM_REG_SPM_CTL, ctl_val);
>  }
>  
> +static int spm_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector)
> +{
> +	struct spm_driver_data *drv = rdev_get_drvdata(rdev);
> +
> +	drv->volt_sel = selector;
> +
> +	/* Always do the SAW register writes on the corresponding CPU */
> +	return smp_call_function_single(drv->reg_cpu, drv->reg_data->set_vdd, drv, true);
> +}
> +
> +static int spm_get_voltage_sel(struct regulator_dev *rdev)
> +{
> +	struct spm_driver_data *drv = rdev_get_drvdata(rdev);
> +
> +	return drv->volt_sel;
> +}
> +
> +static const struct regulator_ops spm_reg_ops = {
> +	.set_voltage_sel	= spm_set_voltage_sel,
> +	.get_voltage_sel	= spm_get_voltage_sel,
> +	.list_voltage		= regulator_list_voltage_linear_range,
> +	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
> +};
> +
> +static void smp_set_vdd_v1_1(void *data)
> +{
> +	struct spm_driver_data *drv = data;
> +	unsigned int vctl, data0, data1, avs_ctl, sts;
> +	unsigned int vlevel, volt_sel;
> +	bool avs_enabled;
> +
> +	volt_sel = drv->volt_sel;
> +	vlevel = volt_sel | 0x80; /* band */
> +
> +	avs_ctl = spm_register_read(drv, SPM_REG_AVS_CTL);
> +	vctl = spm_register_read(drv, SPM_REG_VCTL);
> +	data0 = spm_register_read(drv, SPM_REG_PMIC_DATA_0);
> +	data1 = spm_register_read(drv, SPM_REG_PMIC_DATA_1);
> +
> +	avs_enabled = avs_ctl & SPM_1_1_AVS_CTL_AVS_ENABLED;
> +
> +	/* If AVS is enabled, switch it off during the voltage change */
> +	if (avs_enabled) {
> +		avs_ctl &= ~SPM_1_1_AVS_CTL_AVS_ENABLED;
> +		spm_register_write(drv, SPM_REG_AVS_CTL, avs_ctl);
> +	}
> +
> +	/* Kick the state machine back to idle */
> +	spm_register_write(drv, SPM_REG_RST, 1);
> +
> +	vctl = FIELD_SET(vctl, SPM_VCTL_VLVL, vlevel);
> +	data0 = FIELD_SET(data0, SPM_PMIC_DATA_0_VLVL, vlevel);
> +	data1 = FIELD_SET(data1, SPM_PMIC_DATA_1_MIN_VSEL, volt_sel);
> +	data1 = FIELD_SET(data1, SPM_PMIC_DATA_1_MAX_VSEL, volt_sel);
> +
> +	spm_register_write(drv, SPM_REG_VCTL, vctl);
> +	spm_register_write(drv, SPM_REG_PMIC_DATA_0, data0);
> +	spm_register_write(drv, SPM_REG_PMIC_DATA_1, data1);
> +
> +	if (read_poll_timeout_atomic(spm_register_read,
> +				     sts, sts == vlevel,
> +				     1, 200, false,
> +				     drv, SPM_REG_STS1)) {
> +		dev_err_ratelimited(drv->dev, "timeout setting the voltage (%x %x)!\n", sts, vlevel);
> +		goto enable_avs;
> +	}
> +
> +	if (avs_enabled) {
> +		unsigned int max_avs = volt_sel;
> +		unsigned int min_avs = max(max_avs, 4U) - 4;
> +
> +		avs_ctl = FIELD_SET(avs_ctl, SPM_AVS_CTL_MIN_VLVL, min_avs);
> +		avs_ctl = FIELD_SET(avs_ctl, SPM_AVS_CTL_MAX_VLVL, max_avs);
> +		spm_register_write(drv, SPM_REG_AVS_CTL, avs_ctl);
> +	}
> +
> +enable_avs:
> +	if (avs_enabled) {
> +		avs_ctl |= SPM_1_1_AVS_CTL_AVS_ENABLED;
> +		spm_register_write(drv, SPM_REG_AVS_CTL, avs_ctl);
> +	}
> +}
> +
> +static int spm_get_cpu(struct device *dev)
> +{
> +	int cpu;
> +	bool found;
> +
> +	for_each_possible_cpu(cpu) {
> +		struct device_node *cpu_node, *saw_node;
> +
> +		cpu_node = of_cpu_device_node_get(cpu);
> +		if (!cpu_node)
> +			continue;
> +
> +		saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
> +		found = (saw_node == dev->of_node);
> +		of_node_put(saw_node);
> +		of_node_put(cpu_node);
> +
> +		if (found)
> +			return cpu;
> +	}
> +
> +	/* L2 SPM is not bound to any CPU, tie it to CPU0 */

Is this necessary? I would kind of expect that it's only important that
this doesn't happen in parallel on multiple CPUs. The lock in the
regulator core should already ensure that, though. It's somewhat
expensive to schedule on other cores, especially if they are currently
idle and power collapsed.

I don't have too much experience with these really old platforms but at
least on MSM8916 I can't think of any reason that would make the CPU0
more special for the L2 cache than the others (MSM8916 has the regulator
stuff only in the L2 SAW since there is just one CPU power rail).

Thanks,
Stephan

  reply	other threads:[~2023-12-07 17:12 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-07 13:06 [PATCH v5 00/10] soc: qcom: spm: add support for SPM regulator Dmitry Baryshkov
2023-12-07 13:06 ` [PATCH v5 01/10] dt-bindings: soc: qcom: merge qcom,saw2.txt into qcom,spm.yaml Dmitry Baryshkov
2023-12-07 13:06 ` [PATCH v5 02/10] dt-bindings: soc: qcom: qcom,saw2: define optional regulator node Dmitry Baryshkov
2023-12-07 13:06 ` [PATCH v5 03/10] soc: qcom: spm: add support for voltage regulator Dmitry Baryshkov
2023-12-07 17:12   ` Stephan Gerhold [this message]
2023-12-07 20:33     ` Dmitry Baryshkov
2023-12-07 21:34       ` Stephan Gerhold
2023-12-08  0:25         ` Dmitry Baryshkov
2023-12-07 13:06 ` [PATCH v5 04/10] ARM: dts: qcom: apq8064: rename SAW nodes to power-manager Dmitry Baryshkov
2023-12-07 13:06 ` [PATCH v5 05/10] ARM: dts: qcom: apq8064: declare SAW2 regulators Dmitry Baryshkov
2023-12-07 13:06 ` [PATCH v5 06/10] ARM: dts: qcom: msm8960: " Dmitry Baryshkov
2023-12-07 13:07 ` [PATCH v5 07/10] ARM: dts: qcom: apq8084: drop 'regulator' property from SAW2 device Dmitry Baryshkov
2023-12-07 13:07 ` [PATCH v5 08/10] ARM: dts: qcom: msm8974: " Dmitry Baryshkov
2023-12-07 13:07 ` [PATCH v5 09/10] ARM: dts: qcom: ipq4019: drop 'regulator' property from SAW2 devices Dmitry Baryshkov
2023-12-07 13:07 ` [PATCH v5 10/10] ARM: dts: qcom: ipq8064: " Dmitry Baryshkov

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=ZXH88_nwT_3g6MS9@gerhold.net \
    --to=stephan@gerhold.net \
    --cc=agross@kernel.org \
    --cc=andersson@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dmitry.baryshkov@linaro.org \
    --cc=konrad.dybcio@linaro.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=robh+dt@kernel.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