static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) { struct rtsx_cr_option *option = &pcr->option; /* Set mcu_cnt to 7 to ensure data can be sampled properly */ rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07); rtsx_pci_write_register(pcr, SSC_DIV_N_0, 0xFF, 0x5D); rts5260_init_from_cfg(pcr); /* force no MDIO*/ rtsx_pci_write_register(pcr, RTS5260_AUTOLOAD_CFG4, 0xFF, RTS5260_MIMO_DISABLE); /*Modify SDVCC Tune Default Parameters!*/ rtsx_pci_write_register(pcr, LDO_VCC_CFG0, RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33); rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL); rts5260_init_hw(pcr); /* * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced * to drive low, and we forcibly request clock. */ if (option->force_clkreq_0) rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); else rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); return 0; }
static void rts5260_init_ocp(struct rtsx_pcr *pcr) { struct rtsx_cr_option *option = &pcr->option; if (option->ocp_en) { u8 mask, val; rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, RTS5260_DVCC_OCP_THD_MASK, option->sd_800mA_ocp_thd); rtsx_pci_write_register(pcr, RTS5260_DV331812_CFG, RTS5260_DV331812_OCP_THD_MASK, RTS5260_DV331812_OCP_THD_270); mask = SD_OCP_GLITCH_MASK; val = pcr->hw_param.ocp_glitch; rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, val); rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, RTS5260_DVCC_OCP_EN | RTS5260_DVCC_OCP_CL_EN, RTS5260_DVCC_OCP_EN | RTS5260_DVCC_OCP_CL_EN); rtsx_pci_enable_ocp(pcr); } else { rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL, RTS5260_DVCC_OCP_EN | RTS5260_DVCC_OCP_CL_EN, 0); } }
static int rts524a_extra_init_hw(struct rtsx_pcr *pcr) { rts5249_extra_init_hw(pcr); rtsx_pci_write_register(pcr, FUNC_FORCE_CTL, FORCE_ASPM_L1_EN, FORCE_ASPM_L1_EN); rtsx_pci_write_register(pcr, PM_EVENT_DEBUG, PME_DEBUG_0, PME_DEBUG_0); rtsx_pci_write_register(pcr, LDO_VCC_CFG1, LDO_VCC_LMT_EN, LDO_VCC_LMT_EN); rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL); if (is_version(pcr, 0x524A, IC_VER_A)) { rtsx_pci_write_register(pcr, LDO_DV18_CFG, LDO_DV18_SR_MASK, LDO_DV18_SR_DF); rtsx_pci_write_register(pcr, LDO_VCC_CFG1, LDO_VCC_REF_TUNE_MASK, LDO_VCC_REF_1V2); rtsx_pci_write_register(pcr, LDO_VIO_CFG, LDO_VIO_REF_TUNE_MASK, LDO_VIO_REF_1V2); rtsx_pci_write_register(pcr, LDO_VIO_CFG, LDO_VIO_SR_MASK, LDO_VIO_SR_DF); rtsx_pci_write_register(pcr, LDO_DV12S_CFG, LDO_REF12_TUNE_MASK, LDO_REF12_TUNE_DF); rtsx_pci_write_register(pcr, SD40_LDO_CTL1, SD40_VIO_TUNE_MASK, SD40_VIO_TUNE_1V7); } return 0; }
static int rtl8411_do_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage, int bpp_tuned18_shift, int bpp_asic_1v8) { u8 mask, val; int err; mask = (BPP_REG_TUNED18 << bpp_tuned18_shift) | BPP_PAD_MASK; if (voltage == OUTPUT_3V3) { err = rtsx_pci_write_register(pcr, SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3); if (err < 0) return err; val = (BPP_ASIC_3V3 << bpp_tuned18_shift) | BPP_PAD_3V3; } else if (voltage == OUTPUT_1V8) { err = rtsx_pci_write_register(pcr, SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8); if (err < 0) return err; val = (bpp_asic_1v8 << bpp_tuned18_shift) | BPP_PAD_1V8; } else { return -EINVAL; } return rtsx_pci_write_register(pcr, LDO_CTL, mask, val); }
static void rtsx_pci_ms_handle_req(struct work_struct *work) { struct realtek_pci_ms *host = container_of(work, struct realtek_pci_ms, handle_req); struct rtsx_pcr *pcr = host->pcr; struct memstick_host *msh = host->msh; int rc; mutex_lock(&pcr->pcr_mutex); rtsx_pci_start_run(pcr); rtsx_pci_switch_clock(host->pcr, host->clock, host->ssc_depth, false, true, false); rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, MS_MOD_SEL); rtsx_pci_write_register(pcr, CARD_SHARE_MODE, CARD_SHARE_MASK, CARD_SHARE_48_MS); if (!host->req) { do { rc = memstick_next_req(msh, &host->req); dev_dbg(ms_dev(host), "next req %d\n", rc); if (!rc) host->req->error = rtsx_pci_ms_issue_cmd(host); } while (!rc); } mutex_unlock(&pcr->pcr_mutex); }
static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) { int err; if (voltage == OUTPUT_3V3) { err = rtsx_pci_write_register(pcr, SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3); if (err < 0) return err; err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); if (err < 0) return err; } else if (voltage == OUTPUT_1V8) { err = rtsx_pci_write_register(pcr, SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8); if (err < 0) return err; err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); if (err < 0) return err; } else { return -EINVAL; } return 0; }
static int rtsx_pci_ms_set_param(struct memstick_host *msh, enum memstick_param param, int value) { struct realtek_pci_ms *host = memstick_priv(msh); struct rtsx_pcr *pcr = host->pcr; unsigned int clock = 0; u8 ssc_depth = 0; int err; dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n", __func__, param, value); err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_MS_CARD); if (err) return err; switch (param) { case MEMSTICK_POWER: if (value == MEMSTICK_POWER_ON) err = ms_power_on(host); else if (value == MEMSTICK_POWER_OFF) err = ms_power_off(host); else return -EINVAL; break; case MEMSTICK_INTERFACE: if (value == MEMSTICK_SERIAL) { clock = 19000000; ssc_depth = RTSX_SSC_DEPTH_500K; err = rtsx_pci_write_register(pcr, MS_CFG, 0x18, MS_BUS_WIDTH_1); if (err < 0) return err; } else if (value == MEMSTICK_PAR4) { clock = 39000000; ssc_depth = RTSX_SSC_DEPTH_1M; err = rtsx_pci_write_register(pcr, MS_CFG, 0x58, MS_BUS_WIDTH_4 | PUSH_TIME_ODD); if (err < 0) return err; } else { return -EINVAL; } err = rtsx_pci_switch_clock(pcr, clock, ssc_depth, false, true, false); if (err < 0) return err; host->ssc_depth = ssc_depth; host->clock = clock; host->ifmode = value; break; } return 0; }
void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr) { rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD); rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA); rtsx_pci_write_register(pcr, DMACTL, 0x80, 0x80); rtsx_pci_write_register(pcr, RBCTL, 0x80, 0x80); }
static void rts5260_stop_cmd(struct rtsx_pcr *pcr) { rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD); rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA); rtsx_pci_write_register(pcr, RTS5260_DMA_RST_CTL_0, RTS5260_DMA_RST | RTS5260_ADMA3_RST, RTS5260_DMA_RST | RTS5260_ADMA3_RST); rtsx_pci_write_register(pcr, RBCTL, RB_FLUSH, RB_FLUSH); }
static int sd_set_sample_push_timing_sd30(struct rtsx_pcr *pcr) { rtsx_pci_write_register(pcr, SD_CFG1, SD_MODE_SELECT_MASK | SD_ASYNC_FIFO_NOT_RST, SD_30_MODE | SD_ASYNC_FIFO_NOT_RST); rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); rtsx_pci_write_register(pcr, CARD_CLK_SOURCE, 0xFF, CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0); return 0; }
static void rts5249_force_power_down(struct rtsx_pcr *pcr, u8 pm_state) { /* Set relink_time to 0 */ rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0); rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, 0xFF, 0); rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0); if (pm_state == HOST_ENTER_S3) rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10); rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03); }
static int rtl8411_card_power_off(struct rtsx_pcr *pcr, int card) { int err; err = rtsx_pci_write_register(pcr, CARD_PWR_CTL, BPP_POWER_MASK, BPP_POWER_OFF); if (err < 0) return err; return rtsx_pci_write_register(pcr, LDO_CTL, BPP_LDO_POWB, BPP_LDO_SUSPEND); }
static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, u8 pm_state) { /* Set relink_time to 0 */ rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0); rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, 0xFF, 0); rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0); if (pm_state == HOST_ENTER_S3) rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, D3_DELINK_MODE_EN, D3_DELINK_MODE_EN); rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03); }
static int rts5260_card_power_off(struct rtsx_pcr *pcr, int card) { int err = 0; rts5260_card_before_power_off(pcr); err = rtsx_pci_write_register(pcr, LDO_VCC_CFG1, LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF); err = rtsx_pci_write_register(pcr, LDO_CONFIG2, DV331812_POWERON, DV331812_POWEROFF); if (pcr->option.ocp_en) rtsx_pci_disable_ocp(pcr); return err; }
static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, u8 pm_state) { /* Set relink_time to 0 */ rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, MASK_8_BIT_DEF, 0); rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, MASK_8_BIT_DEF, 0); rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, RELINK_TIME_MASK, 0); if (pm_state == HOST_ENTER_S3) rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, D3_DELINK_MODE_EN, D3_DELINK_MODE_EN); rtsx_pci_write_register(pcr, FPDCTL, ALL_POWER_DOWN, ALL_POWER_DOWN); }
static int rts525a_optimize_phy(struct rtsx_pcr *pcr) { int err; err = rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3, D3_DELINK_MODE_EN, 0x00); if (err < 0) return err; rtsx_pci_write_phy_register(pcr, _PHY_FLD0, _PHY_FLD0_CLK_REQ_20C | _PHY_FLD0_RX_IDLE_EN | _PHY_FLD0_BIT_ERR_RSTN | _PHY_FLD0_BER_COUNT | _PHY_FLD0_BER_TIMER | _PHY_FLD0_CHECK_EN); rtsx_pci_write_phy_register(pcr, _PHY_ANA03, _PHY_ANA03_TIMER_MAX | _PHY_ANA03_OOBS_DEB_EN | _PHY_CMU_DEBUG_EN); if (is_version(pcr, 0x525A, IC_VER_A)) rtsx_pci_write_phy_register(pcr, _PHY_REV0, _PHY_REV0_FILTER_OUT | _PHY_REV0_CDR_BYPASS_PFD | _PHY_REV0_CDR_RX_IDLE_BYPASS); return 0; }
static int ms_power_on(struct realtek_pci_ms *host) { struct rtsx_pcr *pcr = host->pcr; int err; rtsx_pci_init_cmd(pcr); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SELECT, 0x07, MS_MOD_SEL); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SHARE_MODE, CARD_SHARE_MASK, CARD_SHARE_48_MS); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, MS_CLK_EN, MS_CLK_EN); err = rtsx_pci_send_cmd(pcr, 100); if (err < 0) return err; err = rtsx_pci_card_pull_ctl_enable(pcr, RTSX_MS_CARD); if (err < 0) return err; err = rtsx_pci_card_power_on(pcr, RTSX_MS_CARD); if (err < 0) return err; /* Wait ms power stable */ msleep(150); err = rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, MS_OUTPUT_EN); if (err < 0) return err; return 0; }
static void rts5260_enable_ocp(struct rtsx_pcr *pcr) { u8 val = 0; val = SD_OCP_INT_EN | SD_DETECT_EN; rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val); }
static void rts5260_disable_ocp(struct rtsx_pcr *pcr) { u8 mask = 0; mask = SD_OCP_INT_EN | SD_DETECT_EN; rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0); }
static void rts5260_clear_ocpstat(struct rtsx_pcr *pcr) { u8 mask = 0; u8 val = 0; mask = SD_OCP_INT_CLR | SD_OC_CLR; val = SD_OCP_INT_CLR | SD_OC_CLR; rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val); rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL, DV3318_OCP_INT_CLR | DV3318_OCP_CLR, DV3318_OCP_INT_CLR | DV3318_OCP_CLR); udelay(10); rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0); rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL, DV3318_OCP_INT_CLR | DV3318_OCP_CLR, 0); }
static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr) { unsigned int card_exist; card_exist = rtsx_pci_readl(pcr, RTSX_BIPR); card_exist &= CARD_EXIST; if (!card_exist) { /* Enable card CD */ rtsx_pci_write_register(pcr, CD_PAD_CTL, CD_DISABLE_MASK, CD_ENABLE); /* Enable card interrupt */ rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x00); return 0; } if (hweight32(card_exist) > 1) { rtsx_pci_write_register(pcr, CARD_PWR_CTL, BPP_POWER_MASK, BPP_POWER_5_PERCENT_ON); msleep(100); card_exist = rtsx_pci_readl(pcr, RTSX_BIPR); if (card_exist & MS_EXIST) card_exist = MS_EXIST; else if (card_exist & SD_EXIST) card_exist = SD_EXIST; else card_exist = 0; rtsx_pci_write_register(pcr, CARD_PWR_CTL, BPP_POWER_MASK, BPP_POWER_OFF); dev_dbg(&(pcr->pci->dev), "After CD deglitch, card_exist = 0x%x\n", card_exist); } if (card_exist & MS_EXIST) { /* Disable SD interrupt */ rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x40); rtsx_pci_write_register(pcr, CD_PAD_CTL, CD_DISABLE_MASK, MS_CD_EN_ONLY); } else if (card_exist & SD_EXIST) { /* Disable MS interrupt */ rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x80); rtsx_pci_write_register(pcr, CD_PAD_CTL, CD_DISABLE_MASK, SD_CD_EN_ONLY); } return card_exist; }
static int rts5260_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) { switch (voltage) { case OUTPUT_3V3: rtsx_pci_write_register(pcr, LDO_CONFIG2, DV331812_VDD1, DV331812_VDD1); rtsx_pci_write_register(pcr, LDO_DV18_CFG, DV331812_MASK, DV331812_33); rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, 0); break; case OUTPUT_1V8: rtsx_pci_write_register(pcr, LDO_CONFIG2, DV331812_VDD1, DV331812_VDD1); rtsx_pci_write_register(pcr, LDO_DV18_CFG, DV331812_MASK, DV331812_17); rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, SD_IO_USING_1V8); break; default: return -EINVAL; } /* set pad drive */ rts5260_fill_driving(pcr, voltage); return 0; }
static int rts525a_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) { switch (voltage) { case OUTPUT_3V3: rtsx_pci_write_register(pcr, LDO_CONFIG2, LDO_D3318_MASK, LDO_D3318_33V); rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, 0); break; case OUTPUT_1V8: rtsx_pci_write_register(pcr, LDO_CONFIG2, LDO_D3318_MASK, LDO_D3318_18V); rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, SD_IO_USING_1V8); break; default: return -EINVAL; } rtsx_pci_init_cmd(pcr); rts5249_fill_driving(pcr, voltage); return rtsx_pci_send_cmd(pcr, 100); }
static int rtl8411_card_power_on(struct rtsx_pcr *pcr, int card) { int err; rtsx_pci_init_cmd(pcr); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, BPP_POWER_MASK, BPP_POWER_5_PERCENT_ON); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CTL, BPP_LDO_POWB, BPP_LDO_SUSPEND); err = rtsx_pci_send_cmd(pcr, 100); if (err < 0) return err; /* To avoid too large in-rush current */ udelay(150); err = rtsx_pci_write_register(pcr, CARD_PWR_CTL, BPP_POWER_MASK, BPP_POWER_10_PERCENT_ON); if (err < 0) return err; udelay(150); err = rtsx_pci_write_register(pcr, CARD_PWR_CTL, BPP_POWER_MASK, BPP_POWER_15_PERCENT_ON); if (err < 0) return err; udelay(150); err = rtsx_pci_write_register(pcr, CARD_PWR_CTL, BPP_POWER_MASK, BPP_POWER_ON); if (err < 0) return err; return rtsx_pci_write_register(pcr, LDO_CTL, BPP_LDO_POWB, BPP_LDO_ON); }
static void rts5260_fill_driving(struct rtsx_pcr *pcr, u8 voltage) { u8 driving_3v3[6][3] = { {0x94, 0x94, 0x94}, {0x11, 0x11, 0x18}, {0x55, 0x55, 0x5C}, {0x94, 0x94, 0x94}, {0x94, 0x94, 0x94}, {0xFF, 0xFF, 0xFF}, }; u8 driving_1v8[6][3] = { {0x9A, 0x89, 0x89}, {0xC4, 0xC4, 0xC4}, {0x3C, 0x3C, 0x3C}, {0x9B, 0x99, 0x99}, {0x9A, 0x89, 0x89}, {0xFE, 0xFE, 0xFE}, }; u8 (*driving)[3], drive_sel; if (voltage == OUTPUT_3V3) { driving = driving_3v3; drive_sel = pcr->sd30_drive_sel_3v3; } else { driving = driving_1v8; drive_sel = pcr->sd30_drive_sel_1v8; } rtsx_pci_write_register(pcr, SD30_CLK_DRIVE_SEL, 0xFF, driving[drive_sel][0]); rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL, 0xFF, driving[drive_sel][1]); rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL, 0xFF, driving[drive_sel][2]); }
static void rts5260_process_ocp(struct rtsx_pcr *pcr) { if (!pcr->option.ocp_en) return; rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat); rts5260_get_ocpstat2(pcr, &pcr->ocp_stat2); if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) || (pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) { rtsx_pci_card_power_off(pcr, RTSX_SD_CARD); rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0); rtsx_pci_clear_ocpstat(pcr); pcr->ocp_stat = 0; pcr->ocp_stat2 = 0; } }
static int rts524a_optimize_phy(struct rtsx_pcr *pcr) { int err; err = rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3, D3_DELINK_MODE_EN, 0x00); if (err < 0) return err; rtsx_pci_write_phy_register(pcr, PHY_PCR, PHY_PCR_FORCE_CODE | PHY_PCR_OOBS_CALI_50 | PHY_PCR_OOBS_VCM_08 | PHY_PCR_OOBS_SEN_90 | PHY_PCR_RSSI_EN); rtsx_pci_write_phy_register(pcr, PHY_SSCCR3, PHY_SSCCR3_STEP_IN | PHY_SSCCR3_CHECK_DELAY); if (is_version(pcr, 0x524A, IC_VER_A)) { rtsx_pci_write_phy_register(pcr, PHY_SSCCR3, PHY_SSCCR3_STEP_IN | PHY_SSCCR3_CHECK_DELAY); rtsx_pci_write_phy_register(pcr, PHY_SSCCR2, PHY_SSCCR2_PLL_NCODE | PHY_SSCCR2_TIME0 | PHY_SSCCR2_TIME2_WIDTH); rtsx_pci_write_phy_register(pcr, PHY_ANA1A, PHY_ANA1A_TXR_LOOPBACK | PHY_ANA1A_RXT_BIST | PHY_ANA1A_TXR_BIST | PHY_ANA1A_REV); rtsx_pci_write_phy_register(pcr, PHY_ANA1D, PHY_ANA1D_DEBUG_ADDR); rtsx_pci_write_phy_register(pcr, PHY_DIG1E, PHY_DIG1E_REV | PHY_DIG1E_D0_X_D1 | PHY_DIG1E_RX_ON_HOST | PHY_DIG1E_RCLK_REF_HOST | PHY_DIG1E_RCLK_TX_EN_KEEP | PHY_DIG1E_RCLK_TX_TERM_KEEP | PHY_DIG1E_RCLK_RX_EIDLE_ON | PHY_DIG1E_TX_TERM_KEEP | PHY_DIG1E_RX_TERM_KEEP | PHY_DIG1E_TX_EN_KEEP | PHY_DIG1E_RX_EN_KEEP); } rtsx_pci_write_phy_register(pcr, PHY_ANA08, PHY_ANA08_RX_EQ_DCGAIN | PHY_ANA08_SEL_RX_EN | PHY_ANA08_RX_EQ_VAL | PHY_ANA08_SCP | PHY_ANA08_SEL_IPI); return 0; }
static int rts525a_extra_init_hw(struct rtsx_pcr *pcr) { rts5249_extra_init_hw(pcr); rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL); if (is_version(pcr, 0x525A, IC_VER_A)) { rtsx_pci_write_register(pcr, L1SUB_CONFIG2, L1SUB_AUTO_CFG, L1SUB_AUTO_CFG); rtsx_pci_write_register(pcr, RREF_CFG, RREF_VBGSEL_MASK, RREF_VBGSEL_1V25); rtsx_pci_write_register(pcr, LDO_VIO_CFG, LDO_VIO_TUNE_MASK, LDO_VIO_1V7); rtsx_pci_write_register(pcr, LDO_DV12S_CFG, LDO_D12_TUNE_MASK, LDO_D12_TUNE_DF); rtsx_pci_write_register(pcr, LDO_AV12S_CFG, LDO_AV12S_TUNE_MASK, LDO_AV12S_TUNE_DF); rtsx_pci_write_register(pcr, LDO_VCC_CFG0, LDO_VCC_LMTVTH_MASK, LDO_VCC_LMTVTH_2A); rtsx_pci_write_register(pcr, OOBS_CONFIG, OOBS_AUTOK_DIS | OOBS_VAL_MASK, 0x89); } return 0; }
static void rts5260_set_aspm(struct rtsx_pcr *pcr, bool enable) { struct rtsx_cr_option *option = &pcr->option; u8 val = 0; if (pcr->aspm_enabled == enable) return; if (option->dev_aspm_mode == DEV_ASPM_DYNAMIC) { if (enable) val = pcr->aspm_en; rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL, ASPM_MASK_NEG, val); } else if (option->dev_aspm_mode == DEV_ASPM_BACKDOOR) { u8 mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0; if (!enable) val = FORCE_ASPM_CTL0; rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val); } pcr->aspm_enabled = enable; }
static void sd_request(struct work_struct *work) { struct realtek_pci_sdmmc *host = container_of(work, struct realtek_pci_sdmmc, work); struct rtsx_pcr *pcr = host->pcr; struct mmc_host *mmc = host->mmc; struct mmc_request *mrq = host->mrq; struct mmc_command *cmd = mrq->cmd; struct mmc_data *data = mrq->data; unsigned int data_size = 0; int err; if (host->eject) { cmd->error = -ENOMEDIUM; goto finish; } err = rtsx_pci_card_exclusive_check(host->pcr, RTSX_SD_CARD); if (err) { cmd->error = err; goto finish; } mutex_lock(&pcr->pcr_mutex); rtsx_pci_start_run(pcr); rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth, host->initial_mode, host->double_clk, host->vpclk); rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, SD_MOD_SEL); rtsx_pci_write_register(pcr, CARD_SHARE_MODE, CARD_SHARE_MASK, CARD_SHARE_48_SD); mutex_lock(&host->host_mutex); host->mrq = mrq; mutex_unlock(&host->host_mutex); if (mrq->data) data_size = data->blocks * data->blksz; if (!data_size || sd_rw_cmd(cmd)) { sd_send_cmd_get_rsp(host, cmd); if (!cmd->error && data_size) { sd_rw_multi(host, mrq); if (!host->using_cookie) sdmmc_post_req(host->mmc, host->mrq, 0); if (mmc_op_multi(cmd->opcode) && mrq->stop) sd_send_cmd_get_rsp(host, mrq->stop); } } else { sd_normal_rw(host, mrq); } if (mrq->data) { if (cmd->error || data->error) data->bytes_xfered = 0; else data->bytes_xfered = data->blocks * data->blksz; } mutex_unlock(&pcr->pcr_mutex); finish: if (cmd->error) dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error); mutex_lock(&host->host_mutex); host->mrq = NULL; mutex_unlock(&host->host_mutex); mmc_request_done(mmc, mrq); }