Example #1
0
static int spi_set_init_para(struct rtsx_chip *chip)
{
	struct spi_info *spi = &(chip->spi);
	int retval;

	RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, (u8)(spi->clk_div >> 8));
	RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, (u8)(spi->clk_div));

	retval = switch_clock(chip, spi->spi_clock);
	if (retval != STATUS_SUCCESS)
		TRACE_RET(chip, STATUS_FAIL);

	retval = select_card(chip, SPI_CARD);
	if (retval != STATUS_SUCCESS)
		TRACE_RET(chip, STATUS_FAIL);

	RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN);
	RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN);

	wait_timeout(10);

	retval = spi_init(chip);
	if (retval != STATUS_SUCCESS)
		TRACE_RET(chip, STATUS_FAIL);

	return STATUS_SUCCESS;
}
Example #2
0
static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip)
{
	if (chip->ignore_sd && CHK_SDIO_EXIST(chip)) {
		if (chip->asic_code) {
			RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF,
				MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU);
		} else {
			RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF,
				FPGA_SD_PULL_CTL_EN);
		}
		RTSX_WRITE_REG(chip, CARD_SHARE_MODE, 0xFF, CARD_SHARE_48_SD);

		/* Enable SDIO internal clock */
		RTSX_WRITE_REG(chip, 0xFF2C, 0x01, 0x01);

		RTSX_WRITE_REG(chip, SDIO_CTRL, 0xFF,
			SDIO_BUS_CTRL | SDIO_CD_CTRL);

		chip->sd_int = 1;
		chip->sd_io = 1;
	} else {
		chip->need_reset |= SD_CARD;
	}

	return STATUS_SUCCESS;
}
Example #3
0
static int spi_init(struct rtsx_chip *chip)
{
	RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF,
		CS_POLARITY_LOW | DTO_MSB_FIRST | SPI_MASTER | SPI_MODE0 | SPI_AUTO);
	RTSX_WRITE_REG(chip, SPI_TCTL, EDO_TIMING_MASK, SAMPLE_DELAY_HALF);

	return STATUS_SUCCESS;
}
Example #4
0
int select_card(struct rtsx_chip *chip, int card)
{
	int retval;

	if (chip->cur_card != card) {
		u8 mod;

		if (card == SD_CARD) {
			mod = SD_MOD_SEL;
		} else if (card == MS_CARD) {
			mod = MS_MOD_SEL;
		} else if (card == XD_CARD) {
			mod = XD_MOD_SEL;
		} else if (card == SPI_CARD) {
			mod = SPI_MOD_SEL;
		} else {
			TRACE_RET(chip, STATUS_FAIL);
		}
		RTSX_WRITE_REG(chip, CARD_SELECT, 0x07, mod);
		chip->cur_card = card;

		retval =  card_share_mode(chip, card);
		if (retval != STATUS_SUCCESS) {
			TRACE_RET(chip, STATUS_FAIL);
		}
	}

	return STATUS_SUCCESS;
}
Example #5
0
int card_share_mode(struct rtsx_chip *chip, int card)
{
	u8 mask, value;

	if (CHECK_PID(chip, 0x5209) || CHECK_PID(chip, 0x5208)) {
		mask = CARD_SHARE_MASK;
		if (card == SD_CARD) {
			value = CARD_SHARE_48_SD;
		} else if (card == MS_CARD) {
			value = CARD_SHARE_48_MS;
		} else if (card == XD_CARD) {
			value = CARD_SHARE_48_XD;
		} else {
			TRACE_RET(chip, STATUS_FAIL);
		}
	} else if (CHECK_PID(chip, 0x5288)) {
		mask = 0x03;
		if (card == SD_CARD) {
			value = CARD_SHARE_BAROSSA_SD;
		} else if (card == MS_CARD) {
			value = CARD_SHARE_BAROSSA_MS;
		} else if (card == XD_CARD) {
			value = CARD_SHARE_BAROSSA_XD;
		} else {
			TRACE_RET(chip, STATUS_FAIL);
		}
	} else {
		TRACE_RET(chip, STATUS_FAIL);
	}

	RTSX_WRITE_REG(chip, CARD_SHARE_MODE, mask, value);

	return STATUS_SUCCESS;
}
Example #6
0
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, &reg);
		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 {
Example #7
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;
}
Example #8
0
int disable_card_clock(struct rtsx_chip *chip, u8 card)
{
	u8 clk_en = 0;

	if (card & XD_CARD)
		clk_en |= XD_CLK_EN;
	if (card & SD_CARD)
		clk_en |= SD_CLK_EN;
	if (card & MS_CARD)
		clk_en |= MS_CLK_EN;

	RTSX_WRITE_REG(chip, CARD_CLK_EN, clk_en, 0);

	return STATUS_SUCCESS;
}
Example #9
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;
	}

	RTSX_WRITE_REG(chip, CARD_PWR_CTL, mask, val);

	return STATUS_SUCCESS;
}
Example #10
0
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;
}
Example #11
0
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;
}
Example #12
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,
								&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;
}
Example #13
0
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;
}
Example #14
0
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;
}