Merge tag 'mips-pull-2020-06-29' of https://gitlab.denx.de/u-boot/custodians/u-boot...
[platform/kernel/u-boot.git] / drivers / mmc / mmc.c
index 3e36566..50f47d4 100644 (file)
@@ -8,12 +8,16 @@
 
 #include <config.h>
 #include <common.h>
+#include <blk.h>
 #include <command.h>
 #include <dm.h>
+#include <log.h>
 #include <dm/device-internal.h>
 #include <errno.h>
 #include <mmc.h>
 #include <part.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
 #include <power/regulator.h>
 #include <malloc.h>
 #include <memalign.h>
@@ -409,6 +413,16 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
        return blkcnt;
 }
 
+#if !CONFIG_IS_ENABLED(DM_MMC)
+static int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt)
+{
+       if (mmc->cfg->ops->get_b_max)
+               return mmc->cfg->ops->get_b_max(mmc, dst, blkcnt);
+       else
+               return mmc->cfg->b_max;
+}
+#endif
+
 #if CONFIG_IS_ENABLED(BLK)
 ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
 #else
@@ -422,6 +436,7 @@ ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
        int dev_num = block_dev->devnum;
        int err;
        lbaint_t cur, blocks_todo = blkcnt;
+       uint b_max;
 
        if (blkcnt == 0)
                return 0;
@@ -451,9 +466,10 @@ ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
                return 0;
        }
 
+       b_max = mmc_get_b_max(mmc, dst, blkcnt);
+
        do {
-               cur = (blocks_todo > mmc->cfg->b_max) ?
-                       mmc->cfg->b_max : blocks_todo;
+               cur = (blocks_todo > b_max) ? b_max : blocks_todo;
                if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
                        pr_debug("%s: Failed to read blocks\n", __func__);
                        return 0;
@@ -653,12 +669,15 @@ static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
 static int mmc_send_op_cond(struct mmc *mmc)
 {
        int err, i;
+       int timeout = 1000;
+       uint start;
 
        /* Some cards seem to need this */
        mmc_go_idle(mmc);
 
+       start = get_timer(0);
        /* Asking to the card its capabilities */
-       for (i = 0; i < 2; i++) {
+       for (i = 0; ; i++) {
                err = mmc_send_op_cond_iter(mmc, i != 0);
                if (err)
                        return err;
@@ -666,6 +685,10 @@ static int mmc_send_op_cond(struct mmc *mmc)
                /* exit if not busy (flag seems to be inverted) */
                if (mmc->ocr & OCR_BUSY)
                        break;
+
+               if (get_timer(start) > timeout)
+                       return -ETIMEDOUT;
+               udelay(100);
        }
        mmc->op_cond_pending = 1;
        return 0;
@@ -718,7 +741,7 @@ static int mmc_complete_op_cond(struct mmc *mmc)
 }
 
 
-static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
+int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
 {
        struct mmc_cmd cmd;
        struct mmc_data data;
@@ -810,6 +833,11 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
        return __mmc_switch(mmc, set, index, value, true);
 }
 
+int mmc_boot_wp(struct mmc *mmc)
+{
+       return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, 1);
+}
+
 #if !CONFIG_IS_ENABLED(MMC_TINY)
 static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode,
                              bool hsdowngrade)
@@ -2803,7 +2831,7 @@ retry:
        if (err)
                return err;
 
-       /* The internal partition reset to user partition(0) at every CMD0*/
+       /* The internal partition reset to user partition(0) at every CMD0 */
        mmc_get_blk_desc(mmc)->hwpart = 0;
 
        /* Test for SD version 2 */