Skip to content

Commit 371e4a1

Browse files
committed
Merge tag 'mmc-v6.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC fixes from Ulf Hansson: "MMC core: - Fix eMMC initialization with 1-bit bus connection MMC host: - mmci: Fix DMA API overlapping mappings for the stm32 variant - sdhci-xenon: Fix PHY stability issues" * tag 'mmc-v6.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: mmc: sdhci-xenon: add timeout for PHY init complete mmc: sdhci-xenon: fix PHY init clock stability mmc: mmci: stm32: fix DMA API overlapping mappings warning mmc: core: Fix eMMC initialization with 1-bit bus connection
2 parents fafbad4 + 09e2382 commit 371e4a1

3 files changed

Lines changed: 65 additions & 9 deletions

File tree

drivers/mmc/core/mmc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,10 +1015,12 @@ static int mmc_select_bus_width(struct mmc_card *card)
10151015
static unsigned ext_csd_bits[] = {
10161016
EXT_CSD_BUS_WIDTH_8,
10171017
EXT_CSD_BUS_WIDTH_4,
1018+
EXT_CSD_BUS_WIDTH_1,
10181019
};
10191020
static unsigned bus_widths[] = {
10201021
MMC_BUS_WIDTH_8,
10211022
MMC_BUS_WIDTH_4,
1023+
MMC_BUS_WIDTH_1,
10221024
};
10231025
struct mmc_host *host = card->host;
10241026
unsigned idx, bus_width = 0;

drivers/mmc/host/mmci_stm32_sdmmc.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ static int sdmmc_idma_start(struct mmci_host *host, unsigned int *datactrl)
225225
struct scatterlist *sg;
226226
int i;
227227

228+
host->dma_in_progress = true;
229+
228230
if (!host->variant->dma_lli || data->sg_len == 1 ||
229231
idma->use_bounce_buffer) {
230232
u32 dma_addr;
@@ -263,9 +265,30 @@ static int sdmmc_idma_start(struct mmci_host *host, unsigned int *datactrl)
263265
return 0;
264266
}
265267

268+
static void sdmmc_idma_error(struct mmci_host *host)
269+
{
270+
struct mmc_data *data = host->data;
271+
struct sdmmc_idma *idma = host->dma_priv;
272+
273+
if (!dma_inprogress(host))
274+
return;
275+
276+
writel_relaxed(0, host->base + MMCI_STM32_IDMACTRLR);
277+
host->dma_in_progress = false;
278+
data->host_cookie = 0;
279+
280+
if (!idma->use_bounce_buffer)
281+
dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
282+
mmc_get_dma_dir(data));
283+
}
284+
266285
static void sdmmc_idma_finalize(struct mmci_host *host, struct mmc_data *data)
267286
{
287+
if (!dma_inprogress(host))
288+
return;
289+
268290
writel_relaxed(0, host->base + MMCI_STM32_IDMACTRLR);
291+
host->dma_in_progress = false;
269292

270293
if (!data->host_cookie)
271294
sdmmc_idma_unprep_data(host, data, 0);
@@ -676,6 +699,7 @@ static struct mmci_host_ops sdmmc_variant_ops = {
676699
.dma_setup = sdmmc_idma_setup,
677700
.dma_start = sdmmc_idma_start,
678701
.dma_finalize = sdmmc_idma_finalize,
702+
.dma_error = sdmmc_idma_error,
679703
.set_clkreg = mmci_sdmmc_set_clkreg,
680704
.set_pwrreg = mmci_sdmmc_set_pwrreg,
681705
.busy_complete = sdmmc_busy_complete,

drivers/mmc/host/sdhci-xenon-phy.c

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/slab.h>
1212
#include <linux/delay.h>
1313
#include <linux/ktime.h>
14+
#include <linux/iopoll.h>
1415
#include <linux/of_address.h>
1516

1617
#include "sdhci-pltfm.h"
@@ -109,6 +110,8 @@
109110
#define XENON_EMMC_PHY_LOGIC_TIMING_ADJUST (XENON_EMMC_PHY_REG_BASE + 0x18)
110111
#define XENON_LOGIC_TIMING_VALUE 0x00AA8977
111112

113+
#define XENON_MAX_PHY_TIMEOUT_LOOPS 100
114+
112115
/*
113116
* List offset of PHY registers and some special register values
114117
* in eMMC PHY 5.0 or eMMC PHY 5.1
@@ -216,6 +219,19 @@ static int xenon_alloc_emmc_phy(struct sdhci_host *host)
216219
return 0;
217220
}
218221

222+
static int xenon_check_stability_internal_clk(struct sdhci_host *host)
223+
{
224+
u32 reg;
225+
int err;
226+
227+
err = read_poll_timeout(sdhci_readw, reg, reg & SDHCI_CLOCK_INT_STABLE,
228+
1100, 20000, false, host, SDHCI_CLOCK_CONTROL);
229+
if (err)
230+
dev_err(mmc_dev(host->mmc), "phy_init: Internal clock never stabilized.\n");
231+
232+
return err;
233+
}
234+
219235
/*
220236
* eMMC 5.0/5.1 PHY init/re-init.
221237
* eMMC PHY init should be executed after:
@@ -232,6 +248,11 @@ static int xenon_emmc_phy_init(struct sdhci_host *host)
232248
struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
233249
struct xenon_emmc_phy_regs *phy_regs = priv->emmc_phy_regs;
234250

251+
int ret = xenon_check_stability_internal_clk(host);
252+
253+
if (ret)
254+
return ret;
255+
235256
reg = sdhci_readl(host, phy_regs->timing_adj);
236257
reg |= XENON_PHY_INITIALIZAION;
237258
sdhci_writel(host, reg, phy_regs->timing_adj);
@@ -259,18 +280,27 @@ static int xenon_emmc_phy_init(struct sdhci_host *host)
259280
/* get the wait time */
260281
wait /= clock;
261282
wait++;
262-
/* wait for host eMMC PHY init completes */
263-
udelay(wait);
264283

265-
reg = sdhci_readl(host, phy_regs->timing_adj);
266-
reg &= XENON_PHY_INITIALIZAION;
267-
if (reg) {
284+
/*
285+
* AC5X spec says bit must be polled until zero.
286+
* We see cases in which timeout can take longer
287+
* than the standard calculation on AC5X, which is
288+
* expected following the spec comment above.
289+
* According to the spec, we must wait as long as
290+
* it takes for that bit to toggle on AC5X.
291+
* Cap that with 100 delay loops so we won't get
292+
* stuck here forever:
293+
*/
294+
295+
ret = read_poll_timeout(sdhci_readl, reg,
296+
!(reg & XENON_PHY_INITIALIZAION),
297+
wait, XENON_MAX_PHY_TIMEOUT_LOOPS * wait,
298+
false, host, phy_regs->timing_adj);
299+
if (ret)
268300
dev_err(mmc_dev(host->mmc), "eMMC PHY init cannot complete after %d us\n",
269-
wait);
270-
return -ETIMEDOUT;
271-
}
301+
wait * XENON_MAX_PHY_TIMEOUT_LOOPS);
272302

273-
return 0;
303+
return ret;
274304
}
275305

276306
#define ARMADA_3700_SOC_PAD_1_8V 0x1

0 commit comments

Comments
 (0)