summaryrefslogtreecommitdiff
path: root/drivers/mmc/renesas-sdhi.c
diff options
context:
space:
mode:
authorMarek Vasut <marek.vasut+renesas@mailbox.org>2023-02-27 23:49:27 +0100
committerMarek Vasut <marek.vasut+renesas@mailbox.org>2023-03-10 17:45:47 +0100
commit6ddffa89cb8396bf043adcc5090e8b1a9b1d0246 (patch)
tree9719483499ce278f9012b6c8e0468db32252eb73 /drivers/mmc/renesas-sdhi.c
parentb08ffdffdce95e267e782366f4a77bf6b5537b28 (diff)
mmc: renesas-sdhi: Always configure default SDnH clock rate to 800 MHz
The prior stage bootloader might have left the SDnCKCR register in completely arbitrary state before passing control to U-Boot, which includes the register being populated with incorrect values. Currently the SDHI driver will attempt to use clock framework to configure SDn clock, which may fail in case SDnCKCR contains invalid values for the SDnH clock, because the clock framework would not be able to determine SDnH clock rate and would get -EINVAL instead, which in turn would not allow the clock framework to determine the correct SDn clock divider ratio. This failure occurs specifically in case SDnCKCR reads back 0x209 . Correct the problem by first setting default SDnH clock rate to 800 MHz, thus assuring the SDnCKCR SDnH bits are correct, and only afterward set up the SDn clock rate to default 200 MHz. Note that the SDHI driver may reconfigure SDnH clock later based on IOS settings obtained from the attached card, the 800 MHz set up here is only the default value. Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Diffstat (limited to 'drivers/mmc/renesas-sdhi.c')
-rw-r--r--drivers/mmc/renesas-sdhi.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index 4a1accebfc..2473261f3c 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -977,8 +977,16 @@ static int renesas_sdhi_probe(struct udevice *dev)
/* optional SDnH clock */
ret = clk_get_by_name(dev, "clkh", &priv->clkh);
- if (ret < 0)
+ if (ret < 0) {
dev_dbg(dev, "failed to get clkh\n");
+ } else {
+ ret = clk_set_rate(&priv->clkh, 800000000);
+ if (ret < 0) {
+ dev_err(dev, "failed to set rate for SDnH clock\n");
+ clk_free(&priv->clk);
+ return ret;
+ }
+ }
/* set to max rate */
ret = clk_set_rate(&priv->clk, 200000000);