From: Luke Wang <ziniu.wan...@nxp.com>

Current mmc bootpart-resize cmd only support samsung emmc boot/rpmb
partition resizing. Add sandisk and micron emmc boot/rpmb partition
resizing support. The commands and parameters for resizing partitions
are different for each manufacturer. Select the corresponding function
according to cid.

Signed-off-by: Luke Wang <ziniu.wan...@nxp.com>
---
 drivers/mmc/mmc_boot.c | 169 ++++++++++++++++++++++++++++++++++-------
 include/mmc.h          |   1 +
 2 files changed, 141 insertions(+), 29 deletions(-)

diff --git a/drivers/mmc/mmc_boot.c b/drivers/mmc/mmc_boot.c
index 367c957b518..8e5d765009f 100644
--- a/drivers/mmc/mmc_boot.c
+++ b/drivers/mmc/mmc_boot.c
@@ -8,20 +8,102 @@
 #include <mmc.h>
 #include "mmc_private.h"
 
-/*
- * This function changes the size of boot partition and the size of rpmb
- * partition present on EMMC devices.
- *
- * Input Parameters:
- * struct *mmc: pointer for the mmc device strcuture
- * bootsize: size of boot partition
- * rpmbsize: size of rpmb partition
- *
- * Returns 0 on success.
- */
+static int mmc_resize_boot_micron(struct mmc *mmc, unsigned long bootsize,
+                                 unsigned long rpmbsize)
+{
+       int err;
 
-int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
-                               unsigned long rpmbsize)
+       /* micron emmc doesn't support resizing rpmb partition */
+       (void)rpmbsize;
+
+       /* boot partition size is multiple of 128KB */
+       bootsize = (bootsize * 1024) / 128;
+
+       if (bootsize > 0xff)
+               bootsize = 0xff;
+
+       /* Set EXT_CSD[175] ERASE_GROUP_DEF to 0x01 */
+       err = mmc_switch(mmc, 0, 175, 0x01);
+       if (err)
+               goto error;
+
+       /* Set EXT_CSD[127:125] for boot partition size, [125] is low byte */
+       err = mmc_switch(mmc, 0, 125, bootsize);
+       if (err)
+               goto error;
+
+       err = mmc_switch(mmc, 0, 126, 0x00);
+       if (err)
+               goto error;
+
+       err = mmc_switch(mmc, 0, 127, 0x00);
+       if (err)
+               goto error;
+
+       /* Set EXT_CSD[155] PARTITION_SETTING_COMPLETE to 0x01 */
+       err = mmc_switch(mmc, 0, 155, 0x01);
+       if (err)
+               goto error;
+
+       return 0;
+
+error:
+       debug("%s: Error = %d\n", __func__, err);
+       return err;
+}
+
+static int mmc_resize_boot_sandisk(struct mmc *mmc, unsigned long bootsize,
+                                  unsigned long rpmbsize)
+{
+       int err;
+       struct mmc_cmd cmd;
+
+       /* boot/rpmb partition size is multiple of 128KB */
+       bootsize = (bootsize * 1024) / 128;
+       rpmbsize = (rpmbsize * 1024) / 128;
+
+       if (bootsize > 0xff)
+               bootsize = 0xff;
+
+       if (rpmbsize > 0xff)
+               rpmbsize = 0xff;
+
+       /* Send boot/rpmb resize op code */
+       cmd.cmdidx = MMC_CMD_RES_MAN;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = MMC_CMD62_ARG_SANDISK;
+
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err)
+               goto error;
+
+       /* Arg: boot partition size */
+       cmd.cmdidx = MMC_CMD_RES_MAN;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = bootsize;
+
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err)
+               goto error;
+
+       /* Arg: RPMB partition size */
+       cmd.cmdidx = MMC_CMD_RES_MAN;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = rpmbsize;
+
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err)
+               goto error;
+
+       return 0;
+
+error:
+       debug("%s: Error = %d\n", __func__, err);
+       return err;
+}
+
+static int mmc_resize_boot_samsung(struct mmc *mmc, unsigned long bootsize,
+                                  unsigned long rpmbsize)
 {
        int err;
        struct mmc_cmd cmd;
@@ -32,10 +114,8 @@ int mmc_boot_partition_size_change(struct mmc *mmc, 
unsigned long bootsize,
        cmd.cmdarg = MMC_CMD62_ARG1;
 
        err = mmc_send_cmd(mmc, &cmd, NULL);
-       if (err) {
-               debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
-               return err;
-       }
+       if (err)
+               goto error;
 
        /* Boot partition changing mode */
        cmd.cmdidx = MMC_CMD_RES_MAN;
@@ -43,10 +123,9 @@ int mmc_boot_partition_size_change(struct mmc *mmc, 
unsigned long bootsize,
        cmd.cmdarg = MMC_CMD62_ARG2;
 
        err = mmc_send_cmd(mmc, &cmd, NULL);
-       if (err) {
-               debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
-               return err;
-       }
+       if (err)
+               goto error;
+
        /* boot partition size is multiple of 128KB */
        bootsize = (bootsize * 1024) / 128;
 
@@ -56,10 +135,9 @@ int mmc_boot_partition_size_change(struct mmc *mmc, 
unsigned long bootsize,
        cmd.cmdarg = bootsize;
 
        err = mmc_send_cmd(mmc, &cmd, NULL);
-       if (err) {
-               debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
-               return err;
-       }
+       if (err)
+               goto error;
+
        /* RPMB partition size is multiple of 128KB */
        rpmbsize = (rpmbsize * 1024) / 128;
        /* Arg: RPMB partition size */
@@ -68,11 +146,44 @@ int mmc_boot_partition_size_change(struct mmc *mmc, 
unsigned long bootsize,
        cmd.cmdarg = rpmbsize;
 
        err = mmc_send_cmd(mmc, &cmd, NULL);
-       if (err) {
-               debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
-               return err;
-       }
+       if (err)
+               goto error;
+
        return 0;
+
+error:
+       debug("%s: Error = %d\n", __func__, err);
+       return err;
+}
+
+/*
+ * This function changes the size of boot partition and the size of rpmb
+ * partition present on EMMC devices.
+ *
+ * Input Parameters:
+ * struct *mmc: pointer for the mmc device strcuture
+ * bootsize: size of boot partition
+ * rpmbsize: size of rpmb partition
+ *
+ * Returns 0 on success.
+ */
+
+int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
+                                  unsigned long rpmbsize)
+{
+       switch (mmc->cid[0] >> 24) {
+       case 0x13:
+       case 0x2c:
+               return mmc_resize_boot_micron(mmc, bootsize, rpmbsize);
+       case 0x45:
+               return mmc_resize_boot_sandisk(mmc, bootsize, rpmbsize);
+       case 0xec:
+               return mmc_resize_boot_samsung(mmc, bootsize, rpmbsize);
+       default:
+               printf("Unsupported manufacturer id 0x%02x\n",
+                      mmc->cid[0] >> 24);
+               return -EPERM;
+       }
 }
 
 /*
diff --git a/include/mmc.h b/include/mmc.h
index 81bccb4cf12..81b648cb5d4 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -112,6 +112,7 @@ struct bd_info;
 
 #define MMC_CMD62_ARG1                 0xefac62ec
 #define MMC_CMD62_ARG2                 0xcbaea7
+#define MMC_CMD62_ARG_SANDISK          0x254ddec4
 
 #define SD_CMD_SEND_RELATIVE_ADDR      3
 #define SD_CMD_SWITCH_FUNC             6
-- 
2.34.1

Reply via email to