128fc64afSShawn Lin /* 228fc64afSShawn Lin * This file contains work-arounds for many known SD/MMC 328fc64afSShawn Lin * and SDIO hardware bugs. 428fc64afSShawn Lin * 528fc64afSShawn Lin * Copyright (c) 2011 Andrei Warkentin <andreiw@motorola.com> 628fc64afSShawn Lin * Copyright (c) 2011 Pierre Tardy <tardyp@gmail.com> 728fc64afSShawn Lin * Inspired from pci fixup code: 828fc64afSShawn Lin * Copyright (c) 1999 Martin Mares <mj@ucw.cz> 928fc64afSShawn Lin * 1028fc64afSShawn Lin */ 1128fc64afSShawn Lin 1228fc64afSShawn Lin #include <linux/mmc/sdio_ids.h> 1328fc64afSShawn Lin 1428fc64afSShawn Lin #include "card.h" 1528fc64afSShawn Lin 160e9cfcf4SShawn Lin static const struct mmc_fixup blk_fixups[] = { 170e9cfcf4SShawn Lin #define INAND_CMD38_ARG_EXT_CSD 113 180e9cfcf4SShawn Lin #define INAND_CMD38_ARG_ERASE 0x00 190e9cfcf4SShawn Lin #define INAND_CMD38_ARG_TRIM 0x01 200e9cfcf4SShawn Lin #define INAND_CMD38_ARG_SECERASE 0x80 210e9cfcf4SShawn Lin #define INAND_CMD38_ARG_SECTRIM1 0x81 220e9cfcf4SShawn Lin #define INAND_CMD38_ARG_SECTRIM2 0x88 230e9cfcf4SShawn Lin /* CMD38 argument is passed through EXT_CSD[113] */ 240e9cfcf4SShawn Lin MMC_FIXUP("SEM02G", CID_MANFID_SANDISK, 0x100, add_quirk, 250e9cfcf4SShawn Lin MMC_QUIRK_INAND_CMD38), 260e9cfcf4SShawn Lin MMC_FIXUP("SEM04G", CID_MANFID_SANDISK, 0x100, add_quirk, 270e9cfcf4SShawn Lin MMC_QUIRK_INAND_CMD38), 280e9cfcf4SShawn Lin MMC_FIXUP("SEM08G", CID_MANFID_SANDISK, 0x100, add_quirk, 290e9cfcf4SShawn Lin MMC_QUIRK_INAND_CMD38), 300e9cfcf4SShawn Lin MMC_FIXUP("SEM16G", CID_MANFID_SANDISK, 0x100, add_quirk, 310e9cfcf4SShawn Lin MMC_QUIRK_INAND_CMD38), 320e9cfcf4SShawn Lin MMC_FIXUP("SEM32G", CID_MANFID_SANDISK, 0x100, add_quirk, 330e9cfcf4SShawn Lin MMC_QUIRK_INAND_CMD38), 340e9cfcf4SShawn Lin 350e9cfcf4SShawn Lin /* 360e9cfcf4SShawn Lin * Some MMC cards experience performance degradation with CMD23 370e9cfcf4SShawn Lin * instead of CMD12-bounded multiblock transfers. For now we'll 380e9cfcf4SShawn Lin * black list what's bad... 390e9cfcf4SShawn Lin * - Certain Toshiba cards. 400e9cfcf4SShawn Lin * 410e9cfcf4SShawn Lin * N.B. This doesn't affect SD cards. 420e9cfcf4SShawn Lin */ 430e9cfcf4SShawn Lin MMC_FIXUP("SDMB-32", CID_MANFID_SANDISK, CID_OEMID_ANY, add_quirk_mmc, 440e9cfcf4SShawn Lin MMC_QUIRK_BLK_NO_CMD23), 450e9cfcf4SShawn Lin MMC_FIXUP("SDM032", CID_MANFID_SANDISK, CID_OEMID_ANY, add_quirk_mmc, 460e9cfcf4SShawn Lin MMC_QUIRK_BLK_NO_CMD23), 470e9cfcf4SShawn Lin MMC_FIXUP("MMC08G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, 480e9cfcf4SShawn Lin MMC_QUIRK_BLK_NO_CMD23), 490e9cfcf4SShawn Lin MMC_FIXUP("MMC16G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, 500e9cfcf4SShawn Lin MMC_QUIRK_BLK_NO_CMD23), 510e9cfcf4SShawn Lin MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, 520e9cfcf4SShawn Lin MMC_QUIRK_BLK_NO_CMD23), 530e9cfcf4SShawn Lin 540e9cfcf4SShawn Lin /* 550e9cfcf4SShawn Lin * Some MMC cards need longer data read timeout than indicated in CSD. 560e9cfcf4SShawn Lin */ 570e9cfcf4SShawn Lin MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, 580e9cfcf4SShawn Lin MMC_QUIRK_LONG_READ_TIME), 590e9cfcf4SShawn Lin MMC_FIXUP("008GE0", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, 600e9cfcf4SShawn Lin MMC_QUIRK_LONG_READ_TIME), 610e9cfcf4SShawn Lin 620e9cfcf4SShawn Lin /* 630e9cfcf4SShawn Lin * On these Samsung MoviNAND parts, performing secure erase or 640e9cfcf4SShawn Lin * secure trim can result in unrecoverable corruption due to a 650e9cfcf4SShawn Lin * firmware bug. 660e9cfcf4SShawn Lin */ 670e9cfcf4SShawn Lin MMC_FIXUP("M8G2FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, 680e9cfcf4SShawn Lin MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), 690e9cfcf4SShawn Lin MMC_FIXUP("MAG4FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, 700e9cfcf4SShawn Lin MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), 710e9cfcf4SShawn Lin MMC_FIXUP("MBG8FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, 720e9cfcf4SShawn Lin MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), 730e9cfcf4SShawn Lin MMC_FIXUP("MCGAFA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, 740e9cfcf4SShawn Lin MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), 750e9cfcf4SShawn Lin MMC_FIXUP("VAL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, 760e9cfcf4SShawn Lin MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), 770e9cfcf4SShawn Lin MMC_FIXUP("VYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, 780e9cfcf4SShawn Lin MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), 790e9cfcf4SShawn Lin MMC_FIXUP("KYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, 800e9cfcf4SShawn Lin MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), 810e9cfcf4SShawn Lin MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, 820e9cfcf4SShawn Lin MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), 830e9cfcf4SShawn Lin 840e9cfcf4SShawn Lin /* 850e9cfcf4SShawn Lin * On Some Kingston eMMCs, performing trim can result in 860e9cfcf4SShawn Lin * unrecoverable data conrruption occasionally due to a firmware bug. 870e9cfcf4SShawn Lin */ 880e9cfcf4SShawn Lin MMC_FIXUP("V10008", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc, 890e9cfcf4SShawn Lin MMC_QUIRK_TRIM_BROKEN), 900e9cfcf4SShawn Lin MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc, 910e9cfcf4SShawn Lin MMC_QUIRK_TRIM_BROKEN), 920e9cfcf4SShawn Lin 930e9cfcf4SShawn Lin END_FIXUP 940e9cfcf4SShawn Lin }; 950e9cfcf4SShawn Lin 960e9cfcf4SShawn Lin static const struct mmc_fixup mmc_ext_csd_fixups[] = { 970e9cfcf4SShawn Lin /* 980e9cfcf4SShawn Lin * Certain Hynix eMMC 4.41 cards might get broken when HPI feature 990e9cfcf4SShawn Lin * is used so disable the HPI feature for such buggy cards. 1000e9cfcf4SShawn Lin */ 1010e9cfcf4SShawn Lin MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_HYNIX, 1020e9cfcf4SShawn Lin 0x014a, add_quirk, MMC_QUIRK_BROKEN_HPI, 5), 1030e9cfcf4SShawn Lin 1040e9cfcf4SShawn Lin END_FIXUP 1050e9cfcf4SShawn Lin }; 1060e9cfcf4SShawn Lin 1071144c1e4SShawn Lin static const struct mmc_fixup sdio_fixup_methods[] = { 10828fc64afSShawn Lin SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, 10928fc64afSShawn Lin add_quirk, MMC_QUIRK_NONSTD_FUNC_IF), 11028fc64afSShawn Lin 11128fc64afSShawn Lin SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, 11228fc64afSShawn Lin add_quirk, MMC_QUIRK_DISABLE_CD), 11328fc64afSShawn Lin 11428fc64afSShawn Lin SDIO_FIXUP(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200, 11528fc64afSShawn Lin add_quirk, MMC_QUIRK_BROKEN_BYTE_MODE_512), 11628fc64afSShawn Lin 11728fc64afSShawn Lin SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797_F0, 11828fc64afSShawn Lin add_quirk, MMC_QUIRK_BROKEN_IRQ_POLLING), 11928fc64afSShawn Lin 12028fc64afSShawn Lin END_FIXUP 12128fc64afSShawn Lin }; 12228fc64afSShawn Lin 12328fc64afSShawn Lin static inline void mmc_fixup_device(struct mmc_card *card, 12428fc64afSShawn Lin const struct mmc_fixup *table) 12528fc64afSShawn Lin { 12628fc64afSShawn Lin const struct mmc_fixup *f; 12728fc64afSShawn Lin u64 rev = cid_rev_card(card); 12828fc64afSShawn Lin 12928fc64afSShawn Lin for (f = table; f->vendor_fixup; f++) { 13028fc64afSShawn Lin if ((f->manfid == CID_MANFID_ANY || 13128fc64afSShawn Lin f->manfid == card->cid.manfid) && 13228fc64afSShawn Lin (f->oemid == CID_OEMID_ANY || 13328fc64afSShawn Lin f->oemid == card->cid.oemid) && 13428fc64afSShawn Lin (f->name == CID_NAME_ANY || 13528fc64afSShawn Lin !strncmp(f->name, card->cid.prod_name, 13628fc64afSShawn Lin sizeof(card->cid.prod_name))) && 13728fc64afSShawn Lin (f->cis_vendor == card->cis.vendor || 13828fc64afSShawn Lin f->cis_vendor == (u16) SDIO_ANY_ID) && 13928fc64afSShawn Lin (f->cis_device == card->cis.device || 14028fc64afSShawn Lin f->cis_device == (u16) SDIO_ANY_ID) && 14128fc64afSShawn Lin (f->ext_csd_rev == EXT_CSD_REV_ANY || 14228fc64afSShawn Lin f->ext_csd_rev == card->ext_csd.rev) && 14328fc64afSShawn Lin rev >= f->rev_start && rev <= f->rev_end) { 14428fc64afSShawn Lin dev_dbg(&card->dev, "calling %pf\n", f->vendor_fixup); 14528fc64afSShawn Lin f->vendor_fixup(card, f->data); 14628fc64afSShawn Lin } 14728fc64afSShawn Lin } 14828fc64afSShawn Lin } 149