Пример #1
0
void do_remaining_work(struct rtsx_chip *chip)
{
	struct sd_info *sd_card = &(chip->sd_card);
#ifdef XD_DELAY_WRITE	
	struct xd_info *xd_card = &(chip->xd_card);
#endif
	struct ms_info *ms_card = &(chip->ms_card);

	if (chip->card_ready & SD_CARD) {
		if (sd_card->seq_mode) {
			rtsx_set_stat(chip, RTSX_STAT_RUN);
			sd_card->cleanup_counter ++;
		} else {
			sd_card->cleanup_counter = 0;
		}
	}

#ifdef XD_DELAY_WRITE	
	if (chip->card_ready & XD_CARD) {
		if (xd_card->delay_write.delay_write_flag) {
			rtsx_set_stat(chip, RTSX_STAT_RUN);
			xd_card->cleanup_counter ++;
		} else {
			xd_card->cleanup_counter = 0;
		}
	}
#endif

	if (chip->card_ready & MS_CARD) {
		if (CHK_MSPRO(ms_card)) {
			if (ms_card->seq_mode) {
				rtsx_set_stat(chip, RTSX_STAT_RUN);
				ms_card->cleanup_counter ++;
			} else {
				ms_card->cleanup_counter = 0;
			}
		} else {
#ifdef MS_DELAY_WRITE
			if (ms_card->delay_write.delay_write_flag) {
				rtsx_set_stat(chip, RTSX_STAT_RUN);
				ms_card->cleanup_counter ++; 
			} else {
				ms_card->cleanup_counter = 0;
			}
#endif
		}
	}
	
	if (sd_card->cleanup_counter > POLLING_WAIT_CNT) {
		sd_cleanup_work(chip);
	}

	if (xd_card->cleanup_counter > POLLING_WAIT_CNT) {
		xd_cleanup_work(chip);
	}

	if (ms_card->cleanup_counter > POLLING_WAIT_CNT) {
		ms_cleanup_work(chip);
	}
}
Пример #2
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;
}