1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2013 BayHub Technology Ltd. |
4 | * |
5 | * Authors: Peter Guo <peter.guo@bayhubtech.com> |
6 | * Adam Lee <adam.lee@canonical.com> |
7 | * Ernest Zhang <ernest.zhang@bayhubtech.com> |
8 | */ |
9 | |
10 | #include <linux/pci.h> |
11 | #include <linux/mmc/host.h> |
12 | #include <linux/mmc/mmc.h> |
13 | #include <linux/delay.h> |
14 | #include <linux/iopoll.h> |
15 | #include <linux/bitfield.h> |
16 | |
17 | #include "sdhci.h" |
18 | #include "sdhci-pci.h" |
19 | |
20 | /* |
21 | * O2Micro device registers |
22 | */ |
23 | |
24 | #define O2_SD_PCIE_SWITCH 0x54 |
25 | #define O2_SD_MISC_REG5 0x64 |
26 | #define O2_SD_LD0_CTRL 0x68 |
27 | #define O2_SD_DEV_CTRL 0x88 |
28 | #define O2_SD_LOCK_WP 0xD3 |
29 | #define O2_SD_TEST_REG 0xD4 |
30 | #define O2_SD_FUNC_REG0 0xDC |
31 | #define O2_SD_MULTI_VCC3V 0xEE |
32 | #define O2_SD_CLKREQ 0xEC |
33 | #define O2_SD_CAPS 0xE0 |
34 | #define O2_SD_ADMA1 0xE2 |
35 | #define O2_SD_ADMA2 0xE7 |
36 | #define O2_SD_MISC_CTRL2 0xF0 |
37 | #define O2_SD_INF_MOD 0xF1 |
38 | #define O2_SD_MISC_CTRL4 0xFC |
39 | #define O2_SD_MISC_CTRL 0x1C0 |
40 | #define O2_SD_EXP_INT_REG 0x1E0 |
41 | #define O2_SD_PWR_FORCE_L0 0x0002 |
42 | #define O2_SD_TUNING_CTRL 0x300 |
43 | #define O2_SD_PLL_SETTING 0x304 |
44 | #define O2_SD_MISC_SETTING 0x308 |
45 | #define O2_SD_CLK_SETTING 0x328 |
46 | #define O2_SD_CAP_REG2 0x330 |
47 | #define O2_SD_CAP_REG0 0x334 |
48 | #define O2_SD_UHS1_CAP_SETTING 0x33C |
49 | #define O2_SD_DELAY_CTRL 0x350 |
50 | #define O2_SD_OUTPUT_CLK_SOURCE_SWITCH 0x354 |
51 | #define O2_SD_UHS2_L1_CTRL 0x35C |
52 | #define O2_SD_FUNC_REG3 0x3E0 |
53 | #define O2_SD_FUNC_REG4 0x3E4 |
54 | #define O2_SD_PARA_SET_REG1 0x444 |
55 | #define O2_SD_VDDX_CTRL_REG 0x508 |
56 | #define O2_SD_GPIO_CTRL_REG1 0x510 |
57 | #define O2_SD_LED_ENABLE BIT(6) |
58 | #define O2_SD_FREG0_LEDOFF BIT(13) |
59 | #define O2_SD_SEL_DLL BIT(16) |
60 | #define O2_SD_FREG4_ENABLE_CLK_SET BIT(22) |
61 | #define O2_SD_PHASE_MASK GENMASK(23, 20) |
62 | #define O2_SD_FIX_PHASE FIELD_PREP(O2_SD_PHASE_MASK, 0x9) |
63 | |
64 | #define O2_SD_VENDOR_SETTING 0x110 |
65 | #define O2_SD_VENDOR_SETTING2 0x1C8 |
66 | #define O2_SD_HW_TUNING_DISABLE BIT(4) |
67 | |
68 | #define O2_PLL_DLL_WDT_CONTROL1 0x1CC |
69 | #define O2_PLL_FORCE_ACTIVE BIT(18) |
70 | #define O2_PLL_LOCK_STATUS BIT(14) |
71 | #define O2_PLL_SOFT_RESET BIT(12) |
72 | #define O2_DLL_LOCK_STATUS BIT(11) |
73 | |
74 | #define O2_SD_DETECT_SETTING 0x324 |
75 | |
76 | static const u32 dmdn_table[] = {0x2B1C0000, |
77 | 0x2C1A0000, 0x371B0000, 0x35100000}; |
78 | #define DMDN_SZ ARRAY_SIZE(dmdn_table) |
79 | |
80 | struct o2_host { |
81 | u8 dll_adjust_count; |
82 | }; |
83 | |
84 | static void sdhci_o2_wait_card_detect_stable(struct sdhci_host *host) |
85 | { |
86 | ktime_t timeout; |
87 | u32 scratch32; |
88 | |
89 | /* Wait max 50 ms */ |
90 | timeout = ktime_add_ms(kt: ktime_get(), msec: 50); |
91 | while (1) { |
92 | bool timedout = ktime_after(cmp1: ktime_get(), cmp2: timeout); |
93 | |
94 | scratch32 = sdhci_readl(host, SDHCI_PRESENT_STATE); |
95 | if ((scratch32 & SDHCI_CARD_PRESENT) >> SDHCI_CARD_PRES_SHIFT |
96 | == (scratch32 & SDHCI_CD_LVL) >> SDHCI_CD_LVL_SHIFT) |
97 | break; |
98 | |
99 | if (timedout) { |
100 | pr_err("%s: Card Detect debounce never finished.\n" , |
101 | mmc_hostname(host->mmc)); |
102 | sdhci_dumpregs(host); |
103 | return; |
104 | } |
105 | udelay(10); |
106 | } |
107 | } |
108 | |
109 | static void sdhci_o2_enable_internal_clock(struct sdhci_host *host) |
110 | { |
111 | ktime_t timeout; |
112 | u16 scratch; |
113 | u32 scratch32; |
114 | |
115 | /* PLL software reset */ |
116 | scratch32 = sdhci_readl(host, O2_PLL_DLL_WDT_CONTROL1); |
117 | scratch32 |= O2_PLL_SOFT_RESET; |
118 | sdhci_writel(host, val: scratch32, O2_PLL_DLL_WDT_CONTROL1); |
119 | udelay(1); |
120 | scratch32 &= ~(O2_PLL_SOFT_RESET); |
121 | sdhci_writel(host, val: scratch32, O2_PLL_DLL_WDT_CONTROL1); |
122 | |
123 | /* PLL force active */ |
124 | scratch32 |= O2_PLL_FORCE_ACTIVE; |
125 | sdhci_writel(host, val: scratch32, O2_PLL_DLL_WDT_CONTROL1); |
126 | |
127 | /* Wait max 20 ms */ |
128 | timeout = ktime_add_ms(kt: ktime_get(), msec: 20); |
129 | while (1) { |
130 | bool timedout = ktime_after(cmp1: ktime_get(), cmp2: timeout); |
131 | |
132 | scratch = sdhci_readw(host, O2_PLL_DLL_WDT_CONTROL1); |
133 | if (scratch & O2_PLL_LOCK_STATUS) |
134 | break; |
135 | if (timedout) { |
136 | pr_err("%s: Internal clock never stabilised.\n" , |
137 | mmc_hostname(host->mmc)); |
138 | sdhci_dumpregs(host); |
139 | goto out; |
140 | } |
141 | udelay(10); |
142 | } |
143 | |
144 | /* Wait for card detect finish */ |
145 | udelay(1); |
146 | sdhci_o2_wait_card_detect_stable(host); |
147 | |
148 | out: |
149 | /* Cancel PLL force active */ |
150 | scratch32 = sdhci_readl(host, O2_PLL_DLL_WDT_CONTROL1); |
151 | scratch32 &= ~O2_PLL_FORCE_ACTIVE; |
152 | sdhci_writel(host, val: scratch32, O2_PLL_DLL_WDT_CONTROL1); |
153 | } |
154 | |
155 | static int sdhci_o2_get_cd(struct mmc_host *mmc) |
156 | { |
157 | struct sdhci_host *host = mmc_priv(host: mmc); |
158 | |
159 | if (!(sdhci_readw(host, O2_PLL_DLL_WDT_CONTROL1) & O2_PLL_LOCK_STATUS)) |
160 | sdhci_o2_enable_internal_clock(host); |
161 | else |
162 | sdhci_o2_wait_card_detect_stable(host); |
163 | |
164 | return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT); |
165 | } |
166 | |
167 | static void o2_pci_set_baseclk(struct sdhci_pci_chip *chip, u32 value) |
168 | { |
169 | u32 scratch_32; |
170 | |
171 | pci_read_config_dword(dev: chip->pdev, |
172 | O2_SD_PLL_SETTING, val: &scratch_32); |
173 | |
174 | scratch_32 &= 0x0000FFFF; |
175 | scratch_32 |= value; |
176 | |
177 | pci_write_config_dword(dev: chip->pdev, |
178 | O2_SD_PLL_SETTING, val: scratch_32); |
179 | } |
180 | |
181 | static u32 sdhci_o2_pll_dll_wdt_control(struct sdhci_host *host) |
182 | { |
183 | return sdhci_readl(host, O2_PLL_DLL_WDT_CONTROL1); |
184 | } |
185 | |
186 | /* |
187 | * This function is used to detect dll lock status. |
188 | * Since the dll lock status bit will toggle randomly |
189 | * with very short interval which needs to be polled |
190 | * as fast as possible. Set sleep_us as 1 microsecond. |
191 | */ |
192 | static int sdhci_o2_wait_dll_detect_lock(struct sdhci_host *host) |
193 | { |
194 | u32 scratch32 = 0; |
195 | |
196 | return readx_poll_timeout(sdhci_o2_pll_dll_wdt_control, host, |
197 | scratch32, !(scratch32 & O2_DLL_LOCK_STATUS), 1, 1000000); |
198 | } |
199 | |
200 | static void sdhci_o2_set_tuning_mode(struct sdhci_host *host) |
201 | { |
202 | u16 reg; |
203 | |
204 | /* enable hardware tuning */ |
205 | reg = sdhci_readw(host, O2_SD_VENDOR_SETTING); |
206 | reg &= ~O2_SD_HW_TUNING_DISABLE; |
207 | sdhci_writew(host, val: reg, O2_SD_VENDOR_SETTING); |
208 | } |
209 | |
210 | static void __sdhci_o2_execute_tuning(struct sdhci_host *host, u32 opcode) |
211 | { |
212 | int i; |
213 | |
214 | sdhci_send_tuning(host, opcode); |
215 | |
216 | for (i = 0; i < 150; i++) { |
217 | u16 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
218 | |
219 | if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) { |
220 | if (ctrl & SDHCI_CTRL_TUNED_CLK) { |
221 | host->tuning_done = true; |
222 | return; |
223 | } |
224 | pr_warn("%s: HW tuning failed !\n" , |
225 | mmc_hostname(host->mmc)); |
226 | break; |
227 | } |
228 | |
229 | mdelay(1); |
230 | } |
231 | |
232 | pr_info("%s: Tuning failed, falling back to fixed sampling clock\n" , |
233 | mmc_hostname(host->mmc)); |
234 | sdhci_reset_tuning(host); |
235 | } |
236 | |
237 | /* |
238 | * This function is used to fix o2 dll shift issue. |
239 | * It isn't necessary to detect card present before recovery. |
240 | * Firstly, it is used by bht emmc card, which is embedded. |
241 | * Second, before call recovery card present will be detected |
242 | * outside of the execute tuning function. |
243 | */ |
244 | static int sdhci_o2_dll_recovery(struct sdhci_host *host) |
245 | { |
246 | int ret = 0; |
247 | u8 scratch_8 = 0; |
248 | u32 scratch_32 = 0; |
249 | struct sdhci_pci_slot *slot = sdhci_priv(host); |
250 | struct sdhci_pci_chip *chip = slot->chip; |
251 | struct o2_host *o2_host = sdhci_pci_priv(slot); |
252 | |
253 | /* UnLock WP */ |
254 | pci_read_config_byte(dev: chip->pdev, |
255 | O2_SD_LOCK_WP, val: &scratch_8); |
256 | scratch_8 &= 0x7f; |
257 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch_8); |
258 | while (o2_host->dll_adjust_count < DMDN_SZ && !ret) { |
259 | /* Disable clock */ |
260 | sdhci_writeb(host, val: 0, SDHCI_CLOCK_CONTROL); |
261 | |
262 | /* PLL software reset */ |
263 | scratch_32 = sdhci_readl(host, O2_PLL_DLL_WDT_CONTROL1); |
264 | scratch_32 |= O2_PLL_SOFT_RESET; |
265 | sdhci_writel(host, val: scratch_32, O2_PLL_DLL_WDT_CONTROL1); |
266 | |
267 | pci_read_config_dword(dev: chip->pdev, |
268 | O2_SD_FUNC_REG4, |
269 | val: &scratch_32); |
270 | /* Enable Base Clk setting change */ |
271 | scratch_32 |= O2_SD_FREG4_ENABLE_CLK_SET; |
272 | pci_write_config_dword(dev: chip->pdev, O2_SD_FUNC_REG4, val: scratch_32); |
273 | o2_pci_set_baseclk(chip, value: dmdn_table[o2_host->dll_adjust_count]); |
274 | |
275 | /* Enable internal clock */ |
276 | scratch_8 = SDHCI_CLOCK_INT_EN; |
277 | sdhci_writeb(host, val: scratch_8, SDHCI_CLOCK_CONTROL); |
278 | |
279 | if (sdhci_o2_get_cd(mmc: host->mmc)) { |
280 | /* |
281 | * need wait at least 5ms for dll status stable, |
282 | * after enable internal clock |
283 | */ |
284 | usleep_range(min: 5000, max: 6000); |
285 | if (sdhci_o2_wait_dll_detect_lock(host)) { |
286 | scratch_8 |= SDHCI_CLOCK_CARD_EN; |
287 | sdhci_writeb(host, val: scratch_8, |
288 | SDHCI_CLOCK_CONTROL); |
289 | ret = 1; |
290 | } else { |
291 | pr_warn("%s: DLL unlocked when dll_adjust_count is %d.\n" , |
292 | mmc_hostname(host->mmc), |
293 | o2_host->dll_adjust_count); |
294 | } |
295 | } else { |
296 | pr_err("%s: card present detect failed.\n" , |
297 | mmc_hostname(host->mmc)); |
298 | break; |
299 | } |
300 | |
301 | o2_host->dll_adjust_count++; |
302 | } |
303 | if (!ret && o2_host->dll_adjust_count == DMDN_SZ) |
304 | pr_err("%s: DLL adjust over max times\n" , |
305 | mmc_hostname(host->mmc)); |
306 | /* Lock WP */ |
307 | pci_read_config_byte(dev: chip->pdev, |
308 | O2_SD_LOCK_WP, val: &scratch_8); |
309 | scratch_8 |= 0x80; |
310 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch_8); |
311 | return ret; |
312 | } |
313 | |
314 | static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode) |
315 | { |
316 | struct sdhci_host *host = mmc_priv(host: mmc); |
317 | struct sdhci_pci_slot *slot = sdhci_priv(host); |
318 | struct sdhci_pci_chip *chip = slot->chip; |
319 | int current_bus_width = 0; |
320 | u32 scratch32 = 0; |
321 | u16 scratch = 0; |
322 | u8 scratch_8 = 0; |
323 | u32 reg_val; |
324 | |
325 | /* |
326 | * This handler implements the hardware tuning that is specific to |
327 | * this controller. Fall back to the standard method for other TIMING. |
328 | */ |
329 | if ((host->timing != MMC_TIMING_MMC_HS200) && |
330 | (host->timing != MMC_TIMING_UHS_SDR104) && |
331 | (host->timing != MMC_TIMING_UHS_SDR50)) |
332 | return sdhci_execute_tuning(mmc, opcode); |
333 | |
334 | if (WARN_ON(!mmc_op_tuning(opcode))) |
335 | return -EINVAL; |
336 | |
337 | /* Force power mode enter L0 */ |
338 | scratch = sdhci_readw(host, O2_SD_MISC_CTRL); |
339 | scratch |= O2_SD_PWR_FORCE_L0; |
340 | sdhci_writew(host, val: scratch, O2_SD_MISC_CTRL); |
341 | |
342 | /* Update output phase */ |
343 | switch (chip->pdev->device) { |
344 | case PCI_DEVICE_ID_O2_SDS0: |
345 | case PCI_DEVICE_ID_O2_SEABIRD0: |
346 | case PCI_DEVICE_ID_O2_SEABIRD1: |
347 | case PCI_DEVICE_ID_O2_SDS1: |
348 | case PCI_DEVICE_ID_O2_FUJIN2: |
349 | /* Stop clk */ |
350 | reg_val = sdhci_readw(host, SDHCI_CLOCK_CONTROL); |
351 | reg_val &= ~SDHCI_CLOCK_CARD_EN; |
352 | sdhci_writew(host, val: reg_val, SDHCI_CLOCK_CONTROL); |
353 | |
354 | if (host->timing == MMC_TIMING_MMC_HS200 || |
355 | host->timing == MMC_TIMING_UHS_SDR104) { |
356 | /* UnLock WP */ |
357 | pci_read_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: &scratch_8); |
358 | scratch_8 &= 0x7f; |
359 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch_8); |
360 | |
361 | /* Set pcr 0x354[16] to choose dll clock, and set the default phase */ |
362 | pci_read_config_dword(dev: chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, val: ®_val); |
363 | reg_val &= ~(O2_SD_SEL_DLL | O2_SD_PHASE_MASK); |
364 | reg_val |= (O2_SD_SEL_DLL | O2_SD_FIX_PHASE); |
365 | pci_write_config_dword(dev: chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, val: reg_val); |
366 | |
367 | /* Lock WP */ |
368 | pci_read_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: &scratch_8); |
369 | scratch_8 |= 0x80; |
370 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch_8); |
371 | } |
372 | |
373 | /* Start clk */ |
374 | reg_val = sdhci_readw(host, SDHCI_CLOCK_CONTROL); |
375 | reg_val |= SDHCI_CLOCK_CARD_EN; |
376 | sdhci_writew(host, val: reg_val, SDHCI_CLOCK_CONTROL); |
377 | break; |
378 | default: |
379 | break; |
380 | } |
381 | |
382 | /* wait DLL lock, timeout value 5ms */ |
383 | if (readx_poll_timeout(sdhci_o2_pll_dll_wdt_control, host, |
384 | scratch32, (scratch32 & O2_DLL_LOCK_STATUS), 1, 5000)) |
385 | pr_warn("%s: DLL can't lock in 5ms after force L0 during tuning.\n" , |
386 | mmc_hostname(host->mmc)); |
387 | /* |
388 | * Judge the tuning reason, whether caused by dll shift |
389 | * If cause by dll shift, should call sdhci_o2_dll_recovery |
390 | */ |
391 | if (!sdhci_o2_wait_dll_detect_lock(host)) |
392 | if (!sdhci_o2_dll_recovery(host)) { |
393 | pr_err("%s: o2 dll recovery failed\n" , |
394 | mmc_hostname(host->mmc)); |
395 | return -EINVAL; |
396 | } |
397 | /* |
398 | * o2 sdhci host didn't support 8bit emmc tuning |
399 | */ |
400 | if (mmc->ios.bus_width == MMC_BUS_WIDTH_8) { |
401 | current_bus_width = mmc->ios.bus_width; |
402 | mmc->ios.bus_width = MMC_BUS_WIDTH_4; |
403 | sdhci_set_bus_width(host, MMC_BUS_WIDTH_4); |
404 | } |
405 | |
406 | sdhci_o2_set_tuning_mode(host); |
407 | |
408 | sdhci_start_tuning(host); |
409 | |
410 | __sdhci_o2_execute_tuning(host, opcode); |
411 | |
412 | sdhci_end_tuning(host); |
413 | |
414 | if (current_bus_width == MMC_BUS_WIDTH_8) { |
415 | mmc->ios.bus_width = MMC_BUS_WIDTH_8; |
416 | sdhci_set_bus_width(host, width: current_bus_width); |
417 | } |
418 | |
419 | /* Cancel force power mode enter L0 */ |
420 | scratch = sdhci_readw(host, O2_SD_MISC_CTRL); |
421 | scratch &= ~(O2_SD_PWR_FORCE_L0); |
422 | sdhci_writew(host, val: scratch, O2_SD_MISC_CTRL); |
423 | |
424 | sdhci_reset(host, SDHCI_RESET_CMD); |
425 | sdhci_reset(host, SDHCI_RESET_DATA); |
426 | |
427 | host->flags &= ~SDHCI_HS400_TUNING; |
428 | return 0; |
429 | } |
430 | |
431 | static void o2_pci_led_enable(struct sdhci_pci_chip *chip) |
432 | { |
433 | int ret; |
434 | u32 scratch_32; |
435 | |
436 | /* Set led of SD host function enable */ |
437 | ret = pci_read_config_dword(dev: chip->pdev, |
438 | O2_SD_FUNC_REG0, val: &scratch_32); |
439 | if (ret) |
440 | return; |
441 | |
442 | scratch_32 &= ~O2_SD_FREG0_LEDOFF; |
443 | pci_write_config_dword(dev: chip->pdev, |
444 | O2_SD_FUNC_REG0, val: scratch_32); |
445 | |
446 | ret = pci_read_config_dword(dev: chip->pdev, |
447 | O2_SD_TEST_REG, val: &scratch_32); |
448 | if (ret) |
449 | return; |
450 | |
451 | scratch_32 |= O2_SD_LED_ENABLE; |
452 | pci_write_config_dword(dev: chip->pdev, |
453 | O2_SD_TEST_REG, val: scratch_32); |
454 | } |
455 | |
456 | static void sdhci_pci_o2_fujin2_pci_init(struct sdhci_pci_chip *chip) |
457 | { |
458 | u32 scratch_32; |
459 | int ret; |
460 | /* Improve write performance for SD3.0 */ |
461 | ret = pci_read_config_dword(dev: chip->pdev, O2_SD_DEV_CTRL, val: &scratch_32); |
462 | if (ret) |
463 | return; |
464 | scratch_32 &= ~((1 << 12) | (1 << 13) | (1 << 14)); |
465 | pci_write_config_dword(dev: chip->pdev, O2_SD_DEV_CTRL, val: scratch_32); |
466 | |
467 | /* Enable Link abnormal reset generating Reset */ |
468 | ret = pci_read_config_dword(dev: chip->pdev, O2_SD_MISC_REG5, val: &scratch_32); |
469 | if (ret) |
470 | return; |
471 | scratch_32 &= ~((1 << 19) | (1 << 11)); |
472 | scratch_32 |= (1 << 10); |
473 | pci_write_config_dword(dev: chip->pdev, O2_SD_MISC_REG5, val: scratch_32); |
474 | |
475 | /* set card power over current protection */ |
476 | ret = pci_read_config_dword(dev: chip->pdev, O2_SD_TEST_REG, val: &scratch_32); |
477 | if (ret) |
478 | return; |
479 | scratch_32 |= (1 << 4); |
480 | pci_write_config_dword(dev: chip->pdev, O2_SD_TEST_REG, val: scratch_32); |
481 | |
482 | /* adjust the output delay for SD mode */ |
483 | pci_write_config_dword(dev: chip->pdev, O2_SD_DELAY_CTRL, val: 0x00002492); |
484 | |
485 | /* Set the output voltage setting of Aux 1.2v LDO */ |
486 | ret = pci_read_config_dword(dev: chip->pdev, O2_SD_LD0_CTRL, val: &scratch_32); |
487 | if (ret) |
488 | return; |
489 | scratch_32 &= ~(3 << 12); |
490 | pci_write_config_dword(dev: chip->pdev, O2_SD_LD0_CTRL, val: scratch_32); |
491 | |
492 | /* Set Max power supply capability of SD host */ |
493 | ret = pci_read_config_dword(dev: chip->pdev, O2_SD_CAP_REG0, val: &scratch_32); |
494 | if (ret) |
495 | return; |
496 | scratch_32 &= ~(0x01FE); |
497 | scratch_32 |= 0x00CC; |
498 | pci_write_config_dword(dev: chip->pdev, O2_SD_CAP_REG0, val: scratch_32); |
499 | /* Set DLL Tuning Window */ |
500 | ret = pci_read_config_dword(dev: chip->pdev, |
501 | O2_SD_TUNING_CTRL, val: &scratch_32); |
502 | if (ret) |
503 | return; |
504 | scratch_32 &= ~(0x000000FF); |
505 | scratch_32 |= 0x00000066; |
506 | pci_write_config_dword(dev: chip->pdev, O2_SD_TUNING_CTRL, val: scratch_32); |
507 | |
508 | /* Set UHS2 T_EIDLE */ |
509 | ret = pci_read_config_dword(dev: chip->pdev, |
510 | O2_SD_UHS2_L1_CTRL, val: &scratch_32); |
511 | if (ret) |
512 | return; |
513 | scratch_32 &= ~(0x000000FC); |
514 | scratch_32 |= 0x00000084; |
515 | pci_write_config_dword(dev: chip->pdev, O2_SD_UHS2_L1_CTRL, val: scratch_32); |
516 | |
517 | /* Set UHS2 Termination */ |
518 | ret = pci_read_config_dword(dev: chip->pdev, O2_SD_FUNC_REG3, val: &scratch_32); |
519 | if (ret) |
520 | return; |
521 | scratch_32 &= ~((1 << 21) | (1 << 30)); |
522 | |
523 | pci_write_config_dword(dev: chip->pdev, O2_SD_FUNC_REG3, val: scratch_32); |
524 | |
525 | /* Set L1 Entrance Timer */ |
526 | ret = pci_read_config_dword(dev: chip->pdev, O2_SD_CAPS, val: &scratch_32); |
527 | if (ret) |
528 | return; |
529 | scratch_32 &= ~(0xf0000000); |
530 | scratch_32 |= 0x30000000; |
531 | pci_write_config_dword(dev: chip->pdev, O2_SD_CAPS, val: scratch_32); |
532 | |
533 | ret = pci_read_config_dword(dev: chip->pdev, |
534 | O2_SD_MISC_CTRL4, val: &scratch_32); |
535 | if (ret) |
536 | return; |
537 | scratch_32 &= ~(0x000f0000); |
538 | scratch_32 |= 0x00080000; |
539 | pci_write_config_dword(dev: chip->pdev, O2_SD_MISC_CTRL4, val: scratch_32); |
540 | } |
541 | |
542 | static void sdhci_pci_o2_enable_msi(struct sdhci_pci_chip *chip, |
543 | struct sdhci_host *host) |
544 | { |
545 | int ret; |
546 | |
547 | ret = pci_find_capability(dev: chip->pdev, PCI_CAP_ID_MSI); |
548 | if (!ret) { |
549 | pr_info("%s: unsupported MSI, use INTx irq\n" , |
550 | mmc_hostname(host->mmc)); |
551 | return; |
552 | } |
553 | |
554 | ret = pci_alloc_irq_vectors(dev: chip->pdev, min_vecs: 1, max_vecs: 1, |
555 | PCI_IRQ_MSI | PCI_IRQ_MSIX); |
556 | if (ret < 0) { |
557 | pr_err("%s: enable PCI MSI failed, err=%d\n" , |
558 | mmc_hostname(host->mmc), ret); |
559 | return; |
560 | } |
561 | |
562 | host->irq = pci_irq_vector(dev: chip->pdev, nr: 0); |
563 | } |
564 | |
565 | static void sdhci_o2_enable_clk(struct sdhci_host *host, u16 clk) |
566 | { |
567 | /* Enable internal clock */ |
568 | clk |= SDHCI_CLOCK_INT_EN; |
569 | sdhci_writew(host, val: clk, SDHCI_CLOCK_CONTROL); |
570 | |
571 | sdhci_o2_enable_internal_clock(host); |
572 | if (sdhci_o2_get_cd(mmc: host->mmc)) { |
573 | clk |= SDHCI_CLOCK_CARD_EN; |
574 | sdhci_writew(host, val: clk, SDHCI_CLOCK_CONTROL); |
575 | } |
576 | } |
577 | |
578 | static void sdhci_pci_o2_set_clock(struct sdhci_host *host, unsigned int clock) |
579 | { |
580 | u16 clk; |
581 | u8 scratch; |
582 | u32 scratch_32; |
583 | u32 dmdn_208m, dmdn_200m; |
584 | struct sdhci_pci_slot *slot = sdhci_priv(host); |
585 | struct sdhci_pci_chip *chip = slot->chip; |
586 | |
587 | host->mmc->actual_clock = 0; |
588 | |
589 | sdhci_writew(host, val: 0, SDHCI_CLOCK_CONTROL); |
590 | |
591 | if (clock == 0) |
592 | return; |
593 | |
594 | /* UnLock WP */ |
595 | pci_read_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: &scratch); |
596 | scratch &= 0x7f; |
597 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch); |
598 | |
599 | if (chip->pdev->device == PCI_DEVICE_ID_O2_GG8_9860 || |
600 | chip->pdev->device == PCI_DEVICE_ID_O2_GG8_9861 || |
601 | chip->pdev->device == PCI_DEVICE_ID_O2_GG8_9862 || |
602 | chip->pdev->device == PCI_DEVICE_ID_O2_GG8_9863) { |
603 | dmdn_208m = 0x2c500000; |
604 | dmdn_200m = 0x25200000; |
605 | } else { |
606 | dmdn_208m = 0x2c280000; |
607 | dmdn_200m = 0x25100000; |
608 | } |
609 | |
610 | if ((host->timing == MMC_TIMING_UHS_SDR104) && (clock == 200000000)) { |
611 | pci_read_config_dword(dev: chip->pdev, O2_SD_PLL_SETTING, val: &scratch_32); |
612 | |
613 | if ((scratch_32 & 0xFFFF0000) != dmdn_208m) |
614 | o2_pci_set_baseclk(chip, value: dmdn_208m); |
615 | } else { |
616 | pci_read_config_dword(dev: chip->pdev, O2_SD_PLL_SETTING, val: &scratch_32); |
617 | |
618 | if ((scratch_32 & 0xFFFF0000) != dmdn_200m) |
619 | o2_pci_set_baseclk(chip, value: dmdn_200m); |
620 | } |
621 | |
622 | pci_read_config_dword(dev: chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, val: &scratch_32); |
623 | scratch_32 &= ~(O2_SD_SEL_DLL | O2_SD_PHASE_MASK); |
624 | pci_write_config_dword(dev: chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, val: scratch_32); |
625 | |
626 | /* Lock WP */ |
627 | pci_read_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: &scratch); |
628 | scratch |= 0x80; |
629 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch); |
630 | |
631 | clk = sdhci_calc_clk(host, clock, actual_clock: &host->mmc->actual_clock); |
632 | sdhci_o2_enable_clk(host, clk); |
633 | } |
634 | |
635 | static int sdhci_pci_o2_init_sd_express(struct mmc_host *mmc, struct mmc_ios *ios) |
636 | { |
637 | struct sdhci_host *host = mmc_priv(host: mmc); |
638 | struct sdhci_pci_slot *slot = sdhci_priv(host); |
639 | struct sdhci_pci_chip *chip = slot->chip; |
640 | u8 scratch8; |
641 | u16 scratch16; |
642 | int ret; |
643 | |
644 | /* Disable clock */ |
645 | sdhci_writeb(host, val: 0, SDHCI_CLOCK_CONTROL); |
646 | |
647 | /* Set VDD2 voltage*/ |
648 | scratch8 = sdhci_readb(host, SDHCI_POWER_CONTROL); |
649 | scratch8 &= 0x0F; |
650 | if (host->mmc->ios.timing == MMC_TIMING_SD_EXP_1_2V && |
651 | host->mmc->caps2 & MMC_CAP2_SD_EXP_1_2V) { |
652 | scratch8 |= SDHCI_VDD2_POWER_ON | SDHCI_VDD2_POWER_120; |
653 | } else { |
654 | scratch8 |= SDHCI_VDD2_POWER_ON | SDHCI_VDD2_POWER_180; |
655 | } |
656 | |
657 | sdhci_writeb(host, val: scratch8, SDHCI_POWER_CONTROL); |
658 | |
659 | /* UnLock WP */ |
660 | pci_read_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: &scratch8); |
661 | scratch8 &= 0x7f; |
662 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch8); |
663 | |
664 | /* Wait for express card clkreqn assert */ |
665 | ret = read_poll_timeout(sdhci_readb, scratch8, !(scratch8 & BIT(0)), |
666 | 1, 30000, false, host, O2_SD_EXP_INT_REG); |
667 | |
668 | if (!ret) { |
669 | /* Switch to PCIe mode */ |
670 | scratch16 = sdhci_readw(host, O2_SD_PCIE_SWITCH); |
671 | scratch16 |= BIT(8); |
672 | sdhci_writew(host, val: scratch16, O2_SD_PCIE_SWITCH); |
673 | } else { |
674 | /* Power off VDD2 voltage*/ |
675 | scratch8 = sdhci_readb(host, SDHCI_POWER_CONTROL); |
676 | scratch8 &= 0x0F; |
677 | sdhci_writeb(host, val: scratch8, SDHCI_POWER_CONTROL); |
678 | |
679 | /* Keep mode as UHSI */ |
680 | pci_read_config_word(dev: chip->pdev, O2_SD_PARA_SET_REG1, val: &scratch16); |
681 | scratch16 &= ~BIT(11); |
682 | pci_write_config_word(dev: chip->pdev, O2_SD_PARA_SET_REG1, val: scratch16); |
683 | |
684 | host->mmc->ios.timing = MMC_TIMING_LEGACY; |
685 | pr_info("%s: Express card initialization failed, falling back to Legacy\n" , |
686 | mmc_hostname(host->mmc)); |
687 | } |
688 | /* Lock WP */ |
689 | pci_read_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: &scratch8); |
690 | scratch8 |= 0x80; |
691 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch8); |
692 | |
693 | return 0; |
694 | } |
695 | |
696 | static int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot) |
697 | { |
698 | struct sdhci_pci_chip *chip; |
699 | struct sdhci_host *host; |
700 | struct o2_host *o2_host = sdhci_pci_priv(slot); |
701 | u32 reg, caps; |
702 | int ret; |
703 | |
704 | chip = slot->chip; |
705 | host = slot->host; |
706 | |
707 | o2_host->dll_adjust_count = 0; |
708 | caps = sdhci_readl(host, SDHCI_CAPABILITIES); |
709 | |
710 | /* |
711 | * mmc_select_bus_width() will test the bus to determine the actual bus |
712 | * width. |
713 | */ |
714 | if (caps & SDHCI_CAN_DO_8BIT) |
715 | host->mmc->caps |= MMC_CAP_8_BIT_DATA; |
716 | |
717 | host->quirks2 |= SDHCI_QUIRK2_BROKEN_DDR50; |
718 | |
719 | sdhci_pci_o2_enable_msi(chip, host); |
720 | |
721 | host->mmc_host_ops.execute_tuning = sdhci_o2_execute_tuning; |
722 | switch (chip->pdev->device) { |
723 | case PCI_DEVICE_ID_O2_SDS0: |
724 | case PCI_DEVICE_ID_O2_SEABIRD0: |
725 | case PCI_DEVICE_ID_O2_SEABIRD1: |
726 | case PCI_DEVICE_ID_O2_SDS1: |
727 | case PCI_DEVICE_ID_O2_FUJIN2: |
728 | reg = sdhci_readl(host, O2_SD_VENDOR_SETTING); |
729 | if (reg & 0x1) |
730 | host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; |
731 | |
732 | if (chip->pdev->device == PCI_DEVICE_ID_O2_SEABIRD0) { |
733 | ret = pci_read_config_dword(dev: chip->pdev, |
734 | O2_SD_MISC_SETTING, val: ®); |
735 | if (ret) |
736 | return -EIO; |
737 | if (reg & (1 << 4)) { |
738 | pr_info("%s: emmc 1.8v flag is set, force 1.8v signaling voltage\n" , |
739 | mmc_hostname(host->mmc)); |
740 | host->flags &= ~SDHCI_SIGNALING_330; |
741 | host->flags |= SDHCI_SIGNALING_180; |
742 | host->mmc->caps2 |= MMC_CAP2_NO_SD; |
743 | host->mmc->caps2 |= MMC_CAP2_NO_SDIO; |
744 | pci_write_config_dword(dev: chip->pdev, |
745 | O2_SD_DETECT_SETTING, val: 3); |
746 | } |
747 | |
748 | slot->host->mmc_host_ops.get_cd = sdhci_o2_get_cd; |
749 | } |
750 | |
751 | if (chip->pdev->device == PCI_DEVICE_ID_O2_SEABIRD1) { |
752 | slot->host->mmc_host_ops.get_cd = sdhci_o2_get_cd; |
753 | host->mmc->caps2 |= MMC_CAP2_NO_SDIO; |
754 | host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; |
755 | } |
756 | |
757 | if (chip->pdev->device != PCI_DEVICE_ID_O2_FUJIN2) |
758 | break; |
759 | /* set dll watch dog timer */ |
760 | reg = sdhci_readl(host, O2_SD_VENDOR_SETTING2); |
761 | reg |= (1 << 12); |
762 | sdhci_writel(host, val: reg, O2_SD_VENDOR_SETTING2); |
763 | break; |
764 | case PCI_DEVICE_ID_O2_GG8_9860: |
765 | case PCI_DEVICE_ID_O2_GG8_9861: |
766 | case PCI_DEVICE_ID_O2_GG8_9862: |
767 | case PCI_DEVICE_ID_O2_GG8_9863: |
768 | host->mmc->caps2 |= MMC_CAP2_NO_SDIO | MMC_CAP2_SD_EXP | MMC_CAP2_SD_EXP_1_2V; |
769 | host->mmc->caps |= MMC_CAP_HW_RESET; |
770 | host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; |
771 | slot->host->mmc_host_ops.get_cd = sdhci_o2_get_cd; |
772 | host->mmc_host_ops.init_sd_express = sdhci_pci_o2_init_sd_express; |
773 | break; |
774 | default: |
775 | break; |
776 | } |
777 | |
778 | return 0; |
779 | } |
780 | |
781 | static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) |
782 | { |
783 | int ret; |
784 | u8 scratch; |
785 | u16 scratch16; |
786 | u32 scratch_32; |
787 | |
788 | switch (chip->pdev->device) { |
789 | case PCI_DEVICE_ID_O2_8220: |
790 | case PCI_DEVICE_ID_O2_8221: |
791 | case PCI_DEVICE_ID_O2_8320: |
792 | case PCI_DEVICE_ID_O2_8321: |
793 | /* This extra setup is required due to broken ADMA. */ |
794 | ret = pci_read_config_byte(dev: chip->pdev, |
795 | O2_SD_LOCK_WP, val: &scratch); |
796 | if (ret) |
797 | return ret; |
798 | scratch &= 0x7f; |
799 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch); |
800 | |
801 | /* Set Multi 3 to VCC3V# */ |
802 | pci_write_config_byte(dev: chip->pdev, O2_SD_MULTI_VCC3V, val: 0x08); |
803 | |
804 | /* Disable CLK_REQ# support after media DET */ |
805 | ret = pci_read_config_byte(dev: chip->pdev, |
806 | O2_SD_CLKREQ, val: &scratch); |
807 | if (ret) |
808 | return ret; |
809 | scratch |= 0x20; |
810 | pci_write_config_byte(dev: chip->pdev, O2_SD_CLKREQ, val: scratch); |
811 | |
812 | /* Choose capabilities, enable SDMA. We have to write 0x01 |
813 | * to the capabilities register first to unlock it. |
814 | */ |
815 | ret = pci_read_config_byte(dev: chip->pdev, O2_SD_CAPS, val: &scratch); |
816 | if (ret) |
817 | return ret; |
818 | scratch |= 0x01; |
819 | pci_write_config_byte(dev: chip->pdev, O2_SD_CAPS, val: scratch); |
820 | pci_write_config_byte(dev: chip->pdev, O2_SD_CAPS, val: 0x73); |
821 | |
822 | /* Disable ADMA1/2 */ |
823 | pci_write_config_byte(dev: chip->pdev, O2_SD_ADMA1, val: 0x39); |
824 | pci_write_config_byte(dev: chip->pdev, O2_SD_ADMA2, val: 0x08); |
825 | |
826 | /* Disable the infinite transfer mode */ |
827 | ret = pci_read_config_byte(dev: chip->pdev, |
828 | O2_SD_INF_MOD, val: &scratch); |
829 | if (ret) |
830 | return ret; |
831 | scratch |= 0x08; |
832 | pci_write_config_byte(dev: chip->pdev, O2_SD_INF_MOD, val: scratch); |
833 | |
834 | /* Lock WP */ |
835 | ret = pci_read_config_byte(dev: chip->pdev, |
836 | O2_SD_LOCK_WP, val: &scratch); |
837 | if (ret) |
838 | return ret; |
839 | scratch |= 0x80; |
840 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch); |
841 | break; |
842 | case PCI_DEVICE_ID_O2_SDS0: |
843 | case PCI_DEVICE_ID_O2_SDS1: |
844 | case PCI_DEVICE_ID_O2_FUJIN2: |
845 | /* UnLock WP */ |
846 | ret = pci_read_config_byte(dev: chip->pdev, |
847 | O2_SD_LOCK_WP, val: &scratch); |
848 | if (ret) |
849 | return ret; |
850 | |
851 | scratch &= 0x7f; |
852 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch); |
853 | |
854 | /* DevId=8520 subId= 0x11 or 0x12 Type Chip support */ |
855 | if (chip->pdev->device == PCI_DEVICE_ID_O2_FUJIN2) { |
856 | ret = pci_read_config_dword(dev: chip->pdev, |
857 | O2_SD_FUNC_REG0, |
858 | val: &scratch_32); |
859 | if (ret) |
860 | return ret; |
861 | scratch_32 = ((scratch_32 & 0xFF000000) >> 24); |
862 | |
863 | /* Check Whether subId is 0x11 or 0x12 */ |
864 | if ((scratch_32 == 0x11) || (scratch_32 == 0x12)) { |
865 | scratch_32 = 0x25100000; |
866 | |
867 | o2_pci_set_baseclk(chip, value: scratch_32); |
868 | ret = pci_read_config_dword(dev: chip->pdev, |
869 | O2_SD_FUNC_REG4, |
870 | val: &scratch_32); |
871 | if (ret) |
872 | return ret; |
873 | |
874 | /* Enable Base Clk setting change */ |
875 | scratch_32 |= O2_SD_FREG4_ENABLE_CLK_SET; |
876 | pci_write_config_dword(dev: chip->pdev, |
877 | O2_SD_FUNC_REG4, |
878 | val: scratch_32); |
879 | |
880 | /* Set Tuning Window to 4 */ |
881 | pci_write_config_byte(dev: chip->pdev, |
882 | O2_SD_TUNING_CTRL, val: 0x44); |
883 | |
884 | break; |
885 | } |
886 | } |
887 | |
888 | /* Enable 8520 led function */ |
889 | o2_pci_led_enable(chip); |
890 | |
891 | /* Set timeout CLK */ |
892 | ret = pci_read_config_dword(dev: chip->pdev, |
893 | O2_SD_CLK_SETTING, val: &scratch_32); |
894 | if (ret) |
895 | return ret; |
896 | |
897 | scratch_32 &= ~(0xFF00); |
898 | scratch_32 |= 0x07E0C800; |
899 | pci_write_config_dword(dev: chip->pdev, |
900 | O2_SD_CLK_SETTING, val: scratch_32); |
901 | |
902 | ret = pci_read_config_dword(dev: chip->pdev, |
903 | O2_SD_CLKREQ, val: &scratch_32); |
904 | if (ret) |
905 | return ret; |
906 | scratch_32 |= 0x3; |
907 | pci_write_config_dword(dev: chip->pdev, O2_SD_CLKREQ, val: scratch_32); |
908 | |
909 | ret = pci_read_config_dword(dev: chip->pdev, |
910 | O2_SD_PLL_SETTING, val: &scratch_32); |
911 | if (ret) |
912 | return ret; |
913 | |
914 | scratch_32 &= ~(0x1F3F070E); |
915 | scratch_32 |= 0x18270106; |
916 | pci_write_config_dword(dev: chip->pdev, |
917 | O2_SD_PLL_SETTING, val: scratch_32); |
918 | |
919 | /* Disable UHS1 funciton */ |
920 | ret = pci_read_config_dword(dev: chip->pdev, |
921 | O2_SD_CAP_REG2, val: &scratch_32); |
922 | if (ret) |
923 | return ret; |
924 | scratch_32 &= ~(0xE0); |
925 | pci_write_config_dword(dev: chip->pdev, |
926 | O2_SD_CAP_REG2, val: scratch_32); |
927 | |
928 | if (chip->pdev->device == PCI_DEVICE_ID_O2_FUJIN2) |
929 | sdhci_pci_o2_fujin2_pci_init(chip); |
930 | |
931 | /* Lock WP */ |
932 | ret = pci_read_config_byte(dev: chip->pdev, |
933 | O2_SD_LOCK_WP, val: &scratch); |
934 | if (ret) |
935 | return ret; |
936 | scratch |= 0x80; |
937 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch); |
938 | break; |
939 | case PCI_DEVICE_ID_O2_SEABIRD0: |
940 | case PCI_DEVICE_ID_O2_SEABIRD1: |
941 | /* UnLock WP */ |
942 | ret = pci_read_config_byte(dev: chip->pdev, |
943 | O2_SD_LOCK_WP, val: &scratch); |
944 | if (ret) |
945 | return ret; |
946 | |
947 | scratch &= 0x7f; |
948 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch); |
949 | |
950 | ret = pci_read_config_dword(dev: chip->pdev, |
951 | O2_SD_PLL_SETTING, val: &scratch_32); |
952 | if (ret) |
953 | return ret; |
954 | |
955 | if ((scratch_32 & 0xff000000) == 0x01000000) { |
956 | scratch_32 &= 0x0000FFFF; |
957 | scratch_32 |= 0x1F340000; |
958 | |
959 | pci_write_config_dword(dev: chip->pdev, |
960 | O2_SD_PLL_SETTING, val: scratch_32); |
961 | } else { |
962 | scratch_32 &= 0x0000FFFF; |
963 | scratch_32 |= 0x25100000; |
964 | |
965 | pci_write_config_dword(dev: chip->pdev, |
966 | O2_SD_PLL_SETTING, val: scratch_32); |
967 | |
968 | ret = pci_read_config_dword(dev: chip->pdev, |
969 | O2_SD_FUNC_REG4, |
970 | val: &scratch_32); |
971 | if (ret) |
972 | return ret; |
973 | scratch_32 |= (1 << 22); |
974 | pci_write_config_dword(dev: chip->pdev, |
975 | O2_SD_FUNC_REG4, val: scratch_32); |
976 | } |
977 | |
978 | /* Set Tuning Windows to 5 */ |
979 | pci_write_config_byte(dev: chip->pdev, |
980 | O2_SD_TUNING_CTRL, val: 0x55); |
981 | //Adjust 1st and 2nd CD debounce time |
982 | pci_read_config_dword(dev: chip->pdev, O2_SD_MISC_CTRL2, val: &scratch_32); |
983 | scratch_32 &= 0xFFE7FFFF; |
984 | scratch_32 |= 0x00180000; |
985 | pci_write_config_dword(dev: chip->pdev, O2_SD_MISC_CTRL2, val: scratch_32); |
986 | pci_write_config_dword(dev: chip->pdev, O2_SD_DETECT_SETTING, val: 1); |
987 | /* Lock WP */ |
988 | ret = pci_read_config_byte(dev: chip->pdev, |
989 | O2_SD_LOCK_WP, val: &scratch); |
990 | if (ret) |
991 | return ret; |
992 | scratch |= 0x80; |
993 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch); |
994 | break; |
995 | case PCI_DEVICE_ID_O2_GG8_9860: |
996 | case PCI_DEVICE_ID_O2_GG8_9861: |
997 | case PCI_DEVICE_ID_O2_GG8_9862: |
998 | case PCI_DEVICE_ID_O2_GG8_9863: |
999 | /* UnLock WP */ |
1000 | ret = pci_read_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: &scratch); |
1001 | if (ret) |
1002 | return ret; |
1003 | scratch &= 0x7f; |
1004 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch); |
1005 | |
1006 | /* Select mode switch source as software control */ |
1007 | pci_read_config_word(dev: chip->pdev, O2_SD_PARA_SET_REG1, val: &scratch16); |
1008 | scratch16 &= 0xF8FF; |
1009 | scratch16 |= BIT(9); |
1010 | pci_write_config_word(dev: chip->pdev, O2_SD_PARA_SET_REG1, val: scratch16); |
1011 | |
1012 | /* set VDD1 supply source */ |
1013 | pci_read_config_word(dev: chip->pdev, O2_SD_VDDX_CTRL_REG, val: &scratch16); |
1014 | scratch16 &= 0xFFE3; |
1015 | scratch16 |= BIT(3); |
1016 | pci_write_config_word(dev: chip->pdev, O2_SD_VDDX_CTRL_REG, val: scratch16); |
1017 | |
1018 | /* Set host drive strength*/ |
1019 | scratch16 = 0x0025; |
1020 | pci_write_config_word(dev: chip->pdev, O2_SD_PLL_SETTING, val: scratch16); |
1021 | |
1022 | /* Set output delay*/ |
1023 | pci_read_config_dword(dev: chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, val: &scratch_32); |
1024 | scratch_32 &= 0xFF0FFF00; |
1025 | scratch_32 |= 0x00B0003B; |
1026 | pci_write_config_dword(dev: chip->pdev, O2_SD_OUTPUT_CLK_SOURCE_SWITCH, val: scratch_32); |
1027 | |
1028 | /* Lock WP */ |
1029 | ret = pci_read_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: &scratch); |
1030 | if (ret) |
1031 | return ret; |
1032 | scratch |= 0x80; |
1033 | pci_write_config_byte(dev: chip->pdev, O2_SD_LOCK_WP, val: scratch); |
1034 | break; |
1035 | } |
1036 | |
1037 | return 0; |
1038 | } |
1039 | |
1040 | #ifdef CONFIG_PM_SLEEP |
1041 | static int sdhci_pci_o2_resume(struct sdhci_pci_chip *chip) |
1042 | { |
1043 | sdhci_pci_o2_probe(chip); |
1044 | return sdhci_pci_resume_host(chip); |
1045 | } |
1046 | #endif |
1047 | |
1048 | static const struct sdhci_ops sdhci_pci_o2_ops = { |
1049 | .set_clock = sdhci_pci_o2_set_clock, |
1050 | .enable_dma = sdhci_pci_enable_dma, |
1051 | .set_bus_width = sdhci_set_bus_width, |
1052 | .reset = sdhci_reset, |
1053 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
1054 | }; |
1055 | |
1056 | const struct sdhci_pci_fixes sdhci_o2 = { |
1057 | .probe = sdhci_pci_o2_probe, |
1058 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
1059 | .quirks2 = SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD, |
1060 | .probe_slot = sdhci_pci_o2_probe_slot, |
1061 | #ifdef CONFIG_PM_SLEEP |
1062 | .resume = sdhci_pci_o2_resume, |
1063 | #endif |
1064 | .ops = &sdhci_pci_o2_ops, |
1065 | .priv_size = sizeof(struct o2_host), |
1066 | }; |
1067 | |