different array's for OMAP3 and OMAP4 and choose the right one
during run time.Newly added registers are updated at the bottom
of array.
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Adrian Hunter <adrian.hunter@nokia.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Madhusudhan Chikkature <madhu.cr@ti.com>
Signed-off-by: Kishore Kadiyala <kishore.kadiyala@ti.com>
---
arch/arm/mach-omap2/hsmmc.c | 6 +
arch/arm/plat-omap/include/plat/mmc.h | 76 ++++++++++
drivers/mmc/host/omap_hsmmc.c | 251 +++++++++++++++------------------
3 files changed, 198 insertions(+), 135 deletions(-)
@@ -266,6 +266,12 @@ void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
mmc->slots[0].internal_clock = !c->ext_clock;
mmc->dma_mask = 0xffffffff;
+ /* Register offset Mapping */
+ if (cpu_is_omap44xx())
+ mmc->regs_map = (u16 *) omap4_mmc_reg_map;
+ else
+ mmc->regs_map = (u16 *) omap3_mmc_reg_map;
+
mmc->get_context_loss_count = hsmmc_get_context_loss;
mmc->slots[0].switch_pin = c->gpio_cd;
@@ -53,6 +53,79 @@ struct mmc_dev_attr {
u8 flags;
};
+enum {
+ OMAP_HSMMC_SYSCONFIG = 0,
+ OMAP_HSMMC_SYSSTATUS,
+ OMAP_HSMMC_CON,
+ OMAP_HSMMC_BLK,
+ OMAP_HSMMC_ARG,
+ OMAP_HSMMC_CMD,
+ OMAP_HSMMC_RSP10,
+ OMAP_HSMMC_RSP32,
+ OMAP_HSMMC_RSP54,
+ OMAP_HSMMC_RSP76,
+ OMAP_HSMMC_DATA,
+ OMAP_HSMMC_PSTATE,
+ OMAP_HSMMC_HCTL,
+ OMAP_HSMMC_SYSCTL,
+ OMAP_HSMMC_STAT,
+ OMAP_HSMMC_IE,
+ OMAP_HSMMC_ISE,
+ OMAP_HSMMC_CAPA,
+ OMAP_HSMMC_CUR_CAPA,
+ OMAP_HSMMC_FE,
+ OMAP_HSMMC_ADMA_ES,
+ OMAP_HSMMC_ADMA_SAL,
+ OMAP_HSMMC_REV,
+};
+
+static const u16 omap3_mmc_reg_map[] = {
+ [OMAP_HSMMC_SYSCONFIG] = 0x0010,
+ [OMAP_HSMMC_SYSSTATUS] = 0x0014,
+ [OMAP_HSMMC_CON] = 0x002C,
+ [OMAP_HSMMC_BLK] = 0x0104,
+ [OMAP_HSMMC_ARG] = 0x0108,
+ [OMAP_HSMMC_CMD] = 0x010C,
+ [OMAP_HSMMC_RSP10] = 0x0110,
+ [OMAP_HSMMC_RSP32] = 0x0114,
+ [OMAP_HSMMC_RSP54] = 0x0118,
+ [OMAP_HSMMC_RSP76] = 0x011C,
+ [OMAP_HSMMC_DATA] = 0x0120,
+ [OMAP_HSMMC_PSTATE] = 0x0124,
+ [OMAP_HSMMC_HCTL] = 0x0128,
+ [OMAP_HSMMC_SYSCTL] = 0x012C,
+ [OMAP_HSMMC_STAT] = 0x0130,
+ [OMAP_HSMMC_IE] = 0x0134,
+ [OMAP_HSMMC_ISE] = 0x0138,
+ [OMAP_HSMMC_CAPA] = 0x0140,
+};
+
+static const u16 omap4_mmc_reg_map[] = {
+ [OMAP_HSMMC_SYSCONFIG] = 0x0110,
+ [OMAP_HSMMC_SYSSTATUS] = 0x0114,
+ [OMAP_HSMMC_CON] = 0x012C,
+ [OMAP_HSMMC_BLK] = 0x0204,
+ [OMAP_HSMMC_ARG] = 0x0208,
+ [OMAP_HSMMC_CMD] = 0x020C,
+ [OMAP_HSMMC_RSP10] = 0x0210,
+ [OMAP_HSMMC_RSP32] = 0x0214,
+ [OMAP_HSMMC_RSP54] = 0x0218,
+ [OMAP_HSMMC_RSP76] = 0x021C,
+ [OMAP_HSMMC_DATA] = 0x0220,
+ [OMAP_HSMMC_PSTATE] = 0x0224,
+ [OMAP_HSMMC_HCTL] = 0x0228,
+ [OMAP_HSMMC_SYSCTL] = 0x022C,
+ [OMAP_HSMMC_STAT] = 0x0230,
+ [OMAP_HSMMC_IE] = 0x0234,
+ [OMAP_HSMMC_ISE] = 0x0238,
+ [OMAP_HSMMC_CAPA] = 0x0240,
+ [OMAP_HSMMC_CUR_CAPA] = 0x0248,
+ [OMAP_HSMMC_FE] = 0x0250,
+ [OMAP_HSMMC_ADMA_ES] = 0x0254,
+ [OMAP_HSMMC_ADMA_SAL] = 0x0258,
+ [OMAP_HSMMC_REV] = 0x02FC,
+};
+
struct omap_mmc_platform_data {
/* back-link to device */
struct device *dev;
@@ -60,6 +133,9 @@ struct omap_mmc_platform_data {
/* number of slots per controller */
unsigned nr_slots:2;
+ /* Register Offset Map */
+ u16 *regs_map;
+
/* set if your board has components or wiring that limits the
* maximum frequency on the MMC bus */
unsigned int max_freq;
@@ -40,25 +40,6 @@
#include <plat/mmc.h>
#include <plat/cpu.h>
-/* OMAP HSMMC Host Controller Registers */
-#define OMAP_HSMMC_SYSCONFIG 0x0010
-#define OMAP_HSMMC_SYSSTATUS 0x0014
-#define OMAP_HSMMC_CON 0x002C
-#define OMAP_HSMMC_BLK 0x0104
-#define OMAP_HSMMC_ARG 0x0108
-#define OMAP_HSMMC_CMD 0x010C
-#define OMAP_HSMMC_RSP10 0x0110
-#define OMAP_HSMMC_RSP32 0x0114
-#define OMAP_HSMMC_RSP54 0x0118
-#define OMAP_HSMMC_RSP76 0x011C
-#define OMAP_HSMMC_DATA 0x0120
-#define OMAP_HSMMC_HCTL 0x0128
-#define OMAP_HSMMC_SYSCTL 0x012C
-#define OMAP_HSMMC_STAT 0x0130
-#define OMAP_HSMMC_IE 0x0134
-#define OMAP_HSMMC_ISE 0x0138
-#define OMAP_HSMMC_CAPA 0x0140
-
#define VS18 (1 << 26)
#define VS30 (1 << 25)
#define SDVS18 (0x5 << 9)
@@ -135,11 +116,11 @@
/*
* MMC Host controller read/write API's
*/
-#define OMAP_HSMMC_READ(base, reg) \
- __raw_readl((base) + OMAP_HSMMC_##reg)
+#define OMAP_HSMMC_READ(host, reg) \
+ __raw_readl((host->base) + (host->regs[OMAP_HSMMC_##reg]))
-#define OMAP_HSMMC_WRITE(base, reg, val) \
- __raw_writel((val), (base) + OMAP_HSMMC_##reg)
+#define OMAP_HSMMC_WRITE(host, reg, val) \
+ __raw_writel((val), (host->base) + (host->regs[OMAP_HSMMC_##reg]))
struct omap_hsmmc_host {
struct device *dev;
@@ -168,6 +149,7 @@ struct omap_hsmmc_host {
unsigned int dma_sg_idx;
unsigned char bus_mode;
unsigned char power_mode;
+ u16 *regs;
u32 *buffer;
u32 bytesleft;
int suspended;
@@ -519,9 +501,9 @@ static void omap_hsmmc_gpio_free(struct omap_mmc_platform_data *pdata)
*/
static void omap_hsmmc_stop_clock(struct omap_hsmmc_host *host)
{
- OMAP_HSMMC_WRITE(host->base, SYSCTL,
- OMAP_HSMMC_READ(host->base, SYSCTL) & ~CEN);
- if ((OMAP_HSMMC_READ(host->base, SYSCTL) & CEN) != 0x0)
+ OMAP_HSMMC_WRITE(host, SYSCTL,
+ OMAP_HSMMC_READ(host, SYSCTL) & ~CEN);
+ if ((OMAP_HSMMC_READ(host, SYSCTL) & CEN) != 0x0)
dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stoped\n");
}
@@ -534,16 +516,16 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host)
else
irq_mask = INT_EN_MASK;
- OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
- OMAP_HSMMC_WRITE(host->base, ISE, irq_mask);
- OMAP_HSMMC_WRITE(host->base, IE, irq_mask);
+ OMAP_HSMMC_WRITE(host, STAT, STAT_CLEAR);
+ OMAP_HSMMC_WRITE(host, ISE, irq_mask);
+ OMAP_HSMMC_WRITE(host, IE, irq_mask);
}
static void omap_hsmmc_disable_irq(struct omap_hsmmc_host *host)
{
- OMAP_HSMMC_WRITE(host->base, ISE, 0);
- OMAP_HSMMC_WRITE(host->base, IE, 0);
- OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
+ OMAP_HSMMC_WRITE(host, ISE, 0);
+ OMAP_HSMMC_WRITE(host, IE, 0);
+ OMAP_HSMMC_WRITE(host, STAT, STAT_CLEAR);
}
#ifdef CONFIG_PM
@@ -583,19 +565,19 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
/* Wait for hardware reset */
timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
- while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE
+ while ((OMAP_HSMMC_READ(host, SYSSTATUS) & RESETDONE) != RESETDONE
&& time_before(jiffies, timeout))
;
/* Do software reset */
- OMAP_HSMMC_WRITE(host->base, SYSCONFIG, SOFTRESET);
+ OMAP_HSMMC_WRITE(host, SYSCONFIG, SOFTRESET);
timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
- while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE
+ while ((OMAP_HSMMC_READ(host, SYSSTATUS) & RESETDONE) != RESETDONE
&& time_before(jiffies, timeout))
;
- OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
- OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
+ OMAP_HSMMC_WRITE(host, SYSCONFIG,
+ OMAP_HSMMC_READ(host, SYSCONFIG) | AUTOIDLE);
if (host->id == OMAP_MMC1_DEVID) {
if (host->power_mode != MMC_POWER_OFF &&
@@ -609,17 +591,17 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
capa = VS18;
}
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) | hctl);
+ OMAP_HSMMC_WRITE(host, HCTL,
+ OMAP_HSMMC_READ(host, HCTL) | hctl);
- OMAP_HSMMC_WRITE(host->base, CAPA,
- OMAP_HSMMC_READ(host->base, CAPA) | capa);
+ OMAP_HSMMC_WRITE(host, CAPA,
+ OMAP_HSMMC_READ(host, CAPA) | capa);
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+ OMAP_HSMMC_WRITE(host, HCTL,
+ OMAP_HSMMC_READ(host, HCTL) | SDBP);
timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
- while ((OMAP_HSMMC_READ(host->base, HCTL) & SDBP) != SDBP
+ while ((OMAP_HSMMC_READ(host, HCTL) & SDBP) != SDBP
&& time_before(jiffies, timeout))
;
@@ -629,20 +611,20 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
if (host->power_mode == MMC_POWER_OFF)
goto out;
- con = OMAP_HSMMC_READ(host->base, CON);
+ con = OMAP_HSMMC_READ(host, CON);
switch (ios->bus_width) {
case MMC_BUS_WIDTH_8:
- OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
+ OMAP_HSMMC_WRITE(host, CON, con | DW8);
break;
case MMC_BUS_WIDTH_4:
- OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
+ OMAP_HSMMC_WRITE(host, CON, con & ~DW8);
+ OMAP_HSMMC_WRITE(host, HCTL,
+ OMAP_HSMMC_READ(host, HCTL) | FOUR_BIT);
break;
case MMC_BUS_WIDTH_1:
- OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
+ OMAP_HSMMC_WRITE(host, CON, con & ~DW8);
+ OMAP_HSMMC_WRITE(host, HCTL,
+ OMAP_HSMMC_READ(host, HCTL) & ~FOUR_BIT);
break;
}
@@ -658,25 +640,23 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host)
dsor = 250;
}
- OMAP_HSMMC_WRITE(host->base, SYSCTL,
- OMAP_HSMMC_READ(host->base, SYSCTL) & ~CEN);
- OMAP_HSMMC_WRITE(host->base, SYSCTL, (dsor << 6) | (DTO << 16));
- OMAP_HSMMC_WRITE(host->base, SYSCTL,
- OMAP_HSMMC_READ(host->base, SYSCTL) | ICE);
+ OMAP_HSMMC_WRITE(host, SYSCTL, OMAP_HSMMC_READ(host, SYSCTL) & ~CEN);
+ OMAP_HSMMC_WRITE(host, SYSCTL, (dsor << 6) | (DTO << 16));
+ OMAP_HSMMC_WRITE(host, SYSCTL, OMAP_HSMMC_READ(host, SYSCTL) | ICE);
timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
- while ((OMAP_HSMMC_READ(host->base, SYSCTL) & ICS) != ICS
+ while ((OMAP_HSMMC_READ(host, SYSCTL) & ICS) != ICS
&& time_before(jiffies, timeout))
;
- OMAP_HSMMC_WRITE(host->base, SYSCTL,
- OMAP_HSMMC_READ(host->base, SYSCTL) | CEN);
+ OMAP_HSMMC_WRITE(host, SYSCTL,
+ OMAP_HSMMC_READ(host, SYSCTL) | CEN);
- con = OMAP_HSMMC_READ(host->base, CON);
+ con = OMAP_HSMMC_READ(host, CON);
if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
- OMAP_HSMMC_WRITE(host->base, CON, con | OD);
+ OMAP_HSMMC_WRITE(host, CON, con | OD);
else
- OMAP_HSMMC_WRITE(host->base, CON, con & ~OD);
+ OMAP_HSMMC_WRITE(host, CON, con & ~OD);
out:
host->context_loss = context_loss;
@@ -727,20 +707,20 @@ static void send_init_stream(struct omap_hsmmc_host *host)
disable_irq(host->irq);
- OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
- OMAP_HSMMC_WRITE(host->base, CON,
- OMAP_HSMMC_READ(host->base, CON) | INIT_STREAM);
- OMAP_HSMMC_WRITE(host->base, CMD, INIT_STREAM_CMD);
+ OMAP_HSMMC_WRITE(host, IE, INT_EN_MASK);
+ OMAP_HSMMC_WRITE(host, CON,
+ OMAP_HSMMC_READ(host, CON) | INIT_STREAM);
+ OMAP_HSMMC_WRITE(host, CMD, INIT_STREAM_CMD);
timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
while ((reg != CC) && time_before(jiffies, timeout))
- reg = OMAP_HSMMC_READ(host->base, STAT) & CC;
+ reg = OMAP_HSMMC_READ(host, STAT) & CC;
- OMAP_HSMMC_WRITE(host->base, CON,
- OMAP_HSMMC_READ(host->base, CON) & ~INIT_STREAM);
+ OMAP_HSMMC_WRITE(host, CON,
+ OMAP_HSMMC_READ(host, CON) & ~INIT_STREAM);
- OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
- OMAP_HSMMC_READ(host->base, STAT);
+ OMAP_HSMMC_WRITE(host, STAT, STAT_CLEAR);
+ OMAP_HSMMC_READ(host, STAT);
enable_irq(host->irq);
}
@@ -829,8 +809,8 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd,
host->req_in_progress = 1;
- OMAP_HSMMC_WRITE(host->base, ARG, cmd->arg);
- OMAP_HSMMC_WRITE(host->base, CMD, cmdreg);
+ OMAP_HSMMC_WRITE(host, ARG, cmd->arg);
+ OMAP_HSMMC_WRITE(host, CMD, cmdreg);
}
static int
@@ -904,13 +884,13 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd)
if (cmd->flags & MMC_RSP_PRESENT) {
if (cmd->flags & MMC_RSP_136) {
/* response type 2 */
- cmd->resp[3] = OMAP_HSMMC_READ(host->base, RSP10);
- cmd->resp[2] = OMAP_HSMMC_READ(host->base, RSP32);
- cmd->resp[1] = OMAP_HSMMC_READ(host->base, RSP54);
- cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP76);
+ cmd->resp[3] = OMAP_HSMMC_READ(host, RSP10);
+ cmd->resp[2] = OMAP_HSMMC_READ(host, RSP32);
+ cmd->resp[1] = OMAP_HSMMC_READ(host, RSP54);
+ cmd->resp[0] = OMAP_HSMMC_READ(host, RSP76);
} else {
/* response types 1, 1b, 3, 4, 5, 6 */
- cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10);
+ cmd->resp[0] = OMAP_HSMMC_READ(host, RSP10);
}
}
if ((host->data == NULL && !host->response_busy) || cmd->error)
@@ -983,14 +963,14 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host
*host,
unsigned long limit = (loops_per_jiffy *
msecs_to_jiffies(MMC_TIMEOUT_MS));
- OMAP_HSMMC_WRITE(host->base, SYSCTL,
- OMAP_HSMMC_READ(host->base, SYSCTL) | bit);
+ OMAP_HSMMC_WRITE(host, SYSCTL,
+ OMAP_HSMMC_READ(host, SYSCTL) | bit);
- while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) &&
+ while ((OMAP_HSMMC_READ(host, SYSCTL) & bit) &&
(i++ < limit))
cpu_relax();
- if (OMAP_HSMMC_READ(host->base, SYSCTL) & bit)
+ if (OMAP_HSMMC_READ(host, SYSCTL) & bit)
dev_err(mmc_dev(host->mmc),
"Timeout waiting on controller reset in %s\n",