summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorIan Wisbon <ian.wisbon@timesys.com>2011-02-14 16:41:03 -0500
committerIan Wisbon <ian.wisbon@timesys.com>2011-02-14 16:41:03 -0500
commit8a83780a187ba1961380814eaf9c503043345d12 (patch)
tree80f5d89cca49330e137688c72fb10c9f42dc5663 /drivers/mmc
parent14a4057959f8ee0a2249eb2abd64fd6b1f571d98 (diff)
Digi Release Code from del-5.6/main2.6.31-digi-201102141643
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/mmc.c298
-rw-r--r--drivers/mmc/core/sd.c10
-rw-r--r--drivers/mmc/host/mx_sdhci.c130
-rw-r--r--drivers/mmc/host/mx_sdhci.h3
-rw-r--r--drivers/mmc/host/mxs-mmc.c24
-rw-r--r--drivers/mmc/host/pxamci.c4
6 files changed, 113 insertions, 356 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 2338c761c74f..abcd4392a8e9 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -179,11 +179,11 @@ static int mmc_read_ext_csd(struct mmc_card *card)
err = mmc_send_ext_csd(card, ext_csd);
if (err) {
- /*
- * We all hosts that cannot perform the command
- * to fail more gracefully
- */
- if (err != -EINVAL)
+ /* If the host or the card can't do the switch,
+ * fail more gracefully. */
+ if ((err != -EINVAL)
+ && (err != -ENOSYS)
+ && (err != -EFAULT))
goto out;
/*
@@ -225,10 +225,6 @@ static int mmc_read_ext_csd(struct mmc_card *card)
mmc_card_set_blockaddr(card);
}
- card->ext_csd.boot_info = ext_csd[EXT_CSD_BOOT_INFO];
- card->ext_csd.boot_size_mult = ext_csd[EXT_CSD_BOOT_SIZE_MULT];
- card->ext_csd.boot_config = ext_csd[EXT_CSD_BOOT_CONFIG];
- card->ext_csd.boot_bus_width = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
card->ext_csd.card_type = ext_csd[EXT_CSD_CARD_TYPE];
switch (ext_csd[EXT_CSD_CARD_TYPE]) {
@@ -267,281 +263,6 @@ out:
return err;
}
-/* configure the boot partitions */
-static ssize_t
-setup_boot_partitions(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int err, busy = 0;
- u32 part, new_part;
- u8 *ext_csd, boot_config;
- struct mmc_command cmd;
- struct mmc_card *card = container_of(dev, struct mmc_card, dev);
-
- BUG_ON(!card);
-
- sscanf(buf, "%d\n", &part);
-
- if (card->csd.mmca_vsn < CSD_SPEC_VER_4) {
- printk(KERN_ERR "%s: invalid mmc version"
- " mmc version is below version 4!)\n",
- mmc_hostname(card->host));
- return -EINVAL;
- }
-
- /* it's a normal SD/MMC but user request to configure boot partition */
- if (card->ext_csd.boot_size_mult <= 0) {
- printk(KERN_ERR "%s: this is a normal SD/MMC card"
- " but you request to access boot partition!\n",
- mmc_hostname(card->host));
- return -EINVAL;
- }
-
- ext_csd = kmalloc(512, GFP_KERNEL);
- if (!ext_csd) {
- printk(KERN_ERR "%s: could not allocate a buffer to "
- "receive the ext_csd.\n", mmc_hostname(card->host));
- return -ENOMEM;
- }
-
- mmc_claim_host(card->host);
- err = mmc_send_ext_csd(card, ext_csd);
- if (err) {
- printk(KERN_ERR "%s: unable to read EXT_CSD.\n",
- mmc_hostname(card->host));
- goto err_rtn;
- }
-
- /* enable the boot partition in boot mode */
- /* boot enable be -
- * 0x00 - disable boot enable.
- * 0x08 - boot partition 1 is enabled for boot.
- * 0x10 - boot partition 2 is enabled for boot.
- * 0x38 - User area is enabled for boot.
- */
- switch (part & EXT_CSD_BOOT_PARTITION_ENABLE_MASK) {
- case 0:
- boot_config = (ext_csd[EXT_CSD_BOOT_CONFIG]
- & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK
- & ~EXT_CSD_BOOT_ACK_ENABLE);
- break;
- case EXT_CSD_BOOT_PARTITION_PART1:
- boot_config = ((ext_csd[EXT_CSD_BOOT_CONFIG]
- & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
- | EXT_CSD_BOOT_PARTITION_PART1
- | EXT_CSD_BOOT_ACK_ENABLE);
- break;
- case EXT_CSD_BOOT_PARTITION_PART2:
- boot_config = ((ext_csd[EXT_CSD_BOOT_CONFIG]
- & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
- | EXT_CSD_BOOT_PARTITION_PART2
- | EXT_CSD_BOOT_ACK_ENABLE);
- break;
- case EXT_CSD_BOOT_PARTITION_ENABLE_MASK:
- boot_config = ((ext_csd[EXT_CSD_BOOT_CONFIG]
- | EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
- & ~EXT_CSD_BOOT_ACK_ENABLE);
- break;
- default:
- printk(KERN_ERR "%s: wrong boot config parameter"
- " 00 (disable boot), 08 (enable boot1),"
- "16 (enable boot2), 56 (User area)\n",
- mmc_hostname(card->host));
- err = -EINVAL;
- goto err_rtn;
- }
-
- /* switch the partitions that used to be accessed in OS layer */
- /* partition must be -
- * 0 - user area
- * 1 - boot partition 1
- * 2 - boot partition 2
- */
- if ((part & EXT_CSD_BOOT_PARTITION_ACCESS_MASK) > 2) {
- printk(KERN_ERR "%s: wrong partition id"
- " 0 (user area), 1 (boot1), 2 (boot2)\n",
- mmc_hostname(card->host));
- err = -EINVAL;
- goto err_rtn;
- }
-
- /* Send SWITCH command to change partition for access */
- boot_config &= ~EXT_CSD_BOOT_PARTITION_ACCESS_MASK;
- boot_config |= (part & EXT_CSD_BOOT_PARTITION_ACCESS_MASK);
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_BOOT_CONFIG, boot_config);
- if (err) {
- printk(KERN_ERR "%s: fail to send SWITCH command"
- " to card to swich partition for access!\n",
- mmc_hostname(card->host));
- goto err_rtn;
- }
-
- /* waiting for the card to finish the busy state */
- do {
- memset(&cmd, 0, sizeof(struct mmc_command));
-
- cmd.opcode = MMC_SEND_STATUS;
- cmd.arg = card->rca << 16;
- cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
-
- err = mmc_wait_for_cmd(card->host, &cmd, 0);
- if (err || busy > 100) {
- printk(KERN_ERR "%s: failed to wait for"
- "the busy state to end.\n",
- mmc_hostname(card->host));
- break;
- }
-
- if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
- printk(KERN_INFO "%s: card is in busy state"
- "pls wait for busy state to end.\n",
- mmc_hostname(card->host));
- }
- busy++;
- } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
-
- /* Now check whether it works */
- err = mmc_send_ext_csd(card, ext_csd);
- if (err) {
- printk(KERN_ERR "%s: %d unable to re-read EXT_CSD.\n",
- mmc_hostname(card->host), err);
- goto err_rtn;
- }
-
- new_part = ext_csd[EXT_CSD_BOOT_CONFIG] &
- EXT_CSD_BOOT_PARTITION_ACCESS_MASK;
- if ((part & EXT_CSD_BOOT_PARTITION_ACCESS_MASK) != new_part) {
- printk(KERN_ERR "%s: after SWITCH, current part id %d is not"
- " same as requested partition %d!\n",
- mmc_hostname(card->host), new_part, part);
- goto err_rtn;
- }
- card->ext_csd.boot_config = ext_csd[EXT_CSD_BOOT_CONFIG];
-
-err_rtn:
- mmc_release_host(card->host);
- kfree(ext_csd);
- if (err)
- return err;
- else
- return count;
-}
-
-/* configure the boot bus */
-static ssize_t
-setup_boot_bus(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int err, busy = 0;
- u32 boot_bus, new_bus;
- u8 *ext_csd;
- struct mmc_command cmd;
- struct mmc_card *card = container_of(dev, struct mmc_card, dev);
-
- BUG_ON(!card);
-
- sscanf(buf, "%d\n", &boot_bus);
-
- if (card->csd.mmca_vsn < CSD_SPEC_VER_4) {
- printk(KERN_ERR "%s: invalid mmc version"
- " mmc version is below version 4!)\n",
- mmc_hostname(card->host));
- return -EINVAL;
- }
-
- /* it's a normal SD/MMC but user request to configure boot bus */
- if (card->ext_csd.boot_size_mult <= 0) {
- printk(KERN_ERR "%s: this is a normal SD/MMC card"
- " but you request to configure boot bus !\n",
- mmc_hostname(card->host));
- return -EINVAL;
- }
-
- ext_csd = kmalloc(512, GFP_KERNEL);
- if (!ext_csd) {
- printk(KERN_ERR "%s: could not allocate a buffer to "
- "receive the ext_csd.\n", mmc_hostname(card->host));
- return -ENOMEM;
- }
-
- mmc_claim_host(card->host);
- err = mmc_send_ext_csd(card, ext_csd);
- if (err) {
- printk(KERN_ERR "%s: unable to read EXT_CSD.\n",
- mmc_hostname(card->host));
- goto err_rtn;
- }
-
- /* Configure the boot bus width when boot partition is enabled */
- if (((boot_bus & EXT_CSD_BOOT_BUS_WIDTH_MODE_MASK) >> 3) > 2
- || (boot_bus & EXT_CSD_BOOT_BUS_WIDTH_WIDTH_MASK) > 2
- || (boot_bus & ~EXT_CSD_BOOT_BUS_WIDTH_MASK) > 0) {
- printk(KERN_ERR "%s: Invalid inputs!\n",
- mmc_hostname(card->host));
- err = -EINVAL;
- goto err_rtn;
- }
-
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_BOOT_BUS_WIDTH, boot_bus);
- if (err) {
- printk(KERN_ERR "%s: fail to send SWITCH command to "
- "card to swich partition for access!\n",
- mmc_hostname(card->host));
- goto err_rtn;
- }
-
- /* waiting for the card to finish the busy state */
- do {
- memset(&cmd, 0, sizeof(struct mmc_command));
-
- cmd.opcode = MMC_SEND_STATUS;
- cmd.arg = card->rca << 16;
- cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
-
- err = mmc_wait_for_cmd(card->host, &cmd, 0);
- if (err || busy > 100) {
- printk(KERN_ERR "%s: failed to wait for"
- "the busy state to end.\n",
- mmc_hostname(card->host));
- break;
- }
-
- if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
- printk(KERN_INFO "%s: card is in busy state"
- "pls wait for busy state to end.\n",
- mmc_hostname(card->host));
- }
- busy++;
- } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
-
- /* Now check whether it works */
- err = mmc_send_ext_csd(card, ext_csd);
- if (err) {
- printk(KERN_ERR "%s: %d unable to re-read EXT_CSD.\n",
- mmc_hostname(card->host), err);
- goto err_rtn;
- }
-
- new_bus = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
- if (boot_bus != new_bus) {
- printk(KERN_ERR "%s: after SWITCH, current boot bus mode %d"
- " is not same as requested bus mode %d!\n",
- mmc_hostname(card->host), new_bus, boot_bus);
- goto err_rtn;
- }
- card->ext_csd.boot_bus_width = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
-
-err_rtn:
- mmc_release_host(card->host);
- kfree(ext_csd);
- if (err)
- return err;
- else
- return count;
-}
-
MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
card->raw_cid[2], card->raw_cid[3]);
MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
@@ -553,12 +274,6 @@ MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid);
MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name);
MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid);
MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
-MMC_DEV_ATTR(boot_info, "boot_info:0x%02x; boot_size:%04dKB;"
- " boot_partition:0x%02x; boot_bus:0x%02x\n",
- card->ext_csd.boot_info, card->ext_csd.boot_size_mult * 128,
- card->ext_csd.boot_config, card->ext_csd.boot_bus_width);
-DEVICE_ATTR(boot_config, S_IWUGO, NULL, setup_boot_partitions);
-DEVICE_ATTR(boot_bus_config, S_IWUGO, NULL, setup_boot_bus);
static struct attribute *mmc_std_attrs[] = {
&dev_attr_cid.attr,
@@ -570,9 +285,6 @@ static struct attribute *mmc_std_attrs[] = {
&dev_attr_name.attr,
&dev_attr_oemid.attr,
&dev_attr_serial.attr,
- &dev_attr_boot_info.attr,
- &dev_attr_boot_config.attr,
- &dev_attr_boot_bus_config.attr,
NULL,
};
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 4a73e34f9200..c2a8cafd8276 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -210,11 +210,11 @@ static int mmc_read_switch(struct mmc_card *card)
err = mmc_sd_switch(card, 0, 0, 1, status);
if (err) {
- /*
- * We all hosts that cannot perform the command
- * to fail more gracefully
- */
- if (err != -EINVAL)
+ /* If the host or the card can't do the switch,
+ * fail more gracefully. */
+ if ((err != -EINVAL)
+ && (err != -ENOSYS)
+ && (err != -EFAULT))
goto out;
printk(KERN_WARNING "%s: problem reading switch "
diff --git a/drivers/mmc/host/mx_sdhci.c b/drivers/mmc/host/mx_sdhci.c
index 732135308eb6..0557d4d337c1 100644
--- a/drivers/mmc/host/mx_sdhci.c
+++ b/drivers/mmc/host/mx_sdhci.c
@@ -814,7 +814,6 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
host->plat_data->clk_flg = 1;
}
}
-
if (clock == host->clock && !(ios.bus_width & MMC_BUS_WIDTH_DDR))
return;
@@ -854,20 +853,85 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
DBG("prescaler = 0x%x, divider = 0x%x\n", prescaler, div);
clk |= (prescaler << 8) | (div << 4);
- if (host->plat_data->clk_always_on
- | (host->mmc->card && mmc_card_sdio(host->mmc->card)))
- clk |= SDHCI_CLOCK_PER_EN | SDHCI_CLOCK_HLK_EN
- | SDHCI_CLOCK_IPG_EN;
- else
- clk &= ~(SDHCI_CLOCK_PER_EN | SDHCI_CLOCK_HLK_EN
- | SDHCI_CLOCK_IPG_EN);
+ /* Configure the DLL when DDR mode is enabled */
+ if (ios.bus_width & MMC_BUS_WIDTH_DDR) {
+ /* Make sure that the PER, HLK, IPG are all enabled */
+ writel(readl(host->ioaddr + SDHCI_CLOCK_CONTROL)
+ | SDHCI_CLOCK_IPG_EN
+ | SDHCI_CLOCK_HLK_EN
+ | SDHCI_CLOCK_PER_EN,
+ host->ioaddr + SDHCI_CLOCK_CONTROL);
- /* Configure the clock delay line */
- if ((host->plat_data->vendor_ver >= ESDHC_VENDOR_V3)
- && host->plat_data->dll_override_en)
- writel((host->plat_data->dll_delay_cells << 10)
- | DLL_CTRL_SLV_OVERRIDE,
- host->ioaddr + SDHCI_DLL_CONTROL);
+ /* Enable the DLL and delay chain */
+ writel(readl(host->ioaddr + SDHCI_DLL_CONTROL)
+ | DLL_CTRL_ENABLE,
+ host->ioaddr + SDHCI_DLL_CONTROL);
+
+ timeout = 1000000;
+ while (timeout > 0) {
+ timeout--;
+ if (readl(host->ioaddr + SDHCI_DLL_STATUS)
+ & DLL_STS_REF_LOCK)
+ break;
+ else if (timeout == 0)
+ printk(KERN_ERR "DLL REF LOCK Timeout!\n");
+ };
+ DBG("dll stat: 0x%x\n", readl(host->ioaddr + SDHCI_DLL_STATUS));
+
+ writel(readl(host->ioaddr + SDHCI_DLL_CONTROL)
+ | DLL_CTRL_SLV_UP_INT | DLL_CTRL_REF_UP_INT
+ | DLL_CTRL_SLV_DLY_TAR,
+ host->ioaddr + SDHCI_DLL_CONTROL);
+
+ timeout = 1000000;
+ while (timeout > 0) {
+ timeout--;
+ if (readl(host->ioaddr + SDHCI_DLL_STATUS)
+ & DLL_STS_SLV_LOCK)
+ break;
+ else if (timeout == 0)
+ printk(KERN_ERR "DLL SLV LOCK Timeout!\n");
+ };
+
+ writel(readl(host->ioaddr + SDHCI_DLL_CONTROL)
+ | DLL_CTRL_SLV_FORCE_UPD,
+ host->ioaddr + SDHCI_DLL_CONTROL);
+
+ writel(readl(host->ioaddr + SDHCI_DLL_CONTROL)
+ & (~DLL_CTRL_SLV_FORCE_UPD),
+ host->ioaddr + SDHCI_DLL_CONTROL);
+
+ timeout = 1000000;
+ while (timeout > 0) {
+ timeout--;
+ if (readl(host->ioaddr + SDHCI_DLL_STATUS)
+ & DLL_STS_REF_LOCK)
+ break;
+ else if (timeout == 0)
+ printk(KERN_ERR "DLL REF LOCK Timeout!\n");
+ };
+ timeout = 1000000;
+ while (timeout > 0) {
+ timeout--;
+ if (readl(host->ioaddr + SDHCI_DLL_STATUS)
+ & DLL_STS_SLV_LOCK)
+ break;
+ else if (timeout == 0)
+ printk(KERN_ERR "DLL SLV LOCK Timeout!\n");
+ };
+ DBG("dll stat: 0x%x\n", readl(host->ioaddr + SDHCI_DLL_STATUS));
+
+ /* Let the PER, HLK, IPG to be auto-gate */
+ writel(readl(host->ioaddr + SDHCI_CLOCK_CONTROL)
+ & ~(SDHCI_CLOCK_IPG_EN | SDHCI_CLOCK_HLK_EN
+ | SDHCI_CLOCK_PER_EN),
+ host->ioaddr + SDHCI_CLOCK_CONTROL);
+
+ } else if (readl(host->ioaddr + SDHCI_DLL_STATUS) & DLL_STS_SLV_LOCK) {
+ /* reset DLL CTRL */
+ writel(readl(host->ioaddr + SDHCI_DLL_CONTROL) | DLL_CTRL_RESET,
+ host->ioaddr + SDHCI_DLL_CONTROL);
+ }
/* Configure the clock control register */
clk |=
@@ -1093,7 +1157,7 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct sdhci_host *host;
unsigned long flags;
- u32 ier, prot, present;
+ u32 ier, prot, clk, present;
host = mmc_priv(mmc);
@@ -1106,12 +1170,19 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
if (--(host->sdio_enable))
goto exit_unlock;
}
-
- ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
+ /* Enable the clock */
+ if (!host->plat_data->clk_flg) {
+ clk_enable(host->clk);
+ host->plat_data->clk_flg = 1;
+ }
+ ier = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE);
prot = readl(host->ioaddr + SDHCI_HOST_CONTROL);
+ clk = readl(host->ioaddr + SDHCI_CLOCK_CONTROL);
if (enable) {
ier |= SDHCI_INT_CARD_INT;
+ prot |= SDHCI_CTRL_D3CD;
+ clk |= SDHCI_CLOCK_PER_EN | SDHCI_CLOCK_IPG_EN;
present = readl(host->ioaddr + SDHCI_PRESENT_STATE);
if ((present & SDHCI_CARD_INT_MASK) != SDHCI_CARD_INT_ID)
writel(SDHCI_INT_CARD_INT,
@@ -1119,24 +1190,12 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
} else {
ier &= ~SDHCI_INT_CARD_INT;
prot &= ~SDHCI_CTRL_D3CD;
+ clk &= ~(SDHCI_CLOCK_PER_EN | SDHCI_CLOCK_IPG_EN);
}
writel(prot, host->ioaddr + SDHCI_HOST_CONTROL);
- writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
-
- /*
- * Using D3CD to manually driver the HW to re-sample the SDIO interrupt
- * on bus one more time to guarantee the SDIO interrupt signal sent
- * from card during the interrupt signal disabled period will not
- * be lost.
- */
- prot |= SDHCI_CTRL_CDSS;
- writel(prot, host->ioaddr + SDHCI_HOST_CONTROL);
- prot &= ~SDHCI_CTRL_D3CD;
- writel(prot, host->ioaddr + SDHCI_HOST_CONTROL);
- prot |= SDHCI_CTRL_D3CD;
- writel(prot, host->ioaddr + SDHCI_HOST_CONTROL);
+ writel(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
mmiowb();
exit_unlock:
@@ -1262,7 +1321,7 @@ static void sdhci_tasklet_finish(unsigned long param)
* The root cause is that the ROM code don't ensure
* the SD/MMC clk is running when boot system.
* */
- if (req_done && host->plat_data->clk_flg &&
+ if (!machine_is_mx35_3ds() && req_done && host->plat_data->clk_flg &&
!(host->mmc && host->mmc->card && mmc_card_sdio(host->mmc->card))) {
clk_disable(host->clk);
host->plat_data->clk_flg = 0;
@@ -1840,10 +1899,8 @@ static int __devinit sdhci_probe_slot(struct platform_device
/* Get the SDHC clock from clock system APIs */
host->clk = clk_get(&pdev->dev, mmc_plat->clock_mmc);
- if (NULL == host->clk) {
+ if (NULL == host->clk)
printk(KERN_ERR "MXC MMC can't get clock.\n");
- goto out1;
- }
DBG("SDHC:%d clock:%lu\n", pdev->id, clk_get_rate(host->clk));
host->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -2057,6 +2114,9 @@ static int __devinit sdhci_probe_slot(struct platform_device
}
mxc_dma_callback_set(host->dma, sdhci_dma_irq, (void *)host);
}
+#ifdef CONFIG_MMC_DEBUG
+ sdhci_dumpregs(host);
+#endif
mmiowb();
diff --git a/drivers/mmc/host/mx_sdhci.h b/drivers/mmc/host/mx_sdhci.h
index 83d02975ecd1..fa36dff0fd9a 100644
--- a/drivers/mmc/host/mx_sdhci.h
+++ b/drivers/mmc/host/mx_sdhci.h
@@ -69,7 +69,6 @@
#define SDHCI_CTRL_4BITBUS 0x00000002
#define SDHCI_CTRL_8BITBUS 0x00000004
#define SDHCI_CTRL_HISPD 0x00000004
-#define SDHCI_CTRL_CDSS 0x80
#define SDHCI_CTRL_DMA_MASK 0x18
#define SDHCI_CTRL_SDMA 0x00
#define SDHCI_CTRL_ADMA1 0x08
@@ -194,7 +193,6 @@
#define DLL_CTRL_ENABLE 0x00000001
#define DLL_CTRL_RESET 0x00000002
#define DLL_CTRL_SLV_FORCE_UPD 0x00000004
-#define DLL_CTRL_SLV_OVERRIDE 0x00000200
#define DLL_CTRL_SLV_DLY_TAR 0x00000000
#define DLL_CTRL_SLV_UP_INT 0x00200000
#define DLL_CTRL_REF_UP_INT 0x20000000
@@ -221,7 +219,6 @@ enum {
#define SDHCI_SPEC_100 0
#define SDHCI_SPEC_200 1
#define ESDHC_VENDOR_V22 0x12
-#define ESDHC_VENDOR_V3 0x13
struct sdhci_chip;
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index b7210b7d7af3..b849e873613b 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -49,7 +49,7 @@
#define MXS_MMC_DETECT_TIMEOUT (HZ/2)
/* Max value supported for XFER_COUNT */
-#define SSP_BUFFER_SIZE (65535)
+#define SSP_BUFFER_SIZE (65536)
#ifndef BF
#define BF(value, field) (((value) << BP_##field) & BM_##field)
@@ -93,9 +93,6 @@
#define BF_SSP_BLOCK_SIZE_BLOCK_SIZE(v) \
(((v) << 16) & BM_SSP_BLOCK_SIZE_BLOCK_SIZE)
#endif
-#ifndef BM_SSP_CMD0_DBL_DATA_RATE_EN
-#define BM_SSP_CMD0_DBL_DATA_RATE_EN 0x02000000
-#endif
struct mxs_mmc_host {
struct device *dev;
@@ -162,7 +159,6 @@ static inline int mxs_mmc_is_plugged(struct mxs_mmc_host *host)
return !(status & BM_SSP_STATUS_CARD_DETECT);
}
-static void mxs_mmc_reset(struct mxs_mmc_host *host);
/* Card detection polling function */
static void mxs_mmc_detect_poll(unsigned long arg)
{
@@ -171,8 +167,6 @@ static void mxs_mmc_detect_poll(unsigned long arg)
card_status = mxs_mmc_is_plugged(host);
if (card_status != host->present) {
- /* Reset MMC block */
- mxs_mmc_reset(host);
host->present = card_status;
mmc_detect_change(host->mmc, 0);
}
@@ -558,9 +552,6 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
dev_dbg(host->dev, "%s blksz is 0x%x.\n", __func__, log2_block_size);
if (ssp_ver_major > 3) {
- /* Configure the CMD0 */
- ssp_cmd0 = BF(cmd->opcode, SSP_CMD0_CMD);
-
/* Configure the BLOCK SIZE and BLOCK COUNT */
if ((1<<log2_block_size) != cmd->data->blksz) {
BUG_ON(cmd->data->blocks > 1);
@@ -569,13 +560,9 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
val = BF(log2_block_size, SSP_BLOCK_SIZE_BLOCK_SIZE) |
BF(cmd->data->blocks - 1, SSP_BLOCK_SIZE_BLOCK_COUNT);
__raw_writel(val, host->ssp_base + HW_SSP_BLOCK_SIZE);
- if (host->mmc->ios.bus_width & MMC_BUS_WIDTH_DDR)
- /* Enable the DDR mode */
- ssp_cmd0 |= BM_SSP_CMD0_DBL_DATA_RATE_EN;
- else
- ssp_cmd0 &= ~BM_SSP_CMD0_DBL_DATA_RATE_EN;
-
}
+ /* Configure the CMD0 */
+ ssp_cmd0 = BF(cmd->opcode, SSP_CMD0_CMD);
} else {
if ((1<<log2_block_size) != cmd->data->blksz) {
BUG_ON(cmd->data->blocks > 1);
@@ -818,9 +805,9 @@ static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
dev_warn(host->dev,
"Platform does not support CMD pin pullup control\n");
- if ((ios->bus_width & ~MMC_BUS_WIDTH_DDR) == MMC_BUS_WIDTH_8)
+ if (ios->bus_width == MMC_BUS_WIDTH_8)
host->bus_width = 2;
- else if ((ios->bus_width & ~MMC_BUS_WIDTH_DDR) == MMC_BUS_WIDTH_4)
+ else if (ios->bus_width == MMC_BUS_WIDTH_4)
host->bus_width = 1;
else
host->bus_width = 0;
@@ -892,6 +879,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
/* Configure SSP Control Register 1 */
ssp_ctrl1 =
BM_SSP_CTRL1_DMA_ENABLE |
+ BM_SSP_CTRL1_POLARITY |
BM_SSP_CTRL1_RECV_TIMEOUT_IRQ_EN |
BM_SSP_CTRL1_DATA_CRC_IRQ_EN |
BM_SSP_CTRL1_DATA_TIMEOUT_IRQ_EN |
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index e55ac792d68c..c8c0a7e4f0af 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -694,14 +694,14 @@ static int pxamci_remove(struct platform_device *pdev)
if (mmc) {
struct pxamci_host *host = mmc_priv(mmc);
+ mmc_remove_host(mmc);
+
if (host->vcc)
regulator_put(host->vcc);
if (host->pdata && host->pdata->exit)
host->pdata->exit(&pdev->dev, mmc);
- mmc_remove_host(mmc);
-
pxamci_stop_clock(host);
writel(TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD|
END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,