[PATCH 5/5] drivers: ufs: qcom: Initialize and enable clocks before hardware access
Julien Stephan
jstephan at baylibre.com
Thu Mar 19 11:20:41 CET 2026
Le jeu. 19 mars 2026 à 10:38, Balaji Selvanathan
<balaji.selvanathan at oss.qualcomm.com> a écrit :
>
> 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 <balaji.selvanathan at oss.qualcomm.com>
> ---
> drivers/ufs/ufs-qcom.c | 45 +++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 37 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/ufs/ufs-qcom.c b/drivers/ufs/ufs-qcom.c
> index dc40ee62daf..c63e550c881 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)
> {
> @@ -49,12 +50,34 @@ static int ufs_qcom_enable_clks(struct ufs_qcom_priv *priv)
>
> static int ufs_qcom_init_clks(struct ufs_qcom_priv *priv)
> {
> - int err;
> struct udevice *dev = priv->hba->dev;
> + struct clk clk;
> + int err;
> + long rate;
> + u32 max_freq;
> +
> + /* Get maximum frequency for core_clk_unipro from device tree */
> + max_freq = ufs_qcom_get_core_clk_unipro_max_freq(priv->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);
> + }
>
> err = clk_get_bulk(dev, &priv->clks);
> - if (err)
> + if (err) {
> + dev_err(dev, "clk_get_bulk failed: %d\n", err);
> return err;
> + }
>
> return 0;
> }
> @@ -561,6 +584,18 @@ static int ufs_qcom_init(struct ufs_hba *hba)
>
> priv->hba = hba;
>
> + err = ufs_qcom_init_clks(priv);
> + if (err) {
> + dev_err(hba->dev, "failed to initialize clocks, err:%d\n", err);
> + return err;
> + }
> +
> + err = ufs_qcom_enable_clks(priv);
> + if (err) {
> + dev_err(hba->dev, "failed to enable clocks, err:%d\n", err);
I think you are missing a call to clk_release_bulk in the error path
to free memory allocated by clk_get_bulk in ufs_qcom_init_clks
Cheers
Julien
> + return err;
> + }
> +
> /* setup clocks */
> ufs_qcom_setup_clocks(hba, true, PRE_CHANGE);
>
> @@ -579,12 +614,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);
>
>
> --
> 2.34.1
>
More information about the U-Boot
mailing list