#include <linux/i2c/twl4030.h>
#include <mach/hardware.h>
+#include <mach/control.h>
#include <mach/mmc.h>
#include <mach/board.h>
#define VSEL_S2_CLR 0x40
#define GPIO_0_BIT_POS (1 << 0)
-#define OMAP2_CONTROL_DEVCONF0 0x48002274
-#define OMAP2_CONTROL_DEVCONF1 0x490022E8
-
-#define OMAP2_CONTROL_DEVCONF0_LBCLK (1 << 24)
-#define OMAP2_CONTROL_DEVCONF1_ACTOV (1 << 31)
-
-#define OMAP2_CONTROL_PBIAS_VMODE (1 << 0)
-#define OMAP2_CONTROL_PBIAS_PWRDNZ (1 << 1)
-#define OMAP2_CONTROL_PBIAS_SCTRL (1 << 2)
+static u16 control_pbias_offset;
+static struct hsmmc_controller {
+ u16 control_devconf_offset;
+ u32 devconf_loopback_clock;
+ int mmc1_cd_gpio;
+} hsmmc[] = {
+ {
+ .control_devconf_offset = OMAP2_CONTROL_DEVCONF0,
+ .devconf_loopback_clock = OMAP2_MMCSDIO1ADPCLKISEL,
+ },
+ {
+ /* control_devconf_offset set dynamically */
+ .devconf_loopback_clock = OMAP2_MMCSDIO2ADPCLKISEL,
+ },
+};
static const int mmc1_cd_gpio = OMAP_MAX_GPIO_LINES; /* HACK!! */
#endif
-static int hsmmc_set_power(struct device *dev, int slot, int power_on,
+static int hsmmc1_set_power(struct device *dev, int slot, int power_on,
int vdd)
{
- u32 vdd_sel = 0, devconf = 0, reg = 0;
+ u32 reg;
int ret = 0;
-
- /* REVISIT: Using address directly till the control.h defines
- * are settled.
- */
-#if defined(CONFIG_ARCH_OMAP2430)
- #define OMAP2_CONTROL_PBIAS 0x490024A0
-#else
- #define OMAP2_CONTROL_PBIAS 0x48002520
-#endif
+ u16 control_devconf_offset = hsmmc[0].control_devconf_offset;
if (power_on) {
- if (cpu_is_omap24xx())
- devconf = omap_readl(OMAP2_CONTROL_DEVCONF1);
- else
- devconf = omap_readl(OMAP2_CONTROL_DEVCONF0);
+ u32 vdd_sel = 0;
switch (1 << vdd) {
case MMC_VDD_33_34:
case MMC_VDD_32_33:
vdd_sel = VSEL_3V;
- if (cpu_is_omap24xx())
- devconf |= OMAP2_CONTROL_DEVCONF1_ACTOV;
break;
case MMC_VDD_165_195:
vdd_sel = VSEL_18V;
- if (cpu_is_omap24xx())
- devconf &= ~OMAP2_CONTROL_DEVCONF1_ACTOV;
}
- if (cpu_is_omap24xx())
- omap_writel(devconf, OMAP2_CONTROL_DEVCONF1);
- else
- omap_writel(devconf | OMAP2_CONTROL_DEVCONF0_LBCLK,
- OMAP2_CONTROL_DEVCONF0);
+ if (cpu_is_omap2430()) {
+ reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1);
+ if (vdd_sel == VSEL_3V)
+ reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE;
+ else
+ reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE;
+ omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1);
+ }
- reg = omap_readl(OMAP2_CONTROL_PBIAS);
- reg |= OMAP2_CONTROL_PBIAS_SCTRL;
- omap_writel(reg, OMAP2_CONTROL_PBIAS);
+ /* REVISIT: Loop back clock not needed for 2430? */
+ if (!cpu_is_omap2430()) {
+ reg = omap_ctrl_readl(control_devconf_offset);
+ reg |= OMAP2_MMCSDIO1ADPCLKISEL;
+ omap_ctrl_writel(reg, control_devconf_offset);
+ }
- reg = omap_readl(OMAP2_CONTROL_PBIAS);
- reg &= ~OMAP2_CONTROL_PBIAS_PWRDNZ;
- omap_writel(reg, OMAP2_CONTROL_PBIAS);
+ reg = omap_ctrl_readl(control_pbias_offset);
+ reg |= OMAP2_PBIASSPEEDCTRL0;
+ reg &= ~OMAP2_PBIASLITEPWRDNZ0;
+ omap_ctrl_writel(reg, control_pbias_offset);
ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
P1_DEV_GRP, VMMC1_DEV_GRP);
if (ret)
goto err;
+ /* 100ms delay required for PBIAS configuration */
msleep(100);
- reg = omap_readl(OMAP2_CONTROL_PBIAS);
- reg |= (OMAP2_CONTROL_PBIAS_SCTRL |
- OMAP2_CONTROL_PBIAS_PWRDNZ);
+
+ reg = omap_ctrl_readl(control_pbias_offset);
+ reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0);
if (vdd_sel == VSEL_18V)
- reg &= ~OMAP2_CONTROL_PBIAS_VMODE;
+ reg &= ~OMAP2_PBIASLITEVMODE0;
else
- reg |= OMAP2_CONTROL_PBIAS_VMODE;
- omap_writel(reg, OMAP2_CONTROL_PBIAS);
+ reg |= OMAP2_PBIASLITEVMODE0;
+ omap_ctrl_writel(reg, control_pbias_offset);
return ret;
/* Power OFF */
/* For MMC1, Toggle PBIAS before every power up sequence */
- reg = omap_readl(OMAP2_CONTROL_PBIAS);
- reg &= ~OMAP2_CONTROL_PBIAS_PWRDNZ;
- omap_writel(reg, OMAP2_CONTROL_PBIAS);
+ reg = omap_ctrl_readl(control_pbias_offset);
+ reg &= ~OMAP2_PBIASLITEPWRDNZ0;
+ omap_ctrl_writel(reg, control_pbias_offset);
ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
LDO_CLR, VMMC1_DEV_GRP);
/* 100ms delay required for PBIAS configuration */
msleep(100);
- reg = omap_readl(OMAP2_CONTROL_PBIAS);
- reg |= (OMAP2_CONTROL_PBIAS_VMODE |
- OMAP2_CONTROL_PBIAS_PWRDNZ |
- OMAP2_CONTROL_PBIAS_SCTRL);
- omap_writel(reg, OMAP2_CONTROL_PBIAS);
+
+ reg = omap_ctrl_readl(control_pbias_offset);
+ reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 |
+ OMAP2_PBIASLITEVMODE0);
+ omap_ctrl_writel(reg, control_pbias_offset);
}
return 0;
.dma_mask = 0xffffffff,
.slots[0] = {
.wire4 = 1,
- .set_power = hsmmc_set_power,
+ .set_power = hsmmc1_set_power,
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34 |
MMC_VDD_165_195,
.name = "first slot",
void __init hsmmc_init(void)
{
+ if (cpu_is_omap2430()) {
+ control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
+ hsmmc[1].control_devconf_offset = OMAP243X_CONTROL_DEVCONF1;
+ } else {
+ control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
+ hsmmc[1].control_devconf_offset = OMAP343X_CONTROL_DEVCONF1;
+ }
+
hsmmc_data[0] = &mmc1_data;
omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC);
}
#define OMAP243X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
#define OMAP243X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)
#define OMAP243X_CONTROL_IVA2_GEMCFG (OMAP2_CONTROL_GENERAL + 0x0198)
+#define OMAP243X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x0230)
/* 24xx-only CONTROL_GENERAL register offsets */
#define OMAP24XX_CONTROL_DEBOBS (OMAP2_CONTROL_GENERAL + 0x0000)
#define OMAP343X_CONTROL_FUSE_SR (OMAP2_CONTROL_GENERAL + 0x0130)
#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)
+#define OMAP343X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x02b0)
#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4)
/*
* and the security mode (secure, non-secure, don't care)
*/
/* CONTROL_DEVCONF0 bits */
+#define OMAP2_MMCSDIO1ADPCLKISEL (1 << 24) /* MMC1 loop back clock */
#define OMAP24XX_USBSTANDBYCTRL (1 << 15)
#define OMAP2_MCBSP2_CLKS_MASK (1 << 6)
#define OMAP2_MCBSP1_CLKS_MASK (1 << 2)
/* CONTROL_DEVCONF1 bits */
+#define OMAP243X_MMC1_ACTIVE_OVERWRITE (1 << 31)
+#define OMAP2_MMCSDIO2ADPCLKISEL (1 << 6) /* MMC2 loop back clock */
#define OMAP2_MCBSP5_CLKS_MASK (1 << 4) /* > 242x */
#define OMAP2_MCBSP4_CLKS_MASK (1 << 2) /* > 242x */
#define OMAP2_MCBSP3_CLKS_MASK (1 << 0) /* > 242x */
#define OMAP343X_SR1_SENPENABLE_MASK (0x3 << 0)
#define OMAP343X_SR1_SENPENABLE_SHIFT 0
+/* CONTROL_PBIAS_LITE bits */
+#define OMAP343X_PBIASLITESUPPLY_HIGH1 (1 << 15)
+#define OMAP343X_PBIASLITEVMODEERROR1 (1 << 11)
+#define OMAP343X_PBIASSPEEDCTRL1 (1 << 10)
+#define OMAP343X_PBIASLITEPWRDNZ1 (1 << 9)
+#define OMAP343X_PBIASLITEVMODE1 (1 << 8)
+#define OMAP343X_PBIASLITESUPPLY_HIGH0 (1 << 7)
+#define OMAP343X_PBIASLITEVMODEERROR0 (1 << 3)
+#define OMAP2_PBIASSPEEDCTRL0 (1 << 2)
+#define OMAP2_PBIASLITEPWRDNZ0 (1 << 1)
+#define OMAP2_PBIASLITEVMODE0 (1 << 0)
+
#ifndef __ASSEMBLY__
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
extern void __iomem *omap_ctrl_base_get(void);