Commit d93eb446 authored by Andre Przywara's avatar Andre Przywara
Browse files

allwinner: power: fix DRIVEVBUS pin setup



The DRIVEVBUS pin setup was broken in two ways:
- To configure this pin as an output pin, one has to *clear* the bit in
  register 0x8f. It is 0 by default, but rebooting from Linux might have
  left this bit set.
- Doing this just configures the pin as an output pin, but doesn't
  actually drive power to it. This is done via bit 2 in register 0x30.

Fix the routine to both properly configure the pin and drive power to
it. Add an axp_clrsetbits() helper on the way.

Now this isn't really perfect, still:
We only need to setup the PMIC power rails that are needed for U-Boot.
DRIVEVBUS typically controls the VBUS voltage for the host function of
an USB-OTG port, something we typically don't want in U-Boot (fastboot,
using the USB *device* functionality, is much more common). The
BananaPi-M64 uses the regulator in this way, but the Remix Mini PC
actually controls the power of both its USB ports via this line.

Technically we should differentiate here: if DRIVEVBUS controls a
microUSB-B socket, the power should stay off, any host-type A sockets
should be supplied, though.
For now just always enable the power, that shouldn't really hurt the
USB-OTG functionality anyway.
Signed-off-by: default avatarAndre Przywara <andre.przywara@arm.com>
parent 19a7507a
...@@ -118,7 +118,7 @@ static int axp_write(uint8_t reg, uint8_t val) ...@@ -118,7 +118,7 @@ static int axp_write(uint8_t reg, uint8_t val)
return rsb_write(AXP803_RT_ADDR, reg, val); return rsb_write(AXP803_RT_ADDR, reg, val);
} }
static int axp_setbits(uint8_t reg, uint8_t set_mask) static int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask)
{ {
uint8_t regval; uint8_t regval;
int ret; int ret;
...@@ -127,11 +127,14 @@ static int axp_setbits(uint8_t reg, uint8_t set_mask) ...@@ -127,11 +127,14 @@ static int axp_setbits(uint8_t reg, uint8_t set_mask)
if (ret < 0) if (ret < 0)
return ret; return ret;
regval = ret | set_mask; regval = (ret & ~clr_mask) | set_mask;
return rsb_write(AXP803_RT_ADDR, reg, regval); return rsb_write(AXP803_RT_ADDR, reg, regval);
} }
#define axp_clrbits(reg, clr_mask) axp_clrsetbits(reg, clr_mask, 0)
#define axp_setbits(reg, set_mask) axp_clrsetbits(reg, 0, set_mask)
static bool should_enable_regulator(const void *fdt, int node) static bool should_enable_regulator(const void *fdt, int node)
{ {
if (fdt_getprop(fdt, node, "phandle", NULL) != NULL) if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
...@@ -226,8 +229,11 @@ static void setup_axp803_rails(const void *fdt) ...@@ -226,8 +229,11 @@ static void setup_axp803_rails(const void *fdt)
return; return;
} }
if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) {
axp_setbits(0x8f, BIT(4)); axp_clrbits(0x8f, BIT(4));
axp_setbits(0x30, BIT(2));
INFO("PMIC: AXP803: Enabling DRIVEVBUS\n");
}
/* descend into the "regulators" subnode */ /* descend into the "regulators" subnode */
node = fdt_first_subnode(fdt, node); node = fdt_first_subnode(fdt, node);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment