Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: sd: SDUC Support Recognition

Ultra Capacity SD cards (SDUC) was already introduced in SD7.0. Those
cards support capacity larger than 2TB and up to including 128TB.

ACMD41 was extended to support the host-card handshake during
initialization. The card expects that the HCS & HO2T bits to be set in
the command argument, and sets the applicable bits in the R3 returned
response. On the contrary, if a SDUC card is inserted to a
non-supporting host, it will never respond to this ACMD41 until
eventually, the host will timed out and give up.

Also, add SD CSD version 3.0 - designated for SDUC, and properly parse
the csd register as the c_size field got expanded to 28 bits.

Do not enable SDUC for now - leave it to the last patch in the series.

Tested-by: Ricky WU <ricky_wu@realtek.com>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Avri Altman <avri.altman@wdc.com>
Link: https://lore.kernel.org/r/20241006051148.160278-2-avri.altman@wdc.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Avri Altman and committed by
Ulf Hansson
fce2ce78 078e548a

+27 -15
+3 -1
drivers/mmc/core/bus.c
··· 321 321 case MMC_TYPE_SD: 322 322 type = "SD"; 323 323 if (mmc_card_blockaddr(card)) { 324 - if (mmc_card_ext_capacity(card)) 324 + if (mmc_card_ult_capacity(card)) 325 + type = "SDUC"; 326 + else if (mmc_card_ext_capacity(card)) 325 327 type = "SDXC"; 326 328 else 327 329 type = "SDHC";
+3
drivers/mmc/core/card.h
··· 23 23 #define MMC_CARD_SDXC (1<<3) /* card is SDXC */ 24 24 #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ 25 25 #define MMC_STATE_SUSPENDED (1<<5) /* card is suspended */ 26 + #define MMC_CARD_SDUC (1<<6) /* card is SDUC */ 26 27 27 28 #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) 28 29 #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) ··· 31 30 #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) 32 31 #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) 33 32 #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) 33 + #define mmc_card_ult_capacity(c) ((c)->state & MMC_CARD_SDUC) 34 34 35 35 #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) 36 36 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) 37 37 #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) 38 38 #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) 39 + #define mmc_card_set_ult_capacity(c) ((c)->state |= MMC_CARD_SDUC) 39 40 #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) 40 41 #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED) 41 42 #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED)
+17 -11
drivers/mmc/core/sd.c
··· 100 100 /* 101 101 * Given a 128-bit response, decode to our card CSD structure. 102 102 */ 103 - static int mmc_decode_csd(struct mmc_card *card) 103 + static int mmc_decode_csd(struct mmc_card *card, bool is_sduc) 104 104 { 105 105 struct mmc_csd *csd = &card->csd; 106 106 unsigned int e, m, csd_struct; ··· 144 144 mmc_card_set_readonly(card); 145 145 break; 146 146 case 1: 147 + case 2: 147 148 /* 148 - * This is a block-addressed SDHC or SDXC card. Most 149 - * interesting fields are unused and have fixed 149 + * This is a block-addressed SDHC, SDXC or SDUC card. 150 + * Most interesting fields are unused and have fixed 150 151 * values. To avoid getting tripped by buggy cards, 151 152 * we assume those fixed values ourselves. 152 153 */ ··· 160 159 e = unstuff_bits(resp, 96, 3); 161 160 csd->max_dtr = tran_exp[e] * tran_mant[m]; 162 161 csd->cmdclass = unstuff_bits(resp, 84, 12); 163 - csd->c_size = unstuff_bits(resp, 48, 22); 164 162 165 - /* SDXC cards have a minimum C_SIZE of 0x00FFFF */ 166 - if (csd->c_size >= 0xFFFF) 163 + if (csd_struct == 1) 164 + m = unstuff_bits(resp, 48, 22); 165 + else 166 + m = unstuff_bits(resp, 48, 28); 167 + csd->c_size = m; 168 + 169 + if (csd->c_size >= 0x400000 && is_sduc) 170 + mmc_card_set_ult_capacity(card); 171 + else if (csd->c_size >= 0xFFFF) 167 172 mmc_card_set_ext_capacity(card); 168 173 169 - m = unstuff_bits(resp, 48, 22); 170 - csd->capacity = (1 + m) << 10; 174 + csd->capacity = (1 + (typeof(sector_t))m) << 10; 171 175 172 176 csd->read_blkbits = 9; 173 177 csd->read_partial = 0; ··· 882 876 return err; 883 877 } 884 878 885 - int mmc_sd_get_csd(struct mmc_card *card) 879 + int mmc_sd_get_csd(struct mmc_card *card, bool is_sduc) 886 880 { 887 881 int err; 888 882 ··· 893 887 if (err) 894 888 return err; 895 889 896 - err = mmc_decode_csd(card); 890 + err = mmc_decode_csd(card, is_sduc); 897 891 if (err) 898 892 return err; 899 893 ··· 1448 1442 } 1449 1443 1450 1444 if (!oldcard) { 1451 - err = mmc_sd_get_csd(card); 1445 + err = mmc_sd_get_csd(card, false); 1452 1446 if (err) 1453 1447 goto free_card; 1454 1448
+1 -1
drivers/mmc/core/sd.h
··· 10 10 struct mmc_card; 11 11 12 12 int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr); 13 - int mmc_sd_get_csd(struct mmc_card *card); 13 + int mmc_sd_get_csd(struct mmc_card *card, bool is_sduc); 14 14 void mmc_decode_cid(struct mmc_card *card); 15 15 int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, 16 16 bool reinit);
+1 -1
drivers/mmc/core/sdio.c
··· 769 769 * Read CSD, before selecting the card 770 770 */ 771 771 if (!oldcard && mmc_card_sd_combo(card)) { 772 - err = mmc_sd_get_csd(card); 772 + err = mmc_sd_get_csd(card, false); 773 773 if (err) 774 774 goto remove; 775 775
+1 -1
include/linux/mmc/card.h
··· 35 35 unsigned int wp_grp_size; 36 36 unsigned int read_blkbits; 37 37 unsigned int write_blkbits; 38 - unsigned int capacity; 38 + sector_t capacity; 39 39 unsigned int read_partial:1, 40 40 read_misalign:1, 41 41 write_partial:1,
+1
include/linux/mmc/sd.h
··· 36 36 /* OCR bit definitions */ 37 37 #define SD_OCR_S18R (1 << 24) /* 1.8V switching request */ 38 38 #define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */ 39 + #define SD_OCR_2T (1 << 27) /* HO2T/CO2T - SDUC support */ 39 40 #define SD_OCR_XPC (1 << 28) /* SDXC power control */ 40 41 #define SD_OCR_CCS (1 << 30) /* Card Capacity Status */ 41 42