* [PATCH 0/5] Add UFS clock support for Qualcomm SoCs
@ 2026-03-19 9:37 Balaji Selvanathan
2026-03-19 9:37 ` [PATCH 1/5] clk: qcom: clk-stub: Add compatibles for QCS615/SA8775P/SC7280 Balaji Selvanathan
` (4 more replies)
0 siblings, 5 replies; 12+ messages in thread
From: Balaji Selvanathan @ 2026-03-19 9:37 UTC (permalink / raw)
To: u-boot, Sumit Garg, u-boot-qcom
Cc: Lukasz Majewski, Tom Rini, Casey Connolly, Neil Armstrong,
David Wronek, Luca Weiss, Jorge Ramirez-Ortiz, Swathi Tamilselvan,
Aswin Murugan, Bhupesh Sharma, Neha Malcom Francis, Marek Vasut,
Julien Stephan, Balaji Selvanathan
This series adds UFS clock support for QCS615, SA8775P, and SC7280
SoCs and enables U-Boot to initialize UFS clocks independently.
Previously, U-Boot depended on earlier bootloader stages to
initialize UFS clocks. When these bootloaders failed to do so,
UFS registers became inaccessible, preventing UFS initialization.
This series removes that dependency by adding clock infrastructure
and enabling U-Boot to configure UFS clocks directly.
Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
---
Balaji Selvanathan (5):
clk: qcom: clk-stub: Add compatibles for QCS615/SA8775P/SC7280
clk: qcom: sa8775p: Add UFS clock support
clk: qcom: qcs615: Add UFS clock support
clk: qcom: sc7280: Add UFS clock support
drivers: ufs: qcom: Initialize and enable clocks before hardware access
drivers/clk/clk-stub.c | 4 ++-
drivers/clk/qcom/clock-qcs615.c | 63 +++++++++++++++++++++++++++++++++++++++-
drivers/clk/qcom/clock-sa8775p.c | 63 ++++++++++++++++++++++++++++++++++++++++
drivers/clk/qcom/clock-sc7280.c | 52 +++++++++++++++++++++++++++++++++
drivers/ufs/ufs-qcom.c | 45 +++++++++++++++++++++++-----
5 files changed, 217 insertions(+), 10 deletions(-)
---
base-commit: 33756fd4a8157d1d921a703c4fa172f6d2eadbd2
change-id: 20260319-ufs_probe_clk-1a03ae24b4eb
Best regards,
--
Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/5] clk: qcom: clk-stub: Add compatibles for QCS615/SA8775P/SC7280
2026-03-19 9:37 [PATCH 0/5] Add UFS clock support for Qualcomm SoCs Balaji Selvanathan
@ 2026-03-19 9:37 ` Balaji Selvanathan
2026-03-19 10:30 ` Julien Stephan
2026-03-19 9:37 ` [PATCH 2/5] clk: qcom: sa8775p: Add UFS clock support Balaji Selvanathan
` (3 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Balaji Selvanathan @ 2026-03-19 9:37 UTC (permalink / raw)
To: u-boot, Sumit Garg, u-boot-qcom
Cc: Lukasz Majewski, Tom Rini, Casey Connolly, Neil Armstrong,
David Wronek, Luca Weiss, Jorge Ramirez-Ortiz, Swathi Tamilselvan,
Aswin Murugan, Bhupesh Sharma, Neha Malcom Francis, Marek Vasut,
Julien Stephan, Balaji Selvanathan
Add RPMH clock compatible strings for QCS615, SA8775P, and SC7280
SoCs to enable clock framework support on these platforms.
Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
---
drivers/clk/clk-stub.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/clk-stub.c b/drivers/clk/clk-stub.c
index 117266ac778..6a178976cc3 100644
--- a/drivers/clk/clk-stub.c
+++ b/drivers/clk/clk-stub.c
@@ -49,7 +49,10 @@ static struct clk_ops stub_clk_ops = {
};
static const struct udevice_id stub_clk_ids[] = {
+ { .compatible = "qcom,qcs615-rpmh-clk" },
{ .compatible = "qcom,rpmcc" },
+ { .compatible = "qcom,sa8775p-rpmh-clk" },
+ { .compatible = "qcom,sc7280-rpmh-clk" },
{ .compatible = "qcom,sdm670-rpmh-clk" },
{ .compatible = "qcom,sdm845-rpmh-clk" },
{ .compatible = "qcom,sc7180-rpmh-clk" },
@@ -69,4 +72,3 @@ U_BOOT_DRIVER(clk_stub) = {
.of_match = stub_clk_ids,
.flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
};
-
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/5] clk: qcom: sa8775p: Add UFS clock support
2026-03-19 9:37 [PATCH 0/5] Add UFS clock support for Qualcomm SoCs Balaji Selvanathan
2026-03-19 9:37 ` [PATCH 1/5] clk: qcom: clk-stub: Add compatibles for QCS615/SA8775P/SC7280 Balaji Selvanathan
@ 2026-03-19 9:37 ` Balaji Selvanathan
2026-03-24 6:12 ` Sumit Garg
2026-03-19 9:37 ` [PATCH 3/5] clk: qcom: qcs615: " Balaji Selvanathan
` (2 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Balaji Selvanathan @ 2026-03-19 9:37 UTC (permalink / raw)
To: u-boot, Sumit Garg, u-boot-qcom
Cc: Lukasz Majewski, Tom Rini, Casey Connolly, Neil Armstrong,
David Wronek, Luca Weiss, Jorge Ramirez-Ortiz, Swathi Tamilselvan,
Aswin Murugan, Bhupesh Sharma, Neha Malcom Francis, Marek Vasut,
Julien Stephan, Balaji Selvanathan
Add UFS clock support for SA8775P including register definitions,
rate configuration, and gate clocks.
Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
---
drivers/clk/qcom/clock-sa8775p.c | 63 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/drivers/clk/qcom/clock-sa8775p.c b/drivers/clk/qcom/clock-sa8775p.c
index 4957abf6f58..7eec4aeae48 100644
--- a/drivers/clk/qcom/clock-sa8775p.c
+++ b/drivers/clk/qcom/clock-sa8775p.c
@@ -19,6 +19,11 @@
#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0x1b028
#define USB3_PRIM_PHY_AUX_CMD_RCGR 0x1b06c
+#define UFS_PHY_AXI_CLK_CMD_RCGR 0x8302c
+#define UFS_PHY_ICE_CORE_CLK_CMD_RCGR 0x83074
+#define UFS_PHY_PHY_AUX_CLK_CMD_RCGR 0x830a8
+#define UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR 0x8308c
+
#define GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT BIT(10)
#define GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT BIT(11)
#define GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT BIT(12)
@@ -44,9 +49,35 @@
#define GCC_QUPV3_WRAP3_S0_CLK_ENA_BIT BIT(25)
+/* UFS AXI clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+ F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
+ { }
+};
+
+/* UFS ICE CORE clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
+ { }
+};
+
+/* UFS UNIPRO CORE clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
+ { }
+};
+
static ulong sa8775p_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct freq_tbl *freq;
if (clk->id < priv->data->num_clks)
debug("%s: %s, requested rate=%ld\n", __func__,
@@ -63,6 +94,24 @@ static ulong sa8775p_set_rate(struct clk *clk, ulong rate)
5, 0, 0, CFG_CLK_SRC_GPLL0, 8);
clk_rcg_set_rate(priv->base, USB3_PRIM_PHY_AUX_CMD_RCGR, 0, 0);
return rate;
+ case GCC_UFS_PHY_AXI_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_axi_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_AXI_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_UNIPRO_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_unipro_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_ICE_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_ice_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_ICE_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_PHY_AUX_CLK:
+ clk_rcg_set_rate(priv->base, UFS_PHY_PHY_AUX_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO);
+ return 19200000;
default:
return 0;
}
@@ -106,6 +155,20 @@ static const struct gate_clk sa8775p_clks[] = {
/* QUP Wrapper 3 clocks */
GATE_CLK(GCC_QUPV3_WRAP3_S0_CLK, 0x4b000, GCC_QUPV3_WRAP3_S0_CLK_ENA_BIT),
+
+ /* UFS PHY clocks */
+ GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x83018, 1),
+ GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x830d4, 1),
+ GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x83020, 1),
+ GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x83064, 1),
+ GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x83024, 1),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x83028, 1),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x830c0, 1),
+ GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x830a4, 1),
+ GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x8306c, 1),
+
+ /* EDP reference clock (used by UFS PHY) */
+ GATE_CLK(GCC_EDP_REF_CLKREF_EN, 0x97448, 1),
};
static int sa8775p_enable(struct clk *clk)
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/5] clk: qcom: qcs615: Add UFS clock support
2026-03-19 9:37 [PATCH 0/5] Add UFS clock support for Qualcomm SoCs Balaji Selvanathan
2026-03-19 9:37 ` [PATCH 1/5] clk: qcom: clk-stub: Add compatibles for QCS615/SA8775P/SC7280 Balaji Selvanathan
2026-03-19 9:37 ` [PATCH 2/5] clk: qcom: sa8775p: Add UFS clock support Balaji Selvanathan
@ 2026-03-19 9:37 ` Balaji Selvanathan
2026-03-24 6:25 ` Sumit Garg
2026-03-19 9:37 ` [PATCH 4/5] clk: qcom: sc7280: " Balaji Selvanathan
2026-03-19 9:37 ` [PATCH 5/5] drivers: ufs: qcom: Initialize and enable clocks before hardware access Balaji Selvanathan
4 siblings, 1 reply; 12+ messages in thread
From: Balaji Selvanathan @ 2026-03-19 9:37 UTC (permalink / raw)
To: u-boot, Sumit Garg, u-boot-qcom
Cc: Lukasz Majewski, Tom Rini, Casey Connolly, Neil Armstrong,
David Wronek, Luca Weiss, Jorge Ramirez-Ortiz, Swathi Tamilselvan,
Aswin Murugan, Bhupesh Sharma, Neha Malcom Francis, Marek Vasut,
Julien Stephan, Balaji Selvanathan
Add UFS clock support for qcs615 including register definitions,
rate configuration, and gate clocks.
Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
---
drivers/clk/qcom/clock-qcs615.c | 63 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/clock-qcs615.c b/drivers/clk/qcom/clock-qcs615.c
index 4700baba8c9..cd097a3cf36 100644
--- a/drivers/clk/qcom/clock-qcs615.c
+++ b/drivers/clk/qcom/clock-qcs615.c
@@ -19,6 +19,11 @@
#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf01c
#define USB3_PRIM_PHY_AUX_CMD_RCGR 0xf060
+#define UFS_PHY_AXI_CLK_CMD_RCGR 0x77020
+#define UFS_PHY_ICE_CORE_CLK_CMD_RCGR 0x77048
+#define UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR 0x77060
+#define UFS_PHY_PHY_AUX_CLK_CMD_RCGR 0x7707c
+
#define GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT BIT(10)
#define GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT BIT(11)
#define GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT BIT(12)
@@ -33,9 +38,37 @@
#define GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT BIT(26)
#define GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT BIT(27)
+/* UFS PHY AXI clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+ F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
+ F(50000000, CFG_CLK_SRC_GPLL0_EVEN, 6, 0, 0),
+ F(100000000, CFG_CLK_SRC_GPLL0, 6, 0, 0),
+ F(200000000, CFG_CLK_SRC_GPLL0, 3, 0, 0),
+ F(240000000, CFG_CLK_SRC_GPLL0, 2.5, 0, 0),
+ { }
+};
+
+/* UFS PHY ICE CORE clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+ F(37500000, CFG_CLK_SRC_GPLL0_EVEN, 8, 0, 0),
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
+ { }
+};
+
+/* UFS PHY UNIPRO CORE clock frequency table */
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+ F(37500000, CFG_CLK_SRC_GPLL0_EVEN, 8, 0, 0),
+ F(75000000, CFG_CLK_SRC_GPLL0, 8, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
+ { }
+};
+
static ulong qcs615_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct freq_tbl *freq;
if (clk->id < priv->data->num_clks)
debug("%s: %s, requested rate=%ld\n", __func__,
@@ -52,6 +85,24 @@ static ulong qcs615_set_rate(struct clk *clk, ulong rate)
5, 0, 0, CFG_CLK_SRC_GPLL0, 8);
clk_rcg_set_rate(priv->base, USB3_PRIM_PHY_AUX_CMD_RCGR, 0, 0);
return rate;
+ case GCC_UFS_PHY_AXI_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_axi_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_AXI_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_UNIPRO_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_unipro_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_ICE_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_ice_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_ICE_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_PHY_AUX_CLK:
+ clk_rcg_set_rate(priv->base, UFS_PHY_PHY_AUX_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO);
+ return 19200000;
default:
return 0;
}
@@ -79,7 +130,17 @@ static const struct gate_clk qcs615_clks[] = {
GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x5200c, GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT),
GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x5200c, GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT),
GATE_CLK(GCC_DISP_HF_AXI_CLK, 0xb038, BIT(0)),
- GATE_CLK(GCC_DISP_AHB_CLK, 0xb032, BIT(0))
+ GATE_CLK(GCC_DISP_AHB_CLK, 0xb032, BIT(0)),
+ /* UFS clocks */
+ GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77010, BIT(0)),
+ GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770c0, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77014, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x77040, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77044, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x77018, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x7701c, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x77078, BIT(0)),
+ GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, BIT(0)),
};
static int qcs615_enable(struct clk *clk)
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/5] clk: qcom: sc7280: Add UFS clock support
2026-03-19 9:37 [PATCH 0/5] Add UFS clock support for Qualcomm SoCs Balaji Selvanathan
` (2 preceding siblings ...)
2026-03-19 9:37 ` [PATCH 3/5] clk: qcom: qcs615: " Balaji Selvanathan
@ 2026-03-19 9:37 ` Balaji Selvanathan
2026-03-24 6:26 ` Sumit Garg
2026-03-19 9:37 ` [PATCH 5/5] drivers: ufs: qcom: Initialize and enable clocks before hardware access Balaji Selvanathan
4 siblings, 1 reply; 12+ messages in thread
From: Balaji Selvanathan @ 2026-03-19 9:37 UTC (permalink / raw)
To: u-boot, Sumit Garg, u-boot-qcom
Cc: Lukasz Majewski, Tom Rini, Casey Connolly, Neil Armstrong,
David Wronek, Luca Weiss, Jorge Ramirez-Ortiz, Swathi Tamilselvan,
Aswin Murugan, Bhupesh Sharma, Neha Malcom Francis, Marek Vasut,
Julien Stephan, Balaji Selvanathan
Add UFS clock support for sc7280 including register definitions,
rate configuration, and gate clocks.
Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
---
drivers/clk/qcom/clock-sc7280.c | 52 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/drivers/clk/qcom/clock-sc7280.c b/drivers/clk/qcom/clock-sc7280.c
index 7b6ed826023..2c73c26484f 100644
--- a/drivers/clk/qcom/clock-sc7280.c
+++ b/drivers/clk/qcom/clock-sc7280.c
@@ -23,6 +23,10 @@
#define PCIE_1_AUX_CLK_CMD_RCGR 0x8d058
#define PCIE1_PHY_RCHNG_CMD_RCGR 0x8d03c
#define PCIE_1_PIPE_CLK_PHY_MUX 0x8d054
+#define UFS_PHY_AXI_CLK_CMD_RCGR 0x77024
+#define UFS_PHY_ICE_CORE_CLK_CMD_RCGR 0x7706c
+#define UFS_PHY_PHY_AUX_CLK_CMD_RCGR 0x770a0
+#define UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR 0x77084
static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
F(66666667, CFG_CLK_SRC_GPLL0_EVEN, 4.5, 0, 0),
@@ -54,6 +58,33 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s2_clk_src[] = {
{ }
};
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+ F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0_EVEN, 2, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0_EVEN, 2, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = {
+ F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+ { }
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+ F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
+ F(150000000, CFG_CLK_SRC_GPLL0_EVEN, 2, 0, 0),
+ F(300000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 0, 0),
+ { }
+};
+
static ulong sc7280_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
@@ -103,6 +134,26 @@ static ulong sc7280_set_rate(struct clk *clk, ulong rate)
case GCC_PCIE1_PHY_RCHNG_CLK:
clk_rcg_set_rate(priv->base, PCIE1_PHY_RCHNG_CMD_RCGR, 5, CFG_CLK_SRC_GPLL0_EVEN);
return 100000000;
+ case GCC_UFS_PHY_AXI_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_axi_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_AXI_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_ICE_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_ice_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_ICE_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_PHY_AUX_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_phy_aux_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_PHY_AUX_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
+ case GCC_UFS_PHY_UNIPRO_CORE_CLK:
+ freq = qcom_find_freq(ftbl_gcc_ufs_phy_unipro_core_clk_src, rate);
+ clk_rcg_set_rate_mnd(priv->base, UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR,
+ freq->pre_div, freq->m, freq->n, freq->src, 8);
+ return freq->freq;
default:
return rate;
}
@@ -147,6 +198,7 @@ static const struct gate_clk sc7280_clks[] = {
GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77010, BIT(0)),
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770cc, BIT(0)),
GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77018, BIT(0)),
+ GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77064, BIT(0)),
GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x7705c, BIT(0)),
GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x7709c, BIT(0)),
GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x7701c, BIT(0)),
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 5/5] drivers: ufs: qcom: Initialize and enable clocks before hardware access
2026-03-19 9:37 [PATCH 0/5] Add UFS clock support for Qualcomm SoCs Balaji Selvanathan
` (3 preceding siblings ...)
2026-03-19 9:37 ` [PATCH 4/5] clk: qcom: sc7280: " Balaji Selvanathan
@ 2026-03-19 9:37 ` Balaji Selvanathan
2026-03-19 10:20 ` Julien Stephan
2026-03-24 6:49 ` Sumit Garg
4 siblings, 2 replies; 12+ messages in thread
From: Balaji Selvanathan @ 2026-03-19 9:37 UTC (permalink / raw)
To: u-boot, Sumit Garg, u-boot-qcom
Cc: Lukasz Majewski, Tom Rini, Casey Connolly, Neil Armstrong,
David Wronek, Luca Weiss, Jorge Ramirez-Ortiz, Swathi Tamilselvan,
Aswin Murugan, Bhupesh Sharma, Neha Malcom Francis, Marek Vasut,
Julien Stephan, Balaji Selvanathan
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@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);
+ 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
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 5/5] drivers: ufs: qcom: Initialize and enable clocks before hardware access
2026-03-19 9:37 ` [PATCH 5/5] drivers: ufs: qcom: Initialize and enable clocks before hardware access Balaji Selvanathan
@ 2026-03-19 10:20 ` Julien Stephan
2026-03-24 6:49 ` Sumit Garg
1 sibling, 0 replies; 12+ messages in thread
From: Julien Stephan @ 2026-03-19 10:20 UTC (permalink / raw)
To: Balaji Selvanathan
Cc: u-boot, Sumit Garg, u-boot-qcom, Lukasz Majewski, Tom Rini,
Casey Connolly, Neil Armstrong, David Wronek, Luca Weiss,
Jorge Ramirez-Ortiz, Swathi Tamilselvan, Aswin Murugan,
Bhupesh Sharma, Neha Malcom Francis, Marek Vasut
Le jeu. 19 mars 2026 à 10:38, Balaji Selvanathan
<balaji.selvanathan@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@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
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/5] clk: qcom: clk-stub: Add compatibles for QCS615/SA8775P/SC7280
2026-03-19 9:37 ` [PATCH 1/5] clk: qcom: clk-stub: Add compatibles for QCS615/SA8775P/SC7280 Balaji Selvanathan
@ 2026-03-19 10:30 ` Julien Stephan
0 siblings, 0 replies; 12+ messages in thread
From: Julien Stephan @ 2026-03-19 10:30 UTC (permalink / raw)
To: Balaji Selvanathan
Cc: u-boot, Sumit Garg, u-boot-qcom, Lukasz Majewski, Tom Rini,
Casey Connolly, Neil Armstrong, David Wronek, Luca Weiss,
Jorge Ramirez-Ortiz, Swathi Tamilselvan, Aswin Murugan,
Bhupesh Sharma, Neha Malcom Francis, Marek Vasut
Le jeu. 19 mars 2026 à 10:37, Balaji Selvanathan
<balaji.selvanathan@oss.qualcomm.com> a écrit :
>
> Add RPMH clock compatible strings for QCS615, SA8775P, and SC7280
> SoCs to enable clock framework support on these platforms.
>
> Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
> ---
> drivers/clk/clk-stub.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/clk-stub.c b/drivers/clk/clk-stub.c
> index 117266ac778..6a178976cc3 100644
> --- a/drivers/clk/clk-stub.c
> +++ b/drivers/clk/clk-stub.c
> @@ -49,7 +49,10 @@ static struct clk_ops stub_clk_ops = {
> };
>
> static const struct udevice_id stub_clk_ids[] = {
> + { .compatible = "qcom,qcs615-rpmh-clk" },
> { .compatible = "qcom,rpmcc" },
> + { .compatible = "qcom,sa8775p-rpmh-clk" },
> + { .compatible = "qcom,sc7280-rpmh-clk" },
This one already exist, so it is a duplicate. Drop it. Also update
commit message accordingly.
Unless you are trying to sort the compatible strings, in which case
you're missing "qcom,sc7180-rpmh-clk", and the sorting should be done
in a separate commit beforehand.
Cheers
Julien
> { .compatible = "qcom,sdm670-rpmh-clk" },
> { .compatible = "qcom,sdm845-rpmh-clk" },
> { .compatible = "qcom,sc7180-rpmh-clk" },
> @@ -69,4 +72,3 @@ U_BOOT_DRIVER(clk_stub) = {
> .of_match = stub_clk_ids,
> .flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
> };
> -
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/5] clk: qcom: sa8775p: Add UFS clock support
2026-03-19 9:37 ` [PATCH 2/5] clk: qcom: sa8775p: Add UFS clock support Balaji Selvanathan
@ 2026-03-24 6:12 ` Sumit Garg
0 siblings, 0 replies; 12+ messages in thread
From: Sumit Garg @ 2026-03-24 6:12 UTC (permalink / raw)
To: Balaji Selvanathan
Cc: u-boot, u-boot-qcom, Lukasz Majewski, Tom Rini, Casey Connolly,
Neil Armstrong, David Wronek, Luca Weiss, Jorge Ramirez-Ortiz,
Swathi Tamilselvan, Aswin Murugan, Bhupesh Sharma,
Neha Malcom Francis, Marek Vasut, Julien Stephan
On Thu, Mar 19, 2026 at 03:07:39PM +0530, Balaji Selvanathan wrote:
> Add UFS clock support for SA8775P including register definitions,
> rate configuration, and gate clocks.
>
> Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
> ---
> drivers/clk/qcom/clock-sa8775p.c | 63 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 63 insertions(+)
>
Reviewed-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
-Sumit
> diff --git a/drivers/clk/qcom/clock-sa8775p.c b/drivers/clk/qcom/clock-sa8775p.c
> index 4957abf6f58..7eec4aeae48 100644
> --- a/drivers/clk/qcom/clock-sa8775p.c
> +++ b/drivers/clk/qcom/clock-sa8775p.c
> @@ -19,6 +19,11 @@
> #define USB30_PRIM_MASTER_CLK_CMD_RCGR 0x1b028
> #define USB3_PRIM_PHY_AUX_CMD_RCGR 0x1b06c
>
> +#define UFS_PHY_AXI_CLK_CMD_RCGR 0x8302c
> +#define UFS_PHY_ICE_CORE_CLK_CMD_RCGR 0x83074
> +#define UFS_PHY_PHY_AUX_CLK_CMD_RCGR 0x830a8
> +#define UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR 0x8308c
> +
> #define GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT BIT(10)
> #define GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT BIT(11)
> #define GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT BIT(12)
> @@ -44,9 +49,35 @@
>
> #define GCC_QUPV3_WRAP3_S0_CLK_ENA_BIT BIT(25)
>
> +/* UFS AXI clock frequency table */
> +static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
> + F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
> + F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
> + F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
> + F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
> + { }
> +};
> +
> +/* UFS ICE CORE clock frequency table */
> +static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
> + F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
> + F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
> + F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
> + { }
> +};
> +
> +/* UFS UNIPRO CORE clock frequency table */
> +static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
> + F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
> + F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
> + F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
> + { }
> +};
> +
> static ulong sa8775p_set_rate(struct clk *clk, ulong rate)
> {
> struct msm_clk_priv *priv = dev_get_priv(clk->dev);
> + const struct freq_tbl *freq;
>
> if (clk->id < priv->data->num_clks)
> debug("%s: %s, requested rate=%ld\n", __func__,
> @@ -63,6 +94,24 @@ static ulong sa8775p_set_rate(struct clk *clk, ulong rate)
> 5, 0, 0, CFG_CLK_SRC_GPLL0, 8);
> clk_rcg_set_rate(priv->base, USB3_PRIM_PHY_AUX_CMD_RCGR, 0, 0);
> return rate;
> + case GCC_UFS_PHY_AXI_CLK:
> + freq = qcom_find_freq(ftbl_gcc_ufs_phy_axi_clk_src, rate);
> + clk_rcg_set_rate_mnd(priv->base, UFS_PHY_AXI_CLK_CMD_RCGR,
> + freq->pre_div, freq->m, freq->n, freq->src, 8);
> + return freq->freq;
> + case GCC_UFS_PHY_UNIPRO_CORE_CLK:
> + freq = qcom_find_freq(ftbl_gcc_ufs_phy_unipro_core_clk_src, rate);
> + clk_rcg_set_rate_mnd(priv->base, UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR,
> + freq->pre_div, freq->m, freq->n, freq->src, 8);
> + return freq->freq;
> + case GCC_UFS_PHY_ICE_CORE_CLK:
> + freq = qcom_find_freq(ftbl_gcc_ufs_phy_ice_core_clk_src, rate);
> + clk_rcg_set_rate_mnd(priv->base, UFS_PHY_ICE_CORE_CLK_CMD_RCGR,
> + freq->pre_div, freq->m, freq->n, freq->src, 8);
> + return freq->freq;
> + case GCC_UFS_PHY_PHY_AUX_CLK:
> + clk_rcg_set_rate(priv->base, UFS_PHY_PHY_AUX_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO);
> + return 19200000;
> default:
> return 0;
> }
> @@ -106,6 +155,20 @@ static const struct gate_clk sa8775p_clks[] = {
>
> /* QUP Wrapper 3 clocks */
> GATE_CLK(GCC_QUPV3_WRAP3_S0_CLK, 0x4b000, GCC_QUPV3_WRAP3_S0_CLK_ENA_BIT),
> +
> + /* UFS PHY clocks */
> + GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x83018, 1),
> + GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x830d4, 1),
> + GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x83020, 1),
> + GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x83064, 1),
> + GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x83024, 1),
> + GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x83028, 1),
> + GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x830c0, 1),
> + GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x830a4, 1),
> + GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x8306c, 1),
> +
> + /* EDP reference clock (used by UFS PHY) */
> + GATE_CLK(GCC_EDP_REF_CLKREF_EN, 0x97448, 1),
> };
>
> static int sa8775p_enable(struct clk *clk)
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/5] clk: qcom: qcs615: Add UFS clock support
2026-03-19 9:37 ` [PATCH 3/5] clk: qcom: qcs615: " Balaji Selvanathan
@ 2026-03-24 6:25 ` Sumit Garg
0 siblings, 0 replies; 12+ messages in thread
From: Sumit Garg @ 2026-03-24 6:25 UTC (permalink / raw)
To: Balaji Selvanathan
Cc: u-boot, u-boot-qcom, Lukasz Majewski, Tom Rini, Casey Connolly,
Neil Armstrong, David Wronek, Luca Weiss, Jorge Ramirez-Ortiz,
Swathi Tamilselvan, Aswin Murugan, Bhupesh Sharma,
Neha Malcom Francis, Marek Vasut, Julien Stephan
On Thu, Mar 19, 2026 at 03:07:40PM +0530, Balaji Selvanathan wrote:
> Add UFS clock support for qcs615 including register definitions,
> rate configuration, and gate clocks.
>
> Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
> ---
> drivers/clk/qcom/clock-qcs615.c | 63 ++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 62 insertions(+), 1 deletion(-)
Reviewed-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
-Sumit
>
> diff --git a/drivers/clk/qcom/clock-qcs615.c b/drivers/clk/qcom/clock-qcs615.c
> index 4700baba8c9..cd097a3cf36 100644
> --- a/drivers/clk/qcom/clock-qcs615.c
> +++ b/drivers/clk/qcom/clock-qcs615.c
> @@ -19,6 +19,11 @@
> #define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf01c
> #define USB3_PRIM_PHY_AUX_CMD_RCGR 0xf060
>
> +#define UFS_PHY_AXI_CLK_CMD_RCGR 0x77020
> +#define UFS_PHY_ICE_CORE_CLK_CMD_RCGR 0x77048
> +#define UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR 0x77060
> +#define UFS_PHY_PHY_AUX_CLK_CMD_RCGR 0x7707c
> +
> #define GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT BIT(10)
> #define GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT BIT(11)
> #define GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT BIT(12)
> @@ -33,9 +38,37 @@
> #define GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT BIT(26)
> #define GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT BIT(27)
>
> +/* UFS PHY AXI clock frequency table */
> +static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
> + F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
> + F(50000000, CFG_CLK_SRC_GPLL0_EVEN, 6, 0, 0),
> + F(100000000, CFG_CLK_SRC_GPLL0, 6, 0, 0),
> + F(200000000, CFG_CLK_SRC_GPLL0, 3, 0, 0),
> + F(240000000, CFG_CLK_SRC_GPLL0, 2.5, 0, 0),
> + { }
> +};
> +
> +/* UFS PHY ICE CORE clock frequency table */
> +static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
> + F(37500000, CFG_CLK_SRC_GPLL0_EVEN, 8, 0, 0),
> + F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
> + F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
> + F(300000000, CFG_CLK_SRC_GPLL0, 2, 0, 0),
> + { }
> +};
> +
> +/* UFS PHY UNIPRO CORE clock frequency table */
> +static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
> + F(37500000, CFG_CLK_SRC_GPLL0_EVEN, 8, 0, 0),
> + F(75000000, CFG_CLK_SRC_GPLL0, 8, 0, 0),
> + F(150000000, CFG_CLK_SRC_GPLL0, 4, 0, 0),
> + { }
> +};
> +
> static ulong qcs615_set_rate(struct clk *clk, ulong rate)
> {
> struct msm_clk_priv *priv = dev_get_priv(clk->dev);
> + const struct freq_tbl *freq;
>
> if (clk->id < priv->data->num_clks)
> debug("%s: %s, requested rate=%ld\n", __func__,
> @@ -52,6 +85,24 @@ static ulong qcs615_set_rate(struct clk *clk, ulong rate)
> 5, 0, 0, CFG_CLK_SRC_GPLL0, 8);
> clk_rcg_set_rate(priv->base, USB3_PRIM_PHY_AUX_CMD_RCGR, 0, 0);
> return rate;
> + case GCC_UFS_PHY_AXI_CLK:
> + freq = qcom_find_freq(ftbl_gcc_ufs_phy_axi_clk_src, rate);
> + clk_rcg_set_rate_mnd(priv->base, UFS_PHY_AXI_CLK_CMD_RCGR,
> + freq->pre_div, freq->m, freq->n, freq->src, 8);
> + return freq->freq;
> + case GCC_UFS_PHY_UNIPRO_CORE_CLK:
> + freq = qcom_find_freq(ftbl_gcc_ufs_phy_unipro_core_clk_src, rate);
> + clk_rcg_set_rate_mnd(priv->base, UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR,
> + freq->pre_div, freq->m, freq->n, freq->src, 8);
> + return freq->freq;
> + case GCC_UFS_PHY_ICE_CORE_CLK:
> + freq = qcom_find_freq(ftbl_gcc_ufs_phy_ice_core_clk_src, rate);
> + clk_rcg_set_rate_mnd(priv->base, UFS_PHY_ICE_CORE_CLK_CMD_RCGR,
> + freq->pre_div, freq->m, freq->n, freq->src, 8);
> + return freq->freq;
> + case GCC_UFS_PHY_PHY_AUX_CLK:
> + clk_rcg_set_rate(priv->base, UFS_PHY_PHY_AUX_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO);
> + return 19200000;
> default:
> return 0;
> }
> @@ -79,7 +130,17 @@ static const struct gate_clk qcs615_clks[] = {
> GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x5200c, GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT),
> GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x5200c, GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT),
> GATE_CLK(GCC_DISP_HF_AXI_CLK, 0xb038, BIT(0)),
> - GATE_CLK(GCC_DISP_AHB_CLK, 0xb032, BIT(0))
> + GATE_CLK(GCC_DISP_AHB_CLK, 0xb032, BIT(0)),
> + /* UFS clocks */
> + GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77010, BIT(0)),
> + GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770c0, BIT(0)),
> + GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77014, BIT(0)),
> + GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x77040, BIT(0)),
> + GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77044, BIT(0)),
> + GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x77018, BIT(0)),
> + GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x7701c, BIT(0)),
> + GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x77078, BIT(0)),
> + GATE_CLK(GCC_UFS_MEM_CLKREF_CLK, 0x8c000, BIT(0)),
> };
>
> static int qcs615_enable(struct clk *clk)
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/5] clk: qcom: sc7280: Add UFS clock support
2026-03-19 9:37 ` [PATCH 4/5] clk: qcom: sc7280: " Balaji Selvanathan
@ 2026-03-24 6:26 ` Sumit Garg
0 siblings, 0 replies; 12+ messages in thread
From: Sumit Garg @ 2026-03-24 6:26 UTC (permalink / raw)
To: Balaji Selvanathan
Cc: u-boot, u-boot-qcom, Lukasz Majewski, Tom Rini, Casey Connolly,
Neil Armstrong, David Wronek, Luca Weiss, Jorge Ramirez-Ortiz,
Swathi Tamilselvan, Aswin Murugan, Bhupesh Sharma,
Neha Malcom Francis, Marek Vasut, Julien Stephan
On Thu, Mar 19, 2026 at 03:07:41PM +0530, Balaji Selvanathan wrote:
> Add UFS clock support for sc7280 including register definitions,
> rate configuration, and gate clocks.
>
> Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
> ---
> drivers/clk/qcom/clock-sc7280.c | 52 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 52 insertions(+)
Reviewed-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
-Sumit
>
> diff --git a/drivers/clk/qcom/clock-sc7280.c b/drivers/clk/qcom/clock-sc7280.c
> index 7b6ed826023..2c73c26484f 100644
> --- a/drivers/clk/qcom/clock-sc7280.c
> +++ b/drivers/clk/qcom/clock-sc7280.c
> @@ -23,6 +23,10 @@
> #define PCIE_1_AUX_CLK_CMD_RCGR 0x8d058
> #define PCIE1_PHY_RCHNG_CMD_RCGR 0x8d03c
> #define PCIE_1_PIPE_CLK_PHY_MUX 0x8d054
> +#define UFS_PHY_AXI_CLK_CMD_RCGR 0x77024
> +#define UFS_PHY_ICE_CORE_CLK_CMD_RCGR 0x7706c
> +#define UFS_PHY_PHY_AUX_CLK_CMD_RCGR 0x770a0
> +#define UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR 0x77084
>
> static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
> F(66666667, CFG_CLK_SRC_GPLL0_EVEN, 4.5, 0, 0),
> @@ -54,6 +58,33 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s2_clk_src[] = {
> { }
> };
>
> +static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
> + F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
> + F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
> + F(150000000, CFG_CLK_SRC_GPLL0_EVEN, 2, 0, 0),
> + F(300000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 0, 0),
> + { }
> +};
> +
> +static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
> + F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
> + F(150000000, CFG_CLK_SRC_GPLL0_EVEN, 2, 0, 0),
> + F(300000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 0, 0),
> + { }
> +};
> +
> +static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = {
> + F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
> + { }
> +};
> +
> +static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
> + F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
> + F(150000000, CFG_CLK_SRC_GPLL0_EVEN, 2, 0, 0),
> + F(300000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 0, 0),
> + { }
> +};
> +
> static ulong sc7280_set_rate(struct clk *clk, ulong rate)
> {
> struct msm_clk_priv *priv = dev_get_priv(clk->dev);
> @@ -103,6 +134,26 @@ static ulong sc7280_set_rate(struct clk *clk, ulong rate)
> case GCC_PCIE1_PHY_RCHNG_CLK:
> clk_rcg_set_rate(priv->base, PCIE1_PHY_RCHNG_CMD_RCGR, 5, CFG_CLK_SRC_GPLL0_EVEN);
> return 100000000;
> + case GCC_UFS_PHY_AXI_CLK:
> + freq = qcom_find_freq(ftbl_gcc_ufs_phy_axi_clk_src, rate);
> + clk_rcg_set_rate_mnd(priv->base, UFS_PHY_AXI_CLK_CMD_RCGR,
> + freq->pre_div, freq->m, freq->n, freq->src, 8);
> + return freq->freq;
> + case GCC_UFS_PHY_ICE_CORE_CLK:
> + freq = qcom_find_freq(ftbl_gcc_ufs_phy_ice_core_clk_src, rate);
> + clk_rcg_set_rate_mnd(priv->base, UFS_PHY_ICE_CORE_CLK_CMD_RCGR,
> + freq->pre_div, freq->m, freq->n, freq->src, 8);
> + return freq->freq;
> + case GCC_UFS_PHY_PHY_AUX_CLK:
> + freq = qcom_find_freq(ftbl_gcc_ufs_phy_phy_aux_clk_src, rate);
> + clk_rcg_set_rate_mnd(priv->base, UFS_PHY_PHY_AUX_CLK_CMD_RCGR,
> + freq->pre_div, freq->m, freq->n, freq->src, 8);
> + return freq->freq;
> + case GCC_UFS_PHY_UNIPRO_CORE_CLK:
> + freq = qcom_find_freq(ftbl_gcc_ufs_phy_unipro_core_clk_src, rate);
> + clk_rcg_set_rate_mnd(priv->base, UFS_PHY_UNIPRO_CORE_CLK_CMD_RCGR,
> + freq->pre_div, freq->m, freq->n, freq->src, 8);
> + return freq->freq;
> default:
> return rate;
> }
> @@ -147,6 +198,7 @@ static const struct gate_clk sc7280_clks[] = {
> GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77010, BIT(0)),
> GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770cc, BIT(0)),
> GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77018, BIT(0)),
> + GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77064, BIT(0)),
> GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x7705c, BIT(0)),
> GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x7709c, BIT(0)),
> GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x7701c, BIT(0)),
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 5/5] drivers: ufs: qcom: Initialize and enable clocks before hardware access
2026-03-19 9:37 ` [PATCH 5/5] drivers: ufs: qcom: Initialize and enable clocks before hardware access Balaji Selvanathan
2026-03-19 10:20 ` Julien Stephan
@ 2026-03-24 6:49 ` Sumit Garg
1 sibling, 0 replies; 12+ messages in thread
From: Sumit Garg @ 2026-03-24 6:49 UTC (permalink / raw)
To: Balaji Selvanathan
Cc: u-boot, u-boot-qcom, Lukasz Majewski, Tom Rini, Casey Connolly,
Neil Armstrong, David Wronek, Luca Weiss, Jorge Ramirez-Ortiz,
Swathi Tamilselvan, Aswin Murugan, Bhupesh Sharma,
Neha Malcom Francis, Marek Vasut, Julien Stephan
On Thu, Mar 19, 2026 at 03:07:42PM +0530, Balaji Selvanathan wrote:
> 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@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);
I would just drop this wrapper and directly invoke clk_get_bulk() here.
> + if (err) {
> + dev_err(hba->dev, "failed to initialize clocks, err:%d\n", err);
> + return err;
> + }
> +
> + err = ufs_qcom_enable_clks(priv);
There is already a comment related to this API:
/*
* The PHY PLL output is the source of tx/rx lane symbol
* clocks, hence, enable the lane clocks only after PHY
* is initialized.
*/
Shouldn't PHY be initialized before clocks being enabled?
> + if (err) {
> + dev_err(hba->dev, "failed to enable clocks, err:%d\n", err);
> + 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);
While at it, I see this POST_CHANGE setup invoked twice. Can you check
as to why that is needed?
-Sumit
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-03-24 6:50 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-19 9:37 [PATCH 0/5] Add UFS clock support for Qualcomm SoCs Balaji Selvanathan
2026-03-19 9:37 ` [PATCH 1/5] clk: qcom: clk-stub: Add compatibles for QCS615/SA8775P/SC7280 Balaji Selvanathan
2026-03-19 10:30 ` Julien Stephan
2026-03-19 9:37 ` [PATCH 2/5] clk: qcom: sa8775p: Add UFS clock support Balaji Selvanathan
2026-03-24 6:12 ` Sumit Garg
2026-03-19 9:37 ` [PATCH 3/5] clk: qcom: qcs615: " Balaji Selvanathan
2026-03-24 6:25 ` Sumit Garg
2026-03-19 9:37 ` [PATCH 4/5] clk: qcom: sc7280: " Balaji Selvanathan
2026-03-24 6:26 ` Sumit Garg
2026-03-19 9:37 ` [PATCH 5/5] drivers: ufs: qcom: Initialize and enable clocks before hardware access Balaji Selvanathan
2026-03-19 10:20 ` Julien Stephan
2026-03-24 6:49 ` Sumit Garg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox