diff mbox

[V3,7/9] MMC: APIs to support resize of EMMC boot partition

Message ID 1356951500-22490-8-git-send-email-amarendra.xt@samsung.com
State New
Headers show

Commit Message

Amar Dec. 31, 2012, 10:58 a.m. UTC
This patch adds APIs to open, close and to resize boot partiton for EMMC.

Changes from V1:
	New patch.

Changes from V2:
	1)Updation of commit message and resubmition of proper patch set.

Signed-off-by: Amar <amarendra.xt@samsung.com>
---
 drivers/mmc/mmc.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/mmc.h     |  16 ++++++++
 2 files changed, 134 insertions(+)
diff mbox

Patch

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 72e8ce6..8175b49 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1327,3 +1327,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;
+}
diff --git a/include/mmc.h b/include/mmc.h
index a13e2bd..999f0a3 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -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)