summaryrefslogtreecommitdiff
path: root/drivers/mmc/omap_hsmmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/omap_hsmmc.c')
-rw-r--r--drivers/mmc/omap_hsmmc.c61
1 files changed, 55 insertions, 6 deletions
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index f2a7a78..afd9b30 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -29,6 +29,7 @@
#include <i2c.h>
#include <twl4030.h>
#include <twl6030.h>
+#include <twl6035.h>
#include <asm/io.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/sys_proto.h>
@@ -49,8 +50,8 @@ static struct mmc hsmmc_dev[2];
static void omap4_vmmc_pbias_config(struct mmc *mmc)
{
u32 value = 0;
- struct omap4_sys_ctrl_regs *const ctrl =
- (struct omap4_sys_ctrl_regs *)SYSCTRL_GENERAL_CORE_BASE;
+ struct omap_sys_ctrl_regs *const ctrl =
+ (struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE;
value = readl(&ctrl->control_pbiaslite);
@@ -64,6 +65,34 @@ static void omap4_vmmc_pbias_config(struct mmc *mmc)
}
#endif
+#if defined(CONFIG_OMAP54XX) && defined(CONFIG_TWL6035_POWER)
+static void omap5_pbias_config(struct mmc *mmc)
+{
+ u32 value = 0;
+ struct omap_sys_ctrl_regs *const ctrl =
+ (struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE;
+
+ value = readl(&ctrl->control_pbias);
+ value &= ~(SDCARD_PWRDNZ | SDCARD_BIAS_PWRDNZ);
+ value |= SDCARD_BIAS_HIZ_MODE;
+ writel(value, &ctrl->control_pbias);
+
+ twl6035_mmc1_poweron_ldo();
+
+ value = readl(&ctrl->control_pbias);
+ value &= ~SDCARD_BIAS_HIZ_MODE;
+ value |= SDCARD_PBIASLITE_VMODE | SDCARD_PWRDNZ | SDCARD_BIAS_PWRDNZ;
+ writel(value, &ctrl->control_pbias);
+
+ value = readl(&ctrl->control_pbias);
+ if (value & (1 << 23)) {
+ value &= ~(SDCARD_PWRDNZ | SDCARD_BIAS_PWRDNZ);
+ value |= SDCARD_BIAS_HIZ_MODE;
+ writel(value, &ctrl->control_pbias);
+ }
+}
+#endif
+
unsigned char mmc_board_init(struct mmc *mmc)
{
#if defined(CONFIG_OMAP34XX)
@@ -90,6 +119,11 @@ unsigned char mmc_board_init(struct mmc *mmc)
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);
@@ -104,6 +138,10 @@ unsigned char mmc_board_init(struct mmc *mmc)
if (mmc->block_dev.dev == 0)
omap4_vmmc_pbias_config(mmc);
#endif
+#if defined(CONFIG_OMAP54XX) && defined(CONFIG_TWL6035_POWER)
+ if (mmc->block_dev.dev == 0)
+ omap5_pbias_config(mmc);
+#endif
return 0;
}
@@ -502,7 +540,7 @@ static void mmc_set_ios(struct mmc *mmc)
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;
@@ -533,11 +571,22 @@ int omap_mmc_init(int dev_index)
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;