| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* linux/drivers/mmc/host/sdhci-pci.c - SDHCI on PCI bus interface |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved. |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 6 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 7 | | - * the Free Software Foundation; either version 2 of the License, or (at |
|---|
| 8 | | - * your option) any later version. |
|---|
| 9 | 5 | * |
|---|
| 10 | 6 | * Thanks to the following companies for their support: |
|---|
| 11 | 7 | * |
|---|
| .. | .. |
|---|
| 25 | 21 | #include <linux/mmc/mmc.h> |
|---|
| 26 | 22 | #include <linux/scatterlist.h> |
|---|
| 27 | 23 | #include <linux/io.h> |
|---|
| 24 | +#include <linux/iopoll.h> |
|---|
| 28 | 25 | #include <linux/gpio.h> |
|---|
| 29 | 26 | #include <linux/pm_runtime.h> |
|---|
| 27 | +#include <linux/pm_qos.h> |
|---|
| 28 | +#include <linux/debugfs.h> |
|---|
| 30 | 29 | #include <linux/mmc/slot-gpio.h> |
|---|
| 31 | 30 | #include <linux/mmc/sdhci-pci-data.h> |
|---|
| 32 | 31 | #include <linux/acpi.h> |
|---|
| 33 | 32 | #include <linux/dmi.h> |
|---|
| 33 | + |
|---|
| 34 | +#ifdef CONFIG_X86 |
|---|
| 35 | +#include <asm/iosf_mbi.h> |
|---|
| 36 | +#endif |
|---|
| 34 | 37 | |
|---|
| 35 | 38 | #include "cqhci.h" |
|---|
| 36 | 39 | |
|---|
| .. | .. |
|---|
| 168 | 171 | |
|---|
| 169 | 172 | err_pci_runtime_suspend: |
|---|
| 170 | 173 | while (--i >= 0) |
|---|
| 171 | | - sdhci_runtime_resume_host(chip->slots[i]->host); |
|---|
| 174 | + sdhci_runtime_resume_host(chip->slots[i]->host, 0); |
|---|
| 172 | 175 | return ret; |
|---|
| 173 | 176 | } |
|---|
| 174 | 177 | |
|---|
| .. | .. |
|---|
| 182 | 185 | if (!slot) |
|---|
| 183 | 186 | continue; |
|---|
| 184 | 187 | |
|---|
| 185 | | - ret = sdhci_runtime_resume_host(slot->host); |
|---|
| 188 | + ret = sdhci_runtime_resume_host(slot->host, 0); |
|---|
| 186 | 189 | if (ret) |
|---|
| 187 | 190 | return ret; |
|---|
| 188 | 191 | } |
|---|
| .. | .. |
|---|
| 231 | 234 | sdhci_dumpregs(mmc_priv(mmc)); |
|---|
| 232 | 235 | } |
|---|
| 233 | 236 | |
|---|
| 237 | +static void sdhci_cqhci_reset(struct sdhci_host *host, u8 mask) |
|---|
| 238 | +{ |
|---|
| 239 | + if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL) && |
|---|
| 240 | + host->mmc->cqe_private) |
|---|
| 241 | + cqhci_deactivate(host->mmc); |
|---|
| 242 | + sdhci_reset(host, mask); |
|---|
| 243 | +} |
|---|
| 244 | + |
|---|
| 234 | 245 | /*****************************************************************************\ |
|---|
| 235 | 246 | * * |
|---|
| 236 | 247 | * Hardware specific quirk handling * |
|---|
| .. | .. |
|---|
| 248 | 259 | static int ricoh_mmc_probe_slot(struct sdhci_pci_slot *slot) |
|---|
| 249 | 260 | { |
|---|
| 250 | 261 | slot->host->caps = |
|---|
| 251 | | - ((0x21 << SDHCI_TIMEOUT_CLK_SHIFT) |
|---|
| 252 | | - & SDHCI_TIMEOUT_CLK_MASK) | |
|---|
| 253 | | - |
|---|
| 254 | | - ((0x21 << SDHCI_CLOCK_BASE_SHIFT) |
|---|
| 255 | | - & SDHCI_CLOCK_BASE_MASK) | |
|---|
| 256 | | - |
|---|
| 262 | + FIELD_PREP(SDHCI_TIMEOUT_CLK_MASK, 0x21) | |
|---|
| 263 | + FIELD_PREP(SDHCI_CLOCK_BASE_MASK, 0x21) | |
|---|
| 257 | 264 | SDHCI_TIMEOUT_CLK_UNIT | |
|---|
| 258 | 265 | SDHCI_CAN_VDD_330 | |
|---|
| 259 | 266 | SDHCI_CAN_DO_HISPD | |
|---|
| .. | .. |
|---|
| 452 | 459 | .probe_slot = pch_hc_probe_slot, |
|---|
| 453 | 460 | }; |
|---|
| 454 | 461 | |
|---|
| 462 | +#ifdef CONFIG_X86 |
|---|
| 463 | + |
|---|
| 464 | +#define BYT_IOSF_SCCEP 0x63 |
|---|
| 465 | +#define BYT_IOSF_OCP_NETCTRL0 0x1078 |
|---|
| 466 | +#define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8) |
|---|
| 467 | + |
|---|
| 468 | +static void byt_ocp_setting(struct pci_dev *pdev) |
|---|
| 469 | +{ |
|---|
| 470 | + u32 val = 0; |
|---|
| 471 | + |
|---|
| 472 | + if (pdev->device != PCI_DEVICE_ID_INTEL_BYT_EMMC && |
|---|
| 473 | + pdev->device != PCI_DEVICE_ID_INTEL_BYT_SDIO && |
|---|
| 474 | + pdev->device != PCI_DEVICE_ID_INTEL_BYT_SD && |
|---|
| 475 | + pdev->device != PCI_DEVICE_ID_INTEL_BYT_EMMC2) |
|---|
| 476 | + return; |
|---|
| 477 | + |
|---|
| 478 | + if (iosf_mbi_read(BYT_IOSF_SCCEP, MBI_CR_READ, BYT_IOSF_OCP_NETCTRL0, |
|---|
| 479 | + &val)) { |
|---|
| 480 | + dev_err(&pdev->dev, "%s read error\n", __func__); |
|---|
| 481 | + return; |
|---|
| 482 | + } |
|---|
| 483 | + |
|---|
| 484 | + if (!(val & BYT_IOSF_OCP_TIMEOUT_BASE)) |
|---|
| 485 | + return; |
|---|
| 486 | + |
|---|
| 487 | + val &= ~BYT_IOSF_OCP_TIMEOUT_BASE; |
|---|
| 488 | + |
|---|
| 489 | + if (iosf_mbi_write(BYT_IOSF_SCCEP, MBI_CR_WRITE, BYT_IOSF_OCP_NETCTRL0, |
|---|
| 490 | + val)) { |
|---|
| 491 | + dev_err(&pdev->dev, "%s write error\n", __func__); |
|---|
| 492 | + return; |
|---|
| 493 | + } |
|---|
| 494 | + |
|---|
| 495 | + dev_dbg(&pdev->dev, "%s completed\n", __func__); |
|---|
| 496 | +} |
|---|
| 497 | + |
|---|
| 498 | +#else |
|---|
| 499 | + |
|---|
| 500 | +static inline void byt_ocp_setting(struct pci_dev *pdev) |
|---|
| 501 | +{ |
|---|
| 502 | +} |
|---|
| 503 | + |
|---|
| 504 | +#endif |
|---|
| 505 | + |
|---|
| 455 | 506 | enum { |
|---|
| 456 | 507 | INTEL_DSM_FNS = 0, |
|---|
| 457 | 508 | INTEL_DSM_V18_SWITCH = 3, |
|---|
| .. | .. |
|---|
| 468 | 519 | bool needs_pwr_off; |
|---|
| 469 | 520 | u32 glk_rx_ctrl1; |
|---|
| 470 | 521 | u32 glk_tun_val; |
|---|
| 522 | + u32 active_ltr; |
|---|
| 523 | + u32 idle_ltr; |
|---|
| 471 | 524 | }; |
|---|
| 472 | 525 | |
|---|
| 473 | 526 | static const guid_t intel_dsm_guid = |
|---|
| .. | .. |
|---|
| 629 | 682 | } |
|---|
| 630 | 683 | } |
|---|
| 631 | 684 | |
|---|
| 685 | +static void sdhci_intel_set_uhs_signaling(struct sdhci_host *host, |
|---|
| 686 | + unsigned int timing) |
|---|
| 687 | +{ |
|---|
| 688 | + /* Set UHS timing to SDR25 for High Speed mode */ |
|---|
| 689 | + if (timing == MMC_TIMING_MMC_HS || timing == MMC_TIMING_SD_HS) |
|---|
| 690 | + timing = MMC_TIMING_UHS_SDR25; |
|---|
| 691 | + sdhci_set_uhs_signaling(host, timing); |
|---|
| 692 | +} |
|---|
| 693 | + |
|---|
| 632 | 694 | #define INTEL_HS400_ES_REG 0x78 |
|---|
| 633 | 695 | #define INTEL_HS400_ES_BIT BIT(0) |
|---|
| 634 | 696 | |
|---|
| .. | .. |
|---|
| 685 | 747 | .enable_dma = sdhci_pci_enable_dma, |
|---|
| 686 | 748 | .set_bus_width = sdhci_set_bus_width, |
|---|
| 687 | 749 | .reset = sdhci_reset, |
|---|
| 688 | | - .set_uhs_signaling = sdhci_set_uhs_signaling, |
|---|
| 750 | + .set_uhs_signaling = sdhci_intel_set_uhs_signaling, |
|---|
| 689 | 751 | .hw_reset = sdhci_pci_hw_reset, |
|---|
| 690 | 752 | }; |
|---|
| 691 | 753 | |
|---|
| .. | .. |
|---|
| 694 | 756 | .set_power = sdhci_intel_set_power, |
|---|
| 695 | 757 | .enable_dma = sdhci_pci_enable_dma, |
|---|
| 696 | 758 | .set_bus_width = sdhci_set_bus_width, |
|---|
| 697 | | - .reset = sdhci_reset, |
|---|
| 698 | | - .set_uhs_signaling = sdhci_set_uhs_signaling, |
|---|
| 759 | + .reset = sdhci_cqhci_reset, |
|---|
| 760 | + .set_uhs_signaling = sdhci_intel_set_uhs_signaling, |
|---|
| 699 | 761 | .hw_reset = sdhci_pci_hw_reset, |
|---|
| 700 | 762 | .irq = sdhci_cqhci_irq, |
|---|
| 701 | 763 | }; |
|---|
| .. | .. |
|---|
| 728 | 790 | return 0; |
|---|
| 729 | 791 | } |
|---|
| 730 | 792 | |
|---|
| 793 | +#define INTEL_ACTIVELTR 0x804 |
|---|
| 794 | +#define INTEL_IDLELTR 0x808 |
|---|
| 795 | + |
|---|
| 796 | +#define INTEL_LTR_REQ BIT(15) |
|---|
| 797 | +#define INTEL_LTR_SCALE_MASK GENMASK(11, 10) |
|---|
| 798 | +#define INTEL_LTR_SCALE_1US (2 << 10) |
|---|
| 799 | +#define INTEL_LTR_SCALE_32US (3 << 10) |
|---|
| 800 | +#define INTEL_LTR_VALUE_MASK GENMASK(9, 0) |
|---|
| 801 | + |
|---|
| 802 | +static void intel_cache_ltr(struct sdhci_pci_slot *slot) |
|---|
| 803 | +{ |
|---|
| 804 | + struct intel_host *intel_host = sdhci_pci_priv(slot); |
|---|
| 805 | + struct sdhci_host *host = slot->host; |
|---|
| 806 | + |
|---|
| 807 | + intel_host->active_ltr = readl(host->ioaddr + INTEL_ACTIVELTR); |
|---|
| 808 | + intel_host->idle_ltr = readl(host->ioaddr + INTEL_IDLELTR); |
|---|
| 809 | +} |
|---|
| 810 | + |
|---|
| 811 | +static void intel_ltr_set(struct device *dev, s32 val) |
|---|
| 812 | +{ |
|---|
| 813 | + struct sdhci_pci_chip *chip = dev_get_drvdata(dev); |
|---|
| 814 | + struct sdhci_pci_slot *slot = chip->slots[0]; |
|---|
| 815 | + struct intel_host *intel_host = sdhci_pci_priv(slot); |
|---|
| 816 | + struct sdhci_host *host = slot->host; |
|---|
| 817 | + u32 ltr; |
|---|
| 818 | + |
|---|
| 819 | + pm_runtime_get_sync(dev); |
|---|
| 820 | + |
|---|
| 821 | + /* |
|---|
| 822 | + * Program latency tolerance (LTR) accordingly what has been asked |
|---|
| 823 | + * by the PM QoS layer or disable it in case we were passed |
|---|
| 824 | + * negative value or PM_QOS_LATENCY_ANY. |
|---|
| 825 | + */ |
|---|
| 826 | + ltr = readl(host->ioaddr + INTEL_ACTIVELTR); |
|---|
| 827 | + |
|---|
| 828 | + if (val == PM_QOS_LATENCY_ANY || val < 0) { |
|---|
| 829 | + ltr &= ~INTEL_LTR_REQ; |
|---|
| 830 | + } else { |
|---|
| 831 | + ltr |= INTEL_LTR_REQ; |
|---|
| 832 | + ltr &= ~INTEL_LTR_SCALE_MASK; |
|---|
| 833 | + ltr &= ~INTEL_LTR_VALUE_MASK; |
|---|
| 834 | + |
|---|
| 835 | + if (val > INTEL_LTR_VALUE_MASK) { |
|---|
| 836 | + val >>= 5; |
|---|
| 837 | + if (val > INTEL_LTR_VALUE_MASK) |
|---|
| 838 | + val = INTEL_LTR_VALUE_MASK; |
|---|
| 839 | + ltr |= INTEL_LTR_SCALE_32US | val; |
|---|
| 840 | + } else { |
|---|
| 841 | + ltr |= INTEL_LTR_SCALE_1US | val; |
|---|
| 842 | + } |
|---|
| 843 | + } |
|---|
| 844 | + |
|---|
| 845 | + if (ltr == intel_host->active_ltr) |
|---|
| 846 | + goto out; |
|---|
| 847 | + |
|---|
| 848 | + writel(ltr, host->ioaddr + INTEL_ACTIVELTR); |
|---|
| 849 | + writel(ltr, host->ioaddr + INTEL_IDLELTR); |
|---|
| 850 | + |
|---|
| 851 | + /* Cache the values into lpss structure */ |
|---|
| 852 | + intel_cache_ltr(slot); |
|---|
| 853 | +out: |
|---|
| 854 | + pm_runtime_put_autosuspend(dev); |
|---|
| 855 | +} |
|---|
| 856 | + |
|---|
| 857 | +static bool intel_use_ltr(struct sdhci_pci_chip *chip) |
|---|
| 858 | +{ |
|---|
| 859 | + switch (chip->pdev->device) { |
|---|
| 860 | + case PCI_DEVICE_ID_INTEL_BYT_EMMC: |
|---|
| 861 | + case PCI_DEVICE_ID_INTEL_BYT_EMMC2: |
|---|
| 862 | + case PCI_DEVICE_ID_INTEL_BYT_SDIO: |
|---|
| 863 | + case PCI_DEVICE_ID_INTEL_BYT_SD: |
|---|
| 864 | + case PCI_DEVICE_ID_INTEL_BSW_EMMC: |
|---|
| 865 | + case PCI_DEVICE_ID_INTEL_BSW_SDIO: |
|---|
| 866 | + case PCI_DEVICE_ID_INTEL_BSW_SD: |
|---|
| 867 | + return false; |
|---|
| 868 | + default: |
|---|
| 869 | + return true; |
|---|
| 870 | + } |
|---|
| 871 | +} |
|---|
| 872 | + |
|---|
| 873 | +static void intel_ltr_expose(struct sdhci_pci_chip *chip) |
|---|
| 874 | +{ |
|---|
| 875 | + struct device *dev = &chip->pdev->dev; |
|---|
| 876 | + |
|---|
| 877 | + if (!intel_use_ltr(chip)) |
|---|
| 878 | + return; |
|---|
| 879 | + |
|---|
| 880 | + dev->power.set_latency_tolerance = intel_ltr_set; |
|---|
| 881 | + dev_pm_qos_expose_latency_tolerance(dev); |
|---|
| 882 | +} |
|---|
| 883 | + |
|---|
| 884 | +static void intel_ltr_hide(struct sdhci_pci_chip *chip) |
|---|
| 885 | +{ |
|---|
| 886 | + struct device *dev = &chip->pdev->dev; |
|---|
| 887 | + |
|---|
| 888 | + if (!intel_use_ltr(chip)) |
|---|
| 889 | + return; |
|---|
| 890 | + |
|---|
| 891 | + dev_pm_qos_hide_latency_tolerance(dev); |
|---|
| 892 | + dev->power.set_latency_tolerance = NULL; |
|---|
| 893 | +} |
|---|
| 894 | + |
|---|
| 731 | 895 | static void byt_probe_slot(struct sdhci_pci_slot *slot) |
|---|
| 732 | 896 | { |
|---|
| 733 | 897 | struct mmc_host_ops *ops = &slot->host->mmc_host_ops; |
|---|
| 898 | + struct device *dev = &slot->chip->pdev->dev; |
|---|
| 899 | + struct mmc_host *mmc = slot->host->mmc; |
|---|
| 734 | 900 | |
|---|
| 735 | 901 | byt_read_dsm(slot); |
|---|
| 736 | 902 | |
|---|
| 903 | + byt_ocp_setting(slot->chip->pdev); |
|---|
| 904 | + |
|---|
| 737 | 905 | ops->execute_tuning = intel_execute_tuning; |
|---|
| 738 | 906 | ops->start_signal_voltage_switch = intel_start_signal_voltage_switch; |
|---|
| 907 | + |
|---|
| 908 | + device_property_read_u32(dev, "max-frequency", &mmc->f_max); |
|---|
| 909 | + |
|---|
| 910 | + if (!mmc->slotno) { |
|---|
| 911 | + slot->chip->slots[mmc->slotno] = slot; |
|---|
| 912 | + intel_ltr_expose(slot->chip); |
|---|
| 913 | + } |
|---|
| 914 | +} |
|---|
| 915 | + |
|---|
| 916 | +static void byt_add_debugfs(struct sdhci_pci_slot *slot) |
|---|
| 917 | +{ |
|---|
| 918 | + struct intel_host *intel_host = sdhci_pci_priv(slot); |
|---|
| 919 | + struct mmc_host *mmc = slot->host->mmc; |
|---|
| 920 | + struct dentry *dir = mmc->debugfs_root; |
|---|
| 921 | + |
|---|
| 922 | + if (!intel_use_ltr(slot->chip)) |
|---|
| 923 | + return; |
|---|
| 924 | + |
|---|
| 925 | + debugfs_create_x32("active_ltr", 0444, dir, &intel_host->active_ltr); |
|---|
| 926 | + debugfs_create_x32("idle_ltr", 0444, dir, &intel_host->idle_ltr); |
|---|
| 927 | + |
|---|
| 928 | + intel_cache_ltr(slot); |
|---|
| 929 | +} |
|---|
| 930 | + |
|---|
| 931 | +static int byt_add_host(struct sdhci_pci_slot *slot) |
|---|
| 932 | +{ |
|---|
| 933 | + int ret = sdhci_add_host(slot->host); |
|---|
| 934 | + |
|---|
| 935 | + if (!ret) |
|---|
| 936 | + byt_add_debugfs(slot); |
|---|
| 937 | + return ret; |
|---|
| 938 | +} |
|---|
| 939 | + |
|---|
| 940 | +static void byt_remove_slot(struct sdhci_pci_slot *slot, int dead) |
|---|
| 941 | +{ |
|---|
| 942 | + struct mmc_host *mmc = slot->host->mmc; |
|---|
| 943 | + |
|---|
| 944 | + if (!mmc->slotno) |
|---|
| 945 | + intel_ltr_hide(slot->chip); |
|---|
| 739 | 946 | } |
|---|
| 740 | 947 | |
|---|
| 741 | 948 | static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot) |
|---|
| .. | .. |
|---|
| 760 | 967 | dmi_match(DMI_SYS_VENDOR, "IRBIS")); |
|---|
| 761 | 968 | } |
|---|
| 762 | 969 | |
|---|
| 970 | +static bool jsl_broken_hs400es(struct sdhci_pci_slot *slot) |
|---|
| 971 | +{ |
|---|
| 972 | + return slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_JSL_EMMC && |
|---|
| 973 | + dmi_match(DMI_BIOS_VENDOR, "ASUSTeK COMPUTER INC."); |
|---|
| 974 | +} |
|---|
| 975 | + |
|---|
| 763 | 976 | static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot) |
|---|
| 764 | 977 | { |
|---|
| 765 | 978 | int ret = byt_emmc_probe_slot(slot); |
|---|
| .. | .. |
|---|
| 768 | 981 | slot->host->mmc->caps2 |= MMC_CAP2_CQE; |
|---|
| 769 | 982 | |
|---|
| 770 | 983 | if (slot->chip->pdev->device != PCI_DEVICE_ID_INTEL_GLK_EMMC) { |
|---|
| 771 | | - slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES, |
|---|
| 772 | | - slot->host->mmc_host_ops.hs400_enhanced_strobe = |
|---|
| 773 | | - intel_hs400_enhanced_strobe; |
|---|
| 984 | + if (!jsl_broken_hs400es(slot)) { |
|---|
| 985 | + slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES; |
|---|
| 986 | + slot->host->mmc_host_ops.hs400_enhanced_strobe = |
|---|
| 987 | + intel_hs400_enhanced_strobe; |
|---|
| 988 | + } |
|---|
| 774 | 989 | slot->host->mmc->caps2 |= MMC_CAP2_CQE_DCMD; |
|---|
| 775 | 990 | } |
|---|
| 776 | 991 | |
|---|
| .. | .. |
|---|
| 816 | 1031 | ret = __sdhci_add_host(host); |
|---|
| 817 | 1032 | if (ret) |
|---|
| 818 | 1033 | goto cleanup; |
|---|
| 1034 | + |
|---|
| 1035 | + byt_add_debugfs(slot); |
|---|
| 819 | 1036 | |
|---|
| 820 | 1037 | return 0; |
|---|
| 821 | 1038 | |
|---|
| .. | .. |
|---|
| 973 | 1190 | return 0; |
|---|
| 974 | 1191 | } |
|---|
| 975 | 1192 | |
|---|
| 1193 | +#ifdef CONFIG_PM_SLEEP |
|---|
| 1194 | + |
|---|
| 1195 | +static int byt_resume(struct sdhci_pci_chip *chip) |
|---|
| 1196 | +{ |
|---|
| 1197 | + byt_ocp_setting(chip->pdev); |
|---|
| 1198 | + |
|---|
| 1199 | + return sdhci_pci_resume_host(chip); |
|---|
| 1200 | +} |
|---|
| 1201 | + |
|---|
| 1202 | +#endif |
|---|
| 1203 | + |
|---|
| 1204 | +#ifdef CONFIG_PM |
|---|
| 1205 | + |
|---|
| 1206 | +static int byt_runtime_resume(struct sdhci_pci_chip *chip) |
|---|
| 1207 | +{ |
|---|
| 1208 | + byt_ocp_setting(chip->pdev); |
|---|
| 1209 | + |
|---|
| 1210 | + return sdhci_pci_runtime_resume_host(chip); |
|---|
| 1211 | +} |
|---|
| 1212 | + |
|---|
| 1213 | +#endif |
|---|
| 1214 | + |
|---|
| 976 | 1215 | static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = { |
|---|
| 1216 | +#ifdef CONFIG_PM_SLEEP |
|---|
| 1217 | + .resume = byt_resume, |
|---|
| 1218 | +#endif |
|---|
| 1219 | +#ifdef CONFIG_PM |
|---|
| 1220 | + .runtime_resume = byt_runtime_resume, |
|---|
| 1221 | +#endif |
|---|
| 977 | 1222 | .allow_runtime_pm = true, |
|---|
| 978 | 1223 | .probe_slot = byt_emmc_probe_slot, |
|---|
| 979 | | - .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
|---|
| 1224 | + .add_host = byt_add_host, |
|---|
| 1225 | + .remove_slot = byt_remove_slot, |
|---|
| 1226 | + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | |
|---|
| 1227 | + SDHCI_QUIRK_NO_LED, |
|---|
| 980 | 1228 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | |
|---|
| 981 | 1229 | SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 | |
|---|
| 982 | 1230 | SDHCI_QUIRK2_STOP_WITH_TC, |
|---|
| .. | .. |
|---|
| 988 | 1236 | .allow_runtime_pm = true, |
|---|
| 989 | 1237 | .probe_slot = glk_emmc_probe_slot, |
|---|
| 990 | 1238 | .add_host = glk_emmc_add_host, |
|---|
| 1239 | + .remove_slot = byt_remove_slot, |
|---|
| 991 | 1240 | #ifdef CONFIG_PM_SLEEP |
|---|
| 992 | 1241 | .suspend = sdhci_cqhci_suspend, |
|---|
| 993 | 1242 | .resume = sdhci_cqhci_resume, |
|---|
| .. | .. |
|---|
| 996 | 1245 | .runtime_suspend = glk_runtime_suspend, |
|---|
| 997 | 1246 | .runtime_resume = glk_runtime_resume, |
|---|
| 998 | 1247 | #endif |
|---|
| 999 | | - .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
|---|
| 1248 | + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | |
|---|
| 1249 | + SDHCI_QUIRK_NO_LED, |
|---|
| 1000 | 1250 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | |
|---|
| 1001 | 1251 | SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 | |
|---|
| 1002 | 1252 | SDHCI_QUIRK2_STOP_WITH_TC, |
|---|
| .. | .. |
|---|
| 1005 | 1255 | }; |
|---|
| 1006 | 1256 | |
|---|
| 1007 | 1257 | static const struct sdhci_pci_fixes sdhci_ni_byt_sdio = { |
|---|
| 1008 | | - .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
|---|
| 1258 | +#ifdef CONFIG_PM_SLEEP |
|---|
| 1259 | + .resume = byt_resume, |
|---|
| 1260 | +#endif |
|---|
| 1261 | +#ifdef CONFIG_PM |
|---|
| 1262 | + .runtime_resume = byt_runtime_resume, |
|---|
| 1263 | +#endif |
|---|
| 1264 | + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | |
|---|
| 1265 | + SDHCI_QUIRK_NO_LED, |
|---|
| 1009 | 1266 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON | |
|---|
| 1010 | 1267 | SDHCI_QUIRK2_PRESET_VALUE_BROKEN, |
|---|
| 1011 | 1268 | .allow_runtime_pm = true, |
|---|
| 1012 | 1269 | .probe_slot = ni_byt_sdio_probe_slot, |
|---|
| 1270 | + .add_host = byt_add_host, |
|---|
| 1271 | + .remove_slot = byt_remove_slot, |
|---|
| 1013 | 1272 | .ops = &sdhci_intel_byt_ops, |
|---|
| 1014 | 1273 | .priv_size = sizeof(struct intel_host), |
|---|
| 1015 | 1274 | }; |
|---|
| 1016 | 1275 | |
|---|
| 1017 | 1276 | static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = { |
|---|
| 1018 | | - .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
|---|
| 1277 | +#ifdef CONFIG_PM_SLEEP |
|---|
| 1278 | + .resume = byt_resume, |
|---|
| 1279 | +#endif |
|---|
| 1280 | +#ifdef CONFIG_PM |
|---|
| 1281 | + .runtime_resume = byt_runtime_resume, |
|---|
| 1282 | +#endif |
|---|
| 1283 | + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | |
|---|
| 1284 | + SDHCI_QUIRK_NO_LED, |
|---|
| 1019 | 1285 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON | |
|---|
| 1020 | 1286 | SDHCI_QUIRK2_PRESET_VALUE_BROKEN, |
|---|
| 1021 | 1287 | .allow_runtime_pm = true, |
|---|
| 1022 | 1288 | .probe_slot = byt_sdio_probe_slot, |
|---|
| 1289 | + .add_host = byt_add_host, |
|---|
| 1290 | + .remove_slot = byt_remove_slot, |
|---|
| 1023 | 1291 | .ops = &sdhci_intel_byt_ops, |
|---|
| 1024 | 1292 | .priv_size = sizeof(struct intel_host), |
|---|
| 1025 | 1293 | }; |
|---|
| 1026 | 1294 | |
|---|
| 1027 | 1295 | static const struct sdhci_pci_fixes sdhci_intel_byt_sd = { |
|---|
| 1028 | | - .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
|---|
| 1296 | +#ifdef CONFIG_PM_SLEEP |
|---|
| 1297 | + .resume = byt_resume, |
|---|
| 1298 | +#endif |
|---|
| 1299 | +#ifdef CONFIG_PM |
|---|
| 1300 | + .runtime_resume = byt_runtime_resume, |
|---|
| 1301 | +#endif |
|---|
| 1302 | + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | |
|---|
| 1303 | + SDHCI_QUIRK_NO_LED, |
|---|
| 1029 | 1304 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | |
|---|
| 1030 | 1305 | SDHCI_QUIRK2_PRESET_VALUE_BROKEN | |
|---|
| 1031 | 1306 | SDHCI_QUIRK2_STOP_WITH_TC, |
|---|
| 1032 | 1307 | .allow_runtime_pm = true, |
|---|
| 1033 | 1308 | .own_cd_for_runtime_pm = true, |
|---|
| 1034 | 1309 | .probe_slot = byt_sd_probe_slot, |
|---|
| 1310 | + .add_host = byt_add_host, |
|---|
| 1311 | + .remove_slot = byt_remove_slot, |
|---|
| 1035 | 1312 | .ops = &sdhci_intel_byt_ops, |
|---|
| 1036 | 1313 | .priv_size = sizeof(struct intel_host), |
|---|
| 1037 | 1314 | }; |
|---|
| .. | .. |
|---|
| 1287 | 1564 | } |
|---|
| 1288 | 1565 | #endif |
|---|
| 1289 | 1566 | |
|---|
| 1290 | | -static const struct sdhci_pci_fixes sdhci_o2 = { |
|---|
| 1291 | | - .probe = sdhci_pci_o2_probe, |
|---|
| 1292 | | - .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
|---|
| 1293 | | - .quirks2 = SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD, |
|---|
| 1294 | | - .probe_slot = sdhci_pci_o2_probe_slot, |
|---|
| 1295 | | -#ifdef CONFIG_PM_SLEEP |
|---|
| 1296 | | - .resume = sdhci_pci_o2_resume, |
|---|
| 1297 | | -#endif |
|---|
| 1298 | | -}; |
|---|
| 1299 | | - |
|---|
| 1300 | 1567 | static const struct sdhci_pci_fixes sdhci_jmicron = { |
|---|
| 1301 | 1568 | .probe = jmicron_probe, |
|---|
| 1302 | 1569 | |
|---|
| .. | .. |
|---|
| 1532 | 1799 | } |
|---|
| 1533 | 1800 | } |
|---|
| 1534 | 1801 | |
|---|
| 1802 | + pci_dev_put(smbus_dev); |
|---|
| 1803 | + |
|---|
| 1535 | 1804 | if (gen == AMD_CHIPSET_BEFORE_ML || gen == AMD_CHIPSET_CZ) |
|---|
| 1536 | 1805 | chip->quirks2 |= SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD; |
|---|
| 1537 | 1806 | |
|---|
| 1538 | 1807 | return 0; |
|---|
| 1539 | 1808 | } |
|---|
| 1540 | 1809 | |
|---|
| 1810 | +static u32 sdhci_read_present_state(struct sdhci_host *host) |
|---|
| 1811 | +{ |
|---|
| 1812 | + return sdhci_readl(host, SDHCI_PRESENT_STATE); |
|---|
| 1813 | +} |
|---|
| 1814 | + |
|---|
| 1815 | +static void amd_sdhci_reset(struct sdhci_host *host, u8 mask) |
|---|
| 1816 | +{ |
|---|
| 1817 | + struct sdhci_pci_slot *slot = sdhci_priv(host); |
|---|
| 1818 | + struct pci_dev *pdev = slot->chip->pdev; |
|---|
| 1819 | + u32 present_state; |
|---|
| 1820 | + |
|---|
| 1821 | + /* |
|---|
| 1822 | + * SDHC 0x7906 requires a hard reset to clear all internal state. |
|---|
| 1823 | + * Otherwise it can get into a bad state where the DATA lines are always |
|---|
| 1824 | + * read as zeros. |
|---|
| 1825 | + */ |
|---|
| 1826 | + if (pdev->device == 0x7906 && (mask & SDHCI_RESET_ALL)) { |
|---|
| 1827 | + pci_clear_master(pdev); |
|---|
| 1828 | + |
|---|
| 1829 | + pci_save_state(pdev); |
|---|
| 1830 | + |
|---|
| 1831 | + pci_set_power_state(pdev, PCI_D3cold); |
|---|
| 1832 | + pr_debug("%s: power_state=%u\n", mmc_hostname(host->mmc), |
|---|
| 1833 | + pdev->current_state); |
|---|
| 1834 | + pci_set_power_state(pdev, PCI_D0); |
|---|
| 1835 | + |
|---|
| 1836 | + pci_restore_state(pdev); |
|---|
| 1837 | + |
|---|
| 1838 | + /* |
|---|
| 1839 | + * SDHCI_RESET_ALL says the card detect logic should not be |
|---|
| 1840 | + * reset, but since we need to reset the entire controller |
|---|
| 1841 | + * we should wait until the card detect logic has stabilized. |
|---|
| 1842 | + * |
|---|
| 1843 | + * This normally takes about 40ms. |
|---|
| 1844 | + */ |
|---|
| 1845 | + readx_poll_timeout( |
|---|
| 1846 | + sdhci_read_present_state, |
|---|
| 1847 | + host, |
|---|
| 1848 | + present_state, |
|---|
| 1849 | + present_state & SDHCI_CD_STABLE, |
|---|
| 1850 | + 10000, |
|---|
| 1851 | + 100000 |
|---|
| 1852 | + ); |
|---|
| 1853 | + } |
|---|
| 1854 | + |
|---|
| 1855 | + return sdhci_reset(host, mask); |
|---|
| 1856 | +} |
|---|
| 1857 | + |
|---|
| 1541 | 1858 | static const struct sdhci_ops amd_sdhci_pci_ops = { |
|---|
| 1542 | 1859 | .set_clock = sdhci_set_clock, |
|---|
| 1543 | 1860 | .enable_dma = sdhci_pci_enable_dma, |
|---|
| 1544 | 1861 | .set_bus_width = sdhci_set_bus_width, |
|---|
| 1545 | | - .reset = sdhci_reset, |
|---|
| 1862 | + .reset = amd_sdhci_reset, |
|---|
| 1546 | 1863 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
|---|
| 1547 | 1864 | }; |
|---|
| 1548 | 1865 | |
|---|
| .. | .. |
|---|
| 1616 | 1933 | SDHCI_PCI_DEVICE(INTEL, CNPH_SD, intel_byt_sd), |
|---|
| 1617 | 1934 | SDHCI_PCI_DEVICE(INTEL, ICP_EMMC, intel_glk_emmc), |
|---|
| 1618 | 1935 | SDHCI_PCI_DEVICE(INTEL, ICP_SD, intel_byt_sd), |
|---|
| 1936 | + SDHCI_PCI_DEVICE(INTEL, EHL_EMMC, intel_glk_emmc), |
|---|
| 1937 | + SDHCI_PCI_DEVICE(INTEL, EHL_SD, intel_byt_sd), |
|---|
| 1619 | 1938 | SDHCI_PCI_DEVICE(INTEL, CML_EMMC, intel_glk_emmc), |
|---|
| 1620 | 1939 | SDHCI_PCI_DEVICE(INTEL, CML_SD, intel_byt_sd), |
|---|
| 1940 | + SDHCI_PCI_DEVICE(INTEL, CMLH_SD, intel_byt_sd), |
|---|
| 1941 | + SDHCI_PCI_DEVICE(INTEL, JSL_EMMC, intel_glk_emmc), |
|---|
| 1942 | + SDHCI_PCI_DEVICE(INTEL, JSL_SD, intel_byt_sd), |
|---|
| 1943 | + SDHCI_PCI_DEVICE(INTEL, LKF_EMMC, intel_glk_emmc), |
|---|
| 1944 | + SDHCI_PCI_DEVICE(INTEL, LKF_SD, intel_byt_sd), |
|---|
| 1945 | + SDHCI_PCI_DEVICE(INTEL, ADL_EMMC, intel_glk_emmc), |
|---|
| 1621 | 1946 | SDHCI_PCI_DEVICE(O2, 8120, o2), |
|---|
| 1622 | 1947 | SDHCI_PCI_DEVICE(O2, 8220, o2), |
|---|
| 1623 | 1948 | SDHCI_PCI_DEVICE(O2, 8221, o2), |
|---|
| .. | .. |
|---|
| 1630 | 1955 | SDHCI_PCI_DEVICE(O2, SEABIRD1, o2), |
|---|
| 1631 | 1956 | SDHCI_PCI_DEVICE(ARASAN, PHY_EMMC, arasan), |
|---|
| 1632 | 1957 | SDHCI_PCI_DEVICE(SYNOPSYS, DWC_MSHC, snps), |
|---|
| 1958 | + SDHCI_PCI_DEVICE(GLI, 9750, gl9750), |
|---|
| 1959 | + SDHCI_PCI_DEVICE(GLI, 9755, gl9755), |
|---|
| 1960 | + SDHCI_PCI_DEVICE(GLI, 9763E, gl9763e), |
|---|
| 1633 | 1961 | SDHCI_PCI_DEVICE_CLASS(AMD, SYSTEM_SDHCI, PCI_CLASS_MASK, amd), |
|---|
| 1634 | 1962 | /* Generic SD host controller */ |
|---|
| 1635 | 1963 | {PCI_DEVICE_CLASS(SYSTEM_SDHCI, PCI_CLASS_MASK)}, |
|---|
| .. | .. |
|---|
| 1705 | 2033 | #ifdef CONFIG_PM_SLEEP |
|---|
| 1706 | 2034 | static int sdhci_pci_suspend(struct device *dev) |
|---|
| 1707 | 2035 | { |
|---|
| 1708 | | - struct pci_dev *pdev = to_pci_dev(dev); |
|---|
| 1709 | | - struct sdhci_pci_chip *chip = pci_get_drvdata(pdev); |
|---|
| 2036 | + struct sdhci_pci_chip *chip = dev_get_drvdata(dev); |
|---|
| 1710 | 2037 | |
|---|
| 1711 | 2038 | if (!chip) |
|---|
| 1712 | 2039 | return 0; |
|---|
| .. | .. |
|---|
| 1719 | 2046 | |
|---|
| 1720 | 2047 | static int sdhci_pci_resume(struct device *dev) |
|---|
| 1721 | 2048 | { |
|---|
| 1722 | | - struct pci_dev *pdev = to_pci_dev(dev); |
|---|
| 1723 | | - struct sdhci_pci_chip *chip = pci_get_drvdata(pdev); |
|---|
| 2049 | + struct sdhci_pci_chip *chip = dev_get_drvdata(dev); |
|---|
| 1724 | 2050 | |
|---|
| 1725 | 2051 | if (!chip) |
|---|
| 1726 | 2052 | return 0; |
|---|
| .. | .. |
|---|
| 1735 | 2061 | #ifdef CONFIG_PM |
|---|
| 1736 | 2062 | static int sdhci_pci_runtime_suspend(struct device *dev) |
|---|
| 1737 | 2063 | { |
|---|
| 1738 | | - struct pci_dev *pdev = to_pci_dev(dev); |
|---|
| 1739 | | - struct sdhci_pci_chip *chip = pci_get_drvdata(pdev); |
|---|
| 2064 | + struct sdhci_pci_chip *chip = dev_get_drvdata(dev); |
|---|
| 1740 | 2065 | |
|---|
| 1741 | 2066 | if (!chip) |
|---|
| 1742 | 2067 | return 0; |
|---|
| .. | .. |
|---|
| 1749 | 2074 | |
|---|
| 1750 | 2075 | static int sdhci_pci_runtime_resume(struct device *dev) |
|---|
| 1751 | 2076 | { |
|---|
| 1752 | | - struct pci_dev *pdev = to_pci_dev(dev); |
|---|
| 1753 | | - struct sdhci_pci_chip *chip = pci_get_drvdata(pdev); |
|---|
| 2077 | + struct sdhci_pci_chip *chip = dev_get_drvdata(dev); |
|---|
| 1754 | 2078 | |
|---|
| 1755 | 2079 | if (!chip) |
|---|
| 1756 | 2080 | return 0; |
|---|
| .. | .. |
|---|
| 1879 | 2203 | |
|---|
| 1880 | 2204 | if (slot->cd_idx >= 0) { |
|---|
| 1881 | 2205 | ret = mmc_gpiod_request_cd(host->mmc, "cd", slot->cd_idx, |
|---|
| 1882 | | - slot->cd_override_level, 0, NULL); |
|---|
| 2206 | + slot->cd_override_level, 0); |
|---|
| 1883 | 2207 | if (ret && ret != -EPROBE_DEFER) |
|---|
| 1884 | 2208 | ret = mmc_gpiod_request_cd(host->mmc, NULL, |
|---|
| 1885 | 2209 | slot->cd_idx, |
|---|
| 1886 | 2210 | slot->cd_override_level, |
|---|
| 1887 | | - 0, NULL); |
|---|
| 2211 | + 0); |
|---|
| 1888 | 2212 | if (ret == -EPROBE_DEFER) |
|---|
| 1889 | 2213 | goto remove; |
|---|
| 1890 | 2214 | |
|---|
| .. | .. |
|---|
| 1988 | 2312 | |
|---|
| 1989 | 2313 | slots = PCI_SLOT_INFO_SLOTS(slots) + 1; |
|---|
| 1990 | 2314 | dev_dbg(&pdev->dev, "found %d slot(s)\n", slots); |
|---|
| 1991 | | - if (slots == 0) |
|---|
| 1992 | | - return -ENODEV; |
|---|
| 1993 | 2315 | |
|---|
| 1994 | 2316 | BUG_ON(slots > MAX_SLOTS); |
|---|
| 1995 | 2317 | |
|---|