divers: disk: stm32 sdmmc: Configure clock through device tree

Similarly to what was done in USB or RNG drivers, configure 48MHz domain
clock using device tree.
By default a freq clock check is enabled.

Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
This commit is contained in:
Erwan Gouriou 2023-01-18 15:16:33 +01:00 committed by Lauren Murphy
commit 29a4eb3acc
2 changed files with 36 additions and 39 deletions

View file

@ -72,6 +72,15 @@ config SDMMC_STM32_HWFC
Enable SDMMC Hardware Flow Control to avoid FIFO underrun (TX mode) and Enable SDMMC Hardware Flow Control to avoid FIFO underrun (TX mode) and
overrun (RX mode) errors. overrun (RX mode) errors.
config SDMMC_STM32_CLOCK_CHECK
bool "Runtime SDMMC 48MHz clock check"
depends on SDMMC_STM32
default y
help
Enable SDMMC clock 48MHz configuration runtime check.
In specific cases, this check might provide wrong verdict and should
be disabled.
module = SDMMC module = SDMMC
module-str = sdmmc module-str = sdmmc
source "subsys/logging/Kconfig.template.log_config" source "subsys/logging/Kconfig.template.log_config"

View file

@ -74,7 +74,7 @@ struct stm32_sdmmc_priv {
struct gpio_callback cd_cb; struct gpio_callback cd_cb;
struct gpio_dt_spec cd; struct gpio_dt_spec cd;
struct gpio_dt_spec pe; struct gpio_dt_spec pe;
struct stm32_pclken pclken; struct stm32_pclken *pclken;
const struct pinctrl_dev_config *pcfg; const struct pinctrl_dev_config *pcfg;
const struct reset_dt_spec reset; const struct reset_dt_spec reset;
@ -133,49 +133,37 @@ void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd)
static int stm32_sdmmc_clock_enable(struct stm32_sdmmc_priv *priv) static int stm32_sdmmc_clock_enable(struct stm32_sdmmc_priv *priv)
{ {
const struct device *clock; const struct device *clock;
int res;
#if CONFIG_SOC_SERIES_STM32L4X
LL_RCC_PLLSAI1_Disable();
/* Configure PLLSA11 to enable 48M domain */
LL_RCC_PLLSAI1_ConfigDomain_48M(LL_RCC_PLLSOURCE_HSI,
LL_RCC_PLLM_DIV_1,
8, LL_RCC_PLLSAI1Q_DIV_8);
/* Enable PLLSA1 */
LL_RCC_PLLSAI1_Enable();
/* Enable PLLSAI1 output mapped on 48MHz domain clock */
LL_RCC_PLLSAI1_EnableDomain_48M();
/* Wait for PLLSA1 ready flag */
while (LL_RCC_PLLSAI1_IsReady() != 1)
;
LL_RCC_SetSDMMCClockSource(LL_RCC_SDMMC1_CLKSOURCE_PLLSAI1);
#endif
#if defined(CONFIG_SOC_SERIES_STM32L5X) || \
defined(CONFIG_SOC_SERIES_STM32U5X)
#if !STM32_HSI48_ENABLED
/* Deprecated: enable HSI48 using device tree */
#warning USB device requires HSI48 clock to be enabled using device tree
/*
* Keeping this sequence for legacy :
* By default the SDMMC clock source is set to 0 --> 48MHz, must be enabled
*/
LL_RCC_HSI48_Enable();
while (!LL_RCC_HSI48_IsReady()) {
}
#endif /* !STM32_HSI48_ENABLED */
#endif /* CONFIG_SOC_SERIES_STM32L5X ||
* CONFIG_SOC_SERIES_STM32U5X
*/
/* HSI48 Clock is enabled through using the device tree */ /* HSI48 Clock is enabled through using the device tree */
clock = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); clock = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
if (DT_INST_NUM_CLOCKS(0) > 1) {
if (clock_control_configure(clock,
(clock_control_subsys_t *)&priv->pclken[1],
NULL) != 0) {
LOG_ERR("Failed to enable SDMMC domain clock");
return -EIO;
}
if (IS_ENABLED(CONFIG_SDMMC_STM32_CLOCK_CHECK)) {
uint32_t sdmmc_clock_rate;
if (clock_control_get_rate(clk,
(clock_control_subsys_t *)&pclken[1],
&sdmmc_clock_rate) != 0) {
LOG_ERR("Failed to get SDMMC domain clock rate");
return -EIO;
}
if (sdmmc_clock_rate != MHZ(48)) {
LOG_ERR("SDMMC Clock is not 48MHz (%d)", sdmmc_clock_rate);
return -ENOTSUP;
}
}
/* Enable the APB clock for stm32_sdmmc */ /* Enable the APB clock for stm32_sdmmc */
return clock_control_on(clock, (clock_control_subsys_t *)&priv->pclken); return clock_control_on(clock, (clock_control_subsys_t *)&priv->pclken[0]);
} }
static int stm32_sdmmc_clock_disable(struct stm32_sdmmc_priv *priv) static int stm32_sdmmc_clock_disable(struct stm32_sdmmc_priv *priv)