Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 243414
b: refs/heads/master
c: 58ac817
h: refs/heads/master
v: v3
  • Loading branch information
Richard Zhu authored and Chris Ball committed Mar 25, 2011
1 parent 6bb39a0 commit 813520b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e149860d16d96aef1a8eb7dc1d0b9d4313479e61
refs/heads/master: 58ac8177cebb890ba980cdace36457e0fe1e62af
42 changes: 42 additions & 0 deletions trunk/drivers/mmc/host/sdhci-esdhc-imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,31 @@
#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdhci-pltfm.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h>
#include <mach/hardware.h>
#include <mach/esdhc.h>
#include "sdhci.h"
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"

/* VENDOR SPEC register */
#define SDHCI_VENDOR_SPEC 0xC0
#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002

#define ESDHC_FLAG_GPIO_FOR_CD_WP (1 << 0)
/*
* The CMDTYPE of the CMD register (offset 0xE) should be set to
* "11" when the STOP CMD12 is issued on imx53 to abort one
* open ended multi-blk IO. Otherwise the TC INT wouldn't
* be generated.
* In exact block transfer, the controller doesn't complete the
* operations automatically as required at the end of the
* transfer and remains on hold if the abort command is not sent.
* As a result, the TC flag is not asserted and SW received timeout
* exeception. Bit1 of Vendor Spec registor is used to fix it.
*/
#define ESDHC_FLAG_MULTIBLK_NO_INT (1 << 1)

struct pltfm_imx_data {
int flags;
Expand Down Expand Up @@ -78,6 +96,15 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
*/
val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);

if (unlikely((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
&& (reg == SDHCI_INT_STATUS)
&& (val & SDHCI_INT_DATA_END))) {
u32 v;
v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
v &= ~SDHCI_VENDOR_SPEC_SDIO_QUIRK;
writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
}

writel(val, host->ioaddr + reg);
}

Expand All @@ -100,9 +127,21 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
* Postpone this write, we must do it together with a
* command write that is down below.
*/
if ((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
&& (host->cmd->opcode == SD_IO_RW_EXTENDED)
&& (host->cmd->data->blocks > 1)
&& (host->cmd->data->flags & MMC_DATA_READ)) {
u32 v;
v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
v |= SDHCI_VENDOR_SPEC_SDIO_QUIRK;
writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
}
imx_data->scratchpad = val;
return;
case SDHCI_COMMAND:
if ((host->cmd->opcode == MMC_STOP_TRANSMISSION)
&& (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT))
val |= SDHCI_CMD_ABORTCMD;
writel(val << 16 | imx_data->scratchpad,
host->ioaddr + SDHCI_TRANSFER_MODE);
return;
Expand Down Expand Up @@ -215,6 +254,9 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro;
}

if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51()))
imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;

if (boarddata) {
err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP");
if (err) {
Expand Down

0 comments on commit 813520b

Please sign in to comment.