Beispiel #1
0
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;
}
Beispiel #2
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);
	}
}
Beispiel #3
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;
}
Beispiel #4
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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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;
}
Beispiel #7
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;
}
Beispiel #8
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);
}
Beispiel #9
0
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);
}
Beispiel #10
0
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;
}
Beispiel #11
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);
}
Beispiel #12
0
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);
}
Beispiel #13
0
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);
}
Beispiel #14
0
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;
}
Beispiel #15
0
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);
}
Beispiel #16
0
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;
}
Beispiel #17
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;
}
Beispiel #18
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);

}
Beispiel #19
0
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);

}
Beispiel #20
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);
}
Beispiel #21
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;
}
Beispiel #22
0
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;
}
Beispiel #23
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);
}
Beispiel #24
0
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);
}
Beispiel #25
0
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]);
}
Beispiel #26
0
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;
	}

}
Beispiel #27
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;
}
Beispiel #28
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;
}
Beispiel #29
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;
}
Beispiel #30
0
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);
}