From 4357167e0e941faa0471325450a30227fafbae24 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 18 Jan 2025 04:09:53 +0100 Subject: mmc: Simplify poll CD logic in case cyclic framework is enabled Simplify 90cc07fd786d ("mmc: Poll CD in case cyclic framework is enabled") according to suggestions by Rasmus. The struct cyclic_info is zero-size in case CONFIG_CYCLIC is not enabled and does not add any size to struct mmc, so it can unconditionally be part of that structure. This allows clean up of all the other conditionals in mmc.c which can now be unconditionally present, as they also add no extra space. Suggested-by: Rasmus Villemoes Signed-off-by: Marek Vasut Signed-off-by: Peng Fan --- include/mmc.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/mmc.h b/include/mmc.h index 81bccb4cf12..233a1d69afd 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -759,7 +759,11 @@ struct mmc { enum bus_mode user_speed_mode; /* input speed mode from user */ - CONFIG_IS_ENABLED(CYCLIC, (struct cyclic_info cyclic)); + /* + * If CONFIG_CYCLIC is not set, struct cyclic_info is + * zero-size structure and does not add any space here. + */ + struct cyclic_info cyclic; }; #if CONFIG_IS_ENABLED(DM_MMC) -- cgit v1.3.1 From 7550bfdbf41b721f750a62b87a42a3329a2e2f81 Mon Sep 17 00:00:00 2001 From: Luke Wang Date: Tue, 25 Mar 2025 16:29:14 +0800 Subject: mmc: mmc_boot: Support Sandisk and Micron eMMC BOOT/RPMB hardware partition resizing Current mmc bootpart-resize command only support Samsung eMMC BOOT/RPMB hardware partition resizing. Add Sandisk and Micron eMMC BOOT/RPMB hardware 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 Reviewed-by: Marek Vasut Signed-off-by: Peng Fan --- drivers/mmc/mmc_boot.c | 173 ++++++++++++++++++++++++++++++++++++++++--------- include/mmc.h | 6 ++ 2 files changed, 150 insertions(+), 29 deletions(-) (limited to 'include') diff --git a/drivers/mmc/mmc_boot.c b/drivers/mmc/mmc_boot.c index 367c957b518..986e6c500b1 100644 --- a/drivers/mmc/mmc_boot.c +++ b/drivers/mmc/mmc_boot.c @@ -8,20 +8,107 @@ #include #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, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_ERASE_GROUP_DEF, 0x01); + if (err) + goto error; + + /* Set EXT_CSD[127:125] for BOOT partition size, [125] is low byte */ + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BOOT_SIZE_MULT_MICRON, bootsize); + if (err) + goto error; + + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BOOT_SIZE_MULT_MICRON + 1, 0x00); + if (err) + goto error; + + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BOOT_SIZE_MULT_MICRON + 2, 0x00); + if (err) + goto error; + + /* Set EXT_CSD[155] PARTITION_SETTING_COMPLETE to 0x01 */ + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_PARTITION_SETTING, 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 +119,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 +128,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 +140,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 +151,43 @@ 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 CID_MANFID_MICRON: + return mmc_resize_boot_micron(mmc, bootsize, rpmbsize); + case CID_MANFID_SAMSUNG: + return mmc_resize_boot_samsung(mmc, bootsize, rpmbsize); + case CID_MANFID_SANDISK: + return mmc_resize_boot_sandisk(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 233a1d69afd..52cacfd0eab 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -79,6 +79,10 @@ struct bd_info; #define IS_SD(x) ((x)->version & SD_VERSION_SD) #define IS_MMC(x) ((x)->version & MMC_VERSION_MMC) +#define CID_MANFID_MICRON 0x13 +#define CID_MANFID_SAMSUNG 0x15 +#define CID_MANFID_SANDISK 0x45 + #define MMC_DATA_READ 1 #define MMC_DATA_WRITE 2 @@ -112,6 +116,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 @@ -205,6 +210,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx) /* * EXT_CSD fields */ +#define EXT_CSD_BOOT_SIZE_MULT_MICRON 125 /* R/W, vendor specific field */ #define EXT_CSD_ENH_START_ADDR 136 /* R/W */ #define EXT_CSD_ENH_SIZE_MULT 140 /* R/W */ #define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ -- cgit v1.3.1