summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/dw_mmc.c18
-rw-r--r--include/dwmmc.h9
2 files changed, 27 insertions, 0 deletions
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index a6e50366dc..b3b69fabd4 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -21,6 +21,19 @@
#define PAGE_SIZE 4096
+static inline int __test_and_clear_bit_1(int nr, void *addr)
+{
+ int mask, retval;
+ unsigned int *a = (unsigned int *)addr;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ retval = (mask & *a) != 0;
+ *a &= ~mask;
+
+ return retval;
+}
+
static int dwmci_wait_reset(struct dwmci_host *host, u32 value)
{
unsigned long timeout = 1000;
@@ -317,6 +330,9 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
if (cmd->resp_type & MMC_RSP_CRC)
flags |= DWMCI_CMD_CHECK_CRC;
+ if (__test_and_clear_bit_1(DW_MMC_CARD_NEED_INIT, &host->flags))
+ flags |= DWMCI_CMD_SEND_INIT;
+
flags |= (cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG);
debug("Sending CMD%d\n",cmd->cmdidx);
@@ -594,6 +610,8 @@ static int dwmci_init(struct mmc *mmc)
return -EIO;
}
+ host->flags = 1 << DW_MMC_CARD_NEED_INIT;
+
/* Enumerate at 400KHz */
dwmci_setup_bus(host, mmc->cfg->f_min);
diff --git a/include/dwmmc.h b/include/dwmmc.h
index a2f8ce2bf3..fe1be76a7d 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -92,6 +92,7 @@
#define DWMCI_CMD_RW (1 << 10)
#define DWMCI_CMD_SEND_STOP (1 << 12)
#define DWMCI_CMD_ABORT_STOP (1 << 14)
+#define DWMCI_CMD_SEND_INIT (1 << 15)
#define DWMCI_CMD_PRV_DAT_WAIT (1 << 13)
#define DWMCI_CMD_UPD_CLK (1 << 21)
#define DWMCI_CMD_USE_HOLD_REG (1 << 29)
@@ -198,6 +199,14 @@ struct dwmci_host {
/* use fifo mode to read and write data */
bool fifo_mode;
+
+ /* Starfive: porting from kernel 5.15, fix mmc device power-up sequence */
+ unsigned int flags;
+#define DW_MMC_CARD_PRESENT 0
+#define DW_MMC_CARD_NEED_INIT 1
+#define DW_MMC_CARD_NO_LOW_PWR 2
+#define DW_MMC_CARD_NO_USE_HOLD 3
+#define DW_MMC_CARD_NEEDS_POLL 4
};
struct dwmci_idmac {