* [PATCH v3 0/4] clk: qcom: Add Nord DPRX clock controller support
@ 2026-10-27 18:08 Taniya Das
2026-10-27 18:08 ` [PATCH v3 1/4] clk: qcom: clk-alpha-pll: fix Zonda L value rounding Taniya Das
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Taniya Das @ 2026-10-27 18:08 UTC (permalink / raw)
To: Bjorn Andersson, Stephen Boyd, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Abel Vesa, Satya Priya Kakitapalli, Vladimir Zapolskiy
Cc: Ajit Pandey, Imran Shaik, Jagadeesh Kona, linux-arm-msm,
linux-clk, linux-kernel, devicetree, Taniya Das, stable,
Konrad Dybcio, Abel Vesa, Krzysztof Kozlowski
Add support for the DisplayPort Receiver (DPRX) clock controllers found
on Qualcomm Nord devices. There are two identical DPRX clock controller
instances (DPRX0 and DPRX1), each providing clocks for the DPRX core,
audio, AHB and video memory paths, along with their core PLLs.
The DPRX PLLs are ZONDA_OLE instances whose PLL_ALPHA_VAL register has
been widened to 28 bits to carry the fractional word at a finer
resolution. The alpha-PLL core must support that width for the DPRX PLLs
to lock to and report the correct rate.
The series is organized as follows:
- Patch 1 fixes Zonda PLL L-value rounding.
- Patch 2 adds alpha-PLL support for a 28-bit ALPHA_VAL width.
- Patch 3 documents the Nord DPRX clock controller DT bindings.
- Patch 4 adds the two DPRX clock controller drivers.
Changes in v3:
- Add a separate fix for Zonda PLL L-value rounding.
- Add runtime PM support and use masked divider register updates.
- Use the preferred items form for the power-domains binding property.
- Link to v2: https://lore.kernel.org/r/20260924-nords_dprx-v2-0-fa4364e087ef@oss.qualcomm.com
Changes in v2:
- Address review comments: remove unused definitions and includes, rewrap the
alpha-width ternary, and clarify that DPRXCC provides clocks and resets.
- Add RB-by tag [Abel]
- Link to v1: https://lore.kernel.org/r/20260907-nords_dprx-v1-0-d472af3f01b1@oss.qualcomm.com
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
---
Taniya Das (4):
clk: qcom: clk-alpha-pll: fix Zonda L value rounding
clk: qcom: clk-alpha-pll: support a 28-bit ALPHA_VAL width
dt-bindings: clock: qcom: document the Nord DPRX Clock Controller
clk: qcom: dprxcc: Add Nord DPRX clock controller support
.../bindings/clock/qcom,nord-dprxcc.yaml | 67 ++++
drivers/clk/qcom/Kconfig | 11 +
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/clk-alpha-pll.c | 10 +-
drivers/clk/qcom/clk-alpha-pll.h | 3 +
drivers/clk/qcom/dprxcc0-nord.c | 441 +++++++++++++++++++++
drivers/clk/qcom/dprxcc1-nord.c | 440 ++++++++++++++++++++
include/dt-bindings/clock/qcom,nord-dprxcc.h | 27 ++
8 files changed, 995 insertions(+), 5 deletions(-)
---
base-commit: f1ac44c32cba88ad65dcecd4a279661d14e93651
change-id: 20260903-nords_dprx-4903d7acc841
Best regards,
--
Taniya Das <taniya.das@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/4] clk: qcom: clk-alpha-pll: fix Zonda L value rounding
2026-10-27 18:08 [PATCH v3 0/4] clk: qcom: Add Nord DPRX clock controller support Taniya Das
@ 2026-10-27 18:08 ` Taniya Das
2026-10-27 18:08 ` [PATCH v3 2/4] clk: qcom: clk-alpha-pll: support a 28-bit ALPHA_VAL width Taniya Das
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Taniya Das @ 2026-10-27 18:08 UTC (permalink / raw)
To: Bjorn Andersson, Stephen Boyd, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Abel Vesa, Satya Priya Kakitapalli, Vladimir Zapolskiy
Cc: Ajit Pandey, Imran Shaik, Jagadeesh Kona, linux-arm-msm,
linux-clk, linux-kernel, devicetree, Taniya Das, stable,
Konrad Dybcio
zonda_pll_adjust_l_val() obtains the integer quotient of the requested
rate and parent rate in quotient, but writes the requested rate to L_VAL
when the fractional alpha value requires rounding. This programs a
nonsensical integer divider. For example, a 1.2 GHz rate with a 19.2 MHz
parent requires L = 63, but programs L = 1200000001.
Use quotient when calculating the rounded L value.
A GPT-assisted review reported this issue.
Fixes: a4d89b11aca3 ("clk: qcom: clk-alpha-pll: Simplify the zonda_pll_adjust_l_val()")
Cc: stable@vger.kernel.org
Reported-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://lore.kernel.org/9dc66fa5-47a9-417b-b8ff-b3a61ea75678@oss.qualcomm.com
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
---
drivers/clk/qcom/clk-alpha-pll.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 60173b076cc5f16bb55343a1d1136eb07f3c050f..9782fb062a58a26daf3e911ad23c5e1d805b0c38 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -2271,7 +2271,7 @@ static void zonda_pll_adjust_l_val(unsigned long rate, unsigned long prate, u32
quotient = rate;
remainder = do_div(quotient, prate);
- *l = rate + (u32)(remainder * 2 >= prate);
+ *l = quotient + (u32)(remainder * 2 >= prate);
}
static int clk_zonda_pll_set_rate(struct clk_hw *hw, unsigned long rate,
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 2/4] clk: qcom: clk-alpha-pll: support a 28-bit ALPHA_VAL width
2026-10-27 18:08 [PATCH v3 0/4] clk: qcom: Add Nord DPRX clock controller support Taniya Das
2026-10-27 18:08 ` [PATCH v3 1/4] clk: qcom: clk-alpha-pll: fix Zonda L value rounding Taniya Das
@ 2026-10-27 18:08 ` Taniya Das
2026-10-27 18:08 ` [PATCH v3 3/4] dt-bindings: clock: qcom: document the Nord DPRX Clock Controller Taniya Das
2026-10-27 18:08 ` [PATCH v3 4/4] clk: qcom: dprxcc: Add Nord DPRX clock controller support Taniya Das
3 siblings, 0 replies; 5+ messages in thread
From: Taniya Das @ 2026-10-27 18:08 UTC (permalink / raw)
To: Bjorn Andersson, Stephen Boyd, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Abel Vesa, Satya Priya Kakitapalli, Vladimir Zapolskiy
Cc: Ajit Pandey, Imran Shaik, Jagadeesh Kona, linux-arm-msm,
linux-clk, linux-kernel, devicetree, Taniya Das, Abel Vesa,
Konrad Dybcio
On some PLLs the PLL_ALPHA_VAL register has been increased to 28 bits to
carry the fractional word at a finer resolution, for example the
ZONDA_OLE instances on the Qualcomm Nord DPRX. The alpha-PLL core,
however, derives the ALPHA_VAL width solely from the register-map layout
and can only express 16 or 40 bits, so it programs and reads back the
28-bit configuration at the wrong scale on both the set_rate/slew and
recalc_rate paths, making the PLL lock to and report the wrong rate.
Add a way to identify the wider register: an optional alpha_width field
in struct clk_alpha_pll that, when non-zero, supersedes the
register-derived width. This feeds pll_alpha_width(), so the recalc_rate
and round_rate math scale the fractional word correctly, and the Zonda
set_rate L-adjust MSB check is derived from the active width instead of
a hardcoded BIT(15). PLLs that leave the field zero retain the previous
behaviour.
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
---
drivers/clk/qcom/clk-alpha-pll.c | 8 ++++----
drivers/clk/qcom/clk-alpha-pll.h | 3 +++
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 9782fb062a58a26daf3e911ad23c5e1d805b0c38..9726e6ea7f5f80a6355aa58c345657aad8c157c0 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -41,7 +41,6 @@
#define PLL_USER_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_USER_CTL])
# define PLL_POST_DIV_SHIFT 8
# define PLL_POST_DIV_MASK(p) GENMASK((p)->width ? (p)->width - 1 : 3, 0)
-# define PLL_ALPHA_MSB BIT(15)
# define PLL_ALPHA_EN BIT(24)
# define PLL_ALPHA_MODE BIT(25)
# define PLL_VCO_SHIFT 20
@@ -382,8 +381,9 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
#define ZONDA_PLL_FREQ_LOCK_DET BIT(29)
#define pll_alpha_width(p) \
- ((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ? \
- ALPHA_REG_BITWIDTH : ALPHA_REG_16BIT_WIDTH)
+ ((p)->alpha_width ? (p)->alpha_width : \
+ ((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ? \
+ ALPHA_REG_BITWIDTH : ALPHA_REG_16BIT_WIDTH))
#define pll_has_64bit_config(p) ((PLL_CONFIG_CTL_U(p) - PLL_CONFIG_CTL(p)) == 4)
@@ -2290,7 +2290,7 @@ static int clk_zonda_pll_set_rate(struct clk_hw *hw, unsigned long rate,
if (ret < 0)
return ret;
- if (a & PLL_ALPHA_MSB)
+ if (a & BIT(alpha_width - 1))
zonda_pll_adjust_l_val(rate, prate, &l);
regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h
index 3a2157bebc52cd15f55381a068953f21be18f6bb..ab3b4f4fc7501df0fa3f59d741d64646383e4cfd 100644
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -86,6 +86,8 @@ struct pll_vco {
* struct clk_alpha_pll - phase locked loop (PLL)
* @offset: base address of registers
* @regs: alpha pll register map (see @clk_alpha_pll_regs)
+ * @alpha_width: optional override of the ALPHA_VAL width in bits;
+ * 0 means derive the width from @regs
* @config: array of pll settings
* @vco_table: array of VCO settings
* @num_vco: number of VCO settings in @vco_table
@@ -95,6 +97,7 @@ struct pll_vco {
struct clk_alpha_pll {
u32 offset;
const u8 *regs;
+ u32 alpha_width;
const struct alpha_pll_config *config;
const struct pll_vco *vco_table;
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 3/4] dt-bindings: clock: qcom: document the Nord DPRX Clock Controller
2026-10-27 18:08 [PATCH v3 0/4] clk: qcom: Add Nord DPRX clock controller support Taniya Das
2026-10-27 18:08 ` [PATCH v3 1/4] clk: qcom: clk-alpha-pll: fix Zonda L value rounding Taniya Das
2026-10-27 18:08 ` [PATCH v3 2/4] clk: qcom: clk-alpha-pll: support a 28-bit ALPHA_VAL width Taniya Das
@ 2026-10-27 18:08 ` Taniya Das
2026-10-27 18:08 ` [PATCH v3 4/4] clk: qcom: dprxcc: Add Nord DPRX clock controller support Taniya Das
3 siblings, 0 replies; 5+ messages in thread
From: Taniya Das @ 2026-10-27 18:08 UTC (permalink / raw)
To: Bjorn Andersson, Stephen Boyd, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Abel Vesa, Satya Priya Kakitapalli, Vladimir Zapolskiy
Cc: Ajit Pandey, Imran Shaik, Jagadeesh Kona, linux-arm-msm,
linux-clk, linux-kernel, devicetree, Taniya Das,
Krzysztof Kozlowski
Add bindings documentation for the Nord DisplayPort Receiver (DPRX)
Clock Controller.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
---
.../bindings/clock/qcom,nord-dprxcc.yaml | 67 ++++++++++++++++++++++
include/dt-bindings/clock/qcom,nord-dprxcc.h | 27 +++++++++
2 files changed, 94 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/qcom,nord-dprxcc.yaml b/Documentation/devicetree/bindings/clock/qcom,nord-dprxcc.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1d5d6f89114885aa4faab565dbb8a6dd9b3bbf1a
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,nord-dprxcc.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,nord-dprxcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm DPRX Clock & Reset Controller on Nord
+
+maintainers:
+ - Taniya Das <taniya.das@oss.qualcomm.com>
+
+description: |
+ Qualcomm dprx clock control module provides the clocks, and resets
+ domains on Nord.
+
+ See also:
+ include/dt-bindings/clock/qcom,nord-dprxcc.h
+
+properties:
+ compatible:
+ enum:
+ - qcom,nord-dprxcc0
+ - qcom,nord-dprxcc1
+
+ clocks:
+ items:
+ - description: XO clock source
+ - description: DPRX CFG AHB clock from NWGCC
+ - description: Sleep clock source
+
+ power-domains:
+ items:
+ - description: MMCX power domain
+
+ required-opps:
+ description:
+ MMCX performance point.
+ maxItems: 1
+
+required:
+ - compatible
+ - clocks
+ - power-domains
+ - required-opps
+
+allOf:
+ - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,nord-nwgcc.h>
+ #include <dt-bindings/clock/qcom,rpmh.h>
+ #include <dt-bindings/power/qcom,rpmhpd.h>
+ clock-controller@a940000 {
+ compatible = "qcom,nord-dprxcc0";
+ reg = <0x0a940000 0xc000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&nwgcc NW_GCC_DPRX0_CFG_AHB_CLK>,
+ <&sleep_clk>;
+ power-domains = <&rpmhpd RPMHPD_MMCX>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+...
diff --git a/include/dt-bindings/clock/qcom,nord-dprxcc.h b/include/dt-bindings/clock/qcom,nord-dprxcc.h
new file mode 100644
index 0000000000000000000000000000000000000000..62c26b58ebef04f05ea1dc77664c03aaad65baa4
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,nord-dprxcc.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_DPRX_CC_NORD_H
+#define _DT_BINDINGS_CLK_QCOM_DPRX_CC_NORD_H
+
+/* DPRX_CC clocks */
+#define DPRX_CC_AHB_CLK 0
+#define DPRX_CC_AUD_CLK 1
+#define DPRX_CC_AUDIO_CLK_SRC 2
+#define DPRX_CC_CORE_AHB_DIV_CLK_SRC 3
+#define DPRX_CC_CORE_AUD_DIV_CLK_SRC 4
+#define DPRX_CC_CORE_RCG0_CLK_SRC 5
+#define DPRX_CC_CORE_RCG2_CLK_SRC 6
+#define DPRX_CC_CORE_RCG3_CLK_SRC 7
+#define DPRX_CC_MDP_MEM_CLK 8
+#define DPRX_CC_MMCX_XO_CLK 9
+#define DPRX_CC_PLL0 10
+#define DPRX_CC_PLL1 11
+#define DPRX_CC_VID_MEM_CLK 12
+
+/* DPRX_CC resets */
+#define DPRX_CC_DPRX_BLK_BCR 0
+
+#endif
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 4/4] clk: qcom: dprxcc: Add Nord DPRX clock controller support
2026-10-27 18:08 [PATCH v3 0/4] clk: qcom: Add Nord DPRX clock controller support Taniya Das
` (2 preceding siblings ...)
2026-10-27 18:08 ` [PATCH v3 3/4] dt-bindings: clock: qcom: document the Nord DPRX Clock Controller Taniya Das
@ 2026-10-27 18:08 ` Taniya Das
3 siblings, 0 replies; 5+ messages in thread
From: Taniya Das @ 2026-10-27 18:08 UTC (permalink / raw)
To: Bjorn Andersson, Stephen Boyd, Brian Masney, Jerome Brunet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Abel Vesa, Satya Priya Kakitapalli, Vladimir Zapolskiy
Cc: Ajit Pandey, Imran Shaik, Jagadeesh Kona, linux-arm-msm,
linux-clk, linux-kernel, devicetree, Taniya Das, Abel Vesa
Add support for the DisplayPort Receiver (DPRX) clock controllers on
Nord devices. There are two identical DPRX clock controller
instances (DPRX0 and DPRX1), each providing clocks for the DPRX core,
audio, AHB and video memory paths, along with core PLLs.
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reviewed-by: Shawn Guo <shengchao.guo@oss.qualcomm.com>
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
---
drivers/clk/qcom/Kconfig | 11 +
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/dprxcc0-nord.c | 441 ++++++++++++++++++++++++++++++++++++++++
drivers/clk/qcom/dprxcc1-nord.c | 440 +++++++++++++++++++++++++++++++++++++++
4 files changed, 893 insertions(+)
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 27d0ab24d50a4ca5587ed8d6085c4d6fcd57eb8c..a828e349fee98245b2cfabc43a1fd92b1936403d 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -255,6 +255,17 @@ config CLK_NORD_CAMCC
Say Y if you want to support camera devices and functionality such as
capturing pictures.
+config CLK_NORD_DPRXCC
+ tristate "Nord DPRX Clock Controller"
+ depends on ARM64 || COMPILE_TEST
+ select CLK_NORD_GCC
+ default m if ARCH_QCOM
+ help
+ Support for the Display Port Receiver (DPRX) clock controller on
+ Nord devices. The DPRX clock controller provides clocks for the
+ DPRX core, audio, AHB and video memory paths.
+ Say Y if you want to support DPRX functionality.
+
config CLK_NORD_GCC
tristate "Nord Global Clock Controller"
depends on ARM64 || COMPILE_TEST
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 6affb5073f269d18f1b78d6c7f92e14baeade1e5..237e5d7ff5f30c38a5d3d303998d735afda0c89a 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_CLK_KUNO_GCC) += gcc-kuno.o
obj-$(CONFIG_CLK_MAILI_VIDEOCC) += videocc-maili.o
obj-$(CONFIG_CLK_NORD_CAMCC) += camcc-nord.o
obj-$(CONFIG_CLK_NORD_DISPCC) += dispcc0-nord.o dispcc1-nord.o
+obj-$(CONFIG_CLK_NORD_DPRXCC) += dprxcc0-nord.o dprxcc1-nord.o
obj-$(CONFIG_CLK_NORD_GCC) += gcc-nord.o negcc-nord.o nwgcc-nord.o segcc-nord.o
obj-$(CONFIG_CLK_NORD_GPUCC) += gpucc-nord.o gpu2cc-nord.o
obj-$(CONFIG_CLK_NORD_TCSRCC) += tcsrcc-nord.o
diff --git a/drivers/clk/qcom/dprxcc0-nord.c b/drivers/clk/qcom/dprxcc0-nord.c
new file mode 100644
index 0000000000000000000000000000000000000000..456666834a4f41eb9b6eaa99f57023b9a3567549
--- /dev/null
+++ b/drivers/clk/qcom/dprxcc0-nord.c
@@ -0,0 +1,441 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/bits.h>
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,nord-dprxcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "common.h"
+#include "reset.h"
+
+enum {
+ DT_BI_TCXO,
+ DT_AHB_CLK,
+ DT_SLEEP_CLK,
+};
+
+enum {
+ P_BI_TCXO,
+ P_DPRX_0_DPRX_CC_PLL0_OUT_EVEN,
+ P_DPRX_0_DPRX_CC_PLL0_OUT_MAIN,
+ P_DPRX_0_DPRX_CC_PLL0_OUT_ODD,
+ P_DPRX_0_DPRX_CC_PLL1_OUT_EVEN,
+ P_DPRX_0_DPRX_CC_PLL1_OUT_MAIN,
+ P_SLEEP_CLK,
+};
+
+#define DPRX_CC_CORE_AHB_DIV_CFG 0x80b0
+#define DPRX_CC_CORE_AHB_DIV GENMASK(3, 0)
+#define DPRX_CC_CORE_AUD_DIV_CFG 0x80d0
+#define DPRX_CC_CORE_AUD_DIV GENMASK(8, 0)
+
+static const struct pll_vco lucid_ole_vco[] = {
+ { 249600000, 2300000000, 0 },
+};
+
+static const struct pll_vco zonda_ole_vco[] = {
+ { 700000000, 3600000000, 0 },
+};
+
+/* 550.0 MHz Configuration */
+static const struct alpha_pll_config dprx_0_dprx_cc_pll0_config = {
+ .l = 0x1c,
+ .alpha = 0xa555,
+ .config_ctl_val = 0x20485699,
+ .config_ctl_hi_val = 0x00182261,
+ .config_ctl_hi1_val = 0x82aa299c,
+ .test_ctl_val = 0x00000000,
+ .test_ctl_hi_val = 0x00000003,
+ .test_ctl_hi1_val = 0x00009000,
+ .test_ctl_hi2_val = 0x00000034,
+ .user_ctl_val = 0x00000000,
+ .user_ctl_hi_val = 0x00400005,
+};
+
+static struct clk_alpha_pll dprx_0_dprx_cc_pll0 = {
+ .offset = 0x0,
+ .config = &dprx_0_dprx_cc_pll0_config,
+ .vco_table = lucid_ole_vco,
+ .num_vco = ARRAY_SIZE(lucid_ole_vco),
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+ .clkr = {
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_0_dprx_cc_pll0",
+ .parent_data = &(const struct clk_parent_data) {
+ .index = DT_BI_TCXO,
+ },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_lucid_evo_ops,
+ },
+ },
+};
+
+/* 1080.0 MHz Configuration */
+static const struct alpha_pll_config dprx_0_dprx_cc_pll1_config = {
+ .l = 0x38,
+ .alpha = 0x4000000,
+ .config_ctl_val = 0x08240800,
+ .config_ctl_hi_val = 0x05008001,
+ .config_ctl_hi1_val = 0x00000000,
+ .config_ctl_hi2_val = 0x00000000,
+ .user_ctl_val = 0x00000000,
+ .user_ctl_hi_val = 0x02000080,
+};
+
+static struct clk_alpha_pll dprx_0_dprx_cc_pll1 = {
+ .offset = 0x1000,
+ .alpha_width = 28,
+ .config = &dprx_0_dprx_cc_pll1_config,
+ .vco_table = zonda_ole_vco,
+ .num_vco = ARRAY_SIZE(zonda_ole_vco),
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA_OLE],
+ .clkr = {
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_0_dprx_cc_pll1",
+ .parent_data = &(const struct clk_parent_data) {
+ .index = DT_BI_TCXO,
+ },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_zonda_ole_ops,
+ },
+ },
+};
+
+static const struct parent_map dprx_cc_0_parent_map_0[] = {
+ { P_BI_TCXO, 0 },
+ { P_DPRX_0_DPRX_CC_PLL0_OUT_EVEN, 1 },
+ { P_DPRX_0_DPRX_CC_PLL0_OUT_ODD, 2 },
+ { P_DPRX_0_DPRX_CC_PLL0_OUT_MAIN, 4 },
+ { P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data dprx_cc_0_parent_data_0[] = {
+ { .index = DT_BI_TCXO },
+ { .hw = &dprx_0_dprx_cc_pll0.clkr.hw },
+ { .hw = &dprx_0_dprx_cc_pll0.clkr.hw },
+ { .hw = &dprx_0_dprx_cc_pll0.clkr.hw },
+ { .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map dprx_cc_0_parent_map_1[] = {
+ { P_BI_TCXO, 0 },
+ { P_DPRX_0_DPRX_CC_PLL1_OUT_EVEN, 3 },
+ { P_SLEEP_CLK, 5 },
+ { P_DPRX_0_DPRX_CC_PLL1_OUT_MAIN, 6 },
+};
+
+static const struct clk_parent_data dprx_cc_0_parent_data_1[] = {
+ { .index = DT_BI_TCXO },
+ { .hw = &dprx_0_dprx_cc_pll1.clkr.hw },
+ { .index = DT_SLEEP_CLK },
+ { .hw = &dprx_0_dprx_cc_pll1.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_dprx_0_dprx_cc_audio_clk_src[] = {
+ F(216000000, P_DPRX_0_DPRX_CC_PLL1_OUT_MAIN, 5, 0, 0),
+ F(300000000, P_DPRX_0_DPRX_CC_PLL1_OUT_MAIN, 5, 0, 0),
+ F(360000000, P_DPRX_0_DPRX_CC_PLL1_OUT_MAIN, 5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dprx_0_dprx_cc_audio_clk_src = {
+ .cmd_rcgr = 0x80c8,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dprx_cc_0_parent_map_1,
+ .freq_tbl = ftbl_dprx_0_dprx_cc_audio_clk_src,
+ .hw_clk_ctrl = true,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dprx_0_dprx_cc_audio_clk_src",
+ .parent_data = dprx_cc_0_parent_data_1,
+ .num_parents = ARRAY_SIZE(dprx_cc_0_parent_data_1),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_shared_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_dprx_0_dprx_cc_core_rcg0_clk_src[] = {
+ F(220000000, P_DPRX_0_DPRX_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
+ F(440000000, P_DPRX_0_DPRX_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dprx_0_dprx_cc_core_rcg0_clk_src = {
+ .cmd_rcgr = 0x8004,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dprx_cc_0_parent_map_0,
+ .freq_tbl = ftbl_dprx_0_dprx_cc_core_rcg0_clk_src,
+ .hw_clk_ctrl = true,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dprx_0_dprx_cc_core_rcg0_clk_src",
+ .parent_data = dprx_cc_0_parent_data_0,
+ .num_parents = ARRAY_SIZE(dprx_cc_0_parent_data_0),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_shared_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_dprx_0_dprx_cc_core_rcg2_clk_src[] = {
+ F(275000000, P_DPRX_0_DPRX_CC_PLL0_OUT_MAIN, 2, 0, 0),
+ F(440000000, P_DPRX_0_DPRX_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
+ F(550000000, P_DPRX_0_DPRX_CC_PLL0_OUT_MAIN, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dprx_0_dprx_cc_core_rcg2_clk_src = {
+ .cmd_rcgr = 0x8068,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dprx_cc_0_parent_map_0,
+ .freq_tbl = ftbl_dprx_0_dprx_cc_core_rcg2_clk_src,
+ .hw_clk_ctrl = true,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dprx_0_dprx_cc_core_rcg2_clk_src",
+ .parent_data = dprx_cc_0_parent_data_0,
+ .num_parents = ARRAY_SIZE(dprx_cc_0_parent_data_0),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_shared_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_dprx_0_dprx_cc_core_rcg3_clk_src[] = {
+ F(275000000, P_DPRX_0_DPRX_CC_PLL0_OUT_MAIN, 2, 0, 0),
+ F(550000000, P_DPRX_0_DPRX_CC_PLL0_OUT_MAIN, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dprx_0_dprx_cc_core_rcg3_clk_src = {
+ .cmd_rcgr = 0x8098,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dprx_cc_0_parent_map_0,
+ .freq_tbl = ftbl_dprx_0_dprx_cc_core_rcg3_clk_src,
+ .hw_clk_ctrl = true,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dprx_0_dprx_cc_core_rcg3_clk_src",
+ .parent_data = dprx_cc_0_parent_data_0,
+ .num_parents = ARRAY_SIZE(dprx_cc_0_parent_data_0),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_shared_ops,
+ },
+};
+
+static struct clk_regmap_div dprx_0_dprx_cc_core_ahb_div_clk_src = {
+ .reg = 0x80b0,
+ .shift = 0,
+ .width = 4,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dprx_0_dprx_cc_core_ahb_div_clk_src",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dprx_0_dprx_cc_core_rcg3_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_regmap_div_ro_ops,
+ },
+};
+
+static struct clk_regmap_div dprx_0_dprx_cc_core_aud_div_clk_src = {
+ .reg = 0x80d0,
+ .shift = 0,
+ .width = 9,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dprx_0_dprx_cc_core_aud_div_clk_src",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dprx_0_dprx_cc_audio_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_regmap_div_ro_ops,
+ },
+};
+
+static struct clk_branch dprx_0_dprx_cc_ahb_clk = {
+ .halt_reg = 0x80b4,
+ .halt_check = BRANCH_HALT_VOTED,
+ .hwcg_reg = 0x80b4,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x80b4,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_0_dprx_cc_ahb_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dprx_0_dprx_cc_core_ahb_div_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dprx_0_dprx_cc_aud_clk = {
+ .halt_reg = 0x80d4,
+ .halt_check = BRANCH_HALT_VOTED,
+ .hwcg_reg = 0x80d4,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x80d4,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_0_dprx_cc_aud_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dprx_0_dprx_cc_core_aud_div_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dprx_0_dprx_cc_mdp_mem_clk = {
+ .halt_reg = 0x8088,
+ .halt_check = BRANCH_HALT_VOTED,
+ .hwcg_reg = 0x8088,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x8088,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_0_dprx_cc_mdp_mem_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dprx_0_dprx_cc_core_rcg2_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dprx_0_dprx_cc_mmcx_xo_clk = {
+ .halt_reg = 0x80d8,
+ .halt_check = BRANCH_HALT_VOTED,
+ .hwcg_reg = 0x80d8,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x80d8,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_0_dprx_cc_mmcx_xo_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dprx_0_dprx_cc_vid_mem_clk = {
+ .halt_reg = 0x8028,
+ .halt_check = BRANCH_HALT_VOTED,
+ .hwcg_reg = 0x8028,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x8028,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_0_dprx_cc_vid_mem_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dprx_0_dprx_cc_core_rcg0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_regmap *dprx_cc_0_nord_clocks[] = {
+ [DPRX_CC_AHB_CLK] = &dprx_0_dprx_cc_ahb_clk.clkr,
+ [DPRX_CC_AUD_CLK] = &dprx_0_dprx_cc_aud_clk.clkr,
+ [DPRX_CC_AUDIO_CLK_SRC] = &dprx_0_dprx_cc_audio_clk_src.clkr,
+ [DPRX_CC_CORE_AHB_DIV_CLK_SRC] = &dprx_0_dprx_cc_core_ahb_div_clk_src.clkr,
+ [DPRX_CC_CORE_AUD_DIV_CLK_SRC] = &dprx_0_dprx_cc_core_aud_div_clk_src.clkr,
+ [DPRX_CC_CORE_RCG0_CLK_SRC] = &dprx_0_dprx_cc_core_rcg0_clk_src.clkr,
+ [DPRX_CC_CORE_RCG2_CLK_SRC] = &dprx_0_dprx_cc_core_rcg2_clk_src.clkr,
+ [DPRX_CC_CORE_RCG3_CLK_SRC] = &dprx_0_dprx_cc_core_rcg3_clk_src.clkr,
+
+ [DPRX_CC_MDP_MEM_CLK] = &dprx_0_dprx_cc_mdp_mem_clk.clkr,
+ [DPRX_CC_MMCX_XO_CLK] = &dprx_0_dprx_cc_mmcx_xo_clk.clkr,
+ [DPRX_CC_PLL0] = &dprx_0_dprx_cc_pll0.clkr,
+ [DPRX_CC_PLL1] = &dprx_0_dprx_cc_pll1.clkr,
+ [DPRX_CC_VID_MEM_CLK] = &dprx_0_dprx_cc_vid_mem_clk.clkr,
+};
+
+static const struct qcom_reset_map dprx_cc_0_nord_resets[] = {
+ [DPRX_CC_DPRX_BLK_BCR] = { 0x8000 },
+};
+
+static struct clk_alpha_pll *dprx_cc_0_nord_plls[] = {
+ &dprx_0_dprx_cc_pll0,
+ &dprx_0_dprx_cc_pll1,
+};
+
+static const struct regmap_config dprx_cc_0_nord_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x8104,
+ .fast_io = true,
+};
+
+static void dprx_cc_0_nord_regs_configure(struct device *dev, struct regmap *regmap)
+{
+ /* Configure dividers for core audio and AHB clocks. */
+ regmap_update_bits(regmap, DPRX_CC_CORE_AUD_DIV_CFG,
+ DPRX_CC_CORE_AUD_DIV, 0x13);
+ regmap_update_bits(regmap, DPRX_CC_CORE_AHB_DIV_CFG,
+ DPRX_CC_CORE_AHB_DIV, 0x0a);
+}
+
+static const struct qcom_cc_driver_data dprx_cc_0_nord_driver_data = {
+ .alpha_plls = dprx_cc_0_nord_plls,
+ .num_alpha_plls = ARRAY_SIZE(dprx_cc_0_nord_plls),
+ .clk_regs_configure = dprx_cc_0_nord_regs_configure,
+};
+
+static const struct qcom_cc_desc dprx_cc_0_nord_desc = {
+ .config = &dprx_cc_0_nord_regmap_config,
+ .clks = dprx_cc_0_nord_clocks,
+ .num_clks = ARRAY_SIZE(dprx_cc_0_nord_clocks),
+ .resets = dprx_cc_0_nord_resets,
+ .num_resets = ARRAY_SIZE(dprx_cc_0_nord_resets),
+ .use_rpm = true,
+ .driver_data = &dprx_cc_0_nord_driver_data,
+};
+
+static const struct of_device_id dprx_cc_0_nord_match_table[] = {
+ { .compatible = "qcom,nord-dprxcc0" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, dprx_cc_0_nord_match_table);
+
+static int dprx_cc_0_nord_probe(struct platform_device *pdev)
+{
+ return qcom_cc_probe(pdev, &dprx_cc_0_nord_desc);
+}
+
+static struct platform_driver dprx_cc_0_nord_driver = {
+ .probe = dprx_cc_0_nord_probe,
+ .driver = {
+ .name = "dprxcc0-nord",
+ .of_match_table = dprx_cc_0_nord_match_table,
+ },
+};
+
+module_platform_driver(dprx_cc_0_nord_driver);
+
+MODULE_DESCRIPTION("QTI DPRXCC0 NORD Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/qcom/dprxcc1-nord.c b/drivers/clk/qcom/dprxcc1-nord.c
new file mode 100644
index 0000000000000000000000000000000000000000..836ca7cc50d82be3973df8b5d1322fe2dd7cff6d
--- /dev/null
+++ b/drivers/clk/qcom/dprxcc1-nord.c
@@ -0,0 +1,440 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/bits.h>
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,nord-dprxcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "common.h"
+#include "reset.h"
+
+enum {
+ DT_BI_TCXO,
+ DT_AHB_CLK,
+ DT_SLEEP_CLK,
+};
+
+enum {
+ P_BI_TCXO,
+ P_DPRX_1_DPRX_CC_PLL0_OUT_EVEN,
+ P_DPRX_1_DPRX_CC_PLL0_OUT_MAIN,
+ P_DPRX_1_DPRX_CC_PLL0_OUT_ODD,
+ P_DPRX_1_DPRX_CC_PLL1_OUT_EVEN,
+ P_DPRX_1_DPRX_CC_PLL1_OUT_MAIN,
+ P_SLEEP_CLK,
+};
+
+#define DPRX_CC_CORE_AHB_DIV_CFG 0x80b0
+#define DPRX_CC_CORE_AHB_DIV GENMASK(3, 0)
+#define DPRX_CC_CORE_AUD_DIV_CFG 0x80d0
+#define DPRX_CC_CORE_AUD_DIV GENMASK(8, 0)
+
+static const struct pll_vco lucid_ole_vco[] = {
+ { 249600000, 2300000000, 0 },
+};
+
+static const struct pll_vco zonda_ole_vco[] = {
+ { 700000000, 3600000000, 0 },
+};
+
+/* 550.0 MHz Configuration */
+static const struct alpha_pll_config dprx_1_dprx_cc_pll0_config = {
+ .l = 0x1c,
+ .alpha = 0xa555,
+ .config_ctl_val = 0x20485699,
+ .config_ctl_hi_val = 0x00182261,
+ .config_ctl_hi1_val = 0x82aa299c,
+ .test_ctl_val = 0x00000000,
+ .test_ctl_hi_val = 0x00000003,
+ .test_ctl_hi1_val = 0x00009000,
+ .test_ctl_hi2_val = 0x00000034,
+ .user_ctl_val = 0x00000000,
+ .user_ctl_hi_val = 0x00400005,
+};
+
+static struct clk_alpha_pll dprx_1_dprx_cc_pll0 = {
+ .offset = 0x0,
+ .config = &dprx_1_dprx_cc_pll0_config,
+ .vco_table = lucid_ole_vco,
+ .num_vco = ARRAY_SIZE(lucid_ole_vco),
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+ .clkr = {
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_1_dprx_cc_pll0",
+ .parent_data = &(const struct clk_parent_data) {
+ .index = DT_BI_TCXO,
+ },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_lucid_evo_ops,
+ },
+ },
+};
+
+/* 1080.0 MHz Configuration */
+static const struct alpha_pll_config dprx_1_dprx_cc_pll1_config = {
+ .l = 0x38,
+ .alpha = 0x4000000,
+ .config_ctl_val = 0x08240800,
+ .config_ctl_hi_val = 0x05008001,
+ .config_ctl_hi1_val = 0x00000000,
+ .config_ctl_hi2_val = 0x00000000,
+ .user_ctl_val = 0x00000000,
+ .user_ctl_hi_val = 0x02000080,
+};
+
+static struct clk_alpha_pll dprx_1_dprx_cc_pll1 = {
+ .offset = 0x1000,
+ .alpha_width = 28,
+ .config = &dprx_1_dprx_cc_pll1_config,
+ .vco_table = zonda_ole_vco,
+ .num_vco = ARRAY_SIZE(zonda_ole_vco),
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA_OLE],
+ .clkr = {
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_1_dprx_cc_pll1",
+ .parent_data = &(const struct clk_parent_data) {
+ .index = DT_BI_TCXO,
+ },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_zonda_ole_ops,
+ },
+ },
+};
+
+static const struct parent_map dprx_cc_1_parent_map_0[] = {
+ { P_BI_TCXO, 0 },
+ { P_DPRX_1_DPRX_CC_PLL0_OUT_EVEN, 1 },
+ { P_DPRX_1_DPRX_CC_PLL0_OUT_ODD, 2 },
+ { P_DPRX_1_DPRX_CC_PLL0_OUT_MAIN, 4 },
+ { P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data dprx_cc_1_parent_data_0[] = {
+ { .index = DT_BI_TCXO },
+ { .hw = &dprx_1_dprx_cc_pll0.clkr.hw },
+ { .hw = &dprx_1_dprx_cc_pll0.clkr.hw },
+ { .hw = &dprx_1_dprx_cc_pll0.clkr.hw },
+ { .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map dprx_cc_1_parent_map_1[] = {
+ { P_BI_TCXO, 0 },
+ { P_DPRX_1_DPRX_CC_PLL1_OUT_EVEN, 3 },
+ { P_SLEEP_CLK, 5 },
+ { P_DPRX_1_DPRX_CC_PLL1_OUT_MAIN, 6 },
+};
+
+static const struct clk_parent_data dprx_cc_1_parent_data_1[] = {
+ { .index = DT_BI_TCXO },
+ { .hw = &dprx_1_dprx_cc_pll1.clkr.hw },
+ { .index = DT_SLEEP_CLK },
+ { .hw = &dprx_1_dprx_cc_pll1.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_dprx_1_dprx_cc_audio_clk_src[] = {
+ F(216000000, P_DPRX_1_DPRX_CC_PLL1_OUT_MAIN, 5, 0, 0),
+ F(300000000, P_DPRX_1_DPRX_CC_PLL1_OUT_MAIN, 5, 0, 0),
+ F(360000000, P_DPRX_1_DPRX_CC_PLL1_OUT_MAIN, 5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dprx_1_dprx_cc_audio_clk_src = {
+ .cmd_rcgr = 0x80c8,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dprx_cc_1_parent_map_1,
+ .freq_tbl = ftbl_dprx_1_dprx_cc_audio_clk_src,
+ .hw_clk_ctrl = true,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dprx_1_dprx_cc_audio_clk_src",
+ .parent_data = dprx_cc_1_parent_data_1,
+ .num_parents = ARRAY_SIZE(dprx_cc_1_parent_data_1),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_shared_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_dprx_1_dprx_cc_core_rcg0_clk_src[] = {
+ F(220000000, P_DPRX_1_DPRX_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
+ F(440000000, P_DPRX_1_DPRX_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dprx_1_dprx_cc_core_rcg0_clk_src = {
+ .cmd_rcgr = 0x8004,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dprx_cc_1_parent_map_0,
+ .freq_tbl = ftbl_dprx_1_dprx_cc_core_rcg0_clk_src,
+ .hw_clk_ctrl = true,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dprx_1_dprx_cc_core_rcg0_clk_src",
+ .parent_data = dprx_cc_1_parent_data_0,
+ .num_parents = ARRAY_SIZE(dprx_cc_1_parent_data_0),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_shared_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_dprx_1_dprx_cc_core_rcg2_clk_src[] = {
+ F(275000000, P_DPRX_1_DPRX_CC_PLL0_OUT_MAIN, 2, 0, 0),
+ F(440000000, P_DPRX_1_DPRX_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
+ F(550000000, P_DPRX_1_DPRX_CC_PLL0_OUT_MAIN, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dprx_1_dprx_cc_core_rcg2_clk_src = {
+ .cmd_rcgr = 0x8068,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dprx_cc_1_parent_map_0,
+ .freq_tbl = ftbl_dprx_1_dprx_cc_core_rcg2_clk_src,
+ .hw_clk_ctrl = true,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dprx_1_dprx_cc_core_rcg2_clk_src",
+ .parent_data = dprx_cc_1_parent_data_0,
+ .num_parents = ARRAY_SIZE(dprx_cc_1_parent_data_0),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_shared_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_dprx_1_dprx_cc_core_rcg3_clk_src[] = {
+ F(275000000, P_DPRX_1_DPRX_CC_PLL0_OUT_MAIN, 2, 0, 0),
+ F(550000000, P_DPRX_1_DPRX_CC_PLL0_OUT_MAIN, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dprx_1_dprx_cc_core_rcg3_clk_src = {
+ .cmd_rcgr = 0x8098,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dprx_cc_1_parent_map_0,
+ .freq_tbl = ftbl_dprx_1_dprx_cc_core_rcg3_clk_src,
+ .hw_clk_ctrl = true,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dprx_1_dprx_cc_core_rcg3_clk_src",
+ .parent_data = dprx_cc_1_parent_data_0,
+ .num_parents = ARRAY_SIZE(dprx_cc_1_parent_data_0),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_shared_ops,
+ },
+};
+
+static struct clk_regmap_div dprx_1_dprx_cc_core_ahb_div_clk_src = {
+ .reg = 0x80b0,
+ .shift = 0,
+ .width = 4,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dprx_1_dprx_cc_core_ahb_div_clk_src",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dprx_1_dprx_cc_core_rcg3_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_regmap_div_ro_ops,
+ },
+};
+
+static struct clk_regmap_div dprx_1_dprx_cc_core_aud_div_clk_src = {
+ .reg = 0x80d0,
+ .shift = 0,
+ .width = 9,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dprx_1_dprx_cc_core_aud_div_clk_src",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dprx_1_dprx_cc_audio_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_regmap_div_ro_ops,
+ },
+};
+
+static struct clk_branch dprx_1_dprx_cc_ahb_clk = {
+ .halt_reg = 0x80b4,
+ .halt_check = BRANCH_HALT_VOTED,
+ .hwcg_reg = 0x80b4,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x80b4,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_1_dprx_cc_ahb_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dprx_1_dprx_cc_core_ahb_div_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dprx_1_dprx_cc_aud_clk = {
+ .halt_reg = 0x80d4,
+ .halt_check = BRANCH_HALT_VOTED,
+ .hwcg_reg = 0x80d4,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x80d4,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_1_dprx_cc_aud_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dprx_1_dprx_cc_core_aud_div_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dprx_1_dprx_cc_mdp_mem_clk = {
+ .halt_reg = 0x8088,
+ .halt_check = BRANCH_HALT_VOTED,
+ .hwcg_reg = 0x8088,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x8088,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_1_dprx_cc_mdp_mem_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dprx_1_dprx_cc_core_rcg2_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dprx_1_dprx_cc_mmcx_xo_clk = {
+ .halt_reg = 0x80d8,
+ .halt_check = BRANCH_HALT_VOTED,
+ .hwcg_reg = 0x80d8,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x80d8,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_1_dprx_cc_mmcx_xo_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dprx_1_dprx_cc_vid_mem_clk = {
+ .halt_reg = 0x8028,
+ .halt_check = BRANCH_HALT_VOTED,
+ .hwcg_reg = 0x8028,
+ .hwcg_bit = 1,
+ .clkr = {
+ .enable_reg = 0x8028,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dprx_1_dprx_cc_vid_mem_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dprx_1_dprx_cc_core_rcg0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_regmap *dprx_cc_1_nord_clocks[] = {
+ [DPRX_CC_AHB_CLK] = &dprx_1_dprx_cc_ahb_clk.clkr,
+ [DPRX_CC_AUD_CLK] = &dprx_1_dprx_cc_aud_clk.clkr,
+ [DPRX_CC_AUDIO_CLK_SRC] = &dprx_1_dprx_cc_audio_clk_src.clkr,
+ [DPRX_CC_CORE_AHB_DIV_CLK_SRC] = &dprx_1_dprx_cc_core_ahb_div_clk_src.clkr,
+ [DPRX_CC_CORE_AUD_DIV_CLK_SRC] = &dprx_1_dprx_cc_core_aud_div_clk_src.clkr,
+ [DPRX_CC_CORE_RCG0_CLK_SRC] = &dprx_1_dprx_cc_core_rcg0_clk_src.clkr,
+ [DPRX_CC_CORE_RCG2_CLK_SRC] = &dprx_1_dprx_cc_core_rcg2_clk_src.clkr,
+ [DPRX_CC_CORE_RCG3_CLK_SRC] = &dprx_1_dprx_cc_core_rcg3_clk_src.clkr,
+ [DPRX_CC_MDP_MEM_CLK] = &dprx_1_dprx_cc_mdp_mem_clk.clkr,
+ [DPRX_CC_MMCX_XO_CLK] = &dprx_1_dprx_cc_mmcx_xo_clk.clkr,
+ [DPRX_CC_PLL0] = &dprx_1_dprx_cc_pll0.clkr,
+ [DPRX_CC_PLL1] = &dprx_1_dprx_cc_pll1.clkr,
+ [DPRX_CC_VID_MEM_CLK] = &dprx_1_dprx_cc_vid_mem_clk.clkr,
+};
+
+static const struct qcom_reset_map dprx_cc_1_nord_resets[] = {
+ [DPRX_CC_DPRX_BLK_BCR] = { 0x8000 },
+};
+
+static struct clk_alpha_pll *dprx_cc_1_nord_plls[] = {
+ &dprx_1_dprx_cc_pll0,
+ &dprx_1_dprx_cc_pll1,
+};
+
+static const struct regmap_config dprx_cc_1_nord_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x8104,
+ .fast_io = true,
+};
+
+static void dprx_cc_1_nord_regs_configure(struct device *dev, struct regmap *regmap)
+{
+ /* Configure dividers for core audio and AHB clocks. */
+ regmap_update_bits(regmap, DPRX_CC_CORE_AUD_DIV_CFG,
+ DPRX_CC_CORE_AUD_DIV, 0x13);
+ regmap_update_bits(regmap, DPRX_CC_CORE_AHB_DIV_CFG,
+ DPRX_CC_CORE_AHB_DIV, 0x0a);
+}
+
+static const struct qcom_cc_driver_data dprx_cc_1_nord_driver_data = {
+ .alpha_plls = dprx_cc_1_nord_plls,
+ .num_alpha_plls = ARRAY_SIZE(dprx_cc_1_nord_plls),
+ .clk_regs_configure = dprx_cc_1_nord_regs_configure,
+};
+
+static const struct qcom_cc_desc dprx_cc_1_nord_desc = {
+ .config = &dprx_cc_1_nord_regmap_config,
+ .clks = dprx_cc_1_nord_clocks,
+ .num_clks = ARRAY_SIZE(dprx_cc_1_nord_clocks),
+ .resets = dprx_cc_1_nord_resets,
+ .num_resets = ARRAY_SIZE(dprx_cc_1_nord_resets),
+ .use_rpm = true,
+ .driver_data = &dprx_cc_1_nord_driver_data,
+};
+
+static const struct of_device_id dprx_cc_1_nord_match_table[] = {
+ { .compatible = "qcom,nord-dprxcc1" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, dprx_cc_1_nord_match_table);
+
+static int dprx_cc_1_nord_probe(struct platform_device *pdev)
+{
+ return qcom_cc_probe(pdev, &dprx_cc_1_nord_desc);
+}
+
+static struct platform_driver dprx_cc_1_nord_driver = {
+ .probe = dprx_cc_1_nord_probe,
+ .driver = {
+ .name = "dprxcc1-nord",
+ .of_match_table = dprx_cc_1_nord_match_table,
+ },
+};
+
+module_platform_driver(dprx_cc_1_nord_driver);
+
+MODULE_DESCRIPTION("QTI DPRXCC1 NORD Driver");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-10-27 18:09 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-27 18:08 [PATCH v3 0/4] clk: qcom: Add Nord DPRX clock controller support Taniya Das
2026-10-27 18:08 ` [PATCH v3 1/4] clk: qcom: clk-alpha-pll: fix Zonda L value rounding Taniya Das
2026-10-27 18:08 ` [PATCH v3 2/4] clk: qcom: clk-alpha-pll: support a 28-bit ALPHA_VAL width Taniya Das
2026-10-27 18:08 ` [PATCH v3 3/4] dt-bindings: clock: qcom: document the Nord DPRX Clock Controller Taniya Das
2026-10-27 18:08 ` [PATCH v3 4/4] clk: qcom: dprxcc: Add Nord DPRX clock controller support Taniya Das
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®