diff options
-rw-r--r-- | MAINTAINERS | 7 | ||||
-rw-r--r-- | drivers/mmc/host/Makefile | 3 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pci-core.c | 1 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pci-dwc-mshc.c | 84 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pci.h | 3 |
5 files changed, 97 insertions, 1 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 192d7f73fd01..aa50f070b3b5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -12745,6 +12745,13 @@ S: Maintained | |||
12745 | F: drivers/mmc/host/sdhci* | 12745 | F: drivers/mmc/host/sdhci* |
12746 | F: include/linux/mmc/sdhci* | 12746 | F: include/linux/mmc/sdhci* |
12747 | 12747 | ||
12748 | SYNOPSYS SDHCI COMPLIANT DWC MSHC DRIVER | ||
12749 | M: Prabu Thangamuthu <prabu.t@synopsys.com> | ||
12750 | M: Manjunath M B <manjumb@synopsys.com> | ||
12751 | L: linux-mmc@vger.kernel.org | ||
12752 | S: Maintained | ||
12753 | F: drivers/mmc/host/sdhci-pci-dwc-mshc.c | ||
12754 | |||
12748 | SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) SAMSUNG DRIVER | 12755 | SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) SAMSUNG DRIVER |
12749 | M: Ben Dooks <ben-linux@fluff.org> | 12756 | M: Ben Dooks <ben-linux@fluff.org> |
12750 | M: Jaehoon Chung <jh80.chung@samsung.com> | 12757 | M: Jaehoon Chung <jh80.chung@samsung.com> |
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index a18fbba1b97e..ce8398e6f2c0 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
@@ -11,7 +11,8 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o | |||
11 | obj-$(CONFIG_MMC_MXS) += mxs-mmc.o | 11 | obj-$(CONFIG_MMC_MXS) += mxs-mmc.o |
12 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o | 12 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o |
13 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o | 13 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o |
14 | sdhci-pci-y += sdhci-pci-core.o sdhci-pci-o2micro.o sdhci-pci-arasan.o | 14 | sdhci-pci-y += sdhci-pci-core.o sdhci-pci-o2micro.o sdhci-pci-arasan.o \ |
15 | sdhci-pci-dwc-mshc.o | ||
15 | obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-data.o | 16 | obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-data.o |
16 | obj-$(CONFIG_MMC_SDHCI_ACPI) += sdhci-acpi.o | 17 | obj-$(CONFIG_MMC_SDHCI_ACPI) += sdhci-acpi.o |
17 | obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o | 18 | obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o |
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 3d367613275b..7bfd366d970d 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c | |||
@@ -1513,6 +1513,7 @@ static const struct pci_device_id pci_ids[] = { | |||
1513 | SDHCI_PCI_DEVICE(O2, SEABIRD0, o2), | 1513 | SDHCI_PCI_DEVICE(O2, SEABIRD0, o2), |
1514 | SDHCI_PCI_DEVICE(O2, SEABIRD1, o2), | 1514 | SDHCI_PCI_DEVICE(O2, SEABIRD1, o2), |
1515 | SDHCI_PCI_DEVICE(ARASAN, PHY_EMMC, arasan), | 1515 | SDHCI_PCI_DEVICE(ARASAN, PHY_EMMC, arasan), |
1516 | SDHCI_PCI_DEVICE(SYNOPSYS, DWC_MSHC, snps), | ||
1516 | SDHCI_PCI_DEVICE_CLASS(AMD, SYSTEM_SDHCI, PCI_CLASS_MASK, amd), | 1517 | SDHCI_PCI_DEVICE_CLASS(AMD, SYSTEM_SDHCI, PCI_CLASS_MASK, amd), |
1517 | /* Generic SD host controller */ | 1518 | /* Generic SD host controller */ |
1518 | {PCI_DEVICE_CLASS(SYSTEM_SDHCI, PCI_CLASS_MASK)}, | 1519 | {PCI_DEVICE_CLASS(SYSTEM_SDHCI, PCI_CLASS_MASK)}, |
diff --git a/drivers/mmc/host/sdhci-pci-dwc-mshc.c b/drivers/mmc/host/sdhci-pci-dwc-mshc.c new file mode 100644 index 000000000000..f78d65448d17 --- /dev/null +++ b/drivers/mmc/host/sdhci-pci-dwc-mshc.c | |||
@@ -0,0 +1,84 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * SDHCI driver for Synopsys DWC_MSHC controller | ||
4 | * | ||
5 | * Copyright (C) 2018 Synopsys, Inc. (www.synopsys.com) | ||
6 | * | ||
7 | * Authors: | ||
8 | * Prabu Thangamuthu <prabu.t@synopsys.com> | ||
9 | * Manjunath M B <manjumb@synopsys.com> | ||
10 | */ | ||
11 | |||
12 | #include "sdhci.h" | ||
13 | #include "sdhci-pci.h" | ||
14 | |||
15 | #define SDHCI_VENDOR_PTR_R 0xE8 | ||
16 | |||
17 | /* Synopsys vendor specific registers */ | ||
18 | #define SDHC_GPIO_OUT 0x34 | ||
19 | #define SDHC_AT_CTRL_R 0x40 | ||
20 | #define SDHC_SW_TUNE_EN 0x00000010 | ||
21 | |||
22 | /* MMCM DRP */ | ||
23 | #define SDHC_MMCM_DIV_REG 0x1020 | ||
24 | #define DIV_REG_100_MHZ 0x1145 | ||
25 | #define DIV_REG_200_MHZ 0x1083 | ||
26 | #define SDHC_MMCM_CLKFBOUT 0x1024 | ||
27 | #define CLKFBOUT_100_MHZ 0x0000 | ||
28 | #define CLKFBOUT_200_MHZ 0x0080 | ||
29 | #define SDHC_CCLK_MMCM_RST 0x00000001 | ||
30 | |||
31 | static void sdhci_snps_set_clock(struct sdhci_host *host, unsigned int clock) | ||
32 | { | ||
33 | u16 clk; | ||
34 | u32 reg, vendor_ptr; | ||
35 | |||
36 | vendor_ptr = sdhci_readw(host, SDHCI_VENDOR_PTR_R); | ||
37 | |||
38 | /* Disable software managed rx tuning */ | ||
39 | reg = sdhci_readl(host, (SDHC_AT_CTRL_R + vendor_ptr)); | ||
40 | reg &= ~SDHC_SW_TUNE_EN; | ||
41 | sdhci_writel(host, reg, (SDHC_AT_CTRL_R + vendor_ptr)); | ||
42 | |||
43 | if (clock <= 52000000) { | ||
44 | sdhci_set_clock(host, clock); | ||
45 | } else { | ||
46 | /* Assert reset to MMCM */ | ||
47 | reg = sdhci_readl(host, (SDHC_GPIO_OUT + vendor_ptr)); | ||
48 | reg |= SDHC_CCLK_MMCM_RST; | ||
49 | sdhci_writel(host, reg, (SDHC_GPIO_OUT + vendor_ptr)); | ||
50 | |||
51 | /* Configure MMCM */ | ||
52 | if (clock == 100000000) { | ||
53 | sdhci_writel(host, DIV_REG_100_MHZ, SDHC_MMCM_DIV_REG); | ||
54 | sdhci_writel(host, CLKFBOUT_100_MHZ, | ||
55 | SDHC_MMCM_CLKFBOUT); | ||
56 | } else { | ||
57 | sdhci_writel(host, DIV_REG_200_MHZ, SDHC_MMCM_DIV_REG); | ||
58 | sdhci_writel(host, CLKFBOUT_200_MHZ, | ||
59 | SDHC_MMCM_CLKFBOUT); | ||
60 | } | ||
61 | |||
62 | /* De-assert reset to MMCM */ | ||
63 | reg = sdhci_readl(host, (SDHC_GPIO_OUT + vendor_ptr)); | ||
64 | reg &= ~SDHC_CCLK_MMCM_RST; | ||
65 | sdhci_writel(host, reg, (SDHC_GPIO_OUT + vendor_ptr)); | ||
66 | |||
67 | /* Enable clock */ | ||
68 | clk = SDHCI_PROG_CLOCK_MODE | SDHCI_CLOCK_INT_EN | | ||
69 | SDHCI_CLOCK_CARD_EN; | ||
70 | sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); | ||
71 | } | ||
72 | } | ||
73 | |||
74 | static const struct sdhci_ops sdhci_snps_ops = { | ||
75 | .set_clock = sdhci_snps_set_clock, | ||
76 | .enable_dma = sdhci_pci_enable_dma, | ||
77 | .set_bus_width = sdhci_set_bus_width, | ||
78 | .reset = sdhci_reset, | ||
79 | .set_uhs_signaling = sdhci_set_uhs_signaling, | ||
80 | }; | ||
81 | |||
82 | const struct sdhci_pci_fixes sdhci_snps = { | ||
83 | .ops = &sdhci_snps_ops, | ||
84 | }; | ||
diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index 59af2886631f..2ef0bdca9197 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h | |||
@@ -61,6 +61,8 @@ | |||
61 | #define PCI_VENDOR_ID_ARASAN 0x16e6 | 61 | #define PCI_VENDOR_ID_ARASAN 0x16e6 |
62 | #define PCI_DEVICE_ID_ARASAN_PHY_EMMC 0x0670 | 62 | #define PCI_DEVICE_ID_ARASAN_PHY_EMMC 0x0670 |
63 | 63 | ||
64 | #define PCI_DEVICE_ID_SYNOPSYS_DWC_MSHC 0xc202 | ||
65 | |||
64 | /* | 66 | /* |
65 | * PCI device class and mask | 67 | * PCI device class and mask |
66 | */ | 68 | */ |
@@ -184,5 +186,6 @@ int sdhci_pci_o2_resume(struct sdhci_pci_chip *chip); | |||
184 | #endif | 186 | #endif |
185 | 187 | ||
186 | extern const struct sdhci_pci_fixes sdhci_arasan; | 188 | extern const struct sdhci_pci_fixes sdhci_arasan; |
189 | extern const struct sdhci_pci_fixes sdhci_snps; | ||
187 | 190 | ||
188 | #endif /* __SDHCI_PCI_H */ | 191 | #endif /* __SDHCI_PCI_H */ |