[PATCH 1/3] mmc: msm_sdhci: Fix incorrect divider calculation for SDCLK

Sumit Garg sumit.garg at kernel.org
Fri Dec 12 01:59:56 CET 2025


On Wed, Dec 10, 2025 at 04:54:52PM +0100, Loic Poulain wrote:
> When 'max-clk' is not specified, the SDHCI core retrieves the base clock
> from the SDHCI_CAPABILITIES register (bits [15:8]). However, this field
> is unreliable on MSM SDHCI controllers, as noted by the Linux driver
> using the SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN flag. In addition, the field
> is only 8 bits wide and cannot represent base clocks above 255 MHz.
> 
> On platforms like Agatti/QCM2290, the firmware sets the SDHCI clock to
> 384 MHz, but the capabilities register reports 200 MHz. As a result,
> the core calculates a divider of 4, producing a 96 MHz SDCLK instead of
> the intended ~52 MHz. This overclocking can cause sporadic CRC errors
> with certain eMMC.
> 
> To fix this, use the actual clock rate reported by the SDHCI core clock
> instead of relying on the capabilities register for divider calculation.
> 
> Signed-off-by: Loic Poulain <loic.poulain at oss.qualcomm.com>
> ---
>  drivers/mmc/msm_sdhci.c | 3 +++
>  1 file changed, 3 insertions(+)

Reviewed-by: Sumit Garg <sumit.garg at oss.qualcomm.com>

-Sumit

> 
> diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c
> index ac77fb06bf7..ec003991928 100644
> --- a/drivers/mmc/msm_sdhci.c
> +++ b/drivers/mmc/msm_sdhci.c
> @@ -114,6 +114,9 @@ static int msm_sdc_clk_init(struct udevice *dev)
>  		return -EINVAL;
>  	}
>  
> +	/* This is the base clock sdhci core will use to configure the SDCLK */
> +	prv->host.max_clk = clk_rate;
> +
>  	writel_relaxed(CORE_VENDOR_SPEC_POR_VAL,
>  		       prv->host.ioaddr + var_info->core_vendor_spec);
>  
> -- 
> 2.34.1
> 


More information about the U-Boot mailing list