Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9979dbe5 authored by Chaotian Jing's avatar Chaotian Jing Committed by Ulf Hansson
Browse files

mmc: mmc: extend the mmc_send_tuning()



The mmc_execute_tuning() has already prepared the opcode,
there is no need to prepare it again at mmc_send_tuning(),
and, there is a BUG of mmc_send_tuning() to determine the opcode
by bus width, assume eMMC was running at HS200, 4bit mode,
then the mmc_send_tuning() will overwrite the opcode from CMD21
to CMD19, then got error.

in addition, extend an argument of "cmd_error" to allow getting
if there was cmd error when tune response.

Signed-off-by: default avatarChaotian Jing <chaotian.jing@mediatek.com>
[Ulf: Rebased patch]
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent c9b5061e
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -588,7 +588,7 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
}
EXPORT_SYMBOL_GPL(mmc_switch);

int mmc_send_tuning(struct mmc_host *host)
int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error)
{
	struct mmc_request mrq = {NULL};
	struct mmc_command cmd = {0};
@@ -598,16 +598,13 @@ int mmc_send_tuning(struct mmc_host *host)
	const u8 *tuning_block_pattern;
	int size, err = 0;
	u8 *data_buf;
	u32 opcode;

	if (ios->bus_width == MMC_BUS_WIDTH_8) {
		tuning_block_pattern = tuning_blk_pattern_8bit;
		size = sizeof(tuning_blk_pattern_8bit);
		opcode = MMC_SEND_TUNING_BLOCK_HS200;
	} else if (ios->bus_width == MMC_BUS_WIDTH_4) {
		tuning_block_pattern = tuning_blk_pattern_4bit;
		size = sizeof(tuning_blk_pattern_4bit);
		opcode = MMC_SEND_TUNING_BLOCK;
	} else
		return -EINVAL;

@@ -638,6 +635,9 @@ int mmc_send_tuning(struct mmc_host *host)

	mmc_wait_for_req(host, &mrq);

	if (cmd_error)
		*cmd_error = cmd.error;

	if (cmd.error) {
		err = cmd.error;
		goto out;
+2 −2
Original line number Diff line number Diff line
@@ -446,7 +446,7 @@ static s8 dw_mci_exynos_get_best_clksmpl(u8 candiates)
	return loc;
}

static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
{
	struct dw_mci *host = slot->host;
	struct dw_mci_exynos_priv_data *priv = host->priv;
@@ -461,7 +461,7 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
		mci_writel(host, TMOUT, ~0);
		smpl = dw_mci_exynos_move_next_clksmpl(host);

		if (!mmc_send_tuning(mmc))
		if (!mmc_send_tuning(mmc, opcode, NULL))
			candiates |= (1 << smpl);

	} while (start_smpl != smpl);
+2 −2
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
#define NUM_PHASES			360
#define TUNING_ITERATION_TO_PHASE(i)	(DIV_ROUND_UP((i) * 360, NUM_PHASES))

static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot)
static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
{
	struct dw_mci *host = slot->host;
	struct dw_mci_rockchip_priv_data *priv = host->priv;
@@ -114,7 +114,7 @@ static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot)
	for (i = 0; i < NUM_PHASES; ) {
		clk_set_phase(priv->sample_clk, TUNING_ITERATION_TO_PHASE(i));

		v = !mmc_send_tuning(mmc);
		v = !mmc_send_tuning(mmc, opcode, NULL);

		if (i == 0)
			first_v = v;
+1 −1
Original line number Diff line number Diff line
@@ -1540,7 +1540,7 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
	int err = -EINVAL;

	if (drv_data && drv_data->execute_tuning)
		err = drv_data->execute_tuning(slot);
		err = drv_data->execute_tuning(slot, opcode);
	return err;
}

+1 −1
Original line number Diff line number Diff line
@@ -290,7 +290,7 @@ struct dw_mci_drv_data {
	void		(*prepare_command)(struct dw_mci *host, u32 *cmdr);
	void		(*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
	int		(*parse_dt)(struct dw_mci *host);
	int		(*execute_tuning)(struct dw_mci_slot *slot);
	int		(*execute_tuning)(struct dw_mci_slot *slot, u32 opcode);
	int		(*prepare_hs400_tuning)(struct dw_mci *host,
						struct mmc_ios *ios);
	int		(*switch_voltage)(struct mmc_host *mmc,
Loading