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

allwinner: Scan AXP803 FDT node to setup initial power rails



Now that we have a pointer to the device tree blob, let's use that to
do some initial setup of the PMIC:
- We scan the DT for the compatible string to find the PMIC node.
- We switch the N_VBUSEN pin if the DT property tells us so.
- We scan over all regulator subnodes, and switch DC1SW if there is at
least one other node referencing it (judging by the existence of a
phandle property in that subnode).
This is just the first part of the setup, a follow up patch will setup
voltages.
Signed-off-by: default avatarAndre Przywara <andre.przywara@arm.com>
parent df301601
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <debug.h> #include <debug.h>
#include <delay_timer.h> #include <delay_timer.h>
#include <errno.h> #include <errno.h>
#include <libfdt.h>
#include <mmio.h> #include <mmio.h>
#include <platform_def.h> #include <platform_def.h>
#include <sunxi_def.h> #include <sunxi_def.h>
...@@ -126,6 +127,52 @@ static int axp_setbits(uint8_t reg, uint8_t set_mask) ...@@ -126,6 +127,52 @@ static int axp_setbits(uint8_t reg, uint8_t set_mask)
return rsb_write(AXP803_RT_ADDR, reg, regval); return rsb_write(AXP803_RT_ADDR, reg, regval);
} }
static bool should_enable_regulator(const void *fdt, int node)
{
if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
return true;
if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL)
return true;
return false;
}
static void setup_axp803_rails(const void *fdt)
{
int node;
/* locate the PMIC DT node, bail out if not found */
node = fdt_node_offset_by_compatible(fdt, -1, "x-powers,axp803");
if (node == -FDT_ERR_NOTFOUND) {
WARN("BL31: PMIC: No AXP803 DT node, skipping initial setup.\n");
return;
}
if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL))
axp_setbits(0x8f, BIT(4));
/* descend into the "regulators" subnode */
node = fdt_first_subnode(fdt, node);
/* iterate over all regulators to find used ones */
for (node = fdt_first_subnode(fdt, node);
node != -FDT_ERR_NOTFOUND;
node = fdt_next_subnode(fdt, node)) {
const char *name;
int length;
/* We only care if it's always on or referenced. */
if (!should_enable_regulator(fdt, node))
continue;
name = fdt_get_name(fdt, node, &length);
if (!strncmp(name, "dc1sw", length)) {
INFO("PMIC: AXP803: Enabling DC1SW\n");
axp_setbits(0x12, BIT(7));
continue;
}
}
}
int sunxi_pmic_setup(uint16_t socid, const void *fdt) int sunxi_pmic_setup(uint16_t socid, const void *fdt)
{ {
int ret; int ret;
...@@ -148,6 +195,9 @@ int sunxi_pmic_setup(uint16_t socid, const void *fdt) ...@@ -148,6 +195,9 @@ int sunxi_pmic_setup(uint16_t socid, const void *fdt)
pmic = AXP803_RSB; pmic = AXP803_RSB;
NOTICE("BL31: PMIC: Detected AXP803 on RSB.\n"); NOTICE("BL31: PMIC: Detected AXP803 on RSB.\n");
if (fdt)
setup_axp803_rails(fdt);
break; break;
default: default:
NOTICE("BL31: PMIC: No support for Allwinner %x SoC.\n", socid); NOTICE("BL31: PMIC: No support for Allwinner %x SoC.\n", socid);
......
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