| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* Driver for Realtek PCI-Express card reader |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright(c) 2016-2017 Realtek Semiconductor Corp. All rights reserved. |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 6 | | - * under the terms of the GNU General Public License as published by the |
|---|
| 7 | | - * Free Software Foundation; either version 2, or (at your option) any |
|---|
| 8 | | - * later version. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 11 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 13 | | - * General Public License for more details. |
|---|
| 14 | | - * |
|---|
| 15 | | - * You should have received a copy of the GNU General Public License along |
|---|
| 16 | | - * with this program; if not, see <http://www.gnu.org/licenses/>. |
|---|
| 17 | 5 | * |
|---|
| 18 | 6 | * Author: |
|---|
| 19 | 7 | * Steven FENG <steven_feng@realsil.com.cn> |
|---|
| .. | .. |
|---|
| 38 | 26 | |
|---|
| 39 | 27 | static void rts5260_fill_driving(struct rtsx_pcr *pcr, u8 voltage) |
|---|
| 40 | 28 | { |
|---|
| 41 | | - u8 driving_3v3[6][3] = { |
|---|
| 42 | | - {0x94, 0x94, 0x94}, |
|---|
| 43 | | - {0x11, 0x11, 0x18}, |
|---|
| 44 | | - {0x55, 0x55, 0x5C}, |
|---|
| 45 | | - {0x94, 0x94, 0x94}, |
|---|
| 46 | | - {0x94, 0x94, 0x94}, |
|---|
| 47 | | - {0xFF, 0xFF, 0xFF}, |
|---|
| 29 | + u8 driving_3v3[4][3] = { |
|---|
| 30 | + {0x11, 0x11, 0x11}, |
|---|
| 31 | + {0x22, 0x22, 0x22}, |
|---|
| 32 | + {0x55, 0x55, 0x55}, |
|---|
| 33 | + {0x33, 0x33, 0x33}, |
|---|
| 48 | 34 | }; |
|---|
| 49 | | - u8 driving_1v8[6][3] = { |
|---|
| 50 | | - {0x9A, 0x89, 0x89}, |
|---|
| 51 | | - {0xC4, 0xC4, 0xC4}, |
|---|
| 52 | | - {0x3C, 0x3C, 0x3C}, |
|---|
| 35 | + u8 driving_1v8[4][3] = { |
|---|
| 36 | + {0x35, 0x33, 0x33}, |
|---|
| 37 | + {0x8A, 0x88, 0x88}, |
|---|
| 38 | + {0xBD, 0xBB, 0xBB}, |
|---|
| 53 | 39 | {0x9B, 0x99, 0x99}, |
|---|
| 54 | | - {0x9A, 0x89, 0x89}, |
|---|
| 55 | | - {0xFE, 0xFE, 0xFE}, |
|---|
| 56 | 40 | }; |
|---|
| 57 | 41 | u8 (*driving)[3], drive_sel; |
|---|
| 58 | 42 | |
|---|
| .. | .. |
|---|
| 64 | 48 | drive_sel = pcr->sd30_drive_sel_1v8; |
|---|
| 65 | 49 | } |
|---|
| 66 | 50 | |
|---|
| 67 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL, |
|---|
| 51 | + rtsx_pci_write_register(pcr, SD30_CLK_DRIVE_SEL, |
|---|
| 68 | 52 | 0xFF, driving[drive_sel][0]); |
|---|
| 69 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL, |
|---|
| 53 | + |
|---|
| 54 | + rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL, |
|---|
| 70 | 55 | 0xFF, driving[drive_sel][1]); |
|---|
| 71 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL, |
|---|
| 56 | + |
|---|
| 57 | + rtsx_pci_write_register(pcr, SD30_DAT_DRIVE_SEL, |
|---|
| 72 | 58 | 0xFF, driving[drive_sel][2]); |
|---|
| 73 | 59 | } |
|---|
| 74 | 60 | |
|---|
| 75 | 61 | static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr) |
|---|
| 76 | 62 | { |
|---|
| 63 | + struct pci_dev *pdev = pcr->pci; |
|---|
| 77 | 64 | u32 reg; |
|---|
| 78 | 65 | |
|---|
| 79 | | - rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®); |
|---|
| 66 | + pci_read_config_dword(pdev, PCR_SETTING_REG1, ®); |
|---|
| 80 | 67 | pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg); |
|---|
| 81 | 68 | |
|---|
| 82 | 69 | if (!rtsx_vendor_setting_valid(reg)) { |
|---|
| .. | .. |
|---|
| 89 | 76 | pcr->card_drive_sel &= 0x3F; |
|---|
| 90 | 77 | pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg); |
|---|
| 91 | 78 | |
|---|
| 92 | | - rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®); |
|---|
| 79 | + pci_read_config_dword(pdev, PCR_SETTING_REG2, ®); |
|---|
| 93 | 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; |
|---|
| 94 | 83 | pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg); |
|---|
| 95 | 84 | if (rtsx_reg_check_reverse_socket(reg)) |
|---|
| 96 | 85 | pcr->flags |= PCR_REVERSE_SOCKET; |
|---|
| 97 | | -} |
|---|
| 98 | | - |
|---|
| 99 | | -static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, u8 pm_state) |
|---|
| 100 | | -{ |
|---|
| 101 | | - /* Set relink_time to 0 */ |
|---|
| 102 | | - rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, MASK_8_BIT_DEF, 0); |
|---|
| 103 | | - rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, MASK_8_BIT_DEF, 0); |
|---|
| 104 | | - rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, |
|---|
| 105 | | - RELINK_TIME_MASK, 0); |
|---|
| 106 | | - |
|---|
| 107 | | - if (pm_state == HOST_ENTER_S3) |
|---|
| 108 | | - rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, |
|---|
| 109 | | - D3_DELINK_MODE_EN, D3_DELINK_MODE_EN); |
|---|
| 110 | | - |
|---|
| 111 | | - rtsx_pci_write_register(pcr, FPDCTL, ALL_POWER_DOWN, ALL_POWER_DOWN); |
|---|
| 112 | 86 | } |
|---|
| 113 | 87 | |
|---|
| 114 | 88 | static int rtsx_base_enable_auto_blink(struct rtsx_pcr *pcr) |
|---|
| .. | .. |
|---|
| 193 | 167 | | SD_ASYNC_FIFO_NOT_RST, SD_30_MODE | SD_ASYNC_FIFO_NOT_RST); |
|---|
| 194 | 168 | rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); |
|---|
| 195 | 169 | rtsx_pci_write_register(pcr, CARD_CLK_SOURCE, 0xFF, |
|---|
| 196 | | - CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); |
|---|
| 170 | + CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); |
|---|
| 197 | 171 | rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0); |
|---|
| 198 | 172 | |
|---|
| 199 | 173 | return 0; |
|---|
| .. | .. |
|---|
| 201 | 175 | |
|---|
| 202 | 176 | static int rts5260_card_power_on(struct rtsx_pcr *pcr, int card) |
|---|
| 203 | 177 | { |
|---|
| 204 | | - int err = 0; |
|---|
| 205 | 178 | struct rtsx_cr_option *option = &pcr->option; |
|---|
| 206 | 179 | |
|---|
| 207 | 180 | if (option->ocp_en) |
|---|
| 208 | 181 | rtsx_pci_enable_ocp(pcr); |
|---|
| 209 | 182 | |
|---|
| 210 | | - rtsx_pci_init_cmd(pcr); |
|---|
| 211 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2, |
|---|
| 212 | | - DV331812_VDD1, DV331812_VDD1); |
|---|
| 213 | | - err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF); |
|---|
| 214 | | - if (err < 0) |
|---|
| 215 | | - return err; |
|---|
| 216 | 183 | |
|---|
| 217 | | - rtsx_pci_init_cmd(pcr); |
|---|
| 218 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG0, |
|---|
| 184 | + rtsx_pci_write_register(pcr, LDO_CONFIG2, DV331812_VDD1, DV331812_VDD1); |
|---|
| 185 | + rtsx_pci_write_register(pcr, LDO_VCC_CFG0, |
|---|
| 219 | 186 | RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33); |
|---|
| 220 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1, |
|---|
| 221 | | - LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_ON); |
|---|
| 222 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2, |
|---|
| 223 | | - DV331812_POWERON, DV331812_POWERON); |
|---|
| 224 | | - err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF); |
|---|
| 225 | 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); |
|---|
| 226 | 193 | msleep(20); |
|---|
| 227 | 194 | |
|---|
| 228 | 195 | if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50 || |
|---|
| .. | .. |
|---|
| 242 | 209 | /* Reset SD_CFG3 register */ |
|---|
| 243 | 210 | rtsx_pci_write_register(pcr, SD_CFG3, SD30_CLK_END_EN, 0); |
|---|
| 244 | 211 | rtsx_pci_write_register(pcr, REG_SD_STOP_SDCLK_CFG, |
|---|
| 245 | | - SD30_CLK_STOP_CFG_EN | SD30_CLK_STOP_CFG1 | |
|---|
| 246 | | - SD30_CLK_STOP_CFG0, 0); |
|---|
| 212 | + SD30_CLK_STOP_CFG_EN | SD30_CLK_STOP_CFG1 | |
|---|
| 213 | + SD30_CLK_STOP_CFG0, 0); |
|---|
| 247 | 214 | |
|---|
| 248 | 215 | rtsx_pci_write_register(pcr, REG_PRE_RW_MODE, EN_INFINITE_MODE, 0); |
|---|
| 249 | 216 | |
|---|
| 250 | | - return err; |
|---|
| 217 | + return 0; |
|---|
| 251 | 218 | } |
|---|
| 252 | 219 | |
|---|
| 253 | 220 | static int rts5260_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) |
|---|
| .. | .. |
|---|
| 273 | 240 | } |
|---|
| 274 | 241 | |
|---|
| 275 | 242 | /* set pad drive */ |
|---|
| 276 | | - rtsx_pci_init_cmd(pcr); |
|---|
| 277 | 243 | rts5260_fill_driving(pcr, voltage); |
|---|
| 278 | | - return rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF); |
|---|
| 244 | + |
|---|
| 245 | + return 0; |
|---|
| 279 | 246 | } |
|---|
| 280 | 247 | |
|---|
| 281 | 248 | static void rts5260_stop_cmd(struct rtsx_pcr *pcr) |
|---|
| .. | .. |
|---|
| 290 | 257 | |
|---|
| 291 | 258 | static void rts5260_card_before_power_off(struct rtsx_pcr *pcr) |
|---|
| 292 | 259 | { |
|---|
| 293 | | - struct rtsx_cr_option *option = &pcr->option; |
|---|
| 294 | | - |
|---|
| 295 | 260 | rts5260_stop_cmd(pcr); |
|---|
| 296 | 261 | rts5260_switch_output_voltage(pcr, OUTPUT_3V3); |
|---|
| 297 | 262 | |
|---|
| 298 | | - if (option->ocp_en) |
|---|
| 299 | | - rtsx_pci_disable_ocp(pcr); |
|---|
| 300 | 263 | } |
|---|
| 301 | 264 | |
|---|
| 302 | 265 | static int rts5260_card_power_off(struct rtsx_pcr *pcr, int card) |
|---|
| .. | .. |
|---|
| 304 | 267 | int err = 0; |
|---|
| 305 | 268 | |
|---|
| 306 | 269 | rts5260_card_before_power_off(pcr); |
|---|
| 307 | | - |
|---|
| 308 | | - rtsx_pci_init_cmd(pcr); |
|---|
| 309 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1, |
|---|
| 270 | + err = rtsx_pci_write_register(pcr, LDO_VCC_CFG1, |
|---|
| 310 | 271 | LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF); |
|---|
| 311 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2, |
|---|
| 272 | + err = rtsx_pci_write_register(pcr, LDO_CONFIG2, |
|---|
| 312 | 273 | DV331812_POWERON, DV331812_POWEROFF); |
|---|
| 313 | | - err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF); |
|---|
| 274 | + if (pcr->option.ocp_en) |
|---|
| 275 | + rtsx_pci_disable_ocp(pcr); |
|---|
| 314 | 276 | |
|---|
| 315 | 277 | return err; |
|---|
| 316 | 278 | } |
|---|
| .. | .. |
|---|
| 322 | 284 | if (option->ocp_en) { |
|---|
| 323 | 285 | u8 mask, val; |
|---|
| 324 | 286 | |
|---|
| 287 | + |
|---|
| 288 | + rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, |
|---|
| 289 | + RTS5260_DVCC_OCP_THD_MASK, |
|---|
| 290 | + 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, val); |
|---|
| 325 | 299 | rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, |
|---|
| 326 | 300 | RTS5260_DVCC_OCP_EN | |
|---|
| 327 | 301 | RTS5260_DVCC_OCP_CL_EN, |
|---|
| 328 | 302 | RTS5260_DVCC_OCP_EN | |
|---|
| 329 | 303 | RTS5260_DVCC_OCP_CL_EN); |
|---|
| 330 | | - rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL, |
|---|
| 331 | | - RTS5260_DVIO_OCP_EN | |
|---|
| 332 | | - RTS5260_DVIO_OCP_CL_EN, |
|---|
| 333 | | - RTS5260_DVIO_OCP_EN | |
|---|
| 334 | | - RTS5260_DVIO_OCP_CL_EN); |
|---|
| 335 | | - |
|---|
| 336 | | - rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, |
|---|
| 337 | | - RTS5260_DVCC_OCP_THD_MASK, |
|---|
| 338 | | - option->sd_400mA_ocp_thd); |
|---|
| 339 | | - |
|---|
| 340 | | - rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL, |
|---|
| 341 | | - RTS5260_DVIO_OCP_THD_MASK, |
|---|
| 342 | | - RTS5260_DVIO_OCP_THD_350); |
|---|
| 343 | | - |
|---|
| 344 | | - rtsx_pci_write_register(pcr, RTS5260_DV331812_CFG, |
|---|
| 345 | | - RTS5260_DV331812_OCP_THD_MASK, |
|---|
| 346 | | - RTS5260_DV331812_OCP_THD_210); |
|---|
| 347 | | - |
|---|
| 348 | | - mask = SD_OCP_GLITCH_MASK | SDVIO_OCP_GLITCH_MASK; |
|---|
| 349 | | - val = pcr->hw_param.ocp_glitch; |
|---|
| 350 | | - rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, val); |
|---|
| 351 | 304 | |
|---|
| 352 | 305 | rtsx_pci_enable_ocp(pcr); |
|---|
| 353 | 306 | } else { |
|---|
| 354 | 307 | rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, |
|---|
| 355 | 308 | RTS5260_DVCC_OCP_EN | |
|---|
| 356 | 309 | RTS5260_DVCC_OCP_CL_EN, 0); |
|---|
| 357 | | - rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL, |
|---|
| 358 | | - RTS5260_DVIO_OCP_EN | |
|---|
| 359 | | - RTS5260_DVIO_OCP_CL_EN, 0); |
|---|
| 360 | 310 | } |
|---|
| 361 | 311 | } |
|---|
| 362 | 312 | |
|---|
| .. | .. |
|---|
| 364 | 314 | { |
|---|
| 365 | 315 | u8 val = 0; |
|---|
| 366 | 316 | |
|---|
| 367 | | - rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0); |
|---|
| 368 | | - |
|---|
| 369 | 317 | val = SD_OCP_INT_EN | SD_DETECT_EN; |
|---|
| 370 | | - val |= SDVIO_OCP_INT_EN | SDVIO_DETECT_EN; |
|---|
| 371 | 318 | rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val); |
|---|
| 372 | | - rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL, |
|---|
| 373 | | - DV3318_DETECT_EN | DV3318_OCP_INT_EN, |
|---|
| 374 | | - DV3318_DETECT_EN | DV3318_OCP_INT_EN); |
|---|
| 319 | + |
|---|
| 375 | 320 | } |
|---|
| 376 | 321 | |
|---|
| 377 | 322 | static void rts5260_disable_ocp(struct rtsx_pcr *pcr) |
|---|
| .. | .. |
|---|
| 379 | 324 | u8 mask = 0; |
|---|
| 380 | 325 | |
|---|
| 381 | 326 | mask = SD_OCP_INT_EN | SD_DETECT_EN; |
|---|
| 382 | | - mask |= SDVIO_OCP_INT_EN | SDVIO_DETECT_EN; |
|---|
| 383 | 327 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0); |
|---|
| 384 | | - rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL, |
|---|
| 385 | | - DV3318_DETECT_EN | DV3318_OCP_INT_EN, 0); |
|---|
| 386 | 328 | |
|---|
| 387 | | - rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, |
|---|
| 388 | | - OC_POWER_DOWN); |
|---|
| 389 | 329 | } |
|---|
| 330 | + |
|---|
| 390 | 331 | |
|---|
| 391 | 332 | static int rts5260_get_ocpstat(struct rtsx_pcr *pcr, u8 *val) |
|---|
| 392 | 333 | { |
|---|
| .. | .. |
|---|
| 404 | 345 | u8 val = 0; |
|---|
| 405 | 346 | |
|---|
| 406 | 347 | mask = SD_OCP_INT_CLR | SD_OC_CLR; |
|---|
| 407 | | - mask |= SDVIO_OCP_INT_CLR | SDVIO_OC_CLR; |
|---|
| 408 | 348 | val = SD_OCP_INT_CLR | SD_OC_CLR; |
|---|
| 409 | | - val |= SDVIO_OCP_INT_CLR | SDVIO_OC_CLR; |
|---|
| 410 | 349 | |
|---|
| 411 | 350 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val); |
|---|
| 412 | 351 | rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL, |
|---|
| .. | .. |
|---|
| 425 | 364 | |
|---|
| 426 | 365 | rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat); |
|---|
| 427 | 366 | rts5260_get_ocpstat2(pcr, &pcr->ocp_stat2); |
|---|
| 428 | | - if (pcr->card_exist & SD_EXIST) |
|---|
| 429 | | - rtsx_sd_power_off_card3v3(pcr); |
|---|
| 430 | | - else if (pcr->card_exist & MS_EXIST) |
|---|
| 431 | | - rtsx_ms_power_off_card3v3(pcr); |
|---|
| 432 | 367 | |
|---|
| 433 | | - if (!(pcr->card_exist & MS_EXIST) && !(pcr->card_exist & SD_EXIST)) { |
|---|
| 434 | | - if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER | |
|---|
| 435 | | - SDVIO_OC_NOW | SDVIO_OC_EVER)) || |
|---|
| 436 | | - (pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) |
|---|
| 437 | | - rtsx_pci_clear_ocpstat(pcr); |
|---|
| 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); |
|---|
| 438 | 373 | pcr->ocp_stat = 0; |
|---|
| 439 | 374 | pcr->ocp_stat2 = 0; |
|---|
| 440 | 375 | } |
|---|
| 441 | 376 | |
|---|
| 442 | | - if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER | |
|---|
| 443 | | - SDVIO_OC_NOW | SDVIO_OC_EVER)) || |
|---|
| 444 | | - (pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) { |
|---|
| 445 | | - if (pcr->card_exist & SD_EXIST) |
|---|
| 446 | | - rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0); |
|---|
| 447 | | - else if (pcr->card_exist & MS_EXIST) |
|---|
| 448 | | - rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, 0); |
|---|
| 449 | | - } |
|---|
| 450 | 377 | } |
|---|
| 451 | 378 | |
|---|
| 452 | 379 | static int rts5260_init_hw(struct rtsx_pcr *pcr) |
|---|
| 453 | 380 | { |
|---|
| 454 | 381 | int err; |
|---|
| 455 | | - |
|---|
| 456 | | - rtsx_pci_init_ocp(pcr); |
|---|
| 457 | 382 | |
|---|
| 458 | 383 | rtsx_pci_init_cmd(pcr); |
|---|
| 459 | 384 | |
|---|
| .. | .. |
|---|
| 483 | 408 | if (err < 0) |
|---|
| 484 | 409 | return err; |
|---|
| 485 | 410 | |
|---|
| 411 | + rtsx_pci_init_ocp(pcr); |
|---|
| 412 | + |
|---|
| 486 | 413 | return 0; |
|---|
| 487 | 414 | } |
|---|
| 488 | 415 | |
|---|
| .. | .. |
|---|
| 495 | 422 | lss_l1_2 = rtsx_check_dev_flag(pcr, ASPM_L1_2_EN) |
|---|
| 496 | 423 | | rtsx_check_dev_flag(pcr, PM_L1_2_EN); |
|---|
| 497 | 424 | |
|---|
| 425 | + rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0); |
|---|
| 498 | 426 | if (lss_l1_2) { |
|---|
| 499 | 427 | pcr_dbg(pcr, "Set parameters for L1.2."); |
|---|
| 500 | 428 | rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL, |
|---|
| 501 | 429 | 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 | + |
|---|
| 502 | 436 | rtsx_pci_write_register(pcr, PWR_FE_CTL, |
|---|
| 503 | 437 | 0xFF, PCIE_L1_2_PD_FE_EN); |
|---|
| 504 | 438 | } else if (lss_l1_1) { |
|---|
| .. | .. |
|---|
| 546 | 480 | |
|---|
| 547 | 481 | static void rts5260_init_from_cfg(struct rtsx_pcr *pcr) |
|---|
| 548 | 482 | { |
|---|
| 483 | + struct pci_dev *pdev = pcr->pci; |
|---|
| 484 | + int l1ss; |
|---|
| 549 | 485 | struct rtsx_cr_option *option = &pcr->option; |
|---|
| 550 | 486 | u32 lval; |
|---|
| 551 | 487 | |
|---|
| 552 | | - rtsx_pci_read_config_dword(pcr, PCR_ASPM_SETTING_5260, &lval); |
|---|
| 488 | + l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); |
|---|
| 489 | + if (!l1ss) |
|---|
| 490 | + return; |
|---|
| 553 | 491 | |
|---|
| 554 | | - if (lval & ASPM_L1_1_EN_MASK) |
|---|
| 492 | + pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); |
|---|
| 493 | + |
|---|
| 494 | + if (lval & PCI_L1SS_CTL1_ASPM_L1_1) |
|---|
| 555 | 495 | rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); |
|---|
| 556 | 496 | |
|---|
| 557 | | - if (lval & ASPM_L1_2_EN_MASK) |
|---|
| 497 | + if (lval & PCI_L1SS_CTL1_ASPM_L1_2) |
|---|
| 558 | 498 | rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); |
|---|
| 559 | 499 | |
|---|
| 560 | | - if (lval & PM_L1_1_EN_MASK) |
|---|
| 500 | + if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) |
|---|
| 561 | 501 | rtsx_set_dev_flag(pcr, PM_L1_1_EN); |
|---|
| 562 | 502 | |
|---|
| 563 | | - if (lval & PM_L1_2_EN_MASK) |
|---|
| 503 | + if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) |
|---|
| 564 | 504 | rtsx_set_dev_flag(pcr, PM_L1_2_EN); |
|---|
| 565 | 505 | |
|---|
| 566 | 506 | rts5260_pwr_saving_setting(pcr); |
|---|
| .. | .. |
|---|
| 568 | 508 | if (option->ltr_en) { |
|---|
| 569 | 509 | u16 val; |
|---|
| 570 | 510 | |
|---|
| 571 | | - pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val); |
|---|
| 511 | + pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val); |
|---|
| 572 | 512 | if (val & PCI_EXP_DEVCTL2_LTR_EN) { |
|---|
| 573 | 513 | option->ltr_enabled = true; |
|---|
| 574 | 514 | option->ltr_active = true; |
|---|
| .. | .. |
|---|
| 611 | 551 | * to drive low, and we forcibly request clock. |
|---|
| 612 | 552 | */ |
|---|
| 613 | 553 | if (option->force_clkreq_0) |
|---|
| 614 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, |
|---|
| 554 | + rtsx_pci_write_register(pcr, PETXCFG, |
|---|
| 615 | 555 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); |
|---|
| 616 | 556 | else |
|---|
| 617 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, |
|---|
| 557 | + rtsx_pci_write_register(pcr, PETXCFG, |
|---|
| 618 | 558 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); |
|---|
| 619 | 559 | |
|---|
| 560 | + rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); |
|---|
| 561 | + |
|---|
| 620 | 562 | return 0; |
|---|
| 621 | | -} |
|---|
| 622 | | - |
|---|
| 623 | | -static void rts5260_set_aspm(struct rtsx_pcr *pcr, bool enable) |
|---|
| 624 | | -{ |
|---|
| 625 | | - struct rtsx_cr_option *option = &pcr->option; |
|---|
| 626 | | - u8 val = 0; |
|---|
| 627 | | - |
|---|
| 628 | | - if (pcr->aspm_enabled == enable) |
|---|
| 629 | | - return; |
|---|
| 630 | | - |
|---|
| 631 | | - if (option->dev_aspm_mode == DEV_ASPM_DYNAMIC) { |
|---|
| 632 | | - if (enable) |
|---|
| 633 | | - val = pcr->aspm_en; |
|---|
| 634 | | - rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL, |
|---|
| 635 | | - ASPM_MASK_NEG, val); |
|---|
| 636 | | - } else if (option->dev_aspm_mode == DEV_ASPM_BACKDOOR) { |
|---|
| 637 | | - u8 mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0; |
|---|
| 638 | | - |
|---|
| 639 | | - if (!enable) |
|---|
| 640 | | - val = FORCE_ASPM_CTL0; |
|---|
| 641 | | - rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val); |
|---|
| 642 | | - } |
|---|
| 643 | | - |
|---|
| 644 | | - pcr->aspm_enabled = enable; |
|---|
| 645 | 563 | } |
|---|
| 646 | 564 | |
|---|
| 647 | 565 | static void rts5260_set_l1off_cfg_sub_d0(struct rtsx_pcr *pcr, int active) |
|---|
| .. | .. |
|---|
| 687 | 605 | .card_power_on = rts5260_card_power_on, |
|---|
| 688 | 606 | .card_power_off = rts5260_card_power_off, |
|---|
| 689 | 607 | .switch_output_voltage = rts5260_switch_output_voltage, |
|---|
| 690 | | - .force_power_down = rtsx_base_force_power_down, |
|---|
| 691 | 608 | .stop_cmd = rts5260_stop_cmd, |
|---|
| 692 | | - .set_aspm = rts5260_set_aspm, |
|---|
| 693 | 609 | .set_l1off_cfg_sub_d0 = rts5260_set_l1off_cfg_sub_d0, |
|---|
| 694 | 610 | .enable_ocp = rts5260_enable_ocp, |
|---|
| 695 | 611 | .disable_ocp = rts5260_disable_ocp, |
|---|
| .. | .. |
|---|
| 733 | 649 | option->ltr_active_latency = LTR_ACTIVE_LATENCY_DEF; |
|---|
| 734 | 650 | option->ltr_idle_latency = LTR_IDLE_LATENCY_DEF; |
|---|
| 735 | 651 | option->ltr_l1off_latency = LTR_L1OFF_LATENCY_DEF; |
|---|
| 736 | | - option->dev_aspm_mode = DEV_ASPM_DYNAMIC; |
|---|
| 737 | 652 | option->l1_snooze_delay = L1_SNOOZE_DELAY_DEF; |
|---|
| 738 | 653 | option->ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; |
|---|
| 739 | 654 | option->ltr_l1off_snooze_sspwrgate = |
|---|
| .. | .. |
|---|
| 742 | 657 | option->ocp_en = 1; |
|---|
| 743 | 658 | if (option->ocp_en) |
|---|
| 744 | 659 | hw_param->interrupt_en |= SD_OC_INT_EN; |
|---|
| 745 | | - hw_param->ocp_glitch = SD_OCP_GLITCH_10M | SDVIO_OCP_GLITCH_800U; |
|---|
| 660 | + hw_param->ocp_glitch = SD_OCP_GLITCH_100U | SDVIO_OCP_GLITCH_800U; |
|---|
| 746 | 661 | option->sd_400mA_ocp_thd = RTS5260_DVCC_OCP_THD_550; |
|---|
| 747 | 662 | option->sd_800mA_ocp_thd = RTS5260_DVCC_OCP_THD_970; |
|---|
| 748 | 663 | } |
|---|