Commit c467c8f0 authored by Marek Vasut's avatar Marek Vasut Committed by Ulf Hansson
Browse files

mmc: Add MMC_QUIRK_BROKEN_SD_CACHE for Kingston Canvas Go Plus from 11/2019



This microSD card never clears Flush Cache bit after cache flush has
been started in sd_flush_cache(). This leads e.g. to failure to mount
file system. Add a quirk which disables the SD cache for this specific
card from specific manufacturing date of 11/2019, since on newer dated
cards from 05/2023 the cache flush works correctly.

Fixes: 08ebf903 ("mmc: core: Fixup support for writeback-cache for eMMC and SD")
Signed-off-by: default avatarMarek Vasut <marex@denx.de>
Link: https://lore.kernel.org/r/20230620102713.7701-1-marex@denx.de


Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent f1738a1f
Loading
Loading
Loading
Loading
+23 −7
Original line number Diff line number Diff line
@@ -53,6 +53,10 @@ struct mmc_fixup {
	unsigned int manfid;
	unsigned short oemid;

	/* Manufacturing date */
	unsigned short year;
	unsigned char month;

	/* SDIO-specific fields. You can use SDIO_ANY_ID here of course */
	u16 cis_vendor, cis_device;

@@ -68,6 +72,8 @@ struct mmc_fixup {

#define CID_MANFID_ANY (-1u)
#define CID_OEMID_ANY ((unsigned short) -1)
#define CID_YEAR_ANY ((unsigned short) -1)
#define CID_MONTH_ANY ((unsigned char) -1)
#define CID_NAME_ANY (NULL)

#define EXT_CSD_REV_ANY (-1u)
@@ -81,17 +87,21 @@ struct mmc_fixup {
#define CID_MANFID_APACER       0x27
#define CID_MANFID_KINGSTON     0x70
#define CID_MANFID_HYNIX	0x90
#define CID_MANFID_KINGSTON_SD	0x9F
#define CID_MANFID_NUMONYX	0xFE

#define END_FIXUP { NULL }

#define _FIXUP_EXT(_name, _manfid, _oemid, _rev_start, _rev_end,	\
#define _FIXUP_EXT(_name, _manfid, _oemid, _year, _month,	\
		   _rev_start, _rev_end,			\
		   _cis_vendor, _cis_device,			\
		   _fixup, _data, _ext_csd_rev)			\
	{						\
		.name = (_name),			\
		.manfid = (_manfid),			\
		.oemid = (_oemid),			\
		.year = (_year),			\
		.month = (_month),			\
		.rev_start = (_rev_start),		\
		.rev_end = (_rev_end),			\
		.cis_vendor = (_cis_vendor),		\
@@ -103,8 +113,8 @@ struct mmc_fixup {

#define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end,	\
		      _fixup, _data, _ext_csd_rev)			\
	_FIXUP_EXT(_name, _manfid,					\
		   _oemid, _rev_start, _rev_end,			\
	_FIXUP_EXT(_name, _manfid, _oemid, CID_YEAR_ANY, CID_MONTH_ANY,	\
		   _rev_start, _rev_end,				\
		   SDIO_ANY_ID, SDIO_ANY_ID,				\
		   _fixup, _data, _ext_csd_rev)				\

@@ -118,8 +128,9 @@ struct mmc_fixup {
		      _ext_csd_rev)

#define SDIO_FIXUP(_vendor, _device, _fixup, _data)			\
	_FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY,			\
		    CID_OEMID_ANY, 0, -1ull,				\
	_FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, CID_OEMID_ANY,		\
		   CID_YEAR_ANY, CID_MONTH_ANY,				\
		   0, -1ull,						\
		   _vendor, _device,					\
		   _fixup, _data, EXT_CSD_REV_ANY)			\

@@ -264,4 +275,9 @@ static inline int mmc_card_broken_sd_discard(const struct mmc_card *c)
	return c->quirks & MMC_QUIRK_BROKEN_SD_DISCARD;
}

static inline int mmc_card_broken_sd_cache(const struct mmc_card *c)
{
	return c->quirks & MMC_QUIRK_BROKEN_SD_CACHE;
}

#endif
+13 −0
Original line number Diff line number Diff line
@@ -53,6 +53,15 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = {
	MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
		  MMC_QUIRK_BLK_NO_CMD23),

	/*
	 * Kingston Canvas Go! Plus microSD cards never finish SD cache flush.
	 * This has so far only been observed on cards from 11/2019, while new
	 * cards from 2023/05 do not exhibit this behavior.
	 */
	_FIXUP_EXT("SD64G", CID_MANFID_KINGSTON_SD, 0x5449, 2019, 11,
		   0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
		   MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),

	/*
	 * Some SD cards lockup while using CMD23 multiblock transfers.
	 */
@@ -223,6 +232,10 @@ static inline void mmc_fixup_device(struct mmc_card *card,
		if (f->of_compatible &&
		    !mmc_fixup_of_compatible_match(card, f->of_compatible))
			continue;
		if (f->year != CID_YEAR_ANY && f->year != card->cid.year)
			continue;
		if (f->month != CID_MONTH_ANY && f->month != card->cid.month)
			continue;

		dev_dbg(&card->dev, "calling %ps\n", f->vendor_fixup);
		f->vendor_fixup(card, f->data);
+1 −1
Original line number Diff line number Diff line
@@ -1170,7 +1170,7 @@ static int sd_parse_ext_reg_perf(struct mmc_card *card, u8 fno, u8 page,
		card->ext_perf.feature_support |= SD_EXT_PERF_HOST_MAINT;

	/* Cache support at bit 0. */
	if (reg_buf[4] & BIT(0))
	if ((reg_buf[4] & BIT(0)) && !mmc_card_broken_sd_cache(card))
		card->ext_perf.feature_support |= SD_EXT_PERF_CACHE;

	/* Command queue support indicated via queue depth bits (0 to 4). */
+1 −0
Original line number Diff line number Diff line
@@ -294,6 +294,7 @@ struct mmc_card {
#define MMC_QUIRK_TRIM_BROKEN	(1<<12)		/* Skip trim */
#define MMC_QUIRK_BROKEN_HPI	(1<<13)		/* Disable broken HPI support */
#define MMC_QUIRK_BROKEN_SD_DISCARD	(1<<14)	/* Disable broken SD discard support */
#define MMC_QUIRK_BROKEN_SD_CACHE	(1<<15)	/* Disable broken SD cache support */

	bool			reenable_cmdq;	/* Re-enable Command Queue */