diff mbox series

[v2,03/10] mmc: sd: Add Extension memory addressing

Message ID 20240807060309.2403023-4-avri.altman@wdc.com (mailing list archive)
State New
Headers show
Series Add SDUC Support | expand

Commit Message

Avri Altman Aug. 7, 2024, 6:03 a.m. UTC
SDUC memory addressing spans beyond 2TB and up to 128TB.  Therefore, 38
bits are required to access the entire memory space of all sectors.
Those extra 6 bits are to be carried by CMD22 prior of sending
read/write/erase commands: CMD17, CMD18, CMD24, CMD25, CMD32, and CMD33.

CMD22 will carry the higher order 6 bits, and must precedes any of the
above commands even if it targets sector < 2TB.

No error related to address or length is indicated in CMD22 but rather
in the read/write command itself.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/mmc/core/sd_ops.c | 15 +++++++++++++++
 drivers/mmc/core/sd_ops.h |  1 +
 include/linux/mmc/sd.h    |  3 +++
 3 files changed, 19 insertions(+)

Comments

Ricky WU Aug. 9, 2024, 9:54 a.m. UTC | #1
> SDUC memory addressing spans beyond 2TB and up to 128TB.  Therefore, 38
> bits are required to access the entire memory space of all sectors.
> Those extra 6 bits are to be carried by CMD22 prior of sending
> read/write/erase commands: CMD17, CMD18, CMD24, CMD25, CMD32, and
> CMD33.
> 
> CMD22 will carry the higher order 6 bits, and must precedes any of the above
> commands even if it targets sector < 2TB.
> 
> No error related to address or length is indicated in CMD22 but rather in the
> read/write command itself.
> 
> Signed-off-by: Avri Altman <avri.altman@wdc.com>
> ---
>  drivers/mmc/core/sd_ops.c | 15 +++++++++++++++
> drivers/mmc/core/sd_ops.h |  1 +
>  include/linux/mmc/sd.h    |  3 +++
>  3 files changed, 19 insertions(+)
> 
> diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index
> 7f6963dac873..8b69129d7b61 100644
> --- a/drivers/mmc/core/sd_ops.c
> +++ b/drivers/mmc/core/sd_ops.c
> @@ -199,6 +199,21 @@ int mmc_send_app_op_cond(struct mmc_host *host,
> u32 ocr, u32 *rocr)
>         return 0;
>  }
> 
> +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr) {
> +       struct mmc_command cmd = {
> +               .opcode = SD_ADDR_EXT,
> +               .arg = (u32)((addr >> 32) & 0x3F),
> +               .flags = MMC_RSP_R1 | MMC_CMD_AC,
> +       };
> +
> +       if (!mmc_card_is_sduc(host))
> +               return 0;
> +
I think here can be removed, all mmc_send_ext_addr caller are have if-statement to check the card is SDUC

> +       return mmc_wait_for_cmd(host, &cmd, 0); }
> +EXPORT_SYMBOL_GPL(mmc_send_ext_addr);
> +
>  static int __mmc_send_if_cond(struct mmc_host *host, u32 ocr, u8 pcie_bits,
>                               u32 *resp)  { diff --git
> a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h index
> 7667fc223b74..462efd43acfa 100644
> --- a/drivers/mmc/core/sd_ops.h
> +++ b/drivers/mmc/core/sd_ops.h
> @@ -21,6 +21,7 @@ int mmc_send_relative_addr(struct mmc_host *host,
> unsigned int *rca);  int mmc_app_send_scr(struct mmc_card *card);  int
> mmc_app_sd_status(struct mmc_card *card, void *ssr);  int
> mmc_app_cmd(struct mmc_host *host, struct mmc_card *card);
> +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr);
> 
>  #endif
> 
> diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index
> 865cc0ca8543..af5fc70e09a2 100644
> --- a/include/linux/mmc/sd.h
> +++ b/include/linux/mmc/sd.h
> @@ -15,6 +15,9 @@
>  #define SD_SEND_IF_COND           8   /* bcr  [11:0] See below   R7
> */
>  #define SD_SWITCH_VOLTAGE         11  /* ac
> R1  */
> 
> +/* Class 2 */
> +#define SD_ADDR_EXT             22   /* ac   [5:0]
> R1  */
> +
>    /* class 10 */
>  #define SD_SWITCH                 6   /* adtc [31:0] See below   R1
> */
> 
> --
> 2.25.1
Avri Altman Aug. 10, 2024, 8:11 a.m. UTC | #2
> > SDUC memory addressing spans beyond 2TB and up to 128TB.  Therefore,
> > 38 bits are required to access the entire memory space of all sectors.
> > Those extra 6 bits are to be carried by CMD22 prior of sending
> > read/write/erase commands: CMD17, CMD18, CMD24, CMD25, CMD32, and
> > CMD33.
> >
> > CMD22 will carry the higher order 6 bits, and must precedes any of the
> > above commands even if it targets sector < 2TB.
> >
> > No error related to address or length is indicated in CMD22 but rather
> > in the read/write command itself.
> >
> > Signed-off-by: Avri Altman <avri.altman@wdc.com>
> > ---
> >  drivers/mmc/core/sd_ops.c | 15 +++++++++++++++
> > drivers/mmc/core/sd_ops.h |  1 +
> >  include/linux/mmc/sd.h    |  3 +++
> >  3 files changed, 19 insertions(+)
> >
> > diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
> > index
> > 7f6963dac873..8b69129d7b61 100644
> > --- a/drivers/mmc/core/sd_ops.c
> > +++ b/drivers/mmc/core/sd_ops.c
> > @@ -199,6 +199,21 @@ int mmc_send_app_op_cond(struct mmc_host *host,
> > u32 ocr, u32 *rocr)
> >         return 0;
> >  }
> >
> > +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr) {
> > +       struct mmc_command cmd = {
> > +               .opcode = SD_ADDR_EXT,
> > +               .arg = (u32)((addr >> 32) & 0x3F),
> > +               .flags = MMC_RSP_R1 | MMC_CMD_AC,
> > +       };
> > +
> > +       if (!mmc_card_is_sduc(host))
> > +               return 0;
> > +
> I think here can be removed, all mmc_send_ext_addr caller are have if-statement
> to check the card is SDUC
Theoretically yes.
But since it is exported (kernel test robot warning), we should protect from loadable modules callers.
Also, IMO it serves as some sort of documentation and improves readability.

Thanks,
Avri
> 
> > +       return mmc_wait_for_cmd(host, &cmd, 0); }
> > +EXPORT_SYMBOL_GPL(mmc_send_ext_addr);
> > +
> >  static int __mmc_send_if_cond(struct mmc_host *host, u32 ocr, u8 pcie_bits,
> >                               u32 *resp)  { diff --git
> > a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h index
> > 7667fc223b74..462efd43acfa 100644
> > --- a/drivers/mmc/core/sd_ops.h
> > +++ b/drivers/mmc/core/sd_ops.h
> > @@ -21,6 +21,7 @@ int mmc_send_relative_addr(struct mmc_host *host,
> > unsigned int *rca);  int mmc_app_send_scr(struct mmc_card *card);  int
> > mmc_app_sd_status(struct mmc_card *card, void *ssr);  int
> > mmc_app_cmd(struct mmc_host *host, struct mmc_card *card);
> > +int mmc_send_ext_addr(struct mmc_host *host, sector_t addr);
> >
> >  #endif
> >
> > diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index
> > 865cc0ca8543..af5fc70e09a2 100644
> > --- a/include/linux/mmc/sd.h
> > +++ b/include/linux/mmc/sd.h
> > @@ -15,6 +15,9 @@
> >  #define SD_SEND_IF_COND           8   /* bcr  [11:0] See below   R7
> > */
> >  #define SD_SWITCH_VOLTAGE         11  /* ac
> > R1  */
> >
> > +/* Class 2 */
> > +#define SD_ADDR_EXT             22   /* ac   [5:0]
> > R1  */
> > +
> >    /* class 10 */
> >  #define SD_SWITCH                 6   /* adtc [31:0] See below   R1
> > */
> >
> > --
> > 2.25.1
diff mbox series

Patch

diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
index 7f6963dac873..8b69129d7b61 100644
--- a/drivers/mmc/core/sd_ops.c
+++ b/drivers/mmc/core/sd_ops.c
@@ -199,6 +199,21 @@  int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
 	return 0;
 }
 
+int mmc_send_ext_addr(struct mmc_host *host, sector_t addr)
+{
+	struct mmc_command cmd = {
+		.opcode = SD_ADDR_EXT,
+		.arg = (u32)((addr >> 32) & 0x3F),
+		.flags = MMC_RSP_R1 | MMC_CMD_AC,
+	};
+
+	if (!mmc_card_is_sduc(host))
+		return 0;
+
+	return mmc_wait_for_cmd(host, &cmd, 0);
+}
+EXPORT_SYMBOL_GPL(mmc_send_ext_addr);
+
 static int __mmc_send_if_cond(struct mmc_host *host, u32 ocr, u8 pcie_bits,
 			      u32 *resp)
 {
diff --git a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h
index 7667fc223b74..462efd43acfa 100644
--- a/drivers/mmc/core/sd_ops.h
+++ b/drivers/mmc/core/sd_ops.h
@@ -21,6 +21,7 @@  int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca);
 int mmc_app_send_scr(struct mmc_card *card);
 int mmc_app_sd_status(struct mmc_card *card, void *ssr);
 int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card);
+int mmc_send_ext_addr(struct mmc_host *host, sector_t addr);
 
 #endif
 
diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h
index 865cc0ca8543..af5fc70e09a2 100644
--- a/include/linux/mmc/sd.h
+++ b/include/linux/mmc/sd.h
@@ -15,6 +15,9 @@ 
 #define SD_SEND_IF_COND           8   /* bcr  [11:0] See below   R7  */
 #define SD_SWITCH_VOLTAGE         11  /* ac                      R1  */
 
+/* Class 2 */
+#define SD_ADDR_EXT		 22   /* ac   [5:0]              R1  */
+
   /* class 10 */
 #define SD_SWITCH                 6   /* adtc [31:0] See below   R1  */