]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00285671 mmc: setup emmc boot partition configure methods
authorRichard Zhu <r65037@freescale.com>
Sat, 12 Oct 2013 07:25:58 +0000 (15:25 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Wed, 20 Aug 2014 08:06:37 +0000 (10:06 +0200)
- Configure boot partition
Expose the interfaces that used to enable the configurations
of the boot mode of the eMMC cards.
usage how-to and examples:
Enable the boot partition 1 boot enabled.
"echo 8 > /sys/devices/soc0/soc.1/2100000.aips-bus/
219c000.usdhc/mmc_host/mmc2/mmc2\:0001/boot_config"

In order to make sure that the re-read the ext-csd of card
can be completed successfully, add the method to wait for
the finish of the busy state.

- setup boot_info message output
Output bit means of important esd_csd register

Read esd_csd info each time when cat boot_info
becasue user may change config affect esd_csd
value.

- Boot partition access howto:
About the details, please refer to the guidance of
Documentation/mmc/mmc-dev-parts.txt

To enable write access to /dev/mmcblkXbootY, disable the forced
read-only access with:
echo 0 > /sys/block/mmcblkXbootY/force_ro

To re-enable read-only access:
echo 1 > /sys/block/mmcblkXbootY/force_ro

NOTE:
- The definitions of the EXT_CSD_PART_CONFIG and EXT_CSD_BOOT_BUS_WIDTH
+------------------------------------------------------------+
| Bit7 | Bit6     | Bit5 Bit4 Bit3        | Bit2 Bit1 Bit0   |
|------|----------|-----------------------|------------------|
| X    | BOOT_ACK | BOOT_PARTITION_ENABLE | PARTITION_ACCESS |
+------------------------------------------------------------+
Bit7: Reserved
Bit6: always set to vaule '1' when boot_part is enabled
Bit[5:3]:
0x0 : Device not boot enabled (default)
0x1 : Boot partition 1 enabled for boot
0x2 : Boot partition 2 enabled for boot
0x7 : User area enabled for boot
Bit[2:0]:
0x0 : No access to boot partition (default)
0x1 : R/W boot partition 1
0x2 : R/W boot partition 2

+--------------------------------------------------------------------+
| Bit7 Bit6 Bit5 | Bit4 Bit3 | Bit2                 | Bit1 Bit0      |
|----------------|----------------------------------|----------------|
| X              | BOOT_MODE | RESET_BOOT_BUS_WIDTH | BOOT_BUS_WIDTH |
+--------------------------------------------------------------------+
Bit [4:3] : BOOT_MODE (non-volatile)
0x0 : Use single data rate + backward compatible timings in boot
operation (default)
0x1 : Use single data rate + high speed timings in boot operation mode
0x2 : Use dual data rate in boot operation
0x3 : Reserved
Bit [2]: RESET_BOOT_BUS_WIDTH (non-volatile)
0x0 : Reset bus width to x1, single data rate and backward compatible
timings after boot operation (default)
0x1 : Retain boot bus width and boot mode after boot operation
Bit[1:0] : BOOT_BUS_WIDTH (non-volatile)
0x0 : x1 (sdr) or x4 (ddr) bus width in boot operation mode (default)
0x1 : x4 (sdr/ddr) bus width in boot operation mode
0x2 : x8 (sdr/ddr) bus width in boot operation mode
0x3 : Reserved

- example of the boot_info:
boot_info:0x07;
  ALT_BOOT_MODE:1 - Supports alternate boot method
  DDR_BOOT_MODE:1 - Supports alternate dual data rate during boot
  HS_BOOTMODE:1 - Supports high speed timing during boot
boot_size:2048KB
  boot_partition:0x48;
  BOOT_ACK:1 - Boot acknowledge sent during boot operation
  BOOT_PARTITION-ENABLE: 1 - Boot partition 1 enabled
  PARTITION_ACCESS:0 - No access to boot partition
boot_bus:0x00
  BOOT_MODE:0 - Use single data rate + backward compatible timings
  in boot operation
  RESET_BOOT_BUS_WIDTH:0 - Reset bus width to x1, single data rate
  and backwardcompatible timings after boot operation
  BOOT_BUS_WIDTH:0 - x1 (sdr) or x4 (ddr) bus width in boot
  operation mode

Signed-off-by: Richard Zhu <r65037@freescale.com>
drivers/mmc/core/mmc.c
include/linux/mmc/card.h
include/linux/mmc/mmc.h

index 793c6f7ddb049a735916eae87585b5cfb0f3b452..249f4d5bca653eb13f1af449f9c8bc6206ccdd63 100644 (file)
@@ -348,6 +348,11 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
                        mmc_card_set_blockaddr(card);
        }
 
+       card->ext_csd.boot_info = ext_csd[EXT_CSD_BOOT_INFO];
+       card->ext_csd.boot_config = ext_csd[EXT_CSD_PART_CONFIG];
+       card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT];
+       card->ext_csd.boot_bus_width = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
+
        card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
        mmc_select_card_type(card);
 
@@ -691,6 +696,372 @@ out:
        return err;
 }
 
+static ssize_t mmc_boot_info_show(struct device *dev,
+                       struct device_attribute *attr, char *buf)
+{
+       char *boot_partition[8] = {
+               "Device not boot enabled",
+               "Boot partition 1 enabled",
+               "Boot partition 2 enabled",
+               "Reserved",
+               "Reserved",
+               "Reserved",
+               "Reserved",
+               "User area enabled for boot"};
+
+       char *bus_width[4] = {
+               "x1 (sdr) or x4 (ddr) bus width in boot operation mode",
+               "x4 (sdr/ddr) bus width in boot operation mode",
+               "x8 (sdr/ddr) bus width in boot operation mode",
+               "Reserved"};
+
+       char *boot_mode[4] = {
+       "Use single data rate + backward compatible timings in boot operation",
+       "Use single data rate + high speed timings in boot operation mode",
+       "Use dual data rate in boot operation",
+       "Reserved"};
+
+       int partition;
+       int width;
+       int mode;
+       int err;
+       u8 *ext_csd = NULL;
+       struct mmc_card *card = container_of(dev, struct mmc_card, dev);
+
+       /* read it again because user may change it */
+       mmc_claim_host(card->host);
+       err = mmc_get_ext_csd(card, &ext_csd);
+       mmc_release_host(card->host);
+       if (err || !ext_csd) {
+               pr_err("%s: failed to get ext_csd, err=%d\n",
+                               mmc_hostname(card->host),
+                               err);
+               return err;
+       }
+
+       mmc_read_ext_csd(card, ext_csd);
+       mmc_free_ext_csd(ext_csd);
+
+       partition = (card->ext_csd.boot_config >> 3) & 0x7;
+       width =  card->ext_csd.boot_bus_width & 0x3;
+       mode = (card->ext_csd.boot_bus_width >> 3) & 0x3;
+
+       return sprintf(buf,
+               "boot_info:0x%02x;\n"
+               "  ALT_BOOT_MODE:%x - %s\n"
+               "  DDR_BOOT_MODE:%x - %s\n"
+               "  HS_BOOTMODE:%x - %s\n"
+               "boot_size:%04dKB\n"
+               "boot_partition:0x%02x;\n"
+               "  BOOT_ACK:%x - %s\n"
+               "  BOOT_PARTITION-ENABLE: %x - %s\n"
+               "boot_bus:0x%02x\n"
+               "  BOOT_MODE:%x - %s\n"
+               "  RESET_BOOT_BUS_WIDTH:%x - %s\n"
+               "  BOOT_BUS_WIDTH:%x - %s\n",
+
+               card->ext_csd.boot_info,
+               !!(card->ext_csd.boot_info & 0x1),
+               (card->ext_csd.boot_info & 0x1) ?
+                       "Supports alternate boot method" :
+                       "Does not support alternate boot method",
+               !!(card->ext_csd.boot_info & 0x2),
+               (card->ext_csd.boot_info & 0x2) ?
+                       "Supports alternate dual data rate during boot" :
+                       "Does not support dual data rate during boot",
+               !!(card->ext_csd.boot_info & 0x4),
+               (card->ext_csd.boot_info & 0x4) ?
+                       "Supports high speed timing during boot" :
+                       "Does not support high speed timing during boot",
+
+               card->ext_csd.boot_size * 128,
+
+               card->ext_csd.boot_config,
+               !!(card->ext_csd.boot_config & 0x40),
+               (card->ext_csd.boot_config & 0x40) ?
+                       "Boot acknowledge sent during boot operation" :
+                       "No boot acknowledge sent",
+               partition,
+               boot_partition[partition],
+
+               card->ext_csd.boot_bus_width,
+               mode,
+               boot_mode[mode],
+               !!(card->ext_csd.boot_bus_width & 0x4),
+               (card->ext_csd.boot_bus_width & 0x4) ?
+                 "Retain boot bus width and boot mode after boot operation" :
+                 "Reset bus width to x1, single data rate and backward"
+                 "compatible timings after boot operation",
+               width,
+               bus_width[width]);
+}
+
+/* set up boot partitions */
+static ssize_t
+setup_boot_partitions(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       int err, busy = 0;
+       u32 part;
+       u8 *ext_csd, boot_config;
+       struct mmc_command cmd;
+       struct mmc_card *card = container_of(dev, struct mmc_card, dev);
+
+       BUG_ON(!card);
+
+       sscanf(buf, "%d\n", &part);
+
+       if (card->csd.mmca_vsn < CSD_SPEC_VER_4) {
+               pr_err("%s: invalid mmc version" \
+                       " mmc version is below version 4!)\n",
+                       mmc_hostname(card->host));
+               return -EINVAL;
+       }
+
+       /* it's a normal SD/MMC but user request to configure boot partition */
+       if (card->ext_csd.boot_size <= 0) {
+               pr_err("%s: fail to send SWITCH command to card " \
+                               "to update boot_config of the EXT_CSD!\n",
+                       mmc_hostname(card->host));
+               return -EINVAL;
+       }
+
+       /*
+        * partition must be -
+        * 0 - user area
+        * 1 - boot partition 1
+        * 2 - boot partition 2
+        * DO NOT switch the partitions that used to be accessed
+        * in OS layer HERE
+        */
+       if (part & EXT_CSD_BOOT_PARTITION_ACCESS_MASK) {
+               pr_err("%s: DO NOT switch the partitions that used to be\n" \
+                       " accessed in OS layer HERE. please following the\n" \
+                       " guidance of Documentation/mmc/mmc-dev-parts.txt.\n",
+                       mmc_hostname(card->host));
+               return -EINVAL;
+       }
+
+       ext_csd = kmalloc(512, GFP_KERNEL);
+       if (!ext_csd) {
+               pr_err("%s: could not allocate a buffer to " \
+                       "receive the ext_csd.\n", mmc_hostname(card->host));
+               return -ENOMEM;
+       }
+
+       mmc_claim_host(card->host);
+       err = mmc_send_ext_csd(card, ext_csd);
+       if (err) {
+               pr_err("%s: unable to read EXT_CSD.\n",
+                       mmc_hostname(card->host));
+               goto err_rtn;
+       }
+
+       /* enable the boot partition in boot mode */
+       /* boot enable be -
+        * 0x00 - disable boot enable.
+        * 0x08 - boot partition 1 is enabled for boot.
+        * 0x10 - boot partition 2 is enabled for boot.
+        * 0x38 - User area is enabled for boot.
+        */
+       switch (part & EXT_CSD_BOOT_PARTITION_ENABLE_MASK) {
+       case 0:
+               boot_config = (ext_csd[EXT_CSD_PART_CONFIG]
+                               & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK
+                               & ~EXT_CSD_BOOT_ACK_ENABLE);
+               break;
+       case EXT_CSD_BOOT_PARTITION_PART1:
+               boot_config = ((ext_csd[EXT_CSD_PART_CONFIG]
+                               & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
+                               | EXT_CSD_BOOT_PARTITION_PART1
+                               | EXT_CSD_BOOT_ACK_ENABLE);
+               break;
+       case EXT_CSD_BOOT_PARTITION_PART2:
+               boot_config = ((ext_csd[EXT_CSD_PART_CONFIG]
+                               & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
+                               | EXT_CSD_BOOT_PARTITION_PART2
+                               | EXT_CSD_BOOT_ACK_ENABLE);
+               break;
+       case EXT_CSD_BOOT_PARTITION_ENABLE_MASK:
+               boot_config = ((ext_csd[EXT_CSD_PART_CONFIG]
+                               | EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
+                               & ~EXT_CSD_BOOT_ACK_ENABLE);
+               break;
+       default:
+               pr_err("%s: wrong boot config parameter" \
+                       " 00 (disable boot), 08 (enable boot1)," \
+                       "16 (enable boot2), 56 (User area)\n",
+                       mmc_hostname(card->host));
+               err = -EINVAL;
+               goto err_rtn;
+       }
+
+       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+               EXT_CSD_PART_CONFIG, boot_config, card->ext_csd.part_time);
+       if (err) {
+               pr_err("%s: fail to send SWITCH command to card " \
+                               "to update boot_config of the EXT_CSD!\n",
+                       mmc_hostname(card->host));
+               goto err_rtn;
+       }
+
+       /* waiting for the card to finish the busy state */
+       do {
+               memset(&cmd, 0, sizeof(struct mmc_command));
+
+               cmd.opcode = MMC_SEND_STATUS;
+               cmd.arg = card->rca << 16;
+               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+
+               err = mmc_wait_for_cmd(card->host, &cmd, 0);
+               if (err || busy > 100) {
+                       pr_err("%s: failed to wait for" \
+                               "the busy state to end.\n",
+                               mmc_hostname(card->host));
+                       break;
+               }
+
+               if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
+                       pr_info("%s: card is in busy state" \
+                               "pls wait for busy state to end.\n",
+                               mmc_hostname(card->host));
+               }
+               busy++;
+       } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
+
+       /* Now check whether it works */
+       err = mmc_send_ext_csd(card, ext_csd);
+       if (err) {
+               pr_err("%s: %d unable to re-read EXT_CSD.\n",
+                       mmc_hostname(card->host), err);
+               goto err_rtn;
+       }
+
+       card->ext_csd.boot_config = ext_csd[EXT_CSD_PART_CONFIG];
+
+err_rtn:
+       mmc_release_host(card->host);
+       kfree(ext_csd);
+       if (err)
+               return err;
+       else
+               return count;
+}
+
+/* configure the boot bus */
+static ssize_t
+setup_boot_bus(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       int err, busy = 0;
+       u32 boot_bus, new_bus;
+       u8 *ext_csd;
+       struct mmc_command cmd;
+       struct mmc_card *card = container_of(dev, struct mmc_card, dev);
+
+       BUG_ON(!card);
+
+       sscanf(buf, "%d\n", &boot_bus);
+
+       if (card->csd.mmca_vsn < CSD_SPEC_VER_4) {
+               pr_err("%s: invalid mmc version" \
+                       " mmc version is below version 4!)\n",
+                       mmc_hostname(card->host));
+               return -EINVAL;
+       }
+
+       /* it's a normal SD/MMC but user request to configure boot bus */
+       if (card->ext_csd.boot_size <= 0) {
+               pr_err("%s: this is a normal SD/MMC card" \
+                       " but you request to configure boot bus !\n",
+                       mmc_hostname(card->host));
+               return -EINVAL;
+       }
+
+       ext_csd = kmalloc(512, GFP_KERNEL);
+       if (!ext_csd) {
+               pr_err("%s: could not allocate a buffer to " \
+                       "receive the ext_csd.\n", mmc_hostname(card->host));
+               return -ENOMEM;
+       }
+
+       mmc_claim_host(card->host);
+       err = mmc_send_ext_csd(card, ext_csd);
+       if (err) {
+               pr_err("%s: unable to read EXT_CSD.\n",
+                       mmc_hostname(card->host));
+               goto err_rtn;
+       }
+
+       /* Configure the boot bus width when boot partition is enabled */
+       if (((boot_bus & EXT_CSD_BOOT_BUS_WIDTH_MODE_MASK) >> 3) > 2
+                       || (boot_bus & EXT_CSD_BOOT_BUS_WIDTH_WIDTH_MASK) > 2
+                       || (boot_bus & ~EXT_CSD_BOOT_BUS_WIDTH_MASK) > 0) {
+               pr_err("%s: Invalid inputs!\n",
+                       mmc_hostname(card->host));
+               err = -EINVAL;
+               goto err_rtn;
+       }
+
+       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+               EXT_CSD_BOOT_BUS_WIDTH, boot_bus, card->ext_csd.part_time);
+       if (err) {
+               pr_err("%s: fail to send SWITCH command to card " \
+                               "to update boot_config of the EXT_CSD!\n",
+                       mmc_hostname(card->host));
+               goto err_rtn;
+       }
+
+       /* waiting for the card to finish the busy state */
+       do {
+               memset(&cmd, 0, sizeof(struct mmc_command));
+
+               cmd.opcode = MMC_SEND_STATUS;
+               cmd.arg = card->rca << 16;
+               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+
+               err = mmc_wait_for_cmd(card->host, &cmd, 0);
+               if (err || busy > 100) {
+                       pr_err("%s: failed to wait for" \
+                               "the busy state to end.\n",
+                               mmc_hostname(card->host));
+                       break;
+               }
+
+               if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
+                       pr_info("%s: card is in busy state" \
+                               "pls wait for busy state to end.\n",
+                               mmc_hostname(card->host));
+               }
+               busy++;
+       } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
+
+       /* Now check whether it works */
+       err = mmc_send_ext_csd(card, ext_csd);
+       if (err) {
+               pr_err("%s: %d unable to re-read EXT_CSD.\n",
+                       mmc_hostname(card->host), err);
+               goto err_rtn;
+       }
+
+       new_bus = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
+       if (boot_bus  != new_bus) {
+               pr_err("%s: after SWITCH, current boot bus mode %d" \
+                               " is not same as requested bus mode %d!\n",
+                       mmc_hostname(card->host), new_bus, boot_bus);
+               goto err_rtn;
+       }
+       card->ext_csd.boot_bus_width = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
+
+err_rtn:
+       mmc_release_host(card->host);
+       mmc_free_ext_csd(ext_csd);
+       if (err)
+               return err;
+       else
+               return count;
+}
+
 MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
        card->raw_cid[2], card->raw_cid[3]);
 MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
@@ -710,6 +1081,9 @@ MMC_DEV_ATTR(enhanced_area_offset, "%llu\n",
 MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size);
 MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult);
 MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
+DEVICE_ATTR(boot_info, S_IRUGO, mmc_boot_info_show, NULL);
+DEVICE_ATTR(boot_config, S_IWUGO, NULL, setup_boot_partitions);
+DEVICE_ATTR(boot_bus_config, S_IWUGO, NULL, setup_boot_bus);
 
 static struct attribute *mmc_std_attrs[] = {
        &dev_attr_cid.attr,
@@ -728,6 +1102,9 @@ static struct attribute *mmc_std_attrs[] = {
        &dev_attr_enhanced_area_size.attr,
        &dev_attr_raw_rpmb_size_mult.attr,
        &dev_attr_rel_sectors.attr,
+       &dev_attr_boot_info.attr,
+       &dev_attr_boot_config.attr,
+       &dev_attr_boot_bus_config.attr,
        NULL,
 };
 ATTRIBUTE_GROUPS(mmc_std);
index d424b9de3affbbee5476b9973070fc03b1b38422..3f81170f6df1b0cf43b991211fd405eafd60f0f5 100644 (file)
@@ -86,10 +86,13 @@ struct mmc_ext_csd {
        unsigned int            data_sector_size;       /* 512 bytes or 4KB */
        unsigned int            data_tag_unit_size;     /* DATA TAG UNIT size */
        unsigned int            boot_ro_lock;           /* ro lock support */
+       unsigned int            boot_size;
        bool                    boot_ro_lockable;
        u8                      raw_exception_status;   /* 54 */
        u8                      raw_partition_support;  /* 160 */
        u8                      raw_rpmb_size_mult;     /* 168 */
+       u8                      boot_bus_width;         /* 177 */
+       u8                      boot_config;            /* 179 */
        u8                      raw_erased_mem_count;   /* 181 */
        u8                      raw_ext_csd_structure;  /* 194 */
        u8                      raw_card_type;          /* 196 */
@@ -102,6 +105,7 @@ struct mmc_ext_csd {
        u8                      raw_hc_erase_gap_size;  /* 221 */
        u8                      raw_erase_timeout_mult; /* 223 */
        u8                      raw_hc_erase_grp_size;  /* 224 */
+       u8                      boot_info;              /* 228 */
        u8                      raw_sec_trim_mult;      /* 229 */
        u8                      raw_sec_erase_mult;     /* 230 */
        u8                      raw_sec_feature_support;/* 231 */
index 64ec963ed3478b88babe7c4292c2b2e310ca51c2..e175d05186af954d074e9949ede733f40690e72b 100644 (file)
@@ -292,6 +292,7 @@ struct _mmc_csd {
 #define EXT_CSD_RPMB_MULT              168     /* RO */
 #define EXT_CSD_BOOT_WP                        173     /* R/W */
 #define EXT_CSD_ERASE_GROUP_DEF                175     /* R/W */
+#define EXT_CSD_BOOT_BUS_WIDTH         177     /* R/W */
 #define EXT_CSD_PART_CONFIG            179     /* R/W */
 #define EXT_CSD_ERASED_MEM_CONT                181     /* RO */
 #define EXT_CSD_BUS_WIDTH              183     /* R/W */
@@ -313,6 +314,7 @@ struct _mmc_csd {
 #define EXT_CSD_ERASE_TIMEOUT_MULT     223     /* RO */
 #define EXT_CSD_HC_ERASE_GRP_SIZE      224     /* RO */
 #define EXT_CSD_BOOT_MULT              226     /* RO */
+#define EXT_CSD_BOOT_INFO              228     /* RO, 1 bytes */
 #define EXT_CSD_SEC_TRIM_MULT          229     /* RO */
 #define EXT_CSD_SEC_ERASE_MULT         230     /* RO */
 #define EXT_CSD_SEC_FEATURE_SUPPORT    231     /* RO */
@@ -391,6 +393,29 @@ struct _mmc_csd {
 #define EXT_CSD_SEC_GB_CL_EN   BIT(4)
 #define EXT_CSD_SEC_SANITIZE   BIT(6)  /* v4.5 only */
 
+#define EXT_CSD_BOOT_BUS_WIDTH_MASK                    (0x1F)
+#define EXT_CSD_BOOT_BUS_WIDTH_MODE_MASK       (0x3 << 3)
+#define EXT_CSD_BOOT_BUS_WIDTH_MODE_SDR_NORMAL (0x0)
+#define EXT_CSD_BOOT_BUS_WIDTH_MODE_SDR_HIGH   (0x1)
+#define EXT_CSD_BOOT_BUS_WIDTH_MODE_DDR                (0x2)
+#define EXT_CSD_BOOT_BUS_WIDTH_RST_WIDTH       (1 << 2)
+#define EXT_CSD_BOOT_BUS_WIDTH_WIDTH_MASK      (0x3)
+#define EXT_CSD_BOOT_BUS_WIDTH_1_SDR_4_DDR     (0x0)
+#define EXT_CSD_BOOT_BUS_WIDTH_4_SDR_4_DDR     (0x1)
+#define EXT_CSD_BOOT_BUS_WIDTH_8_SDR_8_DDR     (0x2)
+
+#define EXT_CSD_BOOT_ACK_ENABLE                (0x1 << 6)
+#define EXT_CSD_BOOT_PARTITION_ENABLE_MASK      (0x7 << 3)
+#define EXT_CSD_BOOT_PARTITION_DISABLE          (0x0)
+#define EXT_CSD_BOOT_PARTITION_PART1            (0x1 << 3)
+#define EXT_CSD_BOOT_PARTITION_PART2            (0x2 << 3)
+#define EXT_CSD_BOOT_PARTITION_USER             (0x7 << 3)
+
+#define EXT_CSD_BOOT_PARTITION_ACCESS_MASK      (0x7)
+#define EXT_CSD_BOOT_PARTITION_ACCESS_DISABLE   (0x0)
+#define EXT_CSD_BOOT_PARTITION_ACCESS_PART1     (0x1)
+#define EXT_CSD_BOOT_PARTITION_ACCESS_PART2     (0x2)
+
 #define EXT_CSD_RST_N_EN_MASK  0x3
 #define EXT_CSD_RST_N_ENABLED  1       /* RST_n is enabled on card */