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