1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* Driver for Realtek PCI-Express card reader |
3 | * |
4 | * Copyright(c) 2016-2017 Realtek Semiconductor Corp. All rights reserved. |
5 | * |
6 | * Author: |
7 | * Steven FENG <steven_feng@realsil.com.cn> |
8 | * Rui FENG <rui_feng@realsil.com.cn> |
9 | * Wei WANG <wei_wang@realsil.com.cn> |
10 | */ |
11 | |
12 | #include <linux/module.h> |
13 | #include <linux/delay.h> |
14 | #include <linux/rtsx_pci.h> |
15 | |
16 | #include "rts5260.h" |
17 | #include "rtsx_pcr.h" |
18 | |
19 | static u8 rts5260_get_ic_version(struct rtsx_pcr *pcr) |
20 | { |
21 | u8 val; |
22 | |
23 | rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, data: &val); |
24 | return val & IC_VERSION_MASK; |
25 | } |
26 | |
27 | static void rts5260_fill_driving(struct rtsx_pcr *pcr, u8 voltage) |
28 | { |
29 | u8 driving_3v3[4][3] = { |
30 | {0x11, 0x11, 0x11}, |
31 | {0x22, 0x22, 0x22}, |
32 | {0x55, 0x55, 0x55}, |
33 | {0x33, 0x33, 0x33}, |
34 | }; |
35 | u8 driving_1v8[4][3] = { |
36 | {0x35, 0x33, 0x33}, |
37 | {0x8A, 0x88, 0x88}, |
38 | {0xBD, 0xBB, 0xBB}, |
39 | {0x9B, 0x99, 0x99}, |
40 | }; |
41 | u8 (*driving)[3], drive_sel; |
42 | |
43 | if (voltage == OUTPUT_3V3) { |
44 | driving = driving_3v3; |
45 | drive_sel = pcr->sd30_drive_sel_3v3; |
46 | } else { |
47 | driving = driving_1v8; |
48 | drive_sel = pcr->sd30_drive_sel_1v8; |
49 | } |
50 | |
51 | rtsx_pci_write_register(pcr, SD30_CLK_DRIVE_SEL, |
52 | mask: 0xFF, data: driving[drive_sel][0]); |
53 | |
54 | rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL, |
55 | mask: 0xFF, data: driving[drive_sel][1]); |
56 | |
57 | rtsx_pci_write_register(pcr, SD30_DAT_DRIVE_SEL, |
58 | mask: 0xFF, data: driving[drive_sel][2]); |
59 | } |
60 | |
61 | static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr) |
62 | { |
63 | struct pci_dev *pdev = pcr->pci; |
64 | u32 reg; |
65 | |
66 | pci_read_config_dword(dev: pdev, PCR_SETTING_REG1, val: ®); |
67 | pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n" , PCR_SETTING_REG1, reg); |
68 | |
69 | if (!rtsx_vendor_setting_valid(reg)) { |
70 | pcr_dbg(pcr, "skip fetch vendor setting\n" ); |
71 | return; |
72 | } |
73 | |
74 | pcr->aspm_en = rtsx_reg_to_aspm(reg); |
75 | pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg); |
76 | pcr->card_drive_sel &= 0x3F; |
77 | pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg); |
78 | |
79 | pci_read_config_dword(dev: pdev, PCR_SETTING_REG2, val: ®); |
80 | pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n" , PCR_SETTING_REG2, reg); |
81 | if (rtsx_check_mmc_support(reg)) |
82 | pcr->extra_caps |= EXTRA_CAPS_NO_MMC; |
83 | pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg); |
84 | if (rtsx_reg_check_reverse_socket(reg)) |
85 | pcr->flags |= PCR_REVERSE_SOCKET; |
86 | } |
87 | |
88 | static int rtsx_base_enable_auto_blink(struct rtsx_pcr *pcr) |
89 | { |
90 | return rtsx_pci_write_register(pcr, OLT_LED_CTL, |
91 | LED_SHINE_MASK, LED_SHINE_EN); |
92 | } |
93 | |
94 | static int rtsx_base_disable_auto_blink(struct rtsx_pcr *pcr) |
95 | { |
96 | return rtsx_pci_write_register(pcr, OLT_LED_CTL, |
97 | LED_SHINE_MASK, LED_SHINE_DISABLE); |
98 | } |
99 | |
100 | static int rts5260_turn_on_led(struct rtsx_pcr *pcr) |
101 | { |
102 | return rtsx_pci_write_register(pcr, RTS5260_REG_GPIO_CTL0, |
103 | RTS5260_REG_GPIO_MASK, RTS5260_REG_GPIO_ON); |
104 | } |
105 | |
106 | static int rts5260_turn_off_led(struct rtsx_pcr *pcr) |
107 | { |
108 | return rtsx_pci_write_register(pcr, RTS5260_REG_GPIO_CTL0, |
109 | RTS5260_REG_GPIO_MASK, RTS5260_REG_GPIO_OFF); |
110 | } |
111 | |
112 | /* SD Pull Control Enable: |
113 | * SD_DAT[3:0] ==> pull up |
114 | * SD_CD ==> pull up |
115 | * SD_WP ==> pull up |
116 | * SD_CMD ==> pull up |
117 | * SD_CLK ==> pull down |
118 | */ |
119 | static const u32 rts5260_sd_pull_ctl_enable_tbl[] = { |
120 | RTSX_REG_PAIR(CARD_PULL_CTL1, 0x66), |
121 | RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA), |
122 | RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9), |
123 | RTSX_REG_PAIR(CARD_PULL_CTL4, 0xAA), |
124 | 0, |
125 | }; |
126 | |
127 | /* SD Pull Control Disable: |
128 | * SD_DAT[3:0] ==> pull down |
129 | * SD_CD ==> pull up |
130 | * SD_WP ==> pull down |
131 | * SD_CMD ==> pull down |
132 | * SD_CLK ==> pull down |
133 | */ |
134 | static const u32 rts5260_sd_pull_ctl_disable_tbl[] = { |
135 | RTSX_REG_PAIR(CARD_PULL_CTL1, 0x66), |
136 | RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55), |
137 | RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5), |
138 | RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55), |
139 | 0, |
140 | }; |
141 | |
142 | /* MS Pull Control Enable: |
143 | * MS CD ==> pull up |
144 | * others ==> pull down |
145 | */ |
146 | static const u32 rts5260_ms_pull_ctl_enable_tbl[] = { |
147 | RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55), |
148 | RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55), |
149 | RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15), |
150 | 0, |
151 | }; |
152 | |
153 | /* MS Pull Control Disable: |
154 | * MS CD ==> pull up |
155 | * others ==> pull down |
156 | */ |
157 | static const u32 rts5260_ms_pull_ctl_disable_tbl[] = { |
158 | RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55), |
159 | RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55), |
160 | RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15), |
161 | 0, |
162 | }; |
163 | |
164 | static int sd_set_sample_push_timing_sd30(struct rtsx_pcr *pcr) |
165 | { |
166 | rtsx_pci_write_register(pcr, SD_CFG1, SD_MODE_SELECT_MASK |
167 | | SD_ASYNC_FIFO_NOT_RST, SD_30_MODE | SD_ASYNC_FIFO_NOT_RST); |
168 | rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); |
169 | rtsx_pci_write_register(pcr, CARD_CLK_SOURCE, mask: 0xFF, |
170 | CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); |
171 | rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, data: 0); |
172 | |
173 | return 0; |
174 | } |
175 | |
176 | static int rts5260_card_power_on(struct rtsx_pcr *pcr, int card) |
177 | { |
178 | struct rtsx_cr_option *option = &pcr->option; |
179 | |
180 | if (option->ocp_en) |
181 | rtsx_pci_enable_ocp(pcr); |
182 | |
183 | |
184 | rtsx_pci_write_register(pcr, LDO_CONFIG2, DV331812_VDD1, DV331812_VDD1); |
185 | rtsx_pci_write_register(pcr, LDO_VCC_CFG0, |
186 | RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33); |
187 | |
188 | rtsx_pci_write_register(pcr, LDO_VCC_CFG1, LDO_POW_SDVDD1_MASK, |
189 | LDO_POW_SDVDD1_ON); |
190 | |
191 | rtsx_pci_write_register(pcr, LDO_CONFIG2, |
192 | DV331812_POWERON, DV331812_POWERON); |
193 | msleep(msecs: 20); |
194 | |
195 | if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50 || |
196 | pcr->extra_caps & EXTRA_CAPS_SD_SDR104) |
197 | sd_set_sample_push_timing_sd30(pcr); |
198 | |
199 | /* Initialize SD_CFG1 register */ |
200 | rtsx_pci_write_register(pcr, SD_CFG1, mask: 0xFF, |
201 | SD_CLK_DIVIDE_128 | SD_20_MODE); |
202 | |
203 | rtsx_pci_write_register(pcr, SD_SAMPLE_POINT_CTL, |
204 | mask: 0xFF, SD20_RX_POS_EDGE); |
205 | rtsx_pci_write_register(pcr, SD_PUSH_POINT_CTL, mask: 0xFF, data: 0); |
206 | rtsx_pci_write_register(pcr, CARD_STOP, SD_STOP | SD_CLR_ERR, |
207 | SD_STOP | SD_CLR_ERR); |
208 | |
209 | /* Reset SD_CFG3 register */ |
210 | rtsx_pci_write_register(pcr, SD_CFG3, SD30_CLK_END_EN, data: 0); |
211 | rtsx_pci_write_register(pcr, REG_SD_STOP_SDCLK_CFG, |
212 | SD30_CLK_STOP_CFG_EN | SD30_CLK_STOP_CFG1 | |
213 | SD30_CLK_STOP_CFG0, data: 0); |
214 | |
215 | rtsx_pci_write_register(pcr, REG_PRE_RW_MODE, EN_INFINITE_MODE, data: 0); |
216 | |
217 | return 0; |
218 | } |
219 | |
220 | static int rts5260_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) |
221 | { |
222 | switch (voltage) { |
223 | case OUTPUT_3V3: |
224 | rtsx_pci_write_register(pcr, LDO_CONFIG2, |
225 | DV331812_VDD1, DV331812_VDD1); |
226 | rtsx_pci_write_register(pcr, LDO_DV18_CFG, |
227 | DV331812_MASK, DV331812_33); |
228 | rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, data: 0); |
229 | break; |
230 | case OUTPUT_1V8: |
231 | rtsx_pci_write_register(pcr, LDO_CONFIG2, |
232 | DV331812_VDD1, DV331812_VDD1); |
233 | rtsx_pci_write_register(pcr, LDO_DV18_CFG, |
234 | DV331812_MASK, DV331812_17); |
235 | rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, |
236 | SD_IO_USING_1V8); |
237 | break; |
238 | default: |
239 | return -EINVAL; |
240 | } |
241 | |
242 | /* set pad drive */ |
243 | rts5260_fill_driving(pcr, voltage); |
244 | |
245 | return 0; |
246 | } |
247 | |
248 | static void rts5260_stop_cmd(struct rtsx_pcr *pcr) |
249 | { |
250 | rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD); |
251 | rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA); |
252 | rtsx_pci_write_register(pcr, RTS5260_DMA_RST_CTL_0, |
253 | RTS5260_DMA_RST | RTS5260_ADMA3_RST, |
254 | RTS5260_DMA_RST | RTS5260_ADMA3_RST); |
255 | rtsx_pci_write_register(pcr, RBCTL, RB_FLUSH, RB_FLUSH); |
256 | } |
257 | |
258 | static void rts5260_card_before_power_off(struct rtsx_pcr *pcr) |
259 | { |
260 | rts5260_stop_cmd(pcr); |
261 | rts5260_switch_output_voltage(pcr, OUTPUT_3V3); |
262 | |
263 | } |
264 | |
265 | static int rts5260_card_power_off(struct rtsx_pcr *pcr, int card) |
266 | { |
267 | int err = 0; |
268 | |
269 | rts5260_card_before_power_off(pcr); |
270 | err = rtsx_pci_write_register(pcr, LDO_VCC_CFG1, |
271 | LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF); |
272 | err = rtsx_pci_write_register(pcr, LDO_CONFIG2, |
273 | DV331812_POWERON, DV331812_POWEROFF); |
274 | if (pcr->option.ocp_en) |
275 | rtsx_pci_disable_ocp(pcr); |
276 | |
277 | return err; |
278 | } |
279 | |
280 | static void rts5260_init_ocp(struct rtsx_pcr *pcr) |
281 | { |
282 | struct rtsx_cr_option *option = &pcr->option; |
283 | |
284 | if (option->ocp_en) { |
285 | u8 mask, val; |
286 | |
287 | |
288 | rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, |
289 | RTS5260_DVCC_OCP_THD_MASK, |
290 | data: option->sd_800mA_ocp_thd); |
291 | |
292 | rtsx_pci_write_register(pcr, RTS5260_DV331812_CFG, |
293 | RTS5260_DV331812_OCP_THD_MASK, |
294 | RTS5260_DV331812_OCP_THD_270); |
295 | |
296 | mask = SD_OCP_GLITCH_MASK; |
297 | val = pcr->hw_param.ocp_glitch; |
298 | rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, data: val); |
299 | rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, |
300 | RTS5260_DVCC_OCP_EN | |
301 | RTS5260_DVCC_OCP_CL_EN, |
302 | RTS5260_DVCC_OCP_EN | |
303 | RTS5260_DVCC_OCP_CL_EN); |
304 | |
305 | rtsx_pci_enable_ocp(pcr); |
306 | } else { |
307 | rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, |
308 | RTS5260_DVCC_OCP_EN | |
309 | RTS5260_DVCC_OCP_CL_EN, data: 0); |
310 | } |
311 | } |
312 | |
313 | static void rts5260_enable_ocp(struct rtsx_pcr *pcr) |
314 | { |
315 | u8 val = 0; |
316 | |
317 | val = SD_OCP_INT_EN | SD_DETECT_EN; |
318 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask: 0xFF, data: val); |
319 | |
320 | } |
321 | |
322 | static void rts5260_disable_ocp(struct rtsx_pcr *pcr) |
323 | { |
324 | u8 mask = 0; |
325 | |
326 | mask = SD_OCP_INT_EN | SD_DETECT_EN; |
327 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask, data: 0); |
328 | |
329 | } |
330 | |
331 | |
332 | static int rts5260_get_ocpstat(struct rtsx_pcr *pcr, u8 *val) |
333 | { |
334 | return rtsx_pci_read_register(pcr, REG_OCPSTAT, data: val); |
335 | } |
336 | |
337 | static int rts5260_get_ocpstat2(struct rtsx_pcr *pcr, u8 *val) |
338 | { |
339 | return rtsx_pci_read_register(pcr, REG_DV3318_OCPSTAT, data: val); |
340 | } |
341 | |
342 | static void rts5260_clear_ocpstat(struct rtsx_pcr *pcr) |
343 | { |
344 | u8 mask = 0; |
345 | u8 val = 0; |
346 | |
347 | mask = SD_OCP_INT_CLR | SD_OC_CLR; |
348 | val = SD_OCP_INT_CLR | SD_OC_CLR; |
349 | |
350 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask, data: val); |
351 | rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL, |
352 | DV3318_OCP_INT_CLR | DV3318_OCP_CLR, |
353 | DV3318_OCP_INT_CLR | DV3318_OCP_CLR); |
354 | udelay(10); |
355 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask, data: 0); |
356 | rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL, |
357 | DV3318_OCP_INT_CLR | DV3318_OCP_CLR, data: 0); |
358 | } |
359 | |
360 | static void rts5260_process_ocp(struct rtsx_pcr *pcr) |
361 | { |
362 | if (!pcr->option.ocp_en) |
363 | return; |
364 | |
365 | rtsx_pci_get_ocpstat(pcr, val: &pcr->ocp_stat); |
366 | rts5260_get_ocpstat2(pcr, val: &pcr->ocp_stat2); |
367 | |
368 | if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) || |
369 | (pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) { |
370 | rtsx_pci_card_power_off(pcr, RTSX_SD_CARD); |
371 | rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, data: 0); |
372 | rtsx_pci_clear_ocpstat(pcr); |
373 | pcr->ocp_stat = 0; |
374 | pcr->ocp_stat2 = 0; |
375 | } |
376 | |
377 | } |
378 | |
379 | static int rts5260_init_hw(struct rtsx_pcr *pcr) |
380 | { |
381 | int err; |
382 | |
383 | rtsx_pci_init_cmd(pcr); |
384 | |
385 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG1, |
386 | AUX_CLK_ACTIVE_SEL_MASK, MAC_CKSW_DONE); |
387 | /* Rest L1SUB Config */ |
388 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG3, mask: 0xFF, data: 0x00); |
389 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CLK_FORCE_CTL, |
390 | CLK_PM_EN, CLK_PM_EN); |
391 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWD_SUSPEND_EN, mask: 0xFF, data: 0xFF); |
392 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, |
393 | PWR_GATE_EN, PWR_GATE_EN); |
394 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, REG_VREF, |
395 | PWD_SUSPND_EN, PWD_SUSPND_EN); |
396 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, RBCTL, |
397 | U_AUTO_DMA_EN_MASK, U_AUTO_DMA_DISABLE); |
398 | |
399 | if (pcr->flags & PCR_REVERSE_SOCKET) |
400 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, mask: 0xB0, data: 0xB0); |
401 | else |
402 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, mask: 0xB0, data: 0x80); |
403 | |
404 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, |
405 | OBFF_EN_MASK, OBFF_DISABLE); |
406 | |
407 | err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF); |
408 | if (err < 0) |
409 | return err; |
410 | |
411 | rtsx_pci_init_ocp(pcr); |
412 | |
413 | return 0; |
414 | } |
415 | |
416 | static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr) |
417 | { |
418 | int lss_l1_1, lss_l1_2; |
419 | |
420 | lss_l1_1 = rtsx_check_dev_flag(pcr, ASPM_L1_1_EN) |
421 | | rtsx_check_dev_flag(pcr, PM_L1_1_EN); |
422 | lss_l1_2 = rtsx_check_dev_flag(pcr, ASPM_L1_2_EN) |
423 | | rtsx_check_dev_flag(pcr, PM_L1_2_EN); |
424 | |
425 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask: 0xFF, data: 0); |
426 | if (lss_l1_2) { |
427 | pcr_dbg(pcr, "Set parameters for L1.2." ); |
428 | rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL, |
429 | mask: 0xFF, PCIE_L1_2_EN); |
430 | rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, |
431 | RTS5260_DVCC_OCP_EN | |
432 | RTS5260_DVCC_OCP_CL_EN, |
433 | RTS5260_DVCC_OCP_EN | |
434 | RTS5260_DVCC_OCP_CL_EN); |
435 | |
436 | rtsx_pci_write_register(pcr, PWR_FE_CTL, |
437 | mask: 0xFF, PCIE_L1_2_PD_FE_EN); |
438 | } else if (lss_l1_1) { |
439 | pcr_dbg(pcr, "Set parameters for L1.1." ); |
440 | rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL, |
441 | mask: 0xFF, PCIE_L1_1_EN); |
442 | rtsx_pci_write_register(pcr, PWR_FE_CTL, |
443 | mask: 0xFF, PCIE_L1_1_PD_FE_EN); |
444 | } else { |
445 | pcr_dbg(pcr, "Set parameters for L1." ); |
446 | rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL, |
447 | mask: 0xFF, PCIE_L1_0_EN); |
448 | rtsx_pci_write_register(pcr, PWR_FE_CTL, |
449 | mask: 0xFF, PCIE_L1_0_PD_FE_EN); |
450 | } |
451 | |
452 | rtsx_pci_write_register(pcr, CFG_L1_0_PCIE_DPHY_RET_VALUE, |
453 | mask: 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); |
454 | rtsx_pci_write_register(pcr, CFG_L1_0_PCIE_MAC_RET_VALUE, |
455 | mask: 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); |
456 | rtsx_pci_write_register(pcr, CFG_L1_0_CRC_SD30_RET_VALUE, |
457 | mask: 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); |
458 | rtsx_pci_write_register(pcr, CFG_L1_0_CRC_SD40_RET_VALUE, |
459 | mask: 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); |
460 | rtsx_pci_write_register(pcr, CFG_L1_0_SYS_RET_VALUE, |
461 | mask: 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); |
462 | /*Option cut APHY*/ |
463 | rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_0, |
464 | mask: 0xFF, CFG_PCIE_APHY_OFF_0_DEFAULT); |
465 | rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_1, |
466 | mask: 0xFF, CFG_PCIE_APHY_OFF_1_DEFAULT); |
467 | rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_2, |
468 | mask: 0xFF, CFG_PCIE_APHY_OFF_2_DEFAULT); |
469 | rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_3, |
470 | mask: 0xFF, CFG_PCIE_APHY_OFF_3_DEFAULT); |
471 | /*CDR DEC*/ |
472 | rtsx_pci_write_register(pcr, PWC_CDR, mask: 0xFF, PWC_CDR_DEFAULT); |
473 | /*PWMPFM*/ |
474 | rtsx_pci_write_register(pcr, CFG_LP_FPWM_VALUE, |
475 | mask: 0xFF, CFG_LP_FPWM_VALUE_DEFAULT); |
476 | /*No Power Saving WA*/ |
477 | rtsx_pci_write_register(pcr, CFG_L1_0_CRC_MISC_RET_VALUE, |
478 | mask: 0xFF, CFG_L1_0_CRC_MISC_RET_VALUE_DEFAULT); |
479 | } |
480 | |
481 | static void rts5260_init_from_cfg(struct rtsx_pcr *pcr) |
482 | { |
483 | struct rtsx_cr_option *option = &pcr->option; |
484 | |
485 | rts5260_pwr_saving_setting(pcr); |
486 | |
487 | if (option->ltr_en) { |
488 | if (option->ltr_enabled) |
489 | rtsx_set_ltr_latency(pcr, latency: option->ltr_active_latency); |
490 | } |
491 | } |
492 | |
493 | static int (struct rtsx_pcr *pcr) |
494 | { |
495 | struct rtsx_cr_option *option = &pcr->option; |
496 | |
497 | /* Set mcu_cnt to 7 to ensure data can be sampled properly */ |
498 | rtsx_pci_write_register(pcr, addr: 0xFC03, mask: 0x7F, data: 0x07); |
499 | rtsx_pci_write_register(pcr, SSC_DIV_N_0, mask: 0xFF, data: 0x5D); |
500 | |
501 | rts5260_init_from_cfg(pcr); |
502 | |
503 | /* force no MDIO*/ |
504 | rtsx_pci_write_register(pcr, RTS5260_AUTOLOAD_CFG4, |
505 | mask: 0xFF, RTS5260_MIMO_DISABLE); |
506 | /*Modify SDVCC Tune Default Parameters!*/ |
507 | rtsx_pci_write_register(pcr, LDO_VCC_CFG0, |
508 | RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33); |
509 | |
510 | rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL); |
511 | |
512 | rts5260_init_hw(pcr); |
513 | |
514 | /* |
515 | * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced |
516 | * to drive low, and we forcibly request clock. |
517 | */ |
518 | if (option->force_clkreq_0) |
519 | rtsx_pci_write_register(pcr, PETXCFG, |
520 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); |
521 | else |
522 | rtsx_pci_write_register(pcr, PETXCFG, |
523 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); |
524 | |
525 | rtsx_pci_write_register(pcr, addr: pcr->reg_pm_ctrl3, mask: 0x10, data: 0x00); |
526 | |
527 | return 0; |
528 | } |
529 | |
530 | static void rts5260_set_l1off_cfg_sub_d0(struct rtsx_pcr *pcr, int active) |
531 | { |
532 | struct rtsx_cr_option *option = &pcr->option; |
533 | u32 interrupt = rtsx_pci_readl(pcr, RTSX_BIPR); |
534 | int card_exist = (interrupt & SD_EXIST) | (interrupt & MS_EXIST); |
535 | int aspm_L1_1, aspm_L1_2; |
536 | u8 val = 0; |
537 | |
538 | aspm_L1_1 = rtsx_check_dev_flag(pcr, ASPM_L1_1_EN); |
539 | aspm_L1_2 = rtsx_check_dev_flag(pcr, ASPM_L1_2_EN); |
540 | |
541 | if (active) { |
542 | /* run, latency: 60us */ |
543 | if (aspm_L1_1) |
544 | val = option->ltr_l1off_snooze_sspwrgate; |
545 | } else { |
546 | /* l1off, latency: 300us */ |
547 | if (aspm_L1_2) |
548 | val = option->ltr_l1off_sspwrgate; |
549 | } |
550 | |
551 | if (aspm_L1_1 || aspm_L1_2) { |
552 | if (rtsx_check_dev_flag(pcr, |
553 | LTR_L1SS_PWR_GATE_CHECK_CARD_EN)) { |
554 | if (card_exist) |
555 | val &= ~L1OFF_MBIAS2_EN_5250; |
556 | else |
557 | val |= L1OFF_MBIAS2_EN_5250; |
558 | } |
559 | } |
560 | rtsx_set_l1off_sub(pcr, val); |
561 | } |
562 | |
563 | static const struct pcr_ops rts5260_pcr_ops = { |
564 | .fetch_vendor_settings = rtsx_base_fetch_vendor_settings, |
565 | .turn_on_led = rts5260_turn_on_led, |
566 | .turn_off_led = rts5260_turn_off_led, |
567 | .extra_init_hw = rts5260_extra_init_hw, |
568 | .enable_auto_blink = rtsx_base_enable_auto_blink, |
569 | .disable_auto_blink = rtsx_base_disable_auto_blink, |
570 | .card_power_on = rts5260_card_power_on, |
571 | .card_power_off = rts5260_card_power_off, |
572 | .switch_output_voltage = rts5260_switch_output_voltage, |
573 | .stop_cmd = rts5260_stop_cmd, |
574 | .set_l1off_cfg_sub_d0 = rts5260_set_l1off_cfg_sub_d0, |
575 | .enable_ocp = rts5260_enable_ocp, |
576 | .disable_ocp = rts5260_disable_ocp, |
577 | .init_ocp = rts5260_init_ocp, |
578 | .process_ocp = rts5260_process_ocp, |
579 | .get_ocpstat = rts5260_get_ocpstat, |
580 | .clear_ocpstat = rts5260_clear_ocpstat, |
581 | }; |
582 | |
583 | void rts5260_init_params(struct rtsx_pcr *pcr) |
584 | { |
585 | struct rtsx_cr_option *option = &pcr->option; |
586 | struct rtsx_hw_param *hw_param = &pcr->hw_param; |
587 | |
588 | pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104; |
589 | pcr->num_slots = 2; |
590 | |
591 | pcr->flags = 0; |
592 | pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT; |
593 | pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; |
594 | pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; |
595 | pcr->aspm_en = ASPM_L1_EN; |
596 | pcr->aspm_mode = ASPM_MODE_REG; |
597 | pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 29, 11); |
598 | pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); |
599 | |
600 | pcr->ic_version = rts5260_get_ic_version(pcr); |
601 | pcr->sd_pull_ctl_enable_tbl = rts5260_sd_pull_ctl_enable_tbl; |
602 | pcr->sd_pull_ctl_disable_tbl = rts5260_sd_pull_ctl_disable_tbl; |
603 | pcr->ms_pull_ctl_enable_tbl = rts5260_ms_pull_ctl_enable_tbl; |
604 | pcr->ms_pull_ctl_disable_tbl = rts5260_ms_pull_ctl_disable_tbl; |
605 | |
606 | pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3; |
607 | |
608 | pcr->ops = &rts5260_pcr_ops; |
609 | |
610 | option->dev_flags = (LTR_L1SS_PWR_GATE_CHECK_CARD_EN |
611 | | LTR_L1SS_PWR_GATE_EN); |
612 | option->ltr_en = true; |
613 | |
614 | /* init latency of active, idle, L1OFF to 60us, 300us, 3ms */ |
615 | option->ltr_active_latency = LTR_ACTIVE_LATENCY_DEF; |
616 | option->ltr_idle_latency = LTR_IDLE_LATENCY_DEF; |
617 | option->ltr_l1off_latency = LTR_L1OFF_LATENCY_DEF; |
618 | option->l1_snooze_delay = L1_SNOOZE_DELAY_DEF; |
619 | option->ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; |
620 | option->ltr_l1off_snooze_sspwrgate = |
621 | LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF; |
622 | |
623 | option->ocp_en = 1; |
624 | if (option->ocp_en) |
625 | hw_param->interrupt_en |= SD_OC_INT_EN; |
626 | hw_param->ocp_glitch = SD_OCP_GLITCH_100U | SDVIO_OCP_GLITCH_800U; |
627 | option->sd_400mA_ocp_thd = RTS5260_DVCC_OCP_THD_550; |
628 | option->sd_800mA_ocp_thd = RTS5260_DVCC_OCP_THD_970; |
629 | } |
630 | |