|
@@ -899,23 +899,35 @@ done:
|
|
mci_writel(host, FIFOTH, fifoth_val);
|
|
mci_writel(host, FIFOTH, fifoth_val);
|
|
}
|
|
}
|
|
|
|
|
|
-static void dw_mci_ctrl_rd_thld(struct dw_mci *host, struct mmc_data *data)
|
|
|
|
|
|
+static void dw_mci_ctrl_thld(struct dw_mci *host, struct mmc_data *data)
|
|
{
|
|
{
|
|
unsigned int blksz = data->blksz;
|
|
unsigned int blksz = data->blksz;
|
|
u32 blksz_depth, fifo_depth;
|
|
u32 blksz_depth, fifo_depth;
|
|
u16 thld_size;
|
|
u16 thld_size;
|
|
-
|
|
|
|
- WARN_ON(!(data->flags & MMC_DATA_READ));
|
|
|
|
|
|
+ u8 enable;
|
|
|
|
|
|
/*
|
|
/*
|
|
* CDTHRCTL doesn't exist prior to 240A (in fact that register offset is
|
|
* CDTHRCTL doesn't exist prior to 240A (in fact that register offset is
|
|
* in the FIFO region, so we really shouldn't access it).
|
|
* in the FIFO region, so we really shouldn't access it).
|
|
*/
|
|
*/
|
|
- if (host->verid < DW_MMC_240A)
|
|
|
|
|
|
+ if (host->verid < DW_MMC_240A ||
|
|
|
|
+ (host->verid < DW_MMC_280A && data->flags & MMC_DATA_WRITE))
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Card write Threshold is introduced since 2.80a
|
|
|
|
+ * It's used when HS400 mode is enabled.
|
|
|
|
+ */
|
|
|
|
+ if (data->flags & MMC_DATA_WRITE &&
|
|
|
|
+ !(host->timing != MMC_TIMING_MMC_HS400))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ if (data->flags & MMC_DATA_WRITE)
|
|
|
|
+ enable = SDMMC_CARD_WR_THR_EN;
|
|
|
|
+ else
|
|
|
|
+ enable = SDMMC_CARD_RD_THR_EN;
|
|
|
|
+
|
|
if (host->timing != MMC_TIMING_MMC_HS200 &&
|
|
if (host->timing != MMC_TIMING_MMC_HS200 &&
|
|
- host->timing != MMC_TIMING_MMC_HS400 &&
|
|
|
|
host->timing != MMC_TIMING_UHS_SDR104)
|
|
host->timing != MMC_TIMING_UHS_SDR104)
|
|
goto disable;
|
|
goto disable;
|
|
|
|
|
|
@@ -931,11 +943,11 @@ static void dw_mci_ctrl_rd_thld(struct dw_mci *host, struct mmc_data *data)
|
|
* Currently just choose blksz.
|
|
* Currently just choose blksz.
|
|
*/
|
|
*/
|
|
thld_size = blksz;
|
|
thld_size = blksz;
|
|
- mci_writel(host, CDTHRCTL, SDMMC_SET_RD_THLD(thld_size, 1));
|
|
|
|
|
|
+ mci_writel(host, CDTHRCTL, SDMMC_SET_THLD(thld_size, enable));
|
|
return;
|
|
return;
|
|
|
|
|
|
disable:
|
|
disable:
|
|
- mci_writel(host, CDTHRCTL, SDMMC_SET_RD_THLD(0, 0));
|
|
|
|
|
|
+ mci_writel(host, CDTHRCTL, 0);
|
|
}
|
|
}
|
|
|
|
|
|
static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
|
|
static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
|
|
@@ -1006,12 +1018,12 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
|
|
host->sg = NULL;
|
|
host->sg = NULL;
|
|
host->data = data;
|
|
host->data = data;
|
|
|
|
|
|
- if (data->flags & MMC_DATA_READ) {
|
|
|
|
|
|
+ if (data->flags & MMC_DATA_READ)
|
|
host->dir_status = DW_MCI_RECV_STATUS;
|
|
host->dir_status = DW_MCI_RECV_STATUS;
|
|
- dw_mci_ctrl_rd_thld(host, data);
|
|
|
|
- } else {
|
|
|
|
|
|
+ else
|
|
host->dir_status = DW_MCI_SEND_STATUS;
|
|
host->dir_status = DW_MCI_SEND_STATUS;
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ dw_mci_ctrl_thld(host, data);
|
|
|
|
|
|
if (dw_mci_submit_data_dma(host, data)) {
|
|
if (dw_mci_submit_data_dma(host, data)) {
|
|
if (host->data->flags & MMC_DATA_READ)
|
|
if (host->data->flags & MMC_DATA_READ)
|