projects
/
platform
/
kernel
/
u-boot.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
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
diff --git
a/drivers/mmc/mmc.c
b/drivers/mmc/mmc.c
index
eecc7d6
..
50f47d4
100644
(file)
--- a/
drivers/mmc/mmc.c
+++ b/
drivers/mmc/mmc.c
@@
-8,12
+8,16
@@
#include <config.h>
#include <common.h>
#include <config.h>
#include <common.h>
+#include <blk.h>
#include <command.h>
#include <dm.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 <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>
#include <power/regulator.h>
#include <malloc.h>
#include <memalign.h>
@@
-24,14
+28,10
@@
#define DEFAULT_CMD6_TIMEOUT_MS 500
static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
#define DEFAULT_CMD6_TIMEOUT_MS 500
static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
-static int mmc_power_cycle(struct mmc *mmc);
-#if !CONFIG_IS_ENABLED(MMC_TINY)
-static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps);
-#endif
#if !CONFIG_IS_ENABLED(DM_MMC)
#if !CONFIG_IS_ENABLED(DM_MMC)
-static int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
+static int mmc_wait_dat0(struct mmc *mmc, int state, int timeout
_us
)
{
return -ENOSYS;
}
{
return -ENOSYS;
}
@@
-136,7
+136,6
@@
const char *mmc_mode_name(enum bus_mode mode)
{
static const char *const names[] = {
[MMC_LEGACY] = "MMC legacy",
{
static const char *const names[] = {
[MMC_LEGACY] = "MMC legacy",
- [SD_LEGACY] = "SD Legacy",
[MMC_HS] = "MMC High Speed (26MHz)",
[SD_HS] = "SD High Speed (50MHz)",
[UHS_SDR12] = "UHS SDR12 (25MHz)",
[MMC_HS] = "MMC High Speed (26MHz)",
[SD_HS] = "SD High Speed (50MHz)",
[UHS_SDR12] = "UHS SDR12 (25MHz)",
@@
-162,7
+161,6
@@
static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
{
static const int freqs[] = {
[MMC_LEGACY] = 25000000,
{
static const int freqs[] = {
[MMC_LEGACY] = 25000000,
- [SD_LEGACY] = 25000000,
[MMC_HS] = 26000000,
[SD_HS] = 50000000,
[MMC_HS_52] = 52000000,
[MMC_HS] = 26000000,
[SD_HS] = 50000000,
[MMC_HS_52] = 52000000,
@@
-230,12
+228,12
@@
int mmc_send_status(struct mmc *mmc, unsigned int *status)
return -ECOMM;
}
return -ECOMM;
}
-int mmc_poll_for_busy(struct mmc *mmc, int timeout)
+int mmc_poll_for_busy(struct mmc *mmc, int timeout
_ms
)
{
unsigned int status;
int err;
{
unsigned int status;
int err;
- err = mmc_wait_dat0(mmc, 1, timeout);
+ err = mmc_wait_dat0(mmc, 1, timeout
_ms * 1000
);
if (err != -ENOSYS)
return err;
if (err != -ENOSYS)
return err;
@@
-256,13
+254,13
@@
int mmc_poll_for_busy(struct mmc *mmc, int timeout)
return -ECOMM;
}
return -ECOMM;
}
- if (timeout-- <= 0)
+ if (timeout
_ms
-- <= 0)
break;
udelay(1000);
}
break;
udelay(1000);
}
- if (timeout <= 0) {
+ if (timeout
_ms
<= 0) {
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
pr_err("Timeout waiting card ready\n");
#endif
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
pr_err("Timeout waiting card ready\n");
#endif
@@
-415,6
+413,16
@@
static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
return blkcnt;
}
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
#if CONFIG_IS_ENABLED(BLK)
ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
#else
@@
-428,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;
int dev_num = block_dev->devnum;
int err;
lbaint_t cur, blocks_todo = blkcnt;
+ uint b_max;
if (blkcnt == 0)
return 0;
if (blkcnt == 0)
return 0;
@@
-457,9
+466,10
@@
ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
return 0;
}
return 0;
}
+ b_max = mmc_get_b_max(mmc, dst, blkcnt);
+
do {
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;
if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
pr_debug("%s: Failed to read blocks\n", __func__);
return 0;
@@
-659,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;
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);
/* Some cards seem to need this */
mmc_go_idle(mmc);
+ start = get_timer(0);
/* Asking to the card its capabilities */
/* 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;
err = mmc_send_op_cond_iter(mmc, i != 0);
if (err)
return err;
@@
-672,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;
/* 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;
}
mmc->op_cond_pending = 1;
return 0;
@@
-724,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;
{
struct mmc_cmd cmd;
struct mmc_data data;
@@
-750,17
+767,17
@@
static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
{
unsigned int status, start;
struct mmc_cmd cmd;
{
unsigned int status, start;
struct mmc_cmd cmd;
- int timeout = DEFAULT_CMD6_TIMEOUT_MS;
+ int timeout
_ms
= DEFAULT_CMD6_TIMEOUT_MS;
bool is_part_switch = (set == EXT_CSD_CMD_SET_NORMAL) &&
(index == EXT_CSD_PART_CONF);
int retries = 3;
int ret;
if (mmc->gen_cmd6_time)
bool is_part_switch = (set == EXT_CSD_CMD_SET_NORMAL) &&
(index == EXT_CSD_PART_CONF);
int retries = 3;
int ret;
if (mmc->gen_cmd6_time)
- timeout = mmc->gen_cmd6_time * 10;
+ timeout
_ms
= mmc->gen_cmd6_time * 10;
if (is_part_switch && mmc->part_switch_time)
if (is_part_switch && mmc->part_switch_time)
- timeout = mmc->part_switch_time * 10;
+ timeout
_ms
= mmc->part_switch_time * 10;
cmd.cmdidx = MMC_CMD_SWITCH;
cmd.resp_type = MMC_RSP_R1b;
cmd.cmdidx = MMC_CMD_SWITCH;
cmd.resp_type = MMC_RSP_R1b;
@@
-778,7
+795,7
@@
static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
start = get_timer(0);
/* poll dat0 for rdy/buys status */
start = get_timer(0);
/* poll dat0 for rdy/buys status */
- ret = mmc_wait_dat0(mmc, 1, timeout);
+ ret = mmc_wait_dat0(mmc, 1, timeout
_ms * 1000
);
if (ret && ret != -ENOSYS)
return ret;
if (ret && ret != -ENOSYS)
return ret;
@@
-788,11
+805,11
@@
static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
* stated timeout to be sufficient.
*/
if (ret == -ENOSYS && !send_status)
* stated timeout to be sufficient.
*/
if (ret == -ENOSYS && !send_status)
- mdelay(timeout);
+ mdelay(timeout
_ms
);
/* Finally wait until the card is ready or indicates a failure
* to switch. It doesn't hurt to use CMD13 here even if send_status
/* Finally wait until the card is ready or indicates a failure
* to switch. It doesn't hurt to use CMD13 here even if send_status
- * is false, because by now (after 'timeout' ms) the bus should be
+ * is false, because by now (after 'timeout
_ms
' ms) the bus should be
* reliable.
*/
do {
* reliable.
*/
do {
@@
-806,7
+823,7
@@
static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
if (!ret && (status & MMC_STATUS_RDY_FOR_DATA))
return 0;
udelay(100);
if (!ret && (status & MMC_STATUS_RDY_FOR_DATA))
return 0;
udelay(100);
- } while (get_timer(start) < timeout);
+ } while (get_timer(start) < timeout
_ms
);
return -ETIMEDOUT;
}
return -ETIMEDOUT;
}
@@
-816,6
+833,11
@@
int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
return __mmc_switch(mmc, set, index, value, true);
}
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)
#if !CONFIG_IS_ENABLED(MMC_TINY)
static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode,
bool hsdowngrade)
@@
-1126,9
+1148,11
@@
int mmc_hwpart_config(struct mmc *mmc,
ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
ext_csd[EXT_CSD_ERASE_GROUP_DEF] = 1;
+#if CONFIG_IS_ENABLED(MMC_WRITE)
/* update erase group size to be high-capacity */
mmc->erase_grp_size =
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
/* update erase group size to be high-capacity */
mmc->erase_grp_size =
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
+#endif
}
}
@@
-1241,7
+1265,7
@@
static int sd_get_capabilities(struct mmc *mmc)
u32 sd3_bus_mode;
#endif
u32 sd3_bus_mode;
#endif
- mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(
SD
_LEGACY);
+ mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(
MMC
_LEGACY);
if (mmc_host_is_spi(mmc))
return 0;
if (mmc_host_is_spi(mmc))
return 0;
@@
-1354,7
+1378,7
@@
static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
return 0;
switch (mode) {
return 0;
switch (mode) {
- case
SD
_LEGACY:
+ case
MMC
_LEGACY:
speed = UHS_SDR12_BUS_SPEED;
break;
case SD_HS:
speed = UHS_SDR12_BUS_SPEED;
break;
case SD_HS:
@@
-1444,6
+1468,20
@@
static int sd_read_ssr(struct mmc *mmc)
cmd.cmdarg = mmc->rca << 16;
err = mmc_send_cmd(mmc, &cmd, NULL);
cmd.cmdarg = mmc->rca << 16;
err = mmc_send_cmd(mmc, &cmd, NULL);
+#ifdef CONFIG_MMC_QUIRKS
+ if (err && (mmc->quirks & MMC_QUIRK_RETRY_APP_CMD)) {
+ int retries = 4;
+ /*
+ * It has been seen that APP_CMD may fail on the first
+ * attempt, let's try a few more times
+ */
+ do {
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+ if (!err)
+ break;
+ } while (retries--);
+ }
+#endif
if (err)
return err;
if (err)
return err;
@@
-1546,6
+1584,16
@@
static int mmc_set_ios(struct mmc *mmc)
return ret;
}
return ret;
}
+
+static int mmc_host_power_cycle(struct mmc *mmc)
+{
+ int ret = 0;
+
+ if (mmc->cfg->ops->host_power_cycle)
+ ret = mmc->cfg->ops->host_power_cycle(mmc);
+
+ return ret;
+}
#endif
int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
#endif
int mmc_set_clock(struct mmc *mmc, uint clock, bool disable)
@@
-1673,7
+1721,7
@@
static const struct mode_width_tuning sd_modes_by_pref[] = {
},
#endif
{
},
#endif
{
- .mode =
SD
_LEGACY,
+ .mode =
MMC
_LEGACY,
.widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
}
};
.widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
}
};
@@
-1703,7
+1751,7
@@
static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
if (mmc_host_is_spi(mmc)) {
mmc_set_bus_width(mmc, 1);
if (mmc_host_is_spi(mmc)) {
mmc_set_bus_width(mmc, 1);
- mmc_select_mode(mmc,
SD
_LEGACY);
+ mmc_select_mode(mmc,
MMC
_LEGACY);
mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
return 0;
}
mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
return 0;
}
@@
-1762,7
+1810,7
@@
static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
error:
/* revert to a safer bus speed */
error:
/* revert to a safer bus speed */
- mmc_select_mode(mmc,
SD
_LEGACY);
+ mmc_select_mode(mmc,
MMC
_LEGACY);
mmc_set_clock(mmc, mmc->tran_speed,
MMC_CLK_ENABLE);
}
mmc_set_clock(mmc, mmc->tran_speed,
MMC_CLK_ENABLE);
}
@@
-2539,7
+2587,7
@@
static int mmc_startup(struct mmc *mmc)
#if CONFIG_IS_ENABLED(MMC_TINY)
mmc_set_clock(mmc, mmc->legacy_speed, false);
#if CONFIG_IS_ENABLED(MMC_TINY)
mmc_set_clock(mmc, mmc->legacy_speed, false);
- mmc_select_mode(mmc,
IS_SD(mmc) ? SD_LEGACY :
MMC_LEGACY);
+ mmc_select_mode(mmc, MMC_LEGACY);
mmc_set_bus_width(mmc, 1);
#else
if (IS_SD(mmc)) {
mmc_set_bus_width(mmc, 1);
#else
if (IS_SD(mmc)) {
@@
-2551,7
+2599,7
@@
static int mmc_startup(struct mmc *mmc)
err = mmc_get_capabilities(mmc);
if (err)
return err;
err = mmc_get_capabilities(mmc);
if (err)
return err;
- mmc_select_mode_and_width(mmc, mmc->card_caps);
+
err =
mmc_select_mode_and_width(mmc, mmc->card_caps);
}
#endif
if (err)
}
#endif
if (err)
@@
-2577,7
+2625,7
@@
static int mmc_startup(struct mmc *mmc)
bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
#if !defined(CONFIG_SPL_BUILD) || \
(defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len);
#if !defined(CONFIG_SPL_BUILD) || \
(defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
- !
defined(CONFIG_
USE_TINY_PRINTF))
+ !
CONFIG_IS_ENABLED(
USE_TINY_PRINTF))
sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
(mmc->cid[3] >> 16) & 0xffff);
sprintf(bdesc->vendor, "Man %06x Snr %04x%04x",
mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
(mmc->cid[3] >> 16) & 0xffff);
@@
-2715,6
+2763,11
@@
static int mmc_power_cycle(struct mmc *mmc)
ret = mmc_power_off(mmc);
if (ret)
return ret;
ret = mmc_power_off(mmc);
if (ret)
return ret;
+
+ ret = mmc_host_power_cycle(mmc);
+ if (ret)
+ return ret;
+
/*
* SD spec recommends at least 1ms of delay. Let's wait for 2ms
* to be on the safer side.
/*
* SD spec recommends at least 1ms of delay. Let's wait for 2ms
* to be on the safer side.
@@
-2740,7
+2793,8
@@
int mmc_get_op_cond(struct mmc *mmc)
#ifdef CONFIG_MMC_QUIRKS
mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
#ifdef CONFIG_MMC_QUIRKS
mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
- MMC_QUIRK_RETRY_SEND_CID;
+ MMC_QUIRK_RETRY_SEND_CID |
+ MMC_QUIRK_RETRY_APP_CMD;
#endif
err = mmc_power_cycle(mmc);
#endif
err = mmc_power_cycle(mmc);
@@
-2777,7
+2831,7
@@
retry:
if (err)
return err;
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 */
mmc_get_blk_desc(mmc)->hwpart = 0;
/* Test for SD version 2 */
@@
-2815,9
+2869,11
@@
int mmc_start_init(struct mmc *mmc)
* all hosts are capable of 1 bit bus-width and able to use the legacy
* timings.
*/
* all hosts are capable of 1 bit bus-width and able to use the legacy
* timings.
*/
- mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(
SD
_LEGACY) |
+ mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(
MMC
_LEGACY) |
MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
-
+#if CONFIG_IS_ENABLED(DM_MMC)
+ mmc_deferred_probe(mmc);
+#endif
#if !defined(CONFIG_MMC_BROKEN_CD)
no_card = mmc_getcd(mmc) == 0;
#else
#if !defined(CONFIG_MMC_BROKEN_CD)
no_card = mmc_getcd(mmc) == 0;
#else
@@
-2998,6
+3054,30
@@
int mmc_initialize(bd_t *bis)
return 0;
}
return 0;
}
+#if CONFIG_IS_ENABLED(DM_MMC)
+int mmc_init_device(int num)
+{
+ struct udevice *dev;
+ struct mmc *m;
+ int ret;
+
+ ret = uclass_get_device(UCLASS_MMC, num, &dev);
+ if (ret)
+ return ret;
+
+ m = mmc_get_mmc_dev(dev);
+ if (!m)
+ return 0;
+#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
+ mmc_set_preinit(m, 1);
+#endif
+ if (m->preinit)
+ mmc_start_init(m);
+
+ return 0;
+}
+#endif
+
#ifdef CONFIG_CMD_BKOPS_ENABLE
int mmc_set_bkops_enable(struct mmc *mmc)
{
#ifdef CONFIG_CMD_BKOPS_ENABLE
int mmc_set_bkops_enable(struct mmc *mmc)
{