mmc: sdhci-esdhc: enable esdhc on imx53

Fix the NO INT in the Multi-BLK IO in SD/MMC, and Multi-BLK read in
SDIO on imx53.

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 on imx53.

As a result, the TC flag is not asserted and SW receives timeout
exception. Set bit1 of Vendor Spec register to fix it.

Signed-off-by: Richard Zhu <Hong-Xing.Zhu@freescale.com>
Signed-off-by: Richard Zhao <richard.zhao@freescale.com>
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Chris Ball <cjb@laptop.org>

authored by Richard Zhu and committed by Chris Ball 58ac8177 e149860d

+42
+42
drivers/mmc/host/sdhci-esdhc-imx.c
··· 19 19 #include <linux/slab.h> 20 20 #include <linux/mmc/host.h> 21 21 #include <linux/mmc/sdhci-pltfm.h> 22 + #include <linux/mmc/mmc.h> 23 + #include <linux/mmc/sdio.h> 22 24 #include <mach/hardware.h> 23 25 #include <mach/esdhc.h> 24 26 #include "sdhci.h" 25 27 #include "sdhci-pltfm.h" 26 28 #include "sdhci-esdhc.h" 27 29 30 + /* VENDOR SPEC register */ 31 + #define SDHCI_VENDOR_SPEC 0xC0 32 + #define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002 33 + 28 34 #define ESDHC_FLAG_GPIO_FOR_CD_WP (1 << 0) 35 + /* 36 + * The CMDTYPE of the CMD register (offset 0xE) should be set to 37 + * "11" when the STOP CMD12 is issued on imx53 to abort one 38 + * open ended multi-blk IO. Otherwise the TC INT wouldn't 39 + * be generated. 40 + * In exact block transfer, the controller doesn't complete the 41 + * operations automatically as required at the end of the 42 + * transfer and remains on hold if the abort command is not sent. 43 + * As a result, the TC flag is not asserted and SW received timeout 44 + * exeception. Bit1 of Vendor Spec registor is used to fix it. 45 + */ 46 + #define ESDHC_FLAG_MULTIBLK_NO_INT (1 << 1) 29 47 30 48 struct pltfm_imx_data { 31 49 int flags; ··· 96 78 */ 97 79 val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT); 98 80 81 + if (unlikely((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT) 82 + && (reg == SDHCI_INT_STATUS) 83 + && (val & SDHCI_INT_DATA_END))) { 84 + u32 v; 85 + v = readl(host->ioaddr + SDHCI_VENDOR_SPEC); 86 + v &= ~SDHCI_VENDOR_SPEC_SDIO_QUIRK; 87 + writel(v, host->ioaddr + SDHCI_VENDOR_SPEC); 88 + } 89 + 99 90 writel(val, host->ioaddr + reg); 100 91 } 101 92 ··· 127 100 * Postpone this write, we must do it together with a 128 101 * command write that is down below. 129 102 */ 103 + if ((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT) 104 + && (host->cmd->opcode == SD_IO_RW_EXTENDED) 105 + && (host->cmd->data->blocks > 1) 106 + && (host->cmd->data->flags & MMC_DATA_READ)) { 107 + u32 v; 108 + v = readl(host->ioaddr + SDHCI_VENDOR_SPEC); 109 + v |= SDHCI_VENDOR_SPEC_SDIO_QUIRK; 110 + writel(v, host->ioaddr + SDHCI_VENDOR_SPEC); 111 + } 130 112 imx_data->scratchpad = val; 131 113 return; 132 114 case SDHCI_COMMAND: 115 + if ((host->cmd->opcode == MMC_STOP_TRANSMISSION) 116 + && (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) 117 + val |= SDHCI_CMD_ABORTCMD; 133 118 writel(val << 16 | imx_data->scratchpad, 134 119 host->ioaddr + SDHCI_TRANSFER_MODE); 135 120 return; ··· 253 214 /* write_protect can't be routed to controller, use gpio */ 254 215 sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro; 255 216 } 217 + 218 + if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51())) 219 + imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT; 256 220 257 221 if (boarddata) { 258 222 err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP");