diff --git a/core/arch/arm/plat-stm32mp1/conf.mk b/core/arch/arm/plat-stm32mp1/conf.mk index 29f666ba362..dada6e6d114 100644 --- a/core/arch/arm/plat-stm32mp1/conf.mk +++ b/core/arch/arm/plat-stm32mp1/conf.mk @@ -114,9 +114,9 @@ $(call force,CFG_SECONDARY_INIT_CNTFRQ,n) $(call force,CFG_STM32_GPIO,y) $(call force,CFG_STM32_VREFBUF,y) $(call force,CFG_STM32MP_CLK_CORE,y) -$(call force,CFG_STM32MP1_REGULATOR_IOD,y) $(call force,CFG_STM32MP1_SHARED_RESOURCES,n) $(call force,CFG_STM32MP13_CLK,y) +$(call force,CFG_STM32MP13_REGULATOR_IOD,y) $(call force,CFG_TEE_CORE_NB_CORE,1) $(call force,CFG_WITH_NSEC_GPIOS,n) CFG_EXTERNAL_DT ?= n diff --git a/core/drivers/regulator/stm32mp1_regulator_iod.c b/core/drivers/regulator/stm32mp1_regulator_iod.c deleted file mode 100644 index b9e637a08c0..00000000000 --- a/core/drivers/regulator/stm32mp1_regulator_iod.c +++ /dev/null @@ -1,296 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - * Copyright (c) 2021-2023, STMicroelectronics - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TIMEOUT_US_10MS U(10000) - -#define IO_VOLTAGE_THRESHOLD_UV 2700000 - -/* - * struct iod_regul - IO domain regulator instance - * - * @enable_reg: PWR register offset for the IO domain - * @enable_mask: Domain enable register bit mask in PWR register - * @ready_mask: Domain ready bit mask in PWR register - * @valid_mask: Domain valid bit mask in PWR register - * @hslv_id: ID of the related HSLV domain - * @io_comp_id: ID of the related IO compensation domain - * @suspend_state: True if regulator is enabled before suspend, false otherwise - * @suspend_level_uv: Voltage level before suspend, in microvolts - */ -struct iod_regul { - uint32_t enable_reg; - uint32_t enable_mask; - uint32_t ready_mask; - uint32_t valid_mask; - enum stm32mp13_hslv_id hslv_id; - enum stm32mp13_vddsd_comp_id io_comp_id; - bool suspend_state; - int suspend_level_uv; -}; - -static struct iod_regul iod_regulator_priv[IOD_REGU_COUNT] = { - [IOD_SDMMC1] = { - .enable_reg = PWR_CR3_OFF, - .enable_mask = PWR_CR3_VDDSD1EN, - .ready_mask = PWR_CR3_VDDSD1RDY, - .valid_mask = PWR_CR3_VDDSD1VALID, - .hslv_id = SYSCFG_HSLV_IDX_SDMMC1, - .io_comp_id = SYSCFG_IO_COMP_IDX_SD1, - }, - [IOD_SDMMC2] = { - .enable_reg = PWR_CR3_OFF, - .enable_mask = PWR_CR3_VDDSD2EN, - .ready_mask = PWR_CR3_VDDSD2RDY, - .valid_mask = PWR_CR3_VDDSD2VALID, - .hslv_id = SYSCFG_HSLV_IDX_SDMMC2, - .io_comp_id = SYSCFG_IO_COMP_IDX_SD2, - }, -}; - -static struct regulator *iod_regulator[IOD_REGU_COUNT]; - -struct regulator *stm32mp1_get_iod_regulator(enum iod_regulator_id index) -{ - assert(index >= IOD_SDMMC1 && index < IOD_REGU_COUNT); - - return iod_regulator[index]; -} - -static TEE_Result iod_set_state(struct regulator *regu, bool enable) -{ - struct iod_regul *iod = regu->priv; - uintptr_t pwr_reg = stm32_pwr_base() + iod->enable_reg; - - FMSG("%s: set state %u", regulator_name(regu), enable); - - if (enable) { - uint32_t value = 0; - - io_setbits32(pwr_reg, iod->enable_mask); - - if (IO_READ32_POLL_TIMEOUT(pwr_reg, value, - value & iod->ready_mask, - 0, TIMEOUT_US_10MS)) - return TEE_ERROR_GENERIC; - - io_setbits32(pwr_reg, iod->valid_mask); - io_clrbits32(pwr_reg, iod->enable_mask); - - stm32mp_set_vddsd_comp_state(iod->io_comp_id, true); - } else { - stm32mp_set_vddsd_comp_state(iod->io_comp_id, false); - - io_clrbits32(pwr_reg, iod->enable_mask | iod->valid_mask); - } - - return TEE_SUCCESS; -} - -static TEE_Result iod_get_state(struct regulator *regu, bool *enabled) -{ - struct iod_regul *iod = regu->priv; - uintptr_t pwr_reg = stm32_pwr_base() + iod->enable_reg; - - *enabled = io_read32(pwr_reg) & (iod->enable_mask | iod->valid_mask); - - return TEE_SUCCESS; -} - -static TEE_Result iod_get_voltage(struct regulator *regu, int *level_uv) -{ - *level_uv = regulator_get_voltage(regu->supply); - - return TEE_SUCCESS; -} - -static TEE_Result iod_set_voltage(struct regulator *regu, int level_uv) -{ - struct iod_regul *iod = regu->priv; - TEE_Result res = TEE_ERROR_GENERIC; - bool iod_enabled = false; - - FMSG("%s: set voltage level to %duV", regulator_name(regu), level_uv); - - res = iod_get_state(regu, &iod_enabled); - if (res) - return res; - - /* Isolate IOs and disable IOs compensation when changing voltage */ - if (iod_enabled) { - res = iod_set_state(regu, false); - if (res) - return res; - } - - /* - * Set IO to low speed. - * Setting high voltage with IOs in high speed mode may damage the IOs. - */ - stm32mp_set_hslv_state(iod->hslv_id, false); - - /* Forward set voltage request to the power supply */ - res = regulator_set_voltage(regu->supply, level_uv); - if (res) { - EMSG("regulator %s set voltage failed: %#"PRIx32, - regulator_name(regu), res); - - /* Ensure IO domain consistency for current voltage level */ - level_uv = regulator_get_voltage(regu->supply); - } - - if (level_uv <= IO_VOLTAGE_THRESHOLD_UV) - stm32mp_set_hslv_state(iod->hslv_id, true); - - if (iod_enabled) { - TEE_Result res2 = TEE_ERROR_GENERIC; - - res2 = iod_set_state(regu, true); - if (res2) - return res2; - } - - return res; -} - -static TEE_Result iod_list_voltages(struct regulator *regu, - struct regulator_voltages **voltages) -{ - /* Return supply voltage list */ - return regulator_supported_voltages(regu->supply, voltages); -} - -/* - * To protect the IOs, we disable High Speed Low Voltage mode before - * entering suspend state and restore the configuration when resuming. - */ -static TEE_Result iod_pm(enum pm_op op, unsigned int pm_hint __unused, - const struct pm_callback_handle *hdl) -{ - struct regulator *regu = hdl->handle; - struct iod_regul *iod = regu->priv; - TEE_Result res = TEE_ERROR_GENERIC; - - assert(op == PM_OP_SUSPEND || op == PM_OP_RESUME); - - if (op == PM_OP_SUSPEND) { - FMSG("%s: suspend", regulator_name(regu)); - - res = iod_get_state(regu, &iod->suspend_state); - if (res) - return res; - - res = iod_get_voltage(regu, &iod->suspend_level_uv); - if (res) - return res; - - stm32mp_set_hslv_state(iod->hslv_id, false); - } else { - FMSG("%s: resume", regulator_name(regu)); - - res = iod_set_voltage(regu, iod->suspend_level_uv); - if (res) - return res; - - res = iod_set_state(regu, iod->suspend_state); - if (res) - return res; - } - - return TEE_SUCCESS; -} - -static TEE_Result iod_supplied_init(struct regulator *regu, - const void *fdt __unused, int node __unused) -{ - struct iod_regul *iod = regu->priv; - int index = iod - iod_regulator_priv; - - assert(index >= 0 && index < IOD_REGU_COUNT); - - if (regulator_get_voltage(regu) < IO_VOLTAGE_THRESHOLD_UV) - stm32mp_set_hslv_state(iod->hslv_id, true); - - /* Save regulator reference */ - iod_regulator[index] = regu; - - register_pm_driver_cb(iod_pm, regu, "iod-regulator"); - - FMSG("IOD regulator %s intiialized", regulator_name(regu)); - - return TEE_SUCCESS; -} - -static const struct regulator_ops iod_ops = { - .set_state = iod_set_state, - .get_state = iod_get_state, - .set_voltage = iod_set_voltage, - .get_voltage = iod_get_voltage, - .supported_voltages = iod_list_voltages, - .supplied_init = iod_supplied_init, -}; - -#define DEFINE_REG(_id, _name, _supply_name) { \ - .name = (_name), \ - .ops = &iod_ops, \ - .priv = iod_regulator_priv + (_id), \ - .supply_name = (_supply_name), \ -} - -static struct regu_dt_desc iod_regul_desc[IOD_REGU_COUNT] = { - [IOD_SDMMC1] = DEFINE_REG(IOD_SDMMC1, "sdmmc1_io", "vddsd1"), - [IOD_SDMMC2] = DEFINE_REG(IOD_SDMMC2, "sdmmc2_io", "vddsd2"), -}; - -static TEE_Result iod_regulator_probe(const void *fdt, int node, - const void *compat_data __unused) -{ - const char *node_name = NULL; - size_t i = 0; - - node_name = fdt_get_name(fdt, node, NULL); - - FMSG("iod probe node '%s'", node_name); - - /* Look up matching regulator name defined in SoC DTSI file */ - for (i = 0; i < IOD_REGU_COUNT; i++) - if (!strcmp(iod_regul_desc[i].name, node_name)) - break; - - if (i == IOD_REGU_COUNT) { - EMSG("Unexpected IO domain node name '%s'", node_name); - return TEE_ERROR_GENERIC; - } - - return regulator_dt_register(fdt, node, node, iod_regul_desc + i); -} - -static const struct dt_device_match iod_regulator_match_table[] = { - { .compatible = "st,stm32mp13-iod" }, - { } -}; - -DEFINE_DT_DRIVER(stm32mp1_regulator_iod_dt_driver) = { - .name = "stm32mp13-iod-regulator", - .match_table = iod_regulator_match_table, - .probe = iod_regulator_probe, -}; diff --git a/core/drivers/regulator/sub.mk b/core/drivers/regulator/sub.mk index ce4608cdc8e..82d839a436c 100644 --- a/core/drivers/regulator/sub.mk +++ b/core/drivers/regulator/sub.mk @@ -3,4 +3,4 @@ srcs-$(CFG_DT) += regulator_dt.c srcs-$(CFG_REGULATOR_FIXED) += regulator_fixed.c srcs-$(CFG_REGULATOR_GPIO) += regulator_gpio.c srcs-$(CFG_STM32_VREFBUF) += stm32_vrefbuf.c -srcs-$(CFG_STM32MP1_REGULATOR_IOD) += stm32mp1_regulator_iod.c +srcs-$(CFG_STM32MP13_REGULATOR_IOD) += stm32mp13_regulator_iod.c diff --git a/core/include/drivers/stm32mp1_regulator_iod.h b/core/include/drivers/stm32mp1_regulator_iod.h index d45917d42eb..9cd70e37235 100644 --- a/core/include/drivers/stm32mp1_regulator_iod.h +++ b/core/include/drivers/stm32mp1_regulator_iod.h @@ -3,8 +3,8 @@ * Copyright (c) 2021-2023, STMicroelectronics */ -#ifndef __DRIVERS_STM32MP1_REGULATOR_IOD_H -#define __DRIVERS_STM32MP1_REGULATOR_IOD_H +#ifndef __DRIVERS_STM32MP13_REGULATOR_IOD_H +#define __DRIVERS_STM32MP13_REGULATOR_IOD_H #include @@ -14,10 +14,10 @@ enum iod_regulator_id { IOD_REGU_COUNT }; -#ifdef CFG_STM32MP1_REGULATOR_IOD +#ifdef CFG_STM32MP13_REGULATOR_IOD struct regulator *stm32mp1_get_iod_regulator(enum iod_regulator_id index); #else static inline struct regulator * stm32mp1_get_iod_regulator(enum iod_regulator_id id __unused) { return NULL; } -#endif /* CFG_STM32MP1_REGULATOR_IOD */ -#endif /* __DRIVERS_STM32MP1_REGULATOR_IOD_H */ +#endif /* CFG_STM32MP13_REGULATOR_IOD */ +#endif /* __DRIVERS_STM32MP13_REGULATOR_IOD_H */