0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/bitops.h>
0013 #include <linux/delay.h>
0014 #include <linux/rtsx_pci.h>
0015
0016 #include "rtsx_pcr.h"
0017
0018 static u8 rtl8411_get_ic_version(struct rtsx_pcr *pcr)
0019 {
0020 u8 val;
0021
0022 rtsx_pci_read_register(pcr, SYS_VER, &val);
0023 return val & 0x0F;
0024 }
0025
0026 static int rtl8411b_is_qfn48(struct rtsx_pcr *pcr)
0027 {
0028 u8 val = 0;
0029
0030 rtsx_pci_read_register(pcr, RTL8411B_PACKAGE_MODE, &val);
0031
0032 if (val & 0x2)
0033 return 1;
0034 else
0035 return 0;
0036 }
0037
0038 static void rtl8411_fetch_vendor_settings(struct rtsx_pcr *pcr)
0039 {
0040 struct pci_dev *pdev = pcr->pci;
0041 u32 reg1 = 0;
0042 u8 reg3 = 0;
0043
0044 pci_read_config_dword(pdev, PCR_SETTING_REG1, ®1);
0045 pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1);
0046
0047 if (!rtsx_vendor_setting_valid(reg1))
0048 return;
0049
0050 pcr->aspm_en = rtsx_reg_to_aspm(reg1);
0051 pcr->sd30_drive_sel_1v8 =
0052 map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg1));
0053 pcr->card_drive_sel &= 0x3F;
0054 pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg1);
0055
0056 pci_read_config_byte(pdev, PCR_SETTING_REG3, ®3);
0057 pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3);
0058 pcr->sd30_drive_sel_3v3 = rtl8411_reg_to_sd30_drive_sel_3v3(reg3);
0059 }
0060
0061 static void rtl8411b_fetch_vendor_settings(struct rtsx_pcr *pcr)
0062 {
0063 struct pci_dev *pdev = pcr->pci;
0064 u32 reg = 0;
0065
0066 pci_read_config_dword(pdev, PCR_SETTING_REG1, ®);
0067 pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
0068
0069 if (!rtsx_vendor_setting_valid(reg))
0070 return;
0071
0072 pcr->aspm_en = rtsx_reg_to_aspm(reg);
0073 pcr->sd30_drive_sel_1v8 =
0074 map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg));
0075 pcr->sd30_drive_sel_3v3 =
0076 map_sd_drive(rtl8411b_reg_to_sd30_drive_sel_3v3(reg));
0077 }
0078
0079 static void rtl8411_force_power_down(struct rtsx_pcr *pcr, u8 pm_state, bool runtime)
0080 {
0081 rtsx_pci_write_register(pcr, FPDCTL, 0x07, 0x07);
0082 }
0083
0084 static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr)
0085 {
0086 rtsx_pci_init_cmd(pcr);
0087
0088 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
0089 0xFF, pcr->sd30_drive_sel_3v3);
0090 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CD_PAD_CTL,
0091 CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
0092
0093 return rtsx_pci_send_cmd(pcr, 100);
0094 }
0095
0096 static int rtl8411b_extra_init_hw(struct rtsx_pcr *pcr)
0097 {
0098 rtsx_pci_init_cmd(pcr);
0099
0100 if (rtl8411b_is_qfn48(pcr))
0101 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
0102 CARD_PULL_CTL3, 0xFF, 0xF5);
0103 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
0104 0xFF, pcr->sd30_drive_sel_3v3);
0105 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CD_PAD_CTL,
0106 CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
0107 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, FUNC_FORCE_CTL,
0108 0x06, 0x00);
0109
0110 return rtsx_pci_send_cmd(pcr, 100);
0111 }
0112
0113 static int rtl8411_turn_on_led(struct rtsx_pcr *pcr)
0114 {
0115 return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x00);
0116 }
0117
0118 static int rtl8411_turn_off_led(struct rtsx_pcr *pcr)
0119 {
0120 return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x01);
0121 }
0122
0123 static int rtl8411_enable_auto_blink(struct rtsx_pcr *pcr)
0124 {
0125 return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0xFF, 0x0D);
0126 }
0127
0128 static int rtl8411_disable_auto_blink(struct rtsx_pcr *pcr)
0129 {
0130 return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0x08, 0x00);
0131 }
0132
0133 static int rtl8411_card_power_on(struct rtsx_pcr *pcr, int card)
0134 {
0135 int err;
0136
0137 rtsx_pci_init_cmd(pcr);
0138 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
0139 BPP_POWER_MASK, BPP_POWER_5_PERCENT_ON);
0140 rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CTL,
0141 BPP_LDO_POWB, BPP_LDO_SUSPEND);
0142 err = rtsx_pci_send_cmd(pcr, 100);
0143 if (err < 0)
0144 return err;
0145
0146
0147 udelay(150);
0148
0149 err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
0150 BPP_POWER_MASK, BPP_POWER_10_PERCENT_ON);
0151 if (err < 0)
0152 return err;
0153
0154 udelay(150);
0155
0156 err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
0157 BPP_POWER_MASK, BPP_POWER_15_PERCENT_ON);
0158 if (err < 0)
0159 return err;
0160
0161 udelay(150);
0162
0163 err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
0164 BPP_POWER_MASK, BPP_POWER_ON);
0165 if (err < 0)
0166 return err;
0167
0168 return rtsx_pci_write_register(pcr, LDO_CTL, BPP_LDO_POWB, BPP_LDO_ON);
0169 }
0170
0171 static int rtl8411_card_power_off(struct rtsx_pcr *pcr, int card)
0172 {
0173 int err;
0174
0175 err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
0176 BPP_POWER_MASK, BPP_POWER_OFF);
0177 if (err < 0)
0178 return err;
0179
0180 return rtsx_pci_write_register(pcr, LDO_CTL,
0181 BPP_LDO_POWB, BPP_LDO_SUSPEND);
0182 }
0183
0184 static int rtl8411_do_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage,
0185 int bpp_tuned18_shift, int bpp_asic_1v8)
0186 {
0187 u8 mask, val;
0188 int err;
0189
0190 mask = (BPP_REG_TUNED18 << bpp_tuned18_shift) | BPP_PAD_MASK;
0191 if (voltage == OUTPUT_3V3) {
0192 err = rtsx_pci_write_register(pcr,
0193 SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3);
0194 if (err < 0)
0195 return err;
0196 val = (BPP_ASIC_3V3 << bpp_tuned18_shift) | BPP_PAD_3V3;
0197 } else if (voltage == OUTPUT_1V8) {
0198 err = rtsx_pci_write_register(pcr,
0199 SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8);
0200 if (err < 0)
0201 return err;
0202 val = (bpp_asic_1v8 << bpp_tuned18_shift) | BPP_PAD_1V8;
0203 } else {
0204 return -EINVAL;
0205 }
0206
0207 return rtsx_pci_write_register(pcr, LDO_CTL, mask, val);
0208 }
0209
0210 static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
0211 {
0212 return rtl8411_do_switch_output_voltage(pcr, voltage,
0213 BPP_TUNED18_SHIFT_8411, BPP_ASIC_1V8);
0214 }
0215
0216 static int rtl8402_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
0217 {
0218 return rtl8411_do_switch_output_voltage(pcr, voltage,
0219 BPP_TUNED18_SHIFT_8402, BPP_ASIC_2V0);
0220 }
0221
0222 static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr)
0223 {
0224 unsigned int card_exist;
0225
0226 card_exist = rtsx_pci_readl(pcr, RTSX_BIPR);
0227 card_exist &= CARD_EXIST;
0228 if (!card_exist) {
0229
0230 rtsx_pci_write_register(pcr, CD_PAD_CTL,
0231 CD_DISABLE_MASK, CD_ENABLE);
0232
0233 rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x00);
0234 return 0;
0235 }
0236
0237 if (hweight32(card_exist) > 1) {
0238 rtsx_pci_write_register(pcr, CARD_PWR_CTL,
0239 BPP_POWER_MASK, BPP_POWER_5_PERCENT_ON);
0240 msleep(100);
0241
0242 card_exist = rtsx_pci_readl(pcr, RTSX_BIPR);
0243 if (card_exist & MS_EXIST)
0244 card_exist = MS_EXIST;
0245 else if (card_exist & SD_EXIST)
0246 card_exist = SD_EXIST;
0247 else
0248 card_exist = 0;
0249
0250 rtsx_pci_write_register(pcr, CARD_PWR_CTL,
0251 BPP_POWER_MASK, BPP_POWER_OFF);
0252
0253 pcr_dbg(pcr, "After CD deglitch, card_exist = 0x%x\n",
0254 card_exist);
0255 }
0256
0257 if (card_exist & MS_EXIST) {
0258
0259 rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x40);
0260 rtsx_pci_write_register(pcr, CD_PAD_CTL,
0261 CD_DISABLE_MASK, MS_CD_EN_ONLY);
0262 } else if (card_exist & SD_EXIST) {
0263
0264 rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x80);
0265 rtsx_pci_write_register(pcr, CD_PAD_CTL,
0266 CD_DISABLE_MASK, SD_CD_EN_ONLY);
0267 }
0268
0269 return card_exist;
0270 }
0271
0272 static int rtl8411_conv_clk_and_div_n(int input, int dir)
0273 {
0274 int output;
0275
0276 if (dir == CLK_TO_DIV_N)
0277 output = input * 4 / 5 - 2;
0278 else
0279 output = (input + 2) * 5 / 4;
0280
0281 return output;
0282 }
0283
0284 static const struct pcr_ops rtl8411_pcr_ops = {
0285 .fetch_vendor_settings = rtl8411_fetch_vendor_settings,
0286 .extra_init_hw = rtl8411_extra_init_hw,
0287 .optimize_phy = NULL,
0288 .turn_on_led = rtl8411_turn_on_led,
0289 .turn_off_led = rtl8411_turn_off_led,
0290 .enable_auto_blink = rtl8411_enable_auto_blink,
0291 .disable_auto_blink = rtl8411_disable_auto_blink,
0292 .card_power_on = rtl8411_card_power_on,
0293 .card_power_off = rtl8411_card_power_off,
0294 .switch_output_voltage = rtl8411_switch_output_voltage,
0295 .cd_deglitch = rtl8411_cd_deglitch,
0296 .conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
0297 .force_power_down = rtl8411_force_power_down,
0298 };
0299
0300 static const struct pcr_ops rtl8402_pcr_ops = {
0301 .fetch_vendor_settings = rtl8411_fetch_vendor_settings,
0302 .extra_init_hw = rtl8411_extra_init_hw,
0303 .optimize_phy = NULL,
0304 .turn_on_led = rtl8411_turn_on_led,
0305 .turn_off_led = rtl8411_turn_off_led,
0306 .enable_auto_blink = rtl8411_enable_auto_blink,
0307 .disable_auto_blink = rtl8411_disable_auto_blink,
0308 .card_power_on = rtl8411_card_power_on,
0309 .card_power_off = rtl8411_card_power_off,
0310 .switch_output_voltage = rtl8402_switch_output_voltage,
0311 .cd_deglitch = rtl8411_cd_deglitch,
0312 .conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
0313 .force_power_down = rtl8411_force_power_down,
0314 };
0315
0316 static const struct pcr_ops rtl8411b_pcr_ops = {
0317 .fetch_vendor_settings = rtl8411b_fetch_vendor_settings,
0318 .extra_init_hw = rtl8411b_extra_init_hw,
0319 .optimize_phy = NULL,
0320 .turn_on_led = rtl8411_turn_on_led,
0321 .turn_off_led = rtl8411_turn_off_led,
0322 .enable_auto_blink = rtl8411_enable_auto_blink,
0323 .disable_auto_blink = rtl8411_disable_auto_blink,
0324 .card_power_on = rtl8411_card_power_on,
0325 .card_power_off = rtl8411_card_power_off,
0326 .switch_output_voltage = rtl8411_switch_output_voltage,
0327 .cd_deglitch = rtl8411_cd_deglitch,
0328 .conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
0329 .force_power_down = rtl8411_force_power_down,
0330 };
0331
0332
0333
0334
0335
0336
0337
0338
0339 static const u32 rtl8411_sd_pull_ctl_enable_tbl[] = {
0340 RTSX_REG_PAIR(CARD_PULL_CTL1, 0xAA),
0341 RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
0342 RTSX_REG_PAIR(CARD_PULL_CTL3, 0xA9),
0343 RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09),
0344 RTSX_REG_PAIR(CARD_PULL_CTL5, 0x09),
0345 RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
0346 0,
0347 };
0348
0349
0350
0351
0352
0353
0354
0355
0356 static const u32 rtl8411_sd_pull_ctl_disable_tbl[] = {
0357 RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
0358 RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
0359 RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95),
0360 RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09),
0361 RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05),
0362 RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
0363 0,
0364 };
0365
0366
0367
0368
0369
0370 static const u32 rtl8411_ms_pull_ctl_enable_tbl[] = {
0371 RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
0372 RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
0373 RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95),
0374 RTSX_REG_PAIR(CARD_PULL_CTL4, 0x05),
0375 RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05),
0376 RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
0377 0,
0378 };
0379
0380
0381
0382
0383
0384 static const u32 rtl8411_ms_pull_ctl_disable_tbl[] = {
0385 RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
0386 RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
0387 RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95),
0388 RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09),
0389 RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05),
0390 RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
0391 0,
0392 };
0393
0394 static const u32 rtl8411b_qfn64_sd_pull_ctl_enable_tbl[] = {
0395 RTSX_REG_PAIR(CARD_PULL_CTL1, 0xAA),
0396 RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
0397 RTSX_REG_PAIR(CARD_PULL_CTL3, 0x09 | 0xD0),
0398 RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09 | 0x50),
0399 RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
0400 RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
0401 0,
0402 };
0403
0404 static const u32 rtl8411b_qfn48_sd_pull_ctl_enable_tbl[] = {
0405 RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
0406 RTSX_REG_PAIR(CARD_PULL_CTL3, 0x69 | 0x90),
0407 RTSX_REG_PAIR(CARD_PULL_CTL6, 0x08 | 0x11),
0408 0,
0409 };
0410
0411 static const u32 rtl8411b_qfn64_sd_pull_ctl_disable_tbl[] = {
0412 RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
0413 RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
0414 RTSX_REG_PAIR(CARD_PULL_CTL3, 0x05 | 0xD0),
0415 RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09 | 0x50),
0416 RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
0417 RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
0418 0,
0419 };
0420
0421 static const u32 rtl8411b_qfn48_sd_pull_ctl_disable_tbl[] = {
0422 RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
0423 RTSX_REG_PAIR(CARD_PULL_CTL3, 0x65 | 0x90),
0424 RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
0425 0,
0426 };
0427
0428 static const u32 rtl8411b_qfn64_ms_pull_ctl_enable_tbl[] = {
0429 RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
0430 RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
0431 RTSX_REG_PAIR(CARD_PULL_CTL3, 0x05 | 0xD0),
0432 RTSX_REG_PAIR(CARD_PULL_CTL4, 0x05 | 0x50),
0433 RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
0434 RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
0435 0,
0436 };
0437
0438 static const u32 rtl8411b_qfn48_ms_pull_ctl_enable_tbl[] = {
0439 RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
0440 RTSX_REG_PAIR(CARD_PULL_CTL3, 0x65 | 0x90),
0441 RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
0442 0,
0443 };
0444
0445 static const u32 rtl8411b_qfn64_ms_pull_ctl_disable_tbl[] = {
0446 RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
0447 RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
0448 RTSX_REG_PAIR(CARD_PULL_CTL3, 0x05 | 0xD0),
0449 RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09 | 0x50),
0450 RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
0451 RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
0452 0,
0453 };
0454
0455 static const u32 rtl8411b_qfn48_ms_pull_ctl_disable_tbl[] = {
0456 RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
0457 RTSX_REG_PAIR(CARD_PULL_CTL3, 0x65 | 0x90),
0458 RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
0459 0,
0460 };
0461
0462 static void rtl8411_init_common_params(struct rtsx_pcr *pcr)
0463 {
0464 pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
0465 pcr->num_slots = 2;
0466 pcr->flags = 0;
0467 pcr->card_drive_sel = RTL8411_CARD_DRIVE_DEFAULT;
0468 pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B;
0469 pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D;
0470 pcr->aspm_en = ASPM_L1_EN;
0471 pcr->aspm_mode = ASPM_MODE_CFG;
0472 pcr->tx_initial_phase = SET_CLOCK_PHASE(23, 7, 14);
0473 pcr->rx_initial_phase = SET_CLOCK_PHASE(4, 3, 10);
0474 pcr->ic_version = rtl8411_get_ic_version(pcr);
0475 }
0476
0477 void rtl8411_init_params(struct rtsx_pcr *pcr)
0478 {
0479 rtl8411_init_common_params(pcr);
0480 pcr->ops = &rtl8411_pcr_ops;
0481 set_pull_ctrl_tables(pcr, rtl8411);
0482 }
0483
0484 void rtl8411b_init_params(struct rtsx_pcr *pcr)
0485 {
0486 rtl8411_init_common_params(pcr);
0487 pcr->ops = &rtl8411b_pcr_ops;
0488 if (rtl8411b_is_qfn48(pcr))
0489 set_pull_ctrl_tables(pcr, rtl8411b_qfn48);
0490 else
0491 set_pull_ctrl_tables(pcr, rtl8411b_qfn64);
0492 }
0493
0494 void rtl8402_init_params(struct rtsx_pcr *pcr)
0495 {
0496 rtl8411_init_common_params(pcr);
0497 pcr->ops = &rtl8402_pcr_ops;
0498 set_pull_ctrl_tables(pcr, rtl8411);
0499 }