* [PATCH 0/2] clk: qcom: Add SM7250 display clock controller
@ 2026-10-23 10:18 Ishu Brar via B4 Relay
2026-10-23 10:18 ` [PATCH 1/2] dt-bindings: clock: qcom: Document the " Ishu Brar via B4 Relay
2026-10-23 10:18 ` [PATCH 2/2] clk: qcom: Add SM7250 display clock controller driver Ishu Brar via B4 Relay
0 siblings, 2 replies; 7+ messages in thread
From: Ishu Brar via B4 Relay @ 2026-10-23 10:18 UTC (permalink / raw)
To: Bjorn Andersson, Abel Vesa, Stephen Boyd, Brian Masney,
Jerome Brunet, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-clk, devicetree, linux-kernel, Ishu Brar
Add the display clock controller (DISPCC) of the Qualcomm SM7250 SoC
(Snapdragon 765/765G/768G): a binding patch with the header, and the
driver. It provides the MDSS clocks, the MDSS GDSC and the core reset.
Both patches are derived from the SM7150 ones, since the register layout
is the same. The differences are the Lucid PLL and the AHB, MDP and
rotator clocks, which take GPLL0 from the GCC. The PLL settings and the
frequency tables were checked against the downstream driver of the platform.
This series depends on the SM7250 GCC series from Shreeshankar [1] (the
Kconfig symbol SM_GCC_7250 and the GPLL0 parent come from it). The DPU
and MDSS series that follows will use this controller. The SoC devicetree
nodes are not part of this series.
Tested on a OnePlus Nord (a 7.3-rc7 based tree with the GCC series
applied): the controller probes and its clocks and power domain drive the
DSI panel. The DisplayPort clocks and the second DSI link are untested,
because the board has neither. I could not run dt_binding_check on the
binding; I will do that before a next version.
[1] https://lore.kernel.org/r/20261016042432.824-1-sreeshankar0910@gmail.com
Signed-off-by: Ishu Brar <patches@brar.si>
---
Ishu Brar (2):
dt-bindings: clock: qcom: Document the SM7250 display clock controller
clk: qcom: Add SM7250 display clock controller driver
.../bindings/clock/qcom,sm7250-dispcc.yaml | 73 ++
drivers/clk/qcom/Kconfig | 11 +
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/dispcc-sm7250.c | 1009 ++++++++++++++++++++
include/dt-bindings/clock/qcom,sm7250-dispcc.h | 62 ++
5 files changed, 1156 insertions(+)
---
base-commit: f5672a3dff0291d6a45eb0c258b9d2baeb4dc577
change-id: 20261023-dispcc-sm7250-fe31e147540f
prerequisite-message-id: <20261016042432.824-1-sreeshankar0910@gmail.com>
prerequisite-patch-id: 73b48e3c0861782784c45684336c1cb2c8b37852
prerequisite-patch-id: fb97b00b62996e3d3634185a803a33eb545522dd
prerequisite-patch-id: 8190bf61e50dbe2e09859505e8e4d8cb4ab02ddb
prerequisite-patch-id: 8c34692012f724a93c58e1df02338acec497344d
prerequisite-patch-id: 983ca91f160cca12047d9b0829c8cbbf4cc32e98
Best regards,
--
Ishu Brar <patches@brar.si>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] dt-bindings: clock: qcom: Document the SM7250 display clock controller
2026-10-23 10:18 [PATCH 0/2] clk: qcom: Add SM7250 display clock controller Ishu Brar via B4 Relay
@ 2026-10-23 10:18 ` Ishu Brar via B4 Relay
2026-10-23 10:38 ` sashiko-bot
2026-10-26 9:35 ` Krzysztof Kozlowski
2026-10-23 10:18 ` [PATCH 2/2] clk: qcom: Add SM7250 display clock controller driver Ishu Brar via B4 Relay
1 sibling, 2 replies; 7+ messages in thread
From: Ishu Brar via B4 Relay @ 2026-10-23 10:18 UTC (permalink / raw)
To: Bjorn Andersson, Abel Vesa, Stephen Boyd, Brian Masney,
Jerome Brunet, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-clk, devicetree, linux-kernel, Ishu Brar
From: Ishu Brar <patches@brar.si>
Add the binding and the header with the clock, reset and GDSC indices
for the display clock controller (DISPCC) of the Qualcomm SM7250 SoC
(Snapdragon 765/765G/768G).
The header and the binding are derived from the SM7150 ones: the register
layout is the same, but the controller takes GPLL0 from the GCC as an
extra parent and has its own PLL.
Assisted-by: Claude
Signed-off-by: Ishu Brar <patches@brar.si>
---
.../bindings/clock/qcom,sm7250-dispcc.yaml | 73 ++++++++++++++++++++++
include/dt-bindings/clock/qcom,sm7250-dispcc.h | 62 ++++++++++++++++++
2 files changed, 135 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/qcom,sm7250-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm7250-dispcc.yaml
new file mode 100644
index 000000000..684aaf7bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,sm7250-dispcc.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sm7250-dispcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Display Clock & Reset Controller for SM7250
+
+maintainers:
+ - Ishu Brar <patches@brar.si>
+
+description: |
+ Qualcomm display clock control module provides the clocks, resets and power
+ domains on SM7250.
+
+ See also: include/dt-bindings/clock/qcom,sm7250-dispcc.h
+
+properties:
+ compatible:
+ const: qcom,sm7250-dispcc
+
+ clocks:
+ items:
+ - description: Board XO source
+ - description: Board Always On XO source
+ - description: GPLL0 source from GCC
+ - description: Sleep clock source
+ - description: Byte clock from MDSS DSI PHY0
+ - description: Pixel clock from MDSS DSI PHY0
+ - description: Byte clock from MDSS DSI PHY1
+ - description: Pixel clock from MDSS DSI PHY1
+ - description: Link clock from DP PHY
+ - description: VCO DIV clock from DP PHY
+
+ power-domains:
+ maxItems: 1
+ description:
+ CX power domain.
+
+required:
+ - compatible
+ - clocks
+ - power-domains
+
+allOf:
+ - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,sm7250-gcc.h>
+ #include <dt-bindings/clock/qcom,rpmh.h>
+ #include <dt-bindings/power/qcom,rpmhpd.h>
+ clock-controller@af00000 {
+ compatible = "qcom,sm7250-dispcc";
+ reg = <0x0af00000 0x20000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&rpmhcc RPMH_CXO_CLK_A>,
+ <&gcc GCC_DISP_GPLL0_CLK_SRC>,
+ <&sleep_clk>,
+ <&mdss_dsi0_phy 0>,
+ <&mdss_dsi0_phy 1>,
+ <&mdss_dsi1_phy 0>,
+ <&mdss_dsi1_phy 1>,
+ <&dp_phy 0>,
+ <&dp_phy 1>;
+ power-domains = <&rpmhpd RPMHPD_CX>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+...
diff --git a/include/dt-bindings/clock/qcom,sm7250-dispcc.h b/include/dt-bindings/clock/qcom,sm7250-dispcc.h
new file mode 100644
index 000000000..907f4122c
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,sm7250-dispcc.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com>
+ * Copyright (c) 2024, David Wronek <david@mainlining.org>
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_DISPCC_SM7250_H
+#define _DT_BINDINGS_CLK_QCOM_DISPCC_SM7250_H
+
+/* DISPCC clock registers */
+#define DISPCC_PLL0 0
+#define DISPCC_MDSS_AHB_CLK 1
+#define DISPCC_MDSS_AHB_CLK_SRC 2
+#define DISPCC_MDSS_BYTE0_CLK 3
+#define DISPCC_MDSS_BYTE0_CLK_SRC 4
+#define DISPCC_MDSS_BYTE0_DIV_CLK_SRC 5
+#define DISPCC_MDSS_BYTE0_INTF_CLK 6
+#define DISPCC_MDSS_BYTE1_CLK 7
+#define DISPCC_MDSS_BYTE1_CLK_SRC 8
+#define DISPCC_MDSS_BYTE1_DIV_CLK_SRC 9
+#define DISPCC_MDSS_BYTE1_INTF_CLK 10
+#define DISPCC_MDSS_DP_AUX_CLK 11
+#define DISPCC_MDSS_DP_AUX_CLK_SRC 12
+#define DISPCC_MDSS_DP_CRYPTO_CLK 13
+#define DISPCC_MDSS_DP_CRYPTO_CLK_SRC 14
+#define DISPCC_MDSS_DP_LINK_CLK 15
+#define DISPCC_MDSS_DP_LINK_CLK_SRC 16
+#define DISPCC_MDSS_DP_LINK_INTF_CLK 17
+#define DISPCC_MDSS_DP_PIXEL1_CLK 18
+#define DISPCC_MDSS_DP_PIXEL1_CLK_SRC 19
+#define DISPCC_MDSS_DP_PIXEL_CLK 20
+#define DISPCC_MDSS_DP_PIXEL_CLK_SRC 21
+#define DISPCC_MDSS_ESC0_CLK 22
+#define DISPCC_MDSS_ESC0_CLK_SRC 23
+#define DISPCC_MDSS_ESC1_CLK 24
+#define DISPCC_MDSS_ESC1_CLK_SRC 25
+#define DISPCC_MDSS_MDP_CLK 26
+#define DISPCC_MDSS_MDP_CLK_SRC 27
+#define DISPCC_MDSS_MDP_LUT_CLK 28
+#define DISPCC_MDSS_NON_GDSC_AHB_CLK 29
+#define DISPCC_MDSS_PCLK0_CLK 30
+#define DISPCC_MDSS_PCLK0_CLK_SRC 31
+#define DISPCC_MDSS_PCLK1_CLK 32
+#define DISPCC_MDSS_PCLK1_CLK_SRC 33
+#define DISPCC_MDSS_ROT_CLK 34
+#define DISPCC_MDSS_ROT_CLK_SRC 35
+#define DISPCC_MDSS_RSCC_AHB_CLK 36
+#define DISPCC_MDSS_RSCC_VSYNC_CLK 37
+#define DISPCC_MDSS_VSYNC_CLK 38
+#define DISPCC_MDSS_VSYNC_CLK_SRC 39
+#define DISPCC_XO_CLK_SRC 40
+#define DISPCC_SLEEP_CLK 41
+#define DISPCC_SLEEP_CLK_SRC 42
+
+/* DISPCC resets */
+#define DISPCC_MDSS_CORE_BCR 0
+
+/* DISPCC GDSCR */
+#define MDSS_GDSC 0
+
+#endif
--
2.56.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] clk: qcom: Add SM7250 display clock controller driver
2026-10-23 10:18 [PATCH 0/2] clk: qcom: Add SM7250 display clock controller Ishu Brar via B4 Relay
2026-10-23 10:18 ` [PATCH 1/2] dt-bindings: clock: qcom: Document the " Ishu Brar via B4 Relay
@ 2026-10-23 10:18 ` Ishu Brar via B4 Relay
2026-10-23 10:55 ` sashiko-bot
2026-10-26 11:39 ` Taniya Das
1 sibling, 2 replies; 7+ messages in thread
From: Ishu Brar via B4 Relay @ 2026-10-23 10:18 UTC (permalink / raw)
To: Bjorn Andersson, Abel Vesa, Stephen Boyd, Brian Masney,
Jerome Brunet, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-clk, devicetree, linux-kernel, Ishu Brar
From: Ishu Brar <patches@brar.si>
Add a driver for the display clock controller of the Qualcomm SM7250
SoC (Snapdragon 765/765G/768G). It provides the MDSS clocks, the MDSS
GDSC and the core reset. The register layout is the same as on SM7150,
which this driver is derived from; the differences are the Lucid PLL, whose
settings come from the downstream driver of the platform, and the AHB, MDP
and rotator clocks, which take GPLL0 from the GCC as a parent.
Tested on a OnePlus Nord: the controller probes and the MDSS clocks and
power domain drive the DSI panel.
Assisted-by: Claude
Signed-off-by: Ishu Brar <patches@brar.si>
---
drivers/clk/qcom/Kconfig | 11 +
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/dispcc-sm7250.c | 1009 ++++++++++++++++++++++++++++++++++++++
3 files changed, 1021 insertions(+)
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 27d0ab24d..503b6aa12 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -1609,6 +1609,17 @@ config SM_DISPCC_7150
Say Y if you want to support display devices and functionality such as
splash screen.
+config SM_DISPCC_7250
+ tristate "SM7250 Display Clock Controller"
+ depends on ARM64 || COMPILE_TEST
+ depends on SM_GCC_7250
+ default m if ARCH_QCOM
+ help
+ Support for the display clock controller on Qualcomm Technologies, Inc
+ SM7250 devices.
+ Say Y if you want to support display devices and functionality such as
+ splash screen.
+
config SM_DISPCC_8250
tristate "SM8150/SM8250/SM8350 Display Clock Controller"
depends on ARM64 || COMPILE_TEST
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 6affb5073..995be8e92 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -181,6 +181,7 @@ obj-$(CONFIG_SM_DISPCC_6125) += dispcc-sm6125.o
obj-$(CONFIG_SM_DISPCC_6350) += dispcc-sm6350.o
obj-$(CONFIG_SM_DISPCC_6375) += dispcc-sm6375.o
obj-$(CONFIG_SM_DISPCC_7150) += dispcc-sm7150.o
+obj-$(CONFIG_SM_DISPCC_7250) += dispcc-sm7250.o
obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
obj-$(CONFIG_SM_DISPCC_8450) += dispcc-sm8450.o
obj-$(CONFIG_SM_DISPCC_8550) += dispcc-sm8550.o
diff --git a/drivers/clk/qcom/dispcc-sm7250.c b/drivers/clk/qcom/dispcc-sm7250.c
new file mode 100644
index 000000000..f114a9f54
--- /dev/null
+++ b/drivers/clk/qcom/dispcc-sm7250.c
@@ -0,0 +1,1009 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com>
+ * Copyright (c) 2024, David Wronek <david@mainlining.org>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,sm7250-dispcc.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 "gdsc.h"
+#include "reset.h"
+
+enum {
+ DT_BI_TCXO,
+ DT_BI_TCXO_AO,
+ DT_GCC_DISP_GPLL0_CLK,
+ DT_CHIP_SLEEP_CLK,
+ DT_DSI0_PHY_PLL_OUT_BYTECLK,
+ DT_DSI0_PHY_PLL_OUT_DSICLK,
+ DT_DSI1_PHY_PLL_OUT_BYTECLK,
+ DT_DSI1_PHY_PLL_OUT_DSICLK,
+ DT_DP_PHY_PLL_LINK_CLK,
+ DT_DP_PHY_PLL_VCO_DIV_CLK,
+};
+
+enum {
+ P_BI_TCXO,
+ P_CHIP_SLEEP_CLK,
+ P_DISPCC_PLL0_OUT_EVEN,
+ P_DISPCC_PLL0_OUT_MAIN,
+ P_DP_PHY_PLL_LINK_CLK,
+ P_DP_PHY_PLL_VCO_DIV_CLK,
+ P_DSI0_PHY_PLL_OUT_BYTECLK,
+ P_DSI0_PHY_PLL_OUT_DSICLK,
+ P_DSI1_PHY_PLL_OUT_BYTECLK,
+ P_DSI1_PHY_PLL_OUT_DSICLK,
+ P_GCC_DISP_GPLL0_CLK,
+};
+
+static const struct pll_vco lucid_vco[] = {
+ { 249600000, 2000000000, 0 },
+};
+
+/* 1035 MHz configuration (19.2 MHz * (0x35 + 0xe800 / 2^16)) */
+static const struct alpha_pll_config dispcc_pll0_config = {
+ .l = 0x35,
+ .cal_l = 0x44,
+ .alpha = 0xe800,
+ .config_ctl_val = 0x20485699,
+ .config_ctl_hi_val = 0x00002261,
+ .config_ctl_hi1_val = 0x329a699c,
+ .user_ctl_val = 0x00000001,
+ .user_ctl_hi_val = 0x00000805,
+ .user_ctl_hi1_val = 0x00000000,
+ .test_ctl_hi1_val = 0x01800000,
+};
+
+static struct clk_alpha_pll dispcc_pll0 = {
+ .offset = 0x0,
+ .vco_table = lucid_vco,
+ .num_vco = ARRAY_SIZE(lucid_vco),
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+ .clkr = {
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_pll0",
+ .parent_data = &(const struct clk_parent_data) {
+ .index = DT_BI_TCXO,
+ },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_lucid_ops,
+ },
+ },
+};
+
+static const struct parent_map dispcc_parent_map_0[] = {
+ { P_BI_TCXO, 0 },
+ { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
+ { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_0[] = {
+ { .index = DT_BI_TCXO },
+ { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
+ { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK },
+};
+
+static const struct parent_map dispcc_parent_map_1[] = {
+ { P_BI_TCXO, 0 },
+ { P_DP_PHY_PLL_LINK_CLK, 1 },
+ { P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_1[] = {
+ { .index = DT_BI_TCXO },
+ { .index = DT_DP_PHY_PLL_LINK_CLK },
+ { .index = DT_DP_PHY_PLL_VCO_DIV_CLK },
+};
+
+static const struct parent_map dispcc_parent_map_2[] = {
+ { P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_2[] = {
+ { .index = DT_BI_TCXO },
+};
+
+static const struct clk_parent_data dispcc_parent_data_2_ao[] = {
+ { .index = DT_BI_TCXO_AO },
+};
+
+static const struct parent_map dispcc_parent_map_3[] = {
+ { P_BI_TCXO, 0 },
+ { P_DISPCC_PLL0_OUT_MAIN, 1 },
+ { P_GCC_DISP_GPLL0_CLK, 4 },
+ { P_DISPCC_PLL0_OUT_EVEN, 5 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_3[] = {
+ { .index = DT_BI_TCXO },
+ { .hw = &dispcc_pll0.clkr.hw },
+ { .index = DT_GCC_DISP_GPLL0_CLK },
+ { .hw = &dispcc_pll0.clkr.hw },
+};
+
+static const struct parent_map dispcc_parent_map_4[] = {
+ { P_BI_TCXO, 0 },
+ { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+ { P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_4[] = {
+ { .index = DT_BI_TCXO },
+ { .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
+ { .index = DT_DSI1_PHY_PLL_OUT_DSICLK },
+};
+
+static const struct parent_map dispcc_parent_map_5[] = {
+ { P_BI_TCXO, 0 },
+ { P_GCC_DISP_GPLL0_CLK, 4 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_5[] = {
+ { .index = DT_BI_TCXO },
+ { .index = DT_GCC_DISP_GPLL0_CLK },
+};
+
+static const struct parent_map dispcc_parent_map_6[] = {
+ { P_CHIP_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_6[] = {
+ { .index = DT_CHIP_SLEEP_CLK },
+};
+
+static const struct freq_tbl ftbl_dispcc_mdss_ahb_clk_src[] = {
+ F(19200000, P_BI_TCXO, 1, 0, 0),
+ F(37500000, P_GCC_DISP_GPLL0_CLK, 16, 0, 0),
+ F(75000000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dispcc_mdss_ahb_clk_src = {
+ .cmd_rcgr = 0x22bc,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_5,
+ .freq_tbl = ftbl_dispcc_mdss_ahb_clk_src,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_ahb_clk_src",
+ .parent_data = dispcc_parent_data_5,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_5),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_shared_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_dispcc_mdss_byte0_clk_src[] = {
+ F(19200000, P_BI_TCXO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dispcc_mdss_byte0_clk_src = {
+ .cmd_rcgr = 0x2110,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_0,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_byte0_clk_src",
+ .parent_data = dispcc_parent_data_0,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_0),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_byte2_ops,
+ },
+};
+
+static struct clk_rcg2 dispcc_mdss_byte1_clk_src = {
+ .cmd_rcgr = 0x212c,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_0,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_byte1_clk_src",
+ .parent_data = dispcc_parent_data_0,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_0),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_byte2_ops,
+ },
+};
+
+static struct clk_rcg2 dispcc_mdss_dp_aux_clk_src = {
+ .cmd_rcgr = 0x21dc,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_2,
+ .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_dp_aux_clk_src",
+ .parent_data = dispcc_parent_data_2,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_2),
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_dispcc_mdss_dp_crypto_clk_src[] = {
+ F(108000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
+ F(180000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
+ F(360000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
+ F(540000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dispcc_mdss_dp_crypto_clk_src = {
+ .cmd_rcgr = 0x2194,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_1,
+ .freq_tbl = ftbl_dispcc_mdss_dp_crypto_clk_src,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_dp_crypto_clk_src",
+ .parent_data = dispcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_1),
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 dispcc_mdss_dp_link_clk_src = {
+ .cmd_rcgr = 0x2178,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_1,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_dp_link_clk_src",
+ .parent_data = dispcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_1),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_byte2_ops,
+ },
+};
+
+static struct clk_rcg2 dispcc_mdss_dp_pixel1_clk_src = {
+ .cmd_rcgr = 0x21c4,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_1,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_dp_pixel1_clk_src",
+ .parent_data = dispcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_1),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_dp_ops,
+ },
+};
+
+static struct clk_rcg2 dispcc_mdss_dp_pixel_clk_src = {
+ .cmd_rcgr = 0x21ac,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_1,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_dp_pixel_clk_src",
+ .parent_data = dispcc_parent_data_1,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_1),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_dp_ops,
+ },
+};
+
+static struct clk_rcg2 dispcc_mdss_esc0_clk_src = {
+ .cmd_rcgr = 0x2148,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_0,
+ .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_esc0_clk_src",
+ .parent_data = dispcc_parent_data_0,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_0),
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 dispcc_mdss_esc1_clk_src = {
+ .cmd_rcgr = 0x2160,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_0,
+ .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_esc1_clk_src",
+ .parent_data = dispcc_parent_data_0,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_0),
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_dispcc_mdss_mdp_clk_src[] = {
+ F(19200000, P_BI_TCXO, 1, 0, 0),
+ F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),
+ F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),
+ F(345000000, P_DISPCC_PLL0_OUT_MAIN, 3, 0, 0),
+ F(460000000, P_DISPCC_PLL0_OUT_MAIN, 3, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dispcc_mdss_mdp_clk_src = {
+ .cmd_rcgr = 0x20c8,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_3,
+ .freq_tbl = ftbl_dispcc_mdss_mdp_clk_src,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_mdp_clk_src",
+ .parent_data = dispcc_parent_data_3,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_3),
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_rcg2_shared_ops,
+ },
+};
+
+static struct clk_rcg2 dispcc_mdss_pclk0_clk_src = {
+ .cmd_rcgr = 0x2098,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_4,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_pclk0_clk_src",
+ .parent_data = dispcc_parent_data_4,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_4),
+ .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+ .ops = &clk_pixel_ops,
+ },
+};
+
+static struct clk_rcg2 dispcc_mdss_pclk1_clk_src = {
+ .cmd_rcgr = 0x20b0,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_4,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_pclk1_clk_src",
+ .parent_data = dispcc_parent_data_4,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_4),
+ .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+ .ops = &clk_pixel_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_dispcc_mdss_rot_clk_src[] = {
+ F(19200000, P_BI_TCXO, 1, 0, 0),
+ F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),
+ F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dispcc_mdss_rot_clk_src = {
+ .cmd_rcgr = 0x20e0,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_3,
+ .freq_tbl = ftbl_dispcc_mdss_rot_clk_src,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_rot_clk_src",
+ .parent_data = dispcc_parent_data_3,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_3),
+ .ops = &clk_rcg2_shared_ops,
+ },
+};
+
+static struct clk_rcg2 dispcc_mdss_vsync_clk_src = {
+ .cmd_rcgr = 0x20f8,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_2,
+ .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_vsync_clk_src",
+ .parent_data = dispcc_parent_data_2,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_2),
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_dispcc_sleep_clk_src[] = {
+ F(32000, P_CHIP_SLEEP_CLK, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 dispcc_sleep_clk_src = {
+ .cmd_rcgr = 0x6060,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_6,
+ .freq_tbl = ftbl_dispcc_sleep_clk_src,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_sleep_clk_src",
+ .parent_data = dispcc_parent_data_6,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_6),
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 dispcc_xo_clk_src = {
+ .cmd_rcgr = 0x6044,
+ .mnd_width = 0,
+ .hid_width = 5,
+ .parent_map = dispcc_parent_map_2,
+ .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
+ .clkr.hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_xo_clk_src",
+ .parent_data = dispcc_parent_data_2_ao,
+ .num_parents = ARRAY_SIZE(dispcc_parent_data_2_ao),
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch dispcc_mdss_ahb_clk = {
+ .halt_reg = 0x2080,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2080,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_ahb_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_ahb_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_byte0_clk = {
+ .halt_reg = 0x2028,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2028,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_byte0_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_byte0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_regmap_div dispcc_mdss_byte0_div_clk_src = {
+ .reg = 0x2128,
+ .shift = 0,
+ .width = 2,
+ .clkr = {
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_byte0_div_clk_src",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_byte0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_regmap_div_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_byte0_intf_clk = {
+ .halt_reg = 0x202c,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x202c,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_byte0_intf_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_byte0_div_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_byte1_clk = {
+ .halt_reg = 0x2030,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2030,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_byte1_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_byte1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_regmap_div dispcc_mdss_byte1_div_clk_src = {
+ .reg = 0x2144,
+ .shift = 0,
+ .width = 2,
+ .clkr = {
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_byte1_div_clk_src",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_byte1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_regmap_div_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_byte1_intf_clk = {
+ .halt_reg = 0x2034,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2034,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_byte1_intf_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_byte1_div_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_dp_aux_clk = {
+ .halt_reg = 0x2054,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2054,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_dp_aux_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_dp_aux_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_dp_crypto_clk = {
+ .halt_reg = 0x2048,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2048,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_dp_crypto_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_dp_crypto_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_dp_link_clk = {
+ .halt_reg = 0x2040,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2040,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_dp_link_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_dp_link_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_dp_link_intf_clk = {
+ .halt_reg = 0x2044,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2044,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_dp_link_intf_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_dp_link_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_dp_pixel1_clk = {
+ .halt_reg = 0x2050,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2050,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_dp_pixel1_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_dp_pixel1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_dp_pixel_clk = {
+ .halt_reg = 0x204c,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x204c,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_dp_pixel_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_dp_pixel_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_esc0_clk = {
+ .halt_reg = 0x2038,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2038,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_esc0_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_esc0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_esc1_clk = {
+ .halt_reg = 0x203c,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x203c,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_esc1_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_esc1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_mdp_clk = {
+ .halt_reg = 0x200c,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x200c,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_mdp_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_mdp_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_mdp_lut_clk = {
+ .halt_reg = 0x201c,
+ .halt_check = BRANCH_VOTED,
+ .clkr = {
+ .enable_reg = 0x201c,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_mdp_lut_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_mdp_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_non_gdsc_ahb_clk = {
+ .halt_reg = 0x4004,
+ .halt_check = BRANCH_VOTED,
+ .clkr = {
+ .enable_reg = 0x4004,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_non_gdsc_ahb_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_ahb_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_pclk0_clk = {
+ .halt_reg = 0x2004,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2004,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_pclk0_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_pclk0_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_pclk1_clk = {
+ .halt_reg = 0x2008,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2008,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_pclk1_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_pclk1_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_rot_clk = {
+ .halt_reg = 0x2014,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2014,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_rot_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_rot_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_rscc_ahb_clk = {
+ .halt_reg = 0x400c,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x400c,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_rscc_ahb_clk",
+ .parent_names = (const char *[]) {
+ "dispcc_mdss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_rscc_vsync_clk = {
+ .halt_reg = 0x4008,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x4008,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_rscc_vsync_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_vsync_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_mdss_vsync_clk = {
+ .halt_reg = 0x2024,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x2024,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_mdss_vsync_clk",
+ .parent_hws = (const struct clk_hw*[]) {
+ &dispcc_mdss_vsync_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch dispcc_sleep_clk = {
+ .halt_reg = 0x6078,
+ .halt_check = BRANCH_HALT,
+ .clkr = {
+ .enable_reg = 0x6078,
+ .enable_mask = BIT(0),
+ .hw.init = &(const struct clk_init_data) {
+ .name = "dispcc_sleep_clk",
+ .parent_names = (const char *[]) {
+ "dispcc_sleep_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct gdsc mdss_gdsc = {
+ .gdscr = 0x3000,
+ .en_rest_wait_val = 0x2,
+ .en_few_wait_val = 0x2,
+ .clk_dis_wait_val = 0xf,
+ .pd = {
+ .name = "mdss_gdsc",
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+ .flags = HW_CTRL,
+};
+
+static struct clk_regmap *dispcc_sm7250_clocks[] = {
+ [DISPCC_MDSS_AHB_CLK] = &dispcc_mdss_ahb_clk.clkr,
+ [DISPCC_MDSS_AHB_CLK_SRC] = &dispcc_mdss_ahb_clk_src.clkr,
+ [DISPCC_MDSS_BYTE0_CLK] = &dispcc_mdss_byte0_clk.clkr,
+ [DISPCC_MDSS_BYTE0_CLK_SRC] = &dispcc_mdss_byte0_clk_src.clkr,
+ [DISPCC_MDSS_BYTE0_DIV_CLK_SRC] = &dispcc_mdss_byte0_div_clk_src.clkr,
+ [DISPCC_MDSS_BYTE0_INTF_CLK] = &dispcc_mdss_byte0_intf_clk.clkr,
+ [DISPCC_MDSS_BYTE1_CLK] = &dispcc_mdss_byte1_clk.clkr,
+ [DISPCC_MDSS_BYTE1_CLK_SRC] = &dispcc_mdss_byte1_clk_src.clkr,
+ [DISPCC_MDSS_BYTE1_DIV_CLK_SRC] = &dispcc_mdss_byte1_div_clk_src.clkr,
+ [DISPCC_MDSS_BYTE1_INTF_CLK] = &dispcc_mdss_byte1_intf_clk.clkr,
+ [DISPCC_MDSS_DP_AUX_CLK] = &dispcc_mdss_dp_aux_clk.clkr,
+ [DISPCC_MDSS_DP_AUX_CLK_SRC] = &dispcc_mdss_dp_aux_clk_src.clkr,
+ [DISPCC_MDSS_DP_CRYPTO_CLK] = &dispcc_mdss_dp_crypto_clk.clkr,
+ [DISPCC_MDSS_DP_CRYPTO_CLK_SRC] = &dispcc_mdss_dp_crypto_clk_src.clkr,
+ [DISPCC_MDSS_DP_LINK_CLK] = &dispcc_mdss_dp_link_clk.clkr,
+ [DISPCC_MDSS_DP_LINK_CLK_SRC] = &dispcc_mdss_dp_link_clk_src.clkr,
+ [DISPCC_MDSS_DP_LINK_INTF_CLK] = &dispcc_mdss_dp_link_intf_clk.clkr,
+ [DISPCC_MDSS_DP_PIXEL1_CLK] = &dispcc_mdss_dp_pixel1_clk.clkr,
+ [DISPCC_MDSS_DP_PIXEL1_CLK_SRC] = &dispcc_mdss_dp_pixel1_clk_src.clkr,
+ [DISPCC_MDSS_DP_PIXEL_CLK] = &dispcc_mdss_dp_pixel_clk.clkr,
+ [DISPCC_MDSS_DP_PIXEL_CLK_SRC] = &dispcc_mdss_dp_pixel_clk_src.clkr,
+ [DISPCC_MDSS_ESC0_CLK] = &dispcc_mdss_esc0_clk.clkr,
+ [DISPCC_MDSS_ESC0_CLK_SRC] = &dispcc_mdss_esc0_clk_src.clkr,
+ [DISPCC_MDSS_ESC1_CLK] = &dispcc_mdss_esc1_clk.clkr,
+ [DISPCC_MDSS_ESC1_CLK_SRC] = &dispcc_mdss_esc1_clk_src.clkr,
+ [DISPCC_MDSS_MDP_CLK] = &dispcc_mdss_mdp_clk.clkr,
+ [DISPCC_MDSS_MDP_CLK_SRC] = &dispcc_mdss_mdp_clk_src.clkr,
+ [DISPCC_MDSS_MDP_LUT_CLK] = &dispcc_mdss_mdp_lut_clk.clkr,
+ [DISPCC_MDSS_NON_GDSC_AHB_CLK] = &dispcc_mdss_non_gdsc_ahb_clk.clkr,
+ [DISPCC_MDSS_PCLK0_CLK] = &dispcc_mdss_pclk0_clk.clkr,
+ [DISPCC_MDSS_PCLK0_CLK_SRC] = &dispcc_mdss_pclk0_clk_src.clkr,
+ [DISPCC_MDSS_PCLK1_CLK] = &dispcc_mdss_pclk1_clk.clkr,
+ [DISPCC_MDSS_PCLK1_CLK_SRC] = &dispcc_mdss_pclk1_clk_src.clkr,
+ [DISPCC_MDSS_ROT_CLK] = &dispcc_mdss_rot_clk.clkr,
+ [DISPCC_MDSS_ROT_CLK_SRC] = &dispcc_mdss_rot_clk_src.clkr,
+ [DISPCC_MDSS_RSCC_AHB_CLK] = &dispcc_mdss_rscc_ahb_clk.clkr,
+ [DISPCC_MDSS_RSCC_VSYNC_CLK] = &dispcc_mdss_rscc_vsync_clk.clkr,
+ [DISPCC_MDSS_VSYNC_CLK] = &dispcc_mdss_vsync_clk.clkr,
+ [DISPCC_MDSS_VSYNC_CLK_SRC] = &dispcc_mdss_vsync_clk_src.clkr,
+ [DISPCC_PLL0] = &dispcc_pll0.clkr,
+ [DISPCC_SLEEP_CLK] = &dispcc_sleep_clk.clkr,
+ [DISPCC_SLEEP_CLK_SRC] = &dispcc_sleep_clk_src.clkr,
+ [DISPCC_XO_CLK_SRC] = &dispcc_xo_clk_src.clkr,
+};
+
+static struct gdsc *dispcc_sm7250_gdscs[] = {
+ [MDSS_GDSC] = &mdss_gdsc,
+};
+
+static const struct qcom_reset_map dispcc_sm7250_resets[] = {
+ [DISPCC_MDSS_CORE_BCR] = { 0x2000 },
+};
+
+static const struct regmap_config dispcc_sm7250_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x10000,
+ .fast_io = true,
+};
+
+static const struct qcom_cc_desc dispcc_sm7250_desc = {
+ .config = &dispcc_sm7250_regmap_config,
+ .clks = dispcc_sm7250_clocks,
+ .num_clks = ARRAY_SIZE(dispcc_sm7250_clocks),
+ .gdscs = dispcc_sm7250_gdscs,
+ .num_gdscs = ARRAY_SIZE(dispcc_sm7250_gdscs),
+ .resets = dispcc_sm7250_resets,
+ .num_resets = ARRAY_SIZE(dispcc_sm7250_resets),
+};
+
+static const struct of_device_id dispcc_sm7250_match_table[] = {
+ { .compatible = "qcom,sm7250-dispcc" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, dispcc_sm7250_match_table);
+
+static int dispcc_sm7250_probe(struct platform_device *pdev)
+{
+ struct regmap *regmap;
+
+ regmap = qcom_cc_map(pdev, &dispcc_sm7250_desc);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ clk_lucid_pll_configure(&dispcc_pll0, regmap, &dispcc_pll0_config);
+ /* Enable clock gating for DSI and MDP clocks */
+ regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0);
+
+ /* Keep some clocks always-on */
+ qcom_branch_set_clk_en(regmap, 0x605c); /* DISPCC_XO_CLK */
+
+ return qcom_cc_really_probe(&pdev->dev, &dispcc_sm7250_desc, regmap);
+}
+
+static struct platform_driver dispcc_sm7250_driver = {
+ .probe = dispcc_sm7250_probe,
+ .driver = {
+ .name = "dispcc-sm7250",
+ .of_match_table = dispcc_sm7250_match_table,
+ },
+};
+
+module_platform_driver(dispcc_sm7250_driver);
+
+MODULE_DESCRIPTION("Qualcomm SM7250 Display Clock Controller");
+MODULE_LICENSE("GPL");
--
2.56.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] dt-bindings: clock: qcom: Document the SM7250 display clock controller
2026-10-23 10:18 ` [PATCH 1/2] dt-bindings: clock: qcom: Document the " Ishu Brar via B4 Relay
@ 2026-10-23 10:38 ` sashiko-bot
2026-10-26 9:35 ` Krzysztof Kozlowski
1 sibling, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-10-23 10:38 UTC (permalink / raw)
To: Ishu Brar; +Cc: linux-clk, devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] dt-bindings: clock: qcom: duplicate SM7150 DISPCC schema and header for SM7250
- [Medium] dt-bindings: clock: qcom: missing #power-domain-cells in sm7250-dispcc required
--
commit 38f912b989d9f04661892eb5bd0bbd2206b4f767
Author: Ishu Brar <patches@brar.si>
dt-bindings: clock: qcom: Document the SM7250 display clock controller
This commit adds the Device Tree binding schema and dt-bindings header for
the Qualcomm SM7250 display clock controller (DISPCC).
> diff --git a/Documentation/devicetree/bindings/clock/qcom,sm7250-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm7250-dispcc.yaml
> new file mode 100644
> index 0000000000000..684aaf7bb6b48
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/qcom,sm7250-dispcc.yaml
> @@ -0,0 +1,73 @@
[ ... ]
> +properties:
> + compatible:
> + const: qcom,sm7250-dispcc
> +
> + clocks:
> + items:
> + - description: Board XO source
> + - description: Board Always On XO source
> + - description: GPLL0 source from GCC
> + - description: Sleep clock source
> + - description: Byte clock from MDSS DSI PHY0
> + - description: Pixel clock from MDSS DSI PHY0
> + - description: Byte clock from MDSS DSI PHY1
> + - description: Pixel clock from MDSS DSI PHY1
> + - description: Link clock from DP PHY
> + - description: VCO DIV clock from DP PHY
> +
> + power-domains:
> + maxItems: 1
> + description:
> + CX power domain.
> +
> +required:
> + - compatible
> + - clocks
> + - power-domains
> +
> +allOf:
> + - $ref: qcom,gcc.yaml#
[Severity: Medium]
Should #power-domain-cells also be listed under required in
Documentation/devicetree/bindings/clock/qcom,sm7250-dispcc.yaml?
The SM7250 DISPCC provides the MDSS_GDSC power domain, and the example node
includes #power-domain-cells = <1>.
However, since commit b0ef3434da07 ("dt-bindings: clock: qcom,gcc: sort out
power-domains support"), Documentation/devicetree/bindings/clock/qcom,gcc.yaml
only lists reg, #clock-cells, and #reset-cells under required:
required:
- reg
- '#clock-cells'
- '#reset-cells'
Without '#power-domain-cells' in required here, a qcom,sm7250-dispcc device
tree node that omits #power-domain-cells will pass dt_binding_check
validation and fail at runtime when consumers reference MDSS_GDSC.
[ ... ]
> diff --git a/include/dt-bindings/clock/qcom,sm7250-dispcc.h b/include/dt-bindings/clock/qcom,sm7250-dispcc.h
> new file mode 100644
> index 0000000000000..907f4122cb19b
> --- /dev/null
> +++ b/include/dt-bindings/clock/qcom,sm7250-dispcc.h
> @@ -0,0 +1,62 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
> +/*
> + * Copyright (c) 2018, The Linux Foundation. All rights reserved.
> + * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com>
> + * Copyright (c) 2024, David Wronek <david@mainlining.org>
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_QCOM_DISPCC_SM7250_H
> +#define _DT_BINDINGS_CLK_QCOM_DISPCC_SM7250_H
> +
> +/* DISPCC clock registers */
> +#define DISPCC_PLL0 0
> +#define DISPCC_MDSS_AHB_CLK 1
[Severity: Medium]
Could qcom,sm7250-dispcc be added to the existing
Documentation/devicetree/bindings/clock/qcom,sm7150-dispcc.yaml schema and
share include/dt-bindings/clock/qcom,sm7150-dispcc.h instead of duplicating
both files?
The commit message notes:
The header and the binding are derived from the SM7150 ones: the register
layout is the same, but the controller takes GPLL0 from the GCC as an
extra parent and has its own PLL.
However, Documentation/devicetree/bindings/clock/qcom,sm7150-dispcc.yaml
already defines the exact same properties, including "GPLL0 source from GCC"
(<&gcc GCC_DISP_GPLL0_CLK_SRC>) as the third clock item, the same 10 input
clocks in the same order, and the same CX power domain:
properties:
compatible:
const: qcom,sm7150-dispcc
clocks:
items:
- description: Board XO source
- description: Board Always On XO source
- description: GPLL0 source from GCC
- description: Sleep clock source
- description: Byte clock from MDSS DSI PHY0
- description: Pixel clock from MDSS DSI PHY0
- description: Byte clock from MDSS DSI PHY1
- description: Pixel clock from MDSS DSI PHY1
- description: Link clock from DP PHY
- description: VCO DIV clock from DP PHY
Likewise, include/dt-bindings/clock/qcom,sm7150-dispcc.h already defines
DISPCC_PLL0 as 0 along with the exact same 43 clock indices,
DISPCC_MDSS_CORE_BCR, and MDSS_GDSC, making
include/dt-bindings/clock/qcom,sm7250-dispcc.h a verbatim copy apart from
the header guard.
Similar Qualcomm clock bindings have been consolidated into existing schemas
(for example, commits 0e094dd19e04 and 67044b2df840 merging SM7150 and
SM7250 GCC into qcom,sm6375-gcc.yaml, and commit c984dde8f3f8 dropping the
duplicate SM8650 DISPCC schema in favor of qcom,sm8550-dispcc.yaml).
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261023-dispcc-sm7250-v1-0-07bdefb99801@brar.si?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] clk: qcom: Add SM7250 display clock controller driver
2026-10-23 10:18 ` [PATCH 2/2] clk: qcom: Add SM7250 display clock controller driver Ishu Brar via B4 Relay
@ 2026-10-23 10:55 ` sashiko-bot
2026-10-26 11:39 ` Taniya Das
1 sibling, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-10-23 10:55 UTC (permalink / raw)
To: Ishu Brar; +Cc: linux-clk, devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] clk: qcom: dispcc-sm7250: missing CLK_SET_RATE_PARENT on byte0_intf_clk
--
commit ab220a77d171c816d3d394b53d2f36fed1ff7979
Author: Ishu Brar <patches@brar.si>
clk: qcom: Add SM7250 display clock controller driver
This commit adds the display clock controller driver for the Qualcomm SM7250
SoC, providing MDSS clocks, the MDSS GDSC, and the core reset.
> diff --git a/drivers/clk/qcom/dispcc-sm7250.c b/drivers/clk/qcom/dispcc-sm7250.c
> new file mode 100644
> index 0000000000000..f114a9f5407ef
> --- /dev/null
> +++ b/drivers/clk/qcom/dispcc-sm7250.c
[ ... ]
> +static struct clk_regmap_div dispcc_mdss_byte0_div_clk_src = {
> + .reg = 0x2128,
> + .shift = 0,
> + .width = 2,
> + .clkr = {
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_byte0_div_clk_src",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_byte0_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .ops = &clk_regmap_div_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_byte0_intf_clk = {
> + .halt_reg = 0x202c,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x202c,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_byte0_intf_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_byte0_div_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
[Severity: Medium]
Should dispcc_mdss_byte0_intf_clk in drivers/clk/qcom/dispcc-sm7250.c set
.flags = CLK_SET_RATE_PARENT, matching dispcc_mdss_byte1_intf_clk right below
it?
During DSI0 power-on, msm_dsi_host_power_on() -> dsi_link_clk_set_rate_6g()
in drivers/gpu/drm/msm/dsi/dsi_host.c configures the byte interface clock:
if (msm_host->byte_intf_clk) {
ret = clk_set_rate(msm_host->byte_intf_clk, msm_host->byte_intf_clk_rate);
if (ret) {
pr_err("%s: Failed to set rate byte intf clk, %d\n",
__func__, ret);
return ret;
}
}
Because dispcc_mdss_byte0_intf_clk uses clk_branch2_ops and omits
CLK_SET_RATE_PARENT, clk_core_round_rate_nolock() and clk_calc_new_rates() in
drivers/clk/clk.c treat it as a pass-through clock without an adjustable
parent and return 0 without forwarding the rate change to
dispcc_mdss_byte0_div_clk_src (register 0x2128), leaving the DSI0 byte
interface divider unconfigured when a non-default divider is needed.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261023-dispcc-sm7250-v1-0-07bdefb99801@brar.si?part=2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] dt-bindings: clock: qcom: Document the SM7250 display clock controller
2026-10-23 10:18 ` [PATCH 1/2] dt-bindings: clock: qcom: Document the " Ishu Brar via B4 Relay
2026-10-23 10:38 ` sashiko-bot
@ 2026-10-26 9:35 ` Krzysztof Kozlowski
1 sibling, 0 replies; 7+ messages in thread
From: Krzysztof Kozlowski @ 2026-10-26 9:35 UTC (permalink / raw)
To: Ishu Brar
Cc: Bjorn Andersson, Abel Vesa, Stephen Boyd, Brian Masney,
Jerome Brunet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
linux-arm-msm, linux-clk, devicetree, linux-kernel
On Fri, Oct 23, 2026 at 03:48:24PM +0530, Ishu Brar wrote:
> Add the binding and the header with the clock, reset and GDSC indices
> for the display clock controller (DISPCC) of the Qualcomm SM7250 SoC
> (Snapdragon 765/765G/768G).
>
> The header and the binding are derived from the SM7150 ones: the register
> layout is the same, but the controller takes GPLL0 from the GCC as an
> extra parent and has its own PLL.
>
> Assisted-by: Claude
Same comments.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] clk: qcom: Add SM7250 display clock controller driver
2026-10-23 10:18 ` [PATCH 2/2] clk: qcom: Add SM7250 display clock controller driver Ishu Brar via B4 Relay
2026-10-23 10:55 ` sashiko-bot
@ 2026-10-26 11:39 ` Taniya Das
1 sibling, 0 replies; 7+ messages in thread
From: Taniya Das @ 2026-10-26 11:39 UTC (permalink / raw)
To: patches, Bjorn Andersson, Abel Vesa, Stephen Boyd, Brian Masney,
Jerome Brunet, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-clk, devicetree, linux-kernel
On 10/23/2026 3:48 PM, Ishu Brar via B4 Relay wrote:
> From: Ishu Brar <patches@brar.si>
>
> Add a driver for the display clock controller of the Qualcomm SM7250
> SoC (Snapdragon 765/765G/768G). It provides the MDSS clocks, the MDSS
> GDSC and the core reset. The register layout is the same as on SM7150,
> which this driver is derived from; the differences are the Lucid PLL, whose
> settings come from the downstream driver of the platform, and the AHB, MDP
> and rotator clocks, which take GPLL0 from the GCC as a parent.
>
> Tested on a OnePlus Nord: the controller probes and the MDSS clocks and
> power domain drive the DSI panel.
>
> Assisted-by: Claude
> Signed-off-by: Ishu Brar <patches@brar.si>
> ---
> drivers/clk/qcom/Kconfig | 11 +
> drivers/clk/qcom/Makefile | 1 +
> drivers/clk/qcom/dispcc-sm7250.c | 1009 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 1021 insertions(+)
>
> diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
> index 27d0ab24d..503b6aa12 100644
> --- a/drivers/clk/qcom/Kconfig
> +++ b/drivers/clk/qcom/Kconfig
> @@ -1609,6 +1609,17 @@ config SM_DISPCC_7150
> Say Y if you want to support display devices and functionality such as
> splash screen.
>
> +config SM_DISPCC_7250
> + tristate "SM7250 Display Clock Controller"
> + depends on ARM64 || COMPILE_TEST
> + depends on SM_GCC_7250
select GCC driver> + default m if ARCH_QCOM
> + help
> + Support for the display clock controller on Qualcomm Technologies, Inc
> + SM7250 devices.
> + Say Y if you want to support display devices and functionality such as
> + splash screen.
> +
> config SM_DISPCC_8250
> tristate "SM8150/SM8250/SM8350 Display Clock Controller"
> depends on ARM64 || COMPILE_TEST
> diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
> index 6affb5073..995be8e92 100644
> --- a/drivers/clk/qcom/Makefile
> +++ b/drivers/clk/qcom/Makefile
> @@ -181,6 +181,7 @@ obj-$(CONFIG_SM_DISPCC_6125) += dispcc-sm6125.o
> obj-$(CONFIG_SM_DISPCC_6350) += dispcc-sm6350.o
> obj-$(CONFIG_SM_DISPCC_6375) += dispcc-sm6375.o
> obj-$(CONFIG_SM_DISPCC_7150) += dispcc-sm7150.o
> +obj-$(CONFIG_SM_DISPCC_7250) += dispcc-sm7250.o
> obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
> obj-$(CONFIG_SM_DISPCC_8450) += dispcc-sm8450.o
> obj-$(CONFIG_SM_DISPCC_8550) += dispcc-sm8550.o
> diff --git a/drivers/clk/qcom/dispcc-sm7250.c b/drivers/clk/qcom/dispcc-sm7250.c
> new file mode 100644
> index 000000000..f114a9f54
> --- /dev/null
> +++ b/drivers/clk/qcom/dispcc-sm7250.c
> @@ -0,0 +1,1009 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
> + * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com>
> + * Copyright (c) 2024, David Wronek <david@mainlining.org>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#include <dt-bindings/clock/qcom,sm7250-dispcc.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 "gdsc.h"
> +#include "reset.h"
> +
> +enum {
> + DT_BI_TCXO,
> + DT_BI_TCXO_AO,
This should not be required.
> + DT_GCC_DISP_GPLL0_CLK,
> + DT_CHIP_SLEEP_CLK,
> + DT_DSI0_PHY_PLL_OUT_BYTECLK,
> + DT_DSI0_PHY_PLL_OUT_DSICLK,
> + DT_DSI1_PHY_PLL_OUT_BYTECLK,
> + DT_DSI1_PHY_PLL_OUT_DSICLK,
> + DT_DP_PHY_PLL_LINK_CLK,
> + DT_DP_PHY_PLL_VCO_DIV_CLK,
> +};
> +
> +enum {
> + P_BI_TCXO,
> + P_CHIP_SLEEP_CLK,
> + P_DISPCC_PLL0_OUT_EVEN,
> + P_DISPCC_PLL0_OUT_MAIN,
> + P_DP_PHY_PLL_LINK_CLK,
> + P_DP_PHY_PLL_VCO_DIV_CLK,
> + P_DSI0_PHY_PLL_OUT_BYTECLK,
> + P_DSI0_PHY_PLL_OUT_DSICLK,
> + P_DSI1_PHY_PLL_OUT_BYTECLK,
> + P_DSI1_PHY_PLL_OUT_DSICLK,
> + P_GCC_DISP_GPLL0_CLK,
> +};
> +
> +static const struct pll_vco lucid_vco[] = {
> + { 249600000, 2000000000, 0 },
> +};
> +
> +/* 1035 MHz configuration (19.2 MHz * (0x35 + 0xe800 / 2^16)) */
> +static const struct alpha_pll_config dispcc_pll0_config = {
> + .l = 0x35,
> + .cal_l = 0x44,
> + .alpha = 0xe800,
> + .config_ctl_val = 0x20485699,
> + .config_ctl_hi_val = 0x00002261,
> + .config_ctl_hi1_val = 0x329a699c,
> + .user_ctl_val = 0x00000001,
> + .user_ctl_hi_val = 0x00000805,
> + .user_ctl_hi1_val = 0x00000000,
> + .test_ctl_hi1_val = 0x01800000,
> +};
> +
> +static struct clk_alpha_pll dispcc_pll0 = {
> + .offset = 0x0,
> + .vco_table = lucid_vco,
> + .num_vco = ARRAY_SIZE(lucid_vco),
> + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
> + .clkr = {
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_pll0",
> + .parent_data = &(const struct clk_parent_data) {
> + .index = DT_BI_TCXO,
> + },
> + .num_parents = 1,
> + .ops = &clk_alpha_pll_lucid_ops,
> + },
> + },
> +};
> +
> +static const struct parent_map dispcc_parent_map_0[] = {
> + { P_BI_TCXO, 0 },
> + { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
> + { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 },
> +};
> +
> +static const struct clk_parent_data dispcc_parent_data_0[] = {
> + { .index = DT_BI_TCXO },
> + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
> + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK },
> +};
> +
> +static const struct parent_map dispcc_parent_map_1[] = {
> + { P_BI_TCXO, 0 },
> + { P_DP_PHY_PLL_LINK_CLK, 1 },
> + { P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
> +};
> +
> +static const struct clk_parent_data dispcc_parent_data_1[] = {
> + { .index = DT_BI_TCXO },
> + { .index = DT_DP_PHY_PLL_LINK_CLK },
> + { .index = DT_DP_PHY_PLL_VCO_DIV_CLK },
> +};
> +
> +static const struct parent_map dispcc_parent_map_2[] = {
> + { P_BI_TCXO, 0 },
> +};
> +
> +static const struct clk_parent_data dispcc_parent_data_2[] = {
> + { .index = DT_BI_TCXO },
> +};
> +
> +static const struct clk_parent_data dispcc_parent_data_2_ao[] = {
> + { .index = DT_BI_TCXO_AO },
> +};
> +
> +static const struct parent_map dispcc_parent_map_3[] = {
> + { P_BI_TCXO, 0 },
> + { P_DISPCC_PLL0_OUT_MAIN, 1 },
> + { P_GCC_DISP_GPLL0_CLK, 4 },
> + { P_DISPCC_PLL0_OUT_EVEN, 5 },
> +};
> +
> +static const struct clk_parent_data dispcc_parent_data_3[] = {
> + { .index = DT_BI_TCXO },
> + { .hw = &dispcc_pll0.clkr.hw },
> + { .index = DT_GCC_DISP_GPLL0_CLK },
> + { .hw = &dispcc_pll0.clkr.hw },
> +};
> +
> +static const struct parent_map dispcc_parent_map_4[] = {
> + { P_BI_TCXO, 0 },
> + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
> + { P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
> +};
> +
> +static const struct clk_parent_data dispcc_parent_data_4[] = {
> + { .index = DT_BI_TCXO },
> + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
> + { .index = DT_DSI1_PHY_PLL_OUT_DSICLK },
> +};
> +
> +static const struct parent_map dispcc_parent_map_5[] = {
> + { P_BI_TCXO, 0 },
> + { P_GCC_DISP_GPLL0_CLK, 4 },
> +};
> +
> +static const struct clk_parent_data dispcc_parent_data_5[] = {
> + { .index = DT_BI_TCXO },
> + { .index = DT_GCC_DISP_GPLL0_CLK },
> +};
> +
> +static const struct parent_map dispcc_parent_map_6[] = {
> + { P_CHIP_SLEEP_CLK, 0 },
> +};
> +
> +static const struct clk_parent_data dispcc_parent_data_6[] = {
> + { .index = DT_CHIP_SLEEP_CLK },
> +};
> +
> +static const struct freq_tbl ftbl_dispcc_mdss_ahb_clk_src[] = {
> + F(19200000, P_BI_TCXO, 1, 0, 0),
> + F(37500000, P_GCC_DISP_GPLL0_CLK, 16, 0, 0),
> + F(75000000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0),
> + { }
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_ahb_clk_src = {
> + .cmd_rcgr = 0x22bc,
> + .mnd_width = 0,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_5,
> + .freq_tbl = ftbl_dispcc_mdss_ahb_clk_src,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_ahb_clk_src",
> + .parent_data = dispcc_parent_data_5,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_5),
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_rcg2_shared_ops,
> + },
> +};
> +
> +static const struct freq_tbl ftbl_dispcc_mdss_byte0_clk_src[] = {
> + F(19200000, P_BI_TCXO, 1, 0, 0),
> + { }
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_byte0_clk_src = {
> + .cmd_rcgr = 0x2110,
> + .mnd_width = 0,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_0,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_byte0_clk_src",
> + .parent_data = dispcc_parent_data_0,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_0),
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_byte2_ops,
> + },
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_byte1_clk_src = {
> + .cmd_rcgr = 0x212c,
> + .mnd_width = 0,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_0,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_byte1_clk_src",
> + .parent_data = dispcc_parent_data_0,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_0),
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_byte2_ops,
> + },
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_dp_aux_clk_src = {
> + .cmd_rcgr = 0x21dc,
> + .mnd_width = 0,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_2,
> + .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_dp_aux_clk_src",
> + .parent_data = dispcc_parent_data_2,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_2),
> + .ops = &clk_rcg2_ops,
> + },
> +};
> +
> +static const struct freq_tbl ftbl_dispcc_mdss_dp_crypto_clk_src[] = {
> + F(108000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
> + F(180000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
> + F(360000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
> + F(540000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
> + { }
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_dp_crypto_clk_src = {
> + .cmd_rcgr = 0x2194,
> + .mnd_width = 0,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_1,
> + .freq_tbl = ftbl_dispcc_mdss_dp_crypto_clk_src,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_dp_crypto_clk_src",
> + .parent_data = dispcc_parent_data_1,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_1),
> + .ops = &clk_rcg2_ops,
> + },
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_dp_link_clk_src = {
> + .cmd_rcgr = 0x2178,
> + .mnd_width = 0,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_1,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_dp_link_clk_src",
> + .parent_data = dispcc_parent_data_1,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_1),
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_byte2_ops,
> + },
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_dp_pixel1_clk_src = {
> + .cmd_rcgr = 0x21c4,
> + .mnd_width = 16,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_1,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_dp_pixel1_clk_src",
> + .parent_data = dispcc_parent_data_1,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_1),
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_dp_ops,
> + },
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_dp_pixel_clk_src = {
> + .cmd_rcgr = 0x21ac,
> + .mnd_width = 16,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_1,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_dp_pixel_clk_src",
> + .parent_data = dispcc_parent_data_1,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_1),
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_dp_ops,
> + },
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_esc0_clk_src = {
> + .cmd_rcgr = 0x2148,
> + .mnd_width = 0,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_0,
> + .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_esc0_clk_src",
> + .parent_data = dispcc_parent_data_0,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_0),
> + .ops = &clk_rcg2_ops,
> + },
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_esc1_clk_src = {
> + .cmd_rcgr = 0x2160,
> + .mnd_width = 0,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_0,
> + .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_esc1_clk_src",
> + .parent_data = dispcc_parent_data_0,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_0),
> + .ops = &clk_rcg2_ops,
> + },
> +};
> +
> +static const struct freq_tbl ftbl_dispcc_mdss_mdp_clk_src[] = {
> + F(19200000, P_BI_TCXO, 1, 0, 0),
> + F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),
> + F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),
> + F(345000000, P_DISPCC_PLL0_OUT_MAIN, 3, 0, 0),
> + F(460000000, P_DISPCC_PLL0_OUT_MAIN, 3, 0, 0),
> + { }
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_mdp_clk_src = {
> + .cmd_rcgr = 0x20c8,
> + .mnd_width = 0,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_3,
> + .freq_tbl = ftbl_dispcc_mdss_mdp_clk_src,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_mdp_clk_src",
> + .parent_data = dispcc_parent_data_3,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_3),
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_rcg2_shared_ops,
> + },
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_pclk0_clk_src = {
> + .cmd_rcgr = 0x2098,
> + .mnd_width = 8,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_4,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_pclk0_clk_src",
> + .parent_data = dispcc_parent_data_4,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_4),
> + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
> + .ops = &clk_pixel_ops,
> + },
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_pclk1_clk_src = {
> + .cmd_rcgr = 0x20b0,
> + .mnd_width = 8,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_4,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_pclk1_clk_src",
> + .parent_data = dispcc_parent_data_4,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_4),
> + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
> + .ops = &clk_pixel_ops,
> + },
> +};
> +
> +static const struct freq_tbl ftbl_dispcc_mdss_rot_clk_src[] = {
> + F(19200000, P_BI_TCXO, 1, 0, 0),
> + F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),
> + F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),
> + { }
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_rot_clk_src = {
> + .cmd_rcgr = 0x20e0,
> + .mnd_width = 0,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_3,
> + .freq_tbl = ftbl_dispcc_mdss_rot_clk_src,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_rot_clk_src",
> + .parent_data = dispcc_parent_data_3,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_3),
> + .ops = &clk_rcg2_shared_ops,
> + },
> +};
> +
> +static struct clk_rcg2 dispcc_mdss_vsync_clk_src = {
> + .cmd_rcgr = 0x20f8,
> + .mnd_width = 0,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_2,
> + .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_vsync_clk_src",
> + .parent_data = dispcc_parent_data_2,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_2),
> + .ops = &clk_rcg2_ops,
> + },
> +};
> +
> +static const struct freq_tbl ftbl_dispcc_sleep_clk_src[] = {
> + F(32000, P_CHIP_SLEEP_CLK, 1, 0, 0),
> + { }
> +};
> +
> +static struct clk_rcg2 dispcc_sleep_clk_src = {
> + .cmd_rcgr = 0x6060,
> + .mnd_width = 0,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_6,
> + .freq_tbl = ftbl_dispcc_sleep_clk_src,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_sleep_clk_src",
> + .parent_data = dispcc_parent_data_6,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_6),
> + .ops = &clk_rcg2_ops,
> + },
> +};
> +
> +static struct clk_rcg2 dispcc_xo_clk_src = {
> + .cmd_rcgr = 0x6044,
> + .mnd_width = 0,
> + .hid_width = 5,
> + .parent_map = dispcc_parent_map_2,
> + .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
> + .clkr.hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_xo_clk_src",
> + .parent_data = dispcc_parent_data_2_ao,
> + .num_parents = ARRAY_SIZE(dispcc_parent_data_2_ao),
This can use the normal XO parent.
> + .ops = &clk_rcg2_ops,
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_ahb_clk = {
> + .halt_reg = 0x2080,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2080,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_ahb_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_ahb_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_byte0_clk = {
> + .halt_reg = 0x2028,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2028,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_byte0_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_byte0_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_regmap_div dispcc_mdss_byte0_div_clk_src = {
> + .reg = 0x2128,
> + .shift = 0,
> + .width = 2,
> + .clkr = {
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_byte0_div_clk_src",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_byte0_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .ops = &clk_regmap_div_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_byte0_intf_clk = {
> + .halt_reg = 0x202c,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x202c,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_byte0_intf_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_byte0_div_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_byte1_clk = {
> + .halt_reg = 0x2030,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2030,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_byte1_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_byte1_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_regmap_div dispcc_mdss_byte1_div_clk_src = {
> + .reg = 0x2144,
> + .shift = 0,
> + .width = 2,
> + .clkr = {
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_byte1_div_clk_src",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_byte1_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .ops = &clk_regmap_div_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_byte1_intf_clk = {
> + .halt_reg = 0x2034,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2034,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_byte1_intf_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_byte1_div_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_dp_aux_clk = {
> + .halt_reg = 0x2054,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2054,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_dp_aux_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_dp_aux_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_dp_crypto_clk = {
> + .halt_reg = 0x2048,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2048,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_dp_crypto_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_dp_crypto_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_dp_link_clk = {
> + .halt_reg = 0x2040,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2040,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_dp_link_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_dp_link_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_dp_link_intf_clk = {
> + .halt_reg = 0x2044,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2044,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_dp_link_intf_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_dp_link_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_dp_pixel1_clk = {
> + .halt_reg = 0x2050,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2050,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_dp_pixel1_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_dp_pixel1_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_dp_pixel_clk = {
> + .halt_reg = 0x204c,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x204c,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_dp_pixel_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_dp_pixel_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_esc0_clk = {
> + .halt_reg = 0x2038,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2038,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_esc0_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_esc0_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_esc1_clk = {
> + .halt_reg = 0x203c,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x203c,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_esc1_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_esc1_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_mdp_clk = {
> + .halt_reg = 0x200c,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x200c,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_mdp_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_mdp_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_mdp_lut_clk = {
> + .halt_reg = 0x201c,
> + .halt_check = BRANCH_VOTED,
> + .clkr = {
> + .enable_reg = 0x201c,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_mdp_lut_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_mdp_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_non_gdsc_ahb_clk = {
> + .halt_reg = 0x4004,
> + .halt_check = BRANCH_VOTED,
Why VOTED? if it is not polled during enable, it is going to return back
wrong status.
> + .clkr = {
> + .enable_reg = 0x4004,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_non_gdsc_ahb_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_ahb_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_pclk0_clk = {
> + .halt_reg = 0x2004,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2004,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_pclk0_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_pclk0_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_pclk1_clk = {
> + .halt_reg = 0x2008,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2008,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_pclk1_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_pclk1_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_rot_clk = {
> + .halt_reg = 0x2014,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2014,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_rot_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_rot_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_rscc_ahb_clk = {
> + .halt_reg = 0x400c,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x400c,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_rscc_ahb_clk",
> + .parent_names = (const char *[]) {
> + "dispcc_mdss_ahb_clk_src",
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_rscc_vsync_clk = {
> + .halt_reg = 0x4008,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x4008,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_rscc_vsync_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_vsync_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_mdss_vsync_clk = {
> + .halt_reg = 0x2024,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x2024,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_mdss_vsync_clk",
> + .parent_hws = (const struct clk_hw*[]) {
> + &dispcc_mdss_vsync_clk_src.clkr.hw,
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct clk_branch dispcc_sleep_clk = {
> + .halt_reg = 0x6078,
> + .halt_check = BRANCH_HALT,
> + .clkr = {
> + .enable_reg = 0x6078,
> + .enable_mask = BIT(0),
> + .hw.init = &(const struct clk_init_data) {
> + .name = "dispcc_sleep_clk",
> + .parent_names = (const char *[]) {
> + "dispcc_sleep_clk_src",
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + .ops = &clk_branch2_ops,
> + },
> + },
> +};
> +
> +static struct gdsc mdss_gdsc = {
> + .gdscr = 0x3000,
> + .en_rest_wait_val = 0x2,
> + .en_few_wait_val = 0x2,
> + .clk_dis_wait_val = 0xf,
> + .pd = {
> + .name = "mdss_gdsc",
> + },
> + .pwrsts = PWRSTS_OFF_ON,
> + .flags = HW_CTRL,
> +};
> +
> +static struct clk_regmap *dispcc_sm7250_clocks[] = {
> + [DISPCC_MDSS_AHB_CLK] = &dispcc_mdss_ahb_clk.clkr,
> + [DISPCC_MDSS_AHB_CLK_SRC] = &dispcc_mdss_ahb_clk_src.clkr,
> + [DISPCC_MDSS_BYTE0_CLK] = &dispcc_mdss_byte0_clk.clkr,
> + [DISPCC_MDSS_BYTE0_CLK_SRC] = &dispcc_mdss_byte0_clk_src.clkr,
> + [DISPCC_MDSS_BYTE0_DIV_CLK_SRC] = &dispcc_mdss_byte0_div_clk_src.clkr,
> + [DISPCC_MDSS_BYTE0_INTF_CLK] = &dispcc_mdss_byte0_intf_clk.clkr,
> + [DISPCC_MDSS_BYTE1_CLK] = &dispcc_mdss_byte1_clk.clkr,
> + [DISPCC_MDSS_BYTE1_CLK_SRC] = &dispcc_mdss_byte1_clk_src.clkr,
> + [DISPCC_MDSS_BYTE1_DIV_CLK_SRC] = &dispcc_mdss_byte1_div_clk_src.clkr,
> + [DISPCC_MDSS_BYTE1_INTF_CLK] = &dispcc_mdss_byte1_intf_clk.clkr,
> + [DISPCC_MDSS_DP_AUX_CLK] = &dispcc_mdss_dp_aux_clk.clkr,
> + [DISPCC_MDSS_DP_AUX_CLK_SRC] = &dispcc_mdss_dp_aux_clk_src.clkr,
> + [DISPCC_MDSS_DP_CRYPTO_CLK] = &dispcc_mdss_dp_crypto_clk.clkr,
> + [DISPCC_MDSS_DP_CRYPTO_CLK_SRC] = &dispcc_mdss_dp_crypto_clk_src.clkr,
> + [DISPCC_MDSS_DP_LINK_CLK] = &dispcc_mdss_dp_link_clk.clkr,
> + [DISPCC_MDSS_DP_LINK_CLK_SRC] = &dispcc_mdss_dp_link_clk_src.clkr,
> + [DISPCC_MDSS_DP_LINK_INTF_CLK] = &dispcc_mdss_dp_link_intf_clk.clkr,
> + [DISPCC_MDSS_DP_PIXEL1_CLK] = &dispcc_mdss_dp_pixel1_clk.clkr,
> + [DISPCC_MDSS_DP_PIXEL1_CLK_SRC] = &dispcc_mdss_dp_pixel1_clk_src.clkr,
> + [DISPCC_MDSS_DP_PIXEL_CLK] = &dispcc_mdss_dp_pixel_clk.clkr,
> + [DISPCC_MDSS_DP_PIXEL_CLK_SRC] = &dispcc_mdss_dp_pixel_clk_src.clkr,
> + [DISPCC_MDSS_ESC0_CLK] = &dispcc_mdss_esc0_clk.clkr,
> + [DISPCC_MDSS_ESC0_CLK_SRC] = &dispcc_mdss_esc0_clk_src.clkr,
> + [DISPCC_MDSS_ESC1_CLK] = &dispcc_mdss_esc1_clk.clkr,
> + [DISPCC_MDSS_ESC1_CLK_SRC] = &dispcc_mdss_esc1_clk_src.clkr,
> + [DISPCC_MDSS_MDP_CLK] = &dispcc_mdss_mdp_clk.clkr,
> + [DISPCC_MDSS_MDP_CLK_SRC] = &dispcc_mdss_mdp_clk_src.clkr,
> + [DISPCC_MDSS_MDP_LUT_CLK] = &dispcc_mdss_mdp_lut_clk.clkr,
> + [DISPCC_MDSS_NON_GDSC_AHB_CLK] = &dispcc_mdss_non_gdsc_ahb_clk.clkr,
> + [DISPCC_MDSS_PCLK0_CLK] = &dispcc_mdss_pclk0_clk.clkr,
> + [DISPCC_MDSS_PCLK0_CLK_SRC] = &dispcc_mdss_pclk0_clk_src.clkr,
> + [DISPCC_MDSS_PCLK1_CLK] = &dispcc_mdss_pclk1_clk.clkr,
> + [DISPCC_MDSS_PCLK1_CLK_SRC] = &dispcc_mdss_pclk1_clk_src.clkr,
> + [DISPCC_MDSS_ROT_CLK] = &dispcc_mdss_rot_clk.clkr,
> + [DISPCC_MDSS_ROT_CLK_SRC] = &dispcc_mdss_rot_clk_src.clkr,
> + [DISPCC_MDSS_RSCC_AHB_CLK] = &dispcc_mdss_rscc_ahb_clk.clkr,
> + [DISPCC_MDSS_RSCC_VSYNC_CLK] = &dispcc_mdss_rscc_vsync_clk.clkr,
> + [DISPCC_MDSS_VSYNC_CLK] = &dispcc_mdss_vsync_clk.clkr,
> + [DISPCC_MDSS_VSYNC_CLK_SRC] = &dispcc_mdss_vsync_clk_src.clkr,
> + [DISPCC_PLL0] = &dispcc_pll0.clkr,
> + [DISPCC_SLEEP_CLK] = &dispcc_sleep_clk.clkr,
> + [DISPCC_SLEEP_CLK_SRC] = &dispcc_sleep_clk_src.clkr,
> + [DISPCC_XO_CLK_SRC] = &dispcc_xo_clk_src.clkr,
> +};
> +
> +static struct gdsc *dispcc_sm7250_gdscs[] = {
> + [MDSS_GDSC] = &mdss_gdsc,
> +};
> +
> +static const struct qcom_reset_map dispcc_sm7250_resets[] = {
> + [DISPCC_MDSS_CORE_BCR] = { 0x2000 },
> +};
> +
> +static const struct regmap_config dispcc_sm7250_regmap_config = {
> + .reg_bits = 32,
> + .reg_stride = 4,
> + .val_bits = 32,
> + .max_register = 0x10000,
> + .fast_io = true,
> +};
> +
> +static const struct qcom_cc_desc dispcc_sm7250_desc = {
> + .config = &dispcc_sm7250_regmap_config,
> + .clks = dispcc_sm7250_clocks,
> + .num_clks = ARRAY_SIZE(dispcc_sm7250_clocks),
> + .gdscs = dispcc_sm7250_gdscs,
> + .num_gdscs = ARRAY_SIZE(dispcc_sm7250_gdscs),
> + .resets = dispcc_sm7250_resets,
> + .num_resets = ARRAY_SIZE(dispcc_sm7250_resets),
> +};
> +
> +static const struct of_device_id dispcc_sm7250_match_table[] = {
> + { .compatible = "qcom,sm7250-dispcc" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, dispcc_sm7250_match_table);
> +
> +static int dispcc_sm7250_probe(struct platform_device *pdev)
> +{
> + struct regmap *regmap;
> +
> + regmap = qcom_cc_map(pdev, &dispcc_sm7250_desc);
> + if (IS_ERR(regmap))
> + return PTR_ERR(regmap);
> +
> + clk_lucid_pll_configure(&dispcc_pll0, regmap, &dispcc_pll0_config);
> + /* Enable clock gating for DSI and MDP clocks */
> + regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0);
please follow the latest way of using the call-backs to configure PLL
and any other misc registers.
> +
> + /* Keep some clocks always-on */
> + qcom_branch_set_clk_en(regmap, 0x605c); /* DISPCC_XO_CLK */
> +
> + return qcom_cc_really_probe(&pdev->dev, &dispcc_sm7250_desc, regmap);
> +}
> +
> +static struct platform_driver dispcc_sm7250_driver = {
> + .probe = dispcc_sm7250_probe,
> + .driver = {
> + .name = "dispcc-sm7250",
> + .of_match_table = dispcc_sm7250_match_table,
> + },
> +};
> +
> +module_platform_driver(dispcc_sm7250_driver);
> +
> +MODULE_DESCRIPTION("Qualcomm SM7250 Display Clock Controller");
> +MODULE_LICENSE("GPL");
>
--
Thanks,
Taniya Das
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-26 11:39 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-23 10:18 [PATCH 0/2] clk: qcom: Add SM7250 display clock controller Ishu Brar via B4 Relay
2026-10-23 10:18 ` [PATCH 1/2] dt-bindings: clock: qcom: Document the " Ishu Brar via B4 Relay
2026-10-23 10:38 ` sashiko-bot
2026-10-26 9:35 ` Krzysztof Kozlowski
2026-10-23 10:18 ` [PATCH 2/2] clk: qcom: Add SM7250 display clock controller driver Ishu Brar via B4 Relay
2026-10-23 10:55 ` sashiko-bot
2026-10-26 11:39 ` Taniya Das
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox