mmc: meson-mx-sdhc: Fix initialization frozen issue

commit 8c124d998ea0c9022e247b11ac51f86ec8afa0e1 upstream.

Commit 4bc31edebd ("mmc: core: Set HS clock speed before sending
HS CMD13") set HS clock (52MHz) before switching to HS mode. For this
freq, FCLK_DIV5 will be selected and div value is 10 (reg value is 9).
Then we set rx_clk_phase to 11 or 15 which is out of range and make
hardware frozen. After we send command request, no irq will be
interrupted and the mmc driver will keep to wait for request finished,
even durning rebooting.

So let's set it to Phase 90 which should work in most cases. Then let
meson_mx_sdhc_execute_tuning() to find the accurate value for data
transfer.

If this doesn't work, maybe need to define a factor in dts.

Fixes: e4bf1b0970 ("mmc: host: meson-mx-sdhc: new driver for the Amlogic Meson SDHC host")
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
Tested-by: Anand Moon <linux.amoon@gmail.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/TYZPR01MB5556A3E71554A2EC08597EA4C9CDA@TYZPR01MB5556.apcprd01.prod.exchangelabs.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Ziyang Huang 2023-10-11 00:44:00 +08:00 коммит произвёл Greg Kroah-Hartman
Родитель 91432aebce
Коммит 41f20ac9bd
1 изменённых файлов: 5 добавлений и 21 удалений

Просмотреть файл

@ -269,7 +269,7 @@ static int meson_mx_sdhc_enable_clks(struct mmc_host *mmc)
static int meson_mx_sdhc_set_clk(struct mmc_host *mmc, struct mmc_ios *ios) static int meson_mx_sdhc_set_clk(struct mmc_host *mmc, struct mmc_ios *ios)
{ {
struct meson_mx_sdhc_host *host = mmc_priv(mmc); struct meson_mx_sdhc_host *host = mmc_priv(mmc);
u32 rx_clk_phase; u32 val, rx_clk_phase;
int ret; int ret;
meson_mx_sdhc_disable_clks(mmc); meson_mx_sdhc_disable_clks(mmc);
@ -290,27 +290,11 @@ static int meson_mx_sdhc_set_clk(struct mmc_host *mmc, struct mmc_ios *ios)
mmc->actual_clock = clk_get_rate(host->sd_clk); mmc->actual_clock = clk_get_rate(host->sd_clk);
/* /*
* according to Amlogic the following latching points are * Phase 90 should work in most cases. For data transmission,
* selected with empirical values, there is no (known) formula * meson_mx_sdhc_execute_tuning() will find a accurate value
* to calculate these.
*/ */
if (mmc->actual_clock > 100000000) { regmap_read(host->regmap, MESON_SDHC_CLKC, &val);
rx_clk_phase = 1; rx_clk_phase = FIELD_GET(MESON_SDHC_CLKC_CLK_DIV, val) / 4;
} else if (mmc->actual_clock > 45000000) {
if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
rx_clk_phase = 15;
else
rx_clk_phase = 11;
} else if (mmc->actual_clock >= 25000000) {
rx_clk_phase = 15;
} else if (mmc->actual_clock > 5000000) {
rx_clk_phase = 23;
} else if (mmc->actual_clock > 1000000) {
rx_clk_phase = 55;
} else {
rx_clk_phase = 1061;
}
regmap_update_bits(host->regmap, MESON_SDHC_CLK2, regmap_update_bits(host->regmap, MESON_SDHC_CLK2,
MESON_SDHC_CLK2_RX_CLK_PHASE, MESON_SDHC_CLK2_RX_CLK_PHASE,
FIELD_PREP(MESON_SDHC_CLK2_RX_CLK_PHASE, FIELD_PREP(MESON_SDHC_CLK2_RX_CLK_PHASE,