diff options
Diffstat (limited to 'drivers/mmc/host/meson-gx-mmc.c')
| -rw-r--r-- | drivers/mmc/host/meson-gx-mmc.c | 26 | 
1 files changed, 22 insertions, 4 deletions
| diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index c885c2d4b904..85745ef179e2 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -531,8 +531,7 @@ static int meson_mmc_clk_init(struct meson_host *host)  	div->shift = __ffs(CLK_DIV_MASK);  	div->width = __builtin_popcountl(CLK_DIV_MASK);  	div->hw.init = &init; -	div->flags = (CLK_DIVIDER_ONE_BASED | -		      CLK_DIVIDER_ROUND_CLOSEST); +	div->flags = CLK_DIVIDER_ONE_BASED;  	clk = devm_clk_register(host->dev, &div->hw);  	if (WARN_ON(IS_ERR(clk))) @@ -717,6 +716,22 @@ static int meson_mmc_clk_phase_tuning(struct mmc_host *mmc, u32 opcode,  static int meson_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode)  {  	struct meson_host *host = mmc_priv(mmc); +	int ret; + +	/* +	 * If this is the initial tuning, try to get a sane Rx starting +	 * phase before doing the actual tuning. +	 */ +	if (!mmc->doing_retune) { +		ret = meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk); + +		if (ret) +			return ret; +	} + +	ret = meson_mmc_clk_phase_tuning(mmc, opcode, host->tx_clk); +	if (ret) +		return ret;  	return meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk);  } @@ -746,6 +761,11 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)  	case MMC_POWER_UP:  		if (!IS_ERR(mmc->supply.vmmc))  			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); + +		/* Reset phases */ +		clk_set_phase(host->rx_clk, 0); +		clk_set_phase(host->tx_clk, 270); +  		break;  	case MMC_POWER_ON: @@ -759,8 +779,6 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)  				host->vqmmc_enabled = true;  		} -		/* Reset rx phase */ -		clk_set_phase(host->rx_clk, 0);  		break;  	} |