From bae4a1fdf59cddf02acd0070d1da7303fe5ffd0e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 10 Jul 2016 00:40:22 +0900 Subject: mmc: sdhci: clean up timeout detection The current timeout detection logic is not very nice; it calls get_timer(start) in the while() loop, and then calls it again after the loop to check if a timeout error happened. Because of the time difference between the two calls of get_timer(), the timeout detected after the loop may not be true. Signed-off-by: Masahiro Yamada Acked-by: Jaehoon Chung Signed-off-by: Jaehoon Chung --- drivers/mmc/sdhci.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 9fdbed8..1de1f8e 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -252,17 +252,17 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, stat = sdhci_readl(host, SDHCI_INT_STATUS); if (stat & SDHCI_INT_ERROR) break; - } while (((stat & mask) != mask) && - (get_timer(start) < SDHCI_READ_STATUS_TIMEOUT)); - if (get_timer(start) >= SDHCI_READ_STATUS_TIMEOUT) { - if (host->quirks & SDHCI_QUIRK_BROKEN_R1B) - return 0; - else { - printf("%s: Timeout for status update!\n", __func__); - return TIMEOUT; + if (get_timer(start) >= SDHCI_READ_STATUS_TIMEOUT) { + if (host->quirks & SDHCI_QUIRK_BROKEN_R1B) { + return 0; + } else { + printf("%s: Timeout for status update!\n", + __func__); + return TIMEOUT; + } } - } + } while ((stat & mask) != mask); if ((stat & (SDHCI_INT_ERROR | mask)) == mask) { sdhci_cmd_done(host, cmd); -- cgit v1.1 From 17ea3c862865c0d704646f67dbf8412f9ff54f59 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Tue, 12 Jul 2016 21:18:46 +0900 Subject: mmc: sdhci: set to INT_DATA_END when there are data There is no data, it doesn't needs to wait for completing data transfer. (It seems that it can be removed.) Almost all timeout error is occured from stop command without data. After applied this patch, I hope that we don't need to increase timeout value anymore. Signed-off-by: Jaehoon Chung Acked-by: Lukasz Majewski Tested-by: Lukasz Majewski Acked-by: Minkyu Kang --- drivers/mmc/sdhci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 1de1f8e..d584b0b 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -184,7 +184,8 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, flags = SDHCI_CMD_RESP_LONG; else if (cmd->resp_type & MMC_RSP_BUSY) { flags = SDHCI_CMD_RESP_SHORT_BUSY; - mask |= SDHCI_INT_DATA_END; + if (data) + mask |= SDHCI_INT_DATA_END; } else flags = SDHCI_CMD_RESP_SHORT; -- cgit v1.1 From a034ec06ff1d558bbe11d5ee05edbb4de3ee2215 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Tue, 12 Jul 2016 21:18:47 +0900 Subject: mmc: s5p_sdhci: unset the SDHCI_QUIRK_BROKEN_R1B Unset the SDHCI_QUIRK_BROKEN_R1B for exynos SoC. (Tested on Exynos4 Boards.) Signed-off-by: Jaehoon Chung Acked-by: Lukasz Majewski Tested-by: Lukasz Majewski --- drivers/mmc/s5p_sdhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index 44353c7..3bace21 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -68,7 +68,7 @@ static int s5p_sdhci_core_init(struct sdhci_host *host) host->name = S5P_NAME; host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE | - SDHCI_QUIRK_BROKEN_R1B | SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_USE_WIDE8; host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; host->version = sdhci_readw(host, SDHCI_HOST_VERSION); -- cgit v1.1 From ccd60a8524aa364e6f3c06e4526f2ddd61f1cf25 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Tue, 19 Jul 2016 16:33:34 +0900 Subject: mmc: dw_mmc: remove the duplicated header file is already included in . It can use instead of Signed-off-by: Jaehoon Chung Reviewed-by: Simon Glass --- drivers/mmc/dw_mmc.c | 1 - drivers/mmc/exynos_dw_mmc.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index b58c282..3ca9743 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -13,7 +13,6 @@ #include #include #include -#include #define PAGE_SIZE 4096 diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 283befc..57271f1 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -10,12 +10,12 @@ #include #include #include +#include #include #include #include #include #include -#include #define DWMMC_MAX_CH_NUM 4 #define DWMMC_MAX_FREQ 52000000 -- cgit v1.1 From 70f862808e8ae4b97fe736ec9d9d496881ad84b2 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Tue, 19 Jul 2016 16:33:35 +0900 Subject: mmc: fsl_esdhc: remove the duplicated header file "mmc.h" is already included. It's duplicated. Signed-off-by: Jaehoon Chung Reviewed-by: Simon Glass --- drivers/mmc/fsl_esdhc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index a865c7b..86c9a67 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include -- cgit v1.1 From 915ffa5213756568f6185d05cda2cb2f6050f974 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Tue, 19 Jul 2016 16:33:36 +0900 Subject: mmc: use the generic error number Use the generic error number instead of specific error number. If use the generic error number, it can debug more easier. Signed-off-by: Jaehoon Chung Reviewed-by: Simon Glass Reviewed-by: Minkyu Kang --- drivers/mmc/arm_pl180_mmci.c | 2 +- drivers/mmc/bfin_sdh.c | 10 +++++----- drivers/mmc/davinci_mmc.c | 11 ++++++----- drivers/mmc/dw_mmc.c | 8 ++++---- drivers/mmc/fsl_esdhc.c | 13 +++++++------ drivers/mmc/ftsdc010_mci.c | 10 +++++----- drivers/mmc/gen_atmel_mci.c | 10 +++++----- drivers/mmc/mmc.c | 18 +++++++++--------- drivers/mmc/mmc_spi.c | 11 ++++++----- drivers/mmc/mvebu_mmc.c | 9 +++++---- drivers/mmc/mxcmmc.c | 6 +++--- drivers/mmc/mxsmmc.c | 18 +++++++++--------- drivers/mmc/omap_hsmmc.c | 18 +++++++++--------- drivers/mmc/s3c_sdi.c | 4 ++-- drivers/mmc/sdhci.c | 8 ++++---- drivers/mmc/sh_mmcif.c | 8 ++++---- drivers/mmc/sh_sdhi.c | 6 +++--- drivers/mmc/sunxi_mmc.c | 6 +++--- drivers/mmc/tegra_mmc.c | 7 ++++--- drivers/mmc/uniphier-sd.c | 2 +- include/mmc.h | 6 ------ 21 files changed, 95 insertions(+), 96 deletions(-) diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 8f2694f..e64ac3c 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -37,7 +37,7 @@ static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd) writel(statusmask, &host->base->status_clear); if (hoststatus & SDI_STA_CTIMEOUT) { debug("CMD%d time out\n", cmd->cmdidx); - return TIMEOUT; + return -ETIMEDOUT; } else if ((hoststatus & SDI_STA_CCRCFAIL) && (cmd->resp_type & MMC_RSP_CRC)) { printf("CMD%d CRC error\n", cmd->cmdidx); diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c index 9bdfbbc..0e493da 100644 --- a/drivers/mmc/bfin_sdh.c +++ b/drivers/mmc/bfin_sdh.c @@ -109,9 +109,9 @@ sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd) } if (status & CMD_TIME_OUT) - ret = TIMEOUT; + ret = -ETIMEDOUT; else if (status & CMD_CRC_FAIL && flags & MMC_RSP_CRC) - ret = COMM_ERR; + ret = -ECOMM; else ret = 0; @@ -136,7 +136,7 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data) /* Don't support write yet. */ if (data->flags & MMC_DATA_WRITE) - return UNUSABLE_ERR; + return -EOPNOTSUPP; #ifndef RSI_BLKSZ data_ctl |= ((ffs(data->blocksize) - 1) << 4); #else @@ -194,10 +194,10 @@ static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd, if (status & DAT_TIME_OUT) { bfin_write_SDH_STATUS_CLR(DAT_TIMEOUT_STAT); - ret |= TIMEOUT; + ret = -ETIMEDOUT; } else if (status & (DAT_CRC_FAIL | RX_OVERRUN)) { bfin_write_SDH_STATUS_CLR(DAT_CRC_FAIL_STAT | RX_OVERRUN_STAT); - ret |= COMM_ERR; + ret = -ECOMM; } else bfin_write_SDH_STATUS_CLR(DAT_BLK_END_STAT | DAT_END_STAT); diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index aae00e9..b495c75 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -66,7 +67,7 @@ dmmc_wait_fifo_status(volatile struct davinci_mmc_regs *regs, uint status) udelay(100); if (wdog == 0) - return COMM_ERR; + return -ECOMM; return 0; } @@ -80,7 +81,7 @@ static int dmmc_busy_wait(volatile struct davinci_mmc_regs *regs) udelay(10); if (wdog == 0) - return COMM_ERR; + return -ECOMM; return 0; } @@ -99,7 +100,7 @@ static int dmmc_check_status(volatile struct davinci_mmc_regs *regs, return 0; } else if (mmcstatus & st_error) { if (mmcstatus & MMCST0_TOUTRS) - return TIMEOUT; + return -ETIMEDOUT; printf("[ ST0 ERROR %x]\n", mmcstatus); /* * Ignore CRC errors as some MMC cards fail to @@ -107,7 +108,7 @@ static int dmmc_check_status(volatile struct davinci_mmc_regs *regs, */ if (mmcstatus & MMCST0_CRCRS) return 0; - return COMM_ERR; + return -ECOMM; } udelay(10); @@ -116,7 +117,7 @@ static int dmmc_check_status(volatile struct davinci_mmc_regs *regs, printf("Status %x Timeout ST0:%x ST1:%x\n", st_ready, mmcstatus, get_val(®s->mmcst1)); - return COMM_ERR; + return -ECOMM; } /* diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 3ca9743..a6a5fc6 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -158,7 +158,7 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) if (get_timer(start) > timeout) { debug("%s: Timeout waiting for data!\n", __func__); - ret = TIMEOUT; + ret = -ETIMEDOUT; break; } } @@ -203,7 +203,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) { if (get_timer(start) > timeout) { debug("%s: Timeout on data busy\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } } @@ -269,7 +269,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, if (i == retry) { debug("%s: Timeout.\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } if (mask & DWMCI_INTMSK_RTO) { @@ -282,7 +282,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, * CMD8, please keep that in mind. */ debug("%s: Response Timeout.\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } else if (mask & DWMCI_INTMSK_RE) { debug("%s: Response Error.\n", __func__); return -EIO; diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 86c9a67..103b32e 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -252,7 +253,7 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) if ((esdhc_read32(®s->prsstat) & PRSSTAT_WPSPL) == 0) { printf("\nThe SD card is locked. Can not write to a locked card.\n\n"); - return TIMEOUT; + return -ETIMEDOUT; } } @@ -410,12 +411,12 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) irqstat = esdhc_read32(®s->irqstat); if (irqstat & CMD_ERR) { - err = COMM_ERR; + err = -ECOMM; goto out; } if (irqstat & IRQSTAT_CTOE) { - err = TIMEOUT; + err = -ETIMEDOUT; goto out; } @@ -441,7 +442,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) if (timeout <= 0) { printf("Timeout waiting for DAT0 to go high!\n"); - err = TIMEOUT; + err = -ETIMEDOUT; goto out; } } @@ -470,12 +471,12 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) irqstat = esdhc_read32(®s->irqstat); if (irqstat & IRQSTAT_DTOE) { - err = TIMEOUT; + err = -ETIMEDOUT; goto out; } if (irqstat & DATA_ERR) { - err = COMM_ERR; + err = -ECOMM; goto out; } } while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE); diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c index a620678..c02740f 100644 --- a/drivers/mmc/ftsdc010_mci.c +++ b/drivers/mmc/ftsdc010_mci.c @@ -34,7 +34,7 @@ static inline int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd) { struct ftsdc010_chip *chip = mmc->priv; struct ftsdc010_mmc __iomem *regs = chip->regs; - int ret = TIMEOUT; + int ret = -ETIMEDOUT; uint32_t ts, st; uint32_t cmd = FTSDC010_CMD_IDX(mmc_cmd->cmdidx); uint32_t arg = mmc_cmd->cmdarg; @@ -126,7 +126,7 @@ static void ftsdc010_clkset(struct mmc *mmc, uint32_t rate) static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask) { - int ret = TIMEOUT; + int ret = -ETIMEDOUT; uint32_t st, ts; for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) { @@ -151,7 +151,7 @@ static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask) static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { - int ret = UNUSABLE_ERR; + int ret = -EOPNOTSUPP; uint32_t len = 0; struct ftsdc010_chip *chip = mmc->priv; struct ftsdc010_mmc __iomem *regs = chip->regs; @@ -279,7 +279,7 @@ static int ftsdc010_init(struct mmc *mmc) uint32_t ts; if (readl(®s->status) & FTSDC010_STATUS_CARD_DETECT) - return NO_CARD_ERR; + return -ENOMEDIUM; if (readl(®s->status) & FTSDC010_STATUS_WRITE_PROT) { printf("ftsdc010: write protected\n"); @@ -297,7 +297,7 @@ static int ftsdc010_init(struct mmc *mmc) } if (readl(®s->cmd) & FTSDC010_CMD_SDC_RST) { printf("ftsdc010: reset failed\n"); - return UNUSABLE_ERR; + return -EOPNOTSUPP; } /* 2. enter low speed mode (400k card detection) */ diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index 0474a15..69770df 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -213,7 +213,7 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) if (!priv->initialized) { puts ("MCI not initialized!\n"); - return COMM_ERR; + return -ECOMM; } /* Figure out the transfer arguments */ @@ -238,10 +238,10 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) if ((status & error_flags) & MMCI_BIT(RTOE)) { dump_cmd(cmdr, cmd->cmdarg, status, "Command Time Out"); - return TIMEOUT; + return -ETIMEDOUT; } else if (status & error_flags) { dump_cmd(cmdr, cmd->cmdarg, status, "Command Failed"); - return COMM_ERR; + return -ECOMM; } /* Copy the response to the response buffer */ @@ -303,7 +303,7 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) if (status) { dump_cmd(cmdr, cmd->cmdarg, status, "Data Transfer Failed"); - return COMM_ERR; + return -ECOMM; } } @@ -315,7 +315,7 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) if (status & error_flags) { dump_cmd(cmdr, cmd->cmdarg, status, "DTIP Wait Failed"); - return COMM_ERR; + return -ECOMM; } i++; } while ((status & MMCI_BIT(DTIP)) && i < 10000); diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index f8e5f7a..3daa748 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -152,7 +152,7 @@ int mmc_send_status(struct mmc *mmc, int timeout) printf("Status Error: 0x%08X\n", cmd.response[0]); #endif - return COMM_ERR; + return -ECOMM; } } else if (--retries < 0) return err; @@ -168,7 +168,7 @@ int mmc_send_status(struct mmc *mmc, int timeout) #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) printf("Timeout waiting card ready\n"); #endif - return TIMEOUT; + return -ETIMEDOUT; } return 0; @@ -344,7 +344,7 @@ static int sd_send_op_cond(struct mmc *mmc) break; if (timeout-- <= 0) - return UNUSABLE_ERR; + return -EOPNOTSUPP; udelay(1000); } @@ -430,7 +430,7 @@ static int mmc_complete_op_cond(struct mmc *mmc) if (mmc->ocr & OCR_BUSY) break; if (get_timer(start) > timeout) - return UNUSABLE_ERR; + return -EOPNOTSUPP; udelay(100); } } @@ -1429,7 +1429,7 @@ static int mmc_startup(struct mmc *mmc) &test_csd[EXT_CSD_SEC_CNT], 4) == 0) break; else - err = SWITCH_ERR; + err = -EBADMSG; } if (err) @@ -1499,7 +1499,7 @@ static int mmc_send_if_cond(struct mmc *mmc) return err; if ((cmd.response[0] & 0xff) != 0xaa) - return UNUSABLE_ERR; + return -EOPNOTSUPP; else mmc->version = SD_VERSION_2; @@ -1526,7 +1526,7 @@ int mmc_start_init(struct mmc *mmc) #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) printf("MMC: no card present\n"); #endif - return NO_CARD_ERR; + return -ENOMEDIUM; } if (mmc->has_init) @@ -1565,14 +1565,14 @@ int mmc_start_init(struct mmc *mmc) err = sd_send_op_cond(mmc); /* If the command timed out, we check for an MMC card */ - if (err == TIMEOUT) { + if (err == -ETIMEDOUT) { err = mmc_send_op_cond(mmc); if (err) { #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) printf("Card did not respond to voltage select!\n"); #endif - return UNUSABLE_ERR; + return -EOPNOTSUPP; } } diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c index 7547e1a..2510117 100644 --- a/drivers/mmc/mmc_spi.c +++ b/drivers/mmc/mmc_spi.c @@ -5,6 +5,7 @@ * Licensed under the GPL-2 or later. */ #include +#include #include #include #include @@ -182,13 +183,13 @@ static int mmc_spi_request(struct mmc *mmc, struct mmc_cmd *cmd, spi_cs_activate(spi); r1 = mmc_spi_sendcmd(mmc, cmd->cmdidx, cmd->cmdarg); if (r1 == 0xff) { /* no response */ - ret = NO_CARD_ERR; + ret = -ENOMEDIUM; goto done; } else if (r1 & R1_SPI_COM_CRC) { - ret = COMM_ERR; + ret = -ECOMM; goto done; } else if (r1 & ~R1_SPI_IDLE) { /* other errors */ - ret = TIMEOUT; + ret = -ETIMEDOUT; goto done; } else if (cmd->resp_type == MMC_RSP_R2) { r1 = mmc_spi_readdata(mmc, cmd->response, 1, 16); @@ -225,9 +226,9 @@ static int mmc_spi_request(struct mmc *mmc, struct mmc_cmd *cmd, data->blocks, data->blocksize, (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)); if (r1 & R1_SPI_COM_CRC) - ret = COMM_ERR; + ret = -ECOMM; else if (r1) /* other errors */ - ret = TIMEOUT; + ret = -ETIMEDOUT; } done: spi_cs_deactivate(spi); diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c index 056aef5..a2792ac 100644 --- a/drivers/mmc/mvebu_mmc.c +++ b/drivers/mmc/mvebu_mmc.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -172,15 +173,15 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) { debug("%s: command READ timed out\n", DRIVER_NAME); - return TIMEOUT; + return -ETIMEDOUT; } debug("%s: command READ error\n", DRIVER_NAME); - return COMM_ERR; + return -ECOMM; } if ((get_timer(0) - start) > TIMEOUT_DELAY) { debug("%s: command timed out\n", DRIVER_NAME); - return TIMEOUT; + return -ETIMEDOUT; } } @@ -232,7 +233,7 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) & (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) - return TIMEOUT; + return -ETIMEDOUT; return 0; } diff --git a/drivers/mmc/mxcmmc.c b/drivers/mmc/mxcmmc.c index 561b204..8038f90 100644 --- a/drivers/mmc/mxcmmc.c +++ b/drivers/mmc/mxcmmc.c @@ -211,11 +211,11 @@ static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat) } else if (stat & STATUS_CRC_WRITE_ERR) { u32 err_code = (stat >> 9) & 0x3; if (err_code == 2) /* No CRC response */ - data_error = TIMEOUT; + data_error = -ETIMEDOUT; else data_error = -EILSEQ; } else if (stat & STATUS_TIME_OUT_READ) { - data_error = TIMEOUT; + data_error = -ETIMEDOUT; } else { data_error = -EIO; } @@ -238,7 +238,7 @@ static int mxcmci_read_response(struct mxcmci_host *host, unsigned int stat) if (stat & STATUS_TIME_OUT_RESP) { printf("CMD TIMEOUT\n"); - return TIMEOUT; + return -ETIMEDOUT; } else if (stat & STATUS_RESP_CRC_ERR && cmd->resp_type & MMC_RSP_CRC) { printf("cmd crc error\n"); return -EILSEQ; diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c index 9fa87d5..40f3eaa 100644 --- a/drivers/mmc/mxsmmc.c +++ b/drivers/mmc/mxsmmc.c @@ -84,7 +84,7 @@ static int mxsmmc_send_cmd_pio(struct mxsmmc_priv *priv, struct mmc_data *data) } } - return timeout ? 0 : COMM_ERR; + return timeout ? 0 : -ECOMM; } static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data) @@ -120,7 +120,7 @@ static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data) mxs_dma_desc_append(dmach, priv->desc); if (mxs_dma_go(dmach)) { bounce_buffer_stop(&bbstate); - return COMM_ERR; + return -ECOMM; } bounce_buffer_stop(&bbstate); @@ -158,13 +158,13 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) if (!timeout) { printf("MMC%d: Bus busy timeout!\n", mmc->block_dev.devnum); - return TIMEOUT; + return -ETIMEDOUT; } /* See if card is present */ if (!mxsmmc_cd(priv)) { printf("MMC%d: No card detected!\n", mmc->block_dev.devnum); - return NO_CARD_ERR; + return -ENOMEDIUM; } /* Start building CTRL0 contents */ @@ -203,7 +203,7 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) priv->mmc_is_wp(mmc->block_dev.devnum)) { printf("MMC%d: Can not write a locked card!\n", mmc->block_dev.devnum); - return UNUSABLE_ERR; + return -EOPNOTSUPP; } ctrl0 |= SSP_CTRL0_DATA_XFER; @@ -244,21 +244,21 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) if (!timeout) { printf("MMC%d: Command %d busy\n", mmc->block_dev.devnum, cmd->cmdidx); - return TIMEOUT; + return -ETIMEDOUT; } /* Check command timeout */ if (reg & SSP_STATUS_RESP_TIMEOUT) { printf("MMC%d: Command %d timeout (status 0x%08x)\n", mmc->block_dev.devnum, cmd->cmdidx, reg); - return TIMEOUT; + return -ETIMEDOUT; } /* Check command errors */ if (reg & (SSP_STATUS_RESP_CRC_ERR | SSP_STATUS_RESP_ERR)) { printf("MMC%d: Command %d error (status 0x%08x)!\n", mmc->block_dev.devnum, cmd->cmdidx, reg); - return COMM_ERR; + return -ECOMM; } /* Copy response to response buffer */ @@ -298,7 +298,7 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) SSP_STATUS_FIFO_OVRFLW | SSP_STATUS_FIFO_UNDRFLW)) { printf("MMC%d: Data error with command %d (status 0x%08x)!\n", mmc->block_dev.devnum, cmd->cmdidx, reg); - return COMM_ERR; + return -ECOMM; } return 0; diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index d007b56..e80ac3d 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -231,7 +231,7 @@ static int omap_hsmmc_init_setup(struct mmc *mmc) while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) { if (get_timer(0) - start > MAX_RETRY_MS) { printf("%s: timedout waiting for cc2!\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } } writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl); @@ -240,7 +240,7 @@ static int omap_hsmmc_init_setup(struct mmc *mmc) if (get_timer(0) - start > MAX_RETRY_MS) { printf("%s: timedout waiting for softresetall!\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } } writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl); @@ -262,7 +262,7 @@ static int omap_hsmmc_init_setup(struct mmc *mmc) while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) { if (get_timer(0) - start > MAX_RETRY_MS) { printf("%s: timedout waiting for ics!\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } } writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl); @@ -337,7 +337,7 @@ static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, if (get_timer(0) - start > MAX_RETRY_MS) { printf("%s: timedout waiting on cmd inhibit to clear\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } } writel(0xFFFFFFFF, &mmc_base->stat); @@ -346,7 +346,7 @@ static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, if (get_timer(0) - start > MAX_RETRY_MS) { printf("%s: timedout waiting for STAT (%x) to clear\n", __func__, readl(&mmc_base->stat)); - return TIMEOUT; + return -ETIMEDOUT; } } /* @@ -410,13 +410,13 @@ static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, mmc_stat = readl(&mmc_base->stat); if (get_timer(0) - start > MAX_RETRY_MS) { printf("%s : timeout: No status update\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } } while (!mmc_stat); if ((mmc_stat & IE_CTO) != 0) { mmc_reset_controller_fsm(mmc_base, SYSCTL_SRC); - return TIMEOUT; + return -ETIMEDOUT; } else if ((mmc_stat & ERRI_MASK) != 0) return -1; @@ -464,7 +464,7 @@ static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size) if (get_timer(0) - start > MAX_RETRY_MS) { printf("%s: timedout waiting for status!\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } } while (mmc_stat == 0); @@ -519,7 +519,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, if (get_timer(0) - start > MAX_RETRY_MS) { printf("%s: timedout waiting for status!\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } } while (mmc_stat == 0); diff --git a/drivers/mmc/s3c_sdi.c b/drivers/mmc/s3c_sdi.c index 02d1138..1b8358a 100644 --- a/drivers/mmc/s3c_sdi.c +++ b/drivers/mmc/s3c_sdi.c @@ -133,7 +133,7 @@ s3cmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) if (!timeout) { puts("S3C SDI: Command timed out!\n"); - ret = TIMEOUT; + ret = -ETIMEDOUT; goto error; } @@ -196,7 +196,7 @@ s3cmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) if (!timeout) { puts("S3C SDI: Command timed out!\n"); - ret = TIMEOUT; + ret = -ETIMEDOUT; goto error; } diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index d584b0b..1d6d2fd 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -170,7 +170,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, cmd_timeout); } else { puts("timeout.\n"); - return COMM_ERR; + return -ECOMM; } } time++; @@ -260,7 +260,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, } else { printf("%s: Timeout for status update!\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } } } while ((stat & mask) != mask); @@ -289,9 +289,9 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, sdhci_reset(host, SDHCI_RESET_CMD); sdhci_reset(host, SDHCI_RESET_DATA); if (stat & SDHCI_INT_TIMEOUT) - return TIMEOUT; + return -ETIMEDOUT; else - return COMM_ERR; + return -ECOMM; } static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 001bf18..bc4b344 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -168,7 +168,7 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host) if (state2 & STS2_CRC_ERR) ret = -EILSEQ; else if (state2 & STS2_TIMEOUT_ERR) - ret = TIMEOUT; + ret = -ETIMEDOUT; else ret = -EILSEQ; return ret; @@ -483,7 +483,7 @@ static int sh_mmcif_start_cmd(struct sh_mmcif_host *host, case MMC_CMD_ALL_SEND_CID: case MMC_CMD_SELECT_CARD: case MMC_CMD_APP_CMD: - ret = TIMEOUT; + ret = -ETIMEDOUT; break; default: printf(DRIVER_NAME": Cmd(d'%d) err\n", cmd->cmdidx); @@ -520,14 +520,14 @@ static int sh_mmcif_request(struct mmc *mmc, struct mmc_cmd *cmd, switch (cmd->cmdidx) { case MMC_CMD_APP_CMD: - return TIMEOUT; + return -ETIMEDOUT; case MMC_CMD_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */ if (data) /* ext_csd */ break; else /* send_if_cond cmd (not support) */ - return TIMEOUT; + return -ETIMEDOUT; default: break; } diff --git a/drivers/mmc/sh_sdhi.c b/drivers/mmc/sh_sdhi.c index 30e538c..be6aeb1 100644 --- a/drivers/mmc/sh_sdhi.c +++ b/drivers/mmc/sh_sdhi.c @@ -232,7 +232,7 @@ static int sh_sdhi_error_manage(struct sh_sdhi_host *host) e_state2 = sh_sdhi_readw(host, SDHI_ERR_STS2); if (e_state2 & ERR_STS2_SYS_ERROR) { if (e_state2 & ERR_STS2_RES_STOP_TIMEOUT) - ret = TIMEOUT; + ret = -ETIMEDOUT; else ret = -EILSEQ; debug("%s: ERR_STS2 = %04x\n", @@ -246,7 +246,7 @@ static int sh_sdhi_error_manage(struct sh_sdhi_host *host) if (e_state1 & ERR_STS1_CRC_ERROR || e_state1 & ERR_STS1_CMD_ERROR) ret = -EILSEQ; else - ret = TIMEOUT; + ret = -ETIMEDOUT; debug("%s: ERR_STS1 = %04x\n", DRIVER_NAME, sh_sdhi_readw(host, SDHI_ERR_STS1)); @@ -566,7 +566,7 @@ static int sh_sdhi_start_cmd(struct sh_sdhi_host *host, case MMC_CMD_SELECT_CARD: case SD_CMD_SEND_IF_COND: case MMC_CMD_APP_CMD: - ret = TIMEOUT; + ret = -ETIMEDOUT; break; default: debug(DRIVER_NAME": Cmd(d'%d) err\n", opc); diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 5d8abdc..6953acc 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -304,7 +304,7 @@ static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, (status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT)) { debug("%s timeout %x\n", what, status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT); - return TIMEOUT; + return -ETIMEDOUT; } udelay(1000); } while (!(status & done_bit)); @@ -375,7 +375,7 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, if (ret) { error = readl(&mmchost->reg->rint) & \ SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT; - error = TIMEOUT; + error = -ETIMEDOUT; goto out; } } @@ -402,7 +402,7 @@ static int sunxi_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, status = readl(&mmchost->reg->status); if (!timeout_msecs--) { debug("busy timeout\n"); - error = TIMEOUT; + error = -ETIMEDOUT; goto out; } udelay(1000); diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index c9d9432..023ba3c 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #ifndef CONFIG_TEGRA186 @@ -216,14 +217,14 @@ static int mmc_send_cmd_bounced(struct mmc *mmc, struct mmc_cmd *cmd, if (i == retry) { printf("%s: waiting for status update\n", __func__); writel(mask, &host->reg->norintsts); - return TIMEOUT; + return -ETIMEDOUT; } if (mask & TEGRA_MMC_NORINTSTS_CMD_TIMEOUT) { /* Timeout Error */ debug("timeout: %08x cmd %d\n", mask, cmd->cmdidx); writel(mask, &host->reg->norintsts); - return TIMEOUT; + return -ETIMEDOUT; } else if (mask & TEGRA_MMC_NORINTSTS_ERR_INTERRUPT) { /* Error Interrupt */ debug("error: %08x cmd %d\n", mask, cmd->cmdidx); @@ -257,7 +258,7 @@ static int mmc_send_cmd_bounced(struct mmc *mmc, struct mmc_cmd *cmd, if (i == retry) { printf("%s: card is still busy\n", __func__); writel(mask, &host->reg->norintsts); - return TIMEOUT; + return -ETIMEDOUT; } cmd->response[0] = readl(&host->reg->rspreg0); diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c index 02df809..2a48378 100644 --- a/drivers/mmc/uniphier-sd.c +++ b/drivers/mmc/uniphier-sd.c @@ -162,7 +162,7 @@ static int uniphier_sd_check_error(struct uniphier_sd_priv *priv) * display error log since this might be a part of sequence to * distinguish between SD and MMC. */ - return TIMEOUT; + return -ETIMEDOUT; } if (info2 & UNIPHIER_SD_INFO2_ERR_TO) { diff --git a/include/mmc.h b/include/mmc.h index dd47f34..aa6d5d1 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -66,12 +66,6 @@ #define MMC_DATA_READ 1 #define MMC_DATA_WRITE 2 -#define NO_CARD_ERR -16 /* No SD/MMC card inserted */ -#define UNUSABLE_ERR -17 /* Unusable Card */ -#define COMM_ERR -18 /* Communications Error */ -#define TIMEOUT -19 -#define SWITCH_ERR -20 /* Card reports failure to switch mode */ - #define MMC_CMD_GO_IDLE_STATE 0 #define MMC_CMD_SEND_OP_COND 1 #define MMC_CMD_ALL_SEND_CID 2 -- cgit v1.1 From 1bd4f92cdbc5f120c962611dfaf11ed01829d7cb Mon Sep 17 00:00:00 2001 From: Xu Ziyuan Date: Sat, 23 Jul 2016 11:11:22 +0800 Subject: mmc: display mmc list information like mmc_legacy type It's nicer to see this: => mmc list dwmmc@ff0c0000: 0 dwmmc@ff0f0000: 1 (eMMC) than this: => mmc list dwmmc@ff0c0000: 0dwmmc@ff0f0000: 1 (eMMC) With the former, it's much clearer which mmc devices are on. Signed-off-by: Ziyuan Xu Acked-by: Simon Glass Reviewed-by: Jaehoon Chung Tested-by: Jaehoon Chung Signed-off-by: Jaehoon Chung --- drivers/mmc/mmc-uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index f262c6e..425abb1 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -169,7 +169,7 @@ void print_mmc_devices(char separator) for (uclass_first_device(UCLASS_MMC, &dev); dev; - uclass_next_device(&dev)) { + uclass_next_device(&dev), first = false) { struct mmc *m = mmc_get_mmc_dev(dev); if (!first) { -- cgit v1.1 From e1ea7c44d67dde263c13e1aef300cab408236994 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Tue, 26 Jul 2016 19:03:49 +0900 Subject: mmc: sdhci: revert "mmc: sdhci: Claer high speed if not supported" This "commit 429790026021d522d51617217d4b86218cca5750" is wrong. SDHCI_QUIRK_NO_HISPD_BIT is for skipping to set CTRL_HISPD bit. For example, Exynos didn't have CTRL_HISPD. But Highspeed mode is supported. (This quirks doesn't mean that driver didn't support the Highseepd mode.) Note: If driver didn't support the Highspeed Mode, use or add the other quirks. After applied this patch, all Exynos SoCs are just running with 25MHz. Signed-off-by: Jaehoon Chung --- drivers/mmc/sdhci.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 1d6d2fd..4112223 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -554,9 +554,6 @@ int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth, cfg->host_caps |= MMC_MODE_8BIT; } - if (quirks & SDHCI_QUIRK_NO_HISPD_BIT) - cfg->host_caps &= ~(MMC_MODE_HS | MMC_MODE_HS_52MHz); - if (host_caps) cfg->host_caps |= host_caps; -- cgit v1.1 From 6a879ec8e7ac9905ad10b98e9cd585622c64b17c Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Tue, 26 Jul 2016 19:06:23 +0900 Subject: mmc: sdhci: remove the unused argument for sdhci_setup_cfg buswidth isn't used anywhere in sdhci_setup_cfg. Signed-off-by: Jaehoon Chung Reviewed-by: Minkyu Kang Reviewed-by: Simon Glass --- drivers/mmc/msm_sdhci.c | 4 ++-- drivers/mmc/sdhci.c | 4 ++-- drivers/mmc/zynq_sdhci.c | 2 +- include/sdhci.h | 3 +-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c index 70a8d96..e90a044 100644 --- a/drivers/mmc/msm_sdhci.c +++ b/drivers/mmc/msm_sdhci.c @@ -144,8 +144,8 @@ static int msm_sdc_probe(struct udevice *dev) host->version = sdhci_readw(host, SDHCI_HOST_VERSION); caps = sdhci_readl(host, SDHCI_CAPABILITIES); - ret = sdhci_setup_cfg(&plat->cfg, dev->name, host->bus_width, - caps, 0, 0, host->version, host->quirks, 0); + ret = sdhci_setup_cfg(&plat->cfg, dev->name, caps, + 0, 0, host->version, host->quirks, 0); host->mmc = &plat->mmc; if (ret) return ret; diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 4112223..c275314 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -511,7 +511,7 @@ static const struct mmc_ops sdhci_ops = { }; #endif -int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth, +int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, uint caps, u32 max_clk, u32 min_clk, uint version, uint quirks, uint host_caps) { @@ -582,7 +582,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) } #endif - if (sdhci_setup_cfg(&host->cfg, host->name, host->bus_width, caps, + if (sdhci_setup_cfg(&host->cfg, host->name, caps, max_clk, min_clk, SDHCI_GET_VERSION(host), host->quirks, host->host_caps)) { printf("%s: Hardware doesn't specify base clock frequency\n", diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index bcd154a..69d6151 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -40,7 +40,7 @@ static int arasan_sdhci_probe(struct udevice *dev) host->version = sdhci_readw(host, SDHCI_HOST_VERSION); caps = sdhci_readl(host, SDHCI_CAPABILITIES); - ret = sdhci_setup_cfg(&plat->cfg, dev->name, host->bus_width, + ret = sdhci_setup_cfg(&plat->cfg, dev->name, caps, CONFIG_ZYNQ_SDHCI_MAX_FREQ, CONFIG_ZYNQ_SDHCI_MIN_FREQ, host->version, host->quirks, 0); diff --git a/include/sdhci.h b/include/sdhci.h index c4d3b55..693ecc1 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -368,7 +368,6 @@ static inline u8 sdhci_readb(struct sdhci_host *host, int reg) * * @cfg: Configuration structure to fill in (generally &plat->mmc) * @name: Device name (normally dev->name) - * @buswidth: Bus width (in bits, such as 4 or 8) * @caps: Host capabilities (MMC_MODE_...) * @max_clk: Maximum supported clock speed in HZ (0 for default) * @min_clk: Minimum supported clock speed in HZ (0 for default) @@ -377,7 +376,7 @@ static inline u8 sdhci_readb(struct sdhci_host *host, int reg) * @quirks: Quick flags (SDHCI_QUIRK_...) * @host_caps: Additional host capabilities (0 if none) */ -int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth, +int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, uint caps, u32 max_clk, u32 min_clk, uint version, uint quirks, uint host_caps); -- cgit v1.1 From 14bed52d276afd36b9674ee7aa2c2ad9d2f4e59e Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Tue, 26 Jul 2016 19:06:24 +0900 Subject: mmc: sdhci: remove the unnecessary arguments for sdhci_setup_cfg Some arguments don't need to pass to sdhci_setup_cfg. Generic variable can be used in sdhci_setup_cfg, and some arguments are already included in sdhci_host struct. It's enough that just pass the board specific things to sdhci_setup_cfg(). After removing the unnecessary arguments, it's more simpler than before. It doesn't consider "Version" and "Capabilities" anymore in each SoC driver. Signed-off-by: Jaehoon Chung Reviewed-by: Simon Glass --- drivers/mmc/msm_sdhci.c | 4 +--- drivers/mmc/rockchip_sdhci.c | 8 ++------ drivers/mmc/sdhci.c | 26 ++++++++++++++------------ drivers/mmc/zynq_sdhci.c | 6 ++---- include/sdhci.h | 12 +++--------- 5 files changed, 22 insertions(+), 34 deletions(-) diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c index e90a044..a8cb9e2 100644 --- a/drivers/mmc/msm_sdhci.c +++ b/drivers/mmc/msm_sdhci.c @@ -143,9 +143,7 @@ static int msm_sdc_probe(struct udevice *dev) /* Set host controller version */ host->version = sdhci_readw(host, SDHCI_HOST_VERSION); - caps = sdhci_readl(host, SDHCI_CAPABILITIES); - ret = sdhci_setup_cfg(&plat->cfg, dev->name, caps, - 0, 0, host->version, host->quirks, 0); + ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0); host->mmc = &plat->mmc; if (ret) return ret; diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c index 023c29b..624029b 100644 --- a/drivers/mmc/rockchip_sdhci.c +++ b/drivers/mmc/rockchip_sdhci.c @@ -33,15 +33,11 @@ static int arasan_sdhci_probe(struct udevice *dev) struct rockchip_sdhc *prv = dev_get_priv(dev); struct sdhci_host *host = &prv->host; int ret; - u32 caps; - host->version = sdhci_readw(host, SDHCI_HOST_VERSION); host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD; - caps = sdhci_readl(host, SDHCI_CAPABILITIES); - ret = sdhci_setup_cfg(&plat->cfg, dev->name, host->bus_width, - caps, CONFIG_ROCKCHIP_SDHCI_MAX_FREQ, EMMC_MIN_FREQ, - host->version, host->quirks, 0); + ret = sdhci_setup_cfg(&plat->cfg, host, CONFIG_ROCKCHIP_SDHCI_MAX_FREQ, + EMMC_MIN_FREQ); host->mmc = &plat->mmc; if (ret) diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index c275314..60108fd 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -511,18 +511,22 @@ static const struct mmc_ops sdhci_ops = { }; #endif -int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, - uint caps, u32 max_clk, u32 min_clk, uint version, - uint quirks, uint host_caps) +int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host, + u32 max_clk, u32 min_clk) { - cfg->name = name; + u32 caps; + + caps = sdhci_readl(host, SDHCI_CAPABILITIES); + host->version = sdhci_readw(host, SDHCI_HOST_VERSION); + + cfg->name = host->name; #ifndef CONFIG_DM_MMC_OPS cfg->ops = &sdhci_ops; #endif if (max_clk) cfg->f_max = max_clk; else { - if (version >= SDHCI_SPEC_300) + if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) cfg->f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; else @@ -535,7 +539,7 @@ int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, if (min_clk) cfg->f_min = min_clk; else { - if (version >= SDHCI_SPEC_300) + if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) cfg->f_min = cfg->f_max / SDHCI_MAX_DIV_SPEC_300; else cfg->f_min = cfg->f_max / SDHCI_MAX_DIV_SPEC_200; @@ -549,13 +553,13 @@ int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, cfg->voltages |= MMC_VDD_165_195; cfg->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT; - if (version >= SDHCI_SPEC_300) { + if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { if (caps & SDHCI_CAN_DO_8BIT) cfg->host_caps |= MMC_MODE_8BIT; } - if (host_caps) - cfg->host_caps |= host_caps; + if (host->host_caps) + cfg->host_caps |= host->host_caps; cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; @@ -582,9 +586,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) } #endif - if (sdhci_setup_cfg(&host->cfg, host->name, caps, - max_clk, min_clk, SDHCI_GET_VERSION(host), - host->quirks, host->host_caps)) { + if (sdhci_setup_cfg(&host->cfg, host, max_clk, min_clk)) { printf("%s: Hardware doesn't specify base clock frequency\n", __func__); return -EINVAL; diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index 69d6151..bf54219 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -40,10 +40,8 @@ static int arasan_sdhci_probe(struct udevice *dev) host->version = sdhci_readw(host, SDHCI_HOST_VERSION); caps = sdhci_readl(host, SDHCI_CAPABILITIES); - ret = sdhci_setup_cfg(&plat->cfg, dev->name, - caps, CONFIG_ZYNQ_SDHCI_MAX_FREQ, - CONFIG_ZYNQ_SDHCI_MIN_FREQ, host->version, - host->quirks, 0); + ret = sdhci_setup_cfg(&plat->cfg, host, CONFIG_ZYNQ_SDHCI_MAX_FREQ, + CONFIG_ZYNQ_SDHCI_MIN_FREQ); host->mmc = &plat->mmc; if (ret) return ret; diff --git a/include/sdhci.h b/include/sdhci.h index 693ecc1..fcef4dc 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -367,18 +367,12 @@ static inline u8 sdhci_readb(struct sdhci_host *host, int reg) * See msm_sdhci.c for an example. * * @cfg: Configuration structure to fill in (generally &plat->mmc) - * @name: Device name (normally dev->name) - * @caps: Host capabilities (MMC_MODE_...) + * @host: SDHCI host structure * @max_clk: Maximum supported clock speed in HZ (0 for default) * @min_clk: Minimum supported clock speed in HZ (0 for default) - * @version: Host controller version (generally read from the - * SDHCI_HOST_VERSION register) - * @quirks: Quick flags (SDHCI_QUIRK_...) - * @host_caps: Additional host capabilities (0 if none) */ -int sdhci_setup_cfg(struct mmc_config *cfg, const char *name, - uint caps, u32 max_clk, u32 min_clk, uint version, - uint quirks, uint host_caps); +int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host, + u32 max_clk, u32 min_clk); /** * sdhci_bind() - Set up a new MMC block device -- cgit v1.1 From 2990e07a33159b1c23325c2c789cdb3f9ab4d89c Mon Sep 17 00:00:00 2001 From: Xu Ziyuan Date: Thu, 28 Jul 2016 10:25:47 +0800 Subject: mmc: dw_mmc: transfer proper bytes to FIFO The former implement, dw_mmc will push and pop the redundant data to FIFO, we should transfer it according to the real size. Signed-off-by: Ziyuan Xu Acked-by: Jaehoon Chung Reviewed-by: Simon Glass Reviewed-by: Shawn Lin Signed-off-by: Jaehoon Chung --- drivers/mmc/dw_mmc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index a6a5fc6..a0a582b 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -125,6 +125,7 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) len = dwmci_readl(host, DWMCI_STATUS); len = (len >> DWMCI_FIFO_SHIFT) & DWMCI_FIFO_MASK; + len = min(size, len); for (i = 0; i < len; i++) *buf++ = dwmci_readl(host, DWMCI_DATA); @@ -138,6 +139,7 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) len = fifo_depth - ((len >> DWMCI_FIFO_SHIFT) & DWMCI_FIFO_MASK); + len = min(size, len); for (i = 0; i < len; i++) dwmci_writel(host, DWMCI_DATA, *buf++); -- cgit v1.1 From 720724d09852858a3938f7bfcbbb3d1a0fdd6b4c Mon Sep 17 00:00:00 2001 From: Xu Ziyuan Date: Thu, 28 Jul 2016 10:25:48 +0800 Subject: mmc: dw_mmc: fix data starvation by host timeout under FIFO mode This patch fixes data starvation by host timeout(HTO) error interrupt which occurred under FIFO mode transfer on rk3036 board. The former implement, the actual bytes were transmitted may be less than should be. The size will still subtract value of len in case of there is no receive/transmit FIFO data request interrupt. Signed-off-by: Ziyuan Xu Acked-by: Jaehoon Chung Reviewed-by: Simon Glass Signed-off-by: Jaehoon Chung --- drivers/mmc/dw_mmc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index a0a582b..afc674d 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -119,6 +119,7 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) } if (host->fifo_mode && size) { + len = 0; if (data->flags == MMC_DATA_READ) { if ((dwmci_readl(host, DWMCI_RINTSTS) & DWMCI_INTMSK_RXDR)) { -- cgit v1.1 From 4587f53a582c9ab0bd908cff590755bfc03fced4 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Thu, 28 Jul 2016 14:26:24 +0900 Subject: mmc: dw_mmc: fix the wrong Mask bit boundary for fifo_count bit According to DesignWare TRM, FIFO_COUNT is bit[29:17]. If get the correct fifo_count value, it has to use the FIFO_MASK as 0x1FFF, not 0x1FF. Signed-off-by: Jaehoon Chung Reviewed-by: Ziyuan Xu --- include/dwmmc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dwmmc.h b/include/dwmmc.h index d18ec84..5b9602c 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -105,7 +105,7 @@ /* Status Register */ #define DWMCI_BUSY (1 << 9) -#define DWMCI_FIFO_MASK 0x1ff +#define DWMCI_FIFO_MASK 0x1fff #define DWMCI_FIFO_SHIFT 17 /* FIFOTH Register */ -- cgit v1.1 From 89f69e51734f5d704ef84503d24907bfde2f5577 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Fri, 5 Aug 2016 14:13:36 +0900 Subject: mmc: sdhci: fix the compiler warning when disable CONFIG_MMC_SDMA When disabled CONFIG_MMC_SDMA, variable caps didn't use. This patch fixes the compiler error for -Wunused-but-set-variable Signed-off-by: Jaehoon Chung --- drivers/mmc/sdhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 60108fd..7ddb549 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -575,10 +575,10 @@ int sdhci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg) #else int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) { +#ifdef CONFIG_MMC_SDMA unsigned int caps; caps = sdhci_readl(host, SDHCI_CAPABILITIES); -#ifdef CONFIG_MMC_SDMA if (!(caps & SDHCI_CAN_DO_SDMA)) { printf("%s: Your controller doesn't support SDMA!!\n", __func__); -- cgit v1.1