Index: /usr/src/sys/dev/mmc/mmc.c =================================================================== --- /usr/src/sys/dev/mmc/mmc.c (revision 263000) +++ /usr/src/sys/dev/mmc/mmc.c (working copy) @@ -1757,6 +1757,7 @@ static driver_t mmc_driver = { }; static devclass_t mmc_devclass; +DRIVER_MODULE(mmc, a10_mmc, mmc_driver, mmc_devclass, NULL, NULL); DRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, NULL, NULL); DRIVER_MODULE(mmc, sdhci_bcm, mmc_driver, mmc_devclass, NULL, NULL); DRIVER_MODULE(mmc, sdhci_fdt, mmc_driver, mmc_devclass, NULL, NULL); Index: sys/arm/allwinner/a10_clk.c =================================================================== --- sys/arm/allwinner/a10_clk.c (revision 263000) +++ sys/arm/allwinner/a10_clk.c (working copy) @@ -174,6 +174,43 @@ a10_clk_usb_deactivate(void) } int +a10_clk_mmc_activate(uint32_t *mod_clk) +{ + struct a10_ccm_softc *sc = a10_ccm_sc; + uint32_t reg_value; + uint32_t pll5_clk; + uint32_t divider; + uint32_t n, k, p; + + if (sc == NULL) + return ENXIO; + + /* Gating AHB clock for SDMMC0 */ + reg_value = ccm_read_4(sc, CCM_AHB_GATING0); + reg_value |= CCM_AHB_GATING_SDMMC0; + ccm_write_4(sc, CCM_AHB_GATING0, reg_value); + + /* Config mod clock */ + reg_value = ccm_read_4(sc, CCM_PLL5_CFG); + n = (reg_value >> 8) & 0x1f; + k = ((reg_value >> 4) & 3) + 1; + p = 1 << ((reg_value >> 16) & 3); + pll5_clk = 24000000 * n * k / p; + + if (pll5_clk > 400000000) + divider = 4; + else + divider = 3; + + ccm_write_4(sc, CCM_MMC0_SCLK_CFG, + CCM_MMC0_GATE_PASS | CCM_MMC0_CLK_SRC_PLL5 | divider); + + *mod_clk = pll5_clk / (divider + 1); + + return 0; +} + +int a10_clk_emac_activate(void) { struct a10_ccm_softc *sc = a10_ccm_sc; uint32_t reg_value; Index: sys/arm/allwinner/a10_clk.h =================================================================== --- sys/arm/allwinner/a10_clk.h (revision 263000) +++ sys/arm/allwinner/a10_clk.h (working copy) @@ -104,14 +104,20 @@ #define CCM_AHB_GATING_EHCI0 (1 << 1) #define CCM_AHB_GATING_EHCI1 (1 << 3) #define CCM_AHB_GATING_EMAC (1 << 17) +#define CCM_AHB_GATING_SDMMC0 (1 << 8) #define CCM_USB_PHY (1 << 8) #define CCM_USB0_RESET (1 << 0) #define CCM_USB1_RESET (1 << 1) #define CCM_USB2_RESET (1 << 2) +#define CCM_MMC0_CLK_SRC_PLL5 (2U << 24) +#define CCM_MMC0_GATE_MASK (0 << 31) +#define CCM_MMC0_GATE_PASS (1 << 31) + int a10_clk_usb_activate(void); int a10_clk_usb_deactivate(void); int a10_clk_emac_activate(void); +int a10_clk_mmc_activate(uint32_t *); #endif /* _A10_CLK_H_ */ Index: sys/arm/allwinner/files.a10 =================================================================== --- sys/arm/allwinner/files.a10 (revision 263000) +++ sys/arm/allwinner/files.a10 (working copy) @@ -21,3 +21,4 @@ arm/allwinner/if_emac.c optional emac arm/allwinner/timer.c standard arm/arm/bus_space-v6.c standard #arm/allwinner/console.c standard +arm/allwinner/a10_mmc.c optional mmc Index: sys/arm/conf/CUBIEBOARD =================================================================== --- sys/arm/conf/CUBIEBOARD (revision 263000) +++ sys/arm/conf/CUBIEBOARD (working copy) @@ -78,8 +78,8 @@ options WITNESS_SKIPSPIN #Don't run witness on sp #options BOOTP_WIRED_TO=cpsw0 # MMC/SD/SDIO card slot support -#device mmc # mmc/sd bus -#device mmcsd # mmc/sd flash cards +device mmc # mmc/sd bus +device mmcsd # mmc/sd flash cards # Boot device is 2nd slice on MMC/SD card options ROOTDEVNAME=\"ufs:/dev/da0s2\" Index: sys/boot/fdt/dts/arm/cubieboard.dts =================================================================== --- sys/boot/fdt/dts/arm/cubieboard.dts (revision 263000) +++ sys/boot/fdt/dts/arm/cubieboard.dts (working copy) @@ -138,6 +138,12 @@ interrupts = <55>; interrupt-parent = <&AINTC>; }; + mmc@0x01c0f000 { + compatible = "allwinner,sun4i-mmc"; + reg = <0x01c0f000 0x1000>; + interrupts = <32>; + interrupt-parent = <&AINTC>; + }; }; chosen {