linux/drivers/mfd/rts5249.c
<<
>>
Prefs
   1/* Driver for Realtek PCI-Express card reader
   2 *
   3 * Copyright(c) 2009-2013 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 *
  18 * Author:
  19 *   Wei WANG <wei_wang@realsil.com.cn>
  20 */
  21
  22#include <linux/module.h>
  23#include <linux/delay.h>
  24#include <linux/mfd/rtsx_pci.h>
  25
  26#include "rtsx_pcr.h"
  27
  28static u8 rts5249_get_ic_version(struct rtsx_pcr *pcr)
  29{
  30        u8 val;
  31
  32        rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val);
  33        return val & 0x0F;
  34}
  35
  36static void rts5249_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
  37{
  38        u8 driving_3v3[4][3] = {
  39                {0x11, 0x11, 0x18},
  40                {0x55, 0x55, 0x5C},
  41                {0xFF, 0xFF, 0xFF},
  42                {0x96, 0x96, 0x96},
  43        };
  44        u8 driving_1v8[4][3] = {
  45                {0xC4, 0xC4, 0xC4},
  46                {0x3C, 0x3C, 0x3C},
  47                {0xFE, 0xFE, 0xFE},
  48                {0xB3, 0xB3, 0xB3},
  49        };
  50        u8 (*driving)[3], drive_sel;
  51
  52        if (voltage == OUTPUT_3V3) {
  53                driving = driving_3v3;
  54                drive_sel = pcr->sd30_drive_sel_3v3;
  55        } else {
  56                driving = driving_1v8;
  57                drive_sel = pcr->sd30_drive_sel_1v8;
  58        }
  59
  60        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
  61                        0xFF, driving[drive_sel][0]);
  62        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
  63                        0xFF, driving[drive_sel][1]);
  64        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
  65                        0xFF, driving[drive_sel][2]);
  66}
  67
  68static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr)
  69{
  70        u32 reg;
  71
  72        rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg);
  73        pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
  74
  75        if (!rtsx_vendor_setting_valid(reg)) {
  76                pcr_dbg(pcr, "skip fetch vendor setting\n");
  77                return;
  78        }
  79
  80        pcr->aspm_en = rtsx_reg_to_aspm(reg);
  81        pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
  82        pcr->card_drive_sel &= 0x3F;
  83        pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
  84
  85        rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, &reg);
  86        pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
  87        pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
  88        if (rtsx_reg_check_reverse_socket(reg))
  89                pcr->flags |= PCR_REVERSE_SOCKET;
  90}
  91
  92static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
  93{
  94        /* Set relink_time to 0 */
  95        rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0);
  96        rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, 0xFF, 0);
  97        rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
  98
  99        if (pm_state == HOST_ENTER_S3)
 100                rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3,
 101                        D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);
 102
 103        rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
 104}
 105
 106static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
 107{
 108        rtsx_pci_init_cmd(pcr);
 109
 110        /* Rest L1SUB Config */
 111        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG3, 0xFF, 0x00);
 112        /* Configure GPIO as output */
 113        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
 114        /* Reset ASPM state to default value */
 115        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
 116        /* Switch LDO3318 source from DV33 to card_3v3 */
 117        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
 118        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
 119        /* LED shine disabled, set initial shine cycle period */
 120        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
 121        /* Configure driving */
 122        rts5249_fill_driving(pcr, OUTPUT_3V3);
 123        if (pcr->flags & PCR_REVERSE_SOCKET)
 124                rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0xB0);
 125        else
 126                rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
 127
 128        return rtsx_pci_send_cmd(pcr, 100);
 129}
 130
 131static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
 132{
 133        int err;
 134
 135        err = rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
 136        if (err < 0)
 137                return err;
 138
 139        err = rtsx_pci_write_phy_register(pcr, PHY_REV,
 140                        PHY_REV_RESV | PHY_REV_RXIDLE_LATCHED |
 141                        PHY_REV_P1_EN | PHY_REV_RXIDLE_EN |
 142                        PHY_REV_CLKREQ_TX_EN | PHY_REV_RX_PWST |
 143                        PHY_REV_CLKREQ_DT_1_0 | PHY_REV_STOP_CLKRD |
 144                        PHY_REV_STOP_CLKWR);
 145        if (err < 0)
 146                return err;
 147
 148        msleep(1);
 149
 150        err = rtsx_pci_write_phy_register(pcr, PHY_BPCR,
 151                        PHY_BPCR_IBRXSEL | PHY_BPCR_IBTXSEL |
 152                        PHY_BPCR_IB_FILTER | PHY_BPCR_CMIRROR_EN);
 153        if (err < 0)
 154                return err;
 155
 156        err = rtsx_pci_write_phy_register(pcr, PHY_PCR,
 157                        PHY_PCR_FORCE_CODE | PHY_PCR_OOBS_CALI_50 |
 158                        PHY_PCR_OOBS_VCM_08 | PHY_PCR_OOBS_SEN_90 |
 159                        PHY_PCR_RSSI_EN | PHY_PCR_RX10K);
 160        if (err < 0)
 161                return err;
 162
 163        err = rtsx_pci_write_phy_register(pcr, PHY_RCR2,
 164                        PHY_RCR2_EMPHASE_EN | PHY_RCR2_NADJR |
 165                        PHY_RCR2_CDR_SR_2 | PHY_RCR2_FREQSEL_12 |
 166                        PHY_RCR2_CDR_SC_12P | PHY_RCR2_CALIB_LATE);
 167        if (err < 0)
 168                return err;
 169
 170        err = rtsx_pci_write_phy_register(pcr, PHY_FLD4,
 171                        PHY_FLD4_FLDEN_SEL | PHY_FLD4_REQ_REF |
 172                        PHY_FLD4_RXAMP_OFF | PHY_FLD4_REQ_ADDA |
 173                        PHY_FLD4_BER_COUNT | PHY_FLD4_BER_TIMER |
 174                        PHY_FLD4_BER_CHK_EN);
 175        if (err < 0)
 176                return err;
 177        err = rtsx_pci_write_phy_register(pcr, PHY_RDR,
 178                        PHY_RDR_RXDSEL_1_9 | PHY_SSC_AUTO_PWD);
 179        if (err < 0)
 180                return err;
 181        err = rtsx_pci_write_phy_register(pcr, PHY_RCR1,
 182                        PHY_RCR1_ADP_TIME_4 | PHY_RCR1_VCO_COARSE);
 183        if (err < 0)
 184                return err;
 185        err = rtsx_pci_write_phy_register(pcr, PHY_FLD3,
 186                        PHY_FLD3_TIMER_4 | PHY_FLD3_TIMER_6 |
 187                        PHY_FLD3_RXDELINK);
 188        if (err < 0)
 189                return err;
 190
 191        return rtsx_pci_write_phy_register(pcr, PHY_TUNE,
 192                        PHY_TUNE_TUNEREF_1_0 | PHY_TUNE_VBGSEL_1252 |
 193                        PHY_TUNE_SDBUS_33 | PHY_TUNE_TUNED18 |
 194                        PHY_TUNE_TUNED12 | PHY_TUNE_TUNEA12);
 195}
 196
 197static int rtsx_base_turn_on_led(struct rtsx_pcr *pcr)
 198{
 199        return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02);
 200}
 201
 202static int rtsx_base_turn_off_led(struct rtsx_pcr *pcr)
 203{
 204        return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00);
 205}
 206
 207static int rtsx_base_enable_auto_blink(struct rtsx_pcr *pcr)
 208{
 209        return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08);
 210}
 211
 212static int rtsx_base_disable_auto_blink(struct rtsx_pcr *pcr)
 213{
 214        return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00);
 215}
 216
 217static int rtsx_base_card_power_on(struct rtsx_pcr *pcr, int card)
 218{
 219        int err;
 220
 221        rtsx_pci_init_cmd(pcr);
 222        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
 223                        SD_POWER_MASK, SD_VCC_PARTIAL_POWER_ON);
 224        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
 225                        LDO3318_PWR_MASK, 0x02);
 226        err = rtsx_pci_send_cmd(pcr, 100);
 227        if (err < 0)
 228                return err;
 229
 230        msleep(5);
 231
 232        rtsx_pci_init_cmd(pcr);
 233        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
 234                        SD_POWER_MASK, SD_VCC_POWER_ON);
 235        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
 236                        LDO3318_PWR_MASK, 0x06);
 237        err = rtsx_pci_send_cmd(pcr, 100);
 238        if (err < 0)
 239                return err;
 240
 241        return 0;
 242}
 243
 244static int rtsx_base_card_power_off(struct rtsx_pcr *pcr, int card)
 245{
 246        rtsx_pci_init_cmd(pcr);
 247        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
 248                        SD_POWER_MASK, SD_POWER_OFF);
 249        rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
 250                        LDO3318_PWR_MASK, 0x00);
 251        return rtsx_pci_send_cmd(pcr, 100);
 252}
 253
 254static int rtsx_base_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 255{
 256        int err;
 257        u16 append;
 258
 259        switch (voltage) {
 260        case OUTPUT_3V3:
 261                err = rtsx_pci_update_phy(pcr, PHY_TUNE, PHY_TUNE_VOLTAGE_MASK,
 262                        PHY_TUNE_VOLTAGE_3V3);
 263                if (err < 0)
 264                        return err;
 265                break;
 266        case OUTPUT_1V8:
 267                append = PHY_TUNE_D18_1V8;
 268                if (CHK_PCI_PID(pcr, 0x5249)) {
 269                        err = rtsx_pci_update_phy(pcr, PHY_BACR,
 270                                PHY_BACR_BASIC_MASK, 0);
 271                        if (err < 0)
 272                                return err;
 273                        append = PHY_TUNE_D18_1V7;
 274                }
 275
 276                err = rtsx_pci_update_phy(pcr, PHY_TUNE, PHY_TUNE_VOLTAGE_MASK,
 277                        append);
 278                if (err < 0)
 279                        return err;
 280                break;
 281        default:
 282                pcr_dbg(pcr, "unknown output voltage %d\n", voltage);
 283                return -EINVAL;
 284        }
 285
 286        /* set pad drive */
 287        rtsx_pci_init_cmd(pcr);
 288        rts5249_fill_driving(pcr, voltage);
 289        return rtsx_pci_send_cmd(pcr, 100);
 290}
 291
 292static const struct pcr_ops rts5249_pcr_ops = {
 293        .fetch_vendor_settings = rtsx_base_fetch_vendor_settings,
 294        .extra_init_hw = rts5249_extra_init_hw,
 295        .optimize_phy = rts5249_optimize_phy,
 296        .turn_on_led = rtsx_base_turn_on_led,
 297        .turn_off_led = rtsx_base_turn_off_led,
 298        .enable_auto_blink = rtsx_base_enable_auto_blink,
 299        .disable_auto_blink = rtsx_base_disable_auto_blink,
 300        .card_power_on = rtsx_base_card_power_on,
 301        .card_power_off = rtsx_base_card_power_off,
 302        .switch_output_voltage = rtsx_base_switch_output_voltage,
 303        .force_power_down = rtsx_base_force_power_down,
 304};
 305
 306/* SD Pull Control Enable:
 307 *     SD_DAT[3:0] ==> pull up
 308 *     SD_CD       ==> pull up
 309 *     SD_WP       ==> pull up
 310 *     SD_CMD      ==> pull up
 311 *     SD_CLK      ==> pull down
 312 */
 313static const u32 rts5249_sd_pull_ctl_enable_tbl[] = {
 314        RTSX_REG_PAIR(CARD_PULL_CTL1, 0x66),
 315        RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
 316        RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9),
 317        RTSX_REG_PAIR(CARD_PULL_CTL4, 0xAA),
 318        0,
 319};
 320
 321/* SD Pull Control Disable:
 322 *     SD_DAT[3:0] ==> pull down
 323 *     SD_CD       ==> pull up
 324 *     SD_WP       ==> pull down
 325 *     SD_CMD      ==> pull down
 326 *     SD_CLK      ==> pull down
 327 */
 328static const u32 rts5249_sd_pull_ctl_disable_tbl[] = {
 329        RTSX_REG_PAIR(CARD_PULL_CTL1, 0x66),
 330        RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
 331        RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5),
 332        RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
 333        0,
 334};
 335
 336/* MS Pull Control Enable:
 337 *     MS CD       ==> pull up
 338 *     others      ==> pull down
 339 */
 340static const u32 rts5249_ms_pull_ctl_enable_tbl[] = {
 341        RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
 342        RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
 343        RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
 344        0,
 345};
 346
 347/* MS Pull Control Disable:
 348 *     MS CD       ==> pull up
 349 *     others      ==> pull down
 350 */
 351static const u32 rts5249_ms_pull_ctl_disable_tbl[] = {
 352        RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
 353        RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
 354        RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
 355        0,
 356};
 357
 358void rts5249_init_params(struct rtsx_pcr *pcr)
 359{
 360        pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
 361        pcr->num_slots = 2;
 362        pcr->ops = &rts5249_pcr_ops;
 363
 364        pcr->flags = 0;
 365        pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
 366        pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B;
 367        pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
 368        pcr->aspm_en = ASPM_L1_EN;
 369        pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16);
 370        pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5);
 371
 372        pcr->ic_version = rts5249_get_ic_version(pcr);
 373        pcr->sd_pull_ctl_enable_tbl = rts5249_sd_pull_ctl_enable_tbl;
 374        pcr->sd_pull_ctl_disable_tbl = rts5249_sd_pull_ctl_disable_tbl;
 375        pcr->ms_pull_ctl_enable_tbl = rts5249_ms_pull_ctl_enable_tbl;
 376        pcr->ms_pull_ctl_disable_tbl = rts5249_ms_pull_ctl_disable_tbl;
 377
 378        pcr->reg_pm_ctrl3 = PM_CTRL3;
 379}
 380
 381static int rts524a_write_phy(struct rtsx_pcr *pcr, u8 addr, u16 val)
 382{
 383        addr = addr & 0x80 ? (addr & 0x7F) | 0x40 : addr;
 384
 385        return __rtsx_pci_write_phy_register(pcr, addr, val);
 386}
 387
 388static int rts524a_read_phy(struct rtsx_pcr *pcr, u8 addr, u16 *val)
 389{
 390        addr = addr & 0x80 ? (addr & 0x7F) | 0x40 : addr;
 391
 392        return __rtsx_pci_read_phy_register(pcr, addr, val);
 393}
 394
 395static int rts524a_optimize_phy(struct rtsx_pcr *pcr)
 396{
 397        int err;
 398
 399        err = rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
 400                D3_DELINK_MODE_EN, 0x00);
 401        if (err < 0)
 402                return err;
 403
 404        rtsx_pci_write_phy_register(pcr, PHY_PCR,
 405                PHY_PCR_FORCE_CODE | PHY_PCR_OOBS_CALI_50 |
 406                PHY_PCR_OOBS_VCM_08 | PHY_PCR_OOBS_SEN_90 | PHY_PCR_RSSI_EN);
 407        rtsx_pci_write_phy_register(pcr, PHY_SSCCR3,
 408                PHY_SSCCR3_STEP_IN | PHY_SSCCR3_CHECK_DELAY);
 409
 410        if (is_version(pcr, 0x524A, IC_VER_A)) {
 411                rtsx_pci_write_phy_register(pcr, PHY_SSCCR3,
 412                        PHY_SSCCR3_STEP_IN | PHY_SSCCR3_CHECK_DELAY);
 413                rtsx_pci_write_phy_register(pcr, PHY_SSCCR2,
 414                        PHY_SSCCR2_PLL_NCODE | PHY_SSCCR2_TIME0 |
 415                        PHY_SSCCR2_TIME2_WIDTH);
 416                rtsx_pci_write_phy_register(pcr, PHY_ANA1A,
 417                        PHY_ANA1A_TXR_LOOPBACK | PHY_ANA1A_RXT_BIST |
 418                        PHY_ANA1A_TXR_BIST | PHY_ANA1A_REV);
 419                rtsx_pci_write_phy_register(pcr, PHY_ANA1D,
 420                        PHY_ANA1D_DEBUG_ADDR);
 421                rtsx_pci_write_phy_register(pcr, PHY_DIG1E,
 422                        PHY_DIG1E_REV | PHY_DIG1E_D0_X_D1 |
 423                        PHY_DIG1E_RX_ON_HOST | PHY_DIG1E_RCLK_REF_HOST |
 424                        PHY_DIG1E_RCLK_TX_EN_KEEP |
 425                        PHY_DIG1E_RCLK_TX_TERM_KEEP |
 426                        PHY_DIG1E_RCLK_RX_EIDLE_ON | PHY_DIG1E_TX_TERM_KEEP |
 427                        PHY_DIG1E_RX_TERM_KEEP | PHY_DIG1E_TX_EN_KEEP |
 428                        PHY_DIG1E_RX_EN_KEEP);
 429        }
 430
 431        rtsx_pci_write_phy_register(pcr, PHY_ANA08,
 432                PHY_ANA08_RX_EQ_DCGAIN | PHY_ANA08_SEL_RX_EN |
 433                PHY_ANA08_RX_EQ_VAL | PHY_ANA08_SCP | PHY_ANA08_SEL_IPI);
 434
 435        return 0;
 436}
 437
 438static int rts524a_extra_init_hw(struct rtsx_pcr *pcr)
 439{
 440        rts5249_extra_init_hw(pcr);
 441
 442        rtsx_pci_write_register(pcr, FUNC_FORCE_CTL,
 443                FORCE_ASPM_L1_EN, FORCE_ASPM_L1_EN);
 444        rtsx_pci_write_register(pcr, PM_EVENT_DEBUG, PME_DEBUG_0, PME_DEBUG_0);
 445        rtsx_pci_write_register(pcr, LDO_VCC_CFG1, LDO_VCC_LMT_EN,
 446                LDO_VCC_LMT_EN);
 447        rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL);
 448        if (is_version(pcr, 0x524A, IC_VER_A)) {
 449                rtsx_pci_write_register(pcr, LDO_DV18_CFG,
 450                        LDO_DV18_SR_MASK, LDO_DV18_SR_DF);
 451                rtsx_pci_write_register(pcr, LDO_VCC_CFG1,
 452                        LDO_VCC_REF_TUNE_MASK, LDO_VCC_REF_1V2);
 453                rtsx_pci_write_register(pcr, LDO_VIO_CFG,
 454                        LDO_VIO_REF_TUNE_MASK, LDO_VIO_REF_1V2);
 455                rtsx_pci_write_register(pcr, LDO_VIO_CFG,
 456                        LDO_VIO_SR_MASK, LDO_VIO_SR_DF);
 457                rtsx_pci_write_register(pcr, LDO_DV12S_CFG,
 458                        LDO_REF12_TUNE_MASK, LDO_REF12_TUNE_DF);
 459                rtsx_pci_write_register(pcr, SD40_LDO_CTL1,
 460                        SD40_VIO_TUNE_MASK, SD40_VIO_TUNE_1V7);
 461        }
 462
 463        return 0;
 464}
 465
 466static const struct pcr_ops rts524a_pcr_ops = {
 467        .write_phy = rts524a_write_phy,
 468        .read_phy = rts524a_read_phy,
 469        .fetch_vendor_settings = rtsx_base_fetch_vendor_settings,
 470        .extra_init_hw = rts524a_extra_init_hw,
 471        .optimize_phy = rts524a_optimize_phy,
 472        .turn_on_led = rtsx_base_turn_on_led,
 473        .turn_off_led = rtsx_base_turn_off_led,
 474        .enable_auto_blink = rtsx_base_enable_auto_blink,
 475        .disable_auto_blink = rtsx_base_disable_auto_blink,
 476        .card_power_on = rtsx_base_card_power_on,
 477        .card_power_off = rtsx_base_card_power_off,
 478        .switch_output_voltage = rtsx_base_switch_output_voltage,
 479        .force_power_down = rtsx_base_force_power_down,
 480};
 481
 482void rts524a_init_params(struct rtsx_pcr *pcr)
 483{
 484        rts5249_init_params(pcr);
 485
 486        pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
 487        pcr->ops = &rts524a_pcr_ops;
 488}
 489
 490static int rts525a_card_power_on(struct rtsx_pcr *pcr, int card)
 491{
 492        rtsx_pci_write_register(pcr, LDO_VCC_CFG1,
 493                LDO_VCC_TUNE_MASK, LDO_VCC_3V3);
 494        return rtsx_base_card_power_on(pcr, card);
 495}
 496
 497static int rts525a_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 498{
 499        switch (voltage) {
 500        case OUTPUT_3V3:
 501                rtsx_pci_write_register(pcr, LDO_CONFIG2,
 502                        LDO_D3318_MASK, LDO_D3318_33V);
 503                rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, 0);
 504                break;
 505        case OUTPUT_1V8:
 506                rtsx_pci_write_register(pcr, LDO_CONFIG2,
 507                        LDO_D3318_MASK, LDO_D3318_18V);
 508                rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8,
 509                        SD_IO_USING_1V8);
 510                break;
 511        default:
 512                return -EINVAL;
 513        }
 514
 515        rtsx_pci_init_cmd(pcr);
 516        rts5249_fill_driving(pcr, voltage);
 517        return rtsx_pci_send_cmd(pcr, 100);
 518}
 519
 520static int rts525a_optimize_phy(struct rtsx_pcr *pcr)
 521{
 522        int err;
 523
 524        err = rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
 525                D3_DELINK_MODE_EN, 0x00);
 526        if (err < 0)
 527                return err;
 528
 529        rtsx_pci_write_phy_register(pcr, _PHY_FLD0,
 530                _PHY_FLD0_CLK_REQ_20C | _PHY_FLD0_RX_IDLE_EN |
 531                _PHY_FLD0_BIT_ERR_RSTN | _PHY_FLD0_BER_COUNT |
 532                _PHY_FLD0_BER_TIMER | _PHY_FLD0_CHECK_EN);
 533
 534        rtsx_pci_write_phy_register(pcr, _PHY_ANA03,
 535                _PHY_ANA03_TIMER_MAX | _PHY_ANA03_OOBS_DEB_EN |
 536                _PHY_CMU_DEBUG_EN);
 537
 538        if (is_version(pcr, 0x525A, IC_VER_A))
 539                rtsx_pci_write_phy_register(pcr, _PHY_REV0,
 540                        _PHY_REV0_FILTER_OUT | _PHY_REV0_CDR_BYPASS_PFD |
 541                        _PHY_REV0_CDR_RX_IDLE_BYPASS);
 542
 543        return 0;
 544}
 545
 546static int rts525a_extra_init_hw(struct rtsx_pcr *pcr)
 547{
 548        rts5249_extra_init_hw(pcr);
 549
 550        rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL);
 551        if (is_version(pcr, 0x525A, IC_VER_A)) {
 552                rtsx_pci_write_register(pcr, L1SUB_CONFIG2,
 553                        L1SUB_AUTO_CFG, L1SUB_AUTO_CFG);
 554                rtsx_pci_write_register(pcr, RREF_CFG,
 555                        RREF_VBGSEL_MASK, RREF_VBGSEL_1V25);
 556                rtsx_pci_write_register(pcr, LDO_VIO_CFG,
 557                        LDO_VIO_TUNE_MASK, LDO_VIO_1V7);
 558                rtsx_pci_write_register(pcr, LDO_DV12S_CFG,
 559                        LDO_D12_TUNE_MASK, LDO_D12_TUNE_DF);
 560                rtsx_pci_write_register(pcr, LDO_AV12S_CFG,
 561                        LDO_AV12S_TUNE_MASK, LDO_AV12S_TUNE_DF);
 562                rtsx_pci_write_register(pcr, LDO_VCC_CFG0,
 563                        LDO_VCC_LMTVTH_MASK, LDO_VCC_LMTVTH_2A);
 564                rtsx_pci_write_register(pcr, OOBS_CONFIG,
 565                        OOBS_AUTOK_DIS | OOBS_VAL_MASK, 0x89);
 566        }
 567
 568        return 0;
 569}
 570
 571static const struct pcr_ops rts525a_pcr_ops = {
 572        .fetch_vendor_settings = rtsx_base_fetch_vendor_settings,
 573        .extra_init_hw = rts525a_extra_init_hw,
 574        .optimize_phy = rts525a_optimize_phy,
 575        .turn_on_led = rtsx_base_turn_on_led,
 576        .turn_off_led = rtsx_base_turn_off_led,
 577        .enable_auto_blink = rtsx_base_enable_auto_blink,
 578        .disable_auto_blink = rtsx_base_disable_auto_blink,
 579        .card_power_on = rts525a_card_power_on,
 580        .card_power_off = rtsx_base_card_power_off,
 581        .switch_output_voltage = rts525a_switch_output_voltage,
 582        .force_power_down = rtsx_base_force_power_down,
 583};
 584
 585void rts525a_init_params(struct rtsx_pcr *pcr)
 586{
 587        rts5249_init_params(pcr);
 588
 589        pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
 590        pcr->ops = &rts525a_pcr_ops;
 591}
 592
 593