mmc: stm32_sdmmc2: manage max-frequency property from DT
authorYann Gautier <yann.gautier@st.com>
Tue, 28 May 2019 09:54:50 +0000 (11:54 +0200)
committerYann Gautier <yann.gautier@st.com>
Mon, 2 Sep 2019 15:53:14 +0000 (17:53 +0200)
If the max-frequency property is provided in the device tree mmc node,
it should be managed. The max allowed frequency will be the min between
this property value and what the card can support.

Change-Id: I885b676c3300d2670a0fe4c6ecab87758b5893ad
Signed-off-by: Yann Gautier <yann.gautier@st.com>
drivers/st/mmc/stm32_sdmmc2.c
include/drivers/st/stm32_sdmmc2.h

index f453ce9a5788c604f361863b32a096e3a51705c7..1be88502dd484c79c41847c9bf4d8c2e0af259d4 100644 (file)
@@ -152,10 +152,14 @@ bool plat_sdmmc2_use_dma(unsigned int instance, unsigned int memory)
 static void stm32_sdmmc2_init(void)
 {
        uint32_t clock_div;
+       uint32_t freq = STM32MP_MMC_INIT_FREQ;
        uintptr_t base = sdmmc2_params.reg_base;
 
-       clock_div = div_round_up(sdmmc2_params.clk_rate,
-                                STM32MP_MMC_INIT_FREQ * 2);
+       if (sdmmc2_params.max_freq != 0U) {
+               freq = MIN(sdmmc2_params.max_freq, freq);
+       }
+
+       clock_div = div_round_up(sdmmc2_params.clk_rate, freq * 2U);
 
        mmio_write_32(base + SDMMC_CLKCR, SDMMC_CLKCR_HWFC_EN | clock_div |
                      sdmmc2_params.negedge |
@@ -406,7 +410,7 @@ static int stm32_sdmmc2_set_ios(unsigned int clk, unsigned int width)
 {
        uintptr_t base = sdmmc2_params.reg_base;
        uint32_t bus_cfg = 0;
-       uint32_t clock_div, max_freq;
+       uint32_t clock_div, max_freq, freq;
        uint32_t clk_rate = sdmmc2_params.clk_rate;
        uint32_t max_bus_freq = sdmmc2_params.device_info->max_bus_freq;
 
@@ -438,7 +442,13 @@ static int stm32_sdmmc2_set_ios(unsigned int clk, unsigned int width)
                }
        }
 
-       clock_div = div_round_up(clk_rate, max_freq * 2);
+       if (sdmmc2_params.max_freq != 0U) {
+               freq = MIN(sdmmc2_params.max_freq, max_freq);
+       } else {
+               freq = max_freq;
+       }
+
+       clock_div = div_round_up(clk_rate, freq * 2U);
 
        mmio_write_32(base + SDMMC_CLKCR,
                      SDMMC_CLKCR_HWFC_EN | clock_div | bus_cfg |
@@ -692,6 +702,11 @@ static int stm32_sdmmc2_dt_get_config(void)
                }
        }
 
+       cuint = fdt_getprop(fdt, sdmmc_node, "max-frequency", NULL);
+       if (cuint != NULL) {
+               sdmmc2_params.max_freq = fdt32_to_cpu(*cuint);
+       }
+
        return 0;
 }
 
index aa9472c8303d7f92e9fa9518a5610d08c3fdc419..4853208c2bed7e4d3b744d3883d71bc8a82aebfd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,7 @@ struct stm32_sdmmc2_params {
        unsigned int            dirpol;
        unsigned int            clock_id;
        unsigned int            reset_id;
+       unsigned int            max_freq;
        bool                    use_dma;
 };