drivers: clock_control: More power supply modes for STM32H7

STM32H7 has different power supply modes but now Zephyr supports just LDO
and direct SMPS. This commit introduses POWER_SUPPLY_CHOICE configuration
parameter and add support for missed power supply modes.

Signed-off-by: Gennady Kovalev <gik@bigur.com>

Fixes #40730.
This commit is contained in:
Gennady Kovalev 2021-12-02 21:04:49 +03:00 committed by Christopher Friedt
commit b49766f001
3 changed files with 90 additions and 10 deletions

View file

@ -259,12 +259,28 @@ static uint32_t get_hclk_frequency(void)
static int32_t prepare_regulator_voltage_scale(void)
{
/* Make sure to put the CPU in highest Voltage scale during clock configuration */
#if defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS)
/* Apply system power supply configuration */
#if defined(SMPS) && defined(CONFIG_POWER_SUPPLY_DIRECT_SMPS)
LL_PWR_ConfigSupply(LL_PWR_DIRECT_SMPS_SUPPLY);
#elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_LDO)
LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_LDO);
#elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_LDO)
LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_LDO);
#elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT_AND_LDO)
LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO);
#elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT_AND_LDO)
LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_EXT_AND_LDO);
#elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT)
LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_EXT);
#elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT)
LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_EXT);
#elif defined(CONFIG_POWER_SUPPLY_EXTERNAL_SOURCE)
LL_PWR_ConfigSupply(LL_PWR_EXTERNAL_SOURCE_SUPPLY);
#else
LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
#endif
/* Make sure to put the CPU in highest Voltage scale during clock configuration */
/* Highest voltage is SCALE0 */
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0);
return 0;
@ -280,8 +296,22 @@ static int32_t optimize_regulator_voltage_scale(uint32_t sysclk_freq)
/* LL_PWR_REGULATOR_SCALE3 is lowest power consumption */
/* Must be done in accordance to the Maximum allowed frequency vs VOS*/
/* See RM0433 page 352 for more details */
#if defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS)
#if defined(SMPS) && defined(CONFIG_POWER_SUPPLY_DIRECT_SMPS)
LL_PWR_ConfigSupply(LL_PWR_DIRECT_SMPS_SUPPLY);
#elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_LDO)
LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_LDO);
#elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_LDO)
LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_LDO);
#elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT_AND_LDO)
LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO);
#elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT_AND_LDO)
LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_EXT_AND_LDO);
#elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT)
LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_EXT);
#elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT)
LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_EXT);
#elif defined(CONFIG_POWER_SUPPLY_EXTERNAL_SOURCE)
LL_PWR_ConfigSupply(LL_PWR_EXTERNAL_SOURCE_SUPPLY);
#else
LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
#endif

View file

@ -22,8 +22,36 @@ config USE_STM32_ASSERT
help
Enable asserts in STM32Cube HAL and LL drivers.
config POWER_SUPPLY_SMPS
bool "Enable STM32 internal SMPS"
choice POWER_SUPPLY_CHOICE
prompt "STM32 power supply configuration"
default POWER_SUPPLY_LDO
depends on SOC_SERIES_STM32H7X
help
Enable SMPS Power Supply.
config POWER_SUPPLY_LDO
bool "LDO supply"
config POWER_SUPPLY_DIRECT_SMPS
bool "Direct SMPS supply"
config POWER_SUPPLY_SMPS_1V8_SUPPLIES_LDO
bool "SMPS 1.8V supplies LDO (no external supply)"
config POWER_SUPPLY_SMPS_2V5_SUPPLIES_LDO
bool "SMPS 2.5V supplies LDO (no external supply)"
config POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT_AND_LDO
bool "External SMPS 1.8V supply, supplies LDO"
config POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT_AND_LDO
bool "External SMPS 2.5V supply, supplies LDO"
config POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT
bool "External SMPS 1.8V supply and bypass"
config POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT
bool "External SMPS 2.5V supply and bypass"
config POWER_SUPPLY_EXTERNAL_SOURCE
bool "Bypass"
endchoice

View file

@ -80,10 +80,32 @@ static int stm32h7_init(const struct device *arg)
SystemCoreClock = 64000000;
/* Power Configuration */
#if defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS)
LL_PWR_ConfigSupply(LL_PWR_DIRECT_SMPS_SUPPLY);
#elif defined(CONFIG_POWER_SUPPLY_SMPS)
#if !defined(SMPS) && \
(defined(CONFIG_POWER_SUPPLY_DIRECT_SMPS) || \
defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_LDO) || \
defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_LDO) || \
defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT_AND_LDO) || \
defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT_AND_LDO) || \
defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT) || \
defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT))
#error Unsupported configuration: Selected SoC do not support SMPS
#endif
#if defined(CONFIG_POWER_SUPPLY_DIRECT_SMPS)
LL_PWR_ConfigSupply(LL_PWR_DIRECT_SMPS_SUPPLY);
#elif defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_LDO)
LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_LDO);
#elif defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_LDO)
LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_LDO);
#elif defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT_AND_LDO)
LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO);
#elif defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT_AND_LDO)
LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_EXT_AND_LDO);
#elif defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT)
LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_EXT);
#elif defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT)
LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_EXT);
#elif defined(CONFIG_POWER_SUPPLY_EXTERNAL_SOURCE)
LL_PWR_ConfigSupply(LL_PWR_EXTERNAL_SOURCE_SUPPLY);
#else
LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
#endif