diff mbox series

[v2,1/1] mmc-utils: Support MANUAL_EN and AUTO_EN in BKOPS_EN register

Message ID 20191024141634.19287-2-lapeddk@gmail.com (mailing list archive)
State New, archived
Headers show
Series mmc-utils: AUTO_EN and MANUAL_EN in BKOPS_EN | expand

Commit Message

Lars Pedersen Oct. 24, 2019, 2:16 p.m. UTC
The BKOPS_EN register in eMMC 5.1 now has two fields AUTO_EN and MANUAL_EN.

Signed-off-by: Lars Pedersen <lapeddk@gmail.com>
---
 mmc.c      | 14 ++++++++----
 mmc.h      |  7 ++++--
 mmc_cmds.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 mmc_cmds.h |  3 ++-
 4 files changed, 80 insertions(+), 10 deletions(-)

Comments

Avri Altman Nov. 4, 2019, 12:50 p.m. UTC | #1
Hi Lars,

> 
> The BKOPS_EN register in eMMC 5.1 now has two fields AUTO_EN and
> MANUAL_EN.
> 
> Signed-off-by: Lars Pedersen <lapeddk@gmail.com>
You didn't responded to my previous comments - 
See https://www.spinics.net/lists/linux-mmc/msg56320.html
Also, The 0/1 is no longer needed.

Thanks,
Avri
Lars Pedersen Nov. 9, 2019, 11:09 p.m. UTC | #2
I'm sorry that I have missed one of your previous comments. From your
comments I'll create a more simple patch that takes the old bkops_en
function that can set bit 0 and 1.

The kernel driver checks for both AUTO_EN and MANUAL_EN in
mmc_decode_ext_csd but only have to do something when MANUAL_EN is set
in mmc_run_bkops. So I don't think the driver cares if we try to set
both bits.

But I also did test on a sandisk emmc where I could flip AUTO_EN back
and forth. Setting the AUTO_EN bit stopped having an effect when I had
set the MANUAL_EN bit. So maybe a line in the help section should
mention this.

On Mon, 4 Nov 2019 at 13:50, Avri Altman <Avri.Altman@wdc.com> wrote:
>
> Hi Lars,
>
> >
> > The BKOPS_EN register in eMMC 5.1 now has two fields AUTO_EN and
> > MANUAL_EN.
> >
> > Signed-off-by: Lars Pedersen <lapeddk@gmail.com>
> You didn't responded to my previous comments -
> See https://www.spinics.net/lists/linux-mmc/msg56320.html
> Also, The 0/1 is no longer needed.
>
> Thanks,
> Avri

Kinds regards,
Lars Pedersen
diff mbox series

Patch

diff --git a/mmc.c b/mmc.c
index 50c9c9e..9e02ba0 100644
--- a/mmc.c
+++ b/mmc.c
@@ -120,9 +120,15 @@  static struct Command commands[] = {
 	  "<boot_bus_width> must be \"x1|x4|x8\"",
 	  NULL
 	},
-	{ do_write_bkops_en, -1,
-	  "bkops enable", "<device>\n"
-		"Enable the eMMC BKOPS feature on <device>.\nNOTE!  This is a one-time programmable (unreversible) change.",
+	{ do_write_bkops_manual_en, -1,
+	  "bkops manual enable", "<device>\n"
+		"Enable eMMC BKOPS MANUAL_EN(BKOPS_EN[0]) on <device>.\nNOTE!  This is a one-time programmable (unreversible) change.",
+	  NULL
+	},
+	{ do_write_bkops_auto_en, -2,
+	  "bkops auto", "<mode> <device>\n"
+		"Enable/disable eMMC BKOPS AUTO_EN feature on <device>.\nThe device may perform background operations while not servicing the host.\n"
+		"NOTE!  Only supported in eMMC-5.1 and MANUAL_EN(BKOPS_EN[0]) must not be set",
 	  NULL
 	},
 	{ do_hwreset_en, -1,
@@ -467,7 +473,7 @@  static int parse_args(int argc, char **argv,
 			matchcmd->verb, matchcmd->nargs);
 			return -2;
 	}
-	
+
         if (prepare_args( nargs_, args_, prgname, matchcmd )){
                 fprintf(stderr, "ERROR: not enough memory\\n");
 		return -20;
diff --git a/mmc.h b/mmc.h
index 648fb26..0596d6c 100644
--- a/mmc.h
+++ b/mmc.h
@@ -126,9 +126,12 @@ 
 #define EN_REL_WR	(1<<2)
 
 /*
- * BKOPS_EN field definition
+ * BKOPS_EN field definitions
  */
-#define BKOPS_ENABLE	(1<<0)
+#define BKOPS_ENABLE_MAN	(1<<0)  /* MANUAL_EN */
+#define BKOPS_ENABLE_AUTO_SET	(1<<1) /* AUTO_EN */
+#define BKOPS_ENABLE_AUTO_CLR	(0)  /* AUTO_EN */
+
 
 /*
  * EXT_CSD field definitions
diff --git a/mmc_cmds.c b/mmc_cmds.c
index fb37189..05a63db 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -729,14 +729,14 @@  int do_hwreset_dis(int nargs, char **argv)
 	return do_hwreset(EXT_CSD_HW_RESET_DIS, nargs, argv);
 }
 
-int do_write_bkops_en(int nargs, char **argv)
+int do_write_bkops_manual_en(int nargs, char **argv)
 {
 	__u8 ext_csd[512], value = 0;
 	int fd, ret;
 	char *device;
 
 	if (nargs != 2) {
-	       fprintf(stderr, "Usage: mmc bkops enable </path/to/mmcblkX>\n");
+	       fprintf(stderr, "Usage: mmc bkops manual enable </path/to/mmcblkX>\n");
 	       exit(1);
 	}
 
@@ -759,7 +759,67 @@  int do_write_bkops_en(int nargs, char **argv)
 		exit(1);
 	}
 
-	ret = write_extcsd_value(fd, EXT_CSD_BKOPS_EN, BKOPS_ENABLE);
+	ret = write_extcsd_value(fd, EXT_CSD_BKOPS_EN, BKOPS_ENABLE_MAN);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
+			value, EXT_CSD_BKOPS_EN, device);
+		exit(1);
+	}
+
+	return ret;
+}
+
+int do_write_bkops_auto_en(int nargs, char **argv)
+{
+	__u8 ext_csd[512], value = 0;
+	int fd, ret;
+	char *device;
+	char *mode;
+
+	if (nargs != 3) {
+	       fprintf(stderr, "Usage: mmc bkops auto enable/disable </path/to/mmcblkX>\n");
+	       exit(1);
+	}
+
+	mode = argv[1];
+	device = argv[2];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = read_extcsd(fd, ext_csd);
+	if (ret) {
+		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+		exit(1);
+	}
+
+	if (ext_csd[EXT_CSD_REV] != EXT_CSD_REV_V5_1) {
+		fprintf(stderr, "%s doesn't support eMMC 5.1\n", device);
+		exit(1);
+	}
+
+	if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) {
+		fprintf(stderr, "%s doesn't support BKOPS\n", device);
+		exit(1);
+	}
+
+	if ((ext_csd[EXT_CSD_BKOPS_EN] & 0x1)) {
+		fprintf(stderr, "%s manual BKOPS already enabled.\n", device);
+		exit(1);
+	}
+
+	if (strcmp(mode, "enable") == 0) {
+		ret = write_extcsd_value(fd, EXT_CSD_BKOPS_EN, BKOPS_ENABLE_AUTO_SET);
+	} else if (strcmp(mode, "disable") == 0) {
+		ret = write_extcsd_value(fd, EXT_CSD_BKOPS_EN, BKOPS_ENABLE_AUTO_CLR);
+	} else {
+		fprintf(stderr, "%s invalid mode for BKOPS_EN AUTO_EN requested: %s. Valid options: enable or disable\n", mode, device);
+		exit(1);
+	}
+
 	if (ret) {
 		fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
 			value, EXT_CSD_BKOPS_EN, device);
diff --git a/mmc_cmds.h b/mmc_cmds.h
index 9d3246c..7f825ae 100644
--- a/mmc_cmds.h
+++ b/mmc_cmds.h
@@ -27,7 +27,8 @@  int do_writeprotect_user_set(int nargs, char **argv);
 int do_disable_512B_emulation(int nargs, char **argv);
 int do_write_boot_en(int nargs, char **argv);
 int do_boot_bus_conditions_set(int nargs, char **argv);
-int do_write_bkops_en(int nargs, char **argv);
+int do_write_bkops_manual_en(int nargs, char **argv);
+int do_write_bkops_auto_en(int nargs, char **argv);
 int do_hwreset_en(int nargs, char **argv);
 int do_hwreset_dis(int nargs, char **argv);
 int do_sanitize(int nargs, char **argv);