Lines Matching +full:mode +full:- +full:reg
1 // SPDX-License-Identifier: GPL-2.0-only
8 * Date: 2016-8-24
17 #include "sdhci-pltfm.h"
18 #include "sdhci-xenon.h"
156 void __iomem *reg; member
209 params = devm_kzalloc(mmc_dev(host->mmc), sizeof(*params), GFP_KERNEL); in xenon_alloc_emmc_phy()
211 return -ENOMEM; in xenon_alloc_emmc_phy()
213 priv->phy_params = params; in xenon_alloc_emmc_phy()
214 if (priv->phy_type == EMMC_5_0_PHY) in xenon_alloc_emmc_phy()
215 priv->emmc_phy_regs = &xenon_emmc_5_0_phy_regs; in xenon_alloc_emmc_phy()
217 priv->emmc_phy_regs = &xenon_emmc_5_1_phy_regs; in xenon_alloc_emmc_phy()
224 u32 reg; in xenon_check_stability_internal_clk() local
227 err = read_poll_timeout(sdhci_readw, reg, reg & SDHCI_CLOCK_INT_STABLE, in xenon_check_stability_internal_clk()
230 dev_err(mmc_dev(host->mmc), "phy_init: Internal clock never stabilized.\n"); in xenon_check_stability_internal_clk()
236 * eMMC 5.0/5.1 PHY init/re-init.
239 * 2. SDCLK is stopped and re-enabled.
240 * 3. config in emmc_phy_regs->timing_adj and emmc_phy_regs->func_ctrl
245 u32 reg; in xenon_emmc_phy_init() local
249 struct xenon_emmc_phy_regs *phy_regs = priv->emmc_phy_regs; in xenon_emmc_phy_init()
256 reg = sdhci_readl(host, phy_regs->timing_adj); in xenon_emmc_phy_init()
257 reg |= XENON_PHY_INITIALIZAION; in xenon_emmc_phy_init()
258 sdhci_writel(host, reg, phy_regs->timing_adj); in xenon_emmc_phy_init()
261 wait = ((reg >> XENON_FC_SYNC_RST_DURATION_SHIFT) & in xenon_emmc_phy_init()
264 wait += ((reg >> XENON_FC_SYNC_RST_EN_DURATION_SHIFT) & in xenon_emmc_phy_init()
267 wait += ((reg >> XENON_FC_SYNC_EN_DURATION_SHIFT) & in xenon_emmc_phy_init()
270 wait += ((reg >> XENON_WAIT_CYCLE_BEFORE_USING_SHIFT) & in xenon_emmc_phy_init()
276 clock = host->clock; in xenon_emmc_phy_init()
295 ret = read_poll_timeout(sdhci_readl, reg, in xenon_emmc_phy_init()
296 !(reg & XENON_PHY_INITIALIZAION), in xenon_emmc_phy_init()
298 false, host, phy_regs->timing_adj); in xenon_emmc_phy_init()
300 dev_err(mmc_dev(host->mmc), "eMMC PHY init cannot complete after %d us\n", in xenon_emmc_phy_init()
314 struct xenon_emmc_phy_params *params = priv->phy_params; in armada_3700_soc_pad_voltage_set()
316 if (params->pad_ctrl.pad_type == SOC_PAD_FIXED_1_8V) { in armada_3700_soc_pad_voltage_set()
317 writel(ARMADA_3700_SOC_PAD_1_8V, params->pad_ctrl.reg); in armada_3700_soc_pad_voltage_set()
318 } else if (params->pad_ctrl.pad_type == SOC_PAD_SD) { in armada_3700_soc_pad_voltage_set()
320 writel(ARMADA_3700_SOC_PAD_1_8V, params->pad_ctrl.reg); in armada_3700_soc_pad_voltage_set()
322 writel(ARMADA_3700_SOC_PAD_3_3V, params->pad_ctrl.reg); in armada_3700_soc_pad_voltage_set()
336 struct xenon_emmc_phy_params *params = priv->phy_params; in xenon_emmc_phy_set_soc_pad()
338 if (!params->pad_ctrl.reg) in xenon_emmc_phy_set_soc_pad()
341 if (params->pad_ctrl.set_soc_pad) in xenon_emmc_phy_set_soc_pad()
342 params->pad_ctrl.set_soc_pad(host, signal_voltage); in xenon_emmc_phy_set_soc_pad()
352 u32 reg; in xenon_emmc_phy_enable_dll() local
355 struct xenon_emmc_phy_regs *phy_regs = priv->emmc_phy_regs; in xenon_emmc_phy_enable_dll()
358 if (WARN_ON(host->clock <= MMC_HIGH_52_MAX_DTR)) in xenon_emmc_phy_enable_dll()
359 return -EINVAL; in xenon_emmc_phy_enable_dll()
361 reg = sdhci_readl(host, phy_regs->dll_ctrl); in xenon_emmc_phy_enable_dll()
362 if (reg & XENON_DLL_ENABLE) in xenon_emmc_phy_enable_dll()
366 reg = sdhci_readl(host, phy_regs->dll_ctrl); in xenon_emmc_phy_enable_dll()
367 reg |= (XENON_DLL_ENABLE | XENON_DLL_FAST_LOCK); in xenon_emmc_phy_enable_dll()
374 reg &= ~((XENON_DLL_PHASE_MASK << XENON_DLL_PHSEL0_SHIFT) | in xenon_emmc_phy_enable_dll()
376 reg |= ((XENON_DLL_PHASE_90_DEGREE << XENON_DLL_PHSEL0_SHIFT) | in xenon_emmc_phy_enable_dll()
379 reg &= ~XENON_DLL_BYPASS_EN; in xenon_emmc_phy_enable_dll()
380 reg |= phy_regs->dll_update; in xenon_emmc_phy_enable_dll()
381 if (priv->phy_type == EMMC_5_1_PHY) in xenon_emmc_phy_enable_dll()
382 reg &= ~XENON_DLL_REFCLK_SEL; in xenon_emmc_phy_enable_dll()
383 sdhci_writel(host, reg, phy_regs->dll_ctrl); in xenon_emmc_phy_enable_dll()
394 dev_err(mmc_dev(host->mmc), "Wait for DLL Lock time-out\n"); in xenon_emmc_phy_enable_dll()
395 return -ETIMEDOUT; in xenon_emmc_phy_enable_dll()
410 struct xenon_emmc_phy_params *params = priv->phy_params; in xenon_emmc_phy_config_tuning()
411 u32 reg, tuning_step; in xenon_emmc_phy_config_tuning() local
414 if (host->clock <= MMC_HIGH_52_MAX_DTR) in xenon_emmc_phy_config_tuning()
415 return -EINVAL; in xenon_emmc_phy_config_tuning()
422 reg = sdhci_readl(host, XENON_SLOT_DLL_CUR_DLY_VAL); in xenon_emmc_phy_config_tuning()
423 tuning_step = reg / params->tun_step_divider; in xenon_emmc_phy_config_tuning()
425 dev_warn(mmc_dev(host->mmc), in xenon_emmc_phy_config_tuning()
432 reg = sdhci_readl(host, XENON_SLOT_OP_STATUS_CTRL); in xenon_emmc_phy_config_tuning()
433 reg &= ~(XENON_TUN_CONSECUTIVE_TIMES_MASK << in xenon_emmc_phy_config_tuning()
435 reg |= (params->nr_tun_times << XENON_TUN_CONSECUTIVE_TIMES_SHIFT); in xenon_emmc_phy_config_tuning()
436 reg &= ~(XENON_TUNING_STEP_MASK << XENON_TUNING_STEP_SHIFT); in xenon_emmc_phy_config_tuning()
437 reg |= (tuning_step << XENON_TUNING_STEP_SHIFT); in xenon_emmc_phy_config_tuning()
438 sdhci_writel(host, reg, XENON_SLOT_OP_STATUS_CTRL); in xenon_emmc_phy_config_tuning()
447 u32 reg; in xenon_emmc_phy_disable_strobe() local
450 reg = sdhci_readl(host, XENON_SLOT_EMMC_CTRL); in xenon_emmc_phy_disable_strobe()
451 reg &= ~(XENON_ENABLE_DATA_STROBE | XENON_ENABLE_RESP_STROBE); in xenon_emmc_phy_disable_strobe()
452 sdhci_writel(host, reg, XENON_SLOT_EMMC_CTRL); in xenon_emmc_phy_disable_strobe()
455 if (priv->phy_type == EMMC_5_0_PHY) { in xenon_emmc_phy_disable_strobe()
456 reg = sdhci_readl(host, XENON_EMMC_5_0_PHY_PAD_CONTROL); in xenon_emmc_phy_disable_strobe()
457 reg &= ~(XENON_EMMC5_FC_QSP_PD | XENON_EMMC5_FC_QSP_PU); in xenon_emmc_phy_disable_strobe()
458 sdhci_writel(host, reg, XENON_EMMC_5_0_PHY_PAD_CONTROL); in xenon_emmc_phy_disable_strobe()
460 reg = sdhci_readl(host, XENON_EMMC_PHY_PAD_CONTROL1); in xenon_emmc_phy_disable_strobe()
461 reg &= ~(XENON_EMMC5_1_FC_QSP_PD | XENON_EMMC5_1_FC_QSP_PU); in xenon_emmc_phy_disable_strobe()
462 sdhci_writel(host, reg, XENON_EMMC_PHY_PAD_CONTROL1); in xenon_emmc_phy_disable_strobe()
471 u32 reg; in xenon_emmc_phy_strobe_delay_adj() local
473 if (WARN_ON(host->timing != MMC_TIMING_MMC_HS400)) in xenon_emmc_phy_strobe_delay_adj()
476 if (host->clock <= MMC_HIGH_52_MAX_DTR) in xenon_emmc_phy_strobe_delay_adj()
479 dev_dbg(mmc_dev(host->mmc), "starts HS400 strobe delay adjustment\n"); in xenon_emmc_phy_strobe_delay_adj()
484 reg = sdhci_readl(host, XENON_SLOT_EMMC_CTRL); in xenon_emmc_phy_strobe_delay_adj()
485 reg |= XENON_ENABLE_DATA_STROBE; in xenon_emmc_phy_strobe_delay_adj()
489 * 1. card is in HS400 mode and in xenon_emmc_phy_strobe_delay_adj()
493 if (host->mmc->ios.enhanced_strobe) in xenon_emmc_phy_strobe_delay_adj()
494 reg |= XENON_ENABLE_RESP_STROBE; in xenon_emmc_phy_strobe_delay_adj()
495 sdhci_writel(host, reg, XENON_SLOT_EMMC_CTRL); in xenon_emmc_phy_strobe_delay_adj()
498 if (priv->phy_type == EMMC_5_0_PHY) { in xenon_emmc_phy_strobe_delay_adj()
499 reg = sdhci_readl(host, XENON_EMMC_5_0_PHY_PAD_CONTROL); in xenon_emmc_phy_strobe_delay_adj()
500 reg |= XENON_EMMC5_FC_QSP_PD; in xenon_emmc_phy_strobe_delay_adj()
501 reg &= ~XENON_EMMC5_FC_QSP_PU; in xenon_emmc_phy_strobe_delay_adj()
502 sdhci_writel(host, reg, XENON_EMMC_5_0_PHY_PAD_CONTROL); in xenon_emmc_phy_strobe_delay_adj()
504 reg = sdhci_readl(host, XENON_EMMC_PHY_PAD_CONTROL1); in xenon_emmc_phy_strobe_delay_adj()
505 reg |= XENON_EMMC5_1_FC_QSP_PD; in xenon_emmc_phy_strobe_delay_adj()
506 reg &= ~XENON_EMMC5_1_FC_QSP_PU; in xenon_emmc_phy_strobe_delay_adj()
507 sdhci_writel(host, reg, XENON_EMMC_PHY_PAD_CONTROL1); in xenon_emmc_phy_strobe_delay_adj()
512 * If eMMC PHY Slow Mode is required in lower speed mode (SDCLK < 55MHz)
513 * in SDR mode, enable Slow Mode to bypass eMMC PHY.
514 * SDIO slower SDR mode also requires Slow Mode.
516 * If Slow Mode is enabled, return true.
524 struct xenon_emmc_phy_params *params = priv->phy_params; in xenon_emmc_phy_slow_mode()
525 struct xenon_emmc_phy_regs *phy_regs = priv->emmc_phy_regs; in xenon_emmc_phy_slow_mode()
526 u32 reg; in xenon_emmc_phy_slow_mode() local
529 if (host->clock > MMC_HIGH_52_MAX_DTR) in xenon_emmc_phy_slow_mode()
532 reg = sdhci_readl(host, phy_regs->timing_adj); in xenon_emmc_phy_slow_mode()
533 /* When in slower SDR mode, enable Slow Mode for SDIO in xenon_emmc_phy_slow_mode()
534 * or when Slow Mode flag is set in xenon_emmc_phy_slow_mode()
539 * If Slow Mode is required, enable Slow Mode by default in xenon_emmc_phy_slow_mode()
542 if (params->slow_mode) { in xenon_emmc_phy_slow_mode()
543 reg |= XENON_TIMING_ADJUST_SLOW_MODE; in xenon_emmc_phy_slow_mode()
546 reg &= ~XENON_TIMING_ADJUST_SLOW_MODE; in xenon_emmc_phy_slow_mode()
554 if ((priv->init_card_type == MMC_TYPE_SDIO) || in xenon_emmc_phy_slow_mode()
555 params->slow_mode) { in xenon_emmc_phy_slow_mode()
556 reg |= XENON_TIMING_ADJUST_SLOW_MODE; in xenon_emmc_phy_slow_mode()
562 reg &= ~XENON_TIMING_ADJUST_SLOW_MODE; in xenon_emmc_phy_slow_mode()
566 sdhci_writel(host, reg, phy_regs->timing_adj); in xenon_emmc_phy_slow_mode()
571 * Set-up eMMC 5.0/5.1 PHY.
572 * Specific configuration depends on the current speed mode in use.
577 u32 reg; in xenon_emmc_phy_set() local
580 struct xenon_emmc_phy_params *params = priv->phy_params; in xenon_emmc_phy_set()
581 struct xenon_emmc_phy_regs *phy_regs = priv->emmc_phy_regs; in xenon_emmc_phy_set()
583 dev_dbg(mmc_dev(host->mmc), "eMMC PHY setting starts\n"); in xenon_emmc_phy_set()
586 reg = sdhci_readl(host, phy_regs->pad_ctrl); in xenon_emmc_phy_set()
587 reg |= (XENON_FC_DQ_RECEN | XENON_FC_CMD_RECEN | in xenon_emmc_phy_set()
590 reg |= XENON_FC_ALL_CMOS_RECEIVER; in xenon_emmc_phy_set()
591 sdhci_writel(host, reg, phy_regs->pad_ctrl); in xenon_emmc_phy_set()
594 if (priv->phy_type == EMMC_5_0_PHY) { in xenon_emmc_phy_set()
595 reg = sdhci_readl(host, XENON_EMMC_5_0_PHY_PAD_CONTROL); in xenon_emmc_phy_set()
596 reg |= (XENON_EMMC5_FC_CMD_PU | XENON_EMMC5_FC_DQ_PU); in xenon_emmc_phy_set()
597 reg &= ~(XENON_EMMC5_FC_CMD_PD | XENON_EMMC5_FC_DQ_PD); in xenon_emmc_phy_set()
598 sdhci_writel(host, reg, XENON_EMMC_5_0_PHY_PAD_CONTROL); in xenon_emmc_phy_set()
600 reg = sdhci_readl(host, XENON_EMMC_PHY_PAD_CONTROL1); in xenon_emmc_phy_set()
601 reg |= (XENON_EMMC5_1_FC_CMD_PU | XENON_EMMC5_1_FC_DQ_PU); in xenon_emmc_phy_set()
602 reg &= ~(XENON_EMMC5_1_FC_CMD_PD | XENON_EMMC5_1_FC_DQ_PD); in xenon_emmc_phy_set()
603 sdhci_writel(host, reg, XENON_EMMC_PHY_PAD_CONTROL1); in xenon_emmc_phy_set()
612 * If SDIO card, set SDIO Mode in xenon_emmc_phy_set()
613 * Otherwise, clear SDIO Mode in xenon_emmc_phy_set()
615 reg = sdhci_readl(host, phy_regs->timing_adj); in xenon_emmc_phy_set()
616 if (priv->init_card_type == MMC_TYPE_SDIO) in xenon_emmc_phy_set()
617 reg |= XENON_TIMING_ADJUST_SDIO_MODE; in xenon_emmc_phy_set()
619 reg &= ~XENON_TIMING_ADJUST_SDIO_MODE; in xenon_emmc_phy_set()
620 sdhci_writel(host, reg, phy_regs->timing_adj); in xenon_emmc_phy_set()
628 * Define them both in sdhci-xenon-emmc-phy.h. in xenon_emmc_phy_set()
630 reg = sdhci_readl(host, phy_regs->pad_ctrl2); in xenon_emmc_phy_set()
631 reg &= ~((XENON_ZNR_MASK << XENON_ZNR_SHIFT) | XENON_ZPR_MASK); in xenon_emmc_phy_set()
632 reg |= ((params->znr << XENON_ZNR_SHIFT) | params->zpr); in xenon_emmc_phy_set()
633 sdhci_writel(host, reg, phy_regs->pad_ctrl2); in xenon_emmc_phy_set()
639 reg = sdhci_readl(host, SDHCI_CLOCK_CONTROL); in xenon_emmc_phy_set()
640 reg &= ~SDHCI_CLOCK_CARD_EN; in xenon_emmc_phy_set()
641 sdhci_writew(host, reg, SDHCI_CLOCK_CONTROL); in xenon_emmc_phy_set()
643 reg = sdhci_readl(host, phy_regs->func_ctrl); in xenon_emmc_phy_set()
646 reg |= (XENON_DQ_DDR_MODE_MASK << XENON_DQ_DDR_MODE_SHIFT) | in xenon_emmc_phy_set()
648 reg &= ~XENON_DQ_ASYNC_MODE; in xenon_emmc_phy_set()
652 reg |= (XENON_DQ_DDR_MODE_MASK << XENON_DQ_DDR_MODE_SHIFT) | in xenon_emmc_phy_set()
656 reg &= ~((XENON_DQ_DDR_MODE_MASK << XENON_DQ_DDR_MODE_SHIFT) | in xenon_emmc_phy_set()
658 reg |= XENON_DQ_ASYNC_MODE; in xenon_emmc_phy_set()
660 sdhci_writel(host, reg, phy_regs->func_ctrl); in xenon_emmc_phy_set()
663 reg = sdhci_readl(host, SDHCI_CLOCK_CONTROL); in xenon_emmc_phy_set()
664 reg |= SDHCI_CLOCK_CARD_EN; in xenon_emmc_phy_set()
665 sdhci_writew(host, reg, SDHCI_CLOCK_CONTROL); in xenon_emmc_phy_set()
669 sdhci_writel(host, phy_regs->logic_timing_val, in xenon_emmc_phy_set()
670 phy_regs->logic_timing_adj); in xenon_emmc_phy_set()
677 dev_dbg(mmc_dev(host->mmc), "eMMC PHY setting completes\n"); in xenon_emmc_phy_set()
690 if (priv->hw_version == XENON_A3700) in get_dt_pad_ctrl_data()
691 params->pad_ctrl.set_soc_pad = armada_3700_soc_pad_voltage_set; in get_dt_pad_ctrl_data()
696 dev_err(mmc_dev(host->mmc), "Unable to find SoC PAD ctrl register address for %pOFn\n", in get_dt_pad_ctrl_data()
698 return -EINVAL; in get_dt_pad_ctrl_data()
701 params->pad_ctrl.reg = devm_ioremap_resource(mmc_dev(host->mmc), in get_dt_pad_ctrl_data()
703 if (IS_ERR(params->pad_ctrl.reg)) in get_dt_pad_ctrl_data()
704 return PTR_ERR(params->pad_ctrl.reg); in get_dt_pad_ctrl_data()
706 ret = of_property_read_string(np, "marvell,pad-type", &name); in get_dt_pad_ctrl_data()
708 dev_err(mmc_dev(host->mmc), "Unable to determine SoC PHY PAD ctrl type\n"); in get_dt_pad_ctrl_data()
712 params->pad_ctrl.pad_type = SOC_PAD_SD; in get_dt_pad_ctrl_data()
713 } else if (!strcmp(name, "fixed-1-8v")) { in get_dt_pad_ctrl_data()
714 params->pad_ctrl.pad_type = SOC_PAD_FIXED_1_8V; in get_dt_pad_ctrl_data()
716 dev_err(mmc_dev(host->mmc), "Unsupported SoC PHY PAD ctrl type %s\n", in get_dt_pad_ctrl_data()
718 return -EINVAL; in get_dt_pad_ctrl_data()
730 params->slow_mode = false; in xenon_emmc_phy_parse_params()
731 if (device_property_read_bool(dev, "marvell,xenon-phy-slow-mode")) in xenon_emmc_phy_parse_params()
732 params->slow_mode = true; in xenon_emmc_phy_parse_params()
734 params->znr = XENON_ZNR_DEF_VALUE; in xenon_emmc_phy_parse_params()
735 if (!device_property_read_u32(dev, "marvell,xenon-phy-znr", &value)) in xenon_emmc_phy_parse_params()
736 params->znr = value & XENON_ZNR_MASK; in xenon_emmc_phy_parse_params()
738 params->zpr = XENON_ZPR_DEF_VALUE; in xenon_emmc_phy_parse_params()
739 if (!device_property_read_u32(dev, "marvell,xenon-phy-zpr", &value)) in xenon_emmc_phy_parse_params()
740 params->zpr = value & XENON_ZPR_MASK; in xenon_emmc_phy_parse_params()
742 params->nr_tun_times = XENON_TUN_CONSECUTIVE_TIMES; in xenon_emmc_phy_parse_params()
743 if (!device_property_read_u32(dev, "marvell,xenon-phy-nr-success-tun", in xenon_emmc_phy_parse_params()
745 params->nr_tun_times = value & XENON_TUN_CONSECUTIVE_TIMES_MASK; in xenon_emmc_phy_parse_params()
747 params->tun_step_divider = XENON_TUNING_STEP_DIVIDER; in xenon_emmc_phy_parse_params()
748 if (!device_property_read_u32(dev, "marvell,xenon-phy-tun-step-divider", in xenon_emmc_phy_parse_params()
750 params->tun_step_divider = value & 0xFF; in xenon_emmc_phy_parse_params()
752 if (dev->of_node) in xenon_emmc_phy_parse_params()
753 return get_dt_pad_ctrl_data(host, dev->of_node, params); in xenon_emmc_phy_parse_params()
765 * Setting PHY when card is working in High Speed Mode.
773 if (WARN_ON(host->clock <= XENON_DEFAULT_SDCLK_FREQ)) in xenon_hs_delay_adj()
774 return -EINVAL; in xenon_hs_delay_adj()
776 switch (host->timing) { in xenon_hs_delay_adj()
786 * DDR Mode requires driver to scan Sampling Fixed Delay Line, in xenon_hs_delay_adj()
791 * default value of DDR mode. in xenon_hs_delay_adj()
793 * If any timing issue occurs in DDR mode on Marvell products, in xenon_hs_delay_adj()
796 dev_warn_once(mmc_dev(host->mmc), "Timing issue might occur in DDR mode\n"); in xenon_hs_delay_adj()
806 * or Speed Mode is changed.
807 * Additional config are required when card is working in High Speed mode,
808 * after leaving Legacy Mode.
816 if (!host->clock) { in xenon_phy_adj()
817 priv->clock = 0; in xenon_phy_adj()
826 if ((host->clock == priv->clock) && in xenon_phy_adj()
827 (ios->bus_width == priv->bus_width) && in xenon_phy_adj()
828 (ios->timing == priv->timing)) in xenon_phy_adj()
831 xenon_emmc_phy_set(host, ios->timing); in xenon_phy_adj()
834 priv->bus_width = ios->bus_width; in xenon_phy_adj()
836 priv->timing = ios->timing; in xenon_phy_adj()
837 priv->clock = host->clock; in xenon_phy_adj()
839 /* Legacy mode is a special case */ in xenon_phy_adj()
840 if (ios->timing == MMC_TIMING_LEGACY) in xenon_phy_adj()
843 if (host->clock > XENON_DEFAULT_SDCLK_FREQ) in xenon_phy_adj()
855 priv->phy_type = match_string(phy_types, NR_PHY_TYPES, phy_name); in xenon_add_phy()
856 if (priv->phy_type < 0) { in xenon_add_phy()
857 dev_err(mmc_dev(host->mmc), in xenon_add_phy()
860 priv->phy_type = EMMC_5_1_PHY; in xenon_add_phy()
867 return xenon_emmc_phy_parse_params(host, dev, priv->phy_params); in xenon_add_phy()
874 if (!device_property_read_string(dev, "marvell,xenon-phy-type", &phy_type)) in xenon_phy_parse_params()