All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/3] mmc: Check support for TRIM operations
@ 2023-01-26  9:24 ` Loic Poulain
  2023-01-26  9:24   ` [PATCH v2 2/3] mmc: erase: Use TRIM erase when available Loic Poulain
                     ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Loic Poulain @ 2023-01-26  9:24 UTC (permalink / raw)
  To: sjg, peng.fan, jh80.chung; +Cc: u-boot, Loic Poulain

When secure/insecure TRIM operations are supported.
When used as erase command argument it applies the
erase operation to write blocks instead of erase
groups.

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
---
v2: Add mmc unit test change to the series

 drivers/mmc/mmc.c | 3 +++
 include/mmc.h     | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 210703ea46..e5f5ccb5f4 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -2432,6 +2432,9 @@ static int mmc_startup_v4(struct mmc *mmc)
 
 	mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
 
+	mmc->can_trim =
+		!!(ext_csd[EXT_CSD_SEC_FEATURE] & EXT_CSD_SEC_FEATURE_TRIM_EN);
+
 	return 0;
 error:
 	if (mmc->ext_csd) {
diff --git a/include/mmc.h b/include/mmc.h
index 571fa625d0..f6e23625ca 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -241,6 +241,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #define EXT_CSD_HC_WP_GRP_SIZE		221	/* RO */
 #define EXT_CSD_HC_ERASE_GRP_SIZE	224	/* RO */
 #define EXT_CSD_BOOT_MULT		226	/* RO */
+#define EXT_CSD_SEC_FEATURE		231	/* RO */
 #define EXT_CSD_GENERIC_CMD6_TIME       248     /* RO */
 #define EXT_CSD_BKOPS_SUPPORT		502	/* RO */
 
@@ -315,6 +316,8 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #define EXT_CSD_WR_DATA_REL_USR		(1 << 0)	/* user data area WR_REL */
 #define EXT_CSD_WR_DATA_REL_GP(x)	(1 << ((x)+1))	/* GP part (x+1) WR_REL */
 
+#define EXT_CSD_SEC_FEATURE_TRIM_EN	(1 << 4) /* Support secure & insecure trim */
+
 #define R1_ILLEGAL_COMMAND		(1 << 22)
 #define R1_APP_CMD			(1 << 5)
 
@@ -687,6 +690,7 @@ struct mmc {
 	uint tran_speed;
 	uint legacy_speed; /* speed for the legacy mode provided by the card */
 	uint read_bl_len;
+	bool can_trim;
 #if CONFIG_IS_ENABLED(MMC_WRITE)
 	uint write_bl_len;
 	uint erase_grp_size;	/* in 512-byte sectors */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 2/3] mmc: erase: Use TRIM erase when available
  2023-01-26  9:24 ` [PATCH v2 1/3] mmc: Check support for TRIM operations Loic Poulain
@ 2023-01-26  9:24   ` Loic Poulain
  2023-01-28 22:01     ` Simon Glass
                       ` (2 more replies)
  2023-01-26  9:24   ` [PATCH v2 3/3] test: dm: mmc: Check block erasing boundaries Loic Poulain
                     ` (3 subsequent siblings)
  4 siblings, 3 replies; 15+ messages in thread
From: Loic Poulain @ 2023-01-26  9:24 UTC (permalink / raw)
  To: sjg, peng.fan, jh80.chung; +Cc: u-boot, Loic Poulain

The default erase command applies on erase group unit, and
simply round down to erase group size. When the start block
is not aligned to erase group size (e.g. erasing partition)
it causes unwanted erasing of the previous blocks, part of
the same erase group (e.g. owned by other logical partition,
or by the partition table itself).

To prevent this issue, a simple solution is to use TRIM as
argument of the Erase command, which is usually supported
with eMMC > 4.0, and allow to apply erase operation to write
blocks instead of erase group

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
---
v2: Add mmc unit test change to the series

 drivers/mmc/mmc_write.c | 34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
index 5b7aeeb012..a6f93380dd 100644
--- a/drivers/mmc/mmc_write.c
+++ b/drivers/mmc/mmc_write.c
@@ -15,7 +15,7 @@
 #include <linux/math64.h>
 #include "mmc_private.h"
 
-static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
+static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, u32 args)
 {
 	struct mmc_cmd cmd;
 	ulong end;
@@ -52,7 +52,7 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
 		goto err_out;
 
 	cmd.cmdidx = MMC_CMD_ERASE;
-	cmd.cmdarg = MMC_ERASE_ARG;
+	cmd.cmdarg = args ? args : MMC_ERASE_ARG;
 	cmd.resp_type = MMC_RSP_R1b;
 
 	err = mmc_send_cmd(mmc, &cmd, NULL);
@@ -77,7 +77,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
 #endif
 	int dev_num = block_dev->devnum;
 	int err = 0;
-	u32 start_rem, blkcnt_rem;
+	u32 start_rem, blkcnt_rem, erase_args = 0;
 	struct mmc *mmc = find_mmc_device(dev_num);
 	lbaint_t blk = 0, blk_r = 0;
 	int timeout_ms = 1000;
@@ -97,13 +97,25 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
 	 */
 	err = div_u64_rem(start, mmc->erase_grp_size, &start_rem);
 	err = div_u64_rem(blkcnt, mmc->erase_grp_size, &blkcnt_rem);
-	if (start_rem || blkcnt_rem)
-		printf("\n\nCaution! Your devices Erase group is 0x%x\n"
-		       "The erase range would be change to "
-		       "0x" LBAF "~0x" LBAF "\n\n",
-		       mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
-		       ((start + blkcnt + mmc->erase_grp_size - 1)
-		       & ~(mmc->erase_grp_size - 1)) - 1);
+	if (start_rem || blkcnt_rem) {
+		if (mmc->can_trim) {
+			/* Trim function applies the erase operation to write
+			 * blocks instead of erase groups.
+			 */
+			erase_args = MMC_TRIM_ARG;
+		} else {
+			/* The card ignores all LSB's below the erase group
+			 * size, rounding down the addess to a erase group
+			 * boundary.
+			 */
+			printf("\n\nCaution! Your devices Erase group is 0x%x\n"
+			       "The erase range would be change to "
+			       "0x" LBAF "~0x" LBAF "\n\n",
+			       mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
+			       ((start + blkcnt + mmc->erase_grp_size - 1)
+			       & ~(mmc->erase_grp_size - 1)) - 1);
+		}
+	}
 
 	while (blk < blkcnt) {
 		if (IS_SD(mmc) && mmc->ssr.au) {
@@ -113,7 +125,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
 			blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
 				mmc->erase_grp_size : (blkcnt - blk);
 		}
-		err = mmc_erase_t(mmc, start + blk, blk_r);
+		err = mmc_erase_t(mmc, start + blk, blk_r, erase_args);
 		if (err)
 			break;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v2 3/3] test: dm: mmc: Check block erasing boundaries
  2023-01-26  9:24 ` [PATCH v2 1/3] mmc: Check support for TRIM operations Loic Poulain
  2023-01-26  9:24   ` [PATCH v2 2/3] mmc: erase: Use TRIM erase when available Loic Poulain
@ 2023-01-26  9:24   ` Loic Poulain
  2023-01-27 14:30     ` Simon Glass
       [not found]     ` <CGME20230310023206epcas1p1df08c1dbe2cb70efdd91ef47d7e95c78@epcas1p1.samsung.com>
  2023-01-28 22:01   ` [PATCH v2 1/3] mmc: Check support for TRIM operations Simon Glass
                     ` (2 subsequent siblings)
  4 siblings, 2 replies; 15+ messages in thread
From: Loic Poulain @ 2023-01-26  9:24 UTC (permalink / raw)
  To: sjg, peng.fan, jh80.chung; +Cc: u-boot, Loic Poulain

Verify that erasing blocks does not impact adjacent ones.
- Write four blocks [0 1 2 3]
- Erase two blocks [ 1 2 ]
- Verify [0 1 2 3 ]

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
---
v2: Add this change to the series

 test/dm/mmc.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/test/dm/mmc.c b/test/dm/mmc.c
index f744452ff2..b1eb8bee2f 100644
--- a/test/dm/mmc.c
+++ b/test/dm/mmc.c
@@ -30,7 +30,7 @@ static int dm_test_mmc_blk(struct unit_test_state *uts)
 	struct udevice *dev;
 	struct blk_desc *dev_desc;
 	int i;
-	char write[1024], read[1024];
+	char write[4 * 512], read[4 * 512];
 
 	ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
 	ut_assertok(blk_get_device_by_str("mmc", "0", &dev_desc));
@@ -39,14 +39,14 @@ static int dm_test_mmc_blk(struct unit_test_state *uts)
 	ut_asserteq(512, dev_desc->blksz);
 	for (i = 0; i < sizeof(write); i++)
 		write[i] = i;
-	ut_asserteq(2, blk_dwrite(dev_desc, 0, 2, write));
-	ut_asserteq(2, blk_dread(dev_desc, 0, 2, read));
+	ut_asserteq(4, blk_dwrite(dev_desc, 0, 4, write));
+	ut_asserteq(4, blk_dread(dev_desc, 0, 4, read));
 	ut_asserteq_mem(write, read, sizeof(write));
 
-	/* Now erase them */
-	memset(write, '\0', sizeof(write));
-	ut_asserteq(2, blk_derase(dev_desc, 0, 2));
-	ut_asserteq(2, blk_dread(dev_desc, 0, 2, read));
+	/* Now erase two of them [1 - 2] and verify all blocks */
+	memset(&write[512], '\0', 2 * 512);
+	ut_asserteq(2, blk_derase(dev_desc, 1, 2));
+	ut_asserteq(4, blk_dread(dev_desc, 0, 4, read));
 	ut_asserteq_mem(write, read, sizeof(write));
 
 	return 0;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 3/3] test: dm: mmc: Check block erasing boundaries
  2023-01-26  9:24   ` [PATCH v2 3/3] test: dm: mmc: Check block erasing boundaries Loic Poulain
@ 2023-01-27 14:30     ` Simon Glass
  2023-02-08  8:13       ` Loic Poulain
       [not found]     ` <CGME20230310023206epcas1p1df08c1dbe2cb70efdd91ef47d7e95c78@epcas1p1.samsung.com>
  1 sibling, 1 reply; 15+ messages in thread
From: Simon Glass @ 2023-01-27 14:30 UTC (permalink / raw)
  To: Loic Poulain; +Cc: peng.fan, jh80.chung, u-boot

Hi Loic,

On Thu, 26 Jan 2023 at 02:24, Loic Poulain <loic.poulain@linaro.org> wrote:
>
> Verify that erasing blocks does not impact adjacent ones.
> - Write four blocks [0 1 2 3]
> - Erase two blocks [ 1 2 ]
> - Verify [0 1 2 3 ]
>
> Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
> ---
> v2: Add this change to the series
>
>  test/dm/mmc.c | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)

This looks good, but can you add the trim command to
sandbox_mmc_send_cmd()? Then you can test that as well.


>
> diff --git a/test/dm/mmc.c b/test/dm/mmc.c
> index f744452ff2..b1eb8bee2f 100644
> --- a/test/dm/mmc.c
> +++ b/test/dm/mmc.c
> @@ -30,7 +30,7 @@ static int dm_test_mmc_blk(struct unit_test_state *uts)
>         struct udevice *dev;
>         struct blk_desc *dev_desc;
>         int i;
> -       char write[1024], read[1024];
> +       char write[4 * 512], read[4 * 512];
>
>         ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
>         ut_assertok(blk_get_device_by_str("mmc", "0", &dev_desc));
> @@ -39,14 +39,14 @@ static int dm_test_mmc_blk(struct unit_test_state *uts)
>         ut_asserteq(512, dev_desc->blksz);
>         for (i = 0; i < sizeof(write); i++)
>                 write[i] = i;
> -       ut_asserteq(2, blk_dwrite(dev_desc, 0, 2, write));
> -       ut_asserteq(2, blk_dread(dev_desc, 0, 2, read));
> +       ut_asserteq(4, blk_dwrite(dev_desc, 0, 4, write));
> +       ut_asserteq(4, blk_dread(dev_desc, 0, 4, read));
>         ut_asserteq_mem(write, read, sizeof(write));
>
> -       /* Now erase them */
> -       memset(write, '\0', sizeof(write));
> -       ut_asserteq(2, blk_derase(dev_desc, 0, 2));
> -       ut_asserteq(2, blk_dread(dev_desc, 0, 2, read));
> +       /* Now erase two of them [1 - 2] and verify all blocks */
> +       memset(&write[512], '\0', 2 * 512);
> +       ut_asserteq(2, blk_derase(dev_desc, 1, 2));
> +       ut_asserteq(4, blk_dread(dev_desc, 0, 4, read));
>         ut_asserteq_mem(write, read, sizeof(write));
>
>         return 0;
> --
> 2.34.1
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/3] mmc: Check support for TRIM operations
  2023-01-26  9:24 ` [PATCH v2 1/3] mmc: Check support for TRIM operations Loic Poulain
  2023-01-26  9:24   ` [PATCH v2 2/3] mmc: erase: Use TRIM erase when available Loic Poulain
  2023-01-26  9:24   ` [PATCH v2 3/3] test: dm: mmc: Check block erasing boundaries Loic Poulain
@ 2023-01-28 22:01   ` Simon Glass
  2023-02-06  4:54   ` Jaehoon Chung
       [not found]   ` <CGME20230310023103epcas1p4e4763c672faff833c978f8e91252119c@epcas1p4.samsung.com>
  4 siblings, 0 replies; 15+ messages in thread
From: Simon Glass @ 2023-01-28 22:01 UTC (permalink / raw)
  To: Loic Poulain; +Cc: peng.fan, jh80.chung, u-boot

On Thu, 26 Jan 2023 at 02:24, Loic Poulain <loic.poulain@linaro.org> wrote:
>
> When secure/insecure TRIM operations are supported.
> When used as erase command argument it applies the
> erase operation to write blocks instead of erase
> groups.
>
> Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
> ---
> v2: Add mmc unit test change to the series
>
>  drivers/mmc/mmc.c | 3 +++
>  include/mmc.h     | 4 ++++
>  2 files changed, 7 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/3] mmc: erase: Use TRIM erase when available
  2023-01-26  9:24   ` [PATCH v2 2/3] mmc: erase: Use TRIM erase when available Loic Poulain
@ 2023-01-28 22:01     ` Simon Glass
  2023-02-01 11:39       ` Loic Poulain
  2023-02-06  5:05     ` Jaehoon Chung
       [not found]     ` <CGME20230310023122epcas1p2e19d3aa9274c88d14992bd878dc8d1ca@epcas1p2.samsung.com>
  2 siblings, 1 reply; 15+ messages in thread
From: Simon Glass @ 2023-01-28 22:01 UTC (permalink / raw)
  To: Loic Poulain; +Cc: peng.fan, jh80.chung, u-boot

Hi Loic,

On Thu, 26 Jan 2023 at 02:24, Loic Poulain <loic.poulain@linaro.org> wrote:
>
> The default erase command applies on erase group unit, and
> simply round down to erase group size. When the start block
> is not aligned to erase group size (e.g. erasing partition)
> it causes unwanted erasing of the previous blocks, part of
> the same erase group (e.g. owned by other logical partition,
> or by the partition table itself).
>
> To prevent this issue, a simple solution is to use TRIM as
> argument of the Erase command, which is usually supported
> with eMMC > 4.0, and allow to apply erase operation to write
> blocks instead of erase group
>
> Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
> ---
> v2: Add mmc unit test change to the series
>
>  drivers/mmc/mmc_write.c | 34 +++++++++++++++++++++++-----------
>  1 file changed, 23 insertions(+), 11 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

Please see below

>
> diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
> index 5b7aeeb012..a6f93380dd 100644
> --- a/drivers/mmc/mmc_write.c
> +++ b/drivers/mmc/mmc_write.c
> @@ -15,7 +15,7 @@
>  #include <linux/math64.h>
>  #include "mmc_private.h"
>
> -static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
> +static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, u32 args)
>  {
>         struct mmc_cmd cmd;
>         ulong end;
> @@ -52,7 +52,7 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
>                 goto err_out;
>
>         cmd.cmdidx = MMC_CMD_ERASE;
> -       cmd.cmdarg = MMC_ERASE_ARG;
> +       cmd.cmdarg = args ? args : MMC_ERASE_ARG;
>         cmd.resp_type = MMC_RSP_R1b;
>
>         err = mmc_send_cmd(mmc, &cmd, NULL);
> @@ -77,7 +77,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
>  #endif
>         int dev_num = block_dev->devnum;
>         int err = 0;
> -       u32 start_rem, blkcnt_rem;
> +       u32 start_rem, blkcnt_rem, erase_args = 0;
>         struct mmc *mmc = find_mmc_device(dev_num);
>         lbaint_t blk = 0, blk_r = 0;
>         int timeout_ms = 1000;
> @@ -97,13 +97,25 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
>          */
>         err = div_u64_rem(start, mmc->erase_grp_size, &start_rem);
>         err = div_u64_rem(blkcnt, mmc->erase_grp_size, &blkcnt_rem);
> -       if (start_rem || blkcnt_rem)
> -               printf("\n\nCaution! Your devices Erase group is 0x%x\n"
> -                      "The erase range would be change to "
> -                      "0x" LBAF "~0x" LBAF "\n\n",
> -                      mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
> -                      ((start + blkcnt + mmc->erase_grp_size - 1)
> -                      & ~(mmc->erase_grp_size - 1)) - 1);
> +       if (start_rem || blkcnt_rem) {
> +               if (mmc->can_trim) {
> +                       /* Trim function applies the erase operation to write
> +                        * blocks instead of erase groups.
> +                        */
> +                       erase_args = MMC_TRIM_ARG;
> +               } else {
> +                       /* The card ignores all LSB's below the erase group
> +                        * size, rounding down the addess to a erase group
> +                        * boundary.
> +                        */
> +                       printf("\n\nCaution! Your devices Erase group is 0x%x\n"
> +                              "The erase range would be change to "
> +                              "0x" LBAF "~0x" LBAF "\n\n",
> +                              mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
> +                              ((start + blkcnt + mmc->erase_grp_size - 1)
> +                              & ~(mmc->erase_grp_size - 1)) - 1);

Should this return an error, or just go ahead?

> +               }
> +       }
>
>         while (blk < blkcnt) {
>                 if (IS_SD(mmc) && mmc->ssr.au) {
> @@ -113,7 +125,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
>                         blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
>                                 mmc->erase_grp_size : (blkcnt - blk);
>                 }
> -               err = mmc_erase_t(mmc, start + blk, blk_r);
> +               err = mmc_erase_t(mmc, start + blk, blk_r, erase_args);
>                 if (err)
>                         break;
>
> --
> 2.34.1
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/3] mmc: erase: Use TRIM erase when available
  2023-01-28 22:01     ` Simon Glass
@ 2023-02-01 11:39       ` Loic Poulain
  0 siblings, 0 replies; 15+ messages in thread
From: Loic Poulain @ 2023-02-01 11:39 UTC (permalink / raw)
  To: Simon Glass; +Cc: peng.fan, jh80.chung, u-boot

Hi Simon,

On Sat, 28 Jan 2023 at 23:01, Simon Glass <sjg@chromium.org> wrote:
>
> Hi Loic,
>
> On Thu, 26 Jan 2023 at 02:24, Loic Poulain <loic.poulain@linaro.org> wrote:
> >
> > The default erase command applies on erase group unit, and
> > simply round down to erase group size. When the start block
> > is not aligned to erase group size (e.g. erasing partition)
> > it causes unwanted erasing of the previous blocks, part of
> > the same erase group (e.g. owned by other logical partition,
> > or by the partition table itself).
> >
> > To prevent this issue, a simple solution is to use TRIM as
> > argument of the Erase command, which is usually supported
> > with eMMC > 4.0, and allow to apply erase operation to write
> > blocks instead of erase group
> >
> > Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
> > ---
> > v2: Add mmc unit test change to the series
> >
> >  drivers/mmc/mmc_write.c | 34 +++++++++++++++++++++++-----------
> >  1 file changed, 23 insertions(+), 11 deletions(-)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Please see below
>
> >
> > diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
> > index 5b7aeeb012..a6f93380dd 100644
> > --- a/drivers/mmc/mmc_write.c
> > +++ b/drivers/mmc/mmc_write.c
> > @@ -15,7 +15,7 @@
> >  #include <linux/math64.h>
> >  #include "mmc_private.h"
> >
> > -static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
> > +static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, u32 args)
> >  {
> >         struct mmc_cmd cmd;
> >         ulong end;
> > @@ -52,7 +52,7 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
> >                 goto err_out;
> >
> >         cmd.cmdidx = MMC_CMD_ERASE;
> > -       cmd.cmdarg = MMC_ERASE_ARG;
> > +       cmd.cmdarg = args ? args : MMC_ERASE_ARG;
> >         cmd.resp_type = MMC_RSP_R1b;
> >
> >         err = mmc_send_cmd(mmc, &cmd, NULL);
> > @@ -77,7 +77,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
> >  #endif
> >         int dev_num = block_dev->devnum;
> >         int err = 0;
> > -       u32 start_rem, blkcnt_rem;
> > +       u32 start_rem, blkcnt_rem, erase_args = 0;
> >         struct mmc *mmc = find_mmc_device(dev_num);
> >         lbaint_t blk = 0, blk_r = 0;
> >         int timeout_ms = 1000;
> > @@ -97,13 +97,25 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
> >          */
> >         err = div_u64_rem(start, mmc->erase_grp_size, &start_rem);
> >         err = div_u64_rem(blkcnt, mmc->erase_grp_size, &blkcnt_rem);
> > -       if (start_rem || blkcnt_rem)
> > -               printf("\n\nCaution! Your devices Erase group is 0x%x\n"
> > -                      "The erase range would be change to "
> > -                      "0x" LBAF "~0x" LBAF "\n\n",
> > -                      mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
> > -                      ((start + blkcnt + mmc->erase_grp_size - 1)
> > -                      & ~(mmc->erase_grp_size - 1)) - 1);
> > +       if (start_rem || blkcnt_rem) {
> > +               if (mmc->can_trim) {
> > +                       /* Trim function applies the erase operation to write
> > +                        * blocks instead of erase groups.
> > +                        */
> > +                       erase_args = MMC_TRIM_ARG;
> > +               } else {
> > +                       /* The card ignores all LSB's below the erase group
> > +                        * size, rounding down the addess to a erase group
> > +                        * boundary.
> > +                        */
> > +                       printf("\n\nCaution! Your devices Erase group is 0x%x\n"
> > +                              "The erase range would be change to "
> > +                              "0x" LBAF "~0x" LBAF "\n\n",
> > +                              mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
> > +                              ((start + blkcnt + mmc->erase_grp_size - 1)
> > +                              & ~(mmc->erase_grp_size - 1)) - 1);
>
> Should this return an error, or just go ahead?

It would indeed make sense to return an error since mmc_erase does not
perform what we expect. Now, since this behavior exists for a while,
we may also want to keep it for legacy, though it should be a corner
case...

Regards,
Loic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH v2 1/3] mmc: Check support for TRIM operations
  2023-01-26  9:24 ` [PATCH v2 1/3] mmc: Check support for TRIM operations Loic Poulain
                     ` (2 preceding siblings ...)
  2023-01-28 22:01   ` [PATCH v2 1/3] mmc: Check support for TRIM operations Simon Glass
@ 2023-02-06  4:54   ` Jaehoon Chung
       [not found]   ` <CGME20230310023103epcas1p4e4763c672faff833c978f8e91252119c@epcas1p4.samsung.com>
  4 siblings, 0 replies; 15+ messages in thread
From: Jaehoon Chung @ 2023-02-06  4:54 UTC (permalink / raw)
  To: 'Loic Poulain', sjg, peng.fan; +Cc: u-boot



> -----Original Message-----
> From: Loic Poulain <loic.poulain@linaro.org>
> Sent: Thursday, January 26, 2023 6:24 PM
> To: sjg@chromium.org; peng.fan@nxp.com; jh80.chung@samsung.com
> Cc: u-boot@lists.denx.de; Loic Poulain <loic.poulain@linaro.org>
> Subject: [PATCH v2 1/3] mmc: Check support for TRIM operations
> 
> When secure/insecure TRIM operations are supported.
> When used as erase command argument it applies the
> erase operation to write blocks instead of erase
> groups.
> 
> Signed-off-by: Loic Poulain <loic.poulain@linaro.org>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
> v2: Add mmc unit test change to the series
> 
>  drivers/mmc/mmc.c | 3 +++
>  include/mmc.h     | 4 ++++
>  2 files changed, 7 insertions(+)
> 
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 210703ea46..e5f5ccb5f4 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -2432,6 +2432,9 @@ static int mmc_startup_v4(struct mmc *mmc)
> 
>  	mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
> 
> +	mmc->can_trim =
> +		!!(ext_csd[EXT_CSD_SEC_FEATURE] & EXT_CSD_SEC_FEATURE_TRIM_EN);
> +
>  	return 0;
>  error:
>  	if (mmc->ext_csd) {
> diff --git a/include/mmc.h b/include/mmc.h
> index 571fa625d0..f6e23625ca 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -241,6 +241,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
>  #define EXT_CSD_HC_WP_GRP_SIZE		221	/* RO */
>  #define EXT_CSD_HC_ERASE_GRP_SIZE	224	/* RO */
>  #define EXT_CSD_BOOT_MULT		226	/* RO */
> +#define EXT_CSD_SEC_FEATURE		231	/* RO */
>  #define EXT_CSD_GENERIC_CMD6_TIME       248     /* RO */
>  #define EXT_CSD_BKOPS_SUPPORT		502	/* RO */
> 
> @@ -315,6 +316,8 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
>  #define EXT_CSD_WR_DATA_REL_USR		(1 << 0)	/* user data area WR_REL */
>  #define EXT_CSD_WR_DATA_REL_GP(x)	(1 << ((x)+1))	/* GP part (x+1) WR_REL */
> 
> +#define EXT_CSD_SEC_FEATURE_TRIM_EN	(1 << 4) /* Support secure & insecure trim */
> +
>  #define R1_ILLEGAL_COMMAND		(1 << 22)
>  #define R1_APP_CMD			(1 << 5)
> 
> @@ -687,6 +690,7 @@ struct mmc {
>  	uint tran_speed;
>  	uint legacy_speed; /* speed for the legacy mode provided by the card */
>  	uint read_bl_len;
> +	bool can_trim;
>  #if CONFIG_IS_ENABLED(MMC_WRITE)
>  	uint write_bl_len;
>  	uint erase_grp_size;	/* in 512-byte sectors */
> --
> 2.34.1



^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH v2 2/3] mmc: erase: Use TRIM erase when available
  2023-01-26  9:24   ` [PATCH v2 2/3] mmc: erase: Use TRIM erase when available Loic Poulain
  2023-01-28 22:01     ` Simon Glass
@ 2023-02-06  5:05     ` Jaehoon Chung
  2023-02-08  8:08       ` Loic Poulain
       [not found]     ` <CGME20230310023122epcas1p2e19d3aa9274c88d14992bd878dc8d1ca@epcas1p2.samsung.com>
  2 siblings, 1 reply; 15+ messages in thread
From: Jaehoon Chung @ 2023-02-06  5:05 UTC (permalink / raw)
  To: 'Loic Poulain', sjg, peng.fan; +Cc: u-boot

Hi,

> -----Original Message-----
> From: Loic Poulain <loic.poulain@linaro.org>
> Sent: Thursday, January 26, 2023 6:24 PM
> To: sjg@chromium.org; peng.fan@nxp.com; jh80.chung@samsung.com
> Cc: u-boot@lists.denx.de; Loic Poulain <loic.poulain@linaro.org>
> Subject: [PATCH v2 2/3] mmc: erase: Use TRIM erase when available
> 
> The default erase command applies on erase group unit, and
> simply round down to erase group size. When the start block
> is not aligned to erase group size (e.g. erasing partition)
> it causes unwanted erasing of the previous blocks, part of
> the same erase group (e.g. owned by other logical partition,
> or by the partition table itself).
> 
> To prevent this issue, a simple solution is to use TRIM as
> argument of the Erase command, which is usually supported
> with eMMC > 4.0, and allow to apply erase operation to write
> blocks instead of erase group
> 
> Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
> ---
> v2: Add mmc unit test change to the series
> 
>  drivers/mmc/mmc_write.c | 34 +++++++++++++++++++++++-----------
>  1 file changed, 23 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
> index 5b7aeeb012..a6f93380dd 100644
> --- a/drivers/mmc/mmc_write.c
> +++ b/drivers/mmc/mmc_write.c
> @@ -15,7 +15,7 @@
>  #include <linux/math64.h>
>  #include "mmc_private.h"
> 
> -static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
> +static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, u32 args)
>  {
>  	struct mmc_cmd cmd;
>  	ulong end;
> @@ -52,7 +52,7 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
>  		goto err_out;
> 
>  	cmd.cmdidx = MMC_CMD_ERASE;
> -	cmd.cmdarg = MMC_ERASE_ARG;
> +	cmd.cmdarg = args ? args : MMC_ERASE_ARG;

It there any case to pass by other value?

Best Regards,
Jaehoon Chung

>  	cmd.resp_type = MMC_RSP_R1b;
> 
>  	err = mmc_send_cmd(mmc, &cmd, NULL);
> @@ -77,7 +77,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
>  #endif
>  	int dev_num = block_dev->devnum;
>  	int err = 0;
> -	u32 start_rem, blkcnt_rem;
> +	u32 start_rem, blkcnt_rem, erase_args = 0;
>  	struct mmc *mmc = find_mmc_device(dev_num);
>  	lbaint_t blk = 0, blk_r = 0;
>  	int timeout_ms = 1000;
> @@ -97,13 +97,25 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
>  	 */
>  	err = div_u64_rem(start, mmc->erase_grp_size, &start_rem);
>  	err = div_u64_rem(blkcnt, mmc->erase_grp_size, &blkcnt_rem);
> -	if (start_rem || blkcnt_rem)
> -		printf("\n\nCaution! Your devices Erase group is 0x%x\n"
> -		       "The erase range would be change to "
> -		       "0x" LBAF "~0x" LBAF "\n\n",
> -		       mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
> -		       ((start + blkcnt + mmc->erase_grp_size - 1)
> -		       & ~(mmc->erase_grp_size - 1)) - 1);
> +	if (start_rem || blkcnt_rem) {
> +		if (mmc->can_trim) {
> +			/* Trim function applies the erase operation to write
> +			 * blocks instead of erase groups.
> +			 */
> +			erase_args = MMC_TRIM_ARG;
> +		} else {
> +			/* The card ignores all LSB's below the erase group
> +			 * size, rounding down the addess to a erase group
> +			 * boundary.
> +			 */
> +			printf("\n\nCaution! Your devices Erase group is 0x%x\n"
> +			       "The erase range would be change to "
> +			       "0x" LBAF "~0x" LBAF "\n\n",
> +			       mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
> +			       ((start + blkcnt + mmc->erase_grp_size - 1)
> +			       & ~(mmc->erase_grp_size - 1)) - 1);
> +		}
> +	}
> 
>  	while (blk < blkcnt) {
>  		if (IS_SD(mmc) && mmc->ssr.au) {
> @@ -113,7 +125,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
>  			blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
>  				mmc->erase_grp_size : (blkcnt - blk);
>  		}
> -		err = mmc_erase_t(mmc, start + blk, blk_r);
> +		err = mmc_erase_t(mmc, start + blk, blk_r, erase_args);
>  		if (err)
>  			break;
> 
> --
> 2.34.1



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/3] mmc: erase: Use TRIM erase when available
  2023-02-06  5:05     ` Jaehoon Chung
@ 2023-02-08  8:08       ` Loic Poulain
  2023-02-08  9:03         ` Jaehoon Chung
  0 siblings, 1 reply; 15+ messages in thread
From: Loic Poulain @ 2023-02-08  8:08 UTC (permalink / raw)
  To: Jaehoon Chung; +Cc: sjg, peng.fan, u-boot

Hi Jaehoon,

On Mon, 6 Feb 2023 at 06:05, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>
> Hi,
>
> > -----Original Message-----
> > From: Loic Poulain <loic.poulain@linaro.org>
> > Sent: Thursday, January 26, 2023 6:24 PM
> > To: sjg@chromium.org; peng.fan@nxp.com; jh80.chung@samsung.com
> > Cc: u-boot@lists.denx.de; Loic Poulain <loic.poulain@linaro.org>
> > Subject: [PATCH v2 2/3] mmc: erase: Use TRIM erase when available
> >
> > The default erase command applies on erase group unit, and
> > simply round down to erase group size. When the start block
> > is not aligned to erase group size (e.g. erasing partition)
> > it causes unwanted erasing of the previous blocks, part of
> > the same erase group (e.g. owned by other logical partition,
> > or by the partition table itself).
> >
> > To prevent this issue, a simple solution is to use TRIM as
> > argument of the Erase command, which is usually supported
> > with eMMC > 4.0, and allow to apply erase operation to write
> > blocks instead of erase group
> >
> > Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
> > ---
> > v2: Add mmc unit test change to the series
> >
> >  drivers/mmc/mmc_write.c | 34 +++++++++++++++++++++++-----------
> >  1 file changed, 23 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
> > index 5b7aeeb012..a6f93380dd 100644
> > --- a/drivers/mmc/mmc_write.c
> > +++ b/drivers/mmc/mmc_write.c
> > @@ -15,7 +15,7 @@
> >  #include <linux/math64.h>
> >  #include "mmc_private.h"
> >
> > -static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
> > +static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, u32 args)
> >  {
> >       struct mmc_cmd cmd;
> >       ulong end;
> > @@ -52,7 +52,7 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
> >               goto err_out;
> >
> >       cmd.cmdidx = MMC_CMD_ERASE;
> > -     cmd.cmdarg = MMC_ERASE_ARG;
> > +     cmd.cmdarg = args ? args : MMC_ERASE_ARG;
>
> It there any case to pass by other value?

Not at the moment, but it can be used to support eMMC 'Secure Erase' arg.

Regards,
Loic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 3/3] test: dm: mmc: Check block erasing boundaries
  2023-01-27 14:30     ` Simon Glass
@ 2023-02-08  8:13       ` Loic Poulain
  0 siblings, 0 replies; 15+ messages in thread
From: Loic Poulain @ 2023-02-08  8:13 UTC (permalink / raw)
  To: Simon Glass; +Cc: peng.fan, jh80.chung, u-boot

On Fri, 27 Jan 2023 at 15:30, Simon Glass <sjg@chromium.org> wrote:
>
> Hi Loic,
>
> On Thu, 26 Jan 2023 at 02:24, Loic Poulain <loic.poulain@linaro.org> wrote:
> >
> > Verify that erasing blocks does not impact adjacent ones.
> > - Write four blocks [0 1 2 3]
> > - Erase two blocks [ 1 2 ]
> > - Verify [0 1 2 3 ]
> >
> > Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
> > ---
> > v2: Add this change to the series
> >
> >  test/dm/mmc.c | 14 +++++++-------
> >  1 file changed, 7 insertions(+), 7 deletions(-)
>
> This looks good, but can you add the trim command to
> sandbox_mmc_send_cmd()? Then you can test that as well.

The TRIM option is not exposed, it is internally managed inside mmc
depending on the need for it. So from a testing perspective, I can
only test that the mmc erase is doing what we ask correctly.

Regards,
Loic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH v2 2/3] mmc: erase: Use TRIM erase when available
  2023-02-08  8:08       ` Loic Poulain
@ 2023-02-08  9:03         ` Jaehoon Chung
  0 siblings, 0 replies; 15+ messages in thread
From: Jaehoon Chung @ 2023-02-08  9:03 UTC (permalink / raw)
  To: 'Loic Poulain'; +Cc: sjg, peng.fan, u-boot

Hi Loic,

> -----Original Message-----
> From: Loic Poulain <loic.poulain@linaro.org>
> Sent: Wednesday, February 8, 2023 5:09 PM
> To: Jaehoon Chung <jh80.chung@samsung.com>
> Cc: sjg@chromium.org; peng.fan@nxp.com; u-boot@lists.denx.de
> Subject: Re: [PATCH v2 2/3] mmc: erase: Use TRIM erase when available
> 
> Hi Jaehoon,
> 
> On Mon, 6 Feb 2023 at 06:05, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> >
> > Hi,
> >
> > > -----Original Message-----
> > > From: Loic Poulain <loic.poulain@linaro.org>
> > > Sent: Thursday, January 26, 2023 6:24 PM
> > > To: sjg@chromium.org; peng.fan@nxp.com; jh80.chung@samsung.com
> > > Cc: u-boot@lists.denx.de; Loic Poulain <loic.poulain@linaro.org>
> > > Subject: [PATCH v2 2/3] mmc: erase: Use TRIM erase when available
> > >
> > > The default erase command applies on erase group unit, and
> > > simply round down to erase group size. When the start block
> > > is not aligned to erase group size (e.g. erasing partition)
> > > it causes unwanted erasing of the previous blocks, part of
> > > the same erase group (e.g. owned by other logical partition,
> > > or by the partition table itself).
> > >
> > > To prevent this issue, a simple solution is to use TRIM as
> > > argument of the Erase command, which is usually supported
> > > with eMMC > 4.0, and allow to apply erase operation to write
> > > blocks instead of erase group
> > >
> > > Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
> > > ---
> > > v2: Add mmc unit test change to the series
> > >
> > >  drivers/mmc/mmc_write.c | 34 +++++++++++++++++++++++-----------
> > >  1 file changed, 23 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
> > > index 5b7aeeb012..a6f93380dd 100644
> > > --- a/drivers/mmc/mmc_write.c
> > > +++ b/drivers/mmc/mmc_write.c
> > > @@ -15,7 +15,7 @@
> > >  #include <linux/math64.h>
> > >  #include "mmc_private.h"
> > >
> > > -static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
> > > +static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, u32 args)
> > >  {
> > >       struct mmc_cmd cmd;
> > >       ulong end;
> > > @@ -52,7 +52,7 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
> > >               goto err_out;
> > >
> > >       cmd.cmdidx = MMC_CMD_ERASE;
> > > -     cmd.cmdarg = MMC_ERASE_ARG;
> > > +     cmd.cmdarg = args ? args : MMC_ERASE_ARG;
> >
> > It there any case to pass by other value?
> 
> Not at the moment, but it can be used to support eMMC 'Secure Erase' arg.

I had mis-read. I had read the MMC_TRIM_ARG as MMC_ERASE_ARG. Thanks for kindly explanation. :)

Best Regards,
Jaehoon Chung

> 
> Regards,
> Loic


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 1/3] mmc: Check support for TRIM operations
       [not found]   ` <CGME20230310023103epcas1p4e4763c672faff833c978f8e91252119c@epcas1p4.samsung.com>
@ 2023-03-10  2:31     ` Jaehoon Chung
  0 siblings, 0 replies; 15+ messages in thread
From: Jaehoon Chung @ 2023-03-10  2:31 UTC (permalink / raw)
  To: Loic Poulain, sjg, peng.fan; +Cc: u-boot

On 1/26/23 18:24, Loic Poulain wrote:
> When secure/insecure TRIM operations are supported.
> When used as erase command argument it applies the
> erase operation to write blocks instead of erase
> groups.
> 
> Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>


Applied to u-boot-mmc/master.

Best Regards,
Jaehoon Chung


> ---
> v2: Add mmc unit test change to the series
> 
>  drivers/mmc/mmc.c | 3 +++
>  include/mmc.h     | 4 ++++
>  2 files changed, 7 insertions(+)
> 
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 210703ea46..e5f5ccb5f4 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -2432,6 +2432,9 @@ static int mmc_startup_v4(struct mmc *mmc)
>  
>  	mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
>  
> +	mmc->can_trim =
> +		!!(ext_csd[EXT_CSD_SEC_FEATURE] & EXT_CSD_SEC_FEATURE_TRIM_EN);
> +
>  	return 0;
>  error:
>  	if (mmc->ext_csd) {
> diff --git a/include/mmc.h b/include/mmc.h
> index 571fa625d0..f6e23625ca 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -241,6 +241,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
>  #define EXT_CSD_HC_WP_GRP_SIZE		221	/* RO */
>  #define EXT_CSD_HC_ERASE_GRP_SIZE	224	/* RO */
>  #define EXT_CSD_BOOT_MULT		226	/* RO */
> +#define EXT_CSD_SEC_FEATURE		231	/* RO */
>  #define EXT_CSD_GENERIC_CMD6_TIME       248     /* RO */
>  #define EXT_CSD_BKOPS_SUPPORT		502	/* RO */
>  
> @@ -315,6 +316,8 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
>  #define EXT_CSD_WR_DATA_REL_USR		(1 << 0)	/* user data area WR_REL */
>  #define EXT_CSD_WR_DATA_REL_GP(x)	(1 << ((x)+1))	/* GP part (x+1) WR_REL */
>  
> +#define EXT_CSD_SEC_FEATURE_TRIM_EN	(1 << 4) /* Support secure & insecure trim */
> +
>  #define R1_ILLEGAL_COMMAND		(1 << 22)
>  #define R1_APP_CMD			(1 << 5)
>  
> @@ -687,6 +690,7 @@ struct mmc {
>  	uint tran_speed;
>  	uint legacy_speed; /* speed for the legacy mode provided by the card */
>  	uint read_bl_len;
> +	bool can_trim;
>  #if CONFIG_IS_ENABLED(MMC_WRITE)
>  	uint write_bl_len;
>  	uint erase_grp_size;	/* in 512-byte sectors */


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 2/3] mmc: erase: Use TRIM erase when available
       [not found]     ` <CGME20230310023122epcas1p2e19d3aa9274c88d14992bd878dc8d1ca@epcas1p2.samsung.com>
@ 2023-03-10  2:31       ` Jaehoon Chung
  0 siblings, 0 replies; 15+ messages in thread
From: Jaehoon Chung @ 2023-03-10  2:31 UTC (permalink / raw)
  To: Loic Poulain, sjg, peng.fan; +Cc: u-boot

On 1/26/23 18:24, Loic Poulain wrote:
> The default erase command applies on erase group unit, and
> simply round down to erase group size. When the start block
> is not aligned to erase group size (e.g. erasing partition)
> it causes unwanted erasing of the previous blocks, part of
> the same erase group (e.g. owned by other logical partition,
> or by the partition table itself).
> 
> To prevent this issue, a simple solution is to use TRIM as
> argument of the Erase command, which is usually supported
> with eMMC > 4.0, and allow to apply erase operation to write
> blocks instead of erase group
> 
> Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
> Reviewed-by: Simon Glass <sjg@chromium.org>


Applied to u-boot-mmc/master.

Best Regards,
Jaehoon Chung


> ---
> v2: Add mmc unit test change to the series
> 
>  drivers/mmc/mmc_write.c | 34 +++++++++++++++++++++++-----------
>  1 file changed, 23 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
> index 5b7aeeb012..a6f93380dd 100644
> --- a/drivers/mmc/mmc_write.c
> +++ b/drivers/mmc/mmc_write.c
> @@ -15,7 +15,7 @@
>  #include <linux/math64.h>
>  #include "mmc_private.h"
>  
> -static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
> +static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, u32 args)
>  {
>  	struct mmc_cmd cmd;
>  	ulong end;
> @@ -52,7 +52,7 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
>  		goto err_out;
>  
>  	cmd.cmdidx = MMC_CMD_ERASE;
> -	cmd.cmdarg = MMC_ERASE_ARG;
> +	cmd.cmdarg = args ? args : MMC_ERASE_ARG;
>  	cmd.resp_type = MMC_RSP_R1b;
>  
>  	err = mmc_send_cmd(mmc, &cmd, NULL);
> @@ -77,7 +77,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
>  #endif
>  	int dev_num = block_dev->devnum;
>  	int err = 0;
> -	u32 start_rem, blkcnt_rem;
> +	u32 start_rem, blkcnt_rem, erase_args = 0;
>  	struct mmc *mmc = find_mmc_device(dev_num);
>  	lbaint_t blk = 0, blk_r = 0;
>  	int timeout_ms = 1000;
> @@ -97,13 +97,25 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
>  	 */
>  	err = div_u64_rem(start, mmc->erase_grp_size, &start_rem);
>  	err = div_u64_rem(blkcnt, mmc->erase_grp_size, &blkcnt_rem);
> -	if (start_rem || blkcnt_rem)
> -		printf("\n\nCaution! Your devices Erase group is 0x%x\n"
> -		       "The erase range would be change to "
> -		       "0x" LBAF "~0x" LBAF "\n\n",
> -		       mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
> -		       ((start + blkcnt + mmc->erase_grp_size - 1)
> -		       & ~(mmc->erase_grp_size - 1)) - 1);
> +	if (start_rem || blkcnt_rem) {
> +		if (mmc->can_trim) {
> +			/* Trim function applies the erase operation to write
> +			 * blocks instead of erase groups.
> +			 */
> +			erase_args = MMC_TRIM_ARG;
> +		} else {
> +			/* The card ignores all LSB's below the erase group
> +			 * size, rounding down the addess to a erase group
> +			 * boundary.
> +			 */
> +			printf("\n\nCaution! Your devices Erase group is 0x%x\n"
> +			       "The erase range would be change to "
> +			       "0x" LBAF "~0x" LBAF "\n\n",
> +			       mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
> +			       ((start + blkcnt + mmc->erase_grp_size - 1)
> +			       & ~(mmc->erase_grp_size - 1)) - 1);
> +		}
> +	}
>  
>  	while (blk < blkcnt) {
>  		if (IS_SD(mmc) && mmc->ssr.au) {
> @@ -113,7 +125,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
>  			blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
>  				mmc->erase_grp_size : (blkcnt - blk);
>  		}
> -		err = mmc_erase_t(mmc, start + blk, blk_r);
> +		err = mmc_erase_t(mmc, start + blk, blk_r, erase_args);
>  		if (err)
>  			break;
>  


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2 3/3] test: dm: mmc: Check block erasing boundaries
       [not found]     ` <CGME20230310023206epcas1p1df08c1dbe2cb70efdd91ef47d7e95c78@epcas1p1.samsung.com>
@ 2023-03-10  2:32       ` Jaehoon Chung
  0 siblings, 0 replies; 15+ messages in thread
From: Jaehoon Chung @ 2023-03-10  2:32 UTC (permalink / raw)
  To: Loic Poulain, sjg, peng.fan; +Cc: u-boot

On 1/26/23 18:24, Loic Poulain wrote:
> Verify that erasing blocks does not impact adjacent ones.
> - Write four blocks [0 1 2 3]
> - Erase two blocks [ 1 2 ]
> - Verify [0 1 2 3 ]
> 
> Signed-off-by: Loic Poulain <loic.poulain@linaro.org>


Applied to u-boot-mmc/master.

Best Regards,
Jaehoon Chung

> ---
> v2: Add this change to the series
> 
>  test/dm/mmc.c | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/test/dm/mmc.c b/test/dm/mmc.c
> index f744452ff2..b1eb8bee2f 100644
> --- a/test/dm/mmc.c
> +++ b/test/dm/mmc.c
> @@ -30,7 +30,7 @@ static int dm_test_mmc_blk(struct unit_test_state *uts)
>  	struct udevice *dev;
>  	struct blk_desc *dev_desc;
>  	int i;
> -	char write[1024], read[1024];
> +	char write[4 * 512], read[4 * 512];
>  
>  	ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
>  	ut_assertok(blk_get_device_by_str("mmc", "0", &dev_desc));
> @@ -39,14 +39,14 @@ static int dm_test_mmc_blk(struct unit_test_state *uts)
>  	ut_asserteq(512, dev_desc->blksz);
>  	for (i = 0; i < sizeof(write); i++)
>  		write[i] = i;
> -	ut_asserteq(2, blk_dwrite(dev_desc, 0, 2, write));
> -	ut_asserteq(2, blk_dread(dev_desc, 0, 2, read));
> +	ut_asserteq(4, blk_dwrite(dev_desc, 0, 4, write));
> +	ut_asserteq(4, blk_dread(dev_desc, 0, 4, read));
>  	ut_asserteq_mem(write, read, sizeof(write));
>  
> -	/* Now erase them */
> -	memset(write, '\0', sizeof(write));
> -	ut_asserteq(2, blk_derase(dev_desc, 0, 2));
> -	ut_asserteq(2, blk_dread(dev_desc, 0, 2, read));
> +	/* Now erase two of them [1 - 2] and verify all blocks */
> +	memset(&write[512], '\0', 2 * 512);
> +	ut_asserteq(2, blk_derase(dev_desc, 1, 2));
> +	ut_asserteq(4, blk_dread(dev_desc, 0, 4, read));
>  	ut_asserteq_mem(write, read, sizeof(write));
>  
>  	return 0;


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2023-03-10  2:32 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20230126092431epcas1p49aa1d01605df7cfcf0d2f2a4e5e8600c@epcas1p4.samsung.com>
2023-01-26  9:24 ` [PATCH v2 1/3] mmc: Check support for TRIM operations Loic Poulain
2023-01-26  9:24   ` [PATCH v2 2/3] mmc: erase: Use TRIM erase when available Loic Poulain
2023-01-28 22:01     ` Simon Glass
2023-02-01 11:39       ` Loic Poulain
2023-02-06  5:05     ` Jaehoon Chung
2023-02-08  8:08       ` Loic Poulain
2023-02-08  9:03         ` Jaehoon Chung
     [not found]     ` <CGME20230310023122epcas1p2e19d3aa9274c88d14992bd878dc8d1ca@epcas1p2.samsung.com>
2023-03-10  2:31       ` Jaehoon Chung
2023-01-26  9:24   ` [PATCH v2 3/3] test: dm: mmc: Check block erasing boundaries Loic Poulain
2023-01-27 14:30     ` Simon Glass
2023-02-08  8:13       ` Loic Poulain
     [not found]     ` <CGME20230310023206epcas1p1df08c1dbe2cb70efdd91ef47d7e95c78@epcas1p1.samsung.com>
2023-03-10  2:32       ` Jaehoon Chung
2023-01-28 22:01   ` [PATCH v2 1/3] mmc: Check support for TRIM operations Simon Glass
2023-02-06  4:54   ` Jaehoon Chung
     [not found]   ` <CGME20230310023103epcas1p4e4763c672faff833c978f8e91252119c@epcas1p4.samsung.com>
2023-03-10  2:31     ` Jaehoon Chung

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.