@@ -1302,3 +1302,121 @@ int mmc_initialize(bd_t *bis)
return 0;
}
+
+int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
+ unsigned long rpmbsize)
+{
+ int err;
+ struct mmc_cmd cmd;
+
+ /* Only use this command for raw EMMC moviNAND */
+ /* Enter backdoor mode */
+ cmd.cmdidx = MMC_CMD_RES_MAN;
+ cmd.resp_type = MMC_RSP_R1b;
+ 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;
+ }
+
+ /* Boot partition changing mode */
+ cmd.cmdidx = MMC_CMD_RES_MAN;
+ cmd.resp_type = MMC_RSP_R1b;
+ 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;
+ }
+ /* boot partition size is multiple of 128KB */
+ bootsize = ((bootsize*1024)/128);
+
+ /* 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) {
+ debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
+ return err;
+ }
+ /* RPMB partition size is multiple of 128KB */
+ rpmbsize = ((rpmbsize*1024)/128);
+ /* 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) {
+ debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
+ return err;
+ }
+ return 0;
+}
+
+int mmc_boot_open(struct mmc *mmc)
+{
+ int err;
+ struct mmc_cmd cmd;
+
+ /* Boot ack enable, boot partition enable , boot partition access */
+ cmd.cmdidx = MMC_CMD_SWITCH;
+ cmd.resp_type = MMC_RSP_R1b;
+
+ cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24 |
+ EXT_CSD_PART_CONF << 16 |
+ (EXT_CSD_BOOT_ACK_ENABLE |
+ EXT_CSD_BOOT_PARTITION_ENABLE |
+ EXT_CSD_PARTITION_ACCESS_ENABLE) << 8);
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+ if (err) {
+ debug("mmc_boot_open: Error1 = %d\n", err);
+ return err;
+ }
+
+ /* 4bit transfer mode at booting time. */
+ cmd.cmdidx = MMC_CMD_SWITCH;
+ cmd.resp_type = MMC_RSP_R1b;
+
+ cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24|
+ EXT_CSD_BOOT_BUS_WIDTH << 16|
+ ((1<<0) << 8));
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+ if (err) {
+ debug("mmc_boot_open: Error2 = %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int mmc_boot_close(struct mmc *mmc)
+{
+ int err;
+ struct mmc_cmd cmd;
+
+ /* Boot ack enable, boot partition enable , boot partition access */
+ cmd.cmdidx = MMC_CMD_SWITCH;
+ cmd.resp_type = MMC_RSP_R1b;
+
+ cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24|
+ EXT_CSD_PART_CONF << 16|
+ (EXT_CSD_BOOT_ACK_ENABLE |
+ EXT_CSD_BOOT_PARTITION_ENABLE |
+ EXT_CSD_PARTITION_ACCESS_DISABLE) << 8);
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+ if (err) {
+ debug("mmc_boot_close: Error = %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
@@ -86,6 +86,11 @@
#define MMC_CMD_APP_CMD 55
#define MMC_CMD_SPI_READ_OCR 58
#define MMC_CMD_SPI_CRC_ON_OFF 59
+#define MMC_CMD_RES_MAN 62
+
+#define MMC_CMD62_ARG1 0xefac62ec
+#define MMC_CMD62_ARG2 0xcbaea7
+
#define SD_CMD_SEND_RELATIVE_ADDR 3
#define SD_CMD_SWITCH_FUNC 6
@@ -153,6 +158,7 @@
*/
#define EXT_CSD_PARTITIONING_SUPPORT 160 /* RO */
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
+#define EXT_CSD_BOOT_BUS_WIDTH 177
#define EXT_CSD_PART_CONF 179 /* R/W */
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
#define EXT_CSD_HS_TIMING 185 /* R/W */
@@ -177,6 +183,12 @@
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
+#define EXT_CSD_BOOT_ACK_ENABLE (1<<6)
+#define EXT_CSD_BOOT_PARTITION_ENABLE (1<<3)
+#define EXT_CSD_PARTITION_ACCESS_ENABLE (1<<0)
+#define EXT_CSD_PARTITION_ACCESS_DISABLE (0<<0)
+
+
#define R1_ILLEGAL_COMMAND (1 << 22)
#define R1_APP_CMD (1 << 5)
@@ -275,6 +287,10 @@ int board_mmc_getcd(struct mmc *mmc);
int mmc_switch_part(int dev_num, unsigned int part_num);
int mmc_getcd(struct mmc *mmc);
void spl_mmc_load(void) __noreturn;
+int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
+ unsigned long rpmbsize);
+int mmc_boot_open(struct mmc *mmc);
+int mmc_boot_close(struct mmc *mmc);
#ifdef CONFIG_GENERIC_MMC
#define mmc_host_is_spi(mmc) ((mmc)->host_caps & MMC_MODE_SPI)
This patch adds APIs to open, close and to create boot partiton for EMMC. Signed-off-by: Amar <amarendra.xt@samsung.com> --- drivers/mmc/mmc.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/mmc.h | 16 ++++++++ 2 files changed, 134 insertions(+)