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
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-str = sdmmc
source "subsys/logging/Kconfig.template.log_config"

View file

@ -74,7 +74,7 @@ struct stm32_sdmmc_priv {
struct gpio_callback cd_cb;
struct gpio_dt_spec cd;
struct gpio_dt_spec pe;
struct stm32_pclken pclken;
struct stm32_pclken *pclken;
const struct pinctrl_dev_config *pcfg;
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)
{
const struct device *clock;
#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
*/
int res;
/* HSI48 Clock is enabled through using the device tree */
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 */
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)