Commit | Line | Data |
---|---|---|
aaf4989b | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
5da4e04a RF |
2 | /* Driver for Realtek PCI-Express card reader |
3 | * | |
4 | * Copyright(c) 2016-2017 Realtek Semiconductor Corp. All rights reserved. | |
5 | * | |
5da4e04a RF |
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, &val); | |
24 | return val & IC_VERSION_MASK; | |
25 | } | |
26 | ||
27 | static void rts5260_fill_driving(struct rtsx_pcr *pcr, u8 voltage) | |
28 | { | |
7c33e3c4 RW |
29 | u8 driving_3v3[4][3] = { |
30 | {0x11, 0x11, 0x11}, | |
31 | {0x22, 0x22, 0x22}, | |
32 | {0x55, 0x55, 0x55}, | |
33 | {0x33, 0x33, 0x33}, | |
5da4e04a | 34 | }; |
7c33e3c4 RW |
35 | u8 driving_1v8[4][3] = { |
36 | {0x35, 0x33, 0x33}, | |
37 | {0x8A, 0x88, 0x88}, | |
38 | {0xBD, 0xBB, 0xBB}, | |
5da4e04a | 39 | {0x9B, 0x99, 0x99}, |
5da4e04a RF |
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 | ||
bede03a5 | 51 | rtsx_pci_write_register(pcr, SD30_CLK_DRIVE_SEL, |
5da4e04a | 52 | 0xFF, driving[drive_sel][0]); |
bede03a5 R |
53 | |
54 | rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL, | |
5da4e04a | 55 | 0xFF, driving[drive_sel][1]); |
bede03a5 | 56 | |
7c33e3c4 | 57 | rtsx_pci_write_register(pcr, SD30_DAT_DRIVE_SEL, |
5da4e04a RF |
58 | 0xFF, driving[drive_sel][2]); |
59 | } | |
60 | ||
61 | static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr) | |
62 | { | |
22bf3251 | 63 | struct pci_dev *pdev = pcr->pci; |
5da4e04a RF |
64 | u32 reg; |
65 | ||
22bf3251 | 66 | pci_read_config_dword(pdev, PCR_SETTING_REG1, ®); |
5da4e04a RF |
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 | ||
22bf3251 | 79 | pci_read_config_dword(pdev, PCR_SETTING_REG2, ®); |
5da4e04a | 80 | pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg); |
7c33e3c4 RW |
81 | if (rtsx_check_mmc_support(reg)) |
82 | pcr->extra_caps |= EXTRA_CAPS_NO_MMC; | |
5da4e04a RF |
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 | ||
5da4e04a RF |
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, 0xFF, | |
bede03a5 | 170 | CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); |
5da4e04a RF |
171 | rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0); |
172 | ||
173 | return 0; | |
174 | } | |
175 | ||
176 | static int rts5260_card_power_on(struct rtsx_pcr *pcr, int card) | |
177 | { | |
5da4e04a RF |
178 | struct rtsx_cr_option *option = &pcr->option; |
179 | ||
180 | if (option->ocp_en) | |
181 | rtsx_pci_enable_ocp(pcr); | |
182 | ||
5da4e04a | 183 | |
bede03a5 R |
184 | rtsx_pci_write_register(pcr, LDO_CONFIG2, DV331812_VDD1, DV331812_VDD1); |
185 | rtsx_pci_write_register(pcr, LDO_VCC_CFG0, | |
5da4e04a | 186 | RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33); |
5da4e04a | 187 | |
bede03a5 R |
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); | |
5da4e04a RF |
193 | msleep(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, 0xFF, | |
201 | SD_CLK_DIVIDE_128 | SD_20_MODE); | |
202 | ||
203 | rtsx_pci_write_register(pcr, SD_SAMPLE_POINT_CTL, | |
204 | 0xFF, SD20_RX_POS_EDGE); | |
205 | rtsx_pci_write_register(pcr, SD_PUSH_POINT_CTL, 0xFF, 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, 0); | |
211 | rtsx_pci_write_register(pcr, REG_SD_STOP_SDCLK_CFG, | |
bede03a5 R |
212 | SD30_CLK_STOP_CFG_EN | SD30_CLK_STOP_CFG1 | |
213 | SD30_CLK_STOP_CFG0, 0); | |
5da4e04a RF |
214 | |
215 | rtsx_pci_write_register(pcr, REG_PRE_RW_MODE, EN_INFINITE_MODE, 0); | |
216 | ||
9964f8c8 | 217 | return 0; |
5da4e04a RF |
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, 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 */ | |
5da4e04a | 243 | rts5260_fill_driving(pcr, voltage); |
bede03a5 R |
244 | |
245 | return 0; | |
5da4e04a RF |
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 | { | |
5da4e04a RF |
260 | rts5260_stop_cmd(pcr); |
261 | rts5260_switch_output_voltage(pcr, OUTPUT_3V3); | |
262 | ||
5da4e04a RF |
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); | |
bede03a5 | 270 | err = rtsx_pci_write_register(pcr, LDO_VCC_CFG1, |
5da4e04a | 271 | LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF); |
bede03a5 | 272 | err = rtsx_pci_write_register(pcr, LDO_CONFIG2, |
5da4e04a | 273 | DV331812_POWERON, DV331812_POWEROFF); |
bede03a5 R |
274 | if (pcr->option.ocp_en) |
275 | rtsx_pci_disable_ocp(pcr); | |
5da4e04a RF |
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 | ||
5da4e04a RF |
287 | |
288 | rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, | |
bede03a5 R |
289 | RTS5260_DVCC_OCP_THD_MASK, |
290 | option->sd_800mA_ocp_thd); | |
5da4e04a RF |
291 | |
292 | rtsx_pci_write_register(pcr, RTS5260_DV331812_CFG, | |
bede03a5 R |
293 | RTS5260_DV331812_OCP_THD_MASK, |
294 | RTS5260_DV331812_OCP_THD_270); | |
5da4e04a | 295 | |
bede03a5 | 296 | mask = SD_OCP_GLITCH_MASK; |
5da4e04a RF |
297 | val = pcr->hw_param.ocp_glitch; |
298 | rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, val); | |
bede03a5 R |
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); | |
5da4e04a RF |
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, 0); | |
5da4e04a RF |
310 | } |
311 | } | |
312 | ||
313 | static void rts5260_enable_ocp(struct rtsx_pcr *pcr) | |
314 | { | |
315 | u8 val = 0; | |
316 | ||
5da4e04a | 317 | val = SD_OCP_INT_EN | SD_DETECT_EN; |
5da4e04a | 318 | rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val); |
bede03a5 | 319 | |
5da4e04a RF |
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; | |
5da4e04a | 327 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0); |
5da4e04a | 328 | |
5da4e04a RF |
329 | } |
330 | ||
bede03a5 | 331 | |
75a89805 | 332 | static int rts5260_get_ocpstat(struct rtsx_pcr *pcr, u8 *val) |
5da4e04a RF |
333 | { |
334 | return rtsx_pci_read_register(pcr, REG_OCPSTAT, val); | |
335 | } | |
336 | ||
75a89805 | 337 | static int rts5260_get_ocpstat2(struct rtsx_pcr *pcr, u8 *val) |
5da4e04a RF |
338 | { |
339 | return rtsx_pci_read_register(pcr, REG_DV3318_OCPSTAT, val); | |
340 | } | |
341 | ||
75a89805 | 342 | static void rts5260_clear_ocpstat(struct rtsx_pcr *pcr) |
5da4e04a RF |
343 | { |
344 | u8 mask = 0; | |
345 | u8 val = 0; | |
346 | ||
347 | mask = SD_OCP_INT_CLR | SD_OC_CLR; | |
5da4e04a | 348 | val = SD_OCP_INT_CLR | SD_OC_CLR; |
5da4e04a RF |
349 | |
350 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 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, 0); | |
356 | rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL, | |
357 | DV3318_OCP_INT_CLR | DV3318_OCP_CLR, 0); | |
358 | } | |
359 | ||
75a89805 | 360 | static void rts5260_process_ocp(struct rtsx_pcr *pcr) |
5da4e04a RF |
361 | { |
362 | if (!pcr->option.ocp_en) | |
363 | return; | |
364 | ||
365 | rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat); | |
366 | rts5260_get_ocpstat2(pcr, &pcr->ocp_stat2); | |
bede03a5 R |
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, 0); | |
372 | rtsx_pci_clear_ocpstat(pcr); | |
5da4e04a RF |
373 | pcr->ocp_stat = 0; |
374 | pcr->ocp_stat2 = 0; | |
375 | } | |
376 | ||
5da4e04a RF |
377 | } |
378 | ||
75a89805 | 379 | static int rts5260_init_hw(struct rtsx_pcr *pcr) |
5da4e04a RF |
380 | { |
381 | int err; | |
382 | ||
5da4e04a RF |
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, 0xFF, 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, 0xFF, 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, 0xB0, 0xB0); | |
401 | else | |
402 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 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 | ||
bede03a5 R |
411 | rtsx_pci_init_ocp(pcr); |
412 | ||
5da4e04a RF |
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 | ||
24f1bc28 | 425 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0); |
5da4e04a RF |
426 | if (lss_l1_2) { |
427 | pcr_dbg(pcr, "Set parameters for L1.2."); | |
428 | rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL, | |
429 | 0xFF, PCIE_L1_2_EN); | |
34bf9ce9 | 430 | rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, |
bede03a5 R |
431 | RTS5260_DVCC_OCP_EN | |
432 | RTS5260_DVCC_OCP_CL_EN, | |
433 | RTS5260_DVCC_OCP_EN | | |
434 | RTS5260_DVCC_OCP_CL_EN); | |
435 | ||
34bf9ce9 | 436 | rtsx_pci_write_register(pcr, PWR_FE_CTL, |
5da4e04a RF |
437 | 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 | 0xFF, PCIE_L1_1_EN); | |
442 | rtsx_pci_write_register(pcr, PWR_FE_CTL, | |
443 | 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 | 0xFF, PCIE_L1_0_EN); | |
448 | rtsx_pci_write_register(pcr, PWR_FE_CTL, | |
449 | 0xFF, PCIE_L1_0_PD_FE_EN); | |
450 | } | |
451 | ||
452 | rtsx_pci_write_register(pcr, CFG_L1_0_PCIE_DPHY_RET_VALUE, | |
453 | 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); | |
454 | rtsx_pci_write_register(pcr, CFG_L1_0_PCIE_MAC_RET_VALUE, | |
455 | 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); | |
456 | rtsx_pci_write_register(pcr, CFG_L1_0_CRC_SD30_RET_VALUE, | |
457 | 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); | |
458 | rtsx_pci_write_register(pcr, CFG_L1_0_CRC_SD40_RET_VALUE, | |
459 | 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); | |
460 | rtsx_pci_write_register(pcr, CFG_L1_0_SYS_RET_VALUE, | |
461 | 0xFF, CFG_L1_0_RET_VALUE_DEFAULT); | |
462 | /*Option cut APHY*/ | |
463 | rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_0, | |
464 | 0xFF, CFG_PCIE_APHY_OFF_0_DEFAULT); | |
465 | rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_1, | |
466 | 0xFF, CFG_PCIE_APHY_OFF_1_DEFAULT); | |
467 | rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_2, | |
468 | 0xFF, CFG_PCIE_APHY_OFF_2_DEFAULT); | |
469 | rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_3, | |
470 | 0xFF, CFG_PCIE_APHY_OFF_3_DEFAULT); | |
471 | /*CDR DEC*/ | |
472 | rtsx_pci_write_register(pcr, PWC_CDR, 0xFF, PWC_CDR_DEFAULT); | |
473 | /*PWMPFM*/ | |
474 | rtsx_pci_write_register(pcr, CFG_LP_FPWM_VALUE, | |
475 | 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 | 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; | |
5da4e04a RF |
484 | |
485 | rts5260_pwr_saving_setting(pcr); | |
486 | ||
487 | if (option->ltr_en) { | |
0e4cac55 | 488 | if (option->ltr_enabled) |
5da4e04a | 489 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); |
5da4e04a | 490 | } |
5da4e04a RF |
491 | } |
492 | ||
493 | static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) | |
494 | { | |
0e4cac55 | 495 | struct rtsx_cr_option *option = &pcr->option; |
5da4e04a RF |
496 | |
497 | /* Set mcu_cnt to 7 to ensure data can be sampled properly */ | |
498 | rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07); | |
499 | rtsx_pci_write_register(pcr, SSC_DIV_N_0, 0xFF, 0x5D); | |
500 | ||
501 | rts5260_init_from_cfg(pcr); | |
502 | ||
503 | /* force no MDIO*/ | |
504 | rtsx_pci_write_register(pcr, RTS5260_AUTOLOAD_CFG4, | |
505 | 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 | ||
0e4cac55 RW |
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 | ||
7c33e3c4 RW |
525 | rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); |
526 | ||
5da4e04a RF |
527 | return 0; |
528 | } | |
529 | ||
5da4e04a RF |
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, | |
5da4e04a | 573 | .stop_cmd = rts5260_stop_cmd, |
5da4e04a RF |
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; | |
3df4fce7 | 596 | pcr->aspm_mode = ASPM_MODE_REG; |
4686392c | 597 | pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 29, 11); |
5da4e04a RF |
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; | |
5da4e04a RF |
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; | |
24f1bc28 | 626 | hw_param->ocp_glitch = SD_OCP_GLITCH_100U | SDVIO_OCP_GLITCH_800U; |
5da4e04a RF |
627 | option->sd_400mA_ocp_thd = RTS5260_DVCC_OCP_THD_550; |
628 | option->sd_800mA_ocp_thd = RTS5260_DVCC_OCP_THD_970; | |
629 | } |