diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c index b2bb482f9d626bbb23b1e8c17c9e5b60ae3703bd..371cb80fccc8d924e2ad030c0a966044e1e9760f 100644 --- a/drivers/st/pmic/stm32mp_pmic.c +++ b/drivers/st/pmic/stm32mp_pmic.c @@ -245,6 +245,62 @@ static void register_pmic_shared_peripherals(void) } } +static int pmic_regulator_enable(struct stm32mp_regulator *regu) +{ + void *fdt; + const char *node_name; + + if (fdt_get_address(&fdt) == 0) { + return -ENOENT; + } + + node_name = fdt_get_name(fdt, fdt_node_offset_by_phandle(fdt, regu->id), + NULL); + + return stpmic1_regulator_enable(node_name); +} + +static int pmic_regulator_disable(struct stm32mp_regulator *regu) +{ + void *fdt; + const char *node_name; + + if (fdt_get_address(&fdt) == 0) { + return -ENOENT; + } + + node_name = fdt_get_name(fdt, fdt_node_offset_by_phandle(fdt, regu->id), + NULL); + + return stpmic1_regulator_disable(node_name); +} + +static const struct stm32mp_regulator_ops pmic_regu_ops = { + .enable = pmic_regulator_enable, + .disable = pmic_regulator_disable, +}; + +bool is_pmic_regulator(struct stm32mp_regulator *regu) +{ + void *fdt; + int parent_node; + + if (fdt_get_address(&fdt) == 0) { + return false; + } + + parent_node = fdt_parent_offset(fdt, + fdt_node_offset_by_phandle(fdt, + regu->id)); + return (fdt_node_check_compatible(fdt, parent_node, + "st,stpmic1-regulators") == 0); +} + +void bind_pmic_regulator(struct stm32mp_regulator *regu) +{ + regu->ops = &pmic_regu_ops; +} + void initialize_pmic(void) { unsigned long pmic_version; diff --git a/include/drivers/st/stm32mp_pmic.h b/include/drivers/st/stm32mp_pmic.h index 984cd60143cda0bcc2b1fc370a5341b55df4fdf1..57475c09385a1ead4c7088d40cf2d444bc579929 100644 --- a/include/drivers/st/stm32mp_pmic.h +++ b/include/drivers/st/stm32mp_pmic.h @@ -11,6 +11,8 @@ #include <platform_def.h> +#include <drivers/st/stm32mp_regulator.h> + /* * dt_pmic_status - Check PMIC status from device tree * @@ -41,6 +43,9 @@ bool initialize_pmic_i2c(void); */ void initialize_pmic(void); +bool is_pmic_regulator(struct stm32mp_regulator *regu); +void bind_pmic_regulator(struct stm32mp_regulator *regu); + /* * pmic_ddr_power_init - Initialize regulators required for DDR * diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index c9b71cc2b77ea2edaa6a4edfb6f72c918a35eb69..db54e6c0af540d9e72f1b7b8afc71516dd94297c 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -11,6 +11,8 @@ #include <platform_def.h> #include <drivers/st/stm32_iwdg.h> +#include <drivers/st/stm32mp_pmic.h> +#include <drivers/st/stm32mp_regulator.h> #include <lib/xlat_tables/xlat_tables_v2.h> /* Internal layout of the 32bit OTP word board_id */ @@ -505,6 +507,15 @@ uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags) } #endif +int plat_bind_regulator(struct stm32mp_regulator *regu) +{ + if ((dt_pmic_status() > 0) && is_pmic_regulator(regu)) { + bind_pmic_regulator(regu); + } + + return 0; +} + /* Get the non-secure DDR size */ uint32_t stm32mp_get_ddr_ns_size(void) {