Hi, On SDHC version 3.0 controllers the divisor doesn't have to be a power of two, but can be a multiple of two. This means we can get a lot closer to the target clock.
E.g. to reach 400 kHz on a 200 MHz bus clock, the old mechanism would take 512 as divisor (== 390.612 kHz) while the new mechanism would use divisor 500 and reach exactly 400 kHz. ok? Patrick diff --git a/sys/dev/sdmmc/sdhc.c b/sys/dev/sdmmc/sdhc.c index 28923e22279..a2866b23ce5 100644 --- a/sys/dev/sdmmc/sdhc.c +++ b/sys/dev/sdmmc/sdhc.c @@ -635,15 +635,21 @@ sdhc_bus_power(sdmmc_chipset_handle_t sch, u_int32_t ocr) static int sdhc_clock_divisor(struct sdhc_host *hp, u_int freq) { - int max_div = SDHC_SDCLK_DIV_MAX; int div; - if (SDHC_SPEC_VERSION(hp->version) >= SDHC_SPEC_V3) - max_div = SDHC_SDCLK_DIV_MAX_V3; + if (SDHC_SPEC_VERSION(hp->version) >= SDHC_SPEC_V3) { + if (hp->clkbase <= freq) + return 0; + + for (div = 2; div <= SDHC_SDCLK_DIV_MAX_V3; div += 2) + if ((hp->clkbase / div) <= freq) + return (div / 2); + } else { + for (div = 1; div <= SDHC_SDCLK_DIV_MAX; div *= 2) + if ((hp->clkbase / div) <= freq) + return (div / 2); + } - for (div = 1; div <= max_div; div *= 2) - if ((hp->clkbase / div) <= freq) - return (div / 2); /* No divisor found. */ return -1; }