Merge branch 'master' of git://git.denx.de/u-boot-arm
[platform/kernel/u-boot.git] / drivers / mmc / mmc.c
index 84dae4d..8ab0bc9 100644 (file)
@@ -430,7 +430,7 @@ int mmc_complete_op_cond(struct mmc *mmc)
        mmc->ocr = cmd.response[0];
 
        mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
-       mmc->rca = 0;
+       mmc->rca = 1;
 
        return 0;
 }
@@ -877,6 +877,7 @@ static int mmc_startup(struct mmc *mmc)
 
        mmc->tran_speed = freq * mult;
 
+       mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
        mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
 
        if (IS_SD(mmc))
@@ -907,6 +908,14 @@ static int mmc_startup(struct mmc *mmc)
        if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
                mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
 
+       if ((mmc->dsr_imp) && (0xffffffff != mmc->dsr)) {
+               cmd.cmdidx = MMC_CMD_SET_DSR;
+               cmd.cmdarg = (mmc->dsr & 0xffff) << 16;
+               cmd.resp_type = MMC_RSP_NONE;
+               if (mmc_send_cmd(mmc, &cmd, NULL))
+                       printf("MMC: SET_DSR failed\n");
+       }
+
        /* Select the card, and put it into Transfer Mode */
        if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
                cmd.cmdidx = MMC_CMD_SELECT_CARD;
@@ -960,15 +969,24 @@ static int mmc_startup(struct mmc *mmc)
                }
 
                /*
-                * Check whether GROUP_DEF is set, if yes, read out
-                * group size from ext_csd directly, or calculate
-                * the group size from the csd value.
+                * Host needs to enable ERASE_GRP_DEF bit if device is
+                * partitioned. This bit will be lost every time after a reset
+                * or power off. This will affect erase size.
                 */
-               if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) {
+               if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) &&
+                   (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
+                       err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+                               EXT_CSD_ERASE_GROUP_DEF, 1);
+
+                       if (err)
+                               return err;
+
+                       /* Read out group size from ext_csd */
                        mmc->erase_grp_size =
                                ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
                                        MMC_MAX_BLOCK_LEN * 1024;
                } else {
+                       /* Calculate the group size from the csd value. */
                        int erase_gsz, erase_gmul;
                        erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
                        erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
@@ -1154,6 +1172,9 @@ static int mmc_send_if_cond(struct mmc *mmc)
 
 int mmc_register(struct mmc *mmc)
 {
+       /* Setup dsr related values */
+       mmc->dsr_imp = 0;
+       mmc->dsr = 0xffffffff;
        /* Setup the universal parts of the block interface just once */
        mmc->block_dev.if_type = IF_TYPE_MMC;
        mmc->block_dev.dev = cur_dev_num++;
@@ -1271,6 +1292,12 @@ int mmc_init(struct mmc *mmc)
        return err;
 }
 
+int mmc_set_dsr(struct mmc *mmc, u16 val)
+{
+       mmc->dsr = val;
+       return 0;
+}
+
 /*
  * CPU and board-specific MMC initializations.  Aliased function
  * signals caller to move on
@@ -1415,67 +1442,44 @@ int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
 }
 
 /*
- * This function shall form and send the commands to open / close the
- * boot partition specified by user.
- *
- * Input Parameters:
- * ack: 0x0 - No boot acknowledge sent (default)
- *     0x1 - Boot acknowledge sent during boot operation
- * part_num: User selects boot data that will be sent to master
- *     0x0 - Device not boot enabled (default)
- *     0x1 - Boot partition 1 enabled for boot
- *     0x2 - Boot partition 2 enabled for boot
- * access: User selects partitions to access
- *     0x0 : No access to boot partition (default)
- *     0x1 : R/W boot partition 1
- *     0x2 : R/W boot partition 2
- *     0x3 : R/W Replay Protected Memory Block (RPMB)
+ * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
+ * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
+ * and BOOT_MODE.
  *
  * Returns 0 on success.
  */
-int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
+int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
 {
        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;
+       err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
+                        EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
+                        EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
+                        EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
 
-       cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
-                       (EXT_CSD_PART_CONF << 16) |
-                       ((EXT_CSD_BOOT_ACK(ack) |
-                       EXT_CSD_BOOT_PART_NUM(part_num) |
-                       EXT_CSD_PARTITION_ACCESS(access)) << 8);
-
-       err = mmc_send_cmd(mmc, &cmd, NULL);
-       if (err) {
-               if (access) {
-                       debug("mmc boot partition#%d open fail:Error1 = %d\n",
-                             part_num, err);
-               } else {
-                       debug("mmc boot partition#%d close fail:Error = %d\n",
-                             part_num, err);
-               }
+       if (err)
                return err;
-       }
+       return 0;
+}
 
-       if (access) {
-               /* 4bit transfer mode at booting time. */
-               cmd.cmdidx = MMC_CMD_SWITCH;
-               cmd.resp_type = MMC_RSP_R1b;
+/*
+ * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
+ * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
+ * PARTITION_ACCESS.
+ *
+ * Returns 0 on success.
+ */
+int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
+{
+       int err;
 
-               cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
-                               (EXT_CSD_BOOT_BUS_WIDTH << 16) |
-                               ((1 << 0) << 8);
+       err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
+                        EXT_CSD_BOOT_ACK(ack) |
+                        EXT_CSD_BOOT_PART_NUM(part_num) |
+                        EXT_CSD_PARTITION_ACCESS(access));
 
-               err = mmc_send_cmd(mmc, &cmd, NULL);
-               if (err) {
-                       debug("mmc boot partition#%d open fail:Error2 = %d\n",
-                             part_num, err);
-                       return err;
-               }
-       }
+       if (err)
+               return err;
        return 0;
 }
 #endif