diff options
author | Ian Wisbon <ian.wisbon@timesys.com> | 2011-02-14 16:41:03 -0500 |
---|---|---|
committer | Ian Wisbon <ian.wisbon@timesys.com> | 2011-02-14 16:41:03 -0500 |
commit | 8a83780a187ba1961380814eaf9c503043345d12 (patch) | |
tree | 80f5d89cca49330e137688c72fb10c9f42dc5663 /drivers/mmc | |
parent | 14a4057959f8ee0a2249eb2abd64fd6b1f571d98 (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.c | 298 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 10 | ||||
-rw-r--r-- | drivers/mmc/host/mx_sdhci.c | 130 | ||||
-rw-r--r-- | drivers/mmc/host/mx_sdhci.h | 3 | ||||
-rw-r--r-- | drivers/mmc/host/mxs-mmc.c | 24 | ||||
-rw-r--r-- | drivers/mmc/host/pxamci.c | 4 |
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, |