| 1 | |
| 2 | |
| 3 | *
|
| 4 | * Copyright(c) 2018-2019 Realtek Semiconductor Corp. All rights reserved.
|
| 5 | *
|
| 6 | * Author:
|
| 7 | * Rui FENG <[email protected]>
|
| 8 | * Wei WANG <[email protected]>
|
| 9 |
|
| 10 |
|
| 11 | #include <linux/module.h>
|
| 12 | #include <linux/delay.h>
|
| 13 | #include <linux/rtsx_pci.h>
|
| 14 |
|
| 15 | #include "rts5261.h"
|
| 16 | #include "rtsx_pcr.h"
|
| 17 |
|
| 18 | static u8 rts5261_get_ic_version(struct rtsx_pcr *pcr)
|
| 19 | {
|
| 20 | u8 val;
|
| 21 |
|
| 22 | rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val);
|
| 23 | return val & IC_VERSION_MASK;
|
| 24 | }
|
| 25 |
|
| 26 | static void rts5261_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
|
| 27 | {
|
| 28 | u8 driving_3v3[4][3] = {
|
| 29 | {0x96, 0x96, 0x96},
|
| 30 | {0x96, 0x96, 0x96},
|
| 31 | {0x7F, 0x7F, 0x7F},
|
| 32 | {0x13, 0x13, 0x13},
|
| 33 | };
|
| 34 | u8 driving_1v8[4][3] = {
|
| 35 | {0xB3, 0xB3, 0xB3},
|
| 36 | {0x3A, 0x3A, 0x3A},
|
| 37 | {0xE6, 0xE6, 0xE6},
|
| 38 | {0x99, 0x99, 0x99},
|
| 39 | };
|
| 40 | u8 (*driving)[3], drive_sel;
|
| 41 |
|
| 42 | if (voltage == OUTPUT_3V3) {
|
| 43 | driving = driving_3v3;
|
| 44 | drive_sel = pcr->sd30_drive_sel_3v3;
|
| 45 | } else {
|
| 46 | driving = driving_1v8;
|
| 47 | drive_sel = pcr->sd30_drive_sel_1v8;
|
| 48 | }
|
| 49 |
|
| 50 | rtsx_pci_write_register(pcr, SD30_CLK_DRIVE_SEL,
|
| 51 | 0xFF, driving[drive_sel][0]);
|
| 52 |
|
| 53 | rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL,
|
| 54 | 0xFF, driving[drive_sel][1]);
|
| 55 |
|
| 56 | rtsx_pci_write_register(pcr, SD30_DAT_DRIVE_SEL,
|
| 57 | 0xFF, driving[drive_sel][2]);
|
| 58 | }
|
| 59 |
|
| 60 | static void rts5261_force_power_down(struct rtsx_pcr *pcr, u8 pm_state, bool runtime)
|
| 61 | {
|
| 62 |
|
| 63 | rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, MASK_8_BIT_DEF, 0);
|
| 64 | rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, MASK_8_BIT_DEF, 0);
|
| 65 | rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3,
|
| 66 | RELINK_TIME_MASK, 0);
|
| 67 |
|
| 68 | if (pm_state == HOST_ENTER_S3)
|
| 69 | rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3,
|
| 70 | D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);
|
| 71 |
|
| 72 | if (!runtime) {
|
| 73 | rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1,
|
| 74 | CD_RESUME_EN_MASK, 0);
|
| 75 | rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x01, 0x00);
|
| 76 | rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
|
| 77 | FORCE_PM_CONTROL | FORCE_PM_VALUE, FORCE_PM_CONTROL);
|
| 78 |
|
| 79 | } else {
|
| 80 | rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
|
| 81 | FORCE_PM_CONTROL | FORCE_PM_VALUE, 0);
|
| 82 |
|
| 83 | rtsx_pci_write_register(pcr, RTS5261_FW_CTL,
|
| 84 | RTS5261_INFORM_RTD3_COLD, RTS5261_INFORM_RTD3_COLD);
|
| 85 | rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG4,
|
| 86 | RTS5261_FORCE_PRSNT_LOW, RTS5261_FORCE_PRSNT_LOW);
|
| 87 |
|
| 88 | }
|
| 89 |
|
| 90 | rtsx_pci_write_register(pcr, RTS5261_REG_FPDCTL,
|
| 91 | SSC_POWER_DOWN, SSC_POWER_DOWN);
|
| 92 | }
|
| 93 |
|
| 94 | static int rts5261_enable_auto_blink(struct rtsx_pcr *pcr)
|
| 95 | {
|
| 96 | return rtsx_pci_write_register(pcr, OLT_LED_CTL,
|
| 97 | LED_SHINE_MASK, LED_SHINE_EN);
|
| 98 | }
|
| 99 |
|
| 100 | static int rts5261_disable_auto_blink(struct rtsx_pcr *pcr)
|
| 101 | {
|
| 102 | return rtsx_pci_write_register(pcr, OLT_LED_CTL,
|
| 103 | LED_SHINE_MASK, LED_SHINE_DISABLE);
|
| 104 | }
|
| 105 |
|
| 106 | static int rts5261_turn_on_led(struct rtsx_pcr *pcr)
|
| 107 | {
|
| 108 | return rtsx_pci_write_register(pcr, GPIO_CTL,
|
| 109 | 0x02, 0x02);
|
| 110 | }
|
| 111 |
|
| 112 | static int rts5261_turn_off_led(struct rtsx_pcr *pcr)
|
| 113 | {
|
| 114 | return rtsx_pci_write_register(pcr, GPIO_CTL,
|
| 115 | 0x02, 0x00);
|
| 116 | }
|
| 117 |
|
| 118 | |
| 119 | * SD_DAT[3:0] ==> pull up
|
| 120 | * SD_CD ==> pull up
|
| 121 | * SD_WP ==> pull up
|
| 122 | * SD_CMD ==> pull up
|
| 123 | * SD_CLK ==> pull down
|
| 124 |
|
| 125 | static const u32 rts5261_sd_pull_ctl_enable_tbl[] = {
|
| 126 | RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
|
| 127 | RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9),
|
| 128 | 0,
|
| 129 | };
|
| 130 |
|
| 131 | |
| 132 | * SD_DAT[3:0] ==> pull down
|
| 133 | * SD_CD ==> pull up
|
| 134 | * SD_WP ==> pull down
|
| 135 | * SD_CMD ==> pull down
|
| 136 | * SD_CLK ==> pull down
|
| 137 |
|
| 138 | static const u32 rts5261_sd_pull_ctl_disable_tbl[] = {
|
| 139 | RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
|
| 140 | RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5),
|
| 141 | 0,
|
| 142 | };
|
| 143 |
|
| 144 | static int rts5261_sd_set_sample_push_timing_sd30(struct rtsx_pcr *pcr)
|
| 145 | {
|
| 146 | rtsx_pci_write_register(pcr, SD_CFG1, SD_MODE_SELECT_MASK
|
| 147 | | SD_ASYNC_FIFO_NOT_RST, SD_30_MODE | SD_ASYNC_FIFO_NOT_RST);
|
| 148 | rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ);
|
| 149 | rtsx_pci_write_register(pcr, CARD_CLK_SOURCE, 0xFF,
|
| 150 | CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
|
| 151 | rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
|
| 152 |
|
| 153 | return 0;
|
| 154 | }
|
| 155 |
|
| 156 | static int rts5261_card_power_on(struct rtsx_pcr *pcr, int card)
|
| 157 | {
|
| 158 | struct rtsx_cr_option *option = &pcr->option;
|
| 159 |
|
| 160 | if (option->ocp_en)
|
| 161 | rtsx_pci_enable_ocp(pcr);
|
| 162 |
|
| 163 | rtsx_pci_write_register(pcr, REG_CRC_DUMMY_0,
|
| 164 | CFG_SD_POW_AUTO_PD, CFG_SD_POW_AUTO_PD);
|
| 165 |
|
| 166 | rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG1,
|
| 167 | RTS5261_LDO1_TUNE_MASK, RTS5261_LDO1_33);
|
| 168 | rtsx_pci_write_register(pcr, RTS5261_LDO1233318_POW_CTL,
|
| 169 | RTS5261_LDO1_POWERON, RTS5261_LDO1_POWERON);
|
| 170 |
|
| 171 | rtsx_pci_write_register(pcr, RTS5261_LDO1233318_POW_CTL,
|
| 172 | RTS5261_LDO3318_POWERON, RTS5261_LDO3318_POWERON);
|
| 173 |
|
| 174 | msleep(20);
|
| 175 |
|
| 176 | rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN);
|
| 177 |
|
| 178 |
|
| 179 | rtsx_pci_write_register(pcr, SD_CFG1, 0xFF,
|
| 180 | SD_CLK_DIVIDE_128 | SD_20_MODE | SD_BUS_WIDTH_1BIT);
|
| 181 |
|
| 182 | rtsx_pci_write_register(pcr, SD_SAMPLE_POINT_CTL,
|
| 183 | 0xFF, SD20_RX_POS_EDGE);
|
| 184 | rtsx_pci_write_register(pcr, SD_PUSH_POINT_CTL, 0xFF, 0);
|
| 185 | rtsx_pci_write_register(pcr, CARD_STOP, SD_STOP | SD_CLR_ERR,
|
| 186 | SD_STOP | SD_CLR_ERR);
|
| 187 |
|
| 188 |
|
| 189 | rtsx_pci_write_register(pcr, SD_CFG3, SD30_CLK_END_EN, 0);
|
| 190 | rtsx_pci_write_register(pcr, REG_SD_STOP_SDCLK_CFG,
|
| 191 | SD30_CLK_STOP_CFG_EN | SD30_CLK_STOP_CFG1 |
|
| 192 | SD30_CLK_STOP_CFG0, 0);
|
| 193 |
|
| 194 | if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50 ||
|
| 195 | pcr->extra_caps & EXTRA_CAPS_SD_SDR104)
|
| 196 | rts5261_sd_set_sample_push_timing_sd30(pcr);
|
| 197 |
|
| 198 | return 0;
|
| 199 | }
|
| 200 |
|
| 201 | static int rts5261_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
|
| 202 | {
|
| 203 | int err;
|
| 204 | u16 val = 0;
|
| 205 |
|
| 206 | rtsx_pci_write_register(pcr, RTS5261_CARD_PWR_CTL,
|
| 207 | RTS5261_PUPDC, RTS5261_PUPDC);
|
| 208 |
|
| 209 | switch (voltage) {
|
| 210 | case OUTPUT_3V3:
|
| 211 | rtsx_pci_read_phy_register(pcr, PHY_TUNE, &val);
|
| 212 | val |= PHY_TUNE_SDBUS_33;
|
| 213 | err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, val);
|
| 214 | if (err < 0)
|
| 215 | return err;
|
| 216 |
|
| 217 | rtsx_pci_write_register(pcr, RTS5261_DV3318_CFG,
|
| 218 | RTS5261_DV3318_TUNE_MASK, RTS5261_DV3318_33);
|
| 219 | rtsx_pci_write_register(pcr, SD_PAD_CTL,
|
| 220 | SD_IO_USING_1V8, 0);
|
| 221 | break;
|
| 222 | case OUTPUT_1V8:
|
| 223 | rtsx_pci_read_phy_register(pcr, PHY_TUNE, &val);
|
| 224 | val &= ~PHY_TUNE_SDBUS_33;
|
| 225 | err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, val);
|
| 226 | if (err < 0)
|
| 227 | return err;
|
| 228 |
|
| 229 | rtsx_pci_write_register(pcr, RTS5261_DV3318_CFG,
|
| 230 | RTS5261_DV3318_TUNE_MASK, RTS5261_DV3318_18);
|
| 231 | rtsx_pci_write_register(pcr, SD_PAD_CTL,
|
| 232 | SD_IO_USING_1V8, SD_IO_USING_1V8);
|
| 233 | break;
|
| 234 | default:
|
| 235 | return -EINVAL;
|
| 236 | }
|
| 237 |
|
| 238 |
|
| 239 | rts5261_fill_driving(pcr, voltage);
|
| 240 |
|
| 241 | return 0;
|
| 242 | }
|
| 243 |
|
| 244 | static void rts5261_stop_cmd(struct rtsx_pcr *pcr)
|
| 245 | {
|
| 246 | rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD);
|
| 247 | rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA);
|
| 248 | rtsx_pci_write_register(pcr, RTS5260_DMA_RST_CTL_0,
|
| 249 | RTS5260_DMA_RST | RTS5260_ADMA3_RST,
|
| 250 | RTS5260_DMA_RST | RTS5260_ADMA3_RST);
|
| 251 | rtsx_pci_write_register(pcr, RBCTL, RB_FLUSH, RB_FLUSH);
|
| 252 | }
|
| 253 |
|
| 254 | static void rts5261_card_before_power_off(struct rtsx_pcr *pcr)
|
| 255 | {
|
| 256 | rts5261_stop_cmd(pcr);
|
| 257 | rts5261_switch_output_voltage(pcr, OUTPUT_3V3);
|
| 258 |
|
| 259 | }
|
| 260 |
|
| 261 | static void rts5261_enable_ocp(struct rtsx_pcr *pcr)
|
| 262 | {
|
| 263 | u8 val = 0;
|
| 264 |
|
| 265 | val = SD_OCP_INT_EN | SD_DETECT_EN;
|
| 266 | rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG0,
|
| 267 | RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN,
|
| 268 | RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN);
|
| 269 | rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
|
| 270 |
|
| 271 | }
|
| 272 |
|
| 273 | static void rts5261_disable_ocp(struct rtsx_pcr *pcr)
|
| 274 | {
|
| 275 | u8 mask = 0;
|
| 276 |
|
| 277 | mask = SD_OCP_INT_EN | SD_DETECT_EN;
|
| 278 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
|
| 279 | rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG0,
|
| 280 | RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN, 0);
|
| 281 |
|
| 282 | }
|
| 283 |
|
| 284 | static int rts5261_card_power_off(struct rtsx_pcr *pcr, int card)
|
| 285 | {
|
| 286 | int err = 0;
|
| 287 |
|
| 288 | rts5261_card_before_power_off(pcr);
|
| 289 | err = rtsx_pci_write_register(pcr, RTS5261_LDO1233318_POW_CTL,
|
| 290 | RTS5261_LDO_POWERON_MASK, 0);
|
| 291 |
|
| 292 | rtsx_pci_write_register(pcr, REG_CRC_DUMMY_0,
|
| 293 | CFG_SD_POW_AUTO_PD, 0);
|
| 294 | if (pcr->option.ocp_en)
|
| 295 | rtsx_pci_disable_ocp(pcr);
|
| 296 |
|
| 297 | return err;
|
| 298 | }
|
| 299 |
|
| 300 | static void rts5261_init_ocp(struct rtsx_pcr *pcr)
|
| 301 | {
|
| 302 | struct rtsx_cr_option *option = &pcr->option;
|
| 303 |
|
| 304 | if (option->ocp_en) {
|
| 305 | u8 mask, val;
|
| 306 |
|
| 307 | rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG0,
|
| 308 | RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN,
|
| 309 | RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN);
|
| 310 |
|
| 311 | rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG0,
|
| 312 | RTS5261_LDO1_OCP_THD_MASK, option->sd_800mA_ocp_thd);
|
| 313 |
|
| 314 | rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG0,
|
| 315 | RTS5261_LDO1_OCP_LMT_THD_MASK,
|
| 316 | RTS5261_LDO1_LMT_THD_2000);
|
| 317 |
|
| 318 | mask = SD_OCP_GLITCH_MASK;
|
| 319 | val = pcr->hw_param.ocp_glitch;
|
| 320 | rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, val);
|
| 321 |
|
| 322 | rts5261_enable_ocp(pcr);
|
| 323 | } else {
|
| 324 | rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG0,
|
| 325 | RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN, 0);
|
| 326 | }
|
| 327 | }
|
| 328 |
|
| 329 | static void rts5261_clear_ocpstat(struct rtsx_pcr *pcr)
|
| 330 | {
|
| 331 | u8 mask = 0;
|
| 332 | u8 val = 0;
|
| 333 |
|
| 334 | mask = SD_OCP_INT_CLR | SD_OC_CLR;
|
| 335 | val = SD_OCP_INT_CLR | SD_OC_CLR;
|
| 336 |
|
| 337 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
|
| 338 |
|
| 339 | udelay(1000);
|
| 340 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
|
| 341 |
|
| 342 | }
|
| 343 |
|
| 344 | static void rts5261_process_ocp(struct rtsx_pcr *pcr)
|
| 345 | {
|
| 346 | if (!pcr->option.ocp_en)
|
| 347 | return;
|
| 348 |
|
| 349 | rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat);
|
| 350 |
|
| 351 | if (pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
|
| 352 | rts5261_clear_ocpstat(pcr);
|
| 353 | rts5261_card_power_off(pcr, RTSX_SD_CARD);
|
| 354 | rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
|
| 355 | pcr->ocp_stat = 0;
|
| 356 | }
|
| 357 |
|
| 358 | }
|
| 359 |
|
| 360 | static void rts5261_init_from_hw(struct rtsx_pcr *pcr)
|
| 361 | {
|
| 362 | struct pci_dev *pdev = pcr->pci;
|
| 363 | u32 lval1, lval2, i;
|
| 364 | u16 setting_reg1, setting_reg2;
|
| 365 | u8 valid, efuse_valid, tmp;
|
| 366 |
|
| 367 | rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
|
| 368 | REG_EFUSE_POR | REG_EFUSE_POWER_MASK,
|
| 369 | REG_EFUSE_POR | REG_EFUSE_POWERON);
|
| 370 | udelay(1);
|
| 371 | rtsx_pci_write_register(pcr, RTS5261_EFUSE_ADDR,
|
| 372 | RTS5261_EFUSE_ADDR_MASK, 0x00);
|
| 373 | rtsx_pci_write_register(pcr, RTS5261_EFUSE_CTL,
|
| 374 | RTS5261_EFUSE_ENABLE | RTS5261_EFUSE_MODE_MASK,
|
| 375 | RTS5261_EFUSE_ENABLE);
|
| 376 |
|
| 377 |
|
| 378 | for (i = 0; i < MAX_RW_REG_CNT; i++) {
|
| 379 | rtsx_pci_read_register(pcr, RTS5261_EFUSE_CTL, &tmp);
|
| 380 | if ((tmp & 0x80) == 0)
|
| 381 | break;
|
| 382 | }
|
| 383 | rtsx_pci_read_register(pcr, RTS5261_EFUSE_READ_DATA, &tmp);
|
| 384 | efuse_valid = ((tmp & 0x0C) >> 2);
|
| 385 | pcr_dbg(pcr, "Load efuse valid: 0x%x\n", efuse_valid);
|
| 386 |
|
| 387 | pci_read_config_dword(pdev, PCR_SETTING_REG2, &lval2);
|
| 388 | pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, lval2);
|
| 389 |
|
| 390 | valid = (u8)((lval2 >> 16) & 0x03);
|
| 391 |
|
| 392 | rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
|
| 393 | REG_EFUSE_POR, 0);
|
| 394 | pcr_dbg(pcr, "Disable efuse por!\n");
|
| 395 |
|
| 396 | if (efuse_valid == 2 || efuse_valid == 3) {
|
| 397 | if (valid == 3) {
|
| 398 |
|
| 399 | setting_reg1 = PCR_SETTING_REG1;
|
| 400 | setting_reg2 = PCR_SETTING_REG2;
|
| 401 | } else {
|
| 402 |
|
| 403 | setting_reg1 = PCR_SETTING_REG4;
|
| 404 | setting_reg2 = PCR_SETTING_REG5;
|
| 405 | }
|
| 406 | } else if (efuse_valid == 0) {
|
| 407 | |
| 408 | setting_reg1 = PCR_SETTING_REG1;
|
| 409 | setting_reg2 = PCR_SETTING_REG2;
|
| 410 | } else {
|
| 411 | return;
|
| 412 | }
|
| 413 |
|
| 414 | pci_read_config_dword(pdev, setting_reg2, &lval2);
|
| 415 | pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", setting_reg2, lval2);
|
| 416 |
|
| 417 | if (!rts5261_vendor_setting_valid(lval2)) {
|
| 418 |
|
| 419 | pcr->extra_caps |= EXTRA_CAPS_NO_MMC;
|
| 420 | pcr_dbg(pcr, "skip fetch vendor setting\n");
|
| 421 | return;
|
| 422 | }
|
| 423 |
|
| 424 | if (!rts5261_reg_check_mmc_support(lval2))
|
| 425 | pcr->extra_caps |= EXTRA_CAPS_NO_MMC;
|
| 426 |
|
| 427 | pcr->rtd3_en = rts5261_reg_to_rtd3(lval2);
|
| 428 |
|
| 429 | if (rts5261_reg_check_reverse_socket(lval2))
|
| 430 | pcr->flags |= PCR_REVERSE_SOCKET;
|
| 431 |
|
| 432 | pci_read_config_dword(pdev, setting_reg1, &lval1);
|
| 433 | pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", setting_reg1, lval1);
|
| 434 |
|
| 435 | pcr->aspm_en = rts5261_reg_to_aspm(lval1);
|
| 436 | pcr->sd30_drive_sel_1v8 = rts5261_reg_to_sd30_drive_sel_1v8(lval1);
|
| 437 | pcr->sd30_drive_sel_3v3 = rts5261_reg_to_sd30_drive_sel_3v3(lval1);
|
| 438 |
|
| 439 | if (setting_reg1 == PCR_SETTING_REG1) {
|
| 440 |
|
| 441 | rtsx_pci_write_register(pcr, 0xFF0C, 0xFF, (u8)(lval1 & 0xFF));
|
| 442 | rtsx_pci_write_register(pcr, 0xFF0D, 0xFF, (u8)((lval1 >> 8) & 0xFF));
|
| 443 | rtsx_pci_write_register(pcr, 0xFF0E, 0xFF, (u8)((lval1 >> 16) & 0xFF));
|
| 444 | rtsx_pci_write_register(pcr, 0xFF0F, 0xFF, (u8)((lval1 >> 24) & 0xFF));
|
| 445 | rtsx_pci_write_register(pcr, 0xFF10, 0xFF, (u8)(lval2 & 0xFF));
|
| 446 | rtsx_pci_write_register(pcr, 0xFF11, 0xFF, (u8)((lval2 >> 8) & 0xFF));
|
| 447 | rtsx_pci_write_register(pcr, 0xFF12, 0xFF, (u8)((lval2 >> 16) & 0xFF));
|
| 448 |
|
| 449 | pci_write_config_dword(pdev, PCR_SETTING_REG4, lval1);
|
| 450 | lval2 = lval2 & 0x00FFFFFF;
|
| 451 | pci_write_config_dword(pdev, PCR_SETTING_REG5, lval2);
|
| 452 | }
|
| 453 | }
|
| 454 |
|
| 455 | static void rts5261_init_from_cfg(struct rtsx_pcr *pcr)
|
| 456 | {
|
| 457 | struct rtsx_cr_option *option = &pcr->option;
|
| 458 |
|
| 459 | if (option->ltr_en) {
|
| 460 | if (option->ltr_enabled)
|
| 461 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
|
| 462 | }
|
| 463 | }
|
| 464 |
|
| 465 | static int rts5261_extra_init_hw(struct rtsx_pcr *pcr)
|
| 466 | {
|
| 467 | struct rtsx_cr_option *option = &pcr->option;
|
| 468 | u32 val;
|
| 469 |
|
| 470 | rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1,
|
| 471 | CD_RESUME_EN_MASK, CD_RESUME_EN_MASK);
|
| 472 |
|
| 473 | rts5261_init_from_cfg(pcr);
|
| 474 | rts5261_init_from_hw(pcr);
|
| 475 |
|
| 476 |
|
| 477 | rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
|
| 478 | REG_EFUSE_POWER_MASK, REG_EFUSE_POWEROFF);
|
| 479 | rtsx_pci_write_register(pcr, L1SUB_CONFIG1,
|
| 480 | AUX_CLK_ACTIVE_SEL_MASK, MAC_CKSW_DONE);
|
| 481 | rtsx_pci_write_register(pcr, L1SUB_CONFIG3, 0xFF, 0);
|
| 482 |
|
| 483 | if (is_version_higher_than(pcr, PID_5261, IC_VER_B)) {
|
| 484 | val = rtsx_pci_readl(pcr, RTSX_DUM_REG);
|
| 485 | rtsx_pci_writel(pcr, RTSX_DUM_REG, val | 0x1);
|
| 486 | }
|
| 487 | rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG4,
|
| 488 | RTS5261_AUX_CLK_16M_EN, 0);
|
| 489 |
|
| 490 |
|
| 491 | rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG4,
|
| 492 | RTS5261_FORCE_PRSNT_LOW, 0);
|
| 493 | rtsx_pci_write_register(pcr, FUNC_FORCE_CTL,
|
| 494 | FUNC_FORCE_UPME_XMT_DBG, FUNC_FORCE_UPME_XMT_DBG);
|
| 495 |
|
| 496 | rtsx_pci_write_register(pcr, PCLK_CTL,
|
| 497 | PCLK_MODE_SEL, PCLK_MODE_SEL);
|
| 498 |
|
| 499 | rtsx_pci_write_register(pcr, PM_EVENT_DEBUG, PME_DEBUG_0, PME_DEBUG_0);
|
| 500 | rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, CLK_PM_EN, CLK_PM_EN);
|
| 501 |
|
| 502 |
|
| 503 | rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x0F, 0x02);
|
| 504 |
|
| 505 |
|
| 506 | rts5261_fill_driving(pcr, OUTPUT_3V3);
|
| 507 |
|
| 508 | if (pcr->flags & PCR_REVERSE_SOCKET)
|
| 509 | rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x30);
|
| 510 | else
|
| 511 | rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00);
|
| 512 |
|
| 513 | |
| 514 | * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
|
| 515 | * to drive low, and we forcibly request clock.
|
| 516 |
|
| 517 | if (option->force_clkreq_0)
|
| 518 | rtsx_pci_write_register(pcr, PETXCFG,
|
| 519 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
|
| 520 | else
|
| 521 | rtsx_pci_write_register(pcr, PETXCFG,
|
| 522 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH);
|
| 523 |
|
| 524 | rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB);
|
| 525 |
|
| 526 | if (pcr->rtd3_en) {
|
| 527 | rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x01, 0x01);
|
| 528 | rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
|
| 529 | FORCE_PM_CONTROL | FORCE_PM_VALUE,
|
| 530 | FORCE_PM_CONTROL | FORCE_PM_VALUE);
|
| 531 | } else {
|
| 532 | rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x01, 0x00);
|
| 533 | rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
|
| 534 | FORCE_PM_CONTROL | FORCE_PM_VALUE, FORCE_PM_CONTROL);
|
| 535 | }
|
| 536 | rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, D3_DELINK_MODE_EN, 0x00);
|
| 537 |
|
| 538 |
|
| 539 | rtsx_pci_write_register(pcr, RTS5261_FW_CTL,
|
| 540 | RTS5261_INFORM_RTD3_COLD, 0);
|
| 541 |
|
| 542 | return 0;
|
| 543 | }
|
| 544 |
|
| 545 | static void rts5261_enable_aspm(struct rtsx_pcr *pcr, bool enable)
|
| 546 | {
|
| 547 | u8 val = FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1;
|
| 548 | u8 mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1;
|
| 549 |
|
| 550 | if (pcr->aspm_enabled == enable)
|
| 551 | return;
|
| 552 |
|
| 553 | val |= (pcr->aspm_en & 0x02);
|
| 554 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val);
|
| 555 | pcie_capability_clear_and_set_word(pcr->pci, PCI_EXP_LNKCTL,
|
| 556 | PCI_EXP_LNKCTL_ASPMC, pcr->aspm_en);
|
| 557 | pcr->aspm_enabled = enable;
|
| 558 | }
|
| 559 |
|
| 560 | static void rts5261_disable_aspm(struct rtsx_pcr *pcr, bool enable)
|
| 561 | {
|
| 562 | u8 val = FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1;
|
| 563 | u8 mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1;
|
| 564 |
|
| 565 | if (pcr->aspm_enabled == enable)
|
| 566 | return;
|
| 567 |
|
| 568 | pcie_capability_clear_and_set_word(pcr->pci, PCI_EXP_LNKCTL,
|
| 569 | PCI_EXP_LNKCTL_ASPMC, 0);
|
| 570 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val);
|
| 571 | rtsx_pci_write_register(pcr, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0);
|
| 572 | udelay(10);
|
| 573 | pcr->aspm_enabled = enable;
|
| 574 | }
|
| 575 |
|
| 576 | static void rts5261_set_aspm(struct rtsx_pcr *pcr, bool enable)
|
| 577 | {
|
| 578 | if (enable)
|
| 579 | rts5261_enable_aspm(pcr, true);
|
| 580 | else
|
| 581 | rts5261_disable_aspm(pcr, false);
|
| 582 | }
|
| 583 |
|
| 584 | static void rts5261_set_l1off_cfg_sub_d0(struct rtsx_pcr *pcr, int active)
|
| 585 | {
|
| 586 | struct rtsx_cr_option *option = &pcr->option;
|
| 587 | int aspm_L1_1, aspm_L1_2;
|
| 588 | u8 val = 0;
|
| 589 |
|
| 590 | aspm_L1_1 = rtsx_check_dev_flag(pcr, ASPM_L1_1_EN);
|
| 591 | aspm_L1_2 = rtsx_check_dev_flag(pcr, ASPM_L1_2_EN);
|
| 592 |
|
| 593 | if (active) {
|
| 594 |
|
| 595 | if (aspm_L1_1)
|
| 596 | val = option->ltr_l1off_snooze_sspwrgate;
|
| 597 | } else {
|
| 598 |
|
| 599 | if (aspm_L1_2)
|
| 600 | val = option->ltr_l1off_sspwrgate;
|
| 601 | }
|
| 602 |
|
| 603 | rtsx_set_l1off_sub(pcr, val);
|
| 604 | }
|
| 605 |
|
| 606 | static const struct pcr_ops rts5261_pcr_ops = {
|
| 607 | .turn_on_led = rts5261_turn_on_led,
|
| 608 | .turn_off_led = rts5261_turn_off_led,
|
| 609 | .extra_init_hw = rts5261_extra_init_hw,
|
| 610 | .enable_auto_blink = rts5261_enable_auto_blink,
|
| 611 | .disable_auto_blink = rts5261_disable_auto_blink,
|
| 612 | .card_power_on = rts5261_card_power_on,
|
| 613 | .card_power_off = rts5261_card_power_off,
|
| 614 | .switch_output_voltage = rts5261_switch_output_voltage,
|
| 615 | .force_power_down = rts5261_force_power_down,
|
| 616 | .stop_cmd = rts5261_stop_cmd,
|
| 617 | .set_aspm = rts5261_set_aspm,
|
| 618 | .set_l1off_cfg_sub_d0 = rts5261_set_l1off_cfg_sub_d0,
|
| 619 | .enable_ocp = rts5261_enable_ocp,
|
| 620 | .disable_ocp = rts5261_disable_ocp,
|
| 621 | .init_ocp = rts5261_init_ocp,
|
| 622 | .process_ocp = rts5261_process_ocp,
|
| 623 | .clear_ocpstat = rts5261_clear_ocpstat,
|
| 624 | };
|
| 625 |
|
| 626 | static inline u8 double_ssc_depth(u8 depth)
|
| 627 | {
|
| 628 | return ((depth > 1) ? (depth - 1) : depth);
|
| 629 | }
|
| 630 |
|
| 631 | int rts5261_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
|
| 632 | u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk)
|
| 633 | {
|
| 634 | int err, clk;
|
| 635 | u16 n;
|
| 636 | u8 clk_divider, mcu_cnt, div;
|
| 637 | static const u8 depth[] = {
|
| 638 | [RTSX_SSC_DEPTH_4M] = RTS5261_SSC_DEPTH_4M,
|
| 639 | [RTSX_SSC_DEPTH_2M] = RTS5261_SSC_DEPTH_2M,
|
| 640 | [RTSX_SSC_DEPTH_1M] = RTS5261_SSC_DEPTH_1M,
|
| 641 | [RTSX_SSC_DEPTH_500K] = RTS5261_SSC_DEPTH_512K,
|
| 642 | };
|
| 643 |
|
| 644 | if (initial_mode) {
|
| 645 |
|
| 646 | if (is_version_higher_than(pcr, PID_5261, IC_VER_C)) {
|
| 647 | clk_divider = SD_CLK_DIVIDE_256;
|
| 648 | card_clock = 60000000;
|
| 649 | } else {
|
| 650 | clk_divider = SD_CLK_DIVIDE_128;
|
| 651 | card_clock = 30000000;
|
| 652 | }
|
| 653 | } else {
|
| 654 | clk_divider = SD_CLK_DIVIDE_0;
|
| 655 | }
|
| 656 | err = rtsx_pci_write_register(pcr, SD_CFG1,
|
| 657 | SD_CLK_DIVIDE_MASK, clk_divider);
|
| 658 | if (err < 0)
|
| 659 | return err;
|
| 660 |
|
| 661 | card_clock /= 1000000;
|
| 662 | pcr_dbg(pcr, "Switch card clock to %dMHz\n", card_clock);
|
| 663 |
|
| 664 | clk = card_clock;
|
| 665 | if (!initial_mode && double_clk)
|
| 666 | clk = card_clock * 2;
|
| 667 | pcr_dbg(pcr, "Internal SSC clock: %dMHz (cur_clock = %d)\n",
|
| 668 | clk, pcr->cur_clock);
|
| 669 |
|
| 670 | if (clk == pcr->cur_clock)
|
| 671 | return 0;
|
| 672 |
|
| 673 | if (pcr->ops->conv_clk_and_div_n)
|
| 674 | n = pcr->ops->conv_clk_and_div_n(clk, CLK_TO_DIV_N);
|
| 675 | else
|
| 676 | n = clk - 4;
|
| 677 | if ((clk <= 4) || (n > 396))
|
| 678 | return -EINVAL;
|
| 679 |
|
| 680 | mcu_cnt = 125/clk + 3;
|
| 681 | if (mcu_cnt > 15)
|
| 682 | mcu_cnt = 15;
|
| 683 |
|
| 684 | div = CLK_DIV_1;
|
| 685 | while ((n < MIN_DIV_N_PCR - 4) && (div < CLK_DIV_8)) {
|
| 686 | if (pcr->ops->conv_clk_and_div_n) {
|
| 687 | int dbl_clk = pcr->ops->conv_clk_and_div_n(n,
|
| 688 | DIV_N_TO_CLK) * 2;
|
| 689 | n = pcr->ops->conv_clk_and_div_n(dbl_clk,
|
| 690 | CLK_TO_DIV_N);
|
| 691 | } else {
|
| 692 | n = (n + 4) * 2 - 4;
|
| 693 | }
|
| 694 | div++;
|
| 695 | }
|
| 696 |
|
| 697 | n = (n / 2) - 1;
|
| 698 | pcr_dbg(pcr, "n = %d, div = %d\n", n, div);
|
| 699 |
|
| 700 | ssc_depth = depth[ssc_depth];
|
| 701 | if (double_clk)
|
| 702 | ssc_depth = double_ssc_depth(ssc_depth);
|
| 703 |
|
| 704 | if (ssc_depth) {
|
| 705 | if (div == CLK_DIV_2) {
|
| 706 | if (ssc_depth > 1)
|
| 707 | ssc_depth -= 1;
|
| 708 | else
|
| 709 | ssc_depth = RTS5261_SSC_DEPTH_8M;
|
| 710 | } else if (div == CLK_DIV_4) {
|
| 711 | if (ssc_depth > 2)
|
| 712 | ssc_depth -= 2;
|
| 713 | else
|
| 714 | ssc_depth = RTS5261_SSC_DEPTH_8M;
|
| 715 | } else if (div == CLK_DIV_8) {
|
| 716 | if (ssc_depth > 3)
|
| 717 | ssc_depth -= 3;
|
| 718 | else
|
| 719 | ssc_depth = RTS5261_SSC_DEPTH_8M;
|
| 720 | }
|
| 721 | } else {
|
| 722 | ssc_depth = 0;
|
| 723 | }
|
| 724 | pcr_dbg(pcr, "ssc_depth = %d\n", ssc_depth);
|
| 725 |
|
| 726 | rtsx_pci_init_cmd(pcr);
|
| 727 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL,
|
| 728 | CLK_LOW_FREQ, CLK_LOW_FREQ);
|
| 729 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_DIV,
|
| 730 | 0xFF, (div << 4) | mcu_cnt);
|
| 731 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
|
| 732 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2,
|
| 733 | SSC_DEPTH_MASK, ssc_depth);
|
| 734 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, n);
|
| 735 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB);
|
| 736 | if (vpclk) {
|
| 737 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL,
|
| 738 | PHASE_NOT_RESET, 0);
|
| 739 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK1_CTL,
|
| 740 | PHASE_NOT_RESET, 0);
|
| 741 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL,
|
| 742 | PHASE_NOT_RESET, PHASE_NOT_RESET);
|
| 743 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK1_CTL,
|
| 744 | PHASE_NOT_RESET, PHASE_NOT_RESET);
|
| 745 | }
|
| 746 |
|
| 747 | err = rtsx_pci_send_cmd(pcr, 2000);
|
| 748 | if (err < 0)
|
| 749 | return err;
|
| 750 |
|
| 751 |
|
| 752 | udelay(SSC_CLOCK_STABLE_WAIT);
|
| 753 | err = rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
|
| 754 | if (err < 0)
|
| 755 | return err;
|
| 756 |
|
| 757 | pcr->cur_clock = clk;
|
| 758 | return 0;
|
| 759 |
|
| 760 | }
|
| 761 |
|
| 762 | void rts5261_init_params(struct rtsx_pcr *pcr)
|
| 763 | {
|
| 764 | struct rtsx_cr_option *option = &pcr->option;
|
| 765 | struct rtsx_hw_param *hw_param = &pcr->hw_param;
|
| 766 | u8 val;
|
| 767 |
|
| 768 | pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
|
| 769 | rtsx_pci_read_register(pcr, RTS5261_FW_STATUS, &val);
|
| 770 | if (!(val & RTS5261_EXPRESS_LINK_FAIL_MASK))
|
| 771 | pcr->extra_caps |= EXTRA_CAPS_SD_EXPRESS;
|
| 772 | pcr->num_slots = 1;
|
| 773 | pcr->ops = &rts5261_pcr_ops;
|
| 774 |
|
| 775 | pcr->flags = 0;
|
| 776 | pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
|
| 777 | pcr->sd30_drive_sel_1v8 = 0x00;
|
| 778 | pcr->sd30_drive_sel_3v3 = 0x00;
|
| 779 | pcr->aspm_en = ASPM_L1_EN;
|
| 780 | pcr->aspm_mode = ASPM_MODE_REG;
|
| 781 | pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 11);
|
| 782 | pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5);
|
| 783 |
|
| 784 | pcr->ic_version = rts5261_get_ic_version(pcr);
|
| 785 | pcr->sd_pull_ctl_enable_tbl = rts5261_sd_pull_ctl_enable_tbl;
|
| 786 | pcr->sd_pull_ctl_disable_tbl = rts5261_sd_pull_ctl_disable_tbl;
|
| 787 |
|
| 788 | pcr->reg_pm_ctrl3 = RTS5261_AUTOLOAD_CFG3;
|
| 789 |
|
| 790 | option->dev_flags = (LTR_L1SS_PWR_GATE_CHECK_CARD_EN
|
| 791 | | LTR_L1SS_PWR_GATE_EN);
|
| 792 | option->ltr_en = true;
|
| 793 |
|
| 794 |
|
| 795 | option->ltr_active_latency = LTR_ACTIVE_LATENCY_DEF;
|
| 796 | option->ltr_idle_latency = LTR_IDLE_LATENCY_DEF;
|
| 797 | option->ltr_l1off_latency = LTR_L1OFF_LATENCY_DEF;
|
| 798 | option->l1_snooze_delay = L1_SNOOZE_DELAY_DEF;
|
| 799 | option->ltr_l1off_sspwrgate = 0x7F;
|
| 800 | option->ltr_l1off_snooze_sspwrgate = 0x78;
|
| 801 |
|
| 802 | option->ocp_en = 1;
|
| 803 | hw_param->interrupt_en |= SD_OC_INT_EN;
|
| 804 | hw_param->ocp_glitch = SD_OCP_GLITCH_800U;
|
| 805 | option->sd_800mA_ocp_thd = RTS5261_LDO1_OCP_THD_1040;
|
| 806 | }
|