Skip to content

Commit b5c3eb3

Browse files
Yann-lmsUlf Hansson
authored andcommitted
mmc: mmci: stm32: add delay block support for STM32MP25
On STM32MP25, the delay block is inside the SoC, and configured through the SYSCFG registers. The algorithm is also different from what was in STM32MP1 chip. Signed-off-by: Yann Gautier <yann.gautier@foss.st.com> Link: https://lore.kernel.org/r/20230619115120.64474-7-yann.gautier@foss.st.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent 83efc78 commit b5c3eb3

1 file changed

Lines changed: 65 additions & 1 deletion

File tree

drivers/mmc/host/mmci_stm32_sdmmc.c

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@
3333
#define DLYB_LNG_TIMEOUT_US 1000
3434
#define SDMMC_VSWEND_TIMEOUT_US 10000
3535

36+
#define SYSCFG_DLYBSD_CR 0x0
37+
#define DLYBSD_CR_EN BIT(0)
38+
#define DLYBSD_CR_RXTAPSEL_MASK GENMASK(6, 1)
39+
#define DLYBSD_TAPSEL_NB 32
40+
#define DLYBSD_BYP_EN BIT(16)
41+
#define DLYBSD_BYP_CMD GENMASK(21, 17)
42+
#define DLYBSD_ANTIGLITCH_EN BIT(22)
43+
44+
#define SYSCFG_DLYBSD_SR 0x4
45+
#define DLYBSD_SR_LOCK BIT(0)
46+
#define DLYBSD_SR_RXTAPSEL_ACK BIT(1)
47+
48+
#define DLYBSD_TIMEOUT_1S_IN_US 1000000
49+
3650
struct sdmmc_lli_desc {
3751
u32 idmalar;
3852
u32 idmabase;
@@ -495,6 +509,46 @@ static int sdmmc_dlyb_mp15_prepare(struct mmci_host *host)
495509
return 0;
496510
}
497511

512+
static int sdmmc_dlyb_mp25_enable(struct sdmmc_dlyb *dlyb)
513+
{
514+
u32 cr, sr;
515+
516+
cr = readl_relaxed(dlyb->base + SYSCFG_DLYBSD_CR);
517+
cr |= DLYBSD_CR_EN;
518+
519+
writel_relaxed(cr, dlyb->base + SYSCFG_DLYBSD_CR);
520+
521+
return readl_relaxed_poll_timeout(dlyb->base + SYSCFG_DLYBSD_SR,
522+
sr, sr & DLYBSD_SR_LOCK, 1,
523+
DLYBSD_TIMEOUT_1S_IN_US);
524+
}
525+
526+
static int sdmmc_dlyb_mp25_set_cfg(struct sdmmc_dlyb *dlyb,
527+
int unit __maybe_unused, int phase,
528+
bool sampler __maybe_unused)
529+
{
530+
u32 cr, sr;
531+
532+
cr = readl_relaxed(dlyb->base + SYSCFG_DLYBSD_CR);
533+
cr &= ~DLYBSD_CR_RXTAPSEL_MASK;
534+
cr |= FIELD_PREP(DLYBSD_CR_RXTAPSEL_MASK, phase);
535+
536+
writel_relaxed(cr, dlyb->base + SYSCFG_DLYBSD_CR);
537+
538+
return readl_relaxed_poll_timeout(dlyb->base + SYSCFG_DLYBSD_SR,
539+
sr, sr & DLYBSD_SR_RXTAPSEL_ACK, 1,
540+
DLYBSD_TIMEOUT_1S_IN_US);
541+
}
542+
543+
static int sdmmc_dlyb_mp25_prepare(struct mmci_host *host)
544+
{
545+
struct sdmmc_dlyb *dlyb = host->variant_priv;
546+
547+
dlyb->max = DLYBSD_TAPSEL_NB;
548+
549+
return 0;
550+
}
551+
498552
static int sdmmc_dlyb_phase_tuning(struct mmci_host *host, u32 opcode)
499553
{
500554
struct sdmmc_dlyb *dlyb = host->variant_priv;
@@ -635,6 +689,12 @@ static struct sdmmc_tuning_ops dlyb_tuning_mp15_ops = {
635689
.set_cfg = sdmmc_dlyb_mp15_set_cfg,
636690
};
637691

692+
static struct sdmmc_tuning_ops dlyb_tuning_mp25_ops = {
693+
.dlyb_enable = sdmmc_dlyb_mp25_enable,
694+
.tuning_prepare = sdmmc_dlyb_mp25_prepare,
695+
.set_cfg = sdmmc_dlyb_mp25_set_cfg,
696+
};
697+
638698
void sdmmc_variant_init(struct mmci_host *host)
639699
{
640700
struct device_node *np = host->mmc->parent->of_node;
@@ -653,7 +713,11 @@ void sdmmc_variant_init(struct mmci_host *host)
653713
return;
654714

655715
dlyb->base = base_dlyb;
656-
dlyb->ops = &dlyb_tuning_mp15_ops;
716+
if (of_device_is_compatible(np, "st,stm32mp25-sdmmc2"))
717+
dlyb->ops = &dlyb_tuning_mp25_ops;
718+
else
719+
dlyb->ops = &dlyb_tuning_mp15_ops;
720+
657721
host->variant_priv = dlyb;
658722
host->mmc_ops->execute_tuning = sdmmc_execute_tuning;
659723
}

0 commit comments

Comments
 (0)