Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: sdhci_omap: Add support to set IODELAY values

The data manual of J6/J6 Eco recommends to set different IODELAY values
depending on the mode in which the MMC/SD is enumerated in order to
ensure IO timings are met.

Add support to set the IODELAY values depending on the various MMC
modes using the pinctrl APIs.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Kishon Vijay Abraham I and committed by
Ulf Hansson
8d20b2ea 7d33c358

+148
+148
drivers/mmc/host/sdhci-omap.c
··· 25 25 #include <linux/platform_device.h> 26 26 #include <linux/pm_runtime.h> 27 27 #include <linux/regulator/consumer.h> 28 + #include <linux/pinctrl/consumer.h> 28 29 29 30 #include "sdhci-pltfm.h" 30 31 ··· 91 90 92 91 #define MAX_PHASE_DELAY 0x7C 93 92 93 + /* sdhci-omap controller flags */ 94 + #define SDHCI_OMAP_REQUIRE_IODELAY BIT(0) 95 + 94 96 struct sdhci_omap_data { 95 97 u32 offset; 98 + u8 flags; 96 99 }; 97 100 98 101 struct sdhci_omap_host { ··· 107 102 struct sdhci_host *host; 108 103 u8 bus_mode; 109 104 u8 power_mode; 105 + u8 timing; 106 + u8 flags; 107 + 108 + struct pinctrl *pinctrl; 109 + struct pinctrl_state **pinctrl_state; 110 110 }; 111 + 112 + static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host); 113 + static void sdhci_omap_stop_clock(struct sdhci_omap_host *omap_host); 111 114 112 115 static inline u32 sdhci_omap_readl(struct sdhci_omap_host *host, 113 116 unsigned int offset) ··· 449 436 return 0; 450 437 } 451 438 439 + static void sdhci_omap_set_timing(struct sdhci_omap_host *omap_host, u8 timing) 440 + { 441 + int ret; 442 + struct pinctrl_state *pinctrl_state; 443 + struct device *dev = omap_host->dev; 444 + 445 + if (!(omap_host->flags & SDHCI_OMAP_REQUIRE_IODELAY)) 446 + return; 447 + 448 + if (omap_host->timing == timing) 449 + return; 450 + 451 + sdhci_omap_stop_clock(omap_host); 452 + 453 + pinctrl_state = omap_host->pinctrl_state[timing]; 454 + ret = pinctrl_select_state(omap_host->pinctrl, pinctrl_state); 455 + if (ret) { 456 + dev_err(dev, "failed to select pinctrl state\n"); 457 + return; 458 + } 459 + 460 + sdhci_omap_start_clock(omap_host); 461 + omap_host->timing = timing; 462 + } 463 + 452 464 static void sdhci_omap_set_power_mode(struct sdhci_omap_host *omap_host, 453 465 u8 power_mode) 454 466 { ··· 510 472 omap_host = sdhci_pltfm_priv(pltfm_host); 511 473 512 474 sdhci_omap_set_bus_mode(omap_host, ios->bus_mode); 475 + sdhci_omap_set_timing(omap_host, ios->timing); 513 476 sdhci_set_ios(mmc, ios); 514 477 sdhci_omap_set_power_mode(omap_host, ios->power_mode); 515 478 } ··· 719 680 720 681 static const struct sdhci_omap_data dra7_data = { 721 682 .offset = 0x200, 683 + .flags = SDHCI_OMAP_REQUIRE_IODELAY, 722 684 }; 723 685 724 686 static const struct of_device_id omap_sdhci_match[] = { ··· 727 687 {}, 728 688 }; 729 689 MODULE_DEVICE_TABLE(of, omap_sdhci_match); 690 + 691 + static struct pinctrl_state 692 + *sdhci_omap_iodelay_pinctrl_state(struct sdhci_omap_host *omap_host, char *mode, 693 + u32 *caps, u32 capmask) 694 + { 695 + struct device *dev = omap_host->dev; 696 + struct pinctrl_state *pinctrl_state = ERR_PTR(-ENODEV); 697 + 698 + if (!(*caps & capmask)) 699 + goto ret; 700 + 701 + pinctrl_state = pinctrl_lookup_state(omap_host->pinctrl, mode); 702 + if (IS_ERR(pinctrl_state)) { 703 + dev_err(dev, "no pinctrl state for %s mode", mode); 704 + *caps &= ~capmask; 705 + } 706 + 707 + ret: 708 + return pinctrl_state; 709 + } 710 + 711 + static int sdhci_omap_config_iodelay_pinctrl_state(struct sdhci_omap_host 712 + *omap_host) 713 + { 714 + struct device *dev = omap_host->dev; 715 + struct sdhci_host *host = omap_host->host; 716 + struct mmc_host *mmc = host->mmc; 717 + u32 *caps = &mmc->caps; 718 + u32 *caps2 = &mmc->caps2; 719 + struct pinctrl_state *state; 720 + struct pinctrl_state **pinctrl_state; 721 + 722 + if (!(omap_host->flags & SDHCI_OMAP_REQUIRE_IODELAY)) 723 + return 0; 724 + 725 + pinctrl_state = devm_kzalloc(dev, sizeof(*pinctrl_state) * 726 + (MMC_TIMING_MMC_HS200 + 1), GFP_KERNEL); 727 + if (!pinctrl_state) 728 + return -ENOMEM; 729 + 730 + omap_host->pinctrl = devm_pinctrl_get(omap_host->dev); 731 + if (IS_ERR(omap_host->pinctrl)) { 732 + dev_err(dev, "Cannot get pinctrl\n"); 733 + return PTR_ERR(omap_host->pinctrl); 734 + } 735 + 736 + state = pinctrl_lookup_state(omap_host->pinctrl, "default"); 737 + if (IS_ERR(state)) { 738 + dev_err(dev, "no pinctrl state for default mode\n"); 739 + return PTR_ERR(state); 740 + } 741 + pinctrl_state[MMC_TIMING_LEGACY] = state; 742 + 743 + state = sdhci_omap_iodelay_pinctrl_state(omap_host, "sdr104", caps, 744 + MMC_CAP_UHS_SDR104); 745 + if (!IS_ERR(state)) 746 + pinctrl_state[MMC_TIMING_UHS_SDR104] = state; 747 + 748 + state = sdhci_omap_iodelay_pinctrl_state(omap_host, "ddr50", caps, 749 + MMC_CAP_UHS_DDR50); 750 + if (!IS_ERR(state)) 751 + pinctrl_state[MMC_TIMING_UHS_DDR50] = state; 752 + 753 + state = sdhci_omap_iodelay_pinctrl_state(omap_host, "sdr50", caps, 754 + MMC_CAP_UHS_SDR50); 755 + if (!IS_ERR(state)) 756 + pinctrl_state[MMC_TIMING_UHS_SDR50] = state; 757 + 758 + state = sdhci_omap_iodelay_pinctrl_state(omap_host, "sdr25", caps, 759 + MMC_CAP_UHS_SDR25); 760 + if (!IS_ERR(state)) 761 + pinctrl_state[MMC_TIMING_UHS_SDR25] = state; 762 + 763 + state = sdhci_omap_iodelay_pinctrl_state(omap_host, "sdr12", caps, 764 + MMC_CAP_UHS_SDR12); 765 + if (!IS_ERR(state)) 766 + pinctrl_state[MMC_TIMING_UHS_SDR12] = state; 767 + 768 + state = sdhci_omap_iodelay_pinctrl_state(omap_host, "ddr_1_8v", caps, 769 + MMC_CAP_1_8V_DDR); 770 + if (!IS_ERR(state)) 771 + pinctrl_state[MMC_TIMING_MMC_DDR52] = state; 772 + 773 + state = sdhci_omap_iodelay_pinctrl_state(omap_host, "hs", caps, 774 + MMC_CAP_SD_HIGHSPEED); 775 + if (!IS_ERR(state)) 776 + pinctrl_state[MMC_TIMING_SD_HS] = state; 777 + 778 + state = sdhci_omap_iodelay_pinctrl_state(omap_host, "hs", caps, 779 + MMC_CAP_MMC_HIGHSPEED); 780 + if (!IS_ERR(state)) 781 + pinctrl_state[MMC_TIMING_MMC_HS] = state; 782 + 783 + state = sdhci_omap_iodelay_pinctrl_state(omap_host, "hs200_1_8v", caps2, 784 + MMC_CAP2_HS200_1_8V_SDR); 785 + if (!IS_ERR(state)) 786 + pinctrl_state[MMC_TIMING_MMC_HS200] = state; 787 + 788 + omap_host->pinctrl_state = pinctrl_state; 789 + 790 + return 0; 791 + } 730 792 731 793 static int sdhci_omap_probe(struct platform_device *pdev) 732 794 { ··· 866 724 omap_host->base = host->ioaddr; 867 725 omap_host->dev = dev; 868 726 omap_host->power_mode = MMC_POWER_UNDEFINED; 727 + omap_host->timing = MMC_TIMING_LEGACY; 728 + omap_host->flags = data->flags; 869 729 host->ioaddr += offset; 870 730 871 731 mmc = host->mmc; ··· 915 771 dev_err(dev, "failed to set system capabilities\n"); 916 772 goto err_put_sync; 917 773 } 774 + 775 + ret = sdhci_omap_config_iodelay_pinctrl_state(omap_host); 776 + if (ret) 777 + goto err_put_sync; 918 778 919 779 host->mmc_host_ops.get_ro = mmc_gpio_get_ro; 920 780 host->mmc_host_ops.start_signal_voltage_switch =