static int rts5208_init(struct rtsx_chip *chip) { int retval; u16 reg = 0; u8 val = 0; RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03); RTSX_READ_REG(chip, CLK_SEL, &val); if (val == 0) chip->asic_code = 1; else chip->asic_code = 0; if (chip->asic_code) { retval = rtsx_read_phy_register(chip, 0x1C, ®); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); RTSX_DEBUGP("Value of phy register 0x1C is 0x%x\n", reg); chip->ic_version = (reg >> 4) & 0x07; if (reg & PHY_DEBUG_MODE) chip->phy_debug_mode = 1; else chip->phy_debug_mode = 0; } else {
void do_reset_sd_card(struct rtsx_chip *chip) { int retval; RTSX_DEBUGP(("%s: %d, card2lun = 0x%x\n", __FUNCTION__, chip->sd_reset_counter, chip->card2lun[SD_CARD])); if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) { clear_bit(SD_NR, &(chip->need_reset)); chip->sd_reset_counter = 0; chip->sd_show_cnt = 0; return; } chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; rtsx_set_stat(chip, RTSX_STAT_RUN); rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); retval = reset_sd_card(chip); if (chip->need_release & SD_CARD) { return; } if (retval == STATUS_SUCCESS) { clear_bit(SD_NR, &(chip->need_reset)); chip->sd_reset_counter = 0; chip->sd_show_cnt = 0; chip->card_ready |= SD_CARD; chip->card_fail &= ~SD_CARD; chip->rw_card[chip->card2lun[SD_CARD]] = sd_rw; } else { if (chip->sd_io || (chip->sd_reset_counter >= MAX_RESET_CNT)) { clear_bit(SD_NR, &(chip->need_reset)); chip->sd_reset_counter = 0; chip->sd_show_cnt = 0; } else { chip->sd_reset_counter ++; } chip->card_ready &= ~SD_CARD; chip->card_fail |= SD_CARD; chip->capacity[chip->card2lun[SD_CARD]] = 0; chip->rw_card[chip->card2lun[SD_CARD]] = NULL; rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); if (!chip->ft2_fast_mode) { card_power_off(chip, SD_CARD); } if (chip->sd_io) { chip->sd_int = 0; try_to_switch_sdio_ctrl(chip); } else { disable_card_clock(chip, SD_CARD); } } }
void try_to_switch_sdio_ctrl(struct rtsx_chip *chip) { u8 reg1 = 0, reg2 = 0; rtsx_read_register(chip, 0xFF34, ®1); rtsx_read_register(chip, 0xFF38, ®2); RTSX_DEBUGP("reg 0xFF34: 0x%x, reg 0xFF38: 0x%x\n", reg1, reg2); if ((reg1 & 0xC0) && (reg2 & 0xC0)) { chip->sd_int = 1; rtsx_write_register(chip, SDIO_CTRL, 0xFF, SDIO_BUS_CTRL | SDIO_CD_CTRL); rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); } }
void dynamic_configure_sdio_aspm(struct rtsx_chip *chip) { u8 buf[12], reg; int i; for (i = 0; i < 12; i++) { rtsx_read_register(chip, 0xFF08 + i, &buf[i]); } rtsx_read_register(chip, 0xFF25, ®); if ((memcmp(buf, chip->sdio_raw_data, 12) != 0) || (reg & 0x03)) { chip->sdio_counter = 0; chip->sdio_idle = 0; } else { if (!chip->sdio_idle) { chip->sdio_counter ++; if (chip->sdio_counter >= SDIO_IDLE_COUNT) { chip->sdio_counter = 0; chip->sdio_idle = 1; } } } memcpy(chip->sdio_raw_data, buf, 12); if (chip->sdio_idle) { if (!chip->sdio_aspm) { RTSX_DEBUGP(("SDIO enter ASPM!\n")); rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, 0x30 | (chip->aspm_level[1] << 2)); chip->sdio_aspm = 1; } } else { if (chip->sdio_aspm) { RTSX_DEBUGP(("SDIO exit ASPM!\n")); rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, 0x30); chip->sdio_aspm = 0; } } }
void rtsx_enable_bus_int(struct rtsx_chip *chip) { u32 reg = 0; #ifndef DISABLE_CARD_INT int i; #endif reg = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN; #ifndef DISABLE_CARD_INT for (i = 0; i <= chip->max_lun; i++) { RTSX_DEBUGP("lun2card[%d] = 0x%02x\n", i, chip->lun2card[i]); if (chip->lun2card[i] & XD_CARD) reg |= XD_INT_EN; if (chip->lun2card[i] & SD_CARD) reg |= SD_INT_EN; if (chip->lun2card[i] & MS_CARD) reg |= MS_INT_EN; } if (chip->hw_bypass_sd) reg &= ~((u32)SD_INT_EN); #endif if (chip->ic_version >= IC_VER_C) reg |= DELINK_INT_EN; #ifdef SUPPORT_OCP reg |= OC_INT_EN; #endif if (!chip->adma_mode) reg |= DATA_DONE_INT_EN; /* Enable Bus Interrupt */ rtsx_writel(chip, RTSX_BIER, reg); RTSX_DEBUGP("RTSX_BIER: 0x%08x\n", reg); }
int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec_cnt) { int retval; unsigned int lun = SCSI_LUN(srb); int i; if (chip->rw_card[lun] == NULL) TRACE_RET(chip, STATUS_FAIL); for (i = 0; i < 3; i++) { chip->rw_need_retry = 0; retval = chip->rw_card[lun](srb, chip, sec_addr, sec_cnt); if (retval != STATUS_SUCCESS) { if (rtsx_check_chip_exist(chip) != STATUS_SUCCESS) { rtsx_release_chip(chip); TRACE_RET(chip, STATUS_FAIL); } if (detect_card_cd(chip, chip->cur_card) != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); if (!chip->rw_need_retry) { RTSX_DEBUGP("RW fail, but no need to retry\n"); break; } } else { chip->rw_need_retry = 0; break; } RTSX_DEBUGP("Retry RW, (i = %d)\n", i); } return retval; }
void do_reset_ms_card(struct rtsx_chip *chip) { int retval; RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__, chip->ms_reset_counter, chip->card2lun[MS_CARD]); if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) { clear_bit(MS_NR, &(chip->need_reset)); chip->ms_reset_counter = 0; chip->ms_show_cnt = 0; return; } chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; rtsx_set_stat(chip, RTSX_STAT_RUN); rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); retval = reset_ms_card(chip); if (chip->need_release & MS_CARD) return; if (retval == STATUS_SUCCESS) { clear_bit(MS_NR, &(chip->need_reset)); chip->ms_reset_counter = 0; chip->card_ready |= MS_CARD; chip->card_fail &= ~MS_CARD; chip->rw_card[chip->card2lun[MS_CARD]] = ms_rw; } else { if (chip->ms_reset_counter >= MAX_RESET_CNT) { clear_bit(MS_NR, &(chip->need_reset)); chip->ms_reset_counter = 0; chip->ms_show_cnt = 0; } else { chip->ms_reset_counter++; } chip->card_ready &= ~MS_CARD; chip->card_fail |= MS_CARD; chip->capacity[chip->card2lun[MS_CARD]] = 0; chip->rw_card[chip->card2lun[MS_CARD]] = NULL; rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); if (!chip->ft2_fast_mode) card_power_off(chip, MS_CARD); disable_card_clock(chip, MS_CARD); } }
int detect_card_cd(struct rtsx_chip *chip, int card) { u32 card_cd, status; if (card == SD_CARD) { card_cd = SD_EXIST; } else if (card == MS_CARD) { card_cd = MS_EXIST; } else if (card == XD_CARD) { card_cd = XD_EXIST; } else { RTSX_DEBUGP("Wrong card type: 0x%x\n", card); TRACE_RET(chip, STATUS_FAIL); } status = rtsx_readl(chip, RTSX_BIPR); if (!(status & card_cd)) TRACE_RET(chip, STATUS_FAIL); return STATUS_SUCCESS; }
int switch_normal_clock(struct rtsx_chip *chip, int clk) { u8 sel, div, mcu_cnt; int sd_vpclk_phase_reset = 0; if (chip->cur_clk == clk) return STATUS_SUCCESS; if (CHECK_PID(chip, 0x5209) && (chip->cur_card == SD_CARD)) { struct sd_info *sd_card = &(chip->sd_card); if (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card)) sd_vpclk_phase_reset = 1; } switch (clk) { case CLK_20: RTSX_DEBUGP("Switch clock to 20MHz\n"); sel = SSC_80; div = CLK_DIV_4; mcu_cnt = 7; break; case CLK_30: RTSX_DEBUGP("Switch clock to 30MHz\n"); sel = SSC_120; div = CLK_DIV_4; mcu_cnt = 7; break; case CLK_40: RTSX_DEBUGP("Switch clock to 40MHz\n"); sel = SSC_80; div = CLK_DIV_2; mcu_cnt = 7; break; case CLK_50: RTSX_DEBUGP("Switch clock to 50MHz\n"); sel = SSC_100; div = CLK_DIV_2; mcu_cnt = 6; break; case CLK_60: RTSX_DEBUGP("Switch clock to 60MHz\n"); sel = SSC_120; div = CLK_DIV_2; mcu_cnt = 6; break; case CLK_80: RTSX_DEBUGP("Switch clock to 80MHz\n"); sel = SSC_80; div = CLK_DIV_1; mcu_cnt = 5; break; case CLK_100: RTSX_DEBUGP("Switch clock to 100MHz\n"); sel = SSC_100; div = CLK_DIV_1; mcu_cnt = 5; break; case CLK_120: RTSX_DEBUGP("Switch clock to 120MHz\n"); sel = SSC_120; div = CLK_DIV_1; mcu_cnt = 5; break; case CLK_150: RTSX_DEBUGP("Switch clock to 150MHz\n"); sel = SSC_150; div = CLK_DIV_1; mcu_cnt = 4; break; case CLK_200: RTSX_DEBUGP("Switch clock to 200MHz\n"); sel = SSC_200; div = CLK_DIV_1; mcu_cnt = 4; break; default: RTSX_DEBUGP("Try to switch to an illegal clock (%d)\n", clk); TRACE_RET(chip, STATUS_FAIL); } RTSX_WRITE_REG(chip, CLK_CTL, 0xFF, CLK_LOW_FREQ); if (sd_vpclk_phase_reset) { RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); RTSX_WRITE_REG(chip, SD_VPCLK1_CTL, PHASE_NOT_RESET, 0); } RTSX_WRITE_REG(chip, CLK_DIV, 0xFF, (div << 4) | mcu_cnt); RTSX_WRITE_REG(chip, CLK_SEL, 0xFF, sel); if (sd_vpclk_phase_reset) { udelay(200); RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); RTSX_WRITE_REG(chip, SD_VPCLK1_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); udelay(200); } RTSX_WRITE_REG(chip, CLK_CTL, 0xFF, 0); chip->cur_clk = clk; return STATUS_SUCCESS; }
int switch_ssc_clock(struct rtsx_chip *chip, int clk) { struct sd_info *sd_card = &(chip->sd_card); struct ms_info *ms_card = &(chip->ms_card); int retval; u8 N = (u8)(clk - 2), min_N, max_N; u8 mcu_cnt, div, max_div, ssc_depth, ssc_depth_mask; int sd_vpclk_phase_reset = 0; if (chip->cur_clk == clk) return STATUS_SUCCESS; if (CHECK_PID(chip, 0x5209)) { min_N = 80; max_N = 208; max_div = CLK_DIV_8; } else { min_N = 60; max_N = 120; max_div = CLK_DIV_4; } if (CHECK_PID(chip, 0x5209) && (chip->cur_card == SD_CARD)) { struct sd_info *sd_card = &(chip->sd_card); if (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card)) sd_vpclk_phase_reset = 1; } RTSX_DEBUGP("Switch SSC clock to %dMHz (cur_clk = %d)\n", clk, chip->cur_clk); if ((clk <= 2) || (N > max_N)) { TRACE_RET(chip, STATUS_FAIL); } mcu_cnt = (u8)(125/clk + 3); if (CHECK_PID(chip, 0x5209)) { if (mcu_cnt > 15) mcu_cnt = 15; } else { if (mcu_cnt > 7) mcu_cnt = 7; } div = CLK_DIV_1; while ((N < min_N) && (div < max_div)) { N = (N + 2) * 2 - 2; div++; } RTSX_DEBUGP("N = %d, div = %d\n", N, div); if (chip->ssc_en) { if (CHECK_PID(chip, 0x5209)) { if (chip->cur_card == SD_CARD) { if (CHK_SD_SDR104(sd_card)) { ssc_depth = chip->ssc_depth_sd_sdr104; } else if (CHK_SD_SDR50(sd_card)) { ssc_depth = chip->ssc_depth_sd_sdr50; } else if (CHK_SD_DDR50(sd_card)) { ssc_depth = double_depth(chip->ssc_depth_sd_ddr50); } else if (CHK_SD_HS(sd_card)) { ssc_depth = double_depth(chip->ssc_depth_sd_hs); } else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) { ssc_depth = double_depth(chip->ssc_depth_mmc_52m); } else { ssc_depth = double_depth(chip->ssc_depth_low_speed); } } else if (chip->cur_card == MS_CARD) { if (CHK_MSPRO(ms_card)) { if (CHK_HG8BIT(ms_card)) { ssc_depth = double_depth(chip->ssc_depth_ms_hg); } else { ssc_depth = double_depth(chip->ssc_depth_ms_4bit); } } else { if (CHK_MS4BIT(ms_card)) { ssc_depth = double_depth(chip->ssc_depth_ms_4bit); } else { ssc_depth = double_depth(chip->ssc_depth_low_speed); } } } else { ssc_depth = double_depth(chip->ssc_depth_low_speed); } if (ssc_depth) { if (div == CLK_DIV_2) { if (ssc_depth > 1) { ssc_depth -= 1; } else { ssc_depth = SSC_DEPTH_4M; } } else if (div == CLK_DIV_4) { if (ssc_depth > 2) { ssc_depth -= 2; } else { ssc_depth = SSC_DEPTH_4M; } } else if (div == CLK_DIV_8) { if (ssc_depth > 3) { ssc_depth -= 3; } else { ssc_depth = SSC_DEPTH_4M; } } } } else { ssc_depth = 0x01; N -= 2; } } else { ssc_depth = 0; } if (CHECK_PID(chip, 0x5209)) { ssc_depth_mask = SSC_DEPTH_MASK; } else { ssc_depth_mask = 0x03; } RTSX_DEBUGP("ssc_depth = %d\n", ssc_depth); rtsx_init_cmd(chip); rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0xFF, (div << 4) | mcu_cnt); rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, ssc_depth_mask, ssc_depth); rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N); rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); if (sd_vpclk_phase_reset) { rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); } retval = rtsx_send_cmd(chip, 0, WAIT_TIME); if (retval < 0) { TRACE_RET(chip, STATUS_ERROR); } udelay(10); RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0); chip->cur_clk = clk; 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); } }
static int __devinit rtsx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { struct Scsi_Host *host; struct rtsx_dev *dev; int err = 0; struct task_struct *th; RTSX_DEBUGP("Realtek PCI-E card reader detected\n"); err = pci_enable_device(pci); if (err < 0) { printk(KERN_ERR "PCI enable device failed!\n"); return err; } err = pci_request_regions(pci, CR_DRIVER_NAME); if (err < 0) { printk(KERN_ERR "PCI request regions for %s failed!\n", CR_DRIVER_NAME); pci_disable_device(pci); return err; } /* * Ask the SCSI layer to allocate a host structure, with extra * space at the end for our private rtsx_dev structure. */ host = scsi_host_alloc(&rtsx_host_template, sizeof(*dev)); if (!host) { printk(KERN_ERR "Unable to allocate the scsi host\n"); pci_release_regions(pci); pci_disable_device(pci); return -ENOMEM; } dev = host_to_rtsx(host); memset(dev, 0, sizeof(struct rtsx_dev)); dev->chip = kzalloc(sizeof(struct rtsx_chip), GFP_KERNEL); if (dev->chip == NULL) goto errout; spin_lock_init(&dev->reg_lock); mutex_init(&(dev->dev_mutex)); init_completion(&dev->cmnd_ready); init_completion(&dev->control_exit); init_completion(&dev->polling_exit); init_completion(&(dev->notify)); init_completion(&dev->scanning_done); init_waitqueue_head(&dev->delay_wait); dev->pci = pci; dev->irq = -1; printk(KERN_INFO "Resource length: 0x%x\n", (unsigned int)pci_resource_len(pci, 0)); dev->addr = pci_resource_start(pci, 0); dev->remap_addr = ioremap_nocache(dev->addr, pci_resource_len(pci, 0)); if (dev->remap_addr == NULL) { printk(KERN_ERR "ioremap error\n"); err = -ENXIO; goto errout; } /* * Using "unsigned long" cast here to eliminate gcc warning in * 64-bit system */ printk(KERN_INFO "Original address: 0x%lx, remapped address: 0x%lx\n", (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr)); dev->rtsx_resv_buf = dma_alloc_coherent(&(pci->dev), RTSX_RESV_BUF_LEN, &(dev->rtsx_resv_buf_addr), GFP_KERNEL); if (dev->rtsx_resv_buf == NULL) { printk(KERN_ERR "alloc dma buffer fail\n"); err = -ENXIO; goto errout; } dev->chip->host_cmds_ptr = dev->rtsx_resv_buf; dev->chip->host_cmds_addr = dev->rtsx_resv_buf_addr; dev->chip->host_sg_tbl_ptr = dev->rtsx_resv_buf + HOST_CMDS_BUF_LEN; dev->chip->host_sg_tbl_addr = dev->rtsx_resv_buf_addr + HOST_CMDS_BUF_LEN; dev->chip->rtsx = dev; rtsx_init_options(dev->chip); printk(KERN_INFO "pci->irq = %d\n", pci->irq); if (dev->chip->msi_en) { if (pci_enable_msi(pci) < 0) dev->chip->msi_en = 0; } if (rtsx_acquire_irq(dev) < 0) { err = -EBUSY; goto errout; } pci_set_master(pci); synchronize_irq(dev->irq); rtsx_init_chip(dev->chip); /* Start up our control thread */ th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME); if (IS_ERR(th)) { printk(KERN_ERR "Unable to start control thread\n"); err = PTR_ERR(th); goto errout; } dev->ctl_thread = th; err = scsi_add_host(host, &pci->dev); if (err) { printk(KERN_ERR "Unable to add the scsi host\n"); goto errout; } /* Start up the thread for delayed SCSI-device scanning */ th = kthread_create(rtsx_scan_thread, dev, "rtsx-scan"); if (IS_ERR(th)) { printk(KERN_ERR "Unable to start the device-scanning thread\n"); quiesce_and_remove_host(dev); err = PTR_ERR(th); goto errout; } wake_up_process(th); /* Start up the thread for polling thread */ th = kthread_run(rtsx_polling_thread, dev, "rtsx-polling"); if (IS_ERR(th)) { printk(KERN_ERR "Unable to start the device-polling thread\n"); quiesce_and_remove_host(dev); err = PTR_ERR(th); goto errout; } dev->polling_thread = th; pci_set_drvdata(pci, dev); return 0; /* We come here if there are any problems */ errout: printk(KERN_ERR "rtsx_probe() failed\n"); release_everything(dev); return err; }
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; }
static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) { u8 tmp; int sw_bypass_sd = 0; int retval; if (chip->driver_first_load) { if (CHECK_PID(chip, 0x5288)) { RTSX_READ_REG(chip, 0xFE5A, &tmp); if (tmp & 0x08) sw_bypass_sd = 1; } else if (CHECK_PID(chip, 0x5208)) { RTSX_READ_REG(chip, 0xFE70, &tmp); if (tmp & 0x80) sw_bypass_sd = 1; } } else { if (chip->sdio_in_charge) sw_bypass_sd = 1; } RTSX_DEBUGP("chip->sdio_in_charge = %d\n", chip->sdio_in_charge); RTSX_DEBUGP("chip->driver_first_load = %d\n", chip->driver_first_load); RTSX_DEBUGP("sw_bypass_sd = %d\n", sw_bypass_sd); if (sw_bypass_sd) { u8 cd_toggle_mask = 0; RTSX_READ_REG(chip, TLPTISTAT, &tmp); cd_toggle_mask = 0x08; if (tmp & cd_toggle_mask) { /* Disable sdio_bus_auto_switch */ if (CHECK_PID(chip, 0x5288)) RTSX_WRITE_REG(chip, 0xFE5A, 0x08, 0x00); else if (CHECK_PID(chip, 0x5208)) RTSX_WRITE_REG(chip, 0xFE70, 0x80, 0x00); RTSX_WRITE_REG(chip, TLPTISTAT, 0xFF, tmp); chip->need_reset |= SD_CARD; } else { RTSX_DEBUGP("Chip inserted with SDIO!\n"); if (chip->asic_code) { retval = sd_pull_ctl_enable(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); } else { RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_SD_PULL_CTL_BIT | 0x20, 0); } retval = card_share_mode(chip, SD_CARD); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); /* Enable sdio_bus_auto_switch */ if (CHECK_PID(chip, 0x5288)) RTSX_WRITE_REG(chip, 0xFE5A, 0x08, 0x08); else if (CHECK_PID(chip, 0x5208)) RTSX_WRITE_REG(chip, 0xFE70, 0x80, 0x80); chip->chip_insert_with_sdio = 1; chip->sd_io = 1; } } else { RTSX_WRITE_REG(chip, TLPTISTAT, 0x08, 0x08); chip->need_reset |= SD_CARD; } return STATUS_SUCCESS; }
int switch_ssc_clock(struct rtsx_chip *chip, int clk) { int retval; u8 N = (u8)(clk - 2), min_N, max_N; u8 mcu_cnt, div, max_div, ssc_depth, ssc_depth_mask; int sd_vpclk_phase_reset = 0; if (chip->cur_clk == clk) return STATUS_SUCCESS; min_N = 60; max_N = 120; max_div = CLK_DIV_4; RTSX_DEBUGP("Switch SSC clock to %dMHz (cur_clk = %d)\n", clk, chip->cur_clk); if ((clk <= 2) || (N > max_N)) TRACE_RET(chip, STATUS_FAIL); mcu_cnt = (u8)(125/clk + 3); if (mcu_cnt > 7) mcu_cnt = 7; div = CLK_DIV_1; while ((N < min_N) && (div < max_div)) { N = (N + 2) * 2 - 2; div++; } RTSX_DEBUGP("N = %d, div = %d\n", N, div); if (chip->ssc_en) { ssc_depth = 0x01; N -= 2; } else { ssc_depth = 0; } ssc_depth_mask = 0x03; RTSX_DEBUGP("ssc_depth = %d\n", ssc_depth); rtsx_init_cmd(chip); rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0xFF, (div << 4) | mcu_cnt); rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, ssc_depth_mask, ssc_depth); rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N); rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); if (sd_vpclk_phase_reset) { rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); } retval = rtsx_send_cmd(chip, 0, WAIT_TIME); if (retval < 0) TRACE_RET(chip, STATUS_ERROR); udelay(10); RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0); chip->cur_clk = clk; return STATUS_SUCCESS; }