#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
 int board_mmc_init(bd_t *bis)
 {
-       return omap_mmc_init(0);
+       return omap_mmc_init(0, 0, 0);
 }
 #endif
 
 
 {
        switch (omap_boot_device()) {
        case BOOT_DEVICE_MMC1:
-               omap_mmc_init(0);
+               omap_mmc_init(0, 0, 0);
                break;
        case BOOT_DEVICE_MMC2:
-               omap_mmc_init(1);
+               omap_mmc_init(1, 0, 0);
                break;
        }
        return 0;
 
 #define mmc_reg_out(addr, mask, val)\
        writel((readl(addr) & (~(mask))) | ((val) & (mask)), (addr))
 
-int omap_mmc_init(int dev_index);
+int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max);
 
 #endif /* MMC_HOST_DEF_H */
 
        unsigned int devconf0;          /* 0x274 */
        unsigned char res2[0x060];      /* 0x278 */
        unsigned int devconf1;          /* 0x2D8 */
-       unsigned char res3[0x244];      /* 0x2DC */
+       unsigned char res3[0x16C];      /* 0x2DC */
+       unsigned int ctl_prog_io1;      /* 0x448 */
+       unsigned char res4[0x0D4];      /* 0x44C */
        unsigned int pbias_lite;        /* 0x520 */
 } t2_t;
 
 #define PBIASSPEEDCTRL0                        (1 << 2)
 #define PBIASLITEPWRDNZ1               (1 << 9)
 
+#define CTLPROGIO1SPEEDCTRL            (1 << 20)
+
 /*
  * OMAP HSMMC register definitions
  */
 #define mmc_reg_out(addr, mask, val)\
        writel((readl(addr) & (~(mask))) | ((val) & (mask)), (addr))
 
-int omap_mmc_init(int dev_index);
+int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max);
 
 #endif /* MMC_HOST_DEF_H */
 
 #define mmc_reg_out(addr, mask, val)\
        writel((readl(addr) & (~(mask))) | ((val) & (mask)), (addr))
 
-int omap_mmc_init(int dev_index);
+int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max);
 
 #endif /* MMC_HOST_DEF_H */
 
 #define mmc_reg_out(addr, mask, val)\
        writel((readl(addr) & (~(mask))) | ((val) & (mask)), (addr))
 
-int omap_mmc_init(int dev_index);
+int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max);
 
 #endif /* MMC_HOST_DEF_H */
 
 #ifdef CONFIG_GENERIC_MMC
 int board_mmc_init(bd_t *bis)
 {
-       return omap_mmc_init(0);
+       return omap_mmc_init(0, 0, 0);
 }
 #endif
 
 
 #ifdef CONFIG_GENERIC_MMC
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
 #if defined(CONFIG_GENERIC_MMC) && !(defined(CONFIG_SPL_BUILD))
 int board_mmc_init(bd_t *bis)
 {
-       return omap_mmc_init(0);
+       return omap_mmc_init(0, 0, 0);
 }
 #endif
 
 
 #if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
 int board_mmc_init(bd_t *bis)
 {
-       return omap_mmc_init(0);
+       return omap_mmc_init(0, 0, 0);
 }
 #endif
 
 
 #ifdef CONFIG_GENERIC_MMC
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
 #ifdef CONFIG_GENERIC_MMC
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
 #if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
 #if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
 int board_mmc_init(bd_t *bis)
 {
-       return omap_mmc_init(0);
+       return omap_mmc_init(0, 0, 0);
 }
 #endif
 
 
 #ifdef CONFIG_GENERIC_MMC
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
 #ifdef CONFIG_GENERIC_MMC
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
 #ifdef CONFIG_GENERIC_MMC
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
-       omap_mmc_init(1);
+       omap_mmc_init(0, 0, 0);
+       omap_mmc_init(1, 0, 0);
        return 0;
 }
 #endif
 
 #if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
 #ifdef CONFIG_GENERIC_MMC
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
        !defined(CONFIG_SPL_BUILD)
 int board_mmc_init(bd_t *bis)
 {
-       return omap_mmc_init(0);
+       return omap_mmc_init(0, 0, 0);
 }
 #endif
 
 
        !defined(CONFIG_SPL_BUILD)
 int board_mmc_init(bd_t *bis)
 {
-       return omap_mmc_init(0);
+       return omap_mmc_init(0, 0, 0);
 }
 #endif
 
 #if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
 #if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
 #if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_GENERIC_MMC)
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
-       omap_mmc_init(1);
+       omap_mmc_init(0, 0, 0);
+       omap_mmc_init(1, 0, 0);
        return 0;
 }
 #endif
 
 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_GENERIC_MMC)
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
 #ifdef CONFIG_GENERIC_MMC
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_GENERIC_MMC)
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
-       omap_mmc_init(1);
+       omap_mmc_init(0, 0, 0);
+       omap_mmc_init(1, 0, 0);
        return 0;
 }
 #endif
 
 #if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
 int board_mmc_init(bd_t *bis)
 {
-       omap_mmc_init(0);
+       omap_mmc_init(0, 0, 0);
        return 0;
 }
 #endif
 
        writel(readl(&t2_base->devconf1) | MMCSDIO2ADPCLKISEL,
                &t2_base->devconf1);
 
+       /* Change from default of 52MHz to 26MHz if necessary */
+       if (!(mmc->host_caps & MMC_MODE_HS_52MHz))
+               writel(readl(&t2_base->ctl_prog_io1) & ~CTLPROGIO1SPEEDCTRL,
+                       &t2_base->ctl_prog_io1);
+
        writel(readl(&prcm_base->fclken1_core) |
                EN_MMC1 | EN_MMC2 | EN_MMC3,
                &prcm_base->fclken1_core);
        writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
 }
 
-int omap_mmc_init(int dev_index)
+int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max)
 {
        struct mmc *mmc;
 
                return 1;
        }
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
-       mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
-                               MMC_MODE_HC;
+       mmc->host_caps = (MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
+                               MMC_MODE_HC) & ~host_caps_mask;
 
        mmc->f_min = 400000;
-       mmc->f_max = 52000000;
+
+       if (f_max != 0)
+               mmc->f_max = f_max;
+       else {
+               if (mmc->host_caps & MMC_MODE_HS) {
+                       if (mmc->host_caps & MMC_MODE_HS_52MHz)
+                               mmc->f_max = 52000000;
+                       else
+                               mmc->f_max = 26000000;
+               } else
+                       mmc->f_max = 20000000;
+       }
 
        mmc->b_max = 0;