int card_power_on(struct rtsx_chip *chip, u8 card) { int retval; u8 mask, val1, val2; if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) { mask = MS_POWER_MASK; val1 = MS_PARTIAL_POWER_ON; val2 = MS_POWER_ON; } else { mask = SD_POWER_MASK; val1 = SD_PARTIAL_POWER_ON; val2 = SD_POWER_ON; } rtsx_init_cmd(chip); rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val1); retval = rtsx_send_cmd(chip, 0, 100); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); udelay(chip->pmos_pwr_on_interval); rtsx_init_cmd(chip); rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val2); retval = rtsx_send_cmd(chip, 0, 100); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); return STATUS_SUCCESS; }
int card_power_off(struct rtsx_chip *chip, u8 card) { u8 mask, val; if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) { mask = MS_POWER_MASK; val = MS_POWER_OFF; } else { mask = SD_POWER_MASK; val = SD_POWER_OFF; } RTSX_WRITE_REG(chip, CARD_PWR_CTL, mask, val); return STATUS_SUCCESS; }
int card_power_off(struct rtsx_chip *chip, u8 card) { u8 mask, val; if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) { mask = MS_POWER_MASK; val = MS_POWER_OFF; } else { mask = SD_POWER_MASK; val = SD_POWER_OFF; } if (CHECK_PID(chip, 0x5209)) { mask |= PMOS_STRG_MASK; val |= PMOS_STRG_400mA; } RTSX_WRITE_REG(chip, CARD_PWR_CTL, mask, val); if (CHECK_PID(chip, 0x5209) && (card == SD_CARD)) { RTSX_WRITE_REG(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); } return STATUS_SUCCESS; }
void rtsx_init_cards(struct rtsx_chip *chip) { if (RTSX_TST_DELINK(chip) && (rtsx_get_stat(chip) != RTSX_STAT_SS)) { RTSX_DEBUGP("Reset chip in polling thread!\n"); rtsx_reset_chip(chip); RTSX_CLR_DELINK(chip); } #ifdef DISABLE_CARD_INT card_cd_debounce(chip, &(chip->need_reset), &(chip->need_release)); #endif if (chip->need_release) { if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { if (chip->int_reg & XD_EXIST) { clear_bit(SD_NR, &(chip->need_release)); clear_bit(MS_NR, &(chip->need_release)); } } if (!(chip->card_exist & SD_CARD) && !chip->sd_io) clear_bit(SD_NR, &(chip->need_release)); if (!(chip->card_exist & XD_CARD)) clear_bit(XD_NR, &(chip->need_release)); if (!(chip->card_exist & MS_CARD)) clear_bit(MS_NR, &(chip->need_release)); RTSX_DEBUGP("chip->need_release = 0x%x\n", (unsigned int)(chip->need_release)); #ifdef SUPPORT_OCP if (chip->need_release) { if (CHECK_PID(chip, 0x5209)) { u8 mask = 0, val = 0; if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { if (chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER)) { mask |= MS_OCP_INT_CLR | MS_OC_CLR; val |= MS_OCP_INT_CLR | MS_OC_CLR; } } if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { mask |= SD_OCP_INT_CLR | SD_OC_CLR; val |= SD_OCP_INT_CLR | SD_OC_CLR; } if (mask) rtsx_write_register(chip, OCPCTL, mask, val); } else { if (chip->ocp_stat & (CARD_OC_NOW | CARD_OC_EVER)) rtsx_write_register(chip, OCPCLR, CARD_OC_INT_CLR | CARD_OC_CLR, CARD_OC_INT_CLR | CARD_OC_CLR); } chip->ocp_stat = 0; } #endif if (chip->need_release) { rtsx_set_stat(chip, RTSX_STAT_RUN); rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); } if (chip->need_release & SD_CARD) { clear_bit(SD_NR, &(chip->need_release)); chip->card_exist &= ~SD_CARD; chip->card_ejected &= ~SD_CARD; chip->card_fail &= ~SD_CARD; CLR_BIT(chip->lun_mc, chip->card2lun[SD_CARD]); chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); release_sdio(chip); release_sd_card(chip); } if (chip->need_release & XD_CARD) { clear_bit(XD_NR, &(chip->need_release)); chip->card_exist &= ~XD_CARD; chip->card_ejected &= ~XD_CARD; chip->card_fail &= ~XD_CARD; CLR_BIT(chip->lun_mc, chip->card2lun[XD_CARD]); chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0; release_xd_card(chip); if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0xC0); } if (chip->need_release & MS_CARD) { clear_bit(MS_NR, &(chip->need_release)); chip->card_exist &= ~MS_CARD; chip->card_ejected &= ~MS_CARD; chip->card_fail &= ~MS_CARD; CLR_BIT(chip->lun_mc, chip->card2lun[MS_CARD]); chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; release_ms_card(chip); } RTSX_DEBUGP("chip->card_exist = 0x%x\n", chip->card_exist); if (!chip->card_exist) turn_off_led(chip, LED_GPIO); } if (chip->need_reset) { RTSX_DEBUGP("chip->need_reset = 0x%x\n", (unsigned int)(chip->need_reset)); rtsx_reset_cards(chip); } if (chip->need_reinit) { RTSX_DEBUGP("chip->need_reinit = 0x%x\n", (unsigned int)(chip->need_reinit)); rtsx_reinit_cards(chip, 0); } }
int rtsx_reset_chip(struct rtsx_chip *chip) { int retval; rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); rtsx_disable_aspm(chip); RTSX_WRITE_REG(chip, HOST_SLEEP_STATE, 0x03, 0x00); /* Disable card clock */ RTSX_WRITE_REG(chip, CARD_CLK_EN, 0x1E, 0); #ifdef SUPPORT_OCP /* SSC power on, OCD power on */ if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, 0); else RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, MS_OC_POWER_DOWN); RTSX_WRITE_REG(chip, OCPPARA1, OCP_TIME_MASK, OCP_TIME_800); RTSX_WRITE_REG(chip, OCPPARA2, OCP_THD_MASK, OCP_THD_244_946); RTSX_WRITE_REG(chip, OCPCTL, 0xFF, CARD_OC_INT_EN | CARD_DETECT_EN); #else /* OC power down */ RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, OC_POWER_DOWN); #endif if (!CHECK_PID(chip, 0x5288)) RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0xFF, 0x03); /* Turn off LED */ RTSX_WRITE_REG(chip, CARD_GPIO, 0xFF, 0x03); /* Reset delink mode */ RTSX_WRITE_REG(chip, CHANGE_LINK_STATE, 0x0A, 0); /* Card driving select */ RTSX_WRITE_REG(chip, CARD_DRIVE_SEL, 0xFF, chip->card_drive_sel); #ifdef LED_AUTO_BLINK RTSX_WRITE_REG(chip, CARD_AUTO_BLINK, 0xFF, LED_BLINK_SPEED | BLINK_EN | LED_GPIO0); #endif if (chip->asic_code) { /* Enable SSC Clock */ RTSX_WRITE_REG(chip, SSC_CTL1, 0xFF, SSC_8X_EN | SSC_SEL_4M); RTSX_WRITE_REG(chip, SSC_CTL2, 0xFF, 0x12); } /* Disable cd_pwr_save (u_force_rst_core_en=0, u_cd_rst_core_en=0) 0xFE5B bit[1] u_cd_rst_core_en rst_value = 0 bit[2] u_force_rst_core_en rst_value = 0 bit[5] u_mac_phy_rst_n_dbg rst_value = 1 bit[4] u_non_sticky_rst_n_dbg rst_value = 0 */ RTSX_WRITE_REG(chip, CHANGE_LINK_STATE, 0x16, 0x10); /* Enable ASPM */ if (chip->aspm_l0s_l1_en) { if (chip->dynamic_aspm) { if (CHK_SDIO_EXIST(chip)) { if (CHECK_PID(chip, 0x5288)) { retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); } } } else { if (CHECK_PID(chip, 0x5208)) RTSX_WRITE_REG(chip, ASPM_FORCE_CTL, 0xFF, 0x3F); retval = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); chip->aspm_level[0] = chip->aspm_l0s_l1_en; if (CHK_SDIO_EXIST(chip)) { chip->aspm_level[1] = chip->aspm_l0s_l1_en; if (CHECK_PID(chip, 0x5288)) retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); else retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF, chip->aspm_l0s_l1_en); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); } chip->aspm_enabled = 1; } } else { if (chip->asic_code && CHECK_PID(chip, 0x5208)) { retval = rtsx_write_phy_register(chip, 0x07, 0x0129); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); } retval = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); } retval = rtsx_write_config_byte(chip, 0x81, 1); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); if (CHK_SDIO_EXIST(chip)) { if (CHECK_PID(chip, 0x5288)) retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF00, 0x0100); else retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF00, 0x0100); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); } if (CHECK_PID(chip, 0x5288)) { if (!CHK_SDIO_EXIST(chip)) { retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, 0x0103); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); } } RTSX_WRITE_REG(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); RTSX_WRITE_REG(chip, PERST_GLITCH_WIDTH, 0xFF, 0x80); /* Enable PCIE interrupt */ if (chip->asic_code) { if (CHECK_PID(chip, 0x5208)) { if (chip->phy_debug_mode) { RTSX_WRITE_REG(chip, CDRESUMECTL, 0x77, 0); rtsx_disable_bus_int(chip); } else { rtsx_enable_bus_int(chip); } if (chip->ic_version >= IC_VER_D) { u16 reg; retval = rtsx_read_phy_register(chip, 0x00, ®); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); reg &= 0xFE7F; reg |= 0x80; retval = rtsx_write_phy_register(chip, 0x00, reg); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); retval = rtsx_read_phy_register(chip, 0x1C, ®); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); reg &= 0xFFF7; retval = rtsx_write_phy_register(chip, 0x1C, reg); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); } if (chip->driver_first_load && (chip->ic_version < IC_VER_C)) rtsx_calibration(chip); } else { rtsx_enable_bus_int(chip); } } else { rtsx_enable_bus_int(chip); } chip->need_reset = 0; chip->int_reg = rtsx_readl(chip, RTSX_BIPR); if (chip->hw_bypass_sd) goto NextCard; RTSX_DEBUGP("In rtsx_reset_chip, chip->int_reg = 0x%x\n", chip->int_reg); if (chip->int_reg & SD_EXIST) { #ifdef HW_AUTO_SWITCH_SD_BUS if (CHECK_PID(chip, 0x5208) && (chip->ic_version < IC_VER_C)) retval = rtsx_pre_handle_sdio_old(chip); else retval = rtsx_pre_handle_sdio_new(chip); RTSX_DEBUGP("chip->need_reset = 0x%x (rtsx_reset_chip)\n", (unsigned int)(chip->need_reset)); #else /* HW_AUTO_SWITCH_SD_BUS */ retval = rtsx_pre_handle_sdio_old(chip); #endif /* HW_AUTO_SWITCH_SD_BUS */ if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); } else { chip->sd_io = 0; RTSX_WRITE_REG(chip, SDIO_CTRL, SDIO_BUS_CTRL | SDIO_CD_CTRL, 0); } NextCard: if (chip->int_reg & XD_EXIST) chip->need_reset |= XD_CARD; if (chip->int_reg & MS_EXIST) chip->need_reset |= MS_CARD; if (chip->int_reg & CARD_EXIST) RTSX_WRITE_REG(chip, SSC_CTL1, SSC_RSTB, SSC_RSTB); RTSX_DEBUGP("In rtsx_init_chip, chip->need_reset = 0x%x\n", (unsigned int)(chip->need_reset)); RTSX_WRITE_REG(chip, RCCTL, 0x01, 0x00); if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) { /* Turn off main power when entering S3/S4 state */ RTSX_WRITE_REG(chip, MAIN_PWR_OFF_CTL, 0x03, 0x03); } if (chip->remote_wakeup_en && !chip->auto_delink_en) { RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x07); if (chip->aux_pwr_exist) RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x33); } else { RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x04); RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x30); } if (CHECK_PID(chip, 0x5208) && (chip->ic_version >= IC_VER_D)) RTSX_WRITE_REG(chip, PETXCFG, 0x1C, 0x14); if (chip->asic_code && CHECK_PID(chip, 0x5208)) { retval = rtsx_clr_phy_reg_bit(chip, 0x1C, 2); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); } if (chip->ft2_fast_mode) { RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, MS_PARTIAL_POWER_ON | SD_PARTIAL_POWER_ON); udelay(chip->pmos_pwr_on_interval); RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, MS_POWER_ON | SD_POWER_ON); wait_timeout(200); } /* Reset card */ rtsx_reset_detected_cards(chip, 0); chip->driver_first_load = 0; return STATUS_SUCCESS; }