Lines Matching +full:mode +full:- +full:reg
1 // SPDX-License-Identifier: GPL-2.0-only
8 * Date: 2016-8-24
16 #include "sdhci-pltfm.h"
17 #include "sdhci-xenon.h"
153 void __iomem *reg; member
206 params = devm_kzalloc(mmc_dev(host->mmc), sizeof(*params), GFP_KERNEL); in xenon_alloc_emmc_phy()
208 return -ENOMEM; in xenon_alloc_emmc_phy()
210 priv->phy_params = params; in xenon_alloc_emmc_phy()
211 if (priv->phy_type == EMMC_5_0_PHY) in xenon_alloc_emmc_phy()
212 priv->emmc_phy_regs = &xenon_emmc_5_0_phy_regs; in xenon_alloc_emmc_phy()
214 priv->emmc_phy_regs = &xenon_emmc_5_1_phy_regs; in xenon_alloc_emmc_phy()
220 * eMMC 5.0/5.1 PHY init/re-init.
223 * 2. SDCLK is stopped and re-enabled.
224 * 3. config in emmc_phy_regs->timing_adj and emmc_phy_regs->func_ctrl
229 u32 reg; in xenon_emmc_phy_init() local
233 struct xenon_emmc_phy_regs *phy_regs = priv->emmc_phy_regs; in xenon_emmc_phy_init()
235 reg = sdhci_readl(host, phy_regs->timing_adj); in xenon_emmc_phy_init()
236 reg |= XENON_PHY_INITIALIZAION; in xenon_emmc_phy_init()
237 sdhci_writel(host, reg, phy_regs->timing_adj); in xenon_emmc_phy_init()
240 wait = ((reg >> XENON_FC_SYNC_RST_DURATION_SHIFT) & in xenon_emmc_phy_init()
243 wait += ((reg >> XENON_FC_SYNC_RST_EN_DURATION_SHIFT) & in xenon_emmc_phy_init()
246 wait += ((reg >> XENON_FC_SYNC_EN_DURATION_SHIFT) & in xenon_emmc_phy_init()
249 wait += ((reg >> XENON_WAIT_CYCLE_BEFORE_USING_SHIFT) & in xenon_emmc_phy_init()
255 clock = host->clock; in xenon_emmc_phy_init()
265 reg = sdhci_readl(host, phy_regs->timing_adj); in xenon_emmc_phy_init()
266 reg &= XENON_PHY_INITIALIZAION; in xenon_emmc_phy_init()
267 if (reg) { in xenon_emmc_phy_init()
268 dev_err(mmc_dev(host->mmc), "eMMC PHY init cannot complete after %d us\n", in xenon_emmc_phy_init()
270 return -ETIMEDOUT; in xenon_emmc_phy_init()
284 struct xenon_emmc_phy_params *params = priv->phy_params; in armada_3700_soc_pad_voltage_set()
286 if (params->pad_ctrl.pad_type == SOC_PAD_FIXED_1_8V) { in armada_3700_soc_pad_voltage_set()
287 writel(ARMADA_3700_SOC_PAD_1_8V, params->pad_ctrl.reg); in armada_3700_soc_pad_voltage_set()
288 } else if (params->pad_ctrl.pad_type == SOC_PAD_SD) { in armada_3700_soc_pad_voltage_set()
290 writel(ARMADA_3700_SOC_PAD_1_8V, params->pad_ctrl.reg); in armada_3700_soc_pad_voltage_set()
292 writel(ARMADA_3700_SOC_PAD_3_3V, params->pad_ctrl.reg); in armada_3700_soc_pad_voltage_set()
306 struct xenon_emmc_phy_params *params = priv->phy_params; in xenon_emmc_phy_set_soc_pad()
308 if (!params->pad_ctrl.reg) in xenon_emmc_phy_set_soc_pad()
311 if (params->pad_ctrl.set_soc_pad) in xenon_emmc_phy_set_soc_pad()
312 params->pad_ctrl.set_soc_pad(host, signal_voltage); in xenon_emmc_phy_set_soc_pad()
322 u32 reg; in xenon_emmc_phy_enable_dll() local
325 struct xenon_emmc_phy_regs *phy_regs = priv->emmc_phy_regs; in xenon_emmc_phy_enable_dll()
328 if (WARN_ON(host->clock <= MMC_HIGH_52_MAX_DTR)) in xenon_emmc_phy_enable_dll()
329 return -EINVAL; in xenon_emmc_phy_enable_dll()
331 reg = sdhci_readl(host, phy_regs->dll_ctrl); in xenon_emmc_phy_enable_dll()
332 if (reg & XENON_DLL_ENABLE) in xenon_emmc_phy_enable_dll()
336 reg = sdhci_readl(host, phy_regs->dll_ctrl); in xenon_emmc_phy_enable_dll()
337 reg |= (XENON_DLL_ENABLE | XENON_DLL_FAST_LOCK); in xenon_emmc_phy_enable_dll()
344 reg &= ~((XENON_DLL_PHASE_MASK << XENON_DLL_PHSEL0_SHIFT) | in xenon_emmc_phy_enable_dll()
346 reg |= ((XENON_DLL_PHASE_90_DEGREE << XENON_DLL_PHSEL0_SHIFT) | in xenon_emmc_phy_enable_dll()
349 reg &= ~XENON_DLL_BYPASS_EN; in xenon_emmc_phy_enable_dll()
350 reg |= phy_regs->dll_update; in xenon_emmc_phy_enable_dll()
351 if (priv->phy_type == EMMC_5_1_PHY) in xenon_emmc_phy_enable_dll()
352 reg &= ~XENON_DLL_REFCLK_SEL; in xenon_emmc_phy_enable_dll()
353 sdhci_writel(host, reg, phy_regs->dll_ctrl); in xenon_emmc_phy_enable_dll()
364 dev_err(mmc_dev(host->mmc), "Wait for DLL Lock time-out\n"); in xenon_emmc_phy_enable_dll()
365 return -ETIMEDOUT; in xenon_emmc_phy_enable_dll()
380 struct xenon_emmc_phy_params *params = priv->phy_params; in xenon_emmc_phy_config_tuning()
381 u32 reg, tuning_step; in xenon_emmc_phy_config_tuning() local
384 if (host->clock <= MMC_HIGH_52_MAX_DTR) in xenon_emmc_phy_config_tuning()
385 return -EINVAL; in xenon_emmc_phy_config_tuning()
392 reg = sdhci_readl(host, XENON_SLOT_DLL_CUR_DLY_VAL); in xenon_emmc_phy_config_tuning()
393 tuning_step = reg / params->tun_step_divider; in xenon_emmc_phy_config_tuning()
395 dev_warn(mmc_dev(host->mmc), in xenon_emmc_phy_config_tuning()
402 reg = sdhci_readl(host, XENON_SLOT_OP_STATUS_CTRL); in xenon_emmc_phy_config_tuning()
403 reg &= ~(XENON_TUN_CONSECUTIVE_TIMES_MASK << in xenon_emmc_phy_config_tuning()
405 reg |= (params->nr_tun_times << XENON_TUN_CONSECUTIVE_TIMES_SHIFT); in xenon_emmc_phy_config_tuning()
406 reg &= ~(XENON_TUNING_STEP_MASK << XENON_TUNING_STEP_SHIFT); in xenon_emmc_phy_config_tuning()
407 reg |= (tuning_step << XENON_TUNING_STEP_SHIFT); in xenon_emmc_phy_config_tuning()
408 sdhci_writel(host, reg, XENON_SLOT_OP_STATUS_CTRL); in xenon_emmc_phy_config_tuning()
417 u32 reg; in xenon_emmc_phy_disable_strobe() local
420 reg = sdhci_readl(host, XENON_SLOT_EMMC_CTRL); in xenon_emmc_phy_disable_strobe()
421 reg &= ~(XENON_ENABLE_DATA_STROBE | XENON_ENABLE_RESP_STROBE); in xenon_emmc_phy_disable_strobe()
422 sdhci_writel(host, reg, XENON_SLOT_EMMC_CTRL); in xenon_emmc_phy_disable_strobe()
425 if (priv->phy_type == EMMC_5_0_PHY) { in xenon_emmc_phy_disable_strobe()
426 reg = sdhci_readl(host, XENON_EMMC_5_0_PHY_PAD_CONTROL); in xenon_emmc_phy_disable_strobe()
427 reg &= ~(XENON_EMMC5_FC_QSP_PD | XENON_EMMC5_FC_QSP_PU); in xenon_emmc_phy_disable_strobe()
428 sdhci_writel(host, reg, XENON_EMMC_5_0_PHY_PAD_CONTROL); in xenon_emmc_phy_disable_strobe()
430 reg = sdhci_readl(host, XENON_EMMC_PHY_PAD_CONTROL1); in xenon_emmc_phy_disable_strobe()
431 reg &= ~(XENON_EMMC5_1_FC_QSP_PD | XENON_EMMC5_1_FC_QSP_PU); in xenon_emmc_phy_disable_strobe()
432 sdhci_writel(host, reg, XENON_EMMC_PHY_PAD_CONTROL1); in xenon_emmc_phy_disable_strobe()
441 u32 reg; in xenon_emmc_phy_strobe_delay_adj() local
443 if (WARN_ON(host->timing != MMC_TIMING_MMC_HS400)) in xenon_emmc_phy_strobe_delay_adj()
446 if (host->clock <= MMC_HIGH_52_MAX_DTR) in xenon_emmc_phy_strobe_delay_adj()
449 dev_dbg(mmc_dev(host->mmc), "starts HS400 strobe delay adjustment\n"); in xenon_emmc_phy_strobe_delay_adj()
454 reg = sdhci_readl(host, XENON_SLOT_EMMC_CTRL); in xenon_emmc_phy_strobe_delay_adj()
455 reg |= XENON_ENABLE_DATA_STROBE; in xenon_emmc_phy_strobe_delay_adj()
459 * 1. card is in HS400 mode and in xenon_emmc_phy_strobe_delay_adj()
463 if (host->mmc->ios.enhanced_strobe) in xenon_emmc_phy_strobe_delay_adj()
464 reg |= XENON_ENABLE_RESP_STROBE; in xenon_emmc_phy_strobe_delay_adj()
465 sdhci_writel(host, reg, XENON_SLOT_EMMC_CTRL); in xenon_emmc_phy_strobe_delay_adj()
468 if (priv->phy_type == EMMC_5_0_PHY) { in xenon_emmc_phy_strobe_delay_adj()
469 reg = sdhci_readl(host, XENON_EMMC_5_0_PHY_PAD_CONTROL); in xenon_emmc_phy_strobe_delay_adj()
470 reg |= XENON_EMMC5_FC_QSP_PD; in xenon_emmc_phy_strobe_delay_adj()
471 reg &= ~XENON_EMMC5_FC_QSP_PU; in xenon_emmc_phy_strobe_delay_adj()
472 sdhci_writel(host, reg, XENON_EMMC_5_0_PHY_PAD_CONTROL); in xenon_emmc_phy_strobe_delay_adj()
474 reg = sdhci_readl(host, XENON_EMMC_PHY_PAD_CONTROL1); in xenon_emmc_phy_strobe_delay_adj()
475 reg |= XENON_EMMC5_1_FC_QSP_PD; in xenon_emmc_phy_strobe_delay_adj()
476 reg &= ~XENON_EMMC5_1_FC_QSP_PU; in xenon_emmc_phy_strobe_delay_adj()
477 sdhci_writel(host, reg, XENON_EMMC_PHY_PAD_CONTROL1); in xenon_emmc_phy_strobe_delay_adj()
482 * If eMMC PHY Slow Mode is required in lower speed mode (SDCLK < 55MHz)
483 * in SDR mode, enable Slow Mode to bypass eMMC PHY.
484 * SDIO slower SDR mode also requires Slow Mode.
486 * If Slow Mode is enabled, return true.
494 struct xenon_emmc_phy_params *params = priv->phy_params; in xenon_emmc_phy_slow_mode()
495 struct xenon_emmc_phy_regs *phy_regs = priv->emmc_phy_regs; in xenon_emmc_phy_slow_mode()
496 u32 reg; in xenon_emmc_phy_slow_mode() local
499 if (host->clock > MMC_HIGH_52_MAX_DTR) in xenon_emmc_phy_slow_mode()
502 reg = sdhci_readl(host, phy_regs->timing_adj); in xenon_emmc_phy_slow_mode()
503 /* When in slower SDR mode, enable Slow Mode for SDIO in xenon_emmc_phy_slow_mode()
504 * or when Slow Mode flag is set in xenon_emmc_phy_slow_mode()
509 * If Slow Mode is required, enable Slow Mode by default in xenon_emmc_phy_slow_mode()
512 if (params->slow_mode) { in xenon_emmc_phy_slow_mode()
513 reg |= XENON_TIMING_ADJUST_SLOW_MODE; in xenon_emmc_phy_slow_mode()
516 reg &= ~XENON_TIMING_ADJUST_SLOW_MODE; in xenon_emmc_phy_slow_mode()
524 if ((priv->init_card_type == MMC_TYPE_SDIO) || in xenon_emmc_phy_slow_mode()
525 params->slow_mode) { in xenon_emmc_phy_slow_mode()
526 reg |= XENON_TIMING_ADJUST_SLOW_MODE; in xenon_emmc_phy_slow_mode()
532 reg &= ~XENON_TIMING_ADJUST_SLOW_MODE; in xenon_emmc_phy_slow_mode()
536 sdhci_writel(host, reg, phy_regs->timing_adj); in xenon_emmc_phy_slow_mode()
541 * Set-up eMMC 5.0/5.1 PHY.
542 * Specific configuration depends on the current speed mode in use.
547 u32 reg; in xenon_emmc_phy_set() local
550 struct xenon_emmc_phy_params *params = priv->phy_params; in xenon_emmc_phy_set()
551 struct xenon_emmc_phy_regs *phy_regs = priv->emmc_phy_regs; in xenon_emmc_phy_set()
553 dev_dbg(mmc_dev(host->mmc), "eMMC PHY setting starts\n"); in xenon_emmc_phy_set()
556 reg = sdhci_readl(host, phy_regs->pad_ctrl); in xenon_emmc_phy_set()
557 reg |= (XENON_FC_DQ_RECEN | XENON_FC_CMD_RECEN | in xenon_emmc_phy_set()
560 reg |= XENON_FC_ALL_CMOS_RECEIVER; in xenon_emmc_phy_set()
561 sdhci_writel(host, reg, phy_regs->pad_ctrl); in xenon_emmc_phy_set()
564 if (priv->phy_type == EMMC_5_0_PHY) { in xenon_emmc_phy_set()
565 reg = sdhci_readl(host, XENON_EMMC_5_0_PHY_PAD_CONTROL); in xenon_emmc_phy_set()
566 reg |= (XENON_EMMC5_FC_CMD_PU | XENON_EMMC5_FC_DQ_PU); in xenon_emmc_phy_set()
567 reg &= ~(XENON_EMMC5_FC_CMD_PD | XENON_EMMC5_FC_DQ_PD); in xenon_emmc_phy_set()
568 sdhci_writel(host, reg, XENON_EMMC_5_0_PHY_PAD_CONTROL); in xenon_emmc_phy_set()
570 reg = sdhci_readl(host, XENON_EMMC_PHY_PAD_CONTROL1); in xenon_emmc_phy_set()
571 reg |= (XENON_EMMC5_1_FC_CMD_PU | XENON_EMMC5_1_FC_DQ_PU); in xenon_emmc_phy_set()
572 reg &= ~(XENON_EMMC5_1_FC_CMD_PD | XENON_EMMC5_1_FC_DQ_PD); in xenon_emmc_phy_set()
573 sdhci_writel(host, reg, XENON_EMMC_PHY_PAD_CONTROL1); in xenon_emmc_phy_set()
582 * If SDIO card, set SDIO Mode in xenon_emmc_phy_set()
583 * Otherwise, clear SDIO Mode in xenon_emmc_phy_set()
585 reg = sdhci_readl(host, phy_regs->timing_adj); in xenon_emmc_phy_set()
586 if (priv->init_card_type == MMC_TYPE_SDIO) in xenon_emmc_phy_set()
587 reg |= XENON_TIMING_ADJUST_SDIO_MODE; in xenon_emmc_phy_set()
589 reg &= ~XENON_TIMING_ADJUST_SDIO_MODE; in xenon_emmc_phy_set()
590 sdhci_writel(host, reg, phy_regs->timing_adj); in xenon_emmc_phy_set()
598 * Define them both in sdhci-xenon-emmc-phy.h. in xenon_emmc_phy_set()
600 reg = sdhci_readl(host, phy_regs->pad_ctrl2); in xenon_emmc_phy_set()
601 reg &= ~((XENON_ZNR_MASK << XENON_ZNR_SHIFT) | XENON_ZPR_MASK); in xenon_emmc_phy_set()
602 reg |= ((params->znr << XENON_ZNR_SHIFT) | params->zpr); in xenon_emmc_phy_set()
603 sdhci_writel(host, reg, phy_regs->pad_ctrl2); in xenon_emmc_phy_set()
609 reg = sdhci_readl(host, SDHCI_CLOCK_CONTROL); in xenon_emmc_phy_set()
610 reg &= ~SDHCI_CLOCK_CARD_EN; in xenon_emmc_phy_set()
611 sdhci_writew(host, reg, SDHCI_CLOCK_CONTROL); in xenon_emmc_phy_set()
613 reg = sdhci_readl(host, phy_regs->func_ctrl); in xenon_emmc_phy_set()
616 reg |= (XENON_DQ_DDR_MODE_MASK << XENON_DQ_DDR_MODE_SHIFT) | in xenon_emmc_phy_set()
618 reg &= ~XENON_DQ_ASYNC_MODE; in xenon_emmc_phy_set()
622 reg |= (XENON_DQ_DDR_MODE_MASK << XENON_DQ_DDR_MODE_SHIFT) | in xenon_emmc_phy_set()
626 reg &= ~((XENON_DQ_DDR_MODE_MASK << XENON_DQ_DDR_MODE_SHIFT) | in xenon_emmc_phy_set()
628 reg |= XENON_DQ_ASYNC_MODE; in xenon_emmc_phy_set()
630 sdhci_writel(host, reg, phy_regs->func_ctrl); in xenon_emmc_phy_set()
633 reg = sdhci_readl(host, SDHCI_CLOCK_CONTROL); in xenon_emmc_phy_set()
634 reg |= SDHCI_CLOCK_CARD_EN; in xenon_emmc_phy_set()
635 sdhci_writew(host, reg, SDHCI_CLOCK_CONTROL); in xenon_emmc_phy_set()
639 sdhci_writel(host, phy_regs->logic_timing_val, in xenon_emmc_phy_set()
640 phy_regs->logic_timing_adj); in xenon_emmc_phy_set()
647 dev_dbg(mmc_dev(host->mmc), "eMMC PHY setting completes\n"); in xenon_emmc_phy_set()
658 if (of_device_is_compatible(np, "marvell,armada-3700-sdhci")) in get_dt_pad_ctrl_data()
659 params->pad_ctrl.set_soc_pad = armada_3700_soc_pad_voltage_set; in get_dt_pad_ctrl_data()
664 dev_err(mmc_dev(host->mmc), "Unable to find SoC PAD ctrl register address for %pOFn\n", in get_dt_pad_ctrl_data()
666 return -EINVAL; in get_dt_pad_ctrl_data()
669 params->pad_ctrl.reg = devm_ioremap_resource(mmc_dev(host->mmc), in get_dt_pad_ctrl_data()
671 if (IS_ERR(params->pad_ctrl.reg)) in get_dt_pad_ctrl_data()
672 return PTR_ERR(params->pad_ctrl.reg); in get_dt_pad_ctrl_data()
674 ret = of_property_read_string(np, "marvell,pad-type", &name); in get_dt_pad_ctrl_data()
676 dev_err(mmc_dev(host->mmc), "Unable to determine SoC PHY PAD ctrl type\n"); in get_dt_pad_ctrl_data()
680 params->pad_ctrl.pad_type = SOC_PAD_SD; in get_dt_pad_ctrl_data()
681 } else if (!strcmp(name, "fixed-1-8v")) { in get_dt_pad_ctrl_data()
682 params->pad_ctrl.pad_type = SOC_PAD_FIXED_1_8V; in get_dt_pad_ctrl_data()
684 dev_err(mmc_dev(host->mmc), "Unsupported SoC PHY PAD ctrl type %s\n", in get_dt_pad_ctrl_data()
686 return -EINVAL; in get_dt_pad_ctrl_data()
698 params->slow_mode = false; in xenon_emmc_phy_parse_param_dt()
699 if (of_property_read_bool(np, "marvell,xenon-phy-slow-mode")) in xenon_emmc_phy_parse_param_dt()
700 params->slow_mode = true; in xenon_emmc_phy_parse_param_dt()
702 params->znr = XENON_ZNR_DEF_VALUE; in xenon_emmc_phy_parse_param_dt()
703 if (!of_property_read_u32(np, "marvell,xenon-phy-znr", &value)) in xenon_emmc_phy_parse_param_dt()
704 params->znr = value & XENON_ZNR_MASK; in xenon_emmc_phy_parse_param_dt()
706 params->zpr = XENON_ZPR_DEF_VALUE; in xenon_emmc_phy_parse_param_dt()
707 if (!of_property_read_u32(np, "marvell,xenon-phy-zpr", &value)) in xenon_emmc_phy_parse_param_dt()
708 params->zpr = value & XENON_ZPR_MASK; in xenon_emmc_phy_parse_param_dt()
710 params->nr_tun_times = XENON_TUN_CONSECUTIVE_TIMES; in xenon_emmc_phy_parse_param_dt()
711 if (!of_property_read_u32(np, "marvell,xenon-phy-nr-success-tun", in xenon_emmc_phy_parse_param_dt()
713 params->nr_tun_times = value & XENON_TUN_CONSECUTIVE_TIMES_MASK; in xenon_emmc_phy_parse_param_dt()
715 params->tun_step_divider = XENON_TUNING_STEP_DIVIDER; in xenon_emmc_phy_parse_param_dt()
716 if (!of_property_read_u32(np, "marvell,xenon-phy-tun-step-divider", in xenon_emmc_phy_parse_param_dt()
718 params->tun_step_divider = value & 0xFF; in xenon_emmc_phy_parse_param_dt()
731 * Setting PHY when card is working in High Speed Mode.
739 if (WARN_ON(host->clock <= XENON_DEFAULT_SDCLK_FREQ)) in xenon_hs_delay_adj()
740 return -EINVAL; in xenon_hs_delay_adj()
742 switch (host->timing) { in xenon_hs_delay_adj()
752 * DDR Mode requires driver to scan Sampling Fixed Delay Line, in xenon_hs_delay_adj()
757 * default value of DDR mode. in xenon_hs_delay_adj()
759 * If any timing issue occurs in DDR mode on Marvell products, in xenon_hs_delay_adj()
762 dev_warn_once(mmc_dev(host->mmc), "Timing issue might occur in DDR mode\n"); in xenon_hs_delay_adj()
772 * or Speed Mode is changed.
773 * Additional config are required when card is working in High Speed mode,
774 * after leaving Legacy Mode.
782 if (!host->clock) { in xenon_phy_adj()
783 priv->clock = 0; in xenon_phy_adj()
792 if ((host->clock == priv->clock) && in xenon_phy_adj()
793 (ios->bus_width == priv->bus_width) && in xenon_phy_adj()
794 (ios->timing == priv->timing)) in xenon_phy_adj()
797 xenon_emmc_phy_set(host, ios->timing); in xenon_phy_adj()
800 priv->bus_width = ios->bus_width; in xenon_phy_adj()
802 priv->timing = ios->timing; in xenon_phy_adj()
803 priv->clock = host->clock; in xenon_phy_adj()
805 /* Legacy mode is a special case */ in xenon_phy_adj()
806 if (ios->timing == MMC_TIMING_LEGACY) in xenon_phy_adj()
809 if (host->clock > XENON_DEFAULT_SDCLK_FREQ) in xenon_phy_adj()
821 priv->phy_type = match_string(phy_types, NR_PHY_TYPES, phy_name); in xenon_add_phy()
822 if (priv->phy_type < 0) { in xenon_add_phy()
823 dev_err(mmc_dev(host->mmc), in xenon_add_phy()
826 priv->phy_type = EMMC_5_1_PHY; in xenon_add_phy()
833 return xenon_emmc_phy_parse_param_dt(host, np, priv->phy_params); in xenon_add_phy()
840 if (!of_property_read_string(np, "marvell,xenon-phy-type", &phy_type)) in xenon_phy_parse_dt()