1af873fceSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
24facdde1SUlf Hansson /*
34facdde1SUlf Hansson * Private header for the mmc subsystem
44facdde1SUlf Hansson *
54facdde1SUlf Hansson * Copyright (C) 2016 Linaro Ltd
64facdde1SUlf Hansson *
74facdde1SUlf Hansson * Author: Ulf Hansson <ulf.hansson@linaro.org>
84facdde1SUlf Hansson */
94facdde1SUlf Hansson
104facdde1SUlf Hansson #ifndef _MMC_CORE_CARD_H
114facdde1SUlf Hansson #define _MMC_CORE_CARD_H
124facdde1SUlf Hansson
134facdde1SUlf Hansson #include <linux/mmc/card.h>
144facdde1SUlf Hansson
154facdde1SUlf Hansson #define mmc_card_name(c) ((c)->cid.prod_name)
164facdde1SUlf Hansson #define mmc_card_id(c) (dev_name(&(c)->dev))
174facdde1SUlf Hansson #define mmc_dev_to_card(d) container_of(d, struct mmc_card, dev)
184facdde1SUlf Hansson
194facdde1SUlf Hansson /* Card states */
204facdde1SUlf Hansson #define MMC_STATE_PRESENT (1<<0) /* present in sysfs */
214facdde1SUlf Hansson #define MMC_STATE_READONLY (1<<1) /* card is read-only */
224facdde1SUlf Hansson #define MMC_STATE_BLOCKADDR (1<<2) /* card uses block-addressing */
234facdde1SUlf Hansson #define MMC_CARD_SDXC (1<<3) /* card is SDXC */
244facdde1SUlf Hansson #define MMC_CARD_REMOVED (1<<4) /* card has been removed */
250c204979SUlf Hansson #define MMC_STATE_SUSPENDED (1<<5) /* card is suspended */
264facdde1SUlf Hansson
274facdde1SUlf Hansson #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT)
284facdde1SUlf Hansson #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY)
294facdde1SUlf Hansson #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR)
304facdde1SUlf Hansson #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
314facdde1SUlf Hansson #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED))
324facdde1SUlf Hansson #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED)
334facdde1SUlf Hansson
344facdde1SUlf Hansson #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
354facdde1SUlf Hansson #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
364facdde1SUlf Hansson #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR)
374facdde1SUlf Hansson #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
384facdde1SUlf Hansson #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
394facdde1SUlf Hansson #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED)
404facdde1SUlf Hansson #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED)
414facdde1SUlf Hansson
424facdde1SUlf Hansson /*
434facdde1SUlf Hansson * The world is not perfect and supplies us with broken mmc/sdio devices.
444facdde1SUlf Hansson * For at least some of these bugs we need a work-around.
454facdde1SUlf Hansson */
464facdde1SUlf Hansson struct mmc_fixup {
474facdde1SUlf Hansson /* CID-specific fields. */
484facdde1SUlf Hansson const char *name;
494facdde1SUlf Hansson
504facdde1SUlf Hansson /* Valid revision range */
514facdde1SUlf Hansson u64 rev_start, rev_end;
524facdde1SUlf Hansson
534facdde1SUlf Hansson unsigned int manfid;
544facdde1SUlf Hansson unsigned short oemid;
554facdde1SUlf Hansson
56c467c8f0SMarek Vasut /* Manufacturing date */
57c467c8f0SMarek Vasut unsigned short year;
58c467c8f0SMarek Vasut unsigned char month;
59c467c8f0SMarek Vasut
604facdde1SUlf Hansson /* SDIO-specific fields. You can use SDIO_ANY_ID here of course */
614facdde1SUlf Hansson u16 cis_vendor, cis_device;
624facdde1SUlf Hansson
634facdde1SUlf Hansson /* for MMC cards */
644facdde1SUlf Hansson unsigned int ext_csd_rev;
654facdde1SUlf Hansson
66b360b110SJérôme Pouiller /* Match against functions declared in device tree */
67b360b110SJérôme Pouiller const char *of_compatible;
68b360b110SJérôme Pouiller
694facdde1SUlf Hansson void (*vendor_fixup)(struct mmc_card *card, int data);
704facdde1SUlf Hansson int data;
714facdde1SUlf Hansson };
724facdde1SUlf Hansson
734facdde1SUlf Hansson #define CID_MANFID_ANY (-1u)
744facdde1SUlf Hansson #define CID_OEMID_ANY ((unsigned short) -1)
75c467c8f0SMarek Vasut #define CID_YEAR_ANY ((unsigned short) -1)
76c467c8f0SMarek Vasut #define CID_MONTH_ANY ((unsigned char) -1)
774facdde1SUlf Hansson #define CID_NAME_ANY (NULL)
784facdde1SUlf Hansson
794facdde1SUlf Hansson #define EXT_CSD_REV_ANY (-1u)
804facdde1SUlf Hansson
814facdde1SUlf Hansson #define CID_MANFID_SANDISK 0x2
8207d2872bSAvri Altman #define CID_MANFID_SANDISK_SD 0x3
8391516a2aSChristoph Fritz #define CID_MANFID_ATP 0x9
844facdde1SUlf Hansson #define CID_MANFID_TOSHIBA 0x11
854facdde1SUlf Hansson #define CID_MANFID_MICRON 0x13
864facdde1SUlf Hansson #define CID_MANFID_SAMSUNG 0x15
8791516a2aSChristoph Fritz #define CID_MANFID_APACER 0x27
884facdde1SUlf Hansson #define CID_MANFID_KINGSTON 0x70
894facdde1SUlf Hansson #define CID_MANFID_HYNIX 0x90
90c467c8f0SMarek Vasut #define CID_MANFID_KINGSTON_SD 0x9F
91dbe7dc6bSDirk Behme #define CID_MANFID_NUMONYX 0xFE
924facdde1SUlf Hansson
934facdde1SUlf Hansson #define END_FIXUP { NULL }
944facdde1SUlf Hansson
95c467c8f0SMarek Vasut #define _FIXUP_EXT(_name, _manfid, _oemid, _year, _month, \
96c467c8f0SMarek Vasut _rev_start, _rev_end, \
974facdde1SUlf Hansson _cis_vendor, _cis_device, \
984facdde1SUlf Hansson _fixup, _data, _ext_csd_rev) \
994facdde1SUlf Hansson { \
1004facdde1SUlf Hansson .name = (_name), \
1014facdde1SUlf Hansson .manfid = (_manfid), \
1024facdde1SUlf Hansson .oemid = (_oemid), \
103c467c8f0SMarek Vasut .year = (_year), \
104c467c8f0SMarek Vasut .month = (_month), \
1054facdde1SUlf Hansson .rev_start = (_rev_start), \
1064facdde1SUlf Hansson .rev_end = (_rev_end), \
1074facdde1SUlf Hansson .cis_vendor = (_cis_vendor), \
1084facdde1SUlf Hansson .cis_device = (_cis_device), \
1094facdde1SUlf Hansson .vendor_fixup = (_fixup), \
1104facdde1SUlf Hansson .data = (_data), \
1114facdde1SUlf Hansson .ext_csd_rev = (_ext_csd_rev), \
1124facdde1SUlf Hansson }
1134facdde1SUlf Hansson
1144facdde1SUlf Hansson #define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end, \
1154facdde1SUlf Hansson _fixup, _data, _ext_csd_rev) \
116c467c8f0SMarek Vasut _FIXUP_EXT(_name, _manfid, _oemid, CID_YEAR_ANY, CID_MONTH_ANY, \
117c467c8f0SMarek Vasut _rev_start, _rev_end, \
1184facdde1SUlf Hansson SDIO_ANY_ID, SDIO_ANY_ID, \
1194facdde1SUlf Hansson _fixup, _data, _ext_csd_rev) \
1204facdde1SUlf Hansson
1214facdde1SUlf Hansson #define MMC_FIXUP(_name, _manfid, _oemid, _fixup, _data) \
1224facdde1SUlf Hansson MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \
1234facdde1SUlf Hansson EXT_CSD_REV_ANY)
1244facdde1SUlf Hansson
1254facdde1SUlf Hansson #define MMC_FIXUP_EXT_CSD_REV(_name, _manfid, _oemid, _fixup, _data, \
1264facdde1SUlf Hansson _ext_csd_rev) \
1274facdde1SUlf Hansson MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \
1284facdde1SUlf Hansson _ext_csd_rev)
1294facdde1SUlf Hansson
1304facdde1SUlf Hansson #define SDIO_FIXUP(_vendor, _device, _fixup, _data) \
131c467c8f0SMarek Vasut _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, CID_OEMID_ANY, \
132c467c8f0SMarek Vasut CID_YEAR_ANY, CID_MONTH_ANY, \
133c467c8f0SMarek Vasut 0, -1ull, \
1344facdde1SUlf Hansson _vendor, _device, \
1354facdde1SUlf Hansson _fixup, _data, EXT_CSD_REV_ANY) \
1364facdde1SUlf Hansson
137818cd405SH. Nikolaus Schaller #define SDIO_FIXUP_COMPATIBLE(_compatible, _fixup, _data) \
138818cd405SH. Nikolaus Schaller { \
139818cd405SH. Nikolaus Schaller .name = CID_NAME_ANY, \
140818cd405SH. Nikolaus Schaller .manfid = CID_MANFID_ANY, \
141818cd405SH. Nikolaus Schaller .oemid = CID_OEMID_ANY, \
142818cd405SH. Nikolaus Schaller .rev_start = 0, \
143818cd405SH. Nikolaus Schaller .rev_end = -1ull, \
144818cd405SH. Nikolaus Schaller .cis_vendor = SDIO_ANY_ID, \
145818cd405SH. Nikolaus Schaller .cis_device = SDIO_ANY_ID, \
146818cd405SH. Nikolaus Schaller .vendor_fixup = (_fixup), \
147818cd405SH. Nikolaus Schaller .data = (_data), \
148818cd405SH. Nikolaus Schaller .ext_csd_rev = EXT_CSD_REV_ANY, \
149818cd405SH. Nikolaus Schaller .of_compatible = _compatible, \
150818cd405SH. Nikolaus Schaller }
151818cd405SH. Nikolaus Schaller
1524facdde1SUlf Hansson #define cid_rev(hwrev, fwrev, year, month) \
1534facdde1SUlf Hansson (((u64) hwrev) << 40 | \
1544facdde1SUlf Hansson ((u64) fwrev) << 32 | \
1554facdde1SUlf Hansson ((u64) year) << 16 | \
1564facdde1SUlf Hansson ((u64) month))
1574facdde1SUlf Hansson
1584facdde1SUlf Hansson #define cid_rev_card(card) \
1594facdde1SUlf Hansson cid_rev(card->cid.hwrev, \
1604facdde1SUlf Hansson card->cid.fwrev, \
1614facdde1SUlf Hansson card->cid.year, \
1624facdde1SUlf Hansson card->cid.month)
1634facdde1SUlf Hansson
1644facdde1SUlf Hansson /*
1654facdde1SUlf Hansson * Unconditionally quirk add/remove.
1664facdde1SUlf Hansson */
add_quirk(struct mmc_card * card,int data)1674facdde1SUlf Hansson static inline void __maybe_unused add_quirk(struct mmc_card *card, int data)
1684facdde1SUlf Hansson {
1694facdde1SUlf Hansson card->quirks |= data;
1704facdde1SUlf Hansson }
1714facdde1SUlf Hansson
remove_quirk(struct mmc_card * card,int data)1724facdde1SUlf Hansson static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
1734facdde1SUlf Hansson {
1744facdde1SUlf Hansson card->quirks &= ~data;
1754facdde1SUlf Hansson }
1764facdde1SUlf Hansson
add_limit_rate_quirk(struct mmc_card * card,int data)177ebc5a1bfSharish_kandiga@mentor.com static inline void __maybe_unused add_limit_rate_quirk(struct mmc_card *card,
178ebc5a1bfSharish_kandiga@mentor.com int data)
179ebc5a1bfSharish_kandiga@mentor.com {
180ebc5a1bfSharish_kandiga@mentor.com card->quirk_max_rate = data;
181ebc5a1bfSharish_kandiga@mentor.com }
182ebc5a1bfSharish_kandiga@mentor.com
wl1251_quirk(struct mmc_card * card,int data)183187b1649SH. Nikolaus Schaller static inline void __maybe_unused wl1251_quirk(struct mmc_card *card,
184187b1649SH. Nikolaus Schaller int data)
185187b1649SH. Nikolaus Schaller {
186187b1649SH. Nikolaus Schaller /*
187187b1649SH. Nikolaus Schaller * We have TI wl1251 attached to this mmc. Pass this
188187b1649SH. Nikolaus Schaller * information to the SDIO core because it can't be
189187b1649SH. Nikolaus Schaller * probed by normal methods.
190187b1649SH. Nikolaus Schaller */
191187b1649SH. Nikolaus Schaller
192187b1649SH. Nikolaus Schaller dev_info(card->host->parent, "found wl1251\n");
193187b1649SH. Nikolaus Schaller card->quirks |= MMC_QUIRK_NONSTD_SDIO;
194187b1649SH. Nikolaus Schaller card->cccr.wide_bus = 1;
195187b1649SH. Nikolaus Schaller card->cis.vendor = 0x104c;
196187b1649SH. Nikolaus Schaller card->cis.device = 0x9066;
197187b1649SH. Nikolaus Schaller card->cis.blksize = 512;
198187b1649SH. Nikolaus Schaller card->cis.max_dtr = 24000000;
199187b1649SH. Nikolaus Schaller }
200187b1649SH. Nikolaus Schaller
2014facdde1SUlf Hansson /*
2024facdde1SUlf Hansson * Quirk add/remove for MMC products.
2034facdde1SUlf Hansson */
add_quirk_mmc(struct mmc_card * card,int data)2044facdde1SUlf Hansson static inline void __maybe_unused add_quirk_mmc(struct mmc_card *card, int data)
2054facdde1SUlf Hansson {
2064facdde1SUlf Hansson if (mmc_card_mmc(card))
2074facdde1SUlf Hansson card->quirks |= data;
2084facdde1SUlf Hansson }
2094facdde1SUlf Hansson
remove_quirk_mmc(struct mmc_card * card,int data)2104facdde1SUlf Hansson static inline void __maybe_unused remove_quirk_mmc(struct mmc_card *card,
2114facdde1SUlf Hansson int data)
2124facdde1SUlf Hansson {
2134facdde1SUlf Hansson if (mmc_card_mmc(card))
2144facdde1SUlf Hansson card->quirks &= ~data;
2154facdde1SUlf Hansson }
2164facdde1SUlf Hansson
2174facdde1SUlf Hansson /*
2184facdde1SUlf Hansson * Quirk add/remove for SD products.
2194facdde1SUlf Hansson */
add_quirk_sd(struct mmc_card * card,int data)2204facdde1SUlf Hansson static inline void __maybe_unused add_quirk_sd(struct mmc_card *card, int data)
2214facdde1SUlf Hansson {
2224facdde1SUlf Hansson if (mmc_card_sd(card))
2234facdde1SUlf Hansson card->quirks |= data;
2244facdde1SUlf Hansson }
2254facdde1SUlf Hansson
remove_quirk_sd(struct mmc_card * card,int data)2264facdde1SUlf Hansson static inline void __maybe_unused remove_quirk_sd(struct mmc_card *card,
2274facdde1SUlf Hansson int data)
2284facdde1SUlf Hansson {
2294facdde1SUlf Hansson if (mmc_card_sd(card))
2304facdde1SUlf Hansson card->quirks &= ~data;
2314facdde1SUlf Hansson }
2324facdde1SUlf Hansson
mmc_card_lenient_fn0(const struct mmc_card * c)2334facdde1SUlf Hansson static inline int mmc_card_lenient_fn0(const struct mmc_card *c)
2344facdde1SUlf Hansson {
2354facdde1SUlf Hansson return c->quirks & MMC_QUIRK_LENIENT_FN0;
2364facdde1SUlf Hansson }
2374facdde1SUlf Hansson
mmc_blksz_for_byte_mode(const struct mmc_card * c)2384facdde1SUlf Hansson static inline int mmc_blksz_for_byte_mode(const struct mmc_card *c)
2394facdde1SUlf Hansson {
2404facdde1SUlf Hansson return c->quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
2414facdde1SUlf Hansson }
2424facdde1SUlf Hansson
mmc_card_disable_cd(const struct mmc_card * c)2434facdde1SUlf Hansson static inline int mmc_card_disable_cd(const struct mmc_card *c)
2444facdde1SUlf Hansson {
2454facdde1SUlf Hansson return c->quirks & MMC_QUIRK_DISABLE_CD;
2464facdde1SUlf Hansson }
2474facdde1SUlf Hansson
mmc_card_nonstd_func_interface(const struct mmc_card * c)2484facdde1SUlf Hansson static inline int mmc_card_nonstd_func_interface(const struct mmc_card *c)
2494facdde1SUlf Hansson {
2504facdde1SUlf Hansson return c->quirks & MMC_QUIRK_NONSTD_FUNC_IF;
2514facdde1SUlf Hansson }
2524facdde1SUlf Hansson
mmc_card_broken_byte_mode_512(const struct mmc_card * c)2534facdde1SUlf Hansson static inline int mmc_card_broken_byte_mode_512(const struct mmc_card *c)
2544facdde1SUlf Hansson {
2554facdde1SUlf Hansson return c->quirks & MMC_QUIRK_BROKEN_BYTE_MODE_512;
2564facdde1SUlf Hansson }
2574facdde1SUlf Hansson
mmc_card_long_read_time(const struct mmc_card * c)2584facdde1SUlf Hansson static inline int mmc_card_long_read_time(const struct mmc_card *c)
2594facdde1SUlf Hansson {
2604facdde1SUlf Hansson return c->quirks & MMC_QUIRK_LONG_READ_TIME;
2614facdde1SUlf Hansson }
2624facdde1SUlf Hansson
mmc_card_broken_irq_polling(const struct mmc_card * c)2634facdde1SUlf Hansson static inline int mmc_card_broken_irq_polling(const struct mmc_card *c)
2644facdde1SUlf Hansson {
2654facdde1SUlf Hansson return c->quirks & MMC_QUIRK_BROKEN_IRQ_POLLING;
2664facdde1SUlf Hansson }
2674facdde1SUlf Hansson
mmc_card_broken_hpi(const struct mmc_card * c)2684facdde1SUlf Hansson static inline int mmc_card_broken_hpi(const struct mmc_card *c)
2694facdde1SUlf Hansson {
2704facdde1SUlf Hansson return c->quirks & MMC_QUIRK_BROKEN_HPI;
2714facdde1SUlf Hansson }
2724facdde1SUlf Hansson
mmc_card_broken_sd_discard(const struct mmc_card * c)27307d2872bSAvri Altman static inline int mmc_card_broken_sd_discard(const struct mmc_card *c)
27407d2872bSAvri Altman {
27507d2872bSAvri Altman return c->quirks & MMC_QUIRK_BROKEN_SD_DISCARD;
27607d2872bSAvri Altman }
27707d2872bSAvri Altman
mmc_card_broken_sd_cache(const struct mmc_card * c)278c467c8f0SMarek Vasut static inline int mmc_card_broken_sd_cache(const struct mmc_card *c)
279c467c8f0SMarek Vasut {
280c467c8f0SMarek Vasut return c->quirks & MMC_QUIRK_BROKEN_SD_CACHE;
281c467c8f0SMarek Vasut }
282c467c8f0SMarek Vasut
mmc_card_broken_cache_flush(const struct mmc_card * c)283*ed9009adSBean Huo static inline int mmc_card_broken_cache_flush(const struct mmc_card *c)
284*ed9009adSBean Huo {
285*ed9009adSBean Huo return c->quirks & MMC_QUIRK_BROKEN_CACHE_FLUSH;
286*ed9009adSBean Huo }
2874facdde1SUlf Hansson #endif
288