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

Commit 3bd8e108 authored by David Collins's avatar David Collins Committed by Gerrit - the friendly Code Review server
Browse files

regulator: rpmh-regulator: add support for XOB type regulator resources



Add support for oscillator buffer (XOB) regulator resources.
These can be used to vote on regulators which only require
enable/disable control.

Change-Id: I5108f3aabbbafef1e3b676bba842918c6a2f5653
Signed-off-by: default avatarDavid Collins <collinsd@codeaurora.org>
parent a423f3f3
Loading
Loading
Loading
Loading
+27 −13
Original line number Diff line number Diff line
Qualcomm Technologies, Inc. RPMh Regulators

rpmh-regulator devices support PMIC regulator management via the VRM and ARC
RPMh accelerators.  The APPS processor communicates with these hardware blocks
via an RSC using command packets.  The VRM allows changing four parameters for
a given regulator: enable state, output voltage, operating mode, and minimum
headroom voltage.  The ARC allows changing only a single parameter for a given
regulator: its operating level.  This operating level is fed into CPR which then
decides upon a final explicit voltage for the regulator.
rpmh-regulator devices support PMIC regulator management via the VRM, ARC and
XOB RPMh accelerators.  The APPS processor communicates with these hardware
blocks via an RSC using command packets.  The VRM allows changing four
parameters for a given regulator: enable state, output voltage, operating mode,
and minimum headroom voltage.  The ARC allows changing only a single parameter
for a given regulator: its operating level.  This operating level is fed into
CPR which then decides upon a final explicit voltage for the regulator.  The XOB
allows changing only a single parameter for a given regulator: its enable state.

=======================
Required Node Structure
@@ -24,9 +25,10 @@ First Level Nodes - RPMh Interface
- compatible
	Usage:      required
	Value type: <string>
	Definition: Must be "qcom,rpmh-vrm-regulator" or
		    "qcom,rpmh-arc-regulator" depending upon the hardware type,
		    VRM or ARC, of the RPMh managed regulator resource.
	Definition: Must be "qcom,rpmh-vrm-regulator", "qcom,rpmh-arc-regulator"
		    or "qcom,rpmh-xob-regulator" depending upon the hardware
		    type, VRM, ARC or XOB, of the RPMh managed regulator
		    resource.

- mboxes
	Usage:      required
@@ -116,8 +118,8 @@ Second Level Nodes - Regulator Interfaces
 - regulator-enable-ramp-delay
	Usage:      optional
	Value type: <u32>
	Definition: For VRM resources, the time in microseconds to delay after
		    enabling a regulator.
	Definition: For VRM and XOB resources, the time in microseconds to delay
		    after enabling a regulator.

- qcom,set
	Usage:      required
@@ -130,7 +132,7 @@ Second Level Nodes - Regulator Interfaces
		    one of RPMH_REGULATOR_SET_* (i.e. 1, 2, or 3).

- qcom,init-enable
	Usage:      optional; VRM regulators only
	Usage:      optional; VRM and XOB regulators only
	Value type: <u32>
	Definition: Specifies the initial enable state to request for a VRM
		    regulator.  Supported values are 0 (regulator disabled) and
@@ -267,3 +269,15 @@ rpmh-regulator-ldoa4 {
		qcom,init-voltage = <1000000>;
	};
};

rpmh-regulator-ldoc1 {
	compatible = "qcom,rpmh-xob-regulator";
	mboxes = <&apps_rsc 0>;
	qcom,resource-name = "ldoc1";
	pm855l_l1: regulator-pm855l-l1 {
		regulator-name = "pm855l_l1";
		qcom,set = <RPMH_REGULATOR_SET_ALL>;
		regulator-min-microvolt = <1800000>;
		regulator-max-microvolt = <1800000>;
	};
};
+90 −14
Original line number Diff line number Diff line
@@ -36,10 +36,13 @@
 * %RPMH_REGULATOR_TYPE_ARC:	RPMh ARC accelerator which supports voting on
 *				the CPR managed voltage level of LDO and SMPS
 *				type PMIC regulators.
 * %RPMH_REGULATOR_TYPE_XOB:	RPMh XOB accelerator which supports voting on
 *				the enable state of PMIC regulators.
 */
enum rpmh_regulator_type {
	RPMH_REGULATOR_TYPE_VRM,
	RPMH_REGULATOR_TYPE_ARC,
	RPMH_REGULATOR_TYPE_XOB,
};

/**
@@ -52,6 +55,7 @@ enum rpmh_regulator_type {
 *					for enable voting.  Instead, ARC level
 *					0 corresponds to "disabled" for a given
 *					ARC regulator resource if supported.
 * %RPMH_REGULATOR_REG_XOB_ENABLE:	XOB enable voting register index
 * %RPMH_REGULATOR_REG_ENABLE:		Common enable index used in callback
 *					functions for both ARC and VRM.
 * %RPMH_REGULATOR_REG_VRM_MODE:	VRM regulator mode voting register index
@@ -61,6 +65,8 @@ enum rpmh_regulator_type {
 *					register indices
 * %RPMH_REGULATOR_REG_ARC_MAX:		Exclusive upper limit of ARC register
 *					indices
 * %RPMH_REGULATOR_REG_XOB_MAX:		Exclusive upper limit of XOB register
 *					indices
 * %RPMH_REGULATOR_REG_VRM_MAX:		Exclusive upper limit of VRM register
 *					indices
 * %RPMH_REGULATOR_REG_MAX:		Combined exclusive upper limit of ARC
@@ -73,11 +79,13 @@ enum rpmh_regulator_reg_index {
	RPMH_REGULATOR_REG_ARC_LEVEL		= 0,
	RPMH_REGULATOR_REG_VRM_ENABLE		= 1,
	RPMH_REGULATOR_REG_ARC_PSEUDO_ENABLE	= RPMH_REGULATOR_REG_VRM_ENABLE,
	RPMH_REGULATOR_REG_XOB_ENABLE		= RPMH_REGULATOR_REG_VRM_ENABLE,
	RPMH_REGULATOR_REG_ENABLE		= RPMH_REGULATOR_REG_VRM_ENABLE,
	RPMH_REGULATOR_REG_VRM_MODE		= 2,
	RPMH_REGULATOR_REG_VRM_HEADROOM		= 3,
	RPMH_REGULATOR_REG_ARC_REAL_MAX		= 1,
	RPMH_REGULATOR_REG_ARC_MAX		= 2,
	RPMH_REGULATOR_REG_XOB_MAX		= 2,
	RPMH_REGULATOR_REG_VRM_MAX		= 4,
	RPMH_REGULATOR_REG_MAX			= 4,
};
@@ -104,6 +112,9 @@ enum rpmh_regulator_reg_index {
#define RPMH_VRM_MODE_MIN		0
#define RPMH_VRM_MODE_MAX		7

/* XOB voting registers are found in the VRM hardware module */
#define CMD_DB_HW_XOB			CMD_DB_HW_VRM

/*
 * Mapping from RPMh VRM accelerator modes to regulator framework modes
 * Assumes that SMPS PFM mode == LDO LPM mode and SMPS PWM mode == LDO HPM mode
@@ -297,6 +308,10 @@ static const char *const rpmh_regulator_arc_param_names[] = {
	[RPMH_REGULATOR_REG_ARC_LEVEL]		= "hlvl",
};

static const char *const rpmh_regulator_xob_param_names[] = {
	[RPMH_REGULATOR_REG_XOB_ENABLE]		= "en",
};

/**
 * rpmh_regulator_req() - print the rpmh regulator request to the kernel log
 * @vreg:		Pointer to the RPMh regulator
@@ -323,12 +338,22 @@ static void rpmh_regulator_req(struct rpmh_vreg *vreg,
	u32 valid;
	bool first;

	max_reg_index = aggr_vreg->regulator_type == RPMH_REGULATOR_TYPE_VRM
					? RPMH_REGULATOR_REG_VRM_MAX
					: RPMH_REGULATOR_REG_ARC_REAL_MAX;
	param_name = aggr_vreg->regulator_type == RPMH_REGULATOR_TYPE_VRM
					? rpmh_regulator_vrm_param_names
					: rpmh_regulator_arc_param_names;
	switch (aggr_vreg->regulator_type) {
	case RPMH_REGULATOR_TYPE_VRM:
		max_reg_index = RPMH_REGULATOR_REG_VRM_MAX;
		param_name =  rpmh_regulator_vrm_param_names;
		break;
	case RPMH_REGULATOR_TYPE_ARC:
		max_reg_index = RPMH_REGULATOR_REG_ARC_REAL_MAX;
		param_name =  rpmh_regulator_arc_param_names;
		break;
	case RPMH_REGULATOR_TYPE_XOB:
		max_reg_index = RPMH_REGULATOR_REG_XOB_MAX;
		param_name =  rpmh_regulator_xob_param_names;
		break;
	default:
		return;
	}

	pos += scnprintf(buf + pos, buflen - pos,
			"%s (%s), addr=0x%05X: s=%s; sent: ",
@@ -438,9 +463,20 @@ rpmh_regulator_send_aggregate_requests(struct rpmh_vreg *vreg)
	enum rpmh_state state;
	u32 sent_mask;

	max_reg_index = aggr_vreg->regulator_type == RPMH_REGULATOR_TYPE_VRM
						? RPMH_REGULATOR_REG_VRM_MAX
						: RPMH_REGULATOR_REG_ARC_MAX;
	switch (aggr_vreg->regulator_type) {
	case RPMH_REGULATOR_TYPE_VRM:
		max_reg_index = RPMH_REGULATOR_REG_VRM_MAX;
		break;
	case RPMH_REGULATOR_TYPE_ARC:
		max_reg_index = RPMH_REGULATOR_REG_ARC_MAX;
		break;
	case RPMH_REGULATOR_TYPE_XOB:
		max_reg_index = RPMH_REGULATOR_REG_XOB_MAX;
		break;
	default:
		return -EINVAL;
	}

	/*
	 * Perform max aggregration of each register value across all regulators
	 * which use this RPMh resource.
@@ -1005,9 +1041,16 @@ static const struct regulator_ops rpmh_regulator_arc_ops = {
	.list_voltage		= rpmh_regulator_arc_list_voltage,
};

static const struct regulator_ops rpmh_regulator_xob_ops = {
	.enable			= rpmh_regulator_enable,
	.disable		= rpmh_regulator_disable,
	.is_enabled		= rpmh_regulator_is_enabled,
};

static const struct regulator_ops *rpmh_regulator_ops[] = {
	[RPMH_REGULATOR_TYPE_VRM]	= &rpmh_regulator_vrm_ops,
	[RPMH_REGULATOR_TYPE_ARC]	= &rpmh_regulator_arc_ops,
	[RPMH_REGULATOR_TYPE_XOB]	= &rpmh_regulator_xob_ops,
};

/**
@@ -1322,6 +1365,13 @@ static int rpmh_regulator_load_default_parameters(struct rpmh_vreg *vreg)
		rc = of_property_read_u32(vreg->of_node, prop, &temp);
		if (!rc)
			vreg->rdesc.min_dropout_uV = temp;
	} else if (type == RPMH_REGULATOR_TYPE_XOB) {
		prop = "qcom,init-enable";
		rc = of_property_read_u32(vreg->of_node, prop, &temp);
		if (!rc)
			rpmh_regulator_set_reg(vreg,
						RPMH_REGULATOR_REG_XOB_ENABLE,
						!!temp);
	}

	return 0;
@@ -1408,6 +1458,10 @@ static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg)
		init_data->constraints.valid_ops_mask
			|= REGULATOR_CHANGE_VOLTAGE;

	if (type == RPMH_REGULATOR_TYPE_XOB
	    && init_data->constraints.min_uV == init_data->constraints.max_uV)
		vreg->rdesc.fixed_uV = init_data->constraints.min_uV;

	if (vreg->aggr_vreg->mode_count) {
		init_data->constraints.valid_ops_mask
			|= REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_DRMS;
@@ -1434,8 +1488,19 @@ static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg)
		init_data->constraints.valid_ops_mask
			|= REGULATOR_CHANGE_STATUS;

	vreg->rdesc.n_voltages = type == RPMH_REGULATOR_TYPE_ARC ?
					vreg->aggr_vreg->level_count : 2;
	switch (type) {
	case RPMH_REGULATOR_TYPE_VRM:
		vreg->rdesc.n_voltages = 2;
		break;
	case RPMH_REGULATOR_TYPE_ARC:
		vreg->rdesc.n_voltages = vreg->aggr_vreg->level_count;
		break;
	case RPMH_REGULATOR_TYPE_XOB:
		vreg->rdesc.n_voltages = 1;
		break;
	default:
		return -EINVAL;
	}

	rc = of_property_read_u32(vreg->of_node, "qcom,set", &set);
	if (rc) {
@@ -1493,6 +1558,10 @@ static const struct of_device_id rpmh_regulator_match_table[] = {
		.compatible = "qcom,rpmh-arc-regulator",
		.data = (void *)(uintptr_t)RPMH_REGULATOR_TYPE_ARC,
	},
	{
		.compatible = "qcom,rpmh-xob-regulator",
		.data = (void *)(uintptr_t)RPMH_REGULATOR_TYPE_XOB,
	},
	{}
};

@@ -1570,11 +1639,15 @@ static int rpmh_regulator_probe(struct platform_device *pdev)
	if ((aggr_vreg->regulator_type == RPMH_REGULATOR_TYPE_ARC
			&& sid != CMD_DB_HW_ARC)
	    || (aggr_vreg->regulator_type == RPMH_REGULATOR_TYPE_VRM
			&& sid != CMD_DB_HW_VRM)) {
			&& sid != CMD_DB_HW_VRM)
	    || (aggr_vreg->regulator_type == RPMH_REGULATOR_TYPE_XOB
			&& sid != CMD_DB_HW_XOB)) {
		aggr_vreg_err(aggr_vreg, "RPMh slave ID mismatch; config=%d (%s) != cmd-db=%d\n",
			aggr_vreg->regulator_type,
			aggr_vreg->regulator_type == RPMH_REGULATOR_TYPE_ARC
				? "ARC" : "VRM",
				? "ARC" : (aggr_vreg->regulator_type
						== RPMH_REGULATOR_TYPE_VRM
					  ? "VRM" : "XOB"),
			sid);
		return -EINVAL;
	}
@@ -1643,7 +1716,10 @@ static int rpmh_regulator_probe(struct platform_device *pdev)
	aggr_vreg_debug(aggr_vreg, "successfully probed; addr=0x%05X, type=%s\n",
			aggr_vreg->addr,
			aggr_vreg->regulator_type == RPMH_REGULATOR_TYPE_ARC
				? "ARC" : "VRM");
				? "ARC"
				: (aggr_vreg->regulator_type
						== RPMH_REGULATOR_TYPE_VRM
					? "VRM" : "XOB"));

	return rc;