kernel: bump 4.14 to 4.14.99
[openwrt/openwrt.git] / target / linux / layerscape / patches-4.14 / 819-sdhc-support-layerscape.patch
1 From f901f791d07deaeba6310ac070769575a0bb790a Mon Sep 17 00:00:00 2001
2 From: Biwen Li <biwen.li@nxp.com>
3 Date: Tue, 30 Oct 2018 18:27:54 +0800
4 Subject: [PATCH 36/40] sdhc: support layerscape
5 This is an integrated patch of sdhc for layerscape
6
7 Signed-off-by: Yinbo Zhu <yinbo.zhu@nxp.com>
8 Signed-off-by: Biwen Li <biwen.li@nxp.com>
9 ---
10 drivers/mmc/host/sdhci-of-esdhc.c | 85 +++++++++++++++++++++----------
11 1 file changed, 57 insertions(+), 28 deletions(-)
12
13 --- a/drivers/mmc/host/sdhci-of-esdhc.c
14 +++ b/drivers/mmc/host/sdhci-of-esdhc.c
15 @@ -30,11 +30,56 @@
16 #define VENDOR_V_22 0x12
17 #define VENDOR_V_23 0x13
18
19 +#define MMC_TIMING_NUM (MMC_TIMING_MMC_HS400 + 1)
20 +
21 +struct esdhc_clk_fixup {
22 + const unsigned int sd_dflt_max_clk;
23 + const unsigned int max_clk[MMC_TIMING_NUM];
24 +};
25 +
26 +static const struct esdhc_clk_fixup ls1021a_esdhc_clk = {
27 + .sd_dflt_max_clk = 25000000,
28 + .max_clk[MMC_TIMING_MMC_HS] = 46500000,
29 + .max_clk[MMC_TIMING_SD_HS] = 46500000,
30 +};
31 +
32 +static const struct esdhc_clk_fixup ls1046a_esdhc_clk = {
33 + .sd_dflt_max_clk = 25000000,
34 + .max_clk[MMC_TIMING_UHS_SDR104] = 167000000,
35 + .max_clk[MMC_TIMING_MMC_HS200] = 167000000,
36 +};
37 +
38 +static const struct esdhc_clk_fixup ls1012a_esdhc_clk = {
39 + .sd_dflt_max_clk = 25000000,
40 + .max_clk[MMC_TIMING_UHS_SDR104] = 125000000,
41 + .max_clk[MMC_TIMING_MMC_HS200] = 125000000,
42 +};
43 +
44 +static const struct esdhc_clk_fixup p1010_esdhc_clk = {
45 + .sd_dflt_max_clk = 20000000,
46 + .max_clk[MMC_TIMING_LEGACY] = 20000000,
47 + .max_clk[MMC_TIMING_MMC_HS] = 42000000,
48 + .max_clk[MMC_TIMING_SD_HS] = 40000000,
49 +};
50 +
51 +static const struct of_device_id sdhci_esdhc_of_match[] = {
52 + { .compatible = "fsl,ls1021a-esdhc", .data = &ls1021a_esdhc_clk},
53 + { .compatible = "fsl,ls1046a-esdhc", .data = &ls1046a_esdhc_clk},
54 + { .compatible = "fsl,ls1012a-esdhc", .data = &ls1012a_esdhc_clk},
55 + { .compatible = "fsl,p1010-esdhc", .data = &p1010_esdhc_clk},
56 + { .compatible = "fsl,mpc8379-esdhc" },
57 + { .compatible = "fsl,mpc8536-esdhc" },
58 + { .compatible = "fsl,esdhc" },
59 + { }
60 +};
61 +MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match);
62 +
63 struct sdhci_esdhc {
64 u8 vendor_ver;
65 u8 spec_ver;
66 bool quirk_incorrect_hostver;
67 unsigned int peripheral_clock;
68 + const struct esdhc_clk_fixup *clk_fixup;
69 };
70
71 /**
72 @@ -502,6 +547,7 @@ static void esdhc_of_set_clock(struct sd
73 int pre_div = 1;
74 int div = 1;
75 ktime_t timeout;
76 + long fixup = 0;
77 u32 temp;
78
79 host->mmc->actual_clock = 0;
80 @@ -515,27 +561,14 @@ static void esdhc_of_set_clock(struct sd
81 if (esdhc->vendor_ver < VENDOR_V_23)
82 pre_div = 2;
83
84 - /*
85 - * Limit SD clock to 167MHz for ls1046a according to its datasheet
86 - */
87 - if (clock > 167000000 &&
88 - of_find_compatible_node(NULL, NULL, "fsl,ls1046a-esdhc"))
89 - clock = 167000000;
90 + if (host->mmc->card && mmc_card_sd(host->mmc->card) &&
91 + esdhc->clk_fixup && host->mmc->ios.timing == MMC_TIMING_LEGACY)
92 + fixup = esdhc->clk_fixup->sd_dflt_max_clk;
93 + else if (esdhc->clk_fixup)
94 + fixup = esdhc->clk_fixup->max_clk[host->mmc->ios.timing];
95
96 - /*
97 - * Limit SD clock to 125MHz for ls1012a according to its datasheet
98 - */
99 - if (clock > 125000000 &&
100 - of_find_compatible_node(NULL, NULL, "fsl,ls1012a-esdhc"))
101 - clock = 125000000;
102 -
103 - /* Workaround to reduce the clock frequency for p1010 esdhc */
104 - if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
105 - if (clock > 20000000)
106 - clock -= 5000000;
107 - if (clock > 40000000)
108 - clock -= 5000000;
109 - }
110 + if (fixup && clock > fixup)
111 + clock = fixup;
112
113 temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
114 temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN |
115 @@ -797,6 +830,7 @@ static struct soc_device_attribute soc_i
116
117 static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
118 {
119 + const struct of_device_id *match;
120 struct sdhci_pltfm_host *pltfm_host;
121 struct sdhci_esdhc *esdhc;
122 struct device_node *np;
123 @@ -816,6 +850,9 @@ static void esdhc_init(struct platform_d
124 else
125 esdhc->quirk_incorrect_hostver = false;
126
127 + match = of_match_node(sdhci_esdhc_of_match, pdev->dev.of_node);
128 + if (match)
129 + esdhc->clk_fixup = match->data;
130 np = pdev->dev.of_node;
131 clk = of_clk_get(np, 0);
132 if (!IS_ERR(clk)) {
133 @@ -915,14 +952,6 @@ static int sdhci_esdhc_probe(struct plat
134 return ret;
135 }
136
137 -static const struct of_device_id sdhci_esdhc_of_match[] = {
138 - { .compatible = "fsl,mpc8379-esdhc" },
139 - { .compatible = "fsl,mpc8536-esdhc" },
140 - { .compatible = "fsl,esdhc" },
141 - { }
142 -};
143 -MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match);
144 -
145 static struct platform_driver sdhci_esdhc_driver = {
146 .driver = {
147 .name = "sdhci-esdhc",