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:
parent
a8c0545843
commit
29a4eb3acc
2 changed files with 36 additions and 39 deletions
|
@ -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"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue