Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bab5f303 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "regulator: spm-regulator: add support to recalibrate after voltage changes"

parents 9ecaf63c 82b31127
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@ Optional properties:
		    be managed by an SPM.  Instead, the voltage should be
		    controlled via SPMI.
- qcom,max-voltage-step:  Maximum single voltage step size in microvolts.
- qcom,recal-mask: Bit mask of the APSS clusters to recalibrate after each
		    voltage change.  Bit 0 corresponds to the first cluster,
		    bit 1 corresponds to the second cluster, and so on.

Optional structure:
- A child node may be specified within a qcom,spm-regulator node which defines
+28 −0
Original line number Diff line number Diff line
@@ -28,6 +28,12 @@
#include <linux/regulator/spm-regulator.h>
#include <soc/qcom/spm.h>

#if defined(CONFIG_ARM64) || (defined(CONFIG_ARM) && defined(CONFIG_ARM_PSCI))
	asmlinkage int __invoke_psci_fn_smc(u64, u64, u64, u64);
#else
	#define __invoke_psci_fn_smc(a, b, c, d) 0
#endif

#define SPM_REGULATOR_DRIVER_NAME "qcom,spm-regulator"

struct voltage_range {
@@ -136,6 +142,7 @@ struct spm_vreg {
	int				avs_min_uV;
	int				avs_max_uV;
	bool				avs_enabled;
	u32				recal_cluster_mask;
};

static inline bool spm_regulator_using_avs(struct spm_vreg *vreg)
@@ -290,6 +297,22 @@ static int spm_regulator_write_voltage(struct spm_vreg *vreg, int uV)
	return rc;
}

static int spm_regulator_recalibrate(struct spm_vreg *vreg)
{
	int rc;

	if (!vreg->recal_cluster_mask)
		return 0;

	rc = __invoke_psci_fn_smc(0xC4000020, vreg->recal_cluster_mask,
				  2, 0);
	if (rc)
		pr_err("%s: recalibration failed, rc=%d\n", vreg->rdesc.name,
			rc);

	return rc;
}

static int _spm_regulator_set_voltage(struct regulator_dev *rdev)
{
	struct spm_vreg *vreg = rdev_get_drvdata(rdev);
@@ -334,6 +357,8 @@ static int _spm_regulator_set_voltage(struct regulator_dev *rdev)
			return rc;
	}

	rc = spm_regulator_recalibrate(vreg);

	return rc;
}

@@ -884,6 +909,9 @@ static int spm_regulator_probe(struct spmi_device *spmi)
	of_property_read_u32(vreg->spmi_dev->dev.of_node, "qcom,cpu-num",
						&vreg->cpu_num);

	of_property_read_u32(vreg->spmi_dev->dev.of_node, "qcom,recal-mask",
						&vreg->recal_cluster_mask);

	/*
	 * The regulator must be initialized to range 0 or range 1 during
	 * PMIC power on sequence.  Once it is set, it cannot be changed