Commit 9a0da648 authored by Stefan Nilsson XK's avatar Stefan Nilsson XK Committed by Chris Ball

mmc: sdio: Workaround for dev with broken CMD53

Adds a quirk which can be turned on for SDIO devices that do not support
512 byte requests in byte mode during CMD53. These requests will always
be sent in block mode instead.

This patch also enables this quirk for ST-Ericsson CW1200 WLAN device.
Signed-off-by: default avatarStefan Nilsson XK <stefan.xk.nilsson@stericsson.com>
Signed-off-by: default avatarUlf HANSSON <ulf.hansson@stericsson.com>
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 329f2237
...@@ -21,6 +21,14 @@ ...@@ -21,6 +21,14 @@
#define SDIO_DEVICE_ID_TI_WL1271 0x4076 #define SDIO_DEVICE_ID_TI_WL1271 0x4076
#endif #endif
#ifndef SDIO_VENDOR_ID_STE
#define SDIO_VENDOR_ID_STE 0x0020
#endif
#ifndef SDIO_DEVICE_ID_STE_CW1200
#define SDIO_DEVICE_ID_STE_CW1200 0x2280
#endif
/* /*
* This hook just adds a quirk for all sdio devices * This hook just adds a quirk for all sdio devices
*/ */
...@@ -46,6 +54,9 @@ static const struct mmc_fixup mmc_fixup_methods[] = { ...@@ -46,6 +54,9 @@ static const struct mmc_fixup mmc_fixup_methods[] = {
SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
add_quirk, MMC_QUIRK_DISABLE_CD), add_quirk, MMC_QUIRK_DISABLE_CD),
SDIO_FIXUP(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200,
add_quirk, MMC_QUIRK_BROKEN_BYTE_MODE_512),
END_FIXUP END_FIXUP
}; };
......
...@@ -144,8 +144,11 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, ...@@ -144,8 +144,11 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
cmd.arg |= fn << 28; cmd.arg |= fn << 28;
cmd.arg |= incr_addr ? 0x04000000 : 0x00000000; cmd.arg |= incr_addr ? 0x04000000 : 0x00000000;
cmd.arg |= addr << 9; cmd.arg |= addr << 9;
if (blocks == 1 && blksz <= 512) if (blocks == 1 && blksz < 512)
cmd.arg |= (blksz == 512) ? 0 : blksz; /* byte mode */ cmd.arg |= blksz; /* byte mode */
else if (blocks == 1 && blksz == 512 &&
!(mmc_card_broken_byte_mode_512(card)))
cmd.arg |= 0; /* byte mode, 0==512 */
else else
cmd.arg |= 0x08000000 | blocks; /* block mode */ cmd.arg |= 0x08000000 | blocks; /* block mode */
cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
......
...@@ -188,6 +188,8 @@ struct mmc_card { ...@@ -188,6 +188,8 @@ struct mmc_card {
#define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3] resistor */ #define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3] resistor */
#define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */ #define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */
#define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */ #define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */
#define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */
/* byte mode */
unsigned int erase_size; /* erase size in sectors */ unsigned int erase_size; /* erase size in sectors */
unsigned int erase_shift; /* if erase unit is power 2 */ unsigned int erase_shift; /* if erase unit is power 2 */
...@@ -377,6 +379,11 @@ static inline int mmc_card_nonstd_func_interface(const struct mmc_card *c) ...@@ -377,6 +379,11 @@ static inline int mmc_card_nonstd_func_interface(const struct mmc_card *c)
return c->quirks & MMC_QUIRK_NONSTD_FUNC_IF; return c->quirks & MMC_QUIRK_NONSTD_FUNC_IF;
} }
static inline int mmc_card_broken_byte_mode_512(const struct mmc_card *c)
{
return c->quirks & MMC_QUIRK_BROKEN_BYTE_MODE_512;
}
#define mmc_card_name(c) ((c)->cid.prod_name) #define mmc_card_name(c) ((c)->cid.prod_name)
#define mmc_card_id(c) (dev_name(&(c)->dev)) #define mmc_card_id(c) (dev_name(&(c)->dev))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment