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;
 }

Reply via email to