mmc: Support FFU for Samsung eMMC v4.5
PATCH 1/1 mmc: Support FFU for Samsung eMMC v4.5
This change adds support to field firmware update (ffu) for Samsung emmc v4.5.
Samsung eMMC 4.5 FFU protocol is similar with eMMC 5.0 FFU without MODE_OPERATION.
It uses the different EXT_CSD offset.
This patch depends on patch mmc: Support-FFU-for-eMMC-v5.0 committed by Avi Shchislowski <[email protected]>
--- drivers/mmc/card/Kconfig | 9 +++++ drivers/mmc/card/block.c | 8 ++++ drivers/mmc/card/ffu.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/mmc/ffu.h | 14 +++++++ 4 files changed, 131 insertions(+)
drivers/mmc/card/Kconfig +9 -0
@@ -76,3 +76,12 @@ config MMC_FFU This is an option to run firmware update on eMMC 5.0. Field firmware updates (FFU) enables features enhancement in the field. + +config MMC_FFU_SAMSUNG45 + bool "FFU SUPPORT for Samsung eMMC 4.5." + depends on MMC_FFU + default n + help + This is an option to run firmware update on Samsung eMMC 4.5. + Field firmware updates (FFU) enables features enhancment + in the field.
drivers/mmc/card/block.c +8 -0
@@ -536,6 +536,14 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, goto cmd_rel_host; } +#ifdef CONFIG_MMC_FFU_SAMSUNG45 +if (cmd.opcode ==MMC_FFU_SAMSUNG45_OP ) { + err =mmc_ffu_execute (card, &cmd, idata->buf, + idata->buf_bytes); + goto cmd_rel_host; + } +#endif + err =mmc_blk_part_switch (card, md);if (err) goto cmd_rel_host;
drivers/mmc/card/ffu.c +100 -0
103 lines not on this page · raw message
include/linux/mmc/ffu.h +14 -0
@@ -27,6 +27,9 @@*/ #define MMC_FFU_DOWNLOAD_OP 302#define MMC_FFU_INSTALL_OP 303 +#ifdef CONFIG_MMC_FFU_SAMSUNG45 +#define MMC_FFU_SAMSUNG45_OP 304 +#endif #define MMC_FFU_MODE_SET 0x1#define MMC_FFU_MODE_NORMAL 0x0
@@ -47,6 +50,10 @@int mmc_ffu_download (struct mmc_card *card,struct mmc_command *cmd,u8 *data,int buf_bytes);int mmc_ffu_install (struct mmc_card *card); +#ifdef CONFIG_MMC_FFU_SAMSUNG45 +int mmc_ffu_execute (struct mmc_card *card,struct mmc_command *cmd, +u8 *data,int buf_bytes); +#endif #else static inline int mmc_ffu_download (struct mmc_card *card,struct mmc_command *cmd,u8 *data,int buf_bytes)
@@ -57,6 +64,13 @@ static inline int mmc_ffu_install(struct mmc_card *card) {return -ENOSYS ; } +#ifdef CONFIG_MMC_FFU_SAMSUNG45 +static inline int mmc_ffu_execute (struct mmc_card *card, +struct mmc_command *cmd,u8 *data,int buf_bytes) +{ +return -ENOSYS ; +} +#endif #endif #endif /* FFU_H_ */
Signature · 1 line
1.8.3.2
Quoted 2 lines · Seunguk Shin
This change adds support to field firmware update (ffu) for Samsung emmc v4.5.
Wow. I'm amazed and very happy that this has been posted. :)
Quoted 6 lines
Samsung eMMC 4.5 FFU protocol is similar with eMMC 5.0 FFU without
MODE_OPERATION.
It uses the differentEXT_CSDoffset.This patch depends on patch mmc: Support-FFU-for-eMMC-v5.0 committed by Avi Shchislowski <[email protected]>
While some of the plumbing for loading FW will change, I think most of this patch can be re-used.
Comments below relate to "production use" - not the core FFU implementation.
THANKS! :)
grant
Quoted 16 lines
--- drivers/mmc/card/Kconfig | 9 +++++ drivers/mmc/card/block.c | 8 ++++ drivers/mmc/card/ffu.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/mmc/ffu.h | 14 +++++++ 4 files changed, 131 insertions(+)drivers/mmc/card/Kconfig +0
-0@@ -76,3 +76,12 @@ config MMC_FFU This is an option to run firmware update on eMMC 5.0. Field firmware updates (FFU) enables features enhancement
drivers/mmc/card/Kconfig config MMC_FFU · line 87
Quoted 10 lines
drivers/mmc/card/Kconfig +9
-0in the field. + +config MMC_FFU_SAMSUNG45 + bool "FFU SUPPORT for Samsung eMMC 4.5." + depends on MMC_FFU + default n + help + This is an option to run firmware update on Samsung eMMC 4.5. + Field firmware updates (FFU) enables features enhancment + in the field.
I don't believe FFU needs a separate Kconfig option. FW update is a standard function. The code below has enough protection in it to detect at run time that it won't break something else by accident.
Quoted 49 lines
drivers/mmc/card/block.c +8
-0@@ -536,6 +536,14 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, goto cmd_rel_host; } +#ifdef CONFIG_MMC_FFU_SAMSUNG45 +if (cmd.opcode ==MMC_FFU_SAMSUNG45_OP ) { + err =mmc_ffu_execute (card, &cmd, idata->buf, + idata->buf_bytes); + goto cmd_rel_host; + } +#endif + err =mmc_blk_part_switch (card, md);if (err) goto cmd_rel_host;drivers/mmc/card/ffu.c +22
-0@@ -608,3 +608,103 @@ exit: }EXPORT_SYMBOL (mmc_ffu_install); +#ifdef CONFIG_MMC_FFU_SAMSUNG45 + +#define EXT_CSD_MODE_CONFIG_SAMSUNG45 133 +#define EXT_CSD_FFU_STATUS_SAMSUNG45 253 + +int mmc_ffu_execute (struct mmc_card *card,struct mmc_command *cmd, +u8 *data,int buf_bytes) +{ +u8 ext_csd[CARD_BLOCK_SIZE ]; +int err; +int ret =0 ; + +/* Read the EXT_CSD */ + err =mmc_send_ext_csd (card, ext_csd); +if (err) { +u32 status; +pr_err ("FFU: %s: error %d sending ext_csd\n" , +mmc_hostname (card->host), err); + goto exit; + } + +/*
drivers/mmc/card/ffu.c exit: · line 642
Quoted 10 lines
drivers/mmc/card/ffu.c +10
-0+* Check Manufacturer ID and revision, +* This is only for Samsung eMMC 4.5 +*/ +if (card->cid.manfid !=CID_MANFID_SAMSUNG || + card->ext_csd.rev !=6 ) { + err = -EINVAL ; +pr_err ("FFU: %s: error %d FFU is not supported\n" , +mmc_hostname (card->host), err); + goto exit; + }
This is the "checking for the right HW" that I'm referring to previously.
Quoted 114 lines
drivers/mmc/card/ffu.c +68
-0+ +/* Check if FFU is supported by card */ +if (!FFU_SUPPORTED_MODE (ext_csd[EXT_CSD_SUPPORTED_MODE ])) { + err = -EINVAL ; +pr_err ("FFU: %s: error %d FFU is not supported\n" , +mmc_hostname (card->host), err); + goto exit; + } + +if (FFU_ENABLED (ext_csd[EXT_CSD_FW_CONFIG ])) { + err =mmc_switch (card,EXT_CSD_CMD_SET_NORMAL , +EXT_CSD_FW_CONFIG ,MMC_FFU_ENABLE , + card->ext_csd.generic_cmd6_time); +if (err) { +pr_err ("%s: switch to FFU failed with error %d\n" , +mmc_hostname (card->host), err); +return err; + } + } + +/* set device to FFU mode */ + err =mmc_switch (card,EXT_CSD_CMD_SET_NORMAL , +EXT_CSD_MODE_CONFIG_SAMSUNG45 ,MMC_FFU_MODE_SET , + card->ext_csd.generic_cmd6_time); +if (err) { +pr_err ("FFU: %s: error %d FFU is not supported\n" , +mmc_hostname (card->host), err); + goto exit; + } + cmd->arg =0xc7810000 ; + + err =mmc_ffu_write (card, data, cmd->arg, buf_bytes); + +/* host switch back to work in normal MMC Read/Write commands */ + ret =mmc_switch (card,EXT_CSD_CMD_SET_NORMAL , +EXT_CSD_MODE_CONFIG_SAMSUNG45 ,MMC_FFU_MODE_NORMAL , + card->ext_csd.generic_cmd6_time); +if (ret) + err = ret; + +/* read ext_csd */ + err =mmc_send_ext_csd (card, ext_csd); +if (err) { +pr_err ("FFU: %s: error %d sending ext_csd\n" , +mmc_hostname (card->host), err); + goto exit; + } + +/* return status */ + err = ext_csd[EXT_CSD_FFU_STATUS_SAMSUNG45 ]; +if (!err) { +pr_err ("FFU: %s: error %d FFU execute:\n" , +mmc_hostname (card->host), err); + err = -EINVAL ; + goto exit; + } + err =mmc_ffu_restart (card); +if (err) { +pr_err ("FFU: %s: error %d FFU execute:\n" , +mmc_hostname (card->host), err); + } +exit: + return err; +} +EXPORT_SYMBOL (mmc_ffu_execute); + +#endif +include/linux/mmc/ffu.h +14
-1@@ -27,6 +27,9 @@*/ #define MMC_FFU_DOWNLOAD_OP 302#define MMC_FFU_INSTALL_OP 303 +#ifdef CONFIG_MMC_FFU_SAMSUNG45 +#define MMC_FFU_SAMSUNG45_OP 304 +#endif #define MMC_FFU_MODE_SET 0x1#define MMC_FFU_MODE_NORMAL 0x0@@ -47,6 +50,10 @@int mmc_ffu_download (struct mmc_card *card,struct mmc_command *cmd,u8 *data,int buf_bytes);int mmc_ffu_install (struct mmc_card *card); +#ifdef CONFIG_MMC_FFU_SAMSUNG45 +int mmc_ffu_execute (struct mmc_card *card,struct mmc_command *cmd, +u8 *data,int buf_bytes); +#endif #else static inline int mmc_ffu_download (struct mmc_card *card,struct mmc_command *cmd,u8 *data,int buf_bytes)@@ -57,6 +64,13 @@ static inline int mmc_ffu_install(struct mmc_card *card) {return -ENOSYS ; } +#ifdef CONFIG_MMC_FFU_SAMSUNG45 +static inline int mmc_ffu_execute (struct mmc_card *card, +struct mmc_command *cmd,u8 *data,int buf_bytes) +{ +return -ENOSYS ; +} +#endif #endif #endif /* FFU_H_ */ --1.8.3.2
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html