From: Adrian Hunter <adrian.hunter@intel.com>
To: Avri Altman <avri.altman@wdc.com>,
Ulf Hansson <ulf.hansson@linaro.org>,
linux-mmc@vger.kernel.org
Cc: Ricky WU <ricky_wu@realtek.com>, Shawn Lin <shawn.lin@rock-chips.com>
Subject: Re: [PATCH v6 1/9] mmc: sd: SDUC Support Recognition
Date: Fri, 6 Sep 2024 09:39:44 +0300 [thread overview]
Message-ID: <d43f5407-fb88-437b-9f43-661de0245363@intel.com> (raw)
In-Reply-To: <20240904145256.3670679-2-avri.altman@wdc.com>
On 4/09/24 17:52, Avri Altman wrote:
> 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>
> Signed-off-by: Avri Altman <avri.altman@wdc.com>
> ---
> drivers/mmc/core/bus.c | 4 +++-
> drivers/mmc/core/card.h | 3 +++
> drivers/mmc/core/sd.c | 33 +++++++++++++++++++++------------
> drivers/mmc/core/sd.h | 2 +-
> drivers/mmc/core/sdio.c | 2 +-
> include/linux/mmc/card.h | 2 +-
> include/linux/mmc/sd.h | 1 +
> 7 files changed, 31 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
> index 0ddaee0eae54..30763b342bd3 100644
> --- a/drivers/mmc/core/bus.c
> +++ b/drivers/mmc/core/bus.c
> @@ -321,7 +321,9 @@ int mmc_add_card(struct mmc_card *card)
> case MMC_TYPE_SD:
> type = "SD";
> if (mmc_card_blockaddr(card)) {
> - if (mmc_card_ext_capacity(card))
> + if (mmc_card_ult_capacity(card))
> + type = "SDUC";
> + else if (mmc_card_ext_capacity(card))
> type = "SDXC";
> else
> type = "SDHC";
> diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h
> index b7754a1b8d97..64dcb463a4f4 100644
> --- a/drivers/mmc/core/card.h
> +++ b/drivers/mmc/core/card.h
> @@ -23,6 +23,7 @@
> #define MMC_CARD_SDXC (1<<3) /* card is SDXC */
> #define MMC_CARD_REMOVED (1<<4) /* card has been removed */
> #define MMC_STATE_SUSPENDED (1<<5) /* card is suspended */
> +#define MMC_CARD_SDUC (1<<6) /* card is SDUC */
>
> #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT)
> #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY)
> @@ -30,11 +31,13 @@
> #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
> #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED))
> #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED)
> +#define mmc_card_ult_capacity(c) ((c)->state & MMC_CARD_SDUC)
>
> #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
> #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
> #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR)
> #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
> +#define mmc_card_set_ult_capacity(c) ((c)->state |= MMC_CARD_SDUC)
> #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
> #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED)
> #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED)
> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
> index ee37ad14e79e..eb9990d9db56 100644
> --- a/drivers/mmc/core/sd.c
> +++ b/drivers/mmc/core/sd.c
> @@ -114,7 +114,7 @@ void mmc_decode_cid(struct mmc_card *card)
> /*
> * Given a 128-bit response, decode to our card CSD structure.
> */
> -static int mmc_decode_csd(struct mmc_card *card)
> +static int mmc_decode_csd(struct mmc_card *card, bool is_sduc)
> {
> struct mmc_csd *csd = &card->csd;
> unsigned int e, m, csd_struct;
> @@ -158,9 +158,10 @@ static int mmc_decode_csd(struct mmc_card *card)
> mmc_card_set_readonly(card);
> break;
> case 1:
> + case 2:
> /*
> - * This is a block-addressed SDHC or SDXC card. Most
> - * interesting fields are unused and have fixed
> + * This is a block-addressed SDHC, SDXC or SDUC card.
> + * Most interesting fields are unused and have fixed
> * values. To avoid getting tripped by buggy cards,
> * we assume those fixed values ourselves.
> */
> @@ -173,14 +174,19 @@ static int mmc_decode_csd(struct mmc_card *card)
> e = UNSTUFF_BITS(resp, 96, 3);
> csd->max_dtr = tran_exp[e] * tran_mant[m];
> csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
> - csd->c_size = UNSTUFF_BITS(resp, 48, 22);
>
> - /* SDXC cards have a minimum C_SIZE of 0x00FFFF */
> - if (csd->c_size >= 0xFFFF)
> + if (csd_struct == 1)
> + m = UNSTUFF_BITS(resp, 48, 22);
> + else
> + m = UNSTUFF_BITS(resp, 48, 28);
> + csd->c_size = m;
> +
> + if (csd->c_size >= 0x400000 && is_sduc)
> + mmc_card_set_ult_capacity(card);
> + else if (csd->c_size >= 0xFFFF)
> mmc_card_set_ext_capacity(card);
>
> - m = UNSTUFF_BITS(resp, 48, 22);
> - csd->capacity = (1 + m) << 10;
> + csd->capacity = (1 + (typeof(sector_t))m) << 10;
>
> csd->read_blkbits = 9;
> csd->read_partial = 0;
> @@ -841,8 +847,11 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
> * block-addressed SDHC cards.
> */
> err = mmc_send_if_cond(host, ocr);
> - if (!err)
> + if (!err) {
> ocr |= SD_OCR_CCS;
> + /* Set HO2T as well - SDUC card won't respond otherwise */
> + ocr |= SD_OCR_2T;
Wouldn't that be better to leave for the last patch.
> + }
>
> /*
> * If the host supports one of UHS-I modes, request the card
> @@ -887,7 +896,7 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
> return err;
> }
>
> -int mmc_sd_get_csd(struct mmc_card *card)
> +int mmc_sd_get_csd(struct mmc_card *card, bool is_sduc)
> {
> int err;
>
> @@ -898,7 +907,7 @@ int mmc_sd_get_csd(struct mmc_card *card)
> if (err)
> return err;
>
> - err = mmc_decode_csd(card);
> + err = mmc_decode_csd(card, is_sduc);
> if (err)
> return err;
>
> @@ -1453,7 +1462,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
> }
>
> if (!oldcard) {
> - err = mmc_sd_get_csd(card);
> + err = mmc_sd_get_csd(card, false);
> if (err)
> goto free_card;
>
Also need to prevent Host Software Queue from enabling
for SDUC. Something like:
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 8d77a49357aa..769cd8b9f49c 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1578,7 +1578,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
goto free_card;
}
- if (host->cqe_ops && !host->cqe_enabled) {
+ if (!mmc_card_ult_capacity(card) && host->cqe_ops && !host->cqe_enabled) {
err = host->cqe_ops->cqe_enable(host, card);
if (!err) {
host->cqe_enabled = true;
Ideally try to get testing / feedback from HSQ users though.
> diff --git a/drivers/mmc/core/sd.h b/drivers/mmc/core/sd.h
> index fe6dd46927a4..7e8beface2ca 100644
> --- a/drivers/mmc/core/sd.h
> +++ b/drivers/mmc/core/sd.h
> @@ -10,7 +10,7 @@ struct mmc_host;
> struct mmc_card;
>
> int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr);
> -int mmc_sd_get_csd(struct mmc_card *card);
> +int mmc_sd_get_csd(struct mmc_card *card, bool is_sduc);
> void mmc_decode_cid(struct mmc_card *card);
> int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
> bool reinit);
> diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
> index 4fb247fde5c0..9566837c9848 100644
> --- a/drivers/mmc/core/sdio.c
> +++ b/drivers/mmc/core/sdio.c
> @@ -769,7 +769,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
> * Read CSD, before selecting the card
> */
> if (!oldcard && mmc_card_sd_combo(card)) {
> - err = mmc_sd_get_csd(card);
> + err = mmc_sd_get_csd(card, false);
> if (err)
> goto remove;
>
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index f34407cc2788..f39bce322365 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -35,7 +35,7 @@ struct mmc_csd {
> unsigned int wp_grp_size;
> unsigned int read_blkbits;
> unsigned int write_blkbits;
> - unsigned int capacity;
> + sector_t capacity;
> unsigned int read_partial:1,
> read_misalign:1,
> write_partial:1,
> diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h
> index 6727576a8755..865cc0ca8543 100644
> --- a/include/linux/mmc/sd.h
> +++ b/include/linux/mmc/sd.h
> @@ -36,6 +36,7 @@
> /* OCR bit definitions */
> #define SD_OCR_S18R (1 << 24) /* 1.8V switching request */
> #define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
> +#define SD_OCR_2T (1 << 27) /* HO2T/CO2T - SDUC support */
> #define SD_OCR_XPC (1 << 28) /* SDXC power control */
> #define SD_OCR_CCS (1 << 30) /* Card Capacity Status */
>
next prev parent reply other threads:[~2024-09-06 6:39 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-04 14:52 [PATCH v6 0/9] Add SDUC Support Avri Altman
2024-09-04 14:52 ` [PATCH v6 1/9] mmc: sd: SDUC Support Recognition Avri Altman
2024-09-06 6:39 ` Adrian Hunter [this message]
2024-09-06 8:10 ` Avri Altman
2024-09-04 14:52 ` [PATCH v6 2/9] mmc: sd: Add Extension memory addressing Avri Altman
2024-09-04 14:52 ` [PATCH v6 3/9] mmc: core: Add open-ended Ext " Avri Altman
2024-09-04 22:13 ` Christian Loehle
2024-09-05 6:12 ` Avri Altman
2024-09-05 7:25 ` Adrian Hunter
2024-09-05 8:27 ` Christian Loehle
2024-09-05 9:47 ` Avri Altman
2024-09-06 8:02 ` Adrian Hunter
2024-09-06 8:20 ` Avri Altman
2024-09-06 8:33 ` Adrian Hunter
2024-09-06 10:11 ` Avri Altman
2024-09-04 14:52 ` [PATCH v6 4/9] mmc: core: Don't use close-ended rw for SDUC Avri Altman
2024-09-04 14:52 ` [PATCH v6 5/9] mmc: core: Allow mmc erase to carry large addresses Avri Altman
2024-09-04 14:52 ` [PATCH v6 6/9] mmc: core: Add Ext memory addressing for erase Avri Altman
2024-09-06 10:06 ` Adrian Hunter
2024-09-06 10:14 ` Avri Altman
2024-09-04 14:52 ` [PATCH v6 7/9] mmc: core: Adjust ACMD22 to SDUC Avri Altman
2024-09-06 10:57 ` Adrian Hunter
2024-09-06 11:07 ` Avri Altman
2024-09-04 14:52 ` [PATCH v6 8/9] mmc: core: Disable SDUC for mmc_test Avri Altman
2024-09-06 10:10 ` Adrian Hunter
2024-09-06 10:15 ` Avri Altman
2024-09-04 14:52 ` [PATCH v6 9/9] mmc: core: Enable SDUC Avri Altman
2024-09-06 11:10 ` [PATCH v6 0/9] Add SDUC Support Adrian Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d43f5407-fb88-437b-9f43-661de0245363@intel.com \
--to=adrian.hunter@intel.com \
--cc=avri.altman@wdc.com \
--cc=linux-mmc@vger.kernel.org \
--cc=ricky_wu@realtek.com \
--cc=shawn.lin@rock-chips.com \
--cc=ulf.hansson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox