mmc: if possible, poll the busy state using DAT0
authorJean-Jacques Hiblot <jjhiblot@ti.com>
Tue, 2 Jul 2019 08:53:53 +0000 (10:53 +0200)
committerPeng Fan <peng.fan@nxp.com>
Mon, 15 Jul 2019 02:16:49 +0000 (10:16 +0800)
Using the DAT0 line as a rdy/busy line is an alternative to reading the
status register of the card. It especially useful in situation where the
bus is not in a good shape, like when modes are switched.
This is also how the linux driver behaves.

Note of warning: As per the specification, while polling on DAT0 the CLK
must not turned off: "[...] Without a clock edge the Device (unless
previously disconnected by a deselect command (CMD7)) will force the DAT0
line down, forever. [...]"

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
drivers/mmc/mmc-uclass.c
drivers/mmc/mmc.c
include/mmc.h

index 923a3b150f80db673103c835a923da8b7ea91672..9327c8302de6b3fd922a3dea2b4f4df05cbcb01d 100644 (file)
@@ -47,7 +47,6 @@ int mmc_set_ios(struct mmc *mmc)
        return dm_mmc_set_ios(mmc->dev);
 }
 
-#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
 int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout)
 {
        struct dm_mmc_ops *ops = mmc_get_ops(dev);
@@ -61,7 +60,6 @@ int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
 {
        return dm_mmc_wait_dat0(mmc->dev, state, timeout);
 }
-#endif
 
 int dm_mmc_get_wp(struct udevice *dev)
 {
index 36cce79eafe38dbc2065347e5adeb4fcf4a8663e..a61e311ccaafe6231677cda5c24a0f9124505ae7 100644 (file)
@@ -29,12 +29,10 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps);
 
 #if !CONFIG_IS_ENABLED(DM_MMC)
 
-#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
 static int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
 {
        return -ENOSYS;
 }
-#endif
 
 __weak int board_mmc_getwp(struct mmc *mmc)
 {
@@ -233,6 +231,10 @@ int mmc_poll_for_busy(struct mmc *mmc, int timeout)
        unsigned int status;
        int err;
 
+       err = mmc_wait_dat0(mmc, 1, timeout);
+       if (err != -ENOSYS)
+               return err;
+
        while (1) {
                err = mmc_send_status(mmc, &status);
                if (err)
index 7f95c3585a219bf408af6e0cf60ae00adc2e05ff..cf83b74dcbcb313cfae9cae20e81a26930e072cf 100644 (file)
@@ -445,7 +445,6 @@ struct dm_mmc_ops {
        int (*execute_tuning)(struct udevice *dev, uint opcode);
 #endif
 
-#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
        /**
         * wait_dat0() - wait until dat0 is in the target state
         *              (CLK must be running during the wait)
@@ -456,7 +455,6 @@ struct dm_mmc_ops {
         * @return 0 if dat0 is in the target state, -ve on error
         */
        int (*wait_dat0)(struct udevice *dev, int state, int timeout);
-#endif
 };
 
 #define mmc_get_ops(dev)        ((struct dm_mmc_ops *)(dev)->driver->ops)