750 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) STMicroelectronics 2018 - All Rights Reserved4 * Author: Ludovic.barre@st.com for STMicroelectronics.5 */6#include <linux/bitfield.h>7#include <linux/delay.h>8#include <linux/dma-mapping.h>9#include <linux/iopoll.h>10#include <linux/mmc/host.h>11#include <linux/mmc/card.h>12#include <linux/of_address.h>13#include <linux/reset.h>14#include <linux/scatterlist.h>15#include "mmci.h"16 17#define SDMMC_LLI_BUF_LEN PAGE_SIZE18 19#define DLYB_CR 0x020#define DLYB_CR_DEN BIT(0)21#define DLYB_CR_SEN BIT(1)22 23#define DLYB_CFGR 0x424#define DLYB_CFGR_SEL_MASK GENMASK(3, 0)25#define DLYB_CFGR_UNIT_MASK GENMASK(14, 8)26#define DLYB_CFGR_LNG_MASK GENMASK(27, 16)27#define DLYB_CFGR_LNGF BIT(31)28 29#define DLYB_NB_DELAY 1130#define DLYB_CFGR_SEL_MAX (DLYB_NB_DELAY + 1)31#define DLYB_CFGR_UNIT_MAX 12732 33#define DLYB_LNG_TIMEOUT_US 100034#define SDMMC_VSWEND_TIMEOUT_US 1000035 36#define SYSCFG_DLYBSD_CR 0x037#define DLYBSD_CR_EN BIT(0)38#define DLYBSD_CR_RXTAPSEL_MASK GENMASK(6, 1)39#define DLYBSD_TAPSEL_NB 3240#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 0x445#define DLYBSD_SR_LOCK BIT(0)46#define DLYBSD_SR_RXTAPSEL_ACK BIT(1)47 48#define DLYBSD_TIMEOUT_1S_IN_US 100000049 50struct sdmmc_lli_desc {51 u32 idmalar;52 u32 idmabase;53 u32 idmasize;54};55 56struct sdmmc_idma {57 dma_addr_t sg_dma;58 void *sg_cpu;59 dma_addr_t bounce_dma_addr;60 void *bounce_buf;61 bool use_bounce_buffer;62};63 64struct sdmmc_dlyb;65 66struct sdmmc_tuning_ops {67 int (*dlyb_enable)(struct sdmmc_dlyb *dlyb);68 void (*set_input_ck)(struct sdmmc_dlyb *dlyb);69 int (*tuning_prepare)(struct mmci_host *host);70 int (*set_cfg)(struct sdmmc_dlyb *dlyb, int unit __maybe_unused,71 int phase, bool sampler __maybe_unused);72};73 74struct sdmmc_dlyb {75 void __iomem *base;76 u32 unit;77 u32 max;78 struct sdmmc_tuning_ops *ops;79};80 81static int sdmmc_idma_validate_data(struct mmci_host *host,82 struct mmc_data *data)83{84 struct sdmmc_idma *idma = host->dma_priv;85 struct device *dev = mmc_dev(host->mmc);86 struct scatterlist *sg;87 int i;88 89 /*90 * idma has constraints on idmabase & idmasize for each element91 * excepted the last element which has no constraint on idmasize92 */93 idma->use_bounce_buffer = false;94 for_each_sg(data->sg, sg, data->sg_len - 1, i) {95 if (!IS_ALIGNED(sg->offset, sizeof(u32)) ||96 !IS_ALIGNED(sg->length,97 host->variant->stm32_idmabsize_align)) {98 dev_dbg(mmc_dev(host->mmc),99 "unaligned scatterlist: ofst:%x length:%d\n",100 data->sg->offset, data->sg->length);101 goto use_bounce_buffer;102 }103 }104 105 if (!IS_ALIGNED(sg->offset, sizeof(u32))) {106 dev_dbg(mmc_dev(host->mmc),107 "unaligned last scatterlist: ofst:%x length:%d\n",108 data->sg->offset, data->sg->length);109 goto use_bounce_buffer;110 }111 112 return 0;113 114use_bounce_buffer:115 if (!idma->bounce_buf) {116 idma->bounce_buf = dmam_alloc_coherent(dev,117 host->mmc->max_req_size,118 &idma->bounce_dma_addr,119 GFP_KERNEL);120 if (!idma->bounce_buf) {121 dev_err(dev, "Unable to map allocate DMA bounce buffer.\n");122 return -ENOMEM;123 }124 }125 126 idma->use_bounce_buffer = true;127 128 return 0;129}130 131static int _sdmmc_idma_prep_data(struct mmci_host *host,132 struct mmc_data *data)133{134 struct sdmmc_idma *idma = host->dma_priv;135 136 if (idma->use_bounce_buffer) {137 if (data->flags & MMC_DATA_WRITE) {138 unsigned int xfer_bytes = data->blksz * data->blocks;139 140 sg_copy_to_buffer(data->sg, data->sg_len,141 idma->bounce_buf, xfer_bytes);142 dma_wmb();143 }144 } else {145 int n_elem;146 147 n_elem = dma_map_sg(mmc_dev(host->mmc),148 data->sg,149 data->sg_len,150 mmc_get_dma_dir(data));151 152 if (!n_elem) {153 dev_err(mmc_dev(host->mmc), "dma_map_sg failed\n");154 return -EINVAL;155 }156 }157 return 0;158}159 160static int sdmmc_idma_prep_data(struct mmci_host *host,161 struct mmc_data *data, bool next)162{163 /* Check if job is already prepared. */164 if (!next && data->host_cookie == host->next_cookie)165 return 0;166 167 return _sdmmc_idma_prep_data(host, data);168}169 170static void sdmmc_idma_unprep_data(struct mmci_host *host,171 struct mmc_data *data, int err)172{173 struct sdmmc_idma *idma = host->dma_priv;174 175 if (idma->use_bounce_buffer) {176 if (data->flags & MMC_DATA_READ) {177 unsigned int xfer_bytes = data->blksz * data->blocks;178 179 sg_copy_from_buffer(data->sg, data->sg_len,180 idma->bounce_buf, xfer_bytes);181 }182 } else {183 dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,184 mmc_get_dma_dir(data));185 }186}187 188static int sdmmc_idma_setup(struct mmci_host *host)189{190 struct sdmmc_idma *idma;191 struct device *dev = mmc_dev(host->mmc);192 193 idma = devm_kzalloc(dev, sizeof(*idma), GFP_KERNEL);194 if (!idma)195 return -ENOMEM;196 197 host->dma_priv = idma;198 199 if (host->variant->dma_lli) {200 idma->sg_cpu = dmam_alloc_coherent(dev, SDMMC_LLI_BUF_LEN,201 &idma->sg_dma, GFP_KERNEL);202 if (!idma->sg_cpu) {203 dev_err(dev, "Failed to alloc IDMA descriptor\n");204 return -ENOMEM;205 }206 host->mmc->max_segs = SDMMC_LLI_BUF_LEN /207 sizeof(struct sdmmc_lli_desc);208 host->mmc->max_seg_size = host->variant->stm32_idmabsize_mask;209 210 host->mmc->max_req_size = SZ_1M;211 } else {212 host->mmc->max_segs = 1;213 host->mmc->max_seg_size = host->mmc->max_req_size;214 }215 216 dma_set_max_seg_size(dev, host->mmc->max_seg_size);217 return 0;218}219 220static int sdmmc_idma_start(struct mmci_host *host, unsigned int *datactrl)221 222{223 struct sdmmc_idma *idma = host->dma_priv;224 struct sdmmc_lli_desc *desc = (struct sdmmc_lli_desc *)idma->sg_cpu;225 struct mmc_data *data = host->data;226 struct scatterlist *sg;227 int i;228 229 host->dma_in_progress = true;230 231 if (!host->variant->dma_lli || data->sg_len == 1 ||232 idma->use_bounce_buffer) {233 u32 dma_addr;234 235 if (idma->use_bounce_buffer)236 dma_addr = idma->bounce_dma_addr;237 else238 dma_addr = sg_dma_address(data->sg);239 240 writel_relaxed(dma_addr,241 host->base + MMCI_STM32_IDMABASE0R);242 writel_relaxed(MMCI_STM32_IDMAEN,243 host->base + MMCI_STM32_IDMACTRLR);244 return 0;245 }246 247 for_each_sg(data->sg, sg, data->sg_len, i) {248 desc[i].idmalar = (i + 1) * sizeof(struct sdmmc_lli_desc);249 desc[i].idmalar |= MMCI_STM32_ULA | MMCI_STM32_ULS250 | MMCI_STM32_ABR;251 desc[i].idmabase = sg_dma_address(sg);252 desc[i].idmasize = sg_dma_len(sg);253 }254 255 /* notice the end of link list */256 desc[data->sg_len - 1].idmalar &= ~MMCI_STM32_ULA;257 258 dma_wmb();259 writel_relaxed(idma->sg_dma, host->base + MMCI_STM32_IDMABAR);260 writel_relaxed(desc[0].idmalar, host->base + MMCI_STM32_IDMALAR);261 writel_relaxed(desc[0].idmabase, host->base + MMCI_STM32_IDMABASE0R);262 writel_relaxed(desc[0].idmasize, host->base + MMCI_STM32_IDMABSIZER);263 writel_relaxed(MMCI_STM32_IDMAEN | MMCI_STM32_IDMALLIEN,264 host->base + MMCI_STM32_IDMACTRLR);265 266 return 0;267}268 269static void sdmmc_idma_error(struct mmci_host *host)270{271 struct mmc_data *data = host->data;272 struct sdmmc_idma *idma = host->dma_priv;273 274 if (!dma_inprogress(host))275 return;276 277 writel_relaxed(0, host->base + MMCI_STM32_IDMACTRLR);278 host->dma_in_progress = false;279 data->host_cookie = 0;280 281 if (!idma->use_bounce_buffer)282 dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,283 mmc_get_dma_dir(data));284}285 286static void sdmmc_idma_finalize(struct mmci_host *host, struct mmc_data *data)287{288 if (!dma_inprogress(host))289 return;290 291 writel_relaxed(0, host->base + MMCI_STM32_IDMACTRLR);292 host->dma_in_progress = false;293 294 if (!data->host_cookie)295 sdmmc_idma_unprep_data(host, data, 0);296}297 298static void mmci_sdmmc_set_clkreg(struct mmci_host *host, unsigned int desired)299{300 unsigned int clk = 0, ddr = 0;301 302 if (host->mmc->ios.timing == MMC_TIMING_MMC_DDR52 ||303 host->mmc->ios.timing == MMC_TIMING_UHS_DDR50)304 ddr = MCI_STM32_CLK_DDR;305 306 /*307 * cclk = mclk / (2 * clkdiv)308 * clkdiv 0 => bypass309 * in ddr mode bypass is not possible310 */311 if (desired) {312 if (desired >= host->mclk && !ddr) {313 host->cclk = host->mclk;314 } else {315 clk = DIV_ROUND_UP(host->mclk, 2 * desired);316 if (clk > MCI_STM32_CLK_CLKDIV_MSK)317 clk = MCI_STM32_CLK_CLKDIV_MSK;318 host->cclk = host->mclk / (2 * clk);319 }320 } else {321 /*322 * while power-on phase the clock can't be define to 0,323 * Only power-off and power-cyc deactivate the clock.324 * if desired clock is 0, set max divider325 */326 clk = MCI_STM32_CLK_CLKDIV_MSK;327 host->cclk = host->mclk / (2 * clk);328 }329 330 /* Set actual clock for debug */331 if (host->mmc->ios.power_mode == MMC_POWER_ON)332 host->mmc->actual_clock = host->cclk;333 else334 host->mmc->actual_clock = 0;335 336 if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4)337 clk |= MCI_STM32_CLK_WIDEBUS_4;338 if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)339 clk |= MCI_STM32_CLK_WIDEBUS_8;340 341 clk |= MCI_STM32_CLK_HWFCEN;342 clk |= host->clk_reg_add;343 clk |= ddr;344 345 if (host->mmc->ios.timing >= MMC_TIMING_UHS_SDR50)346 clk |= MCI_STM32_CLK_BUSSPEED;347 348 mmci_write_clkreg(host, clk);349}350 351static void sdmmc_dlyb_mp15_input_ck(struct sdmmc_dlyb *dlyb)352{353 if (!dlyb || !dlyb->base)354 return;355 356 /* Output clock = Input clock */357 writel_relaxed(0, dlyb->base + DLYB_CR);358}359 360static void mmci_sdmmc_set_pwrreg(struct mmci_host *host, unsigned int pwr)361{362 struct mmc_ios ios = host->mmc->ios;363 struct sdmmc_dlyb *dlyb = host->variant_priv;364 365 /* adds OF options */366 pwr = host->pwr_reg_add;367 368 if (dlyb && dlyb->ops->set_input_ck)369 dlyb->ops->set_input_ck(dlyb);370 371 if (ios.power_mode == MMC_POWER_OFF) {372 /* Only a reset could power-off sdmmc */373 reset_control_assert(host->rst);374 udelay(2);375 reset_control_deassert(host->rst);376 377 /*378 * Set the SDMMC in Power-cycle state.379 * This will make that the SDMMC_D[7:0], SDMMC_CMD and SDMMC_CK380 * are driven low, to prevent the Card from being supplied381 * through the signal lines.382 */383 mmci_write_pwrreg(host, MCI_STM32_PWR_CYC | pwr);384 } else if (ios.power_mode == MMC_POWER_ON) {385 /*386 * After power-off (reset): the irq mask defined in probe387 * functionis lost388 * ault irq mask (probe) must be activated389 */390 writel(MCI_IRQENABLE | host->variant->start_err,391 host->base + MMCIMASK0);392 393 /* preserves voltage switch bits */394 pwr |= host->pwr_reg & (MCI_STM32_VSWITCHEN |395 MCI_STM32_VSWITCH);396 397 /*398 * After a power-cycle state, we must set the SDMMC in399 * Power-off. The SDMMC_D[7:0], SDMMC_CMD and SDMMC_CK are400 * driven high. Then we can set the SDMMC to Power-on state401 */402 mmci_write_pwrreg(host, MCI_PWR_OFF | pwr);403 mdelay(1);404 mmci_write_pwrreg(host, MCI_PWR_ON | pwr);405 }406}407 408static u32 sdmmc_get_dctrl_cfg(struct mmci_host *host)409{410 u32 datactrl;411 412 datactrl = mmci_dctrl_blksz(host);413 414 if (host->hw_revision >= 3) {415 u32 thr = 0;416 417 if (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104 ||418 host->mmc->ios.timing == MMC_TIMING_MMC_HS200) {419 thr = ffs(min_t(unsigned int, host->data->blksz,420 host->variant->fifosize));421 thr = min_t(u32, thr, MMCI_STM32_THR_MASK);422 }423 424 writel_relaxed(thr, host->base + MMCI_STM32_FIFOTHRR);425 }426 427 if (host->mmc->card && mmc_card_sdio(host->mmc->card) &&428 host->data->blocks == 1)429 datactrl |= MCI_DPSM_STM32_MODE_SDIO;430 else if (host->data->stop && !host->mrq->sbc)431 datactrl |= MCI_DPSM_STM32_MODE_BLOCK_STOP;432 else433 datactrl |= MCI_DPSM_STM32_MODE_BLOCK;434 435 return datactrl;436}437 438static bool sdmmc_busy_complete(struct mmci_host *host, struct mmc_command *cmd,439 u32 status, u32 err_msk)440{441 void __iomem *base = host->base;442 u32 busy_d0, busy_d0end, mask, sdmmc_status;443 444 mask = readl_relaxed(base + MMCIMASK0);445 sdmmc_status = readl_relaxed(base + MMCISTATUS);446 busy_d0end = sdmmc_status & MCI_STM32_BUSYD0END;447 busy_d0 = sdmmc_status & MCI_STM32_BUSYD0;448 449 /* complete if there is an error or busy_d0end */450 if ((status & err_msk) || busy_d0end)451 goto complete;452 453 /*454 * On response the busy signaling is reflected in the BUSYD0 flag.455 * if busy_d0 is in-progress we must activate busyd0end interrupt456 * to wait this completion. Else this request has no busy step.457 */458 if (busy_d0) {459 if (!host->busy_status) {460 writel_relaxed(mask | host->variant->busy_detect_mask,461 base + MMCIMASK0);462 host->busy_status = status &463 (MCI_CMDSENT | MCI_CMDRESPEND);464 }465 return false;466 }467 468complete:469 if (host->busy_status) {470 writel_relaxed(mask & ~host->variant->busy_detect_mask,471 base + MMCIMASK0);472 host->busy_status = 0;473 }474 475 writel_relaxed(host->variant->busy_detect_mask, base + MMCICLEAR);476 477 return true;478}479 480static int sdmmc_dlyb_mp15_enable(struct sdmmc_dlyb *dlyb)481{482 writel_relaxed(DLYB_CR_DEN, dlyb->base + DLYB_CR);483 484 return 0;485}486 487static int sdmmc_dlyb_mp15_set_cfg(struct sdmmc_dlyb *dlyb,488 int unit, int phase, bool sampler)489{490 u32 cfgr;491 492 writel_relaxed(DLYB_CR_SEN | DLYB_CR_DEN, dlyb->base + DLYB_CR);493 494 cfgr = FIELD_PREP(DLYB_CFGR_UNIT_MASK, unit) |495 FIELD_PREP(DLYB_CFGR_SEL_MASK, phase);496 writel_relaxed(cfgr, dlyb->base + DLYB_CFGR);497 498 if (!sampler)499 writel_relaxed(DLYB_CR_DEN, dlyb->base + DLYB_CR);500 501 return 0;502}503 504static int sdmmc_dlyb_mp15_prepare(struct mmci_host *host)505{506 struct sdmmc_dlyb *dlyb = host->variant_priv;507 u32 cfgr;508 int i, lng, ret;509 510 for (i = 0; i <= DLYB_CFGR_UNIT_MAX; i++) {511 dlyb->ops->set_cfg(dlyb, i, DLYB_CFGR_SEL_MAX, true);512 513 ret = readl_relaxed_poll_timeout(dlyb->base + DLYB_CFGR, cfgr,514 (cfgr & DLYB_CFGR_LNGF),515 1, DLYB_LNG_TIMEOUT_US);516 if (ret) {517 dev_warn(mmc_dev(host->mmc),518 "delay line cfg timeout unit:%d cfgr:%d\n",519 i, cfgr);520 continue;521 }522 523 lng = FIELD_GET(DLYB_CFGR_LNG_MASK, cfgr);524 if (lng < BIT(DLYB_NB_DELAY) && lng > 0)525 break;526 }527 528 if (i > DLYB_CFGR_UNIT_MAX)529 return -EINVAL;530 531 dlyb->unit = i;532 dlyb->max = __fls(lng);533 534 return 0;535}536 537static int sdmmc_dlyb_mp25_enable(struct sdmmc_dlyb *dlyb)538{539 u32 cr, sr;540 541 cr = readl_relaxed(dlyb->base + SYSCFG_DLYBSD_CR);542 cr |= DLYBSD_CR_EN;543 544 writel_relaxed(cr, dlyb->base + SYSCFG_DLYBSD_CR);545 546 return readl_relaxed_poll_timeout(dlyb->base + SYSCFG_DLYBSD_SR,547 sr, sr & DLYBSD_SR_LOCK, 1,548 DLYBSD_TIMEOUT_1S_IN_US);549}550 551static int sdmmc_dlyb_mp25_set_cfg(struct sdmmc_dlyb *dlyb,552 int unit __maybe_unused, int phase,553 bool sampler __maybe_unused)554{555 u32 cr, sr;556 557 cr = readl_relaxed(dlyb->base + SYSCFG_DLYBSD_CR);558 cr &= ~DLYBSD_CR_RXTAPSEL_MASK;559 cr |= FIELD_PREP(DLYBSD_CR_RXTAPSEL_MASK, phase);560 561 writel_relaxed(cr, dlyb->base + SYSCFG_DLYBSD_CR);562 563 return readl_relaxed_poll_timeout(dlyb->base + SYSCFG_DLYBSD_SR,564 sr, sr & DLYBSD_SR_RXTAPSEL_ACK, 1,565 DLYBSD_TIMEOUT_1S_IN_US);566}567 568static int sdmmc_dlyb_mp25_prepare(struct mmci_host *host)569{570 struct sdmmc_dlyb *dlyb = host->variant_priv;571 572 dlyb->max = DLYBSD_TAPSEL_NB;573 574 return 0;575}576 577static int sdmmc_dlyb_phase_tuning(struct mmci_host *host, u32 opcode)578{579 struct sdmmc_dlyb *dlyb = host->variant_priv;580 int cur_len = 0, max_len = 0, end_of_len = 0;581 int phase, ret;582 583 for (phase = 0; phase <= dlyb->max; phase++) {584 ret = dlyb->ops->set_cfg(dlyb, dlyb->unit, phase, false);585 if (ret) {586 dev_err(mmc_dev(host->mmc), "tuning config failed\n");587 return ret;588 }589 590 if (mmc_send_tuning(host->mmc, opcode, NULL)) {591 cur_len = 0;592 } else {593 cur_len++;594 if (cur_len > max_len) {595 max_len = cur_len;596 end_of_len = phase;597 }598 }599 }600 601 if (!max_len) {602 dev_err(mmc_dev(host->mmc), "no tuning point found\n");603 return -EINVAL;604 }605 606 if (dlyb->ops->set_input_ck)607 dlyb->ops->set_input_ck(dlyb);608 609 phase = end_of_len - max_len / 2;610 ret = dlyb->ops->set_cfg(dlyb, dlyb->unit, phase, false);611 if (ret) {612 dev_err(mmc_dev(host->mmc), "tuning reconfig failed\n");613 return ret;614 }615 616 dev_dbg(mmc_dev(host->mmc), "unit:%d max_dly:%d phase:%d\n",617 dlyb->unit, dlyb->max, phase);618 619 return 0;620}621 622static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode)623{624 struct mmci_host *host = mmc_priv(mmc);625 struct sdmmc_dlyb *dlyb = host->variant_priv;626 u32 clk;627 int ret;628 629 if ((host->mmc->ios.timing != MMC_TIMING_UHS_SDR104 &&630 host->mmc->ios.timing != MMC_TIMING_MMC_HS200) ||631 host->mmc->actual_clock <= 50000000)632 return 0;633 634 if (!dlyb || !dlyb->base)635 return -EINVAL;636 637 ret = dlyb->ops->dlyb_enable(dlyb);638 if (ret)639 return ret;640 641 /*642 * SDMMC_FBCK is selected when an external Delay Block is needed643 * with SDR104 or HS200.644 */645 clk = host->clk_reg;646 clk &= ~MCI_STM32_CLK_SEL_MSK;647 clk |= MCI_STM32_CLK_SELFBCK;648 mmci_write_clkreg(host, clk);649 650 ret = dlyb->ops->tuning_prepare(host);651 if (ret)652 return ret;653 654 return sdmmc_dlyb_phase_tuning(host, opcode);655}656 657static void sdmmc_pre_sig_volt_vswitch(struct mmci_host *host)658{659 /* clear the voltage switch completion flag */660 writel_relaxed(MCI_STM32_VSWENDC, host->base + MMCICLEAR);661 /* enable Voltage switch procedure */662 mmci_write_pwrreg(host, host->pwr_reg | MCI_STM32_VSWITCHEN);663}664 665static int sdmmc_post_sig_volt_switch(struct mmci_host *host,666 struct mmc_ios *ios)667{668 unsigned long flags;669 u32 status;670 int ret = 0;671 672 spin_lock_irqsave(&host->lock, flags);673 if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180 &&674 host->pwr_reg & MCI_STM32_VSWITCHEN) {675 mmci_write_pwrreg(host, host->pwr_reg | MCI_STM32_VSWITCH);676 spin_unlock_irqrestore(&host->lock, flags);677 678 /* wait voltage switch completion while 10ms */679 ret = readl_relaxed_poll_timeout(host->base + MMCISTATUS,680 status,681 (status & MCI_STM32_VSWEND),682 10, SDMMC_VSWEND_TIMEOUT_US);683 684 writel_relaxed(MCI_STM32_VSWENDC | MCI_STM32_CKSTOPC,685 host->base + MMCICLEAR);686 spin_lock_irqsave(&host->lock, flags);687 mmci_write_pwrreg(host, host->pwr_reg &688 ~(MCI_STM32_VSWITCHEN | MCI_STM32_VSWITCH));689 }690 spin_unlock_irqrestore(&host->lock, flags);691 692 return ret;693}694 695static struct mmci_host_ops sdmmc_variant_ops = {696 .validate_data = sdmmc_idma_validate_data,697 .prep_data = sdmmc_idma_prep_data,698 .unprep_data = sdmmc_idma_unprep_data,699 .get_datactrl_cfg = sdmmc_get_dctrl_cfg,700 .dma_setup = sdmmc_idma_setup,701 .dma_start = sdmmc_idma_start,702 .dma_finalize = sdmmc_idma_finalize,703 .dma_error = sdmmc_idma_error,704 .set_clkreg = mmci_sdmmc_set_clkreg,705 .set_pwrreg = mmci_sdmmc_set_pwrreg,706 .busy_complete = sdmmc_busy_complete,707 .pre_sig_volt_switch = sdmmc_pre_sig_volt_vswitch,708 .post_sig_volt_switch = sdmmc_post_sig_volt_switch,709};710 711static struct sdmmc_tuning_ops dlyb_tuning_mp15_ops = {712 .dlyb_enable = sdmmc_dlyb_mp15_enable,713 .set_input_ck = sdmmc_dlyb_mp15_input_ck,714 .tuning_prepare = sdmmc_dlyb_mp15_prepare,715 .set_cfg = sdmmc_dlyb_mp15_set_cfg,716};717 718static struct sdmmc_tuning_ops dlyb_tuning_mp25_ops = {719 .dlyb_enable = sdmmc_dlyb_mp25_enable,720 .tuning_prepare = sdmmc_dlyb_mp25_prepare,721 .set_cfg = sdmmc_dlyb_mp25_set_cfg,722};723 724void sdmmc_variant_init(struct mmci_host *host)725{726 struct device_node *np = host->mmc->parent->of_node;727 void __iomem *base_dlyb;728 struct sdmmc_dlyb *dlyb;729 730 host->ops = &sdmmc_variant_ops;731 host->pwr_reg = readl_relaxed(host->base + MMCIPOWER);732 733 base_dlyb = devm_of_iomap(mmc_dev(host->mmc), np, 1, NULL);734 if (IS_ERR(base_dlyb))735 return;736 737 dlyb = devm_kzalloc(mmc_dev(host->mmc), sizeof(*dlyb), GFP_KERNEL);738 if (!dlyb)739 return;740 741 dlyb->base = base_dlyb;742 if (of_device_is_compatible(np, "st,stm32mp25-sdmmc2"))743 dlyb->ops = &dlyb_tuning_mp25_ops;744 else745 dlyb->ops = &dlyb_tuning_mp15_ops;746 747 host->variant_priv = dlyb;748 host->mmc_ops->execute_tuning = sdmmc_execute_tuning;749}750