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

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

Merge "ARM: dts: msm: Add SPM and APC CPR regulator nodes for 8909w-pm660"

parents 4935f8b8 9b90c4c5
Loading
Loading
Loading
Loading
+96 −10
Original line number Diff line number Diff line
@@ -10,16 +10,6 @@
 * GNU General Public License for more details.
 */

/* CPR controlled regulator */
&soc {
	apc_vreg_corner: regulator-apc-corner {
		 compatible = "qcom,stub-regulator";
		  regulator-name = "apc_corner";
		  regulator-min-microvolt = <1>;
		  regulator-max-microvolt = <3>;
	 };
};

&rpm_bus {
	/* CX supply */
	rpm-regulator-smpa2 {
@@ -315,3 +305,99 @@
		};
	};
};

/* SPM controlled regulators */
&spmi_bus {
	qcom,pm660@1 {
		pm660_s1: spm-regulator@1400 {
			compatible = "qcom,spm-regulator";
			regulator-name = "pm660_s1";
			reg = <0x1400 0x100>;
			regulator-min-microvolt = <1052000>;
			regulator-max-microvolt = <1352000>;

			/* TODO: remove after SAW support is enabled */
			qcom,bypass-spm;
		};
	};
};

/* CPR controlled regulator */
&soc {
	mem_acc_vreg_corner: regulator@1942130 {
		compatible = "qcom,mem-acc-regulator";
		reg = <0x1942130 0x4>;
		reg-names = "acc-sel-l1";
		regulator-name = "mem_acc_corner";
		regulator-min-microvolt = <1>;
		regulator-max-microvolt = <3>;

		qcom,acc-sel-l1-bit-pos = <0>;
		qcom,corner-acc-map = <0 1 1>;
	};

	apc_vreg_corner: regulator@b018000 {
		compatible = "qcom,cpr-regulator";
		reg = <0xb018000 0x1000>, <0xb011064 4>, <0x58000 0x1000>;
		reg-names = "rbcpr", "rbcpr_clk", "efuse_addr";
		interrupts = <0 15 0>;
		regulator-name = "apc_corner";
		qcom,cpr-fuse-corners = <3>;
		regulator-min-microvolt = <1>;
		regulator-max-microvolt = <9>;

		qcom,cpr-voltage-ceiling = <1052000 1228000 1352000>;
		qcom,cpr-voltage-floor = <1052000 1052000 1156000>;
		vdd-apc-supply = <&pm660_s1>;

		qcom,vdd-mx-corner-map = <4 5 7>;
		qcom,vdd-mx-vmin-method = <4>;
		vdd-mx-supply = <&pm660_s3_corner_ao>;
		qcom,vdd-mx-vmax = <7>;

		mem-acc-supply = <&mem_acc_vreg_corner>;

		qcom,cpr-ref-clk = <19200>;
		qcom,cpr-timer-delay = <5000>;
		qcom,cpr-timer-cons-up = <0>;
		qcom,cpr-timer-cons-down = <2>;
		qcom,cpr-irq-line = <0>;
		qcom,cpr-step-quotient = <10>;
		qcom,cpr-up-threshold = <0>;
		qcom,cpr-down-threshold = <2>;
		qcom,cpr-idle-clocks = <15>;
		qcom,cpr-gcnt-time = <1>;
		qcom,vdd-apc-step-up-limit = <1>;
		qcom,vdd-apc-step-down-limit = <1>;
		qcom,cpr-apc-volt-step = <4000>;

		qcom,cpr-fuse-row = <26 0>;
		qcom,cpr-fuse-target-quot = <42 24 6>;
		qcom,cpr-fuse-ro-sel = <61 61 54>;
		qcom,cpr-fuse-bp-cpr-disable = <58>;
		qcom,cpr-fuse-init-voltage =
					<26 36 6 0>,
					<26 18 6 0>,
					<26 0 6 0>;
		qcom,cpr-fuse-revision = <26 59 2 0>;
		qcom,cpr-init-voltage-ref = <1052000 1228000 1352000>;
		qcom,cpr-init-voltage-step = <10000>;
		qcom,cpr-corner-map = <1 1 2 2 3 3 3 3 3>;
		qcom,cpr-init-voltage-as-ceiling;
		qcom,cpr-corner-frequency-map =
					<1 200000000>,
					<2 400000000>,
					<3 533330000>,
					<4 800000000>,
					<5 998400000>,
					<6 1094400000>,
					<7 1190400000>,
					<8 1248000000>,
					<9 1267200000>;
		qcom,speed-bin-fuse-sel = <1 34 3 0>;
		qcom,cpr-speed-bin-max-corners =
					<0 (-1) 2 4 9>,
					<2 (-1) 2 4 6>;
		qcom,cpr-quot-adjust-scaling-factor-max = <1400>;
	};
};
+110 −30
Original line number Diff line number Diff line
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -47,6 +47,7 @@ enum qpnp_regulator_uniq_type {
	QPNP_TYPE_HF,
	QPNP_TYPE_FTS2,
	QPNP_TYPE_FTS2p5,
	QPNP_TYPE_FTS426,
	QPNP_TYPE_ULT_HF,
};

@@ -54,6 +55,7 @@ enum qpnp_regulator_type {
	QPNP_HF_TYPE		= 0x03,
	QPNP_FTS2_TYPE		= 0x1C,
	QPNP_FTS2p5_TYPE	= 0x1C,
	QPNP_FTS426_TYPE	= 0x1C,
	QPNP_ULT_HF_TYPE	= 0x22,
};

@@ -61,6 +63,7 @@ enum qpnp_regulator_subtype {
	QPNP_FTS2_SUBTYPE	= 0x08,
	QPNP_HF_SUBTYPE		= 0x08,
	QPNP_FTS2p5_SUBTYPE	= 0x09,
	QPNP_FTS426_SUBTYPE	= 0x0A,
	QPNP_ULT_HF_SUBTYPE	= 0x0D,
};

@@ -70,6 +73,7 @@ static const struct voltage_range fts2p5_range0
					 = { 80000, 350000, 1355000,  5000};
static const struct voltage_range fts2p5_range1
					 = {160000, 700000, 2200000, 10000};
static const struct voltage_range fts426_range = {0, 320000, 1352000, 4000};
static const struct voltage_range ult_hf_range0 = {375000, 375000, 1562500,
								12500};
static const struct voltage_range ult_hf_range1 = {750000, 750000, 1525000,
@@ -85,6 +89,12 @@ static const struct voltage_range hf_range1 = {1550000, 1550000, 3125000,
#define QPNP_SMPS_REG_MODE		0x45
#define QPNP_SMPS_REG_STEP_CTRL		0x61

/* FTS426 voltage control registers */
#define QPNP_FTS426_REG_VOLTAGE_LB		0x40
#define QPNP_FTS426_REG_VOLTAGE_UB		0x41
#define QPNP_FTS426_REG_VOLTAGE_VALID_LB	0x42
#define QPNP_FTS426_REG_VOLTAGE_VALID_UB	0x43

#define QPNP_SMPS_MODE_PWM		0x80
#define QPNP_SMPS_MODE_AUTO		0x40

@@ -92,9 +102,12 @@ static const struct voltage_range hf_range1 = {1550000, 1550000, 3125000,
#define QPNP_SMPS_STEP_CTRL_STEP_SHIFT	3
#define QPNP_SMPS_STEP_CTRL_DELAY_MASK	0x07
#define QPNP_SMPS_STEP_CTRL_DELAY_SHIFT	0
#define QPNP_FTS426_STEP_CTRL_DELAY_MASK	0x03
#define QPNP_FTS426_STEP_CTRL_DELAY_SHIFT	0

/* Clock rate in kHz of the FTS2 regulator reference clock. */
#define QPNP_SMPS_CLOCK_RATE		19200
#define QPNP_FTS426_CLOCK_RATE		4800

/* Time to delay in us to ensure that a mode change has completed. */
#define QPNP_FTS2_MODE_CHANGE_DELAY	50
@@ -105,6 +118,7 @@ static const struct voltage_range hf_range1 = {1550000, 1550000, 3125000,
/* Minimum voltage stepper delay for each step. */
#define QPNP_FTS2_STEP_DELAY		8
#define QPNP_HF_STEP_DELAY		20
#define QPNP_FTS426_STEP_DELAY		2

/* Arbitrarily large max step size used to avoid possible numerical overflow */
#define SPM_REGULATOR_MAX_STEP_UV	10000000
@@ -115,6 +129,8 @@ static const struct voltage_range hf_range1 = {1550000, 1550000, 3125000,
 */
#define QPNP_FTS2_STEP_MARGIN_NUM	4
#define QPNP_FTS2_STEP_MARGIN_DEN	5
#define QPNP_FTS426_STEP_MARGIN_NUM	10
#define QPNP_FTS426_STEP_MARGIN_DEN	11

/*
 * Settling delay for FTS2.5
@@ -160,6 +176,9 @@ static int spm_regulator_uv_to_vlevel(struct spm_vreg *vreg, int uV)
{
	int vlevel;

	if (vreg->regulator_type == QPNP_TYPE_FTS426)
		return roundup(uV, vreg->range->step_uV) / 1000;

	vlevel = DIV_ROUND_UP(uV - vreg->range->min_uV, vreg->range->step_uV);

	/* Fix VSET for ULT HF Buck */
@@ -174,6 +193,8 @@ static int spm_regulator_uv_to_vlevel(struct spm_vreg *vreg, int uV)

static int spm_regulator_vlevel_to_uv(struct spm_vreg *vreg, int vlevel)
{
	if (vreg->regulator_type == QPNP_TYPE_FTS426)
		return vlevel * 1000;
	/*
	 * Calculate ULT HF buck VSET based on range:
	 * In case of range 0: VSET is a 7 bit value.
@@ -201,19 +222,63 @@ static unsigned spm_regulator_vlevel_to_selector(struct spm_vreg *vreg,
static int qpnp_smps_read_voltage(struct spm_vreg *vreg)
{
	int rc;
	u8 reg = 0;
	u8 reg[2] = {0,};

	rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl, vreg->spmi_dev->sid,
		vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT, &reg, 1);
	if (vreg->regulator_type == QPNP_TYPE_FTS426) {
		rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl,
					vreg->spmi_dev->sid,
			vreg->spmi_base_addr + QPNP_FTS426_REG_VOLTAGE_VALID_LB,
					reg, 2);
		if (rc) {
		dev_err(&vreg->spmi_dev->dev, "%s: could not read voltage setpoint register, rc=%d\n",
			dev_err(&vreg->spmi_dev->dev,
				"%s: could not read voltage setpoint registers, rc=%d\n",
				__func__, rc);
			return rc;
		}

	vreg->last_set_vlevel = reg;
	vreg->last_set_uV = spm_regulator_vlevel_to_uv(vreg, reg);
		vreg->last_set_vlevel = (reg[1] << 8) | reg[0];
	} else {
		rc = spmi_ext_register_readl(vreg->spmi_dev->ctrl,
					vreg->spmi_dev->sid,
			vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT,
					reg, 1);
		if (rc) {
			dev_err(&vreg->spmi_dev->dev,
				"%s: could not read voltage setpoint register, rc=%d\n",
				__func__, rc);
			return rc;
		}
		vreg->last_set_vlevel = reg[0];
	}

	vreg->last_set_uV = spm_regulator_vlevel_to_uv(vreg,
						vreg->last_set_vlevel);
	return rc;
}

static int qpnp_smps_write_voltage(struct spm_vreg *vreg, unsigned vlevel)
{
	int rc = 0;
	u8 reg[2];

	/* Set voltage control registers via SPMI. */
	reg[0] = vlevel & 0xFF;
	reg[1] = (vlevel >> 8) & 0xFF;

	if (vreg->regulator_type == QPNP_TYPE_FTS426) {
		rc = spmi_ext_register_writel(vreg->spmi_dev->ctrl,
					vreg->spmi_dev->sid,
			vreg->spmi_base_addr + QPNP_FTS426_REG_VOLTAGE_LB,
					reg, 2);
	} else {
		rc = spmi_ext_register_writel(vreg->spmi_dev->ctrl,
					vreg->spmi_dev->sid,
			vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT,
					reg, 1);
	}
	if (rc)
		pr_err("%s: spmi_ext_register_writel failed, rc=%d\n",
			vreg->rdesc.name, rc);
	return rc;
}

@@ -267,7 +332,6 @@ static int spm_regulator_write_voltage(struct spm_vreg *vreg, int uV)
	bool spm_failed = false;
	int rc = 0;
	u32 slew_delay;
	u8 reg;

	if (likely(!vreg->bypass_spm)) {
		/* Set voltage control register via SPM. */
@@ -280,14 +344,9 @@ static int spm_regulator_write_voltage(struct spm_vreg *vreg, int uV)
	}

	if (unlikely(vreg->bypass_spm || spm_failed)) {
		/* Set voltage control register via SPMI. */
		reg = vlevel;
		rc = spmi_ext_register_writel(vreg->spmi_dev->ctrl,
			vreg->spmi_dev->sid,
			vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT,
			&reg, 1);
		rc = qpnp_smps_write_voltage(vreg, vlevel);
		if (rc) {
			pr_err("%s: spmi_ext_register_writel failed, rc=%d\n",
			pr_err("%s: voltage write failed, rc=%d\n",
			       vreg->rdesc.name, rc);
			return rc;
		}
@@ -531,7 +590,7 @@ static int spm_regulator_avs_set_voltage(struct regulator_dev *rdev, int min_uV,
		return -EINVAL;
	}

	vlevel_max = (uV - range->min_uV) / range->step_uV;
	vlevel_max = spm_regulator_uv_to_vlevel(vreg, uV);
	avs_max_uV = spm_regulator_vlevel_to_uv(vreg, vlevel_max);

	if (avs_max_uV < min_uV) {
@@ -636,6 +695,9 @@ static int qpnp_smps_check_type(struct spm_vreg *vreg)
	} else if (type[0] == QPNP_FTS2p5_TYPE
					&& type[1] == QPNP_FTS2p5_SUBTYPE) {
		vreg->regulator_type = QPNP_TYPE_FTS2p5;
	} else if (type[0] == QPNP_FTS426_TYPE
					&& type[1] == QPNP_FTS426_SUBTYPE) {
		vreg->regulator_type = QPNP_TYPE_FTS426;
	} else if (type[0] == QPNP_ULT_HF_TYPE
					&& type[1] == QPNP_ULT_HF_SUBTYPE) {
		vreg->regulator_type = QPNP_TYPE_ULT_HF;
@@ -776,24 +838,39 @@ static int qpnp_smps_init_step_rate(struct spm_vreg *vreg)
		return rc;
	}

	/* ULT buck does not support steps */
	if (vreg->regulator_type != QPNP_TYPE_ULT_HF)
	/* ULT and FTS426 bucks do not support steps */
	if (vreg->regulator_type != QPNP_TYPE_ULT_HF
		&& vreg->regulator_type != QPNP_TYPE_FTS426)
		step = (reg & QPNP_SMPS_STEP_CTRL_STEP_MASK)
			>> QPNP_SMPS_STEP_CTRL_STEP_SHIFT;

	if (vreg->regulator_type == QPNP_TYPE_FTS426) {
		delay = (reg & QPNP_FTS426_STEP_CTRL_DELAY_MASK)
			>> QPNP_FTS426_STEP_CTRL_DELAY_SHIFT;

		/* step_rate has units of uV/us. */
		vreg->step_rate = QPNP_FTS426_CLOCK_RATE * vreg->range->step_uV;
	} else {
		delay = (reg & QPNP_SMPS_STEP_CTRL_DELAY_MASK)
			>> QPNP_SMPS_STEP_CTRL_DELAY_SHIFT;

		/* step_rate has units of uV/us. */
		vreg->step_rate = QPNP_SMPS_CLOCK_RATE * vreg->range->step_uV
					* (1 << step);
	}

	if ((vreg->regulator_type == QPNP_TYPE_ULT_HF)
			|| (vreg->regulator_type == QPNP_TYPE_HF))
		vreg->step_rate /= 1000 * (QPNP_HF_STEP_DELAY << delay);
	else if (vreg->regulator_type == QPNP_TYPE_FTS426)
		vreg->step_rate /= 1000 * (QPNP_FTS426_STEP_DELAY << delay);
	else
		vreg->step_rate /= 1000 * (QPNP_FTS2_STEP_DELAY << delay);

	if (vreg->regulator_type == QPNP_TYPE_FTS426)
		vreg->step_rate = vreg->step_rate * QPNP_FTS426_STEP_MARGIN_NUM
					/ QPNP_FTS426_STEP_MARGIN_DEN;
	else
		vreg->step_rate = vreg->step_rate * QPNP_FTS2_STEP_MARGIN_NUM
					/ QPNP_FTS2_STEP_MARGIN_DEN;

@@ -806,7 +883,8 @@ static int qpnp_smps_init_step_rate(struct spm_vreg *vreg)
static bool spm_regulator_using_range0(struct spm_vreg *vreg)
{
	return vreg->range == &fts2_range0 || vreg->range == &fts2p5_range0
		|| vreg->range == &ult_hf_range0 || vreg->range == &hf_range0;
		|| vreg->range == &ult_hf_range0 || vreg->range == &hf_range0
		|| vreg->range == &fts426_range;
}

/* Register a regulator to enable/disable AVS and set AVS min/max limits. */
@@ -937,6 +1015,8 @@ static int spm_regulator_probe(struct spmi_device *spmi)
		rc = qpnp_smps_init_range(vreg, &fts2_range0, &fts2_range1);
	else if (vreg->regulator_type == QPNP_TYPE_FTS2p5)
		rc = qpnp_smps_init_range(vreg, &fts2p5_range0, &fts2p5_range1);
	else if (vreg->regulator_type == QPNP_TYPE_FTS426)
		vreg->range = &fts426_range;
	else if (vreg->regulator_type == QPNP_TYPE_HF)
		rc = qpnp_smps_init_range(vreg, &hf_range0, &hf_range1);
	else if (vreg->regulator_type == QPNP_TYPE_ULT_HF)