blob: 97035d77c18c0f34371b1b8ad6f3866f9b661e02 [file] [log] [blame]
Ben Chuange51df6c2019-09-11 15:23:44 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2019 Genesys Logic, Inc.
4 *
5 * Authors: Ben Chuang <ben.chuang@genesyslogic.com.tw>
6 *
7 * Version: v0.9.0 (2019-08-08)
8 */
9
10#include <linux/bitfield.h>
11#include <linux/bits.h>
12#include <linux/pci.h>
13#include <linux/mmc/mmc.h>
14#include <linux/delay.h>
Hector Martin189f1d92021-12-16 01:10:44 +090015#include <linux/of.h>
Ben Chuange51df6c2019-09-11 15:23:44 +080016#include "sdhci.h"
17#include "sdhci-pci.h"
Ben Chuang347f6be2020-10-05 18:55:09 +080018#include "cqhci.h"
Ben Chuange51df6c2019-09-11 15:23:44 +080019
20/* Genesys Logic extra registers */
21#define SDHCI_GLI_9750_WT 0x800
22#define SDHCI_GLI_9750_WT_EN BIT(0)
23#define GLI_9750_WT_EN_ON 0x1
24#define GLI_9750_WT_EN_OFF 0x0
25
Ben Chuang9751bac2021-04-15 11:26:37 +080026#define SDHCI_GLI_9750_CFG2 0x848
27#define SDHCI_GLI_9750_CFG2_L1DLY GENMASK(28, 24)
28#define GLI_9750_CFG2_L1DLY_VALUE 0x1F
29
Ben Chuange51df6c2019-09-11 15:23:44 +080030#define SDHCI_GLI_9750_DRIVING 0x860
31#define SDHCI_GLI_9750_DRIVING_1 GENMASK(11, 0)
32#define SDHCI_GLI_9750_DRIVING_2 GENMASK(27, 26)
33#define GLI_9750_DRIVING_1_VALUE 0xFFF
34#define GLI_9750_DRIVING_2_VALUE 0x3
Ben Chuangb56ff192020-05-04 14:39:57 +080035#define SDHCI_GLI_9750_SEL_1 BIT(29)
36#define SDHCI_GLI_9750_SEL_2 BIT(31)
37#define SDHCI_GLI_9750_ALL_RST (BIT(24)|BIT(25)|BIT(28)|BIT(30))
Ben Chuange51df6c2019-09-11 15:23:44 +080038
39#define SDHCI_GLI_9750_PLL 0x864
Ben Chuang786d33c2020-07-17 11:33:50 +080040#define SDHCI_GLI_9750_PLL_LDIV GENMASK(9, 0)
41#define SDHCI_GLI_9750_PLL_PDIV GENMASK(14, 12)
42#define SDHCI_GLI_9750_PLL_DIR BIT(15)
Ben Chuange51df6c2019-09-11 15:23:44 +080043#define SDHCI_GLI_9750_PLL_TX2_INV BIT(23)
44#define SDHCI_GLI_9750_PLL_TX2_DLY GENMASK(22, 20)
45#define GLI_9750_PLL_TX2_INV_VALUE 0x1
46#define GLI_9750_PLL_TX2_DLY_VALUE 0x0
Ben Chuang786d33c2020-07-17 11:33:50 +080047#define SDHCI_GLI_9750_PLLSSC_STEP GENMASK(28, 24)
48#define SDHCI_GLI_9750_PLLSSC_EN BIT(31)
49
50#define SDHCI_GLI_9750_PLLSSC 0x86C
51#define SDHCI_GLI_9750_PLLSSC_PPM GENMASK(31, 16)
Ben Chuange51df6c2019-09-11 15:23:44 +080052
53#define SDHCI_GLI_9750_SW_CTRL 0x874
54#define SDHCI_GLI_9750_SW_CTRL_4 GENMASK(7, 6)
55#define GLI_9750_SW_CTRL_4_VALUE 0x3
56
57#define SDHCI_GLI_9750_MISC 0x878
58#define SDHCI_GLI_9750_MISC_TX1_INV BIT(2)
59#define SDHCI_GLI_9750_MISC_RX_INV BIT(3)
60#define SDHCI_GLI_9750_MISC_TX1_DLY GENMASK(6, 4)
61#define GLI_9750_MISC_TX1_INV_VALUE 0x0
62#define GLI_9750_MISC_RX_INV_ON 0x1
63#define GLI_9750_MISC_RX_INV_OFF 0x0
64#define GLI_9750_MISC_RX_INV_VALUE GLI_9750_MISC_RX_INV_OFF
65#define GLI_9750_MISC_TX1_DLY_VALUE 0x5
66
67#define SDHCI_GLI_9750_TUNING_CONTROL 0x540
68#define SDHCI_GLI_9750_TUNING_CONTROL_EN BIT(4)
69#define GLI_9750_TUNING_CONTROL_EN_ON 0x1
70#define GLI_9750_TUNING_CONTROL_EN_OFF 0x0
71#define SDHCI_GLI_9750_TUNING_CONTROL_GLITCH_1 BIT(16)
72#define SDHCI_GLI_9750_TUNING_CONTROL_GLITCH_2 GENMASK(20, 19)
73#define GLI_9750_TUNING_CONTROL_GLITCH_1_VALUE 0x1
74#define GLI_9750_TUNING_CONTROL_GLITCH_2_VALUE 0x2
75
76#define SDHCI_GLI_9750_TUNING_PARAMETERS 0x544
77#define SDHCI_GLI_9750_TUNING_PARAMETERS_RX_DLY GENMASK(2, 0)
78#define GLI_9750_TUNING_PARAMETERS_RX_DLY_VALUE 0x1
79
Ben Chuang1ae1d2d2020-05-08 14:41:54 +080080#define SDHCI_GLI_9763E_CTRL_HS400 0x7
81
82#define SDHCI_GLI_9763E_HS400_ES_REG 0x52C
83#define SDHCI_GLI_9763E_HS400_ES_BIT BIT(8)
84
85#define PCIE_GLI_9763E_VHS 0x884
86#define GLI_9763E_VHS_REV GENMASK(19, 16)
87#define GLI_9763E_VHS_REV_R 0x0
88#define GLI_9763E_VHS_REV_M 0x1
89#define GLI_9763E_VHS_REV_W 0x2
Ben Chuang347f6be2020-10-05 18:55:09 +080090#define PCIE_GLI_9763E_MB 0x888
91#define GLI_9763E_MB_CMDQ_OFF BIT(19)
Renius Chen15f908f2021-01-06 16:53:32 +080092#define GLI_9763E_MB_ERP_ON BIT(7)
Ben Chuang1ae1d2d2020-05-08 14:41:54 +080093#define PCIE_GLI_9763E_SCR 0x8E0
94#define GLI_9763E_SCR_AXI_REQ BIT(9)
95
Renius Chenedee82f2021-01-15 13:47:36 +080096#define PCIE_GLI_9763E_CFG2 0x8A4
97#define GLI_9763E_CFG2_L1DLY GENMASK(28, 19)
Ben Chuang34dd3cc2021-05-11 14:18:35 +080098#define GLI_9763E_CFG2_L1DLY_MID 0x54
Renius Chenedee82f2021-01-15 13:47:36 +080099
Ben Chuang98991b12020-11-25 19:01:45 +0800100#define PCIE_GLI_9763E_MMC_CTRL 0x960
101#define GLI_9763E_HS400_SLOW BIT(3)
102
Renius Chenc58c5952021-01-11 16:22:49 +0800103#define PCIE_GLI_9763E_CLKRXDLY 0x934
104#define GLI_9763E_HS400_RXDLY GENMASK(31, 28)
105#define GLI_9763E_HS400_RXDLY_5 0x5
106
Ben Chuang347f6be2020-10-05 18:55:09 +0800107#define SDHCI_GLI_9763E_CQE_BASE_ADDR 0x200
108#define GLI_9763E_CQE_TRNS_MODE (SDHCI_TRNS_MULTI | \
109 SDHCI_TRNS_BLK_CNT_EN | \
110 SDHCI_TRNS_DMA)
111
Ben Chuang786d33c2020-07-17 11:33:50 +0800112#define PCI_GLI_9755_WT 0x800
113#define PCI_GLI_9755_WT_EN BIT(0)
114#define GLI_9755_WT_EN_ON 0x1
115#define GLI_9755_WT_EN_OFF 0x0
116
Ben Chuang0f1d9962020-11-23 13:37:02 +0800117#define PCI_GLI_9755_PECONF 0x44
118#define PCI_GLI_9755_LFCLK GENMASK(14, 12)
119#define PCI_GLI_9755_DMACLK BIT(29)
Hector Martin189f1d92021-12-16 01:10:44 +0900120#define PCI_GLI_9755_INVERT_CD BIT(30)
121#define PCI_GLI_9755_INVERT_WP BIT(31)
Ben Chuang0f1d9962020-11-23 13:37:02 +0800122
Ben Chuang9751bac2021-04-15 11:26:37 +0800123#define PCI_GLI_9755_CFG2 0x48
124#define PCI_GLI_9755_CFG2_L1DLY GENMASK(28, 24)
125#define GLI_9755_CFG2_L1DLY_VALUE 0x1F
126
Ben Chuang786d33c2020-07-17 11:33:50 +0800127#define PCI_GLI_9755_PLL 0x64
128#define PCI_GLI_9755_PLL_LDIV GENMASK(9, 0)
129#define PCI_GLI_9755_PLL_PDIV GENMASK(14, 12)
130#define PCI_GLI_9755_PLL_DIR BIT(15)
131#define PCI_GLI_9755_PLLSSC_STEP GENMASK(28, 24)
132#define PCI_GLI_9755_PLLSSC_EN BIT(31)
133
134#define PCI_GLI_9755_PLLSSC 0x68
135#define PCI_GLI_9755_PLLSSC_PPM GENMASK(15, 0)
136
Renius Chenf46b54c2021-02-25 19:13:07 +0800137#define PCI_GLI_9755_SerDes 0x70
138#define PCI_GLI_9755_SCP_DIS BIT(19)
139
Ben Chuange51df6c2019-09-11 15:23:44 +0800140#define GLI_MAX_TUNING_LOOP 40
141
142/* Genesys Logic chipset */
143static inline void gl9750_wt_on(struct sdhci_host *host)
144{
145 u32 wt_value;
146 u32 wt_enable;
147
148 wt_value = sdhci_readl(host, SDHCI_GLI_9750_WT);
149 wt_enable = FIELD_GET(SDHCI_GLI_9750_WT_EN, wt_value);
150
151 if (wt_enable == GLI_9750_WT_EN_ON)
152 return;
153
154 wt_value &= ~SDHCI_GLI_9750_WT_EN;
155 wt_value |= FIELD_PREP(SDHCI_GLI_9750_WT_EN, GLI_9750_WT_EN_ON);
156
157 sdhci_writel(host, wt_value, SDHCI_GLI_9750_WT);
158}
159
160static inline void gl9750_wt_off(struct sdhci_host *host)
161{
162 u32 wt_value;
163 u32 wt_enable;
164
165 wt_value = sdhci_readl(host, SDHCI_GLI_9750_WT);
166 wt_enable = FIELD_GET(SDHCI_GLI_9750_WT_EN, wt_value);
167
168 if (wt_enable == GLI_9750_WT_EN_OFF)
169 return;
170
171 wt_value &= ~SDHCI_GLI_9750_WT_EN;
172 wt_value |= FIELD_PREP(SDHCI_GLI_9750_WT_EN, GLI_9750_WT_EN_OFF);
173
174 sdhci_writel(host, wt_value, SDHCI_GLI_9750_WT);
175}
176
177static void gli_set_9750(struct sdhci_host *host)
178{
179 u32 driving_value;
180 u32 pll_value;
181 u32 sw_ctrl_value;
182 u32 misc_value;
183 u32 parameter_value;
184 u32 control_value;
185 u16 ctrl2;
186
187 gl9750_wt_on(host);
188
189 driving_value = sdhci_readl(host, SDHCI_GLI_9750_DRIVING);
190 pll_value = sdhci_readl(host, SDHCI_GLI_9750_PLL);
191 sw_ctrl_value = sdhci_readl(host, SDHCI_GLI_9750_SW_CTRL);
192 misc_value = sdhci_readl(host, SDHCI_GLI_9750_MISC);
193 parameter_value = sdhci_readl(host, SDHCI_GLI_9750_TUNING_PARAMETERS);
194 control_value = sdhci_readl(host, SDHCI_GLI_9750_TUNING_CONTROL);
195
196 driving_value &= ~(SDHCI_GLI_9750_DRIVING_1);
197 driving_value &= ~(SDHCI_GLI_9750_DRIVING_2);
198 driving_value |= FIELD_PREP(SDHCI_GLI_9750_DRIVING_1,
199 GLI_9750_DRIVING_1_VALUE);
200 driving_value |= FIELD_PREP(SDHCI_GLI_9750_DRIVING_2,
201 GLI_9750_DRIVING_2_VALUE);
Ben Chuangb56ff192020-05-04 14:39:57 +0800202 driving_value &= ~(SDHCI_GLI_9750_SEL_1|SDHCI_GLI_9750_SEL_2|SDHCI_GLI_9750_ALL_RST);
203 driving_value |= SDHCI_GLI_9750_SEL_2;
Ben Chuange51df6c2019-09-11 15:23:44 +0800204 sdhci_writel(host, driving_value, SDHCI_GLI_9750_DRIVING);
205
206 sw_ctrl_value &= ~SDHCI_GLI_9750_SW_CTRL_4;
207 sw_ctrl_value |= FIELD_PREP(SDHCI_GLI_9750_SW_CTRL_4,
208 GLI_9750_SW_CTRL_4_VALUE);
209 sdhci_writel(host, sw_ctrl_value, SDHCI_GLI_9750_SW_CTRL);
210
211 /* reset the tuning flow after reinit and before starting tuning */
212 pll_value &= ~SDHCI_GLI_9750_PLL_TX2_INV;
213 pll_value &= ~SDHCI_GLI_9750_PLL_TX2_DLY;
214 pll_value |= FIELD_PREP(SDHCI_GLI_9750_PLL_TX2_INV,
215 GLI_9750_PLL_TX2_INV_VALUE);
216 pll_value |= FIELD_PREP(SDHCI_GLI_9750_PLL_TX2_DLY,
217 GLI_9750_PLL_TX2_DLY_VALUE);
218
219 misc_value &= ~SDHCI_GLI_9750_MISC_TX1_INV;
220 misc_value &= ~SDHCI_GLI_9750_MISC_RX_INV;
221 misc_value &= ~SDHCI_GLI_9750_MISC_TX1_DLY;
222 misc_value |= FIELD_PREP(SDHCI_GLI_9750_MISC_TX1_INV,
223 GLI_9750_MISC_TX1_INV_VALUE);
224 misc_value |= FIELD_PREP(SDHCI_GLI_9750_MISC_RX_INV,
225 GLI_9750_MISC_RX_INV_VALUE);
226 misc_value |= FIELD_PREP(SDHCI_GLI_9750_MISC_TX1_DLY,
227 GLI_9750_MISC_TX1_DLY_VALUE);
228
229 parameter_value &= ~SDHCI_GLI_9750_TUNING_PARAMETERS_RX_DLY;
230 parameter_value |= FIELD_PREP(SDHCI_GLI_9750_TUNING_PARAMETERS_RX_DLY,
231 GLI_9750_TUNING_PARAMETERS_RX_DLY_VALUE);
232
233 control_value &= ~SDHCI_GLI_9750_TUNING_CONTROL_GLITCH_1;
234 control_value &= ~SDHCI_GLI_9750_TUNING_CONTROL_GLITCH_2;
235 control_value |= FIELD_PREP(SDHCI_GLI_9750_TUNING_CONTROL_GLITCH_1,
236 GLI_9750_TUNING_CONTROL_GLITCH_1_VALUE);
237 control_value |= FIELD_PREP(SDHCI_GLI_9750_TUNING_CONTROL_GLITCH_2,
238 GLI_9750_TUNING_CONTROL_GLITCH_2_VALUE);
239
240 sdhci_writel(host, pll_value, SDHCI_GLI_9750_PLL);
241 sdhci_writel(host, misc_value, SDHCI_GLI_9750_MISC);
242
243 /* disable tuned clk */
244 ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
245 ctrl2 &= ~SDHCI_CTRL_TUNED_CLK;
246 sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2);
247
248 /* enable tuning parameters control */
249 control_value &= ~SDHCI_GLI_9750_TUNING_CONTROL_EN;
250 control_value |= FIELD_PREP(SDHCI_GLI_9750_TUNING_CONTROL_EN,
251 GLI_9750_TUNING_CONTROL_EN_ON);
252 sdhci_writel(host, control_value, SDHCI_GLI_9750_TUNING_CONTROL);
253
254 /* write tuning parameters */
255 sdhci_writel(host, parameter_value, SDHCI_GLI_9750_TUNING_PARAMETERS);
256
257 /* disable tuning parameters control */
258 control_value &= ~SDHCI_GLI_9750_TUNING_CONTROL_EN;
259 control_value |= FIELD_PREP(SDHCI_GLI_9750_TUNING_CONTROL_EN,
260 GLI_9750_TUNING_CONTROL_EN_OFF);
261 sdhci_writel(host, control_value, SDHCI_GLI_9750_TUNING_CONTROL);
262
263 /* clear tuned clk */
264 ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
265 ctrl2 &= ~SDHCI_CTRL_TUNED_CLK;
266 sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2);
267
268 gl9750_wt_off(host);
269}
270
271static void gli_set_9750_rx_inv(struct sdhci_host *host, bool b)
272{
273 u32 misc_value;
274
275 gl9750_wt_on(host);
276
277 misc_value = sdhci_readl(host, SDHCI_GLI_9750_MISC);
278 misc_value &= ~SDHCI_GLI_9750_MISC_RX_INV;
279 if (b) {
280 misc_value |= FIELD_PREP(SDHCI_GLI_9750_MISC_RX_INV,
281 GLI_9750_MISC_RX_INV_ON);
282 } else {
283 misc_value |= FIELD_PREP(SDHCI_GLI_9750_MISC_RX_INV,
284 GLI_9750_MISC_RX_INV_OFF);
285 }
286 sdhci_writel(host, misc_value, SDHCI_GLI_9750_MISC);
287
288 gl9750_wt_off(host);
289}
290
291static int __sdhci_execute_tuning_9750(struct sdhci_host *host, u32 opcode)
292{
293 int i;
294 int rx_inv;
295
296 for (rx_inv = 0; rx_inv < 2; rx_inv++) {
297 gli_set_9750_rx_inv(host, !!rx_inv);
298 sdhci_start_tuning(host);
299
300 for (i = 0; i < GLI_MAX_TUNING_LOOP; i++) {
301 u16 ctrl;
302
303 sdhci_send_tuning(host, opcode);
304
305 if (!host->tuning_done) {
306 sdhci_abort_tuning(host, opcode);
307 break;
308 }
309
310 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
311 if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) {
312 if (ctrl & SDHCI_CTRL_TUNED_CLK)
313 return 0; /* Success! */
314 break;
315 }
316 }
317 }
318 if (!host->tuning_done) {
319 pr_info("%s: Tuning timeout, falling back to fixed sampling clock\n",
320 mmc_hostname(host->mmc));
321 return -ETIMEDOUT;
322 }
323
324 pr_info("%s: Tuning failed, falling back to fixed sampling clock\n",
325 mmc_hostname(host->mmc));
326 sdhci_reset_tuning(host);
327
328 return -EAGAIN;
329}
330
331static int gl9750_execute_tuning(struct sdhci_host *host, u32 opcode)
332{
333 host->mmc->retune_period = 0;
334 if (host->tuning_mode == SDHCI_TUNING_MODE_1)
335 host->mmc->retune_period = host->tuning_count;
336
337 gli_set_9750(host);
338 host->tuning_err = __sdhci_execute_tuning_9750(host, opcode);
339 sdhci_end_tuning(host);
340
341 return 0;
342}
343
Ben Chuang786d33c2020-07-17 11:33:50 +0800344static void gl9750_disable_ssc_pll(struct sdhci_host *host)
345{
346 u32 pll;
347
348 gl9750_wt_on(host);
349 pll = sdhci_readl(host, SDHCI_GLI_9750_PLL);
350 pll &= ~(SDHCI_GLI_9750_PLL_DIR | SDHCI_GLI_9750_PLLSSC_EN);
351 sdhci_writel(host, pll, SDHCI_GLI_9750_PLL);
352 gl9750_wt_off(host);
353}
354
355static void gl9750_set_pll(struct sdhci_host *host, u8 dir, u16 ldiv, u8 pdiv)
356{
357 u32 pll;
358
359 gl9750_wt_on(host);
360 pll = sdhci_readl(host, SDHCI_GLI_9750_PLL);
361 pll &= ~(SDHCI_GLI_9750_PLL_LDIV |
362 SDHCI_GLI_9750_PLL_PDIV |
363 SDHCI_GLI_9750_PLL_DIR);
364 pll |= FIELD_PREP(SDHCI_GLI_9750_PLL_LDIV, ldiv) |
365 FIELD_PREP(SDHCI_GLI_9750_PLL_PDIV, pdiv) |
366 FIELD_PREP(SDHCI_GLI_9750_PLL_DIR, dir);
367 sdhci_writel(host, pll, SDHCI_GLI_9750_PLL);
368 gl9750_wt_off(host);
369
370 /* wait for pll stable */
371 mdelay(1);
372}
373
374static void gl9750_set_ssc(struct sdhci_host *host, u8 enable, u8 step, u16 ppm)
375{
376 u32 pll;
377 u32 ssc;
378
379 gl9750_wt_on(host);
380 pll = sdhci_readl(host, SDHCI_GLI_9750_PLL);
381 ssc = sdhci_readl(host, SDHCI_GLI_9750_PLLSSC);
382 pll &= ~(SDHCI_GLI_9750_PLLSSC_STEP |
383 SDHCI_GLI_9750_PLLSSC_EN);
384 ssc &= ~SDHCI_GLI_9750_PLLSSC_PPM;
385 pll |= FIELD_PREP(SDHCI_GLI_9750_PLLSSC_STEP, step) |
386 FIELD_PREP(SDHCI_GLI_9750_PLLSSC_EN, enable);
387 ssc |= FIELD_PREP(SDHCI_GLI_9750_PLLSSC_PPM, ppm);
388 sdhci_writel(host, ssc, SDHCI_GLI_9750_PLLSSC);
389 sdhci_writel(host, pll, SDHCI_GLI_9750_PLL);
390 gl9750_wt_off(host);
391}
392
393static void gl9750_set_ssc_pll_205mhz(struct sdhci_host *host)
394{
395 /* set pll to 205MHz and enable ssc */
396 gl9750_set_ssc(host, 0x1, 0x1F, 0xFFE7);
397 gl9750_set_pll(host, 0x1, 0x246, 0x0);
398}
399
400static void sdhci_gl9750_set_clock(struct sdhci_host *host, unsigned int clock)
401{
402 struct mmc_ios *ios = &host->mmc->ios;
403 u16 clk;
404
405 host->mmc->actual_clock = 0;
406
407 gl9750_disable_ssc_pll(host);
408 sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
409
410 if (clock == 0)
411 return;
412
413 clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);
414 if (clock == 200000000 && ios->timing == MMC_TIMING_UHS_SDR104) {
415 host->mmc->actual_clock = 205000000;
416 gl9750_set_ssc_pll_205mhz(host);
417 }
418
419 sdhci_enable_clk(host, clk);
420}
421
Ben Chuang9751bac2021-04-15 11:26:37 +0800422static void gl9750_hw_setting(struct sdhci_host *host)
423{
424 u32 value;
425
426 gl9750_wt_on(host);
427
428 value = sdhci_readl(host, SDHCI_GLI_9750_CFG2);
429 value &= ~SDHCI_GLI_9750_CFG2_L1DLY;
430 /* set ASPM L1 entry delay to 7.9us */
431 value |= FIELD_PREP(SDHCI_GLI_9750_CFG2_L1DLY,
432 GLI_9750_CFG2_L1DLY_VALUE);
433 sdhci_writel(host, value, SDHCI_GLI_9750_CFG2);
434
435 gl9750_wt_off(host);
436}
437
Ben Chuang31e43f32020-02-19 17:29:00 +0800438static void gli_pcie_enable_msi(struct sdhci_pci_slot *slot)
439{
440 int ret;
441
442 ret = pci_alloc_irq_vectors(slot->chip->pdev, 1, 1,
443 PCI_IRQ_MSI | PCI_IRQ_MSIX);
444 if (ret < 0) {
445 pr_warn("%s: enable PCI MSI failed, error=%d\n",
446 mmc_hostname(slot->host->mmc), ret);
447 return;
448 }
449
450 slot->host->irq = pci_irq_vector(slot->chip->pdev, 0);
451}
452
Ben Chuang786d33c2020-07-17 11:33:50 +0800453static inline void gl9755_wt_on(struct pci_dev *pdev)
454{
455 u32 wt_value;
456 u32 wt_enable;
457
458 pci_read_config_dword(pdev, PCI_GLI_9755_WT, &wt_value);
459 wt_enable = FIELD_GET(PCI_GLI_9755_WT_EN, wt_value);
460
461 if (wt_enable == GLI_9755_WT_EN_ON)
462 return;
463
464 wt_value &= ~PCI_GLI_9755_WT_EN;
465 wt_value |= FIELD_PREP(PCI_GLI_9755_WT_EN, GLI_9755_WT_EN_ON);
466
467 pci_write_config_dword(pdev, PCI_GLI_9755_WT, wt_value);
468}
469
470static inline void gl9755_wt_off(struct pci_dev *pdev)
471{
472 u32 wt_value;
473 u32 wt_enable;
474
475 pci_read_config_dword(pdev, PCI_GLI_9755_WT, &wt_value);
476 wt_enable = FIELD_GET(PCI_GLI_9755_WT_EN, wt_value);
477
478 if (wt_enable == GLI_9755_WT_EN_OFF)
479 return;
480
481 wt_value &= ~PCI_GLI_9755_WT_EN;
482 wt_value |= FIELD_PREP(PCI_GLI_9755_WT_EN, GLI_9755_WT_EN_OFF);
483
484 pci_write_config_dword(pdev, PCI_GLI_9755_WT, wt_value);
485}
486
487static void gl9755_disable_ssc_pll(struct pci_dev *pdev)
488{
489 u32 pll;
490
491 gl9755_wt_on(pdev);
492 pci_read_config_dword(pdev, PCI_GLI_9755_PLL, &pll);
493 pll &= ~(PCI_GLI_9755_PLL_DIR | PCI_GLI_9755_PLLSSC_EN);
494 pci_write_config_dword(pdev, PCI_GLI_9755_PLL, pll);
495 gl9755_wt_off(pdev);
496}
497
498static void gl9755_set_pll(struct pci_dev *pdev, u8 dir, u16 ldiv, u8 pdiv)
499{
500 u32 pll;
501
502 gl9755_wt_on(pdev);
503 pci_read_config_dword(pdev, PCI_GLI_9755_PLL, &pll);
504 pll &= ~(PCI_GLI_9755_PLL_LDIV |
505 PCI_GLI_9755_PLL_PDIV |
506 PCI_GLI_9755_PLL_DIR);
507 pll |= FIELD_PREP(PCI_GLI_9755_PLL_LDIV, ldiv) |
508 FIELD_PREP(PCI_GLI_9755_PLL_PDIV, pdiv) |
509 FIELD_PREP(PCI_GLI_9755_PLL_DIR, dir);
510 pci_write_config_dword(pdev, PCI_GLI_9755_PLL, pll);
511 gl9755_wt_off(pdev);
512
513 /* wait for pll stable */
514 mdelay(1);
515}
516
517static void gl9755_set_ssc(struct pci_dev *pdev, u8 enable, u8 step, u16 ppm)
518{
519 u32 pll;
520 u32 ssc;
521
522 gl9755_wt_on(pdev);
523 pci_read_config_dword(pdev, PCI_GLI_9755_PLL, &pll);
524 pci_read_config_dword(pdev, PCI_GLI_9755_PLLSSC, &ssc);
525 pll &= ~(PCI_GLI_9755_PLLSSC_STEP |
526 PCI_GLI_9755_PLLSSC_EN);
527 ssc &= ~PCI_GLI_9755_PLLSSC_PPM;
528 pll |= FIELD_PREP(PCI_GLI_9755_PLLSSC_STEP, step) |
529 FIELD_PREP(PCI_GLI_9755_PLLSSC_EN, enable);
530 ssc |= FIELD_PREP(PCI_GLI_9755_PLLSSC_PPM, ppm);
531 pci_write_config_dword(pdev, PCI_GLI_9755_PLLSSC, ssc);
532 pci_write_config_dword(pdev, PCI_GLI_9755_PLL, pll);
533 gl9755_wt_off(pdev);
534}
535
536static void gl9755_set_ssc_pll_205mhz(struct pci_dev *pdev)
537{
538 /* set pll to 205MHz and enable ssc */
539 gl9755_set_ssc(pdev, 0x1, 0x1F, 0xFFE7);
540 gl9755_set_pll(pdev, 0x1, 0x246, 0x0);
541}
542
543static void sdhci_gl9755_set_clock(struct sdhci_host *host, unsigned int clock)
544{
545 struct sdhci_pci_slot *slot = sdhci_priv(host);
546 struct mmc_ios *ios = &host->mmc->ios;
547 struct pci_dev *pdev;
548 u16 clk;
549
550 pdev = slot->chip->pdev;
551 host->mmc->actual_clock = 0;
552
553 gl9755_disable_ssc_pll(pdev);
554 sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
555
556 if (clock == 0)
557 return;
558
559 clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);
560 if (clock == 200000000 && ios->timing == MMC_TIMING_UHS_SDR104) {
561 host->mmc->actual_clock = 205000000;
562 gl9755_set_ssc_pll_205mhz(pdev);
563 }
564
565 sdhci_enable_clk(host, clk);
566}
567
Ben Chuang0f1d9962020-11-23 13:37:02 +0800568static void gl9755_hw_setting(struct sdhci_pci_slot *slot)
569{
570 struct pci_dev *pdev = slot->chip->pdev;
571 u32 value;
572
573 gl9755_wt_on(pdev);
574
575 pci_read_config_dword(pdev, PCI_GLI_9755_PECONF, &value);
Hector Martin189f1d92021-12-16 01:10:44 +0900576 /*
577 * Apple ARM64 platforms using these chips may have
578 * inverted CD/WP detection.
579 */
580 if (of_property_read_bool(pdev->dev.of_node, "cd-inverted"))
581 value |= PCI_GLI_9755_INVERT_CD;
582 if (of_property_read_bool(pdev->dev.of_node, "wp-inverted"))
583 value |= PCI_GLI_9755_INVERT_WP;
Ben Chuang0f1d9962020-11-23 13:37:02 +0800584 value &= ~PCI_GLI_9755_LFCLK;
585 value &= ~PCI_GLI_9755_DMACLK;
586 pci_write_config_dword(pdev, PCI_GLI_9755_PECONF, value);
587
Renius Chenf46b54c2021-02-25 19:13:07 +0800588 /* enable short circuit protection */
589 pci_read_config_dword(pdev, PCI_GLI_9755_SerDes, &value);
590 value &= ~PCI_GLI_9755_SCP_DIS;
591 pci_write_config_dword(pdev, PCI_GLI_9755_SerDes, value);
592
Ben Chuang9751bac2021-04-15 11:26:37 +0800593 pci_read_config_dword(pdev, PCI_GLI_9755_CFG2, &value);
594 value &= ~PCI_GLI_9755_CFG2_L1DLY;
595 /* set ASPM L1 entry delay to 7.9us */
596 value |= FIELD_PREP(PCI_GLI_9755_CFG2_L1DLY,
597 GLI_9755_CFG2_L1DLY_VALUE);
598 pci_write_config_dword(pdev, PCI_GLI_9755_CFG2, value);
599
Ben Chuang0f1d9962020-11-23 13:37:02 +0800600 gl9755_wt_off(pdev);
601}
602
Ben Chuange51df6c2019-09-11 15:23:44 +0800603static int gli_probe_slot_gl9750(struct sdhci_pci_slot *slot)
604{
605 struct sdhci_host *host = slot->host;
606
Ben Chuang9751bac2021-04-15 11:26:37 +0800607 gl9750_hw_setting(host);
Ben Chuang31e43f32020-02-19 17:29:00 +0800608 gli_pcie_enable_msi(slot);
Ben Chuange51df6c2019-09-11 15:23:44 +0800609 slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO;
610 sdhci_enable_v4_mode(host);
611
612 return 0;
613}
614
615static int gli_probe_slot_gl9755(struct sdhci_pci_slot *slot)
616{
617 struct sdhci_host *host = slot->host;
618
Ben Chuang0f1d9962020-11-23 13:37:02 +0800619 gl9755_hw_setting(slot);
Ben Chuang31e43f32020-02-19 17:29:00 +0800620 gli_pcie_enable_msi(slot);
Ben Chuange51df6c2019-09-11 15:23:44 +0800621 slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO;
622 sdhci_enable_v4_mode(host);
623
624 return 0;
625}
626
627static void sdhci_gli_voltage_switch(struct sdhci_host *host)
628{
629 /*
630 * According to Section 3.6.1 signal voltage switch procedure in
631 * SD Host Controller Simplified Spec. 4.20, steps 6~8 are as
632 * follows:
633 * (6) Set 1.8V Signal Enable in the Host Control 2 register.
634 * (7) Wait 5ms. 1.8V voltage regulator shall be stable within this
635 * period.
636 * (8) If 1.8V Signal Enable is cleared by Host Controller, go to
637 * step (12).
638 *
639 * Wait 5ms after set 1.8V signal enable in Host Control 2 register
640 * to ensure 1.8V signal enable bit is set by GL9750/GL9755.
Daniel Beera1149a62021-04-24 20:16:52 +1200641 *
642 * ...however, the controller in the NUC10i3FNK4 (a 9755) requires
643 * slightly longer than 5ms before the control register reports that
644 * 1.8V is ready, and far longer still before the card will actually
645 * work reliably.
Ben Chuange51df6c2019-09-11 15:23:44 +0800646 */
Daniel Beera1149a62021-04-24 20:16:52 +1200647 usleep_range(100000, 110000);
Ben Chuange51df6c2019-09-11 15:23:44 +0800648}
649
650static void sdhci_gl9750_reset(struct sdhci_host *host, u8 mask)
651{
652 sdhci_reset(host, mask);
653 gli_set_9750(host);
654}
655
656static u32 sdhci_gl9750_readl(struct sdhci_host *host, int reg)
657{
658 u32 value;
659
660 value = readl(host->ioaddr + reg);
661 if (unlikely(reg == SDHCI_MAX_CURRENT && !(value & 0xff)))
662 value |= 0xc8;
663
664 return value;
665}
666
Ben Chuang282ede72020-04-27 18:30:48 +0800667#ifdef CONFIG_PM_SLEEP
668static int sdhci_pci_gli_resume(struct sdhci_pci_chip *chip)
669{
670 struct sdhci_pci_slot *slot = chip->slots[0];
671
672 pci_free_irq_vectors(slot->chip->pdev);
673 gli_pcie_enable_msi(slot);
674
675 return sdhci_pci_resume_host(chip);
676}
Ben Chuang347f6be2020-10-05 18:55:09 +0800677
678static int sdhci_cqhci_gli_resume(struct sdhci_pci_chip *chip)
679{
680 struct sdhci_pci_slot *slot = chip->slots[0];
681 int ret;
682
683 ret = sdhci_pci_gli_resume(chip);
684 if (ret)
685 return ret;
686
687 return cqhci_resume(slot->host->mmc);
688}
689
690static int sdhci_cqhci_gli_suspend(struct sdhci_pci_chip *chip)
691{
692 struct sdhci_pci_slot *slot = chip->slots[0];
693 int ret;
694
695 ret = cqhci_suspend(slot->host->mmc);
696 if (ret)
697 return ret;
698
699 return sdhci_suspend_host(slot->host);
700}
Ben Chuang282ede72020-04-27 18:30:48 +0800701#endif
702
Ben Chuang1ae1d2d2020-05-08 14:41:54 +0800703static void gl9763e_hs400_enhanced_strobe(struct mmc_host *mmc,
704 struct mmc_ios *ios)
705{
706 struct sdhci_host *host = mmc_priv(mmc);
707 u32 val;
708
709 val = sdhci_readl(host, SDHCI_GLI_9763E_HS400_ES_REG);
710 if (ios->enhanced_strobe)
711 val |= SDHCI_GLI_9763E_HS400_ES_BIT;
712 else
713 val &= ~SDHCI_GLI_9763E_HS400_ES_BIT;
714
715 sdhci_writel(host, val, SDHCI_GLI_9763E_HS400_ES_REG);
716}
717
718static void sdhci_set_gl9763e_signaling(struct sdhci_host *host,
719 unsigned int timing)
720{
721 u16 ctrl_2;
722
723 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
724 ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
725 if (timing == MMC_TIMING_MMC_HS200)
726 ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
727 else if (timing == MMC_TIMING_MMC_HS)
728 ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
729 else if (timing == MMC_TIMING_MMC_DDR52)
730 ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
731 else if (timing == MMC_TIMING_MMC_HS400)
732 ctrl_2 |= SDHCI_GLI_9763E_CTRL_HS400;
733
734 sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
735}
736
Ben Chuang347f6be2020-10-05 18:55:09 +0800737static void sdhci_gl9763e_dumpregs(struct mmc_host *mmc)
738{
739 sdhci_dumpregs(mmc_priv(mmc));
740}
741
742static void sdhci_gl9763e_cqe_pre_enable(struct mmc_host *mmc)
743{
744 struct cqhci_host *cq_host = mmc->cqe_private;
745 u32 value;
746
747 value = cqhci_readl(cq_host, CQHCI_CFG);
748 value |= CQHCI_ENABLE;
749 cqhci_writel(cq_host, value, CQHCI_CFG);
750}
751
752static void sdhci_gl9763e_cqe_enable(struct mmc_host *mmc)
753{
754 struct sdhci_host *host = mmc_priv(mmc);
755
756 sdhci_writew(host, GLI_9763E_CQE_TRNS_MODE, SDHCI_TRANSFER_MODE);
757 sdhci_cqe_enable(mmc);
758}
759
760static u32 sdhci_gl9763e_cqhci_irq(struct sdhci_host *host, u32 intmask)
761{
762 int cmd_error = 0;
763 int data_error = 0;
764
765 if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
766 return intmask;
767
768 cqhci_irq(host->mmc, intmask, cmd_error, data_error);
769
770 return 0;
771}
772
773static void sdhci_gl9763e_cqe_post_disable(struct mmc_host *mmc)
774{
775 struct sdhci_host *host = mmc_priv(mmc);
776 struct cqhci_host *cq_host = mmc->cqe_private;
777 u32 value;
778
779 value = cqhci_readl(cq_host, CQHCI_CFG);
780 value &= ~CQHCI_ENABLE;
781 cqhci_writel(cq_host, value, CQHCI_CFG);
782 sdhci_writew(host, 0x0, SDHCI_TRANSFER_MODE);
783}
784
785static const struct cqhci_host_ops sdhci_gl9763e_cqhci_ops = {
786 .enable = sdhci_gl9763e_cqe_enable,
787 .disable = sdhci_cqe_disable,
788 .dumpregs = sdhci_gl9763e_dumpregs,
789 .pre_enable = sdhci_gl9763e_cqe_pre_enable,
790 .post_disable = sdhci_gl9763e_cqe_post_disable,
791};
792
793static int gl9763e_add_host(struct sdhci_pci_slot *slot)
794{
795 struct device *dev = &slot->chip->pdev->dev;
796 struct sdhci_host *host = slot->host;
797 struct cqhci_host *cq_host;
798 bool dma64;
799 int ret;
800
801 ret = sdhci_setup_host(host);
802 if (ret)
803 return ret;
804
805 cq_host = devm_kzalloc(dev, sizeof(*cq_host), GFP_KERNEL);
806 if (!cq_host) {
807 ret = -ENOMEM;
808 goto cleanup;
809 }
810
811 cq_host->mmio = host->ioaddr + SDHCI_GLI_9763E_CQE_BASE_ADDR;
812 cq_host->ops = &sdhci_gl9763e_cqhci_ops;
813
814 dma64 = host->flags & SDHCI_USE_64_BIT_DMA;
815 if (dma64)
816 cq_host->caps |= CQHCI_TASK_DESC_SZ_128;
817
818 ret = cqhci_init(cq_host, host->mmc, dma64);
819 if (ret)
820 goto cleanup;
821
822 ret = __sdhci_add_host(host);
823 if (ret)
824 goto cleanup;
825
826 return 0;
827
828cleanup:
829 sdhci_cleanup_host(host);
830 return ret;
831}
832
833static void sdhci_gl9763e_reset(struct sdhci_host *host, u8 mask)
834{
835 if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL) &&
836 host->mmc->cqe_private)
837 cqhci_deactivate(host->mmc);
838 sdhci_reset(host, mask);
839}
840
Ben Chuang1ae1d2d2020-05-08 14:41:54 +0800841static void gli_set_gl9763e(struct sdhci_pci_slot *slot)
842{
843 struct pci_dev *pdev = slot->chip->pdev;
844 u32 value;
845
846 pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value);
847 value &= ~GLI_9763E_VHS_REV;
848 value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_W);
849 pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value);
850
851 pci_read_config_dword(pdev, PCIE_GLI_9763E_SCR, &value);
852 value |= GLI_9763E_SCR_AXI_REQ;
853 pci_write_config_dword(pdev, PCIE_GLI_9763E_SCR, value);
854
Ben Chuang98991b12020-11-25 19:01:45 +0800855 pci_read_config_dword(pdev, PCIE_GLI_9763E_MMC_CTRL, &value);
856 value &= ~GLI_9763E_HS400_SLOW;
857 pci_write_config_dword(pdev, PCIE_GLI_9763E_MMC_CTRL, value);
858
Renius Chenedee82f2021-01-15 13:47:36 +0800859 pci_read_config_dword(pdev, PCIE_GLI_9763E_CFG2, &value);
860 value &= ~GLI_9763E_CFG2_L1DLY;
Ben Chuang34dd3cc2021-05-11 14:18:35 +0800861 /* set ASPM L1 entry delay to 21us */
Ben Chuangbaaaf552021-04-07 17:38:16 +0800862 value |= FIELD_PREP(GLI_9763E_CFG2_L1DLY, GLI_9763E_CFG2_L1DLY_MID);
Renius Chenedee82f2021-01-15 13:47:36 +0800863 pci_write_config_dword(pdev, PCIE_GLI_9763E_CFG2, value);
864
Renius Chenc58c5952021-01-11 16:22:49 +0800865 pci_read_config_dword(pdev, PCIE_GLI_9763E_CLKRXDLY, &value);
866 value &= ~GLI_9763E_HS400_RXDLY;
867 value |= FIELD_PREP(GLI_9763E_HS400_RXDLY, GLI_9763E_HS400_RXDLY_5);
868 pci_write_config_dword(pdev, PCIE_GLI_9763E_CLKRXDLY, value);
869
Ben Chuang1ae1d2d2020-05-08 14:41:54 +0800870 pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value);
871 value &= ~GLI_9763E_VHS_REV;
872 value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_R);
873 pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value);
874}
875
876static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot)
877{
Ben Chuang347f6be2020-10-05 18:55:09 +0800878 struct pci_dev *pdev = slot->chip->pdev;
Ben Chuang1ae1d2d2020-05-08 14:41:54 +0800879 struct sdhci_host *host = slot->host;
Ben Chuang347f6be2020-10-05 18:55:09 +0800880 u32 value;
Ben Chuang1ae1d2d2020-05-08 14:41:54 +0800881
882 host->mmc->caps |= MMC_CAP_8_BIT_DATA |
883 MMC_CAP_1_8V_DDR |
884 MMC_CAP_NONREMOVABLE;
885 host->mmc->caps2 |= MMC_CAP2_HS200_1_8V_SDR |
886 MMC_CAP2_HS400_1_8V |
887 MMC_CAP2_HS400_ES |
888 MMC_CAP2_NO_SDIO |
889 MMC_CAP2_NO_SD;
Ben Chuang347f6be2020-10-05 18:55:09 +0800890
891 pci_read_config_dword(pdev, PCIE_GLI_9763E_MB, &value);
892 if (!(value & GLI_9763E_MB_CMDQ_OFF))
Renius Chen15f908f2021-01-06 16:53:32 +0800893 if (value & GLI_9763E_MB_ERP_ON)
894 host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD;
Ben Chuang347f6be2020-10-05 18:55:09 +0800895
Ben Chuang1ae1d2d2020-05-08 14:41:54 +0800896 gli_pcie_enable_msi(slot);
897 host->mmc_host_ops.hs400_enhanced_strobe =
898 gl9763e_hs400_enhanced_strobe;
899 gli_set_gl9763e(slot);
900 sdhci_enable_v4_mode(host);
901
902 return 0;
903}
904
Hector Martinc064bb52021-12-16 01:10:45 +0900905#define REG_OFFSET_IN_BITS(reg) ((reg) << 3 & 0x18)
906
907static u16 sdhci_gli_readw(struct sdhci_host *host, int reg)
908{
909 u32 val = readl(host->ioaddr + (reg & ~3));
910 u16 word;
911
912 word = (val >> REG_OFFSET_IN_BITS(reg)) & 0xffff;
913 return word;
914}
915
916static u8 sdhci_gli_readb(struct sdhci_host *host, int reg)
917{
918 u32 val = readl(host->ioaddr + (reg & ~3));
919 u8 byte = (val >> REG_OFFSET_IN_BITS(reg)) & 0xff;
920
921 return byte;
922}
923
Ben Chuange51df6c2019-09-11 15:23:44 +0800924static const struct sdhci_ops sdhci_gl9755_ops = {
Hector Martinc064bb52021-12-16 01:10:45 +0900925 .read_w = sdhci_gli_readw,
926 .read_b = sdhci_gli_readb,
Ben Chuang786d33c2020-07-17 11:33:50 +0800927 .set_clock = sdhci_gl9755_set_clock,
Ben Chuange51df6c2019-09-11 15:23:44 +0800928 .enable_dma = sdhci_pci_enable_dma,
929 .set_bus_width = sdhci_set_bus_width,
930 .reset = sdhci_reset,
931 .set_uhs_signaling = sdhci_set_uhs_signaling,
932 .voltage_switch = sdhci_gli_voltage_switch,
933};
934
935const struct sdhci_pci_fixes sdhci_gl9755 = {
936 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
937 .quirks2 = SDHCI_QUIRK2_BROKEN_DDR50,
938 .probe_slot = gli_probe_slot_gl9755,
939 .ops = &sdhci_gl9755_ops,
Ben Chuang282ede72020-04-27 18:30:48 +0800940#ifdef CONFIG_PM_SLEEP
941 .resume = sdhci_pci_gli_resume,
942#endif
Ben Chuange51df6c2019-09-11 15:23:44 +0800943};
944
945static const struct sdhci_ops sdhci_gl9750_ops = {
Hector Martinc064bb52021-12-16 01:10:45 +0900946 .read_w = sdhci_gli_readw,
947 .read_b = sdhci_gli_readb,
Ben Chuange51df6c2019-09-11 15:23:44 +0800948 .read_l = sdhci_gl9750_readl,
Ben Chuang786d33c2020-07-17 11:33:50 +0800949 .set_clock = sdhci_gl9750_set_clock,
Ben Chuange51df6c2019-09-11 15:23:44 +0800950 .enable_dma = sdhci_pci_enable_dma,
951 .set_bus_width = sdhci_set_bus_width,
952 .reset = sdhci_gl9750_reset,
953 .set_uhs_signaling = sdhci_set_uhs_signaling,
954 .voltage_switch = sdhci_gli_voltage_switch,
955 .platform_execute_tuning = gl9750_execute_tuning,
956};
957
958const struct sdhci_pci_fixes sdhci_gl9750 = {
959 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
960 .quirks2 = SDHCI_QUIRK2_BROKEN_DDR50,
961 .probe_slot = gli_probe_slot_gl9750,
962 .ops = &sdhci_gl9750_ops,
Ben Chuang282ede72020-04-27 18:30:48 +0800963#ifdef CONFIG_PM_SLEEP
964 .resume = sdhci_pci_gli_resume,
965#endif
Ben Chuange51df6c2019-09-11 15:23:44 +0800966};
Ben Chuang1ae1d2d2020-05-08 14:41:54 +0800967
968static const struct sdhci_ops sdhci_gl9763e_ops = {
969 .set_clock = sdhci_set_clock,
970 .enable_dma = sdhci_pci_enable_dma,
971 .set_bus_width = sdhci_set_bus_width,
Ben Chuang347f6be2020-10-05 18:55:09 +0800972 .reset = sdhci_gl9763e_reset,
Ben Chuang1ae1d2d2020-05-08 14:41:54 +0800973 .set_uhs_signaling = sdhci_set_gl9763e_signaling,
974 .voltage_switch = sdhci_gli_voltage_switch,
Ben Chuang347f6be2020-10-05 18:55:09 +0800975 .irq = sdhci_gl9763e_cqhci_irq,
Ben Chuang1ae1d2d2020-05-08 14:41:54 +0800976};
977
978const struct sdhci_pci_fixes sdhci_gl9763e = {
979 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
980 .probe_slot = gli_probe_slot_gl9763e,
981 .ops = &sdhci_gl9763e_ops,
982#ifdef CONFIG_PM_SLEEP
Ben Chuang347f6be2020-10-05 18:55:09 +0800983 .resume = sdhci_cqhci_gli_resume,
984 .suspend = sdhci_cqhci_gli_suspend,
Ben Chuang1ae1d2d2020-05-08 14:41:54 +0800985#endif
Ben Chuang347f6be2020-10-05 18:55:09 +0800986 .add_host = gl9763e_add_host,
Ben Chuang1ae1d2d2020-05-08 14:41:54 +0800987};