コード例 #1
0
ファイル: rtsx_card.c プロジェクト: 7799/linux
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;
}
コード例 #2
0
ファイル: rtsx_card.c プロジェクト: 7799/linux
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;
}
コード例 #3
0
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;
}
コード例 #4
0
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);
	}
}
コード例 #5
0
ファイル: rtsx_chip.c プロジェクト: MaxChina/linux
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,
								&reg);
				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,
								&reg);
				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;
}