Merge remote-tracking branch 'torvalds/master' into perf/core
[linux-2.6-microblaze.git] / drivers / misc / cardreader / rtl8411.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Driver for Realtek PCI-Express card reader
3  *
4  * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
5  *
6  * Author:
7  *   Wei WANG <wei_wang@realsil.com.cn>
8  *   Roger Tseng <rogerable@realtek.com>
9  */
10
11 #include <linux/module.h>
12 #include <linux/bitops.h>
13 #include <linux/delay.h>
14 #include <linux/rtsx_pci.h>
15
16 #include "rtsx_pcr.h"
17
18 static u8 rtl8411_get_ic_version(struct rtsx_pcr *pcr)
19 {
20         u8 val;
21
22         rtsx_pci_read_register(pcr, SYS_VER, &val);
23         return val & 0x0F;
24 }
25
26 static int rtl8411b_is_qfn48(struct rtsx_pcr *pcr)
27 {
28         u8 val = 0;
29
30         rtsx_pci_read_register(pcr, RTL8411B_PACKAGE_MODE, &val);
31
32         if (val & 0x2)
33                 return 1;
34         else
35                 return 0;
36 }
37
38 static void rtl8411_fetch_vendor_settings(struct rtsx_pcr *pcr)
39 {
40         struct pci_dev *pdev = pcr->pci;
41         u32 reg1 = 0;
42         u8 reg3 = 0;
43
44         pci_read_config_dword(pdev, PCR_SETTING_REG1, &reg1);
45         pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1);
46
47         if (!rtsx_vendor_setting_valid(reg1))
48                 return;
49
50         pcr->aspm_en = rtsx_reg_to_aspm(reg1);
51         pcr->sd30_drive_sel_1v8 =
52                 map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg1));
53         pcr->card_drive_sel &= 0x3F;
54         pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg1);
55
56         pci_read_config_byte(pdev, PCR_SETTING_REG3, &reg3);
57         pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3);
58         pcr->sd30_drive_sel_3v3 = rtl8411_reg_to_sd30_drive_sel_3v3(reg3);
59 }
60
61 static void rtl8411b_fetch_vendor_settings(struct rtsx_pcr *pcr)
62 {
63         struct pci_dev *pdev = pcr->pci;
64         u32 reg = 0;
65
66         pci_read_config_dword(pdev, PCR_SETTING_REG1, &reg);
67         pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
68
69         if (!rtsx_vendor_setting_valid(reg))
70                 return;
71
72         pcr->aspm_en = rtsx_reg_to_aspm(reg);
73         pcr->sd30_drive_sel_1v8 =
74                 map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg));
75         pcr->sd30_drive_sel_3v3 =
76                 map_sd_drive(rtl8411b_reg_to_sd30_drive_sel_3v3(reg));
77 }
78
79 static void rtl8411_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
80 {
81         rtsx_pci_write_register(pcr, FPDCTL, 0x07, 0x07);
82 }
83
84 static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr)
85 {
86         rtsx_pci_init_cmd(pcr);
87
88         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
89                         0xFF, pcr->sd30_drive_sel_3v3);
90         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CD_PAD_CTL,
91                         CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
92
93         return rtsx_pci_send_cmd(pcr, 100);
94 }
95
96 static int rtl8411b_extra_init_hw(struct rtsx_pcr *pcr)
97 {
98         rtsx_pci_init_cmd(pcr);
99
100         if (rtl8411b_is_qfn48(pcr))
101                 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
102                                 CARD_PULL_CTL3, 0xFF, 0xF5);
103         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
104                         0xFF, pcr->sd30_drive_sel_3v3);
105         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CD_PAD_CTL,
106                         CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
107         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, FUNC_FORCE_CTL,
108                         0x06, 0x00);
109
110         return rtsx_pci_send_cmd(pcr, 100);
111 }
112
113 static int rtl8411_turn_on_led(struct rtsx_pcr *pcr)
114 {
115         return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x00);
116 }
117
118 static int rtl8411_turn_off_led(struct rtsx_pcr *pcr)
119 {
120         return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x01);
121 }
122
123 static int rtl8411_enable_auto_blink(struct rtsx_pcr *pcr)
124 {
125         return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0xFF, 0x0D);
126 }
127
128 static int rtl8411_disable_auto_blink(struct rtsx_pcr *pcr)
129 {
130         return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0x08, 0x00);
131 }
132
133 static int rtl8411_card_power_on(struct rtsx_pcr *pcr, int card)
134 {
135         int err;
136
137         rtsx_pci_init_cmd(pcr);
138         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
139                         BPP_POWER_MASK, BPP_POWER_5_PERCENT_ON);
140         rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CTL,
141                         BPP_LDO_POWB, BPP_LDO_SUSPEND);
142         err = rtsx_pci_send_cmd(pcr, 100);
143         if (err < 0)
144                 return err;
145
146         /* To avoid too large in-rush current */
147         udelay(150);
148
149         err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
150                         BPP_POWER_MASK, BPP_POWER_10_PERCENT_ON);
151         if (err < 0)
152                 return err;
153
154         udelay(150);
155
156         err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
157                         BPP_POWER_MASK, BPP_POWER_15_PERCENT_ON);
158         if (err < 0)
159                 return err;
160
161         udelay(150);
162
163         err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
164                         BPP_POWER_MASK, BPP_POWER_ON);
165         if (err < 0)
166                 return err;
167
168         return rtsx_pci_write_register(pcr, LDO_CTL, BPP_LDO_POWB, BPP_LDO_ON);
169 }
170
171 static int rtl8411_card_power_off(struct rtsx_pcr *pcr, int card)
172 {
173         int err;
174
175         err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
176                         BPP_POWER_MASK, BPP_POWER_OFF);
177         if (err < 0)
178                 return err;
179
180         return rtsx_pci_write_register(pcr, LDO_CTL,
181                         BPP_LDO_POWB, BPP_LDO_SUSPEND);
182 }
183
184 static int rtl8411_do_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage,
185                 int bpp_tuned18_shift, int bpp_asic_1v8)
186 {
187         u8 mask, val;
188         int err;
189
190         mask = (BPP_REG_TUNED18 << bpp_tuned18_shift) | BPP_PAD_MASK;
191         if (voltage == OUTPUT_3V3) {
192                 err = rtsx_pci_write_register(pcr,
193                                 SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3);
194                 if (err < 0)
195                         return err;
196                 val = (BPP_ASIC_3V3 << bpp_tuned18_shift) | BPP_PAD_3V3;
197         } else if (voltage == OUTPUT_1V8) {
198                 err = rtsx_pci_write_register(pcr,
199                                 SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8);
200                 if (err < 0)
201                         return err;
202                 val = (bpp_asic_1v8 << bpp_tuned18_shift) | BPP_PAD_1V8;
203         } else {
204                 return -EINVAL;
205         }
206
207         return rtsx_pci_write_register(pcr, LDO_CTL, mask, val);
208 }
209
210 static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
211 {
212         return rtl8411_do_switch_output_voltage(pcr, voltage,
213                         BPP_TUNED18_SHIFT_8411, BPP_ASIC_1V8);
214 }
215
216 static int rtl8402_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
217 {
218         return rtl8411_do_switch_output_voltage(pcr, voltage,
219                         BPP_TUNED18_SHIFT_8402, BPP_ASIC_2V0);
220 }
221
222 static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr)
223 {
224         unsigned int card_exist;
225
226         card_exist = rtsx_pci_readl(pcr, RTSX_BIPR);
227         card_exist &= CARD_EXIST;
228         if (!card_exist) {
229                 /* Enable card CD */
230                 rtsx_pci_write_register(pcr, CD_PAD_CTL,
231                                 CD_DISABLE_MASK, CD_ENABLE);
232                 /* Enable card interrupt */
233                 rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x00);
234                 return 0;
235         }
236
237         if (hweight32(card_exist) > 1) {
238                 rtsx_pci_write_register(pcr, CARD_PWR_CTL,
239                                 BPP_POWER_MASK, BPP_POWER_5_PERCENT_ON);
240                 msleep(100);
241
242                 card_exist = rtsx_pci_readl(pcr, RTSX_BIPR);
243                 if (card_exist & MS_EXIST)
244                         card_exist = MS_EXIST;
245                 else if (card_exist & SD_EXIST)
246                         card_exist = SD_EXIST;
247                 else
248                         card_exist = 0;
249
250                 rtsx_pci_write_register(pcr, CARD_PWR_CTL,
251                                 BPP_POWER_MASK, BPP_POWER_OFF);
252
253                 pcr_dbg(pcr, "After CD deglitch, card_exist = 0x%x\n",
254                         card_exist);
255         }
256
257         if (card_exist & MS_EXIST) {
258                 /* Disable SD interrupt */
259                 rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x40);
260                 rtsx_pci_write_register(pcr, CD_PAD_CTL,
261                                 CD_DISABLE_MASK, MS_CD_EN_ONLY);
262         } else if (card_exist & SD_EXIST) {
263                 /* Disable MS interrupt */
264                 rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x80);
265                 rtsx_pci_write_register(pcr, CD_PAD_CTL,
266                                 CD_DISABLE_MASK, SD_CD_EN_ONLY);
267         }
268
269         return card_exist;
270 }
271
272 static int rtl8411_conv_clk_and_div_n(int input, int dir)
273 {
274         int output;
275
276         if (dir == CLK_TO_DIV_N)
277                 output = input * 4 / 5 - 2;
278         else
279                 output = (input + 2) * 5 / 4;
280
281         return output;
282 }
283
284 static const struct pcr_ops rtl8411_pcr_ops = {
285         .fetch_vendor_settings = rtl8411_fetch_vendor_settings,
286         .extra_init_hw = rtl8411_extra_init_hw,
287         .optimize_phy = NULL,
288         .turn_on_led = rtl8411_turn_on_led,
289         .turn_off_led = rtl8411_turn_off_led,
290         .enable_auto_blink = rtl8411_enable_auto_blink,
291         .disable_auto_blink = rtl8411_disable_auto_blink,
292         .card_power_on = rtl8411_card_power_on,
293         .card_power_off = rtl8411_card_power_off,
294         .switch_output_voltage = rtl8411_switch_output_voltage,
295         .cd_deglitch = rtl8411_cd_deglitch,
296         .conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
297         .force_power_down = rtl8411_force_power_down,
298 };
299
300 static const struct pcr_ops rtl8402_pcr_ops = {
301         .fetch_vendor_settings = rtl8411_fetch_vendor_settings,
302         .extra_init_hw = rtl8411_extra_init_hw,
303         .optimize_phy = NULL,
304         .turn_on_led = rtl8411_turn_on_led,
305         .turn_off_led = rtl8411_turn_off_led,
306         .enable_auto_blink = rtl8411_enable_auto_blink,
307         .disable_auto_blink = rtl8411_disable_auto_blink,
308         .card_power_on = rtl8411_card_power_on,
309         .card_power_off = rtl8411_card_power_off,
310         .switch_output_voltage = rtl8402_switch_output_voltage,
311         .cd_deglitch = rtl8411_cd_deglitch,
312         .conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
313         .force_power_down = rtl8411_force_power_down,
314 };
315
316 static const struct pcr_ops rtl8411b_pcr_ops = {
317         .fetch_vendor_settings = rtl8411b_fetch_vendor_settings,
318         .extra_init_hw = rtl8411b_extra_init_hw,
319         .optimize_phy = NULL,
320         .turn_on_led = rtl8411_turn_on_led,
321         .turn_off_led = rtl8411_turn_off_led,
322         .enable_auto_blink = rtl8411_enable_auto_blink,
323         .disable_auto_blink = rtl8411_disable_auto_blink,
324         .card_power_on = rtl8411_card_power_on,
325         .card_power_off = rtl8411_card_power_off,
326         .switch_output_voltage = rtl8411_switch_output_voltage,
327         .cd_deglitch = rtl8411_cd_deglitch,
328         .conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
329         .force_power_down = rtl8411_force_power_down,
330 };
331
332 /* SD Pull Control Enable:
333  *     SD_DAT[3:0] ==> pull up
334  *     SD_CD       ==> pull up
335  *     SD_WP       ==> pull up
336  *     SD_CMD      ==> pull up
337  *     SD_CLK      ==> pull down
338  */
339 static const u32 rtl8411_sd_pull_ctl_enable_tbl[] = {
340         RTSX_REG_PAIR(CARD_PULL_CTL1, 0xAA),
341         RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
342         RTSX_REG_PAIR(CARD_PULL_CTL3, 0xA9),
343         RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09),
344         RTSX_REG_PAIR(CARD_PULL_CTL5, 0x09),
345         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
346         0,
347 };
348
349 /* SD Pull Control Disable:
350  *     SD_DAT[3:0] ==> pull down
351  *     SD_CD       ==> pull up
352  *     SD_WP       ==> pull down
353  *     SD_CMD      ==> pull down
354  *     SD_CLK      ==> pull down
355  */
356 static const u32 rtl8411_sd_pull_ctl_disable_tbl[] = {
357         RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
358         RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
359         RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95),
360         RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09),
361         RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05),
362         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
363         0,
364 };
365
366 /* MS Pull Control Enable:
367  *     MS CD       ==> pull up
368  *     others      ==> pull down
369  */
370 static const u32 rtl8411_ms_pull_ctl_enable_tbl[] = {
371         RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
372         RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
373         RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95),
374         RTSX_REG_PAIR(CARD_PULL_CTL4, 0x05),
375         RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05),
376         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
377         0,
378 };
379
380 /* MS Pull Control Disable:
381  *     MS CD       ==> pull up
382  *     others      ==> pull down
383  */
384 static const u32 rtl8411_ms_pull_ctl_disable_tbl[] = {
385         RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
386         RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
387         RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95),
388         RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09),
389         RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05),
390         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
391         0,
392 };
393
394 static const u32 rtl8411b_qfn64_sd_pull_ctl_enable_tbl[] = {
395         RTSX_REG_PAIR(CARD_PULL_CTL1, 0xAA),
396         RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
397         RTSX_REG_PAIR(CARD_PULL_CTL3, 0x09 | 0xD0),
398         RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09 | 0x50),
399         RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
400         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
401         0,
402 };
403
404 static const u32 rtl8411b_qfn48_sd_pull_ctl_enable_tbl[] = {
405         RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
406         RTSX_REG_PAIR(CARD_PULL_CTL3, 0x69 | 0x90),
407         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x08 | 0x11),
408         0,
409 };
410
411 static const u32 rtl8411b_qfn64_sd_pull_ctl_disable_tbl[] = {
412         RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
413         RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
414         RTSX_REG_PAIR(CARD_PULL_CTL3, 0x05 | 0xD0),
415         RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09 | 0x50),
416         RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
417         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
418         0,
419 };
420
421 static const u32 rtl8411b_qfn48_sd_pull_ctl_disable_tbl[] = {
422         RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
423         RTSX_REG_PAIR(CARD_PULL_CTL3, 0x65 | 0x90),
424         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
425         0,
426 };
427
428 static const u32 rtl8411b_qfn64_ms_pull_ctl_enable_tbl[] = {
429         RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
430         RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
431         RTSX_REG_PAIR(CARD_PULL_CTL3, 0x05 | 0xD0),
432         RTSX_REG_PAIR(CARD_PULL_CTL4, 0x05 | 0x50),
433         RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
434         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
435         0,
436 };
437
438 static const u32 rtl8411b_qfn48_ms_pull_ctl_enable_tbl[] = {
439         RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
440         RTSX_REG_PAIR(CARD_PULL_CTL3, 0x65 | 0x90),
441         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
442         0,
443 };
444
445 static const u32 rtl8411b_qfn64_ms_pull_ctl_disable_tbl[] = {
446         RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
447         RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
448         RTSX_REG_PAIR(CARD_PULL_CTL3, 0x05 | 0xD0),
449         RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09 | 0x50),
450         RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
451         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
452         0,
453 };
454
455 static const u32 rtl8411b_qfn48_ms_pull_ctl_disable_tbl[] = {
456         RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
457         RTSX_REG_PAIR(CARD_PULL_CTL3, 0x65 | 0x90),
458         RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
459         0,
460 };
461
462 static void rtl8411_init_common_params(struct rtsx_pcr *pcr)
463 {
464         pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
465         pcr->num_slots = 2;
466         pcr->flags = 0;
467         pcr->card_drive_sel = RTL8411_CARD_DRIVE_DEFAULT;
468         pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B;
469         pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D;
470         pcr->aspm_en = ASPM_L1_EN;
471         pcr->aspm_mode = ASPM_MODE_CFG;
472         pcr->tx_initial_phase = SET_CLOCK_PHASE(23, 7, 14);
473         pcr->rx_initial_phase = SET_CLOCK_PHASE(4, 3, 10);
474         pcr->ic_version = rtl8411_get_ic_version(pcr);
475 }
476
477 void rtl8411_init_params(struct rtsx_pcr *pcr)
478 {
479         rtl8411_init_common_params(pcr);
480         pcr->ops = &rtl8411_pcr_ops;
481         set_pull_ctrl_tables(pcr, rtl8411);
482 }
483
484 void rtl8411b_init_params(struct rtsx_pcr *pcr)
485 {
486         rtl8411_init_common_params(pcr);
487         pcr->ops = &rtl8411b_pcr_ops;
488         if (rtl8411b_is_qfn48(pcr))
489                 set_pull_ctrl_tables(pcr, rtl8411b_qfn48);
490         else
491                 set_pull_ctrl_tables(pcr, rtl8411b_qfn64);
492 }
493
494 void rtl8402_init_params(struct rtsx_pcr *pcr)
495 {
496         rtl8411_init_common_params(pcr);
497         pcr->ops = &rtl8402_pcr_ops;
498         set_pull_ctrl_tables(pcr, rtl8411);
499 }