mmc: Support FFU for eMMC v5.0 for Samsung
PATCH 1/1 mmc: Support FFU for eMMC v5.0 for Samsung
This change adds support to field firmware update (ffu) for Samsung emmc v5.0
Some of Samsung eMMC does not show the argument for ffu in ext_csd. In case of this, eMMC shows 0x0 from ext_csd, Host has to modify the argument.
And ffu for Samsung eMMC should transfer f/w through not multiple commands but one command.
Because of f/w size, MMC_IOC_MAX_BYTES should be increased. Usually normal io uses 512KB as the max chunk size,
So I think it does not cause the problem.
This patch depends on patch mmc: Support-FFU-for-eMMC-v5.0 committed by Avi Shchislowski <[email protected]>
--- drivers/mmc/card/ffu.c | 7 +++++++ include/linux/mmc/card.h | 1 + include/uapi/linux/mmc/ioctl.h | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-)
drivers/mmc/card/ffu.c +0 -0
@@ -444,6 +444,8 @@ static int mmc_host_set_ffu(struct mmc_card *card, u32
ffu_enable)
return 0;
}
+#define CID_MANFID_SAMSUNG 0x15
+
int mmc_ffu_download(struct mmc_card *card, struct mmc_command *cmd,
u8 *data, int buf_bytes)
{
@@ -490,6 +492,11 @@ int mmc_ffu_download(struct mmc_card *card, struct mmc_command *cmd,
ext_csd[EXT_CSD_FFU_ARG + 2] << 16 |
ext_csd[EXT_CSD_FFU_ARG + 3] << 24;+ /* If arg is zero, should be set to a special value for samsung eMMC
*/
+ if (card->quirks & MMC_QUIRK_SEC_FIX_FFU_ARG &&
+ card->cid.manfid == CID_MANFID_SAMSUNG && cmd->arg == 0x0)
+ cmd->arg = 0xc7810000;
+
err = mmc_ffu_write(card, data, cmd->arg, buf_bytes);
exit_normal:
include/linux/mmc/card.h +0 -0
@@ -275,6 +275,7 @@ struct mmc_card {#define MMC_QUIRK_LONG_READ_TIME (1<<9)/* Data read time >
CSD says */
#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for
erase/trim */
#define MMC_QUIRK_BROKEN_IRQ_POLLING (1<<11) /* Polling SDIO_CCCR_INTx
could create a fake interrupt */
+#define MMC_QUIRK_SEC_FIX_FFU_ARG (1<<12) /* Fix ffu argument */
unsigned int erase_size; /* erase size in sectors */
unsigned int erase_shift; /* if erase unit is power 2*/
include/uapi/linux/mmc/ioctl.h +1 -1
@@ -53,5 +53,5 @@ struct mmc_ioc_cmd {* is enforced per ioctl call. For larger data transfers, use the normal * block device operations. */ -#define MMC_IOC_MAX_BYTES (512L * 256) +#define MMC_IOC_MAX_BYTES (512L * 1024)#endif /* LINUX_MMC_IOCTL_H */
--
1.8.3.2