From f9516d9db115e5067079f823d2c4ad9938bd174e Mon Sep 17 00:00:00 2001 From: William Qiu Date: Mon, 17 Jul 2023 14:45:18 +0800 Subject: mmc: starfive: fix mmc device power-up sequence fix mmc device power-up sequence. Signed-off-by: William Qiu --- drivers/mmc/dw_mmc.c | 18 ++++++++++++++++++ include/dwmmc.h | 9 +++++++++ 2 files changed, 27 insertions(+) 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 { -- cgit v1.2.3