summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBalaji Selvanathan <[email protected]>2026-04-27 14:56:10 +0530
committerCasey Connolly <[email protected]>2026-05-18 11:04:14 +0200
commit83edbe9426a4f4b22d118c9b11d82dfb3cb472ee (patch)
tree6ecc846faf9f6790323e9659afd632b2ba310bc4 /drivers
parent7e670b7d6e10e5e072dfe05f425e635acec2524c (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.c53
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);