svn commit: r355183 - in stable/12/sys: arm/allwinner arm64/rockchip dev/extres/regulator

Emmanuel Vadot manu at FreeBSD.org
Thu Nov 28 18:44:08 UTC 2019


Author: manu
Date: Thu Nov 28 18:44:06 2019
New Revision: 355183
URL: https://svnweb.freebsd.org/changeset/base/355183

Log:
  MFC r353917-r353919, r354396-r354397
  
  r353917:
  regulator: Add a regnode_method_init
  
  This is a default init method for regulator that don't really
  need one.
  
  r353918:
  axp81x: Use the default regnode_init method
  
  r353919:
  regulator: Add a regnode_set_constraint function
  
  This method check that boot_on or always_on is set to 1 and if it
  is it will try to enable the regulator.
  The binding docs aren't clear on what to do but Linux enable the regulator
  if any of those properties is set so we want to do the same.
  The function first check the status to see if the regulator is
  already enabled it then get the voltage to check if it is in a acceptable
  range and then enables it.
  This will be either called from the regnode_init method (if it's needed by the platform)
  or by a SYSINIT at SI_SUB_LAST
  
  Reviewed by:	mmel
  Differential Revision:	https://reviews.freebsd.org/D22106
  
  r354396:
  regulator: Add regulator_check_voltage function
  
  This function will call the regnode_check_voltage method for a given regulator
  and check if the desired voltage in reachable by it.
  Also adds a default method that check the std_param and which should be enough
  for most regulators and add it as the method for axp* rk805 and fixed regulators.
  
  Reviewed by:	mmel
  Differential Revision:	https://reviews.freebsd.org/D22260
  
  r354397:
  arm: allwinner: aw_mmc: Check if the regulator support the voltage
  
  Don't blindy say that we support both 3.3V and 1.8V.
  If we have a regulator for the data lines, check that the voltage is
  supported before adding the signaling caps.
  If we don't have a regulator, just assume that the data lines are 3.3V
  This unbreak eMMC on some allwinner boards.
  
  Reported by:	ganbold
  X-MFC-With:	r354396

Modified:
  stable/12/sys/arm/allwinner/aw_mmc.c
  stable/12/sys/arm/allwinner/axp209.c
  stable/12/sys/arm/allwinner/axp81x.c
  stable/12/sys/arm64/rockchip/rk805.c
  stable/12/sys/dev/extres/regulator/regnode_if.m
  stable/12/sys/dev/extres/regulator/regulator.c
  stable/12/sys/dev/extres/regulator/regulator.h
  stable/12/sys/dev/extres/regulator/regulator_fixed.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/arm/allwinner/aw_mmc.c
==============================================================================
--- stable/12/sys/arm/allwinner/aw_mmc.c	Thu Nov 28 18:28:35 2019	(r355182)
+++ stable/12/sys/arm/allwinner/aw_mmc.c	Thu Nov 28 18:44:06 2019	(r355183)
@@ -509,7 +509,13 @@ aw_mmc_attach(device_t dev)
 			   MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 |
 			   MMC_CAP_UHS_DDR50 | MMC_CAP_MMC_DDR52;
 
-	sc->aw_host.caps |= MMC_CAP_SIGNALING_330 | MMC_CAP_SIGNALING_180;
+	if (sc->aw_reg_vqmmc != NULL) {
+		if (regulator_check_voltage(sc->aw_reg_vqmmc, 1800000) == 0)
+			sc->aw_host.caps |= MMC_CAP_SIGNALING_180;
+		if (regulator_check_voltage(sc->aw_reg_vqmmc, 3300000) == 0)
+			sc->aw_host.caps |= MMC_CAP_SIGNALING_330;
+	} else
+		sc->aw_host.caps |= MMC_CAP_SIGNALING_330;
 
 	if (bus_width >= 4)
 		sc->aw_host.caps |= MMC_CAP_4_BIT_DATA;

Modified: stable/12/sys/arm/allwinner/axp209.c
==============================================================================
--- stable/12/sys/arm/allwinner/axp209.c	Thu Nov 28 18:28:35 2019	(r355182)
+++ stable/12/sys/arm/allwinner/axp209.c	Thu Nov 28 18:44:06 2019	(r355183)
@@ -753,6 +753,7 @@ static regnode_method_t axp2xx_regnode_methods[] = {
 	REGNODEMETHOD(regnode_enable,		axp2xx_regnode_enable),
 	REGNODEMETHOD(regnode_set_voltage,	axp2xx_regnode_set_voltage),
 	REGNODEMETHOD(regnode_get_voltage,	axp2xx_regnode_get_voltage),
+	REGNODEMETHOD(regnode_check_voltage,	regnode_method_check_voltage),
 	REGNODEMETHOD_END
 };
 DEFINE_CLASS_1(axp2xx_regnode, axp2xx_regnode_class, axp2xx_regnode_methods,

Modified: stable/12/sys/arm/allwinner/axp81x.c
==============================================================================
--- stable/12/sys/arm/allwinner/axp81x.c	Thu Nov 28 18:28:35 2019	(r355182)
+++ stable/12/sys/arm/allwinner/axp81x.c	Thu Nov 28 18:44:06 2019	(r355183)
@@ -747,12 +747,6 @@ axp8xx_write(device_t dev, uint8_t reg, uint8_t val)
 }
 
 static int
-axp8xx_regnode_init(struct regnode *regnode)
-{
-	return (0);
-}
-
-static int
 axp8xx_regnode_enable(struct regnode *regnode, bool enable, int *udelay)
 {
 	struct axp8xx_reg_sc *sc;
@@ -869,10 +863,10 @@ axp8xx_regnode_get_voltage(struct regnode *regnode, in
 
 static regnode_method_t axp8xx_regnode_methods[] = {
 	/* Regulator interface */
-	REGNODEMETHOD(regnode_init,		axp8xx_regnode_init),
 	REGNODEMETHOD(regnode_enable,		axp8xx_regnode_enable),
 	REGNODEMETHOD(regnode_set_voltage,	axp8xx_regnode_set_voltage),
 	REGNODEMETHOD(regnode_get_voltage,	axp8xx_regnode_get_voltage),
+	REGNODEMETHOD(regnode_check_voltage,	regnode_method_check_voltage),
 	REGNODEMETHOD_END
 };
 DEFINE_CLASS_1(axp8xx_regnode, axp8xx_regnode_class, axp8xx_regnode_methods,

Modified: stable/12/sys/arm64/rockchip/rk805.c
==============================================================================
--- stable/12/sys/arm64/rockchip/rk805.c	Thu Nov 28 18:28:35 2019	(r355182)
+++ stable/12/sys/arm64/rockchip/rk805.c	Thu Nov 28 18:44:06 2019	(r355183)
@@ -362,6 +362,7 @@ static regnode_method_t rk805_regnode_methods[] = {
 	REGNODEMETHOD(regnode_enable,		rk805_regnode_enable),
 	REGNODEMETHOD(regnode_set_voltage,	rk805_regnode_set_voltage),
 	REGNODEMETHOD(regnode_get_voltage,	rk805_regnode_get_voltage),
+	REGNODEMETHOD(regnode_check_voltage,	regnode_method_check_voltage),
 	REGNODEMETHOD_END
 };
 DEFINE_CLASS_1(rk805_regnode, rk805_regnode_class, rk805_regnode_methods,

Modified: stable/12/sys/dev/extres/regulator/regnode_if.m
==============================================================================
--- stable/12/sys/dev/extres/regulator/regnode_if.m	Thu Nov 28 18:28:35 2019	(r355182)
+++ stable/12/sys/dev/extres/regulator/regnode_if.m	Thu Nov 28 18:44:06 2019	(r355183)
@@ -91,6 +91,15 @@ METHOD int get_voltage {
 };
 
 #
+# Check if a given voltage is supported by the regulator
+# Returns 0 on success or a standard errno value.
+#
+METHOD int check_voltage {
+	struct regnode	*regnode;
+	int		uvolt;
+};
+
+#
 # Stop (shutdown) regulator
 # Returns 0 on success or a standard errno value.
 #

Modified: stable/12/sys/dev/extres/regulator/regulator.c
==============================================================================
--- stable/12/sys/dev/extres/regulator/regulator.c	Thu Nov 28 18:28:35 2019	(r355182)
+++ stable/12/sys/dev/extres/regulator/regulator.c	Thu Nov 28 18:44:06 2019	(r355183)
@@ -65,22 +65,26 @@ typedef TAILQ_HEAD(regnode_list, regnode) regnode_list
 typedef TAILQ_HEAD(regulator_list, regulator) regulator_list_t;
 
 /* Default regulator methods. */
+static int regnode_method_init(struct regnode *regnode);
 static int regnode_method_enable(struct regnode *regnode, bool enable,
     int *udelay);
 static int regnode_method_status(struct regnode *regnode, int *status);
 static int regnode_method_set_voltage(struct regnode *regnode, int min_uvolt,
     int max_uvolt, int *udelay);
 static int regnode_method_get_voltage(struct regnode *regnode, int *uvolt);
+static void regulator_constraint(void *dummy);
 static void regulator_shutdown(void *dummy);
 
 /*
  * Regulator controller methods.
  */
 static regnode_method_t regnode_methods[] = {
+	REGNODEMETHOD(regnode_init,		regnode_method_init),
 	REGNODEMETHOD(regnode_enable,		regnode_method_enable),
 	REGNODEMETHOD(regnode_status,		regnode_method_status),
 	REGNODEMETHOD(regnode_set_voltage,	regnode_method_set_voltage),
 	REGNODEMETHOD(regnode_get_voltage,	regnode_method_get_voltage),
+	REGNODEMETHOD(regnode_check_voltage,	regnode_method_check_voltage),
 
 	REGNODEMETHOD_END
 };
@@ -152,9 +156,27 @@ SX_SYSINIT(regulator_topology, &regnode_topo_lock, "Re
 #define REGNODE_XLOCK(_sc)	sx_xlock(&((_sc)->lock))
 #define REGNODE_UNLOCK(_sc)	sx_unlock(&((_sc)->lock))
 
+SYSINIT(regulator_constraint, SI_SUB_LAST, SI_ORDER_ANY, regulator_constraint,
+    NULL);
 SYSINIT(regulator_shutdown, SI_SUB_LAST, SI_ORDER_ANY, regulator_shutdown,
     NULL);
 
+static void
+regulator_constraint(void *dummy)
+{
+	struct regnode *entry;
+	int rv;
+
+	REG_TOPO_SLOCK();
+	TAILQ_FOREACH(entry, &regnode_list, reglist_link) {
+		rv = regnode_set_constraint(entry);
+		if (rv != 0 && bootverbose)
+			printf("regulator: setting constraint on %s failed (%d)\n",
+			    entry->name, rv);
+	}
+	REG_TOPO_UNLOCK();
+}
+
 /*
  * Disable unused regulator
  * We run this function at SI_SUB_LAST which mean that every driver that needs
@@ -213,6 +235,13 @@ regnode_uvolt_sysctl(SYSCTL_HANDLER_ARGS)
  *
  */
 static int
+regnode_method_init(struct regnode *regnode)
+{
+
+	return (0);
+}
+
+static int
 regnode_method_enable(struct regnode *regnode, bool enable, int *udelay)
 {
 
@@ -250,6 +279,16 @@ regnode_method_get_voltage(struct regnode *regnode, in
 	    (regnode->std_param.max_uvolt - regnode->std_param.min_uvolt) / 2);
 }
 
+int
+regnode_method_check_voltage(struct regnode *regnode, int uvolt)
+{
+
+	if ((uvolt > regnode->std_param.max_uvolt) ||
+	    (uvolt < regnode->std_param.min_uvolt))
+		return (ERANGE);
+	return (0);
+}
+
 /* ----------------------------------------------------------------------------
  *
  * Internal functions.
@@ -771,6 +810,56 @@ regnode_set_voltage_checked(struct regnode *regnode, s
 	return (rv);
 }
 
+int
+regnode_set_constraint(struct regnode *regnode)
+{
+	int status, rv, uvolt;
+
+	if (regnode->std_param.boot_on != true &&
+	    regnode->std_param.always_on != true)
+		return (0);
+
+	rv = regnode_status(regnode, &status);
+	if (rv != 0) {
+		if (bootverbose)
+			printf("Cannot get regulator status for %s\n",
+			    regnode_get_name(regnode));
+		return (rv);
+	}
+
+	if (status == REGULATOR_STATUS_ENABLED)
+		return (0);
+
+	rv = regnode_get_voltage(regnode, &uvolt);
+	if (rv != 0) {
+		if (bootverbose)
+			printf("Cannot get regulator voltage for %s\n",
+			    regnode_get_name(regnode));
+		return (rv);
+	}
+
+	if (uvolt < regnode->std_param.min_uvolt ||
+	  uvolt > regnode->std_param.max_uvolt) {
+		if (bootverbose)
+			printf("Regulator %s current voltage %d is not in the"
+			    " acceptable range : %d<->%d\n",
+			    regnode_get_name(regnode),
+			    uvolt, regnode->std_param.min_uvolt,
+			    regnode->std_param.max_uvolt);
+		return (ERANGE);
+	}
+
+	rv = regnode_enable(regnode);
+	if (rv != 0) {
+		if (bootverbose)
+			printf("Cannot enable regulator %s\n",
+			    regnode_get_name(regnode));
+		return (rv);
+	}
+
+	return (0);
+}
+
 #ifdef FDT
 phandle_t
 regnode_get_ofw_node(struct regnode *regnode)
@@ -913,6 +1002,22 @@ regulator_set_voltage(regulator_t reg, int min_uvolt, 
 		reg->min_uvolt = min_uvolt;
 		reg->max_uvolt = max_uvolt;
 	}
+	REG_TOPO_UNLOCK();
+	return (rv);
+}
+
+int
+regulator_check_voltage(regulator_t reg, int uvolt)
+{
+	int rv;
+	struct regnode *regnode;
+
+	regnode = reg->regnode;
+	KASSERT(regnode->ref_cnt > 0,
+	   ("Attempt to access unreferenced regulator: %s\n", regnode->name));
+
+	REG_TOPO_SLOCK();
+	rv = REGNODE_CHECK_VOLTAGE(regnode, uvolt);
 	REG_TOPO_UNLOCK();
 	return (rv);
 }

Modified: stable/12/sys/dev/extres/regulator/regulator.h
==============================================================================
--- stable/12/sys/dev/extres/regulator/regulator.h	Thu Nov 28 18:28:35 2019	(r355182)
+++ stable/12/sys/dev/extres/regulator/regulator.h	Thu Nov 28 18:44:06 2019	(r355183)
@@ -116,6 +116,11 @@ int regnode_stop(struct regnode *regnode, int depth);
 int regnode_status(struct regnode *regnode, int *status);
 int regnode_get_voltage(struct regnode *regnode, int *uvolt);
 int regnode_set_voltage(struct regnode *regnode, int min_uvolt, int max_uvolt);
+int regnode_set_constraint(struct regnode *regnode);
+
+/* Standard method that aren't default */
+int regnode_method_check_voltage(struct regnode *regnode, int uvolt);
+
 #ifdef FDT
 phandle_t regnode_get_ofw_node(struct regnode *regnode);
 #endif
@@ -133,6 +138,7 @@ int regulator_stop(regulator_t reg);
 int regulator_status(regulator_t reg, int *status);
 int regulator_get_voltage(regulator_t reg, int *uvolt);
 int regulator_set_voltage(regulator_t reg, int min_uvolt, int max_uvolt);
+int regulator_check_voltage(regulator_t reg, int uvolt);
 
 #ifdef FDT
 int regulator_get_by_ofw_property(device_t dev, phandle_t node, char *name,

Modified: stable/12/sys/dev/extres/regulator/regulator_fixed.c
==============================================================================
--- stable/12/sys/dev/extres/regulator/regulator_fixed.c	Thu Nov 28 18:28:35 2019	(r355182)
+++ stable/12/sys/dev/extres/regulator/regulator_fixed.c	Thu Nov 28 18:44:06 2019	(r355183)
@@ -80,6 +80,7 @@ static regnode_method_t regnode_fixed_methods[] = {
 	REGNODEMETHOD(regnode_enable,		regnode_fixed_enable),
 	REGNODEMETHOD(regnode_status,		regnode_fixed_status),
 	REGNODEMETHOD(regnode_stop,		regnode_fixed_stop),
+	REGNODEMETHOD(regnode_check_voltage,	regnode_method_check_voltage),
 	REGNODEMETHOD_END
 };
 DEFINE_CLASS_1(regnode_fixed, regnode_fixed_class, regnode_fixed_methods,


More information about the svn-src-all mailing list