summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrabu Thangamuthu <Prabu.T@synopsys.com>2018-07-11 03:56:17 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2018-07-16 05:21:45 -0400
commit152f8204ffcd7b64aa6b36f39ee86fbce3f650b8 (patch)
treeb1d6f5626dd1d893313df540d1a1ba57dd3d3744
parenta6e7e407a68eee166c83e93c4ce8041aa00c2875 (diff)
mmc: sdhci-pci-dwc-mshc: synopsys dwc mshc support
Synopsys has DWC MSHC controller on HPAS-DX platform connected using PCIe interface with SD card slot and eMMC device slots. This patch is to enable SD cards connected on this platform. As Clock generation logic is implemented using MMCM module of HAPS-DX platform, we have separate functions to control the MMCM to generate required clocks with respect to speed mode. Signed-off-by: Prabu Thangamuthu <prabu.t@synopsys.com> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r--MAINTAINERS7
-rw-r--r--drivers/mmc/host/Makefile3
-rw-r--r--drivers/mmc/host/sdhci-pci-core.c1
-rw-r--r--drivers/mmc/host/sdhci-pci-dwc-mshc.c84
-rw-r--r--drivers/mmc/host/sdhci-pci.h3
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
12745F: drivers/mmc/host/sdhci* 12745F: drivers/mmc/host/sdhci*
12746F: include/linux/mmc/sdhci* 12746F: include/linux/mmc/sdhci*
12747 12747
12748SYNOPSYS SDHCI COMPLIANT DWC MSHC DRIVER
12749M: Prabu Thangamuthu <prabu.t@synopsys.com>
12750M: Manjunath M B <manjumb@synopsys.com>
12751L: linux-mmc@vger.kernel.org
12752S: Maintained
12753F: drivers/mmc/host/sdhci-pci-dwc-mshc.c
12754
12748SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) SAMSUNG DRIVER 12755SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) SAMSUNG DRIVER
12749M: Ben Dooks <ben-linux@fluff.org> 12756M: Ben Dooks <ben-linux@fluff.org>
12750M: Jaehoon Chung <jh80.chung@samsung.com> 12757M: 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
11obj-$(CONFIG_MMC_MXS) += mxs-mmc.o 11obj-$(CONFIG_MMC_MXS) += mxs-mmc.o
12obj-$(CONFIG_MMC_SDHCI) += sdhci.o 12obj-$(CONFIG_MMC_SDHCI) += sdhci.o
13obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o 13obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
14sdhci-pci-y += sdhci-pci-core.o sdhci-pci-o2micro.o sdhci-pci-arasan.o 14sdhci-pci-y += sdhci-pci-core.o sdhci-pci-o2micro.o sdhci-pci-arasan.o \
15 sdhci-pci-dwc-mshc.o
15obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-data.o 16obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-data.o
16obj-$(CONFIG_MMC_SDHCI_ACPI) += sdhci-acpi.o 17obj-$(CONFIG_MMC_SDHCI_ACPI) += sdhci-acpi.o
17obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o 18obj-$(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
31static 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
74static 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
82const 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
186extern const struct sdhci_pci_fixes sdhci_arasan; 188extern const struct sdhci_pci_fixes sdhci_arasan;
189extern const struct sdhci_pci_fixes sdhci_snps;
187 190
188#endif /* __SDHCI_PCI_H */ 191#endif /* __SDHCI_PCI_H */