diff options
| author | Balaji Selvanathan <[email protected]> | 2026-04-27 14:56:10 +0530 |
|---|---|---|
| committer | Casey Connolly <[email protected]> | 2026-05-18 11:04:14 +0200 |
| commit | 83edbe9426a4f4b22d118c9b11d82dfb3cb472ee (patch) | |
| tree | 6ecc846faf9f6790323e9659afd632b2ba310bc4 /drivers | |
| parent | 7e670b7d6e10e5e072dfe05f425e635acec2524c (diff) | |
drivers: ufs: qcom: Initialize and enable clocks before hardware access
Move UFS clock initialization and enabling before hardware setup
to ensure clocks are running when accessing UFS registers.
Previously, U-Boot depended on earlier bootloader stages to
initialize UFS clocks. When these bootloaders failed to do so,
UFS registers became inaccessible, causing initialization to fail.
This change makes U-Boot initialize and enable UFS clocks early
in the init sequence, removing the dependency on previous
bootloaders.
Signed-off-by: Balaji Selvanathan <[email protected]>
Reviewed-by: Sumit Garg <[email protected]>
Reviewed-by: Casey Connolly <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Casey Connolly <[email protected]>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/ufs/ufs-qcom.c | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/drivers/ufs/ufs-qcom.c b/drivers/ufs/ufs-qcom.c index dc40ee62daf..ae33f62fbee 100644 --- a/drivers/ufs/ufs-qcom.c +++ b/drivers/ufs/ufs-qcom.c @@ -30,6 +30,7 @@ #define UFS_CPU_MAX_BANDWIDTH 819200 static void ufs_qcom_dev_ref_clk_ctrl(struct ufs_hba *hba, bool enable); +static u32 ufs_qcom_get_core_clk_unipro_max_freq(struct ufs_hba *hba); static int ufs_qcom_enable_clks(struct ufs_qcom_priv *priv) { @@ -47,17 +48,6 @@ static int ufs_qcom_enable_clks(struct ufs_qcom_priv *priv) return 0; } -static int ufs_qcom_init_clks(struct ufs_qcom_priv *priv) -{ - int err; - struct udevice *dev = priv->hba->dev; - - err = clk_get_bulk(dev, &priv->clks); - if (err) - return err; - - return 0; -} static int ufs_qcom_check_hibern8(struct ufs_hba *hba) { @@ -557,10 +547,45 @@ static void ufs_qcom_dev_ref_clk_ctrl(struct ufs_hba *hba, bool enable) static int ufs_qcom_init(struct ufs_hba *hba) { struct ufs_qcom_priv *priv = dev_get_priv(hba->dev); + struct udevice *dev = hba->dev; + struct clk clk; + u32 max_freq; + long rate; int err; priv->hba = hba; + /* Get maximum frequency for core_clk_unipro from device tree */ + max_freq = ufs_qcom_get_core_clk_unipro_max_freq(hba); + + /* Get and configure core_clk_unipro */ + err = clk_get_by_name(dev, "core_clk_unipro", &clk); + if (err) { + dev_err(dev, "Failed to get core_clk_unipro: %d\n", err); + return err; + } + + rate = clk_set_rate(&clk, max_freq); + if (rate < 0) { + dev_err(dev, "Failed to set core_clk_unipro rate to %u Hz: %ld\n", + max_freq, rate); + } + + /* Get all clocks */ + err = clk_get_bulk(dev, &priv->clks); + if (err) { + dev_err(dev, "clk_get_bulk failed: %d\n", err); + return err; + } + + /* Enable clocks */ + err = ufs_qcom_enable_clks(priv); + if (err) { + dev_err(dev, "failed to enable clocks: %d\n", err); + clk_release_bulk(&priv->clks); + return err; + } + /* setup clocks */ ufs_qcom_setup_clocks(hba, true, PRE_CHANGE); @@ -579,12 +604,6 @@ static int ufs_qcom_init(struct ufs_hba *hba) priv->hw_ver.minor, priv->hw_ver.step); - err = ufs_qcom_init_clks(priv); - if (err) { - dev_err(hba->dev, "failed to initialize clocks, err:%d\n", err); - return err; - } - ufs_qcom_advertise_quirks(hba); ufs_qcom_setup_clocks(hba, true, POST_CHANGE); |
