linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/11] Add new partial clock and reset drivers for StarFive JH7110
@ 2023-02-21  8:33 Xingyu Wu
  2023-02-21  8:33 ` [PATCH v2 01/11] dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and reset generator Xingyu Wu
                   ` (10 more replies)
  0 siblings, 11 replies; 33+ messages in thread
From: Xingyu Wu @ 2023-02-21  8:33 UTC (permalink / raw)
  To: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, Xingyu Wu, linux-kernel, linux-clk

This patch serises are to add new partial clock drivers and reset
supports about System-Top-Group(STG), Image-Signal-Process(ISP)
and Video-Output(VOUT) for the StarFive JH7110 RISC-V SoC.

Patches 1 to 3 are about the System-Top-Group clock and reset
generator(STGCRG) part.
The first patch adds docunmentation to describe STG bindings, and 
the second patch adds support about STG resets. The last patch adds
clock driver to support STG clocks for JH7110.

Patches 4 to 6 are about the Image-Signal-Process clock and reset
gennerator(ISPCRG) part.
The first patch adds docunmentation to describe ISP bindings, and 
the second patch adds support about ISP resets. The last patch adds
clock driver to support ISP clocks for JH7110.

Patches 7 to 9 are about the Video-Output clock and reset
generator(VOUTCRG) part.
The first patch adds docunmentation to describe VOUT bindings, and 
the second patch adds support about VOUT resets. The last patch adds
clock driver to support VOUT clocks for JH7110.

Patch 10 adds external clocks which ISP and VOUT clock driver need.
Patch 11 adds device node about STGCRG, ISPCRG and VOUTCRG to JH7110 dts.

Patches 2, 3, 5, 6, 8 and 9 are dependent on the patchset [1] which
is about JH71x0 clock and reset driver.
Patches 6 and 9 also are dependent on the patchset [2] which is about
JH7110 PMU driver(Accpeted).
Patchdes 10 and 11 are dependent on the patchset [1] and [3] which is
about JH7110 device tree and PMU node.
This patchset should be applied after the patchset [1], [2], [3]:
[1] https://lore.kernel.org/all/20230221024645.127922-1-hal.feng@starfivetech.com/
[2] https://lore.kernel.org/all/20230119094447.21939-3-walker.chen@starfivetech.com/
[3] https://lore.kernel.org/all/20230116074259.22874-4-walker.chen@starfivetech.com/

Changes since v1:
- Modified the binding and dropped the indentation.
- Removed the useless header files in the drivers.
- Used an array lookup instead of a pile of conditions about parent
  clocks' name.
- Added clocks operation on driver remove.

v1: https://lore.kernel.org/all/20230120024445.244345-1-xingyu.wu@starfivetech.com/

Xingyu Wu (11):
  dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and
    reset generator
  reset: starfive: jh7110: Add StarFive System-Top-Group reset support
  clk: starfive: Add StarFive JH7110 System-Top-Group clock driver
  dt-bindings: clock: Add StarFive JH7110 Image-Signal-Process clock and
    reset generator
  reset: starfive: jh7110: Add StarFive Image-Signal-Process reset
    support
  clk: starfive: Add StarFive JH7110 Image-Signal-Process clock driver
  dt-bindings: clock: Add StarFive JH7110 Video-Output clock and reset
    generator
  reset: starfive: jh7110: Add StarFive Video-Output reset support
  clk: starfive: Add StarFive JH7110 Video-Output clock driver
  riscv: dts: starfive: jh7110: Add DVP and HDMI TX pixel external
    clocks
  riscv: dts: starfive: jh7110: Add STGCRG/ISPCRG/VOUTCRG nodes

 .../clock/starfive,jh7110-ispcrg.yaml         |  97 +++++++
 .../clock/starfive,jh7110-stgcrg.yaml         |  82 ++++++
 .../clock/starfive,jh7110-voutcrg.yaml        |  96 +++++++
 MAINTAINERS                                   |   1 +
 .../jh7110-starfive-visionfive-2.dtsi         |   8 +
 arch/riscv/boot/dts/starfive/jh7110.dtsi      |  71 +++++
 drivers/clk/starfive/Kconfig                  |  33 +++
 drivers/clk/starfive/Makefile                 |   3 +
 .../clk/starfive/clk-starfive-jh7110-isp.c    | 254 +++++++++++++++++
 .../clk/starfive/clk-starfive-jh7110-stg.c    | 176 ++++++++++++
 .../clk/starfive/clk-starfive-jh7110-vout.c   | 261 ++++++++++++++++++
 .../reset/starfive/reset-starfive-jh7110.c    |  30 ++
 .../dt-bindings/clock/starfive,jh7110-crg.h   |  74 +++++
 .../dt-bindings/reset/starfive,jh7110-crg.h   |  60 ++++
 14 files changed, 1246 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml
 create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-isp.c
 create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-stg.c
 create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-vout.c


base-commit: c9c3395d5e3dcc6daee66c6908354d47bf98cb0c
prerequisite-patch-id: 4dc515731ce237184553c1606ffb3afaeb51c3d8
prerequisite-patch-id: ac150a8c622e858e088df8121093d448df49c245
prerequisite-patch-id: a4255724d4698f1238663443024de56de38d717b
prerequisite-patch-id: a798370d170dc2bcc79ed86f741c21c1e6d87c78
prerequisite-patch-id: 203d2500cadc112bd20fefc56eabf1470d3d2d2d
prerequisite-patch-id: 315303931e4b6499de7127a88113763f86e97e16
prerequisite-patch-id: 40cb8212ddb024c20593f73d8b87d9894877e172
prerequisite-patch-id: a1673a9e9f19d6fab5a51abb721e54e36636f067
prerequisite-patch-id: 94860423c7acc9025249d4bb36652a585bd0a797
prerequisite-patch-id: b5084253283929d9a6d0e66c350400c7c85d034d
prerequisite-patch-id: a428ed7a2aa45abab86923dc467e1e6b08427e85
prerequisite-patch-id: d4f80829fca7ce370a6fad766593cdcb502fa245
prerequisite-patch-id: e3490e19e089fe284334db300ee189b619a61628
prerequisite-patch-id: 34298e3882261bc2d72955b1570cc9612ab7d662
prerequisite-patch-id: 377c5c282a0776feee9acd10b565adbd5275a67e
prerequisite-patch-id: 3ccee718de0750adbf8d0b77d553a2778a344f64
prerequisite-patch-id: 4710f2ac22dca0bdd9ff5d744d2c37cab3c74515
prerequisite-patch-id: 65f2aed865d88e6fa468d2923527b523d4313857
prerequisite-patch-id: 258ea5f9b8bf41b6981345dcc81795f25865d38f
prerequisite-patch-id: 8b6f2c9660c0ac0ee4e73e4c21aca8e6b75e81b9
prerequisite-patch-id: e3b986b9c60b2b93b7812ec174c9e1b4cfb14c97
prerequisite-patch-id: a2b3a9cff8a683422eb0ccf3a0850091401812d4
prerequisite-patch-id: dbb0c0151b8bdf093e6ce79fd2fe3f60791a6e0b
prerequisite-patch-id: ea9a6d0313dd3936c8de0239dc2072c3360a2f6b
prerequisite-patch-id: d57e95d31686772abc4c4d5aa1cadc344dc293cd
prerequisite-patch-id: 29aab7148bf56a20acddcb8a11f290705fcc97f6
prerequisite-patch-id: eeecb5367bea99627210b661986ca5b49e2a9d63
prerequisite-patch-id: c02658f677990683d4c4957e06c19ed3a3a0cfab
prerequisite-patch-id: 2ddada18ab6ea5cd1da14212aaf59632f5203d40
-- 
2.25.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH v2 01/11] dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and reset generator
  2023-02-21  8:33 [PATCH v2 00/11] Add new partial clock and reset drivers for StarFive JH7110 Xingyu Wu
@ 2023-02-21  8:33 ` Xingyu Wu
  2023-02-21 11:25   ` Krzysztof Kozlowski
  2023-03-02 15:05   ` Emil Renner Berthing
  2023-02-21  8:33 ` [PATCH v2 02/11] reset: starfive: jh7110: Add StarFive System-Top-Group reset support Xingyu Wu
                   ` (9 subsequent siblings)
  10 siblings, 2 replies; 33+ messages in thread
From: Xingyu Wu @ 2023-02-21  8:33 UTC (permalink / raw)
  To: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, Xingyu Wu, linux-kernel, linux-clk

Add bindings for the System-Top-Group clock and reset generator (STGCRG)
on the JH7110 RISC-V SoC by StarFive Ltd.

Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
---
 .../clock/starfive,jh7110-stgcrg.yaml         | 82 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 .../dt-bindings/clock/starfive,jh7110-crg.h   | 34 ++++++++
 .../dt-bindings/reset/starfive,jh7110-crg.h   | 28 +++++++
 4 files changed, 145 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml

diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
new file mode 100644
index 000000000000..b64ccd84200a
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jh7110-stgcrg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH7110 System-Top-Group Clock and Reset Generator
+
+maintainers:
+  - Xingyu Wu <xingyu.wu@starfivetech.com>
+
+properties:
+  compatible:
+    const: starfive,jh7110-stgcrg
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Main Oscillator (24 MHz)
+      - description: HIFI4 core
+      - description: STG AXI/AHB
+      - description: USB (125 MHz)
+      - description: CPU Bus
+      - description: HIFI4 Axi
+      - description: NOC STG Bus
+      - description: APB Bus
+
+  clock-names:
+    items:
+      - const: osc
+      - const: hifi4_core
+      - const: stg_axiahb
+      - const: usb_125m
+      - const: cpu_bus
+      - const: hifi4_axi
+      - const: nocstg_bus
+      - const: apb_bus
+
+  '#clock-cells':
+    const: 1
+    description:
+      See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
+
+  '#reset-cells':
+    const: 1
+    description:
+      See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+  - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/starfive,jh7110-crg.h>
+
+    stgcrg: clock-controller@10230000 {
+        compatible = "starfive,jh7110-stgcrg";
+        reg = <0x10230000 0x10000>;
+        clocks = <&osc>,
+                 <&syscrg JH7110_SYSCLK_HIFI4_CORE>,
+                 <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
+                 <&syscrg JH7110_SYSCLK_USB_125M>,
+                 <&syscrg JH7110_SYSCLK_CPU_BUS>,
+                 <&syscrg JH7110_SYSCLK_HIFI4_AXI>,
+                 <&syscrg JH7110_SYSCLK_NOCSTG_BUS>,
+                 <&syscrg JH7110_SYSCLK_APB_BUS>;
+        clock-names = "osc", "hifi4_core",
+                      "stg_axiahb", "usb_125m",
+                      "cpu_bus", "hifi4_axi",
+                      "nocstg_bus", "apb_bus";
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 93eb504c3b21..2e70c9f21989 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19914,6 +19914,7 @@ F:	arch/riscv/boot/dts/starfive/
 STARFIVE JH71X0 CLOCK DRIVERS
 M:	Emil Renner Berthing <kernel@esmil.dk>
 M:	Hal Feng <hal.feng@starfivetech.com>
+M:	Xingyu Wu <xingyu.wu@starfivetech.com>
 S:	Maintained
 F:	Documentation/devicetree/bindings/clock/starfive,jh71*.yaml
 F:	drivers/clk/starfive/clk-starfive-jh71*
diff --git a/include/dt-bindings/clock/starfive,jh7110-crg.h b/include/dt-bindings/clock/starfive,jh7110-crg.h
index 5e4f21ca0642..5ac8a4d90a7a 100644
--- a/include/dt-bindings/clock/starfive,jh7110-crg.h
+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
 /*
  * Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
+ * Copyright 2022 StarFive Technology Co., Ltd.
  */
 
 #ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
@@ -222,4 +223,37 @@
 
 #define JH7110_AONCLK_END			14
 
+/* STGCRG clocks */
+#define JH7110_STGCLK_HIFI4_CLK_CORE		0
+#define JH7110_STGCLK_USB0_APB			1
+#define JH7110_STGCLK_USB0_UTMI_APB		2
+#define JH7110_STGCLK_USB0_AXI			3
+#define JH7110_STGCLK_USB0_LPM			4
+#define JH7110_STGCLK_USB0_STB			5
+#define JH7110_STGCLK_USB0_APP_125		6
+#define JH7110_STGCLK_USB0_REFCLK		7
+#define JH7110_STGCLK_PCIE0_AXI_MST0		8
+#define JH7110_STGCLK_PCIE0_APB			9
+#define JH7110_STGCLK_PCIE0_TL			10
+#define JH7110_STGCLK_PCIE1_AXI_MST0		11
+#define JH7110_STGCLK_PCIE1_APB			12
+#define JH7110_STGCLK_PCIE1_TL			13
+#define JH7110_STGCLK_PCIE01_SLV_DEC_MAINCLK	14
+#define JH7110_STGCLK_SEC_HCLK			15
+#define JH7110_STGCLK_SEC_MISCAHB		16
+#define JH7110_STGCLK_GRP0_MAIN			17
+#define JH7110_STGCLK_GRP0_BUS			18
+#define JH7110_STGCLK_GRP0_STG			19
+#define JH7110_STGCLK_GRP1_MAIN			20
+#define JH7110_STGCLK_GRP1_BUS			21
+#define JH7110_STGCLK_GRP1_STG			22
+#define JH7110_STGCLK_GRP1_HIFI			23
+#define JH7110_STGCLK_E2_RTC			24
+#define JH7110_STGCLK_E2_CORE			25
+#define JH7110_STGCLK_E2_DBG			26
+#define JH7110_STGCLK_DMA1P_AXI			27
+#define JH7110_STGCLK_DMA1P_AHB			28
+
+#define JH7110_STGCLK_END			29
+
 #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
diff --git a/include/dt-bindings/reset/starfive,jh7110-crg.h b/include/dt-bindings/reset/starfive,jh7110-crg.h
index d78e38690ceb..4a865ded78b8 100644
--- a/include/dt-bindings/reset/starfive,jh7110-crg.h
+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
 /*
  * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
  */
 
 #ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
@@ -151,4 +152,31 @@
 
 #define JH7110_AONRST_END			8
 
+/* STGCRG resets */
+#define JH7110_STGRST_SYSCON			0
+#define JH7110_STGRST_HIFI4_CORE		1
+#define JH7110_STGRST_HIFI4_AXI			2
+#define JH7110_STGRST_SEC_TOP_HRESETN		3
+#define JH7110_STGRST_E24_CORE			4
+#define JH7110_STGRST_DMA1P_AXI			5
+#define JH7110_STGRST_DMA1P_AHB			6
+#define JH7110_STGRST_USB0_AXI			7
+#define JH7110_STGRST_USB0_APB			8
+#define JH7110_STGRST_USB0_UTMI_APB		9
+#define JH7110_STGRST_USB0_PWRUP		10
+#define JH7110_STGRST_PCIE0_AXI_MST0		11
+#define JH7110_STGRST_PCIE0_AXI_SLV0		12
+#define JH7110_STGRST_PCIE0_AXI_SLV		13
+#define JH7110_STGRST_PCIE0_BRG			14
+#define JH7110_STGRST_PCIE0_CORE		15
+#define JH7110_STGRST_PCIE0_APB			16
+#define JH7110_STGRST_PCIE1_AXI_MST0		17
+#define JH7110_STGRST_PCIE1_AXI_SLV0		18
+#define JH7110_STGRST_PCIE1_AXI_SLV		19
+#define JH7110_STGRST_PCIE1_BRG			20
+#define JH7110_STGRST_PCIE1_CORE		21
+#define JH7110_STGRST_PCIE1_APB			22
+
+#define JH7110_STGRST_END			23
+
 #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v2 02/11] reset: starfive: jh7110: Add StarFive System-Top-Group reset support
  2023-02-21  8:33 [PATCH v2 00/11] Add new partial clock and reset drivers for StarFive JH7110 Xingyu Wu
  2023-02-21  8:33 ` [PATCH v2 01/11] dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and reset generator Xingyu Wu
@ 2023-02-21  8:33 ` Xingyu Wu
  2023-02-21  8:33 ` [PATCH v2 03/11] clk: starfive: Add StarFive JH7110 System-Top-Group clock driver Xingyu Wu
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 33+ messages in thread
From: Xingyu Wu @ 2023-02-21  8:33 UTC (permalink / raw)
  To: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, Xingyu Wu, linux-kernel, linux-clk

Add auxiliary_device_id to support StarFive JH7110 System-Top-Group resets
of which the auxiliary device name is "clk_starfive_jh71x0.reset-stg".

Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
---
 drivers/reset/starfive/reset-starfive-jh7110.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/reset/starfive/reset-starfive-jh7110.c b/drivers/reset/starfive/reset-starfive-jh7110.c
index 83577d1b7fc6..94ebb363c6bc 100644
--- a/drivers/reset/starfive/reset-starfive-jh7110.c
+++ b/drivers/reset/starfive/reset-starfive-jh7110.c
@@ -40,6 +40,12 @@ static const struct reset_info jh7110_aon_info = {
 	.status_offset = 0x3C,
 };
 
+static const struct reset_info jh7110_stg_info = {
+	.nr_resets = JH7110_STGRST_END,
+	.assert_offset = 0x74,
+	.status_offset = 0x78,
+};
+
 static const struct auxiliary_device_id jh7110_reset_ids[] = {
 	{
 		.name = "clk_starfive_jh71x0.reset-sys",
@@ -49,6 +55,10 @@ static const struct auxiliary_device_id jh7110_reset_ids[] = {
 		.name = "clk_starfive_jh71x0.reset-aon",
 		.driver_data = (kernel_ulong_t)&jh7110_aon_info,
 	},
+	{
+		.name = "clk_starfive_jh71x0.reset-stg",
+		.driver_data = (kernel_ulong_t)&jh7110_stg_info,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(auxiliary, jh7110_reset_ids);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v2 03/11] clk: starfive: Add StarFive JH7110 System-Top-Group clock driver
  2023-02-21  8:33 [PATCH v2 00/11] Add new partial clock and reset drivers for StarFive JH7110 Xingyu Wu
  2023-02-21  8:33 ` [PATCH v2 01/11] dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and reset generator Xingyu Wu
  2023-02-21  8:33 ` [PATCH v2 02/11] reset: starfive: jh7110: Add StarFive System-Top-Group reset support Xingyu Wu
@ 2023-02-21  8:33 ` Xingyu Wu
  2023-03-02 15:16   ` Emil Renner Berthing
  2023-02-21  8:33 ` [PATCH v2 04/11] dt-bindings: clock: Add StarFive JH7110 Image-Signal-Process clock and reset generator Xingyu Wu
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 33+ messages in thread
From: Xingyu Wu @ 2023-02-21  8:33 UTC (permalink / raw)
  To: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, Xingyu Wu, linux-kernel, linux-clk

Add driver for the StarFive JH7110 System-Top-Group clock controller.

Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
---
 drivers/clk/starfive/Kconfig                  |  11 ++
 drivers/clk/starfive/Makefile                 |   1 +
 .../clk/starfive/clk-starfive-jh7110-stg.c    | 176 ++++++++++++++++++
 3 files changed, 188 insertions(+)
 create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-stg.c

diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index 2aa664f2cdee..a462b6e53543 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -42,3 +42,14 @@ config CLK_STARFIVE_JH7110_AON
 	help
 	  Say yes here to support the always-on clock controller on the
 	  StarFive JH7110 SoC.
+
+config CLK_STARFIVE_JH7110_STG
+	tristate "StarFive JH7110 System-Top-Group clock support"
+	depends on CLK_STARFIVE_JH7110_SYS
+	select AUXILIARY_BUS
+	select CLK_STARFIVE_JH71X0
+	select RESET_STARFIVE_JH7110
+	default CLK_STARFIVE_JH7110_SYS
+	help
+	  Say yes here to support the System-Top-Group clock controller
+	  on the StarFive JH7110 SoC.
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
index f3df7d957b1e..b81e97ee2659 100644
--- a/drivers/clk/starfive/Makefile
+++ b/drivers/clk/starfive/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO)	+= clk-starfive-jh7100-audio.o
 
 obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS)	+= clk-starfive-jh7110-sys.o
 obj-$(CONFIG_CLK_STARFIVE_JH7110_AON)	+= clk-starfive-jh7110-aon.o
+obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)	+= clk-starfive-jh7110-stg.o
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-stg.c b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
new file mode 100644
index 000000000000..a39d2fdb8011
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive JH7110 System-Top-Group Clock Driver
+ *
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/starfive,jh7110-crg.h>
+
+#include "clk-starfive-jh71x0.h"
+
+/* external clocks */
+#define JH7110_STGCLK_OSC			(JH7110_STGCLK_END + 0)
+#define JH7110_STGCLK_HIFI4_CORE		(JH7110_STGCLK_END + 1)
+#define JH7110_STGCLK_STG_AXIAHB		(JH7110_STGCLK_END + 2)
+#define JH7110_STGCLK_USB_125M			(JH7110_STGCLK_END + 3)
+#define JH7110_STGCLK_CPU_BUS			(JH7110_STGCLK_END + 4)
+#define JH7110_STGCLK_HIFI4_AXI			(JH7110_STGCLK_END + 5)
+#define JH7110_STGCLK_NOCSTG_BUS		(JH7110_STGCLK_END + 6)
+#define JH7110_STGCLK_APB_BUS			(JH7110_STGCLK_END + 7)
+#define JH7110_STGCLK_EXT_END			(JH7110_STGCLK_END + 8)
+
+static const struct jh71x0_clk_data jh7110_stgclk_data[] = {
+	/* hifi4 */
+	JH71X0_GATE(JH7110_STGCLK_HIFI4_CLK_CORE, "hifi4_clk_core", 0,
+		    JH7110_STGCLK_HIFI4_CORE),
+	/* usb */
+	JH71X0_GATE(JH7110_STGCLK_USB0_APB, "usb0_apb", 0, JH7110_STGCLK_APB_BUS),
+	JH71X0_GATE(JH7110_STGCLK_USB0_UTMI_APB, "usb0_utmi_apb", 0, JH7110_STGCLK_APB_BUS),
+	JH71X0_GATE(JH7110_STGCLK_USB0_AXI, "usb0_axi", 0, JH7110_STGCLK_STG_AXIAHB),
+	JH71X0_GDIV(JH7110_STGCLK_USB0_LPM, "usb0_lpm", 0, 2, JH7110_STGCLK_OSC),
+	JH71X0_GDIV(JH7110_STGCLK_USB0_STB, "usb0_stb", 0, 4, JH7110_STGCLK_OSC),
+	JH71X0_GATE(JH7110_STGCLK_USB0_APP_125, "usb0_app_125", 0, JH7110_STGCLK_USB_125M),
+	JH71X0__DIV(JH7110_STGCLK_USB0_REFCLK, "usb0_refclk", 2, JH7110_STGCLK_OSC),
+	/* pci-e */
+	JH71X0_GATE(JH7110_STGCLK_PCIE0_AXI_MST0, "pcie0_axi_mst0", 0,
+		    JH7110_STGCLK_STG_AXIAHB),
+	JH71X0_GATE(JH7110_STGCLK_PCIE0_APB, "pcie0_apb", 0, JH7110_STGCLK_APB_BUS),
+	JH71X0_GATE(JH7110_STGCLK_PCIE0_TL, "pcie0_tl", 0, JH7110_STGCLK_STG_AXIAHB),
+	JH71X0_GATE(JH7110_STGCLK_PCIE1_AXI_MST0, "pcie1_axi_mst0", 0,
+		    JH7110_STGCLK_STG_AXIAHB),
+	JH71X0_GATE(JH7110_STGCLK_PCIE1_APB, "pcie1_apb", 0, JH7110_STGCLK_APB_BUS),
+	JH71X0_GATE(JH7110_STGCLK_PCIE1_TL, "pcie1_tl", 0, JH7110_STGCLK_STG_AXIAHB),
+	JH71X0_GATE(JH7110_STGCLK_PCIE01_SLV_DEC_MAINCLK, "pcie01_slv_dec_mainclk",
+		    CLK_IGNORE_UNUSED, JH7110_STGCLK_STG_AXIAHB),
+	/* security */
+	JH71X0_GATE(JH7110_STGCLK_SEC_HCLK, "sec_hclk", 0, JH7110_STGCLK_STG_AXIAHB),
+	JH71X0_GATE(JH7110_STGCLK_SEC_MISCAHB, "sec_miscahb", 0, JH7110_STGCLK_STG_AXIAHB),
+	/* stg mtrx */
+	JH71X0_GATE(JH7110_STGCLK_GRP0_MAIN, "mtrx_grp0_main",
+		    CLK_IGNORE_UNUSED, JH7110_STGCLK_CPU_BUS),
+	JH71X0_GATE(JH7110_STGCLK_GRP0_BUS, "mtrx_grp0_bus",
+		    CLK_IGNORE_UNUSED, JH7110_STGCLK_NOCSTG_BUS),
+	JH71X0_GATE(JH7110_STGCLK_GRP0_STG, "mtrx_grp0_stg",
+		    CLK_IGNORE_UNUSED, JH7110_STGCLK_STG_AXIAHB),
+	JH71X0_GATE(JH7110_STGCLK_GRP1_MAIN, "mtrx_grp1_main",
+		    CLK_IGNORE_UNUSED, JH7110_STGCLK_CPU_BUS),
+	JH71X0_GATE(JH7110_STGCLK_GRP1_BUS, "mtrx_grp1_bus",
+		    CLK_IGNORE_UNUSED, JH7110_STGCLK_NOCSTG_BUS),
+	JH71X0_GATE(JH7110_STGCLK_GRP1_STG, "mtrx_grp1_stg",
+		    CLK_IGNORE_UNUSED, JH7110_STGCLK_STG_AXIAHB),
+	JH71X0_GATE(JH7110_STGCLK_GRP1_HIFI, "mtrx_grp1_hifi",
+		    CLK_IGNORE_UNUSED, JH7110_STGCLK_HIFI4_AXI),
+	/* e24_rvpi */
+	JH71X0_GDIV(JH7110_STGCLK_E2_RTC, "e2_rtc", 0, 24, JH7110_STGCLK_OSC),
+	JH71X0_GATE(JH7110_STGCLK_E2_CORE, "e2_core",
+		    CLK_IGNORE_UNUSED, JH7110_STGCLK_STG_AXIAHB),
+	JH71X0_GATE(JH7110_STGCLK_E2_DBG, "e2_dbg", 0, JH7110_STGCLK_STG_AXIAHB),
+	/* dw_sgdma1p */
+	JH71X0_GATE(JH7110_STGCLK_DMA1P_AXI, "dma1p_axi", 0, JH7110_STGCLK_STG_AXIAHB),
+	JH71X0_GATE(JH7110_STGCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
+};
+
+static struct clk_hw *jh7110_stgclk_get(struct of_phandle_args *clkspec, void *data)
+{
+	struct jh71x0_clk_priv *priv = data;
+	unsigned int idx = clkspec->args[0];
+
+	if (idx < JH7110_STGCLK_END)
+		return &priv->reg[idx].hw;
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int jh7110_stgcrg_probe(struct platform_device *pdev)
+{
+	struct jh71x0_clk_priv *priv;
+	unsigned int idx;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev,
+			    struct_size(priv, reg, JH7110_STGCLK_END),
+			    GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	spin_lock_init(&priv->rmw_lock);
+	priv->dev = &pdev->dev;
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	dev_set_drvdata(priv->dev, (void *)(&priv->base));
+
+	for (idx = 0; idx < JH7110_STGCLK_END; idx++) {
+		u32 max = jh7110_stgclk_data[idx].max;
+		struct clk_parent_data parents[4] = {};
+		struct clk_init_data init = {
+			.name = jh7110_stgclk_data[idx].name,
+			.ops = starfive_jh71x0_clk_ops(max),
+			.parent_data = parents,
+			.num_parents =
+				((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
+			.flags = jh7110_stgclk_data[idx].flags,
+		};
+		struct jh71x0_clk *clk = &priv->reg[idx];
+		unsigned int i;
+		char *fw_name[JH7110_STGCLK_EXT_END - JH7110_STGCLK_END] = {
+			"osc",
+			"hifi4_core",
+			"stg_axiahb",
+			"usb_125m",
+			"cpu_bus",
+			"hifi4_axi",
+			"nocstg_bus",
+			"apb_bus"
+		};
+
+		for (i = 0; i < init.num_parents; i++) {
+			unsigned int pidx = jh7110_stgclk_data[idx].parents[i];
+
+			if (pidx < JH7110_STGCLK_END)
+				parents[i].hw = &priv->reg[pidx].hw;
+			else if (pidx < JH7110_STGCLK_EXT_END)
+				parents[i].fw_name = fw_name[pidx - JH7110_STGCLK_END];
+		}
+
+		clk->hw.init = &init;
+		clk->idx = idx;
+		clk->max_div = max & JH71X0_CLK_DIV_MASK;
+
+		ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
+		if (ret)
+			return ret;
+	}
+
+	ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_stgclk_get, priv);
+	if (ret)
+		return ret;
+
+	return jh7110_reset_controller_register(priv, "reset-stg", 2);
+}
+
+static const struct of_device_id jh7110_stgcrg_match[] = {
+	{ .compatible = "starfive,jh7110-stgcrg" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jh7110_stgcrg_match);
+
+static struct platform_driver jh7110_stgcrg_driver = {
+	.probe = jh7110_stgcrg_probe,
+	.driver = {
+		.name = "clk-starfive-jh7110-stg",
+		.of_match_table = jh7110_stgcrg_match,
+	},
+};
+module_platform_driver(jh7110_stgcrg_driver);
+
+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
+MODULE_DESCRIPTION("StarFive JH7110 System-Top-Group clock driver");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v2 04/11] dt-bindings: clock: Add StarFive JH7110 Image-Signal-Process clock and reset generator
  2023-02-21  8:33 [PATCH v2 00/11] Add new partial clock and reset drivers for StarFive JH7110 Xingyu Wu
                   ` (2 preceding siblings ...)
  2023-02-21  8:33 ` [PATCH v2 03/11] clk: starfive: Add StarFive JH7110 System-Top-Group clock driver Xingyu Wu
@ 2023-02-21  8:33 ` Xingyu Wu
  2023-02-21 11:26   ` Krzysztof Kozlowski
  2023-02-21  8:33 ` [PATCH v2 05/11] reset: starfive: jh7110: Add StarFive Image-Signal-Process reset support Xingyu Wu
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 33+ messages in thread
From: Xingyu Wu @ 2023-02-21  8:33 UTC (permalink / raw)
  To: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, Xingyu Wu, linux-kernel, linux-clk

Add bindings for the Image-Signal-Process clock and reset
generator (ISPCRG) on the JH7110 RISC-V SoC by StarFive Ltd.

Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
---
 .../clock/starfive,jh7110-ispcrg.yaml         | 97 +++++++++++++++++++
 .../dt-bindings/clock/starfive,jh7110-crg.h   | 18 ++++
 .../dt-bindings/reset/starfive,jh7110-crg.h   | 16 +++
 3 files changed, 131 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml

diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml
new file mode 100644
index 000000000000..32794f809364
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jh7110-ispcrg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH7110 Image-Signal-Process Clock and Reset Generator
+
+maintainers:
+  - Xingyu Wu <xingyu.wu@starfivetech.com>
+
+properties:
+  compatible:
+    const: starfive,jh7110-ispcrg
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: ISP Top core
+      - description: ISP Top Axi
+      - description: NOC ISP Bus
+      - description: external DVP
+
+  clock-names:
+    items:
+      - const: isp_top_core
+      - const: isp_top_axi
+      - const: noc_bus_isp_axi
+      - const: dvp_clk
+
+  resets:
+    items:
+      - description: ISP Top core
+      - description: ISP Top Axi
+      - description: NOC ISP Bus
+
+  reset-names:
+    items:
+      - const: isp_top_core
+      - const: isp_top_axi
+      - const: noc_bus_isp_axi
+
+  '#clock-cells':
+    const: 1
+    description:
+      See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
+
+  '#reset-cells':
+    const: 1
+    description:
+      See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
+
+  power-domains:
+    maxItems: 1
+    description:
+      ISP domain power
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - '#clock-cells'
+  - '#reset-cells'
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/starfive,jh7110-crg.h>
+    #include <dt-bindings/power/starfive,jh7110-pmu.h>
+    #include <dt-bindings/reset/starfive,jh7110-crg.h>
+
+    ispcrg: clock-controller@19810000 {
+        compatible = "starfive,jh7110-ispcrg";
+        reg = <0x19810000 0x10000>;
+        clocks = <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
+                 <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>,
+                 <&syscrg JH7110_SYSCLK_NOC_BUS_ISP_AXI>,
+                 <&dvp_clk>;
+        clock-names = "isp_top_core", "isp_top_axi",
+                      "noc_bus_isp_axi", "dvp_clk";
+        resets = <&syscrg JH7110_SYSRST_ISP_TOP>,
+                 <&syscrg JH7110_SYSRST_ISP_TOP_AXI>,
+                 <&syscrg JH7110_SYSRST_NOC_BUS_ISP_AXI>;
+        reset-names = "isp_top_core",
+                      "isp_top_axi",
+                      "noc_bus_isp_axi";
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+        power-domains = <&pwrc JH7110_PD_ISP>;
+    };
diff --git a/include/dt-bindings/clock/starfive,jh7110-crg.h b/include/dt-bindings/clock/starfive,jh7110-crg.h
index 5ac8a4d90a7a..91ee589809c3 100644
--- a/include/dt-bindings/clock/starfive,jh7110-crg.h
+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
@@ -256,4 +256,22 @@
 
 #define JH7110_STGCLK_END			29
 
+/* ISPCRG clocks */
+#define JH7110_ISPCLK_DOM4_APB_FUNC		0
+#define JH7110_ISPCLK_MIPI_RX0_PXL		1
+#define JH7110_ISPCLK_DVP_INV			2
+#define JH7110_ISPCLK_M31DPHY_CFGCLK_IN		3
+#define JH7110_ISPCLK_M31DPHY_REFCLK_IN		4
+#define JH7110_ISPCLK_M31DPHY_TXCLKESC_LAN0	5
+#define JH7110_ISPCLK_VIN_PCLK			6
+#define JH7110_ISPCLK_VIN_SYS_CLK		7
+#define JH7110_ISPCLK_VIN_PIXEL_CLK_IF0		8
+#define JH7110_ISPCLK_VIN_PIXEL_CLK_IF1		9
+#define JH7110_ISPCLK_VIN_PIXEL_CLK_IF2		10
+#define JH7110_ISPCLK_VIN_PIXEL_CLK_IF3		11
+#define JH7110_ISPCLK_VIN_CLK_P_AXIWR		12
+#define JH7110_ISPCLK_ISPV2_TOP_WRAPPER_CLK_C	13
+
+#define JH7110_ISPCLK_END			14
+
 #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
diff --git a/include/dt-bindings/reset/starfive,jh7110-crg.h b/include/dt-bindings/reset/starfive,jh7110-crg.h
index 4a865ded78b8..f23c160ec538 100644
--- a/include/dt-bindings/reset/starfive,jh7110-crg.h
+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
@@ -179,4 +179,20 @@
 
 #define JH7110_STGRST_END			23
 
+/* ISPCRG resets */
+#define JH7110_ISPRST_ISPV2_TOP_WRAPPER_P	0
+#define JH7110_ISPRST_ISPV2_TOP_WRAPPER_C	1
+#define JH7110_ISPRST_M31DPHY_HW		2
+#define JH7110_ISPRST_M31DPHY_B09_ALWAYS_ON	3
+#define JH7110_ISPRST_VIN_PCLK			4
+#define JH7110_ISPRST_VIN_PIXEL_CLK_IF0		5
+#define JH7110_ISPRST_VIN_PIXEL_CLK_IF1		6
+#define JH7110_ISPRST_VIN_PIXEL_CLK_IF2		7
+#define JH7110_ISPRST_VIN_PIXEL_CLK_IF3		8
+#define JH7110_ISPRST_VIN_SYS_CLK		9
+#define JH7110_ISPRST_VIN_P_AXIRD		10
+#define JH7110_ISPRST_VIN_P_AXIWR		11
+
+#define JH7110_ISPRST_END			12
+
 #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v2 05/11] reset: starfive: jh7110: Add StarFive Image-Signal-Process reset support
  2023-02-21  8:33 [PATCH v2 00/11] Add new partial clock and reset drivers for StarFive JH7110 Xingyu Wu
                   ` (3 preceding siblings ...)
  2023-02-21  8:33 ` [PATCH v2 04/11] dt-bindings: clock: Add StarFive JH7110 Image-Signal-Process clock and reset generator Xingyu Wu
@ 2023-02-21  8:33 ` Xingyu Wu
  2023-02-21  8:33 ` [PATCH v2 06/11] clk: starfive: Add StarFive JH7110 Image-Signal-Process clock driver Xingyu Wu
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 33+ messages in thread
From: Xingyu Wu @ 2023-02-21  8:33 UTC (permalink / raw)
  To: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, Xingyu Wu, linux-kernel, linux-clk

Add auxiliary_device_id to support StarFive JH7110 Image-Signal-Process
resets of which the auxiliary device name is
"clk_starfive_jh71x0.reset-isp".

Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
---
 drivers/reset/starfive/reset-starfive-jh7110.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/reset/starfive/reset-starfive-jh7110.c b/drivers/reset/starfive/reset-starfive-jh7110.c
index 94ebb363c6bc..e3b7b6941217 100644
--- a/drivers/reset/starfive/reset-starfive-jh7110.c
+++ b/drivers/reset/starfive/reset-starfive-jh7110.c
@@ -46,6 +46,12 @@ static const struct reset_info jh7110_stg_info = {
 	.status_offset = 0x78,
 };
 
+static const struct reset_info jh7110_isp_info = {
+	.nr_resets = JH7110_ISPRST_END,
+	.assert_offset = 0x38,
+	.status_offset = 0x3C,
+};
+
 static const struct auxiliary_device_id jh7110_reset_ids[] = {
 	{
 		.name = "clk_starfive_jh71x0.reset-sys",
@@ -59,6 +65,10 @@ static const struct auxiliary_device_id jh7110_reset_ids[] = {
 		.name = "clk_starfive_jh71x0.reset-stg",
 		.driver_data = (kernel_ulong_t)&jh7110_stg_info,
 	},
+	{
+		.name = "clk_starfive_jh71x0.reset-isp",
+		.driver_data = (kernel_ulong_t)&jh7110_isp_info,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(auxiliary, jh7110_reset_ids);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v2 06/11] clk: starfive: Add StarFive JH7110 Image-Signal-Process clock driver
  2023-02-21  8:33 [PATCH v2 00/11] Add new partial clock and reset drivers for StarFive JH7110 Xingyu Wu
                   ` (4 preceding siblings ...)
  2023-02-21  8:33 ` [PATCH v2 05/11] reset: starfive: jh7110: Add StarFive Image-Signal-Process reset support Xingyu Wu
@ 2023-02-21  8:33 ` Xingyu Wu
  2023-03-02 15:39   ` Emil Renner Berthing
  2023-02-21  8:33 ` [PATCH v2 07/11] dt-bindings: clock: Add StarFive JH7110 Video-Output clock and reset generator Xingyu Wu
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 33+ messages in thread
From: Xingyu Wu @ 2023-02-21  8:33 UTC (permalink / raw)
  To: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, Xingyu Wu, linux-kernel, linux-clk

Add driver for the StarFive JH7110 Image-Signal-Process clock controller.

Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
---
 drivers/clk/starfive/Kconfig                  |  11 +
 drivers/clk/starfive/Makefile                 |   1 +
 .../clk/starfive/clk-starfive-jh7110-isp.c    | 254 ++++++++++++++++++
 3 files changed, 266 insertions(+)
 create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-isp.c

diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index a462b6e53543..59499acb95f7 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -53,3 +53,14 @@ config CLK_STARFIVE_JH7110_STG
 	help
 	  Say yes here to support the System-Top-Group clock controller
 	  on the StarFive JH7110 SoC.
+
+config CLK_STARFIVE_JH7110_ISP
+	tristate "StarFive JH7110 Image-Signal-Process clock support"
+	depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
+	select AUXILIARY_BUS
+	select CLK_STARFIVE_JH71X0
+	select RESET_STARFIVE_JH7110
+	default CLK_STARFIVE_JH7110_SYS
+	help
+	  Say yes here to support the Image-Signal-Process clock controller
+	  on the StarFive JH7110 SoC.
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
index b81e97ee2659..76fb9f8d628b 100644
--- a/drivers/clk/starfive/Makefile
+++ b/drivers/clk/starfive/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO)	+= clk-starfive-jh7100-audio.o
 obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS)	+= clk-starfive-jh7110-sys.o
 obj-$(CONFIG_CLK_STARFIVE_JH7110_AON)	+= clk-starfive-jh7110-aon.o
 obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)	+= clk-starfive-jh7110-stg.o
+obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP)	+= clk-starfive-jh7110-isp.o
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-isp.c b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
new file mode 100644
index 000000000000..b5bce1ac22e0
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
@@ -0,0 +1,254 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive JH7110 Image-Signal-Process Clock Driver
+ *
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include <dt-bindings/clock/starfive,jh7110-crg.h>
+
+#include "clk-starfive-jh71x0.h"
+
+/* external clocks */
+#define JH7110_ISPCLK_ISP_TOP_CORE		(JH7110_ISPCLK_END + 0)
+#define JH7110_ISPCLK_ISP_TOP_AXI		(JH7110_ISPCLK_END + 1)
+#define JH7110_ISPCLK_NOC_BUS_ISP_AXI		(JH7110_ISPCLK_END + 2)
+#define JH7110_ISPCLK_DVP_CLK			(JH7110_ISPCLK_END + 3)
+#define JH7110_ISPCLK_EXT_END			(JH7110_ISPCLK_END + 4)
+
+static const struct jh71x0_clk_data jh7110_ispclk_data[] = {
+	/* syscon */
+	JH71X0__DIV(JH7110_ISPCLK_DOM4_APB_FUNC, "dom4_apb_func", 15,
+		    JH7110_ISPCLK_ISP_TOP_AXI),
+	JH71X0__DIV(JH7110_ISPCLK_MIPI_RX0_PXL, "mipi_rx0_pxl", 8,
+		    JH7110_ISPCLK_ISP_TOP_CORE),
+	JH71X0__INV(JH7110_ISPCLK_DVP_INV, "dvp_inv", JH7110_ISPCLK_DVP_CLK),
+	/* vin */
+	JH71X0__DIV(JH7110_ISPCLK_M31DPHY_CFGCLK_IN, "m31dphy_cfgclk_in", 16,
+		    JH7110_ISPCLK_ISP_TOP_CORE),
+	JH71X0__DIV(JH7110_ISPCLK_M31DPHY_REFCLK_IN, "m31dphy_refclk_in", 16,
+		    JH7110_ISPCLK_ISP_TOP_CORE),
+	JH71X0__DIV(JH7110_ISPCLK_M31DPHY_TXCLKESC_LAN0, "m31dphy_txclkesc_lan0", 60,
+		    JH7110_ISPCLK_ISP_TOP_CORE),
+	JH71X0_GATE(JH7110_ISPCLK_VIN_PCLK, "vin_pclk", CLK_IGNORE_UNUSED,
+		    JH7110_ISPCLK_DOM4_APB_FUNC),
+	JH71X0__DIV(JH7110_ISPCLK_VIN_SYS_CLK, "vin_sys_clk", 8, JH7110_ISPCLK_ISP_TOP_CORE),
+	JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF0, "vin_pixel_clk_if0", CLK_IGNORE_UNUSED,
+		    JH7110_ISPCLK_MIPI_RX0_PXL),
+	JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF1, "vin_pixel_clk_if1", CLK_IGNORE_UNUSED,
+		    JH7110_ISPCLK_MIPI_RX0_PXL),
+	JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF2, "vin_pixel_clk_if2", CLK_IGNORE_UNUSED,
+		    JH7110_ISPCLK_MIPI_RX0_PXL),
+	JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF3, "vin_pixel_clk_if3", CLK_IGNORE_UNUSED,
+		    JH7110_ISPCLK_MIPI_RX0_PXL),
+	JH71X0__MUX(JH7110_ISPCLK_VIN_CLK_P_AXIWR, "vin_clk_p_axiwr", 2,
+		    JH7110_ISPCLK_MIPI_RX0_PXL,
+		    JH7110_ISPCLK_DVP_INV),
+	/* ispv2_top_wrapper */
+	JH71X0_GMUX(JH7110_ISPCLK_ISPV2_TOP_WRAPPER_CLK_C, "ispv2_top_wrapper_clk_c",
+		    CLK_IGNORE_UNUSED, 2,
+		    JH7110_ISPCLK_MIPI_RX0_PXL,
+		    JH7110_ISPCLK_DVP_INV),
+};
+
+struct isp_top_crg {
+	struct clk_bulk_data *top_clks;
+	struct reset_control *top_rsts;
+	int top_clks_num;
+	void __iomem *base;
+};
+
+static struct clk_bulk_data jh7110_isp_top_clks[] = {
+	{ .id = "isp_top_core" },
+	{ .id = "isp_top_axi" }
+};
+
+static struct isp_top_crg *top_crg_from(void __iomem **base)
+{
+	return container_of(base, struct isp_top_crg, base);
+}
+
+static int jh7110_isp_top_crg_get(struct jh71x0_clk_priv *priv, struct isp_top_crg *top)
+{
+	int ret;
+
+	top->top_clks = jh7110_isp_top_clks;
+	top->top_clks_num = ARRAY_SIZE(jh7110_isp_top_clks);
+	ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
+	if (ret) {
+		dev_err(priv->dev, "top clks get failed: %d\n", ret);
+		return ret;
+	}
+
+	/* The resets should be shared and other ISP modules will use its. */
+	top->top_rsts = devm_reset_control_array_get_shared(priv->dev);
+	if (IS_ERR(top->top_rsts)) {
+		dev_err(priv->dev, "top rsts get failed\n");
+		return PTR_ERR(top->top_rsts);
+	}
+
+	return 0;
+}
+
+static int jh7110_isp_top_crg_enable(struct isp_top_crg *top)
+{
+	int ret;
+
+	ret = clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
+	if (ret)
+		return ret;
+
+	return reset_control_deassert(top->top_rsts);
+}
+
+static void jh7110_isp_top_crg_disable(struct isp_top_crg *top)
+{
+	clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
+}
+
+static struct clk_hw *jh7110_ispclk_get(struct of_phandle_args *clkspec, void *data)
+{
+	struct jh71x0_clk_priv *priv = data;
+	unsigned int idx = clkspec->args[0];
+
+	if (idx < JH7110_ISPCLK_END)
+		return &priv->reg[idx].hw;
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int jh7110_ispcrg_probe(struct platform_device *pdev)
+{
+	struct jh71x0_clk_priv *priv;
+	struct isp_top_crg *top;
+	unsigned int idx;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev,
+			    struct_size(priv, reg, JH7110_ISPCLK_END),
+			    GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
+	if (!top)
+		return -ENOMEM;
+
+	spin_lock_init(&priv->rmw_lock);
+	priv->dev = &pdev->dev;
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	top->base = priv->base;
+	dev_set_drvdata(priv->dev, (void *)(&top->base));
+
+	pm_runtime_enable(priv->dev);
+	ret = pm_runtime_get_sync(priv->dev);
+	if (ret < 0) {
+		dev_err(priv->dev, "failed to turn on power: %d\n", ret);
+		return ret;
+	}
+
+	ret = jh7110_isp_top_crg_get(priv, top);
+	if (ret)
+		goto err_clk;
+
+	ret = jh7110_isp_top_crg_enable(top);
+	if (ret)
+		goto err_clk;
+
+	for (idx = 0; idx < JH7110_ISPCLK_END; idx++) {
+		u32 max = jh7110_ispclk_data[idx].max;
+		struct clk_parent_data parents[4] = {};
+		struct clk_init_data init = {
+			.name = jh7110_ispclk_data[idx].name,
+			.ops = starfive_jh71x0_clk_ops(max),
+			.parent_data = parents,
+			.num_parents =
+				((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
+			.flags = jh7110_ispclk_data[idx].flags,
+		};
+		struct jh71x0_clk *clk = &priv->reg[idx];
+		unsigned int i;
+		char *fw_name[JH7110_ISPCLK_EXT_END - JH7110_ISPCLK_END] = {
+			"isp_top_core",
+			"isp_top_axi",
+			"noc_bus_isp_axi",
+			"dvp_clk"
+		};
+
+		for (i = 0; i < init.num_parents; i++) {
+			unsigned int pidx = jh7110_ispclk_data[idx].parents[i];
+
+			if (pidx < JH7110_ISPCLK_END)
+				parents[i].hw = &priv->reg[pidx].hw;
+			else
+				parents[i].fw_name = fw_name[pidx - JH7110_ISPCLK_END];
+		}
+
+		clk->hw.init = &init;
+		clk->idx = idx;
+		clk->max_div = max & JH71X0_CLK_DIV_MASK;
+
+		ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
+		if (ret)
+			goto err_exit;
+	}
+
+	ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_ispclk_get, priv);
+	if (ret)
+		goto err_exit;
+
+	ret = jh7110_reset_controller_register(priv, "reset-isp", 3);
+	if (ret)
+		goto err_exit;
+
+	return 0;
+
+err_exit:
+	jh7110_isp_top_crg_disable(top);
+err_clk:
+	pm_runtime_put_sync(priv->dev);
+	pm_runtime_disable(priv->dev);
+	return ret;
+}
+
+static int jh7110_ispcrg_remove(struct platform_device *pdev)
+{
+	void __iomem **base = dev_get_drvdata(&pdev->dev);
+	struct isp_top_crg *top = top_crg_from(base);
+
+	jh7110_isp_top_crg_disable(top);
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id jh7110_ispcrg_match[] = {
+	{ .compatible = "starfive,jh7110-ispcrg" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jh7110_ispcrg_match);
+
+static struct platform_driver jh7110_ispcrg_driver = {
+	.probe = jh7110_ispcrg_probe,
+	.remove = jh7110_ispcrg_remove,
+	.driver = {
+		.name = "clk-starfive-jh7110-isp",
+		.of_match_table = jh7110_ispcrg_match,
+	},
+};
+module_platform_driver(jh7110_ispcrg_driver);
+
+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
+MODULE_DESCRIPTION("StarFive JH7110 Image-Signal-Process clock driver");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v2 07/11] dt-bindings: clock: Add StarFive JH7110 Video-Output clock and reset generator
  2023-02-21  8:33 [PATCH v2 00/11] Add new partial clock and reset drivers for StarFive JH7110 Xingyu Wu
                   ` (5 preceding siblings ...)
  2023-02-21  8:33 ` [PATCH v2 06/11] clk: starfive: Add StarFive JH7110 Image-Signal-Process clock driver Xingyu Wu
@ 2023-02-21  8:33 ` Xingyu Wu
  2023-02-21 11:27   ` Krzysztof Kozlowski
  2023-02-21  8:33 ` [PATCH v2 08/11] reset: starfive: jh7110: Add StarFive Video-Output reset support Xingyu Wu
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 33+ messages in thread
From: Xingyu Wu @ 2023-02-21  8:33 UTC (permalink / raw)
  To: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, Xingyu Wu, linux-kernel, linux-clk

Add bindings for the Video-Output clock and reset generator (VOUTCRG)
on the JH7110 RISC-V SoC by StarFive Ltd.

Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
---
 .../clock/starfive,jh7110-voutcrg.yaml        | 96 +++++++++++++++++++
 .../dt-bindings/clock/starfive,jh7110-crg.h   | 22 +++++
 .../dt-bindings/reset/starfive,jh7110-crg.h   | 16 ++++
 3 files changed, 134 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml

diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml
new file mode 100644
index 000000000000..a6a43d86a392
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jh7110-voutcrg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH7110 Video-Output Clock and Reset Generator
+
+maintainers:
+  - Xingyu Wu <xingyu.wu@starfivetech.com>
+
+properties:
+  compatible:
+    const: starfive,jh7110-voutcrg
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Vout Top core
+      - description: Vout Top Ahb
+      - description: Vout Top Axi
+      - description: Vout Top HDMI MCLK
+      - description: I2STX0 BCLK
+      - description: external HDMI pixel
+
+  clock-names:
+    items:
+      - const: vout_src
+      - const: vout_top_ahb
+      - const: vout_top_axi
+      - const: vout_top_hdmitx0_mclk
+      - const: i2stx0_bclk
+      - const: hdmitx0_pixelclk
+
+  resets:
+    items:
+      - description: Vout Top core
+
+  reset-names:
+    items:
+      - const: vout_top_src
+
+  '#clock-cells':
+    const: 1
+    description:
+      See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
+
+  '#reset-cells':
+    const: 1
+    description:
+      See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
+
+  power-domains:
+    maxItems: 1
+    description:
+      Vout domain power
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - '#clock-cells'
+  - '#reset-cells'
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/starfive,jh7110-crg.h>
+    #include <dt-bindings/power/starfive,jh7110-pmu.h>
+    #include <dt-bindings/reset/starfive,jh7110-crg.h>
+
+    voutcrg: clock-controller@295C0000 {
+        compatible = "starfive,jh7110-voutcrg";
+        reg = <0x295C0000 0x10000>;
+        clocks = <&syscrg JH7110_SYSCLK_VOUT_SRC>,
+                 <&syscrg JH7110_SYSCLK_VOUT_TOP_AHB>,
+                 <&syscrg JH7110_SYSCLK_VOUT_TOP_AXI>,
+                 <&syscrg JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK>,
+                 <&syscrg JH7110_SYSCLK_I2STX0_BCLK>,
+                 <&hdmitx0_pixelclk>;
+        clock-names = "vout_src", "vout_top_ahb",
+                      "vout_top_axi", "vout_top_hdmitx0_mclk",
+                      "i2stx0_bclk", "hdmitx0_pixelclk";
+        resets = <&syscrg JH7110_SYSRST_VOUT_TOP_SRC>;
+        reset-names = "vout_top_src";
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+        power-domains = <&pwrc JH7110_PD_VOUT>;
+    };
diff --git a/include/dt-bindings/clock/starfive,jh7110-crg.h b/include/dt-bindings/clock/starfive,jh7110-crg.h
index 91ee589809c3..3ebece93cbd3 100644
--- a/include/dt-bindings/clock/starfive,jh7110-crg.h
+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
@@ -274,4 +274,26 @@
 
 #define JH7110_ISPCLK_END			14
 
+/* VOUTCRG clocks */
+#define JH7110_VOUTCLK_APB			0
+#define JH7110_VOUTCLK_DC8200_PIX		1
+#define JH7110_VOUTCLK_DSI_SYS			2
+#define JH7110_VOUTCLK_TX_ESC			3
+#define JH7110_VOUTCLK_DC8200_AXI		4
+#define JH7110_VOUTCLK_DC8200_CORE		5
+#define JH7110_VOUTCLK_DC8200_AHB		6
+#define JH7110_VOUTCLK_DC8200_PIX0		7
+#define JH7110_VOUTCLK_DC8200_PIX1		8
+#define JH7110_VOUTCLK_DOM_VOUT_TOP_LCD		9
+#define JH7110_VOUTCLK_DSITX_APB		10
+#define JH7110_VOUTCLK_DSITX_SYS		11
+#define JH7110_VOUTCLK_DSITX_DPI		12
+#define JH7110_VOUTCLK_DSITX_TXESC		13
+#define JH7110_VOUTCLK_MIPITX_DPHY_TXESC	14
+#define JH7110_VOUTCLK_HDMI_TX_MCLK		15
+#define JH7110_VOUTCLK_HDMI_TX_BCLK		16
+#define JH7110_VOUTCLK_HDMI_TX_SYS		17
+
+#define JH7110_VOUTCLK_END			18
+
 #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
diff --git a/include/dt-bindings/reset/starfive,jh7110-crg.h b/include/dt-bindings/reset/starfive,jh7110-crg.h
index f23c160ec538..3a3a14bed136 100644
--- a/include/dt-bindings/reset/starfive,jh7110-crg.h
+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
@@ -195,4 +195,20 @@
 
 #define JH7110_ISPRST_END			12
 
+/* VOUTCRG resets */
+#define JH7110_VOUTRST_DC8200_AXI		0
+#define JH7110_VOUTRST_DC8200_AHB		1
+#define JH7110_VOUTRST_DC8200_CORE		2
+#define JH7110_VOUTRST_DSITX_DPI		3
+#define JH7110_VOUTRST_DSITX_APB		4
+#define JH7110_VOUTRST_DSITX_RXESC		5
+#define JH7110_VOUTRST_DSITX_SYS		6
+#define JH7110_VOUTRST_DSITX_TXBYTEHS		7
+#define JH7110_VOUTRST_DSITX_TXESC		8
+#define JH7110_VOUTRST_HDMI_TX_HDMI		9
+#define JH7110_VOUTRST_MIPITX_DPHY_SYS		10
+#define JH7110_VOUTRST_MIPITX_DPHY_TXBYTEHS	11
+
+#define JH7110_VOUTRST_END			12
+
 #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v2 08/11] reset: starfive: jh7110: Add StarFive Video-Output reset support
  2023-02-21  8:33 [PATCH v2 00/11] Add new partial clock and reset drivers for StarFive JH7110 Xingyu Wu
                   ` (6 preceding siblings ...)
  2023-02-21  8:33 ` [PATCH v2 07/11] dt-bindings: clock: Add StarFive JH7110 Video-Output clock and reset generator Xingyu Wu
@ 2023-02-21  8:33 ` Xingyu Wu
  2023-02-21  8:33 ` [PATCH v2 09/11] clk: starfive: Add StarFive JH7110 Video-Output clock driver Xingyu Wu
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 33+ messages in thread
From: Xingyu Wu @ 2023-02-21  8:33 UTC (permalink / raw)
  To: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, Xingyu Wu, linux-kernel, linux-clk

Add auxiliary_device_id to support StarFive JH7110 Video-Output resets
of which the auxiliary device name is "clk_starfive_jh71x0.reset-vout".

Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
---
 drivers/reset/starfive/reset-starfive-jh7110.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/reset/starfive/reset-starfive-jh7110.c b/drivers/reset/starfive/reset-starfive-jh7110.c
index e3b7b6941217..ad967398f227 100644
--- a/drivers/reset/starfive/reset-starfive-jh7110.c
+++ b/drivers/reset/starfive/reset-starfive-jh7110.c
@@ -52,6 +52,12 @@ static const struct reset_info jh7110_isp_info = {
 	.status_offset = 0x3C,
 };
 
+static const struct reset_info jh7110_vout_info = {
+	.nr_resets = JH7110_VOUTRST_END,
+	.assert_offset = 0x48,
+	.status_offset = 0x4C,
+};
+
 static const struct auxiliary_device_id jh7110_reset_ids[] = {
 	{
 		.name = "clk_starfive_jh71x0.reset-sys",
@@ -69,6 +75,10 @@ static const struct auxiliary_device_id jh7110_reset_ids[] = {
 		.name = "clk_starfive_jh71x0.reset-isp",
 		.driver_data = (kernel_ulong_t)&jh7110_isp_info,
 	},
+	{
+		.name = "clk_starfive_jh71x0.reset-vout",
+		.driver_data = (kernel_ulong_t)&jh7110_vout_info,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(auxiliary, jh7110_reset_ids);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v2 09/11] clk: starfive: Add StarFive JH7110 Video-Output clock driver
  2023-02-21  8:33 [PATCH v2 00/11] Add new partial clock and reset drivers for StarFive JH7110 Xingyu Wu
                   ` (7 preceding siblings ...)
  2023-02-21  8:33 ` [PATCH v2 08/11] reset: starfive: jh7110: Add StarFive Video-Output reset support Xingyu Wu
@ 2023-02-21  8:33 ` Xingyu Wu
  2023-03-02 15:48   ` Emil Renner Berthing
  2023-02-21  8:33 ` [PATCH v2 10/11] riscv: dts: starfive: jh7110: Add DVP and HDMI TX pixel external clocks Xingyu Wu
  2023-02-21  8:33 ` [PATCH v2 11/11] riscv: dts: starfive: jh7110: Add STGCRG/ISPCRG/VOUTCRG nodes Xingyu Wu
  10 siblings, 1 reply; 33+ messages in thread
From: Xingyu Wu @ 2023-02-21  8:33 UTC (permalink / raw)
  To: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, Xingyu Wu, linux-kernel, linux-clk

Add driver for the StarFive JH7110 Video-Output clock controller.

Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
---
 drivers/clk/starfive/Kconfig                  |  11 +
 drivers/clk/starfive/Makefile                 |   1 +
 .../clk/starfive/clk-starfive-jh7110-vout.c   | 261 ++++++++++++++++++
 3 files changed, 273 insertions(+)
 create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-vout.c

diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index 59499acb95f7..5ebf1ed08627 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -64,3 +64,14 @@ config CLK_STARFIVE_JH7110_ISP
 	help
 	  Say yes here to support the Image-Signal-Process clock controller
 	  on the StarFive JH7110 SoC.
+
+config CLK_STARFIVE_JH7110_VOUT
+	tristate "StarFive JH7110 Video-Output clock support"
+	depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
+	select AUXILIARY_BUS
+	select CLK_STARFIVE_JH71X0
+	select RESET_STARFIVE_JH7110
+	default CLK_STARFIVE_JH7110_SYS
+	help
+	  Say yes here to support the Video-Output clock controller
+	  on the StarFive JH7110 SoC.
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
index 76fb9f8d628b..841377e45bb6 100644
--- a/drivers/clk/starfive/Makefile
+++ b/drivers/clk/starfive/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS)	+= clk-starfive-jh7110-sys.o
 obj-$(CONFIG_CLK_STARFIVE_JH7110_AON)	+= clk-starfive-jh7110-aon.o
 obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)	+= clk-starfive-jh7110-stg.o
 obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP)	+= clk-starfive-jh7110-isp.o
+obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT)	+= clk-starfive-jh7110-vout.o
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-vout.c b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
new file mode 100644
index 000000000000..d786537563a4
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
@@ -0,0 +1,261 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive JH7110 Video-Output Clock Driver
+ *
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include <dt-bindings/clock/starfive,jh7110-crg.h>
+
+#include "clk-starfive-jh71x0.h"
+
+/* external clocks */
+#define JH7110_VOUTCLK_VOUT_SRC			(JH7110_VOUTCLK_END + 0)
+#define JH7110_VOUTCLK_VOUT_TOP_AHB		(JH7110_VOUTCLK_END + 1)
+#define JH7110_VOUTCLK_VOUT_TOP_AXI		(JH7110_VOUTCLK_END + 2)
+#define JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK	(JH7110_VOUTCLK_END + 3)
+#define JH7110_VOUTCLK_I2STX0_BCLK		(JH7110_VOUTCLK_END + 4)
+#define JH7110_VOUTCLK_HDMITX0_PIXELCLK		(JH7110_VOUTCLK_END + 5)
+#define JH7110_VOUTCLK_EXT_END			(JH7110_VOUTCLK_END + 6)
+
+static const struct jh71x0_clk_data jh7110_voutclk_data[] = {
+	/* divider */
+	JH71X0__DIV(JH7110_VOUTCLK_APB, "apb", 8, JH7110_VOUTCLK_VOUT_TOP_AHB),
+	JH71X0__DIV(JH7110_VOUTCLK_DC8200_PIX, "dc8200_pix", 63, JH7110_VOUTCLK_VOUT_SRC),
+	JH71X0__DIV(JH7110_VOUTCLK_DSI_SYS, "dsi_sys", 31, JH7110_VOUTCLK_VOUT_SRC),
+	JH71X0__DIV(JH7110_VOUTCLK_TX_ESC, "tx_esc", 31, JH7110_VOUTCLK_VOUT_TOP_AHB),
+	/* dc8200 */
+	JH71X0_GATE(JH7110_VOUTCLK_DC8200_AXI, "dc8200_axi", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
+	JH71X0_GATE(JH7110_VOUTCLK_DC8200_CORE, "dc8200_core", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
+	JH71X0_GATE(JH7110_VOUTCLK_DC8200_AHB, "dc8200_ahb", 0, JH7110_VOUTCLK_VOUT_TOP_AHB),
+	JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX0, "dc8200_pix0", 0, 2,
+		    JH7110_VOUTCLK_DC8200_PIX,
+		    JH7110_VOUTCLK_HDMITX0_PIXELCLK),
+	JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX1, "dc8200_pix1", 0, 2,
+		    JH7110_VOUTCLK_DC8200_PIX,
+		    JH7110_VOUTCLK_HDMITX0_PIXELCLK),
+	/* LCD */
+	JH71X0_GMUX(JH7110_VOUTCLK_DOM_VOUT_TOP_LCD, "dom_vout_top_lcd", 0, 2,
+		    JH7110_VOUTCLK_DC8200_PIX0,
+		    JH7110_VOUTCLK_DC8200_PIX1),
+	/* dsiTx */
+	JH71X0_GATE(JH7110_VOUTCLK_DSITX_APB, "dsiTx_apb", 0, JH7110_VOUTCLK_DSI_SYS),
+	JH71X0_GATE(JH7110_VOUTCLK_DSITX_SYS, "dsiTx_sys", 0, JH7110_VOUTCLK_DSI_SYS),
+	JH71X0_GMUX(JH7110_VOUTCLK_DSITX_DPI, "dsiTx_dpi", 0, 2,
+		    JH7110_VOUTCLK_DC8200_PIX,
+		    JH7110_VOUTCLK_HDMITX0_PIXELCLK),
+	JH71X0_GATE(JH7110_VOUTCLK_DSITX_TXESC, "dsiTx_txesc", 0, JH7110_VOUTCLK_TX_ESC),
+	/* mipitx DPHY */
+	JH71X0_GATE(JH7110_VOUTCLK_MIPITX_DPHY_TXESC, "mipitx_dphy_txesc", 0,
+		    JH7110_VOUTCLK_TX_ESC),
+	/* hdmi */
+	JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_MCLK, "hdmi_tx_mclk", 0,
+		    JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK),
+	JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_BCLK, "hdmi_tx_bclk", 0,
+		    JH7110_VOUTCLK_I2STX0_BCLK),
+	JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_SYS, "hdmi_tx_sys", 0, JH7110_VOUTCLK_APB),
+};
+
+struct vout_top_crg {
+	struct clk_bulk_data *top_clks;
+	struct reset_control *top_rst;
+	int top_clks_num;
+	void __iomem *base;
+};
+
+static struct clk_bulk_data jh7110_vout_top_clks[] = {
+	{ .id = "vout_src" },
+	{ .id = "vout_top_ahb" }
+};
+
+static struct vout_top_crg *top_crg_from(void __iomem **base)
+{
+	return container_of(base, struct vout_top_crg, base);
+}
+
+static int jh7110_vout_top_crg_get(struct jh71x0_clk_priv *priv, struct vout_top_crg *top)
+{
+	int ret;
+
+	top->top_clks = jh7110_vout_top_clks;
+	top->top_clks_num = ARRAY_SIZE(jh7110_vout_top_clks);
+	ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
+	if (ret) {
+		dev_err(priv->dev, "top clks get failed: %d\n", ret);
+		return ret;
+	}
+
+	/* The reset should be shared and other Vout modules will use its. */
+	top->top_rst = devm_reset_control_get_shared(priv->dev, NULL);
+	if (IS_ERR(top->top_rst)) {
+		dev_err(priv->dev, "top rst get failed\n");
+		return PTR_ERR(top->top_rst);
+	}
+
+	return 0;
+}
+
+static int jh7110_vout_top_crg_enable(struct vout_top_crg *top)
+{
+	int ret;
+
+	ret = clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
+	if (ret)
+		return ret;
+
+	return reset_control_deassert(top->top_rst);
+}
+
+static void jh7110_vout_top_crg_disable(struct vout_top_crg *top)
+{
+	clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
+}
+
+static struct clk_hw *jh7110_voutclk_get(struct of_phandle_args *clkspec, void *data)
+{
+	struct jh71x0_clk_priv *priv = data;
+	unsigned int idx = clkspec->args[0];
+
+	if (idx < JH7110_VOUTCLK_END)
+		return &priv->reg[idx].hw;
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int jh7110_voutcrg_probe(struct platform_device *pdev)
+{
+	struct jh71x0_clk_priv *priv;
+	struct vout_top_crg *top;
+	unsigned int idx;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev,
+			    struct_size(priv, reg, JH7110_VOUTCLK_END),
+			    GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
+	if (!top)
+		return -ENOMEM;
+
+	spin_lock_init(&priv->rmw_lock);
+	priv->dev = &pdev->dev;
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	top->base = priv->base;
+	dev_set_drvdata(priv->dev, (void *)(&top->base));
+
+	pm_runtime_enable(priv->dev);
+	ret = pm_runtime_get_sync(priv->dev);
+	if (ret < 0) {
+		dev_err(priv->dev, "failed to turn power: %d\n", ret);
+		return ret;
+	}
+
+	ret = jh7110_vout_top_crg_get(priv, top);
+	if (ret)
+		goto err_clk;
+
+	ret = jh7110_vout_top_crg_enable(top);
+	if (ret)
+		goto err_clk;
+
+	for (idx = 0; idx < JH7110_VOUTCLK_END; idx++) {
+		u32 max = jh7110_voutclk_data[idx].max;
+		struct clk_parent_data parents[4] = {};
+		struct clk_init_data init = {
+			.name = jh7110_voutclk_data[idx].name,
+			.ops = starfive_jh71x0_clk_ops(max),
+			.parent_data = parents,
+			.num_parents =
+				((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
+			.flags = jh7110_voutclk_data[idx].flags,
+		};
+		struct jh71x0_clk *clk = &priv->reg[idx];
+		unsigned int i;
+		char *fw_name[JH7110_VOUTCLK_EXT_END - JH7110_VOUTCLK_END] = {
+			"vout_src",
+			"vout_top_ahb",
+			"vout_top_axi",
+			"vout_top_hdmitx0_mclk",
+			"i2stx0_bclk",
+			"hdmitx0_pixelclk"
+		};
+
+		for (i = 0; i < init.num_parents; i++) {
+			unsigned int pidx = jh7110_voutclk_data[idx].parents[i];
+
+			if (pidx < JH7110_VOUTCLK_END)
+				parents[i].hw = &priv->reg[pidx].hw;
+			else if (pidx < JH7110_VOUTCLK_EXT_END)
+				parents[i].fw_name = fw_name[pidx - JH7110_VOUTCLK_END];
+		}
+
+		clk->hw.init = &init;
+		clk->idx = idx;
+		clk->max_div = max & JH71X0_CLK_DIV_MASK;
+
+		ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
+		if (ret)
+			goto err_exit;
+	}
+
+	ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_voutclk_get, priv);
+	if (ret)
+		goto err_exit;
+
+	ret = jh7110_reset_controller_register(priv, "reset-vout", 4);
+	if (ret)
+		goto err_exit;
+
+	return 0;
+
+err_exit:
+	jh7110_vout_top_crg_disable(top);
+err_clk:
+	pm_runtime_put_sync(priv->dev);
+	pm_runtime_disable(priv->dev);
+	return ret;
+}
+
+static int jh7110_voutcrg_remove(struct platform_device *pdev)
+{
+	void __iomem **base = dev_get_drvdata(&pdev->dev);
+	struct vout_top_crg *top = top_crg_from(base);
+
+	jh7110_vout_top_crg_disable(top);
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id jh7110_voutcrg_match[] = {
+	{ .compatible = "starfive,jh7110-voutcrg" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jh7110_voutcrg_match);
+
+static struct platform_driver jh7110_voutcrg_driver = {
+	.probe = jh7110_voutcrg_probe,
+	.remove = jh7110_voutcrg_remove,
+	.driver = {
+		.name = "clk-starfive-jh7110-vout",
+		.of_match_table = jh7110_voutcrg_match,
+	},
+};
+module_platform_driver(jh7110_voutcrg_driver);
+
+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
+MODULE_DESCRIPTION("StarFive JH7110 Video-Output clock driver");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v2 10/11] riscv: dts: starfive: jh7110: Add DVP and HDMI TX pixel external clocks
  2023-02-21  8:33 [PATCH v2 00/11] Add new partial clock and reset drivers for StarFive JH7110 Xingyu Wu
                   ` (8 preceding siblings ...)
  2023-02-21  8:33 ` [PATCH v2 09/11] clk: starfive: Add StarFive JH7110 Video-Output clock driver Xingyu Wu
@ 2023-02-21  8:33 ` Xingyu Wu
  2023-02-27 19:55   ` Conor Dooley
  2023-02-21  8:33 ` [PATCH v2 11/11] riscv: dts: starfive: jh7110: Add STGCRG/ISPCRG/VOUTCRG nodes Xingyu Wu
  10 siblings, 1 reply; 33+ messages in thread
From: Xingyu Wu @ 2023-02-21  8:33 UTC (permalink / raw)
  To: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, Xingyu Wu, linux-kernel, linux-clk

Add DVP and HDMI TX pixel external fixed clocks and the rates are
74.25MHz and 297MHz.

Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
---
 .../dts/starfive/jh7110-starfive-visionfive-2.dtsi   |  8 ++++++++
 arch/riscv/boot/dts/starfive/jh7110.dtsi             | 12 ++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
index c2aa8946a0f1..27af817a55aa 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
@@ -86,6 +86,14 @@ &mclk_ext {
 	clock-frequency = <12288000>;
 };
 
+&dvp_clk {
+	clock-frequency = <74250000>;
+};
+
+&hdmitx0_pixelclk {
+	clock-frequency = <297000000>;
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pins>;
diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
index 005ead2624d4..a5e6fb3ad188 100644
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
@@ -245,6 +245,18 @@ mclk_ext: mclk-ext-clock {
 		#clock-cells = <0>;
 	};
 
+	dvp_clk: dvp-clk-clock {
+		compatible = "fixed-clock";
+		clock-output-names = "dvp_clk";
+		#clock-cells = <0>;
+	};
+
+	hdmitx0_pixelclk: hdmitx0-pixelclk-clock {
+		compatible = "fixed-clock";
+		clock-output-names = "hdmitx0_pixelclk";
+		#clock-cells = <0>;
+	};
+
 	soc {
 		compatible = "simple-bus";
 		interrupt-parent = <&plic>;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v2 11/11] riscv: dts: starfive: jh7110: Add STGCRG/ISPCRG/VOUTCRG nodes
  2023-02-21  8:33 [PATCH v2 00/11] Add new partial clock and reset drivers for StarFive JH7110 Xingyu Wu
                   ` (9 preceding siblings ...)
  2023-02-21  8:33 ` [PATCH v2 10/11] riscv: dts: starfive: jh7110: Add DVP and HDMI TX pixel external clocks Xingyu Wu
@ 2023-02-21  8:33 ` Xingyu Wu
  2023-02-27 19:53   ` Conor Dooley
  10 siblings, 1 reply; 33+ messages in thread
From: Xingyu Wu @ 2023-02-21  8:33 UTC (permalink / raw)
  To: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, Xingyu Wu, linux-kernel, linux-clk

Add STGCRG/ISPCRG/VOUTCRG new node to support JH7110
System-Top-Group, Image-Signal-Process and Video-Output
clock and reset drivers for the JH7110 RISC-V SoC.

Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
---
 arch/riscv/boot/dts/starfive/jh7110.dtsi | 59 ++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
index a5e6fb3ad188..697ab59191a1 100644
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
@@ -6,6 +6,7 @@
 
 /dts-v1/;
 #include <dt-bindings/clock/starfive,jh7110-crg.h>
+#include <dt-bindings/power/starfive,jh7110-pmu.h>
 #include <dt-bindings/reset/starfive,jh7110-crg.h>
 
 / {
@@ -374,6 +375,25 @@ i2c2: i2c@10050000 {
 			status = "disabled";
 		};
 
+		stgcrg: clock-controller@10230000 {
+			compatible = "starfive,jh7110-stgcrg";
+			reg = <0x0 0x10230000 0x0 0x10000>;
+			clocks = <&osc>,
+				 <&syscrg JH7110_SYSCLK_HIFI4_CORE>,
+				 <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
+				 <&syscrg JH7110_SYSCLK_USB_125M>,
+				 <&syscrg JH7110_SYSCLK_CPU_BUS>,
+				 <&syscrg JH7110_SYSCLK_HIFI4_AXI>,
+				 <&syscrg JH7110_SYSCLK_NOCSTG_BUS>,
+				 <&syscrg JH7110_SYSCLK_APB_BUS>;
+			clock-names = "osc", "hifi4_core",
+				      "stg_axiahb", "usb_125m",
+				      "cpu_bus", "hifi4_axi",
+				      "nocstg_bus", "apb_bus";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
 		uart3: serial@12000000 {
 			compatible = "snps,dw-apb-uart";
 			reg = <0x0 0x12000000 0x0 0x10000>;
@@ -522,5 +542,44 @@ pwrc: power-controller@17030000 {
 			interrupts = <111>;
 			#power-domain-cells = <1>;
 		};
+
+		ispcrg: clock-controller@19810000 {
+			compatible = "starfive,jh7110-ispcrg";
+			reg = <0x0 0x19810000 0x0 0x10000>;
+			clocks = <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
+				 <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>,
+				 <&syscrg JH7110_SYSCLK_NOC_BUS_ISP_AXI>,
+				 <&dvp_clk>;
+			clock-names = "isp_top_core", "isp_top_axi",
+				      "noc_bus_isp_axi", "dvp_clk";
+			resets = <&syscrg JH7110_SYSRST_ISP_TOP>,
+				 <&syscrg JH7110_SYSRST_ISP_TOP_AXI>,
+				 <&syscrg JH7110_SYSRST_NOC_BUS_ISP_AXI>;
+			reset-names = "isp_top_core",
+				      "isp_top_axi",
+				      "noc_bus_isp_axi";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			power-domains = <&pwrc JH7110_PD_ISP>;
+		};
+
+		voutcrg: clock-controller@295C0000 {
+			compatible = "starfive,jh7110-voutcrg";
+			reg = <0x0 0x295C0000 0x0 0x10000>;
+			clocks = <&syscrg JH7110_SYSCLK_VOUT_SRC>,
+				 <&syscrg JH7110_SYSCLK_VOUT_TOP_AHB>,
+				 <&syscrg JH7110_SYSCLK_VOUT_TOP_AXI>,
+				 <&syscrg JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK>,
+				 <&syscrg JH7110_SYSCLK_I2STX0_BCLK>,
+				 <&hdmitx0_pixelclk>;
+			clock-names = "vout_src", "vout_top_ahb",
+				      "vout_top_axi", "vout_top_hdmitx0_mclk",
+				      "i2stx0_bclk", "hdmitx0_pixelclk";
+			resets = <&syscrg JH7110_SYSRST_VOUT_TOP_SRC>;
+			reset-names = "vout_top_src";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			power-domains = <&pwrc JH7110_PD_VOUT>;
+		};
 	};
 };
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 01/11] dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and reset generator
  2023-02-21  8:33 ` [PATCH v2 01/11] dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and reset generator Xingyu Wu
@ 2023-02-21 11:25   ` Krzysztof Kozlowski
  2023-02-21 13:01     ` Xingyu Wu
  2023-03-02 15:05   ` Emil Renner Berthing
  1 sibling, 1 reply; 33+ messages in thread
From: Krzysztof Kozlowski @ 2023-02-21 11:25 UTC (permalink / raw)
  To: Xingyu Wu, linux-riscv, devicetree, Michael Turquette,
	Stephen Boyd, Krzysztof Kozlowski, Philipp Zabel,
	Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On 21/02/2023 09:33, Xingyu Wu wrote:
> Add bindings for the System-Top-Group clock and reset generator (STGCRG)
> on the JH7110 RISC-V SoC by StarFive Ltd.
> 
> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>


> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 93eb504c3b21..2e70c9f21989 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19914,6 +19914,7 @@ F:	arch/riscv/boot/dts/starfive/
>  STARFIVE JH71X0 CLOCK DRIVERS
>  M:	Emil Renner Berthing <kernel@esmil.dk>
>  M:	Hal Feng <hal.feng@starfivetech.com>
> +M:	Xingyu Wu <xingyu.wu@starfivetech.com>

No improvements here. You add here new bindings for one device and then
- without explanation - add yourself to all Starfive clock bindings.
Either explain it or drop it or move it to separate patch.

You already got comment for this.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 04/11] dt-bindings: clock: Add StarFive JH7110 Image-Signal-Process clock and reset generator
  2023-02-21  8:33 ` [PATCH v2 04/11] dt-bindings: clock: Add StarFive JH7110 Image-Signal-Process clock and reset generator Xingyu Wu
@ 2023-02-21 11:26   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 33+ messages in thread
From: Krzysztof Kozlowski @ 2023-02-21 11:26 UTC (permalink / raw)
  To: Xingyu Wu, linux-riscv, devicetree, Michael Turquette,
	Stephen Boyd, Krzysztof Kozlowski, Philipp Zabel,
	Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On 21/02/2023 09:33, Xingyu Wu wrote:
> Add bindings for the Image-Signal-Process clock and reset
> generator (ISPCRG) on the JH7110 RISC-V SoC by StarFive Ltd.
> 
> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
> ---


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 07/11] dt-bindings: clock: Add StarFive JH7110 Video-Output clock and reset generator
  2023-02-21  8:33 ` [PATCH v2 07/11] dt-bindings: clock: Add StarFive JH7110 Video-Output clock and reset generator Xingyu Wu
@ 2023-02-21 11:27   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 33+ messages in thread
From: Krzysztof Kozlowski @ 2023-02-21 11:27 UTC (permalink / raw)
  To: Xingyu Wu, linux-riscv, devicetree, Michael Turquette,
	Stephen Boyd, Krzysztof Kozlowski, Philipp Zabel,
	Emil Renner Berthing
  Cc: Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On 21/02/2023 09:33, Xingyu Wu wrote:
> Add bindings for the Video-Output clock and reset generator (VOUTCRG)
> on the JH7110 RISC-V SoC by StarFive Ltd.
> 
> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
> ---
>  .../clock/starfive,jh7110-voutcrg.yaml        | 96 +++++++++++++++++++
>  .../dt-bindings/clock/starfive,jh7110-crg.h   | 22 +++++
>  .../dt-bindings/reset/starfive,jh7110-crg.h   | 16 ++++
>  3 files changed, 134 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 01/11] dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and reset generator
  2023-02-21 11:25   ` Krzysztof Kozlowski
@ 2023-02-21 13:01     ` Xingyu Wu
  2023-02-21 13:37       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 33+ messages in thread
From: Xingyu Wu @ 2023-02-21 13:01 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On 2023/2/21 19:25, Krzysztof Kozlowski wrote:
> On 21/02/2023 09:33, Xingyu Wu wrote:
>> Add bindings for the System-Top-Group clock and reset generator (STGCRG)
>> on the JH7110 RISC-V SoC by StarFive Ltd.
>> 
>> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
> 
> 
>> +    };
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 93eb504c3b21..2e70c9f21989 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -19914,6 +19914,7 @@ F:	arch/riscv/boot/dts/starfive/
>>  STARFIVE JH71X0 CLOCK DRIVERS
>>  M:	Emil Renner Berthing <kernel@esmil.dk>
>>  M:	Hal Feng <hal.feng@starfivetech.com>
>> +M:	Xingyu Wu <xingyu.wu@starfivetech.com>
> 
> No improvements here. You add here new bindings for one device and then
> - without explanation - add yourself to all Starfive clock bindings.
> Either explain it or drop it or move it to separate patch.
> 
> You already got comment for this.
> 

Sorry, I didn't understand what you meant before. Now my understanding is that, 
If I improvements JH71X0 driver no JH7110 driver, I could add this here. Right?

Is it OK if I do it this way to move it to separate patch like this?:
+STARFIVE JH7110 STG CLOCK DRIVERS
+M:	Xingyu Wu <xingyu.wu@starfivetech.com>


Best Regards,
Xingyu Wu

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 01/11] dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and reset generator
  2023-02-21 13:01     ` Xingyu Wu
@ 2023-02-21 13:37       ` Krzysztof Kozlowski
  2023-02-22  1:48         ` Xingyu Wu
  0 siblings, 1 reply; 33+ messages in thread
From: Krzysztof Kozlowski @ 2023-02-21 13:37 UTC (permalink / raw)
  To: Xingyu Wu
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On 21/02/2023 14:01, Xingyu Wu wrote:
> On 2023/2/21 19:25, Krzysztof Kozlowski wrote:
>> On 21/02/2023 09:33, Xingyu Wu wrote:
>>> Add bindings for the System-Top-Group clock and reset generator (STGCRG)
>>> on the JH7110 RISC-V SoC by StarFive Ltd.
>>>
>>> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
>>
>>
>>> +    };
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index 93eb504c3b21..2e70c9f21989 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -19914,6 +19914,7 @@ F:	arch/riscv/boot/dts/starfive/
>>>  STARFIVE JH71X0 CLOCK DRIVERS
>>>  M:	Emil Renner Berthing <kernel@esmil.dk>
>>>  M:	Hal Feng <hal.feng@starfivetech.com>
>>> +M:	Xingyu Wu <xingyu.wu@starfivetech.com>
>>
>> No improvements here. You add here new bindings for one device and then
>> - without explanation - add yourself to all Starfive clock bindings.
>> Either explain it or drop it or move it to separate patch.
>>
>> You already got comment for this.
>>
> 
> Sorry, I didn't understand what you meant before. Now my understanding is that, 
> If I improvements JH71X0 driver no JH7110 driver, I could add this here. Right?
> 
> Is it OK if I do it this way to move it to separate patch like this?:
> +STARFIVE JH7110 STG CLOCK DRIVERS
> +M:	Xingyu Wu <xingyu.wu@starfivetech.com>

If you want to be the maintainer of all drivers, add separate commit for
this, so this is obvious. Or at least explain this change in commit msg.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 01/11] dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and reset generator
  2023-02-21 13:37       ` Krzysztof Kozlowski
@ 2023-02-22  1:48         ` Xingyu Wu
  0 siblings, 0 replies; 33+ messages in thread
From: Xingyu Wu @ 2023-02-22  1:48 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On 2023/2/21 21:37, Krzysztof Kozlowski wrote:
> On 21/02/2023 14:01, Xingyu Wu wrote:
>> On 2023/2/21 19:25, Krzysztof Kozlowski wrote:
>>> On 21/02/2023 09:33, Xingyu Wu wrote:
>>>> Add bindings for the System-Top-Group clock and reset generator (STGCRG)
>>>> on the JH7110 RISC-V SoC by StarFive Ltd.
>>>>
>>>> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
>>>
>>>
>>>> +    };
>>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>>> index 93eb504c3b21..2e70c9f21989 100644
>>>> --- a/MAINTAINERS
>>>> +++ b/MAINTAINERS
>>>> @@ -19914,6 +19914,7 @@ F:	arch/riscv/boot/dts/starfive/
>>>>  STARFIVE JH71X0 CLOCK DRIVERS
>>>>  M:	Emil Renner Berthing <kernel@esmil.dk>
>>>>  M:	Hal Feng <hal.feng@starfivetech.com>
>>>> +M:	Xingyu Wu <xingyu.wu@starfivetech.com>
>>>
>>> No improvements here. You add here new bindings for one device and then
>>> - without explanation - add yourself to all Starfive clock bindings.
>>> Either explain it or drop it or move it to separate patch.
>>>
>>> You already got comment for this.
>>>
>> 
>> Sorry, I didn't understand what you meant before. Now my understanding is that, 
>> If I improvements JH71X0 driver no JH7110 driver, I could add this here. Right?
>> 
>> Is it OK if I do it this way to move it to separate patch like this?:
>> +STARFIVE JH7110 STG CLOCK DRIVERS
>> +M:	Xingyu Wu <xingyu.wu@starfivetech.com>
> 
> If you want to be the maintainer of all drivers, add separate commit for
> this, so this is obvious. Or at least explain this change in commit msg.
> 

OK, got it. Thanks.

Best regard,
Xingyu Wu


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 11/11] riscv: dts: starfive: jh7110: Add STGCRG/ISPCRG/VOUTCRG nodes
  2023-02-21  8:33 ` [PATCH v2 11/11] riscv: dts: starfive: jh7110: Add STGCRG/ISPCRG/VOUTCRG nodes Xingyu Wu
@ 2023-02-27 19:53   ` Conor Dooley
  0 siblings, 0 replies; 33+ messages in thread
From: Conor Dooley @ 2023-02-27 19:53 UTC (permalink / raw)
  To: Xingyu Wu
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Paul Walmsley, Palmer Dabbelt, Albert Ou, Hal Feng,
	linux-kernel, linux-clk

[-- Attachment #1: Type: text/plain, Size: 1016 bytes --]

On Tue, Feb 21, 2023 at 04:33:23PM +0800, Xingyu Wu wrote:
> Add STGCRG/ISPCRG/VOUTCRG new node to support JH7110
> System-Top-Group, Image-Signal-Process and Video-Output
> clock and reset drivers for the JH7110 RISC-V SoC.
> 
> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
> ---
>  arch/riscv/boot/dts/starfive/jh7110.dtsi | 59 ++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
> 
> diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
> index a5e6fb3ad188..697ab59191a1 100644
> --- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
> +++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
> @@ -6,6 +6,7 @@
>  
>  /dts-v1/;
>  #include <dt-bindings/clock/starfive,jh7110-crg.h>
> +#include <dt-bindings/power/starfive,jh7110-pmu.h>
>  #include <dt-bindings/reset/starfive,jh7110-crg.h>

Please keep these sorted alphabetically, otherwise this *looks* fine to
me.
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>

Thanks,
Conor.


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 10/11] riscv: dts: starfive: jh7110: Add DVP and HDMI TX pixel external clocks
  2023-02-21  8:33 ` [PATCH v2 10/11] riscv: dts: starfive: jh7110: Add DVP and HDMI TX pixel external clocks Xingyu Wu
@ 2023-02-27 19:55   ` Conor Dooley
  2023-02-28  1:40     ` Xingyu Wu
  0 siblings, 1 reply; 33+ messages in thread
From: Conor Dooley @ 2023-02-27 19:55 UTC (permalink / raw)
  To: Xingyu Wu
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Paul Walmsley, Palmer Dabbelt, Albert Ou, Hal Feng,
	linux-kernel, linux-clk

[-- Attachment #1: Type: text/plain, Size: 1822 bytes --]

On Tue, Feb 21, 2023 at 04:33:22PM +0800, Xingyu Wu wrote:
> Add DVP and HDMI TX pixel external fixed clocks and the rates are
> 74.25MHz and 297MHz.
> 
> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
> ---
>  .../dts/starfive/jh7110-starfive-visionfive-2.dtsi   |  8 ++++++++
>  arch/riscv/boot/dts/starfive/jh7110.dtsi             | 12 ++++++++++++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
> index c2aa8946a0f1..27af817a55aa 100644
> --- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
> +++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
> @@ -86,6 +86,14 @@ &mclk_ext {
>  	clock-frequency = <12288000>;
>  };
>  
> +&dvp_clk {
> +	clock-frequency = <74250000>;
> +};
> +
> +&hdmitx0_pixelclk {
> +	clock-frequency = <297000000>;
> +};
> +
>  &uart0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&uart0_pins>;
> diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
> index 005ead2624d4..a5e6fb3ad188 100644
> --- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
> +++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
> @@ -245,6 +245,18 @@ mclk_ext: mclk-ext-clock {
>  		#clock-cells = <0>;
>  	};
>  
> +	dvp_clk: dvp-clk-clock {
> +		compatible = "fixed-clock";
> +		clock-output-names = "dvp_clk";
> +		#clock-cells = <0>;
> +	};
> +
> +	hdmitx0_pixelclk: hdmitx0-pixelclk-clock {
> +		compatible = "fixed-clock";
> +		clock-output-names = "hdmitx0_pixelclk";
> +		#clock-cells = <0>;
> +	};
> +

Hmm, would you mind adding these entries with no unit addresses in
alphanumerical order? Both in the soc & board dtsi files.

Thanks,
Conor.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 10/11] riscv: dts: starfive: jh7110: Add DVP and HDMI TX pixel external clocks
  2023-02-27 19:55   ` Conor Dooley
@ 2023-02-28  1:40     ` Xingyu Wu
  0 siblings, 0 replies; 33+ messages in thread
From: Xingyu Wu @ 2023-02-28  1:40 UTC (permalink / raw)
  To: Conor Dooley
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Paul Walmsley, Palmer Dabbelt, Albert Ou, Hal Feng,
	linux-kernel, linux-clk

On 2023/2/28 3:55, Conor Dooley wrote:
> On Tue, Feb 21, 2023 at 04:33:22PM +0800, Xingyu Wu wrote:
>> Add DVP and HDMI TX pixel external fixed clocks and the rates are
>> 74.25MHz and 297MHz.
>> 
>> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
>> ---
>>  .../dts/starfive/jh7110-starfive-visionfive-2.dtsi   |  8 ++++++++
>>  arch/riscv/boot/dts/starfive/jh7110.dtsi             | 12 ++++++++++++
>>  2 files changed, 20 insertions(+)
>> 
>> diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
>> index c2aa8946a0f1..27af817a55aa 100644
>> --- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
>> +++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
>> @@ -86,6 +86,14 @@ &mclk_ext {
>>  	clock-frequency = <12288000>;
>>  };
>>  
>> +&dvp_clk {
>> +	clock-frequency = <74250000>;
>> +};
>> +
>> +&hdmitx0_pixelclk {
>> +	clock-frequency = <297000000>;
>> +};
>> +
>>  &uart0 {
>>  	pinctrl-names = "default";
>>  	pinctrl-0 = <&uart0_pins>;
>> diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
>> index 005ead2624d4..a5e6fb3ad188 100644
>> --- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
>> +++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
>> @@ -245,6 +245,18 @@ mclk_ext: mclk-ext-clock {
>>  		#clock-cells = <0>;
>>  	};
>>  
>> +	dvp_clk: dvp-clk-clock {
>> +		compatible = "fixed-clock";
>> +		clock-output-names = "dvp_clk";
>> +		#clock-cells = <0>;
>> +	};
>> +
>> +	hdmitx0_pixelclk: hdmitx0-pixelclk-clock {
>> +		compatible = "fixed-clock";
>> +		clock-output-names = "hdmitx0_pixelclk";
>> +		#clock-cells = <0>;
>> +	};
>> +
> 
> Hmm, would you mind adding these entries with no unit addresses in
> alphanumerical order? Both in the soc & board dtsi files.
> 

Oh, It was my negligence. I will adjust it. Thanks.

Best regards,
Xingyu Wu


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 01/11] dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and reset generator
  2023-02-21  8:33 ` [PATCH v2 01/11] dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and reset generator Xingyu Wu
  2023-02-21 11:25   ` Krzysztof Kozlowski
@ 2023-03-02 15:05   ` Emil Renner Berthing
  2023-03-03  3:14     ` Xingyu Wu
  1 sibling, 1 reply; 33+ messages in thread
From: Emil Renner Berthing @ 2023-03-02 15:05 UTC (permalink / raw)
  To: Xingyu Wu
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On Tue, 21 Feb 2023 at 09:37, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
> Add bindings for the System-Top-Group clock and reset generator (STGCRG)
> on the JH7110 RISC-V SoC by StarFive Ltd.
>
> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
> ---
>  .../clock/starfive,jh7110-stgcrg.yaml         | 82 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  .../dt-bindings/clock/starfive,jh7110-crg.h   | 34 ++++++++
>  .../dt-bindings/reset/starfive,jh7110-crg.h   | 28 +++++++
>  4 files changed, 145 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
>
> diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
> new file mode 100644
> index 000000000000..b64ccd84200a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
> @@ -0,0 +1,82 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/starfive,jh7110-stgcrg.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: StarFive JH7110 System-Top-Group Clock and Reset Generator
> +
> +maintainers:
> +  - Xingyu Wu <xingyu.wu@starfivetech.com>
> +
> +properties:
> +  compatible:
> +    const: starfive,jh7110-stgcrg
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: Main Oscillator (24 MHz)
> +      - description: HIFI4 core
> +      - description: STG AXI/AHB
> +      - description: USB (125 MHz)
> +      - description: CPU Bus
> +      - description: HIFI4 Axi
> +      - description: NOC STG Bus
> +      - description: APB Bus
> +
> +  clock-names:
> +    items:
> +      - const: osc
> +      - const: hifi4_core
> +      - const: stg_axiahb
> +      - const: usb_125m
> +      - const: cpu_bus
> +      - const: hifi4_axi
> +      - const: nocstg_bus
> +      - const: apb_bus
> +
> +  '#clock-cells':
> +    const: 1
> +    description:
> +      See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
> +
> +  '#reset-cells':
> +    const: 1
> +    description:
> +      See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - '#clock-cells'
> +  - '#reset-cells'
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/starfive,jh7110-crg.h>
> +
> +    stgcrg: clock-controller@10230000 {
> +        compatible = "starfive,jh7110-stgcrg";
> +        reg = <0x10230000 0x10000>;
> +        clocks = <&osc>,
> +                 <&syscrg JH7110_SYSCLK_HIFI4_CORE>,
> +                 <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
> +                 <&syscrg JH7110_SYSCLK_USB_125M>,
> +                 <&syscrg JH7110_SYSCLK_CPU_BUS>,
> +                 <&syscrg JH7110_SYSCLK_HIFI4_AXI>,
> +                 <&syscrg JH7110_SYSCLK_NOCSTG_BUS>,
> +                 <&syscrg JH7110_SYSCLK_APB_BUS>;
> +        clock-names = "osc", "hifi4_core",
> +                      "stg_axiahb", "usb_125m",
> +                      "cpu_bus", "hifi4_axi",
> +                      "nocstg_bus", "apb_bus";
> +        #clock-cells = <1>;
> +        #reset-cells = <1>;
> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 93eb504c3b21..2e70c9f21989 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19914,6 +19914,7 @@ F:      arch/riscv/boot/dts/starfive/
>  STARFIVE JH71X0 CLOCK DRIVERS
>  M:     Emil Renner Berthing <kernel@esmil.dk>
>  M:     Hal Feng <hal.feng@starfivetech.com>
> +M:     Xingyu Wu <xingyu.wu@starfivetech.com>
>  S:     Maintained
>  F:     Documentation/devicetree/bindings/clock/starfive,jh71*.yaml
>  F:     drivers/clk/starfive/clk-starfive-jh71*
> diff --git a/include/dt-bindings/clock/starfive,jh7110-crg.h b/include/dt-bindings/clock/starfive,jh7110-crg.h
> index 5e4f21ca0642..5ac8a4d90a7a 100644
> --- a/include/dt-bindings/clock/starfive,jh7110-crg.h
> +++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
> @@ -1,6 +1,7 @@
>  /* SPDX-License-Identifier: GPL-2.0 OR MIT */
>  /*
>   * Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
> + * Copyright 2022 StarFive Technology Co., Ltd.
>   */
>
>  #ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
> @@ -222,4 +223,37 @@
>
>  #define JH7110_AONCLK_END                      14

Hi Xingyu,

The clock and reset names below have been shortened from the very long
names in the documentation. I see you've come to the same shortened
names as I used in the first STGCRG driver I pushed, which is great,
but I find it highly unlikely to have happened without looking at /
copying my code like you did for the SYSCRG and AONCRG drivers Hal has
posted. Unfortunately the commit message above doesn't reflect that,
so please add a
Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>

I do have some updated suggestions for short names below though:

> +/* STGCRG clocks */
> +#define JH7110_STGCLK_HIFI4_CLK_CORE           0
> +#define JH7110_STGCLK_USB0_APB                 1
> +#define JH7110_STGCLK_USB0_UTMI_APB            2 unli
> +#define JH7110_STGCLK_USB0_AXI                 3
> +#define JH7110_STGCLK_USB0_LPM                 4
> +#define JH7110_STGCLK_USB0_STB                 5
> +#define JH7110_STGCLK_USB0_APP_125             6
> +#define JH7110_STGCLK_USB0_REFCLK              7
> +#define JH7110_STGCLK_PCIE0_AXI_MST0           8
> +#define JH7110_STGCLK_PCIE0_APB                        9
> +#define JH7110_STGCLK_PCIE0_TL                 10
> +#define JH7110_STGCLK_PCIE1_AXI_MST0           11
> +#define JH7110_STGCLK_PCIE1_APB                        12
> +#define JH7110_STGCLK_PCIE1_TL                 13
> +#define JH7110_STGCLK_PCIE01_SLV_DEC_MAINCLK   14

Does PCIE01 here mean that the clock is used by both pcie0 and pcie1?
If so then maybe just call it JH7110_PCIE_SLV_MAIN

> +#define JH7110_STGCLK_SEC_HCLK                 15

For other clocks I think "hclk" means ahb clock, so maybe JH7110_STGCLK_SEC_AHB

> +#define JH7110_STGCLK_SEC_MISCAHB              16

I find something like JH7110_STGCLK_SEC_MISC_AHB a little easier to read.

> +#define JH7110_STGCLK_GRP0_MAIN                        17
> +#define JH7110_STGCLK_GRP0_BUS                 18
> +#define JH7110_STGCLK_GRP0_STG                 19
> +#define JH7110_STGCLK_GRP1_MAIN                        20
> +#define JH7110_STGCLK_GRP1_BUS                 21
> +#define JH7110_STGCLK_GRP1_STG                 22
> +#define JH7110_STGCLK_GRP1_HIFI                        23
> +#define JH7110_STGCLK_E2_RTC                   24
> +#define JH7110_STGCLK_E2_CORE                  25
> +#define JH7110_STGCLK_E2_DBG                   26
> +#define JH7110_STGCLK_DMA1P_AXI                        27
> +#define JH7110_STGCLK_DMA1P_AHB                        28
> +
> +#define JH7110_STGCLK_END                      29
> +
>  #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
> diff --git a/include/dt-bindings/reset/starfive,jh7110-crg.h b/include/dt-bindings/reset/starfive,jh7110-crg.h
> index d78e38690ceb..4a865ded78b8 100644
> --- a/include/dt-bindings/reset/starfive,jh7110-crg.h
> +++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
> @@ -1,6 +1,7 @@
>  /* SPDX-License-Identifier: GPL-2.0 OR MIT */
>  /*
>   * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
> + * Copyright (C) 2022 StarFive Technology Co., Ltd.
>   */
>
>  #ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
> @@ -151,4 +152,31 @@
>
>  #define JH7110_AONRST_END                      8
>
> +/* STGCRG resets */
> +#define JH7110_STGRST_SYSCON                   0
> +#define JH7110_STGRST_HIFI4_CORE               1
> +#define JH7110_STGRST_HIFI4_AXI                        2
> +#define JH7110_STGRST_SEC_TOP_HRESETN          3

JH7110_STGRST_SEC_AHB to match the clock above.

> +#define JH7110_STGRST_E24_CORE                 4
> +#define JH7110_STGRST_DMA1P_AXI                        5
> +#define JH7110_STGRST_DMA1P_AHB                        6
> +#define JH7110_STGRST_USB0_AXI                 7
> +#define JH7110_STGRST_USB0_APB                 8
> +#define JH7110_STGRST_USB0_UTMI_APB            9
> +#define JH7110_STGRST_USB0_PWRUP               10
> +#define JH7110_STGRST_PCIE0_AXI_MST0           11
> +#define JH7110_STGRST_PCIE0_AXI_SLV0           12
> +#define JH7110_STGRST_PCIE0_AXI_SLV            13
> +#define JH7110_STGRST_PCIE0_BRG                        14
> +#define JH7110_STGRST_PCIE0_CORE               15
> +#define JH7110_STGRST_PCIE0_APB                        16
> +#define JH7110_STGRST_PCIE1_AXI_MST0           17
> +#define JH7110_STGRST_PCIE1_AXI_SLV0           18
> +#define JH7110_STGRST_PCIE1_AXI_SLV            19
> +#define JH7110_STGRST_PCIE1_BRG                        20
> +#define JH7110_STGRST_PCIE1_CORE               21
> +#define JH7110_STGRST_PCIE1_APB                        22
> +
> +#define JH7110_STGRST_END                      23
> +
>  #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
> --
> 2.25.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 03/11] clk: starfive: Add StarFive JH7110 System-Top-Group clock driver
  2023-02-21  8:33 ` [PATCH v2 03/11] clk: starfive: Add StarFive JH7110 System-Top-Group clock driver Xingyu Wu
@ 2023-03-02 15:16   ` Emil Renner Berthing
  0 siblings, 0 replies; 33+ messages in thread
From: Emil Renner Berthing @ 2023-03-02 15:16 UTC (permalink / raw)
  To: Xingyu Wu
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On Tue, 21 Feb 2023 at 09:38, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
>
> Add driver for the StarFive JH7110 System-Top-Group clock controller.
>
> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>

Again, this driver is almost identical to the first STGCRG driver I
pushed. You really ought to have kept the authorship like Hal Feng did
for the SYSCRG and AONCRG drivers.

> ---
>  drivers/clk/starfive/Kconfig                  |  11 ++
>  drivers/clk/starfive/Makefile                 |   1 +
>  .../clk/starfive/clk-starfive-jh7110-stg.c    | 176 ++++++++++++++++++
>  3 files changed, 188 insertions(+)
>  create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-stg.c
>
> diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
> index 2aa664f2cdee..a462b6e53543 100644
> --- a/drivers/clk/starfive/Kconfig
> +++ b/drivers/clk/starfive/Kconfig
> @@ -42,3 +42,14 @@ config CLK_STARFIVE_JH7110_AON
>         help
>           Say yes here to support the always-on clock controller on the
>           StarFive JH7110 SoC.
> +
> +config CLK_STARFIVE_JH7110_STG
> +       tristate "StarFive JH7110 System-Top-Group clock support"
> +       depends on CLK_STARFIVE_JH7110_SYS
> +       select AUXILIARY_BUS
> +       select CLK_STARFIVE_JH71X0
> +       select RESET_STARFIVE_JH7110
> +       default CLK_STARFIVE_JH7110_SYS

The JH7110 boots perfectly fine without this driver built in, so just do
default m if ARCH_STARFIVE

> +       help
> +         Say yes here to support the System-Top-Group clock controller
> +         on the StarFive JH7110 SoC.
> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
> index f3df7d957b1e..b81e97ee2659 100644
> --- a/drivers/clk/starfive/Makefile
> +++ b/drivers/clk/starfive/Makefile
> @@ -6,3 +6,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
>
>  obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS)  += clk-starfive-jh7110-sys.o
>  obj-$(CONFIG_CLK_STARFIVE_JH7110_AON)  += clk-starfive-jh7110-aon.o
> +obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)  += clk-starfive-jh7110-stg.o
> diff --git a/drivers/clk/starfive/clk-starfive-jh7110-stg.c b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
> new file mode 100644
> index 000000000000..a39d2fdb8011
> --- /dev/null
> +++ b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
> @@ -0,0 +1,176 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * StarFive JH7110 System-Top-Group Clock Driver
> + *
> + * Copyright (C) 2022 StarFive Technology Co., Ltd.

Removing my copyright line is definitely not ok.

> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +#include <dt-bindings/clock/starfive,jh7110-crg.h>
> +
> +#include "clk-starfive-jh71x0.h"
> +
> +/* external clocks */
> +#define JH7110_STGCLK_OSC                      (JH7110_STGCLK_END + 0)
> +#define JH7110_STGCLK_HIFI4_CORE               (JH7110_STGCLK_END + 1)
> +#define JH7110_STGCLK_STG_AXIAHB               (JH7110_STGCLK_END + 2)
> +#define JH7110_STGCLK_USB_125M                 (JH7110_STGCLK_END + 3)
> +#define JH7110_STGCLK_CPU_BUS                  (JH7110_STGCLK_END + 4)
> +#define JH7110_STGCLK_HIFI4_AXI                        (JH7110_STGCLK_END + 5)
> +#define JH7110_STGCLK_NOCSTG_BUS               (JH7110_STGCLK_END + 6)
> +#define JH7110_STGCLK_APB_BUS                  (JH7110_STGCLK_END + 7)
> +#define JH7110_STGCLK_EXT_END                  (JH7110_STGCLK_END + 8)
> +
> +static const struct jh71x0_clk_data jh7110_stgclk_data[] = {
> +       /* hifi4 */
> +       JH71X0_GATE(JH7110_STGCLK_HIFI4_CLK_CORE, "hifi4_clk_core", 0,
> +                   JH7110_STGCLK_HIFI4_CORE),
> +       /* usb */
> +       JH71X0_GATE(JH7110_STGCLK_USB0_APB, "usb0_apb", 0, JH7110_STGCLK_APB_BUS),
> +       JH71X0_GATE(JH7110_STGCLK_USB0_UTMI_APB, "usb0_utmi_apb", 0, JH7110_STGCLK_APB_BUS),
> +       JH71X0_GATE(JH7110_STGCLK_USB0_AXI, "usb0_axi", 0, JH7110_STGCLK_STG_AXIAHB),
> +       JH71X0_GDIV(JH7110_STGCLK_USB0_LPM, "usb0_lpm", 0, 2, JH7110_STGCLK_OSC),
> +       JH71X0_GDIV(JH7110_STGCLK_USB0_STB, "usb0_stb", 0, 4, JH7110_STGCLK_OSC),
> +       JH71X0_GATE(JH7110_STGCLK_USB0_APP_125, "usb0_app_125", 0, JH7110_STGCLK_USB_125M),
> +       JH71X0__DIV(JH7110_STGCLK_USB0_REFCLK, "usb0_refclk", 2, JH7110_STGCLK_OSC),
> +       /* pci-e */
> +       JH71X0_GATE(JH7110_STGCLK_PCIE0_AXI_MST0, "pcie0_axi_mst0", 0,
> +                   JH7110_STGCLK_STG_AXIAHB),
> +       JH71X0_GATE(JH7110_STGCLK_PCIE0_APB, "pcie0_apb", 0, JH7110_STGCLK_APB_BUS),
> +       JH71X0_GATE(JH7110_STGCLK_PCIE0_TL, "pcie0_tl", 0, JH7110_STGCLK_STG_AXIAHB),
> +       JH71X0_GATE(JH7110_STGCLK_PCIE1_AXI_MST0, "pcie1_axi_mst0", 0,
> +                   JH7110_STGCLK_STG_AXIAHB),
> +       JH71X0_GATE(JH7110_STGCLK_PCIE1_APB, "pcie1_apb", 0, JH7110_STGCLK_APB_BUS),
> +       JH71X0_GATE(JH7110_STGCLK_PCIE1_TL, "pcie1_tl", 0, JH7110_STGCLK_STG_AXIAHB),
> +       JH71X0_GATE(JH7110_STGCLK_PCIE01_SLV_DEC_MAINCLK, "pcie01_slv_dec_mainclk",
> +                   CLK_IGNORE_UNUSED, JH7110_STGCLK_STG_AXIAHB),
> +       /* security */
> +       JH71X0_GATE(JH7110_STGCLK_SEC_HCLK, "sec_hclk", 0, JH7110_STGCLK_STG_AXIAHB),
> +       JH71X0_GATE(JH7110_STGCLK_SEC_MISCAHB, "sec_miscahb", 0, JH7110_STGCLK_STG_AXIAHB),
> +       /* stg mtrx */
> +       JH71X0_GATE(JH7110_STGCLK_GRP0_MAIN, "mtrx_grp0_main",
> +                   CLK_IGNORE_UNUSED, JH7110_STGCLK_CPU_BUS),
> +       JH71X0_GATE(JH7110_STGCLK_GRP0_BUS, "mtrx_grp0_bus",
> +                   CLK_IGNORE_UNUSED, JH7110_STGCLK_NOCSTG_BUS),
> +       JH71X0_GATE(JH7110_STGCLK_GRP0_STG, "mtrx_grp0_stg",
> +                   CLK_IGNORE_UNUSED, JH7110_STGCLK_STG_AXIAHB),
> +       JH71X0_GATE(JH7110_STGCLK_GRP1_MAIN, "mtrx_grp1_main",
> +                   CLK_IGNORE_UNUSED, JH7110_STGCLK_CPU_BUS),
> +       JH71X0_GATE(JH7110_STGCLK_GRP1_BUS, "mtrx_grp1_bus",
> +                   CLK_IGNORE_UNUSED, JH7110_STGCLK_NOCSTG_BUS),
> +       JH71X0_GATE(JH7110_STGCLK_GRP1_STG, "mtrx_grp1_stg",
> +                   CLK_IGNORE_UNUSED, JH7110_STGCLK_STG_AXIAHB),
> +       JH71X0_GATE(JH7110_STGCLK_GRP1_HIFI, "mtrx_grp1_hifi",
> +                   CLK_IGNORE_UNUSED, JH7110_STGCLK_HIFI4_AXI),
> +       /* e24_rvpi */
> +       JH71X0_GDIV(JH7110_STGCLK_E2_RTC, "e2_rtc", 0, 24, JH7110_STGCLK_OSC),
> +       JH71X0_GATE(JH7110_STGCLK_E2_CORE, "e2_core",
> +                   CLK_IGNORE_UNUSED, JH7110_STGCLK_STG_AXIAHB),
> +       JH71X0_GATE(JH7110_STGCLK_E2_DBG, "e2_dbg", 0, JH7110_STGCLK_STG_AXIAHB),
> +       /* dw_sgdma1p */
> +       JH71X0_GATE(JH7110_STGCLK_DMA1P_AXI, "dma1p_axi", 0, JH7110_STGCLK_STG_AXIAHB),
> +       JH71X0_GATE(JH7110_STGCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
> +};

Like the SYSCRG and AONCRG driver in Hal Feng's series I only added
the CLK_IGNORE_UNUSED flag as a placeholder for clocks where I didn't
yet know if
they were ok to turn off when unused. Please go through the clocks and
figure out if they're critical and mark them with CLK_IS_CRITICAL or
they are fine to turn off and just remove the CLK_IGNORE_UNUSED flag.

> +static struct clk_hw *jh7110_stgclk_get(struct of_phandle_args *clkspec, void *data)
> +{
> +       struct jh71x0_clk_priv *priv = data;
> +       unsigned int idx = clkspec->args[0];
> +
> +       if (idx < JH7110_STGCLK_END)
> +               return &priv->reg[idx].hw;
> +
> +       return ERR_PTR(-EINVAL);
> +}
> +
> +static int jh7110_stgcrg_probe(struct platform_device *pdev)
> +{
> +       struct jh71x0_clk_priv *priv;
> +       unsigned int idx;
> +       int ret;
> +
> +       priv = devm_kzalloc(&pdev->dev,
> +                           struct_size(priv, reg, JH7110_STGCLK_END),
> +                           GFP_KERNEL);
> +       if (!priv)
> +               return -ENOMEM;
> +
> +       spin_lock_init(&priv->rmw_lock);
> +       priv->dev = &pdev->dev;
> +       priv->base = devm_platform_ioremap_resource(pdev, 0);
> +       if (IS_ERR(priv->base))
> +               return PTR_ERR(priv->base);
> +
> +       dev_set_drvdata(priv->dev, (void *)(&priv->base));
> +
> +       for (idx = 0; idx < JH7110_STGCLK_END; idx++) {
> +               u32 max = jh7110_stgclk_data[idx].max;
> +               struct clk_parent_data parents[4] = {};
> +               struct clk_init_data init = {
> +                       .name = jh7110_stgclk_data[idx].name,
> +                       .ops = starfive_jh71x0_clk_ops(max),
> +                       .parent_data = parents,
> +                       .num_parents =
> +                               ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
> +                       .flags = jh7110_stgclk_data[idx].flags,
> +               };
> +               struct jh71x0_clk *clk = &priv->reg[idx];
> +               unsigned int i;
> +               char *fw_name[JH7110_STGCLK_EXT_END - JH7110_STGCLK_END] = {
> +                       "osc",
> +                       "hifi4_core",
> +                       "stg_axiahb",
> +                       "usb_125m",
> +                       "cpu_bus",
> +                       "hifi4_axi",
> +                       "nocstg_bus",
> +                       "apb_bus"
> +               };
> +
> +               for (i = 0; i < init.num_parents; i++) {
> +                       unsigned int pidx = jh7110_stgclk_data[idx].parents[i];
> +
> +                       if (pidx < JH7110_STGCLK_END)
> +                               parents[i].hw = &priv->reg[pidx].hw;
> +                       else if (pidx < JH7110_STGCLK_EXT_END)
> +                               parents[i].fw_name = fw_name[pidx - JH7110_STGCLK_END];
> +               }
> +
> +               clk->hw.init = &init;
> +               clk->idx = idx;
> +               clk->max_div = max & JH71X0_CLK_DIV_MASK;
> +
> +               ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
> +               if (ret)
> +                       return ret;
> +       }
> +
> +       ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_stgclk_get, priv);
> +       if (ret)
> +               return ret;
> +
> +       return jh7110_reset_controller_register(priv, "reset-stg", 2);
> +}
> +
> +static const struct of_device_id jh7110_stgcrg_match[] = {
> +       { .compatible = "starfive,jh7110-stgcrg" },
> +       { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, jh7110_stgcrg_match);
> +
> +static struct platform_driver jh7110_stgcrg_driver = {
> +       .probe = jh7110_stgcrg_probe,
> +       .driver = {
> +               .name = "clk-starfive-jh7110-stg",
> +               .of_match_table = jh7110_stgcrg_match,
> +       },
> +};
> +module_platform_driver(jh7110_stgcrg_driver);
> +
> +MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");

Again
MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");

> +MODULE_DESCRIPTION("StarFive JH7110 System-Top-Group clock driver");
> +MODULE_LICENSE("GPL");
> --
> 2.25.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 06/11] clk: starfive: Add StarFive JH7110 Image-Signal-Process clock driver
  2023-02-21  8:33 ` [PATCH v2 06/11] clk: starfive: Add StarFive JH7110 Image-Signal-Process clock driver Xingyu Wu
@ 2023-03-02 15:39   ` Emil Renner Berthing
  2023-03-03  3:59     ` Xingyu Wu
  0 siblings, 1 reply; 33+ messages in thread
From: Emil Renner Berthing @ 2023-03-02 15:39 UTC (permalink / raw)
  To: Xingyu Wu
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On Tue, 21 Feb 2023 at 09:36, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
>
> Add driver for the StarFive JH7110 Image-Signal-Process clock controller.
>
> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
> ---
>  drivers/clk/starfive/Kconfig                  |  11 +
>  drivers/clk/starfive/Makefile                 |   1 +
>  .../clk/starfive/clk-starfive-jh7110-isp.c    | 254 ++++++++++++++++++
>  3 files changed, 266 insertions(+)
>  create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-isp.c
>
> diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
> index a462b6e53543..59499acb95f7 100644
> --- a/drivers/clk/starfive/Kconfig
> +++ b/drivers/clk/starfive/Kconfig
> @@ -53,3 +53,14 @@ config CLK_STARFIVE_JH7110_STG
>         help
>           Say yes here to support the System-Top-Group clock controller
>           on the StarFive JH7110 SoC.
> +
> +config CLK_STARFIVE_JH7110_ISP
> +       tristate "StarFive JH7110 Image-Signal-Process clock support"
> +       depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
> +       select AUXILIARY_BUS
> +       select CLK_STARFIVE_JH71X0
> +       select RESET_STARFIVE_JH7110
> +       default CLK_STARFIVE_JH7110_SYS

default m if ARCH_STARFIVE

> +       help
> +         Say yes here to support the Image-Signal-Process clock controller
> +         on the StarFive JH7110 SoC.
> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
> index b81e97ee2659..76fb9f8d628b 100644
> --- a/drivers/clk/starfive/Makefile
> +++ b/drivers/clk/starfive/Makefile
> @@ -7,3 +7,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
>  obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS)  += clk-starfive-jh7110-sys.o
>  obj-$(CONFIG_CLK_STARFIVE_JH7110_AON)  += clk-starfive-jh7110-aon.o
>  obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)  += clk-starfive-jh7110-stg.o
> +obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP)  += clk-starfive-jh7110-isp.o
> diff --git a/drivers/clk/starfive/clk-starfive-jh7110-isp.c b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
> new file mode 100644
> index 000000000000..b5bce1ac22e0
> --- /dev/null
> +++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
> @@ -0,0 +1,254 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * StarFive JH7110 Image-Signal-Process Clock Driver
> + *
> + * Copyright (C) 2022 StarFive Technology Co., Ltd.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/reset.h>
> +
> +#include <dt-bindings/clock/starfive,jh7110-crg.h>
> +
> +#include "clk-starfive-jh71x0.h"
> +
> +/* external clocks */
> +#define JH7110_ISPCLK_ISP_TOP_CORE             (JH7110_ISPCLK_END + 0)
> +#define JH7110_ISPCLK_ISP_TOP_AXI              (JH7110_ISPCLK_END + 1)
> +#define JH7110_ISPCLK_NOC_BUS_ISP_AXI          (JH7110_ISPCLK_END + 2)
> +#define JH7110_ISPCLK_DVP_CLK                  (JH7110_ISPCLK_END + 3)
> +#define JH7110_ISPCLK_EXT_END                  (JH7110_ISPCLK_END + 4)
> +
> +static const struct jh71x0_clk_data jh7110_ispclk_data[] = {
> +       /* syscon */
> +       JH71X0__DIV(JH7110_ISPCLK_DOM4_APB_FUNC, "dom4_apb_func", 15,
> +                   JH7110_ISPCLK_ISP_TOP_AXI),
> +       JH71X0__DIV(JH7110_ISPCLK_MIPI_RX0_PXL, "mipi_rx0_pxl", 8,
> +                   JH7110_ISPCLK_ISP_TOP_CORE),
> +       JH71X0__INV(JH7110_ISPCLK_DVP_INV, "dvp_inv", JH7110_ISPCLK_DVP_CLK),
> +       /* vin */
> +       JH71X0__DIV(JH7110_ISPCLK_M31DPHY_CFGCLK_IN, "m31dphy_cfgclk_in", 16,
> +                   JH7110_ISPCLK_ISP_TOP_CORE),
> +       JH71X0__DIV(JH7110_ISPCLK_M31DPHY_REFCLK_IN, "m31dphy_refclk_in", 16,
> +                   JH7110_ISPCLK_ISP_TOP_CORE),
> +       JH71X0__DIV(JH7110_ISPCLK_M31DPHY_TXCLKESC_LAN0, "m31dphy_txclkesc_lan0", 60,
> +                   JH7110_ISPCLK_ISP_TOP_CORE),
> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PCLK, "vin_pclk", CLK_IGNORE_UNUSED,
> +                   JH7110_ISPCLK_DOM4_APB_FUNC),
> +       JH71X0__DIV(JH7110_ISPCLK_VIN_SYS_CLK, "vin_sys_clk", 8, JH7110_ISPCLK_ISP_TOP_CORE),
> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF0, "vin_pixel_clk_if0", CLK_IGNORE_UNUSED,
> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF1, "vin_pixel_clk_if1", CLK_IGNORE_UNUSED,
> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF2, "vin_pixel_clk_if2", CLK_IGNORE_UNUSED,
> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF3, "vin_pixel_clk_if3", CLK_IGNORE_UNUSED,
> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
> +       JH71X0__MUX(JH7110_ISPCLK_VIN_CLK_P_AXIWR, "vin_clk_p_axiwr", 2,
> +                   JH7110_ISPCLK_MIPI_RX0_PXL,
> +                   JH7110_ISPCLK_DVP_INV),
> +       /* ispv2_top_wrapper */
> +       JH71X0_GMUX(JH7110_ISPCLK_ISPV2_TOP_WRAPPER_CLK_C, "ispv2_top_wrapper_clk_c",
> +                   CLK_IGNORE_UNUSED, 2,
> +                   JH7110_ISPCLK_MIPI_RX0_PXL,
> +                   JH7110_ISPCLK_DVP_INV),
> +};

Are all the clocks marked CLK_IGNORE_UNUSED here critical or are they
just marked like so because the corresponding drivers don't yet claim
the clocks they need? Please mark the clocks that can never be turned
off CLK_IS_CRITICAL and remove the flag from the rest of the clocks.

> +struct isp_top_crg {
> +       struct clk_bulk_data *top_clks;
> +       struct reset_control *top_rsts;
> +       int top_clks_num;
> +       void __iomem *base;
> +};
> +
> +static struct clk_bulk_data jh7110_isp_top_clks[] = {
> +       { .id = "isp_top_core" },
> +       { .id = "isp_top_axi" }
> +};
> +
> +static struct isp_top_crg *top_crg_from(void __iomem **base)
> +{
> +       return container_of(base, struct isp_top_crg, base);
> +}
> +
> +static int jh7110_isp_top_crg_get(struct jh71x0_clk_priv *priv, struct isp_top_crg *top)
> +{
> +       int ret;
> +
> +       top->top_clks = jh7110_isp_top_clks;
> +       top->top_clks_num = ARRAY_SIZE(jh7110_isp_top_clks);
> +       ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
> +       if (ret) {
> +               dev_err(priv->dev, "top clks get failed: %d\n", ret);
> +               return ret;
> +       }
> +
> +       /* The resets should be shared and other ISP modules will use its. */
> +       top->top_rsts = devm_reset_control_array_get_shared(priv->dev);
> +       if (IS_ERR(top->top_rsts)) {
> +               dev_err(priv->dev, "top rsts get failed\n");
> +               return PTR_ERR(top->top_rsts);
> +       }
> +
> +       return 0;
> +}
> +
> +static int jh7110_isp_top_crg_enable(struct isp_top_crg *top)
> +{
> +       int ret;
> +
> +       ret = clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
> +       if (ret)
> +               return ret;
> +
> +       return reset_control_deassert(top->top_rsts);
> +}
> +
> +static void jh7110_isp_top_crg_disable(struct isp_top_crg *top)
> +{
> +       clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
> +}
> +
> +static struct clk_hw *jh7110_ispclk_get(struct of_phandle_args *clkspec, void *data)
> +{
> +       struct jh71x0_clk_priv *priv = data;
> +       unsigned int idx = clkspec->args[0];
> +
> +       if (idx < JH7110_ISPCLK_END)
> +               return &priv->reg[idx].hw;
> +
> +       return ERR_PTR(-EINVAL);
> +}
> +
> +static int jh7110_ispcrg_probe(struct platform_device *pdev)
> +{
> +       struct jh71x0_clk_priv *priv;
> +       struct isp_top_crg *top;
> +       unsigned int idx;
> +       int ret;
> +
> +       priv = devm_kzalloc(&pdev->dev,
> +                           struct_size(priv, reg, JH7110_ISPCLK_END),
> +                           GFP_KERNEL);
> +       if (!priv)
> +               return -ENOMEM;
> +
> +       top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
> +       if (!top)
> +               return -ENOMEM;
> +
> +       spin_lock_init(&priv->rmw_lock);
> +       priv->dev = &pdev->dev;
> +       priv->base = devm_platform_ioremap_resource(pdev, 0);
> +       if (IS_ERR(priv->base))
> +               return PTR_ERR(priv->base);
> +
> +       top->base = priv->base;
> +       dev_set_drvdata(priv->dev, (void *)(&top->base));
> +
> +       pm_runtime_enable(priv->dev);
> +       ret = pm_runtime_get_sync(priv->dev);
> +       if (ret < 0) {
> +               dev_err(priv->dev, "failed to turn on power: %d\n", ret);
> +               return ret;
> +       }
> +
> +       ret = jh7110_isp_top_crg_get(priv, top);
> +       if (ret)
> +               goto err_clk;
> +
> +       ret = jh7110_isp_top_crg_enable(top);
> +       if (ret)
> +               goto err_clk;
> +
> +       for (idx = 0; idx < JH7110_ISPCLK_END; idx++) {
> +               u32 max = jh7110_ispclk_data[idx].max;
> +               struct clk_parent_data parents[4] = {};
> +               struct clk_init_data init = {
> +                       .name = jh7110_ispclk_data[idx].name,
> +                       .ops = starfive_jh71x0_clk_ops(max),
> +                       .parent_data = parents,
> +                       .num_parents =
> +                               ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
> +                       .flags = jh7110_ispclk_data[idx].flags,
> +               };
> +               struct jh71x0_clk *clk = &priv->reg[idx];
> +               unsigned int i;
> +               char *fw_name[JH7110_ISPCLK_EXT_END - JH7110_ISPCLK_END] = {
> +                       "isp_top_core",
> +                       "isp_top_axi",
> +                       "noc_bus_isp_axi",
> +                       "dvp_clk"
> +               };
> +
> +               for (i = 0; i < init.num_parents; i++) {
> +                       unsigned int pidx = jh7110_ispclk_data[idx].parents[i];
> +
> +                       if (pidx < JH7110_ISPCLK_END)
> +                               parents[i].hw = &priv->reg[pidx].hw;
> +                       else
> +                               parents[i].fw_name = fw_name[pidx - JH7110_ISPCLK_END];
> +               }
> +
> +               clk->hw.init = &init;
> +               clk->idx = idx;
> +               clk->max_div = max & JH71X0_CLK_DIV_MASK;
> +
> +               ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
> +               if (ret)
> +                       goto err_exit;
> +       }
> +
> +       ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_ispclk_get, priv);
> +       if (ret)
> +               goto err_exit;
> +
> +       ret = jh7110_reset_controller_register(priv, "reset-isp", 3);
> +       if (ret)
> +               goto err_exit;
> +
> +       return 0;
> +
> +err_exit:
> +       jh7110_isp_top_crg_disable(top);
> +err_clk:
> +       pm_runtime_put_sync(priv->dev);
> +       pm_runtime_disable(priv->dev);
> +       return ret;
> +}
> +
> +static int jh7110_ispcrg_remove(struct platform_device *pdev)
> +{
> +       void __iomem **base = dev_get_drvdata(&pdev->dev);
> +       struct isp_top_crg *top = top_crg_from(base);
> +
> +       jh7110_isp_top_crg_disable(top);
> +       pm_runtime_disable(&pdev->dev);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id jh7110_ispcrg_match[] = {
> +       { .compatible = "starfive,jh7110-ispcrg" },
> +       { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, jh7110_ispcrg_match);
> +
> +static struct platform_driver jh7110_ispcrg_driver = {
> +       .probe = jh7110_ispcrg_probe,
> +       .remove = jh7110_ispcrg_remove,
> +       .driver = {
> +               .name = "clk-starfive-jh7110-isp",
> +               .of_match_table = jh7110_ispcrg_match,
> +       },
> +};
> +module_platform_driver(jh7110_ispcrg_driver);
> +
> +MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
> +MODULE_DESCRIPTION("StarFive JH7110 Image-Signal-Process clock driver");
> +MODULE_LICENSE("GPL");
> --
> 2.25.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 09/11] clk: starfive: Add StarFive JH7110 Video-Output clock driver
  2023-02-21  8:33 ` [PATCH v2 09/11] clk: starfive: Add StarFive JH7110 Video-Output clock driver Xingyu Wu
@ 2023-03-02 15:48   ` Emil Renner Berthing
  2023-03-03  3:37     ` Xingyu Wu
  0 siblings, 1 reply; 33+ messages in thread
From: Emil Renner Berthing @ 2023-03-02 15:48 UTC (permalink / raw)
  To: Xingyu Wu
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On Tue, 21 Feb 2023 at 09:40, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
>
> Add driver for the StarFive JH7110 Video-Output clock controller.
>
> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
> ---
>  drivers/clk/starfive/Kconfig                  |  11 +
>  drivers/clk/starfive/Makefile                 |   1 +
>  .../clk/starfive/clk-starfive-jh7110-vout.c   | 261 ++++++++++++++++++
>  3 files changed, 273 insertions(+)
>  create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-vout.c
>
> diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
> index 59499acb95f7..5ebf1ed08627 100644
> --- a/drivers/clk/starfive/Kconfig
> +++ b/drivers/clk/starfive/Kconfig
> @@ -64,3 +64,14 @@ config CLK_STARFIVE_JH7110_ISP
>         help
>           Say yes here to support the Image-Signal-Process clock controller
>           on the StarFive JH7110 SoC.
> +
> +config CLK_STARFIVE_JH7110_VOUT
> +       tristate "StarFive JH7110 Video-Output clock support"
> +       depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
> +       select AUXILIARY_BUS
> +       select CLK_STARFIVE_JH71X0
> +       select RESET_STARFIVE_JH7110
> +       default CLK_STARFIVE_JH7110_SYS

default m if ARCH_STARFIVE

> +       help
> +         Say yes here to support the Video-Output clock controller
> +         on the StarFive JH7110 SoC.
> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
> index 76fb9f8d628b..841377e45bb6 100644
> --- a/drivers/clk/starfive/Makefile
> +++ b/drivers/clk/starfive/Makefile
> @@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS)   += clk-starfive-jh7110-sys.o
>  obj-$(CONFIG_CLK_STARFIVE_JH7110_AON)  += clk-starfive-jh7110-aon.o
>  obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)  += clk-starfive-jh7110-stg.o
>  obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP)  += clk-starfive-jh7110-isp.o
> +obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
> diff --git a/drivers/clk/starfive/clk-starfive-jh7110-vout.c b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
> new file mode 100644
> index 000000000000..d786537563a4
> --- /dev/null
> +++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
> @@ -0,0 +1,261 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * StarFive JH7110 Video-Output Clock Driver
> + *
> + * Copyright (C) 2022 StarFive Technology Co., Ltd.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/reset.h>
> +
> +#include <dt-bindings/clock/starfive,jh7110-crg.h>
> +
> +#include "clk-starfive-jh71x0.h"
> +
> +/* external clocks */
> +#define JH7110_VOUTCLK_VOUT_SRC                        (JH7110_VOUTCLK_END + 0)
> +#define JH7110_VOUTCLK_VOUT_TOP_AHB            (JH7110_VOUTCLK_END + 1)
> +#define JH7110_VOUTCLK_VOUT_TOP_AXI            (JH7110_VOUTCLK_END + 2)
> +#define JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK   (JH7110_VOUTCLK_END + 3)
> +#define JH7110_VOUTCLK_I2STX0_BCLK             (JH7110_VOUTCLK_END + 4)
> +#define JH7110_VOUTCLK_HDMITX0_PIXELCLK                (JH7110_VOUTCLK_END + 5)
> +#define JH7110_VOUTCLK_EXT_END                 (JH7110_VOUTCLK_END + 6)
> +
> +static const struct jh71x0_clk_data jh7110_voutclk_data[] = {
> +       /* divider */
> +       JH71X0__DIV(JH7110_VOUTCLK_APB, "apb", 8, JH7110_VOUTCLK_VOUT_TOP_AHB),
> +       JH71X0__DIV(JH7110_VOUTCLK_DC8200_PIX, "dc8200_pix", 63, JH7110_VOUTCLK_VOUT_SRC),
> +       JH71X0__DIV(JH7110_VOUTCLK_DSI_SYS, "dsi_sys", 31, JH7110_VOUTCLK_VOUT_SRC),
> +       JH71X0__DIV(JH7110_VOUTCLK_TX_ESC, "tx_esc", 31, JH7110_VOUTCLK_VOUT_TOP_AHB),
> +       /* dc8200 */
> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_AXI, "dc8200_axi", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_CORE, "dc8200_core", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_AHB, "dc8200_ahb", 0, JH7110_VOUTCLK_VOUT_TOP_AHB),
> +       JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX0, "dc8200_pix0", 0, 2,
> +                   JH7110_VOUTCLK_DC8200_PIX,
> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
> +       JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX1, "dc8200_pix1", 0, 2,
> +                   JH7110_VOUTCLK_DC8200_PIX,
> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
> +       /* LCD */
> +       JH71X0_GMUX(JH7110_VOUTCLK_DOM_VOUT_TOP_LCD, "dom_vout_top_lcd", 0, 2,
> +                   JH7110_VOUTCLK_DC8200_PIX0,
> +                   JH7110_VOUTCLK_DC8200_PIX1),
> +       /* dsiTx */
> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_APB, "dsiTx_apb", 0, JH7110_VOUTCLK_DSI_SYS),
> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_SYS, "dsiTx_sys", 0, JH7110_VOUTCLK_DSI_SYS),
> +       JH71X0_GMUX(JH7110_VOUTCLK_DSITX_DPI, "dsiTx_dpi", 0, 2,
> +                   JH7110_VOUTCLK_DC8200_PIX,
> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_TXESC, "dsiTx_txesc", 0, JH7110_VOUTCLK_TX_ESC),
> +       /* mipitx DPHY */
> +       JH71X0_GATE(JH7110_VOUTCLK_MIPITX_DPHY_TXESC, "mipitx_dphy_txesc", 0,
> +                   JH7110_VOUTCLK_TX_ESC),
> +       /* hdmi */
> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_MCLK, "hdmi_tx_mclk", 0,
> +                   JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK),
> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_BCLK, "hdmi_tx_bclk", 0,
> +                   JH7110_VOUTCLK_I2STX0_BCLK),
> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_SYS, "hdmi_tx_sys", 0, JH7110_VOUTCLK_APB),
> +};
> +
> +struct vout_top_crg {
> +       struct clk_bulk_data *top_clks;
> +       struct reset_control *top_rst;
> +       int top_clks_num;
> +       void __iomem *base;
> +};
> +
> +static struct clk_bulk_data jh7110_vout_top_clks[] = {
> +       { .id = "vout_src" },
> +       { .id = "vout_top_ahb" }
> +};
> +
> +static struct vout_top_crg *top_crg_from(void __iomem **base)
> +{
> +       return container_of(base, struct vout_top_crg, base);
> +}
> +
> +static int jh7110_vout_top_crg_get(struct jh71x0_clk_priv *priv, struct vout_top_crg *top)
> +{
> +       int ret;
> +
> +       top->top_clks = jh7110_vout_top_clks;
> +       top->top_clks_num = ARRAY_SIZE(jh7110_vout_top_clks);
> +       ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
> +       if (ret) {
> +               dev_err(priv->dev, "top clks get failed: %d\n", ret);
> +               return ret;
> +       }
> +
> +       /* The reset should be shared and other Vout modules will use its. */
> +       top->top_rst = devm_reset_control_get_shared(priv->dev, NULL);
> +       if (IS_ERR(top->top_rst)) {
> +               dev_err(priv->dev, "top rst get failed\n");
> +               return PTR_ERR(top->top_rst);
> +       }
> +
> +       return 0;
> +}
> +
> +static int jh7110_vout_top_crg_enable(struct vout_top_crg *top)
> +{
> +       int ret;
> +
> +       ret = clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
> +       if (ret)
> +               return ret;

Hmm.. do all the clocks used as input really need to be enabled for
any one of the vout clocks to work?

In other words: suppose you just need a single clock in the VOUTCRG
domain. Do we really need to turn on all the input clocks for the
VOUTCRG for that one clock to work? Normally I'd expect the clock
framework to make sure all parents of that clock are enabled.

> +
> +       return reset_control_deassert(top->top_rst);
> +}
> +
> +static void jh7110_vout_top_crg_disable(struct vout_top_crg *top)
> +{
> +       clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
> +}
> +
> +static struct clk_hw *jh7110_voutclk_get(struct of_phandle_args *clkspec, void *data)
> +{
> +       struct jh71x0_clk_priv *priv = data;
> +       unsigned int idx = clkspec->args[0];
> +
> +       if (idx < JH7110_VOUTCLK_END)
> +               return &priv->reg[idx].hw;
> +
> +       return ERR_PTR(-EINVAL);
> +}
> +
> +static int jh7110_voutcrg_probe(struct platform_device *pdev)
> +{
> +       struct jh71x0_clk_priv *priv;
> +       struct vout_top_crg *top;
> +       unsigned int idx;
> +       int ret;
> +
> +       priv = devm_kzalloc(&pdev->dev,
> +                           struct_size(priv, reg, JH7110_VOUTCLK_END),
> +                           GFP_KERNEL);
> +       if (!priv)
> +               return -ENOMEM;
> +
> +       top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
> +       if (!top)
> +               return -ENOMEM;
> +
> +       spin_lock_init(&priv->rmw_lock);
> +       priv->dev = &pdev->dev;
> +       priv->base = devm_platform_ioremap_resource(pdev, 0);
> +       if (IS_ERR(priv->base))
> +               return PTR_ERR(priv->base);
> +
> +       top->base = priv->base;
> +       dev_set_drvdata(priv->dev, (void *)(&top->base));
> +
> +       pm_runtime_enable(priv->dev);
> +       ret = pm_runtime_get_sync(priv->dev);
> +       if (ret < 0) {
> +               dev_err(priv->dev, "failed to turn power: %d\n", ret);
> +               return ret;
> +       }
> +
> +       ret = jh7110_vout_top_crg_get(priv, top);
> +       if (ret)
> +               goto err_clk;
> +
> +       ret = jh7110_vout_top_crg_enable(top);
> +       if (ret)
> +               goto err_clk;
> +
> +       for (idx = 0; idx < JH7110_VOUTCLK_END; idx++) {
> +               u32 max = jh7110_voutclk_data[idx].max;
> +               struct clk_parent_data parents[4] = {};
> +               struct clk_init_data init = {
> +                       .name = jh7110_voutclk_data[idx].name,
> +                       .ops = starfive_jh71x0_clk_ops(max),
> +                       .parent_data = parents,
> +                       .num_parents =
> +                               ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
> +                       .flags = jh7110_voutclk_data[idx].flags,
> +               };
> +               struct jh71x0_clk *clk = &priv->reg[idx];
> +               unsigned int i;
> +               char *fw_name[JH7110_VOUTCLK_EXT_END - JH7110_VOUTCLK_END] = {

this can be const char *const fw_name[...] right?

> +                       "vout_src",
> +                       "vout_top_ahb",
> +                       "vout_top_axi",
> +                       "vout_top_hdmitx0_mclk",
> +                       "i2stx0_bclk",
> +                       "hdmitx0_pixelclk"
> +               };
> +
> +               for (i = 0; i < init.num_parents; i++) {
> +                       unsigned int pidx = jh7110_voutclk_data[idx].parents[i];
> +
> +                       if (pidx < JH7110_VOUTCLK_END)
> +                               parents[i].hw = &priv->reg[pidx].hw;
> +                       else if (pidx < JH7110_VOUTCLK_EXT_END)
> +                               parents[i].fw_name = fw_name[pidx - JH7110_VOUTCLK_END];
> +               }
> +
> +               clk->hw.init = &init;
> +               clk->idx = idx;
> +               clk->max_div = max & JH71X0_CLK_DIV_MASK;
> +
> +               ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
> +               if (ret)
> +                       goto err_exit;
> +       }
> +
> +       ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_voutclk_get, priv);
> +       if (ret)
> +               goto err_exit;
> +
> +       ret = jh7110_reset_controller_register(priv, "reset-vout", 4);
> +       if (ret)
> +               goto err_exit;
> +
> +       return 0;
> +
> +err_exit:
> +       jh7110_vout_top_crg_disable(top);
> +err_clk:
> +       pm_runtime_put_sync(priv->dev);
> +       pm_runtime_disable(priv->dev);
> +       return ret;
> +}
> +
> +static int jh7110_voutcrg_remove(struct platform_device *pdev)
> +{
> +       void __iomem **base = dev_get_drvdata(&pdev->dev);
> +       struct vout_top_crg *top = top_crg_from(base);
> +
> +       jh7110_vout_top_crg_disable(top);
> +       pm_runtime_disable(&pdev->dev);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id jh7110_voutcrg_match[] = {
> +       { .compatible = "starfive,jh7110-voutcrg" },
> +       { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, jh7110_voutcrg_match);
> +
> +static struct platform_driver jh7110_voutcrg_driver = {
> +       .probe = jh7110_voutcrg_probe,
> +       .remove = jh7110_voutcrg_remove,
> +       .driver = {
> +               .name = "clk-starfive-jh7110-vout",
> +               .of_match_table = jh7110_voutcrg_match,
> +       },
> +};
> +module_platform_driver(jh7110_voutcrg_driver);
> +
> +MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
> +MODULE_DESCRIPTION("StarFive JH7110 Video-Output clock driver");
> +MODULE_LICENSE("GPL");
> --
> 2.25.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 01/11] dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and reset generator
  2023-03-02 15:05   ` Emil Renner Berthing
@ 2023-03-03  3:14     ` Xingyu Wu
  0 siblings, 0 replies; 33+ messages in thread
From: Xingyu Wu @ 2023-03-03  3:14 UTC (permalink / raw)
  To: Emil Renner Berthing
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On 2023/3/2 23:05, Emil Renner Berthing wrote:
> On Tue, 21 Feb 2023 at 09:37, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
>> Add bindings for the System-Top-Group clock and reset generator (STGCRG)
>> on the JH7110 RISC-V SoC by StarFive Ltd.
>>
>> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
>> ---
>>  .../clock/starfive,jh7110-stgcrg.yaml         | 82 +++++++++++++++++++
>>  MAINTAINERS                                   |  1 +
>>  .../dt-bindings/clock/starfive,jh7110-crg.h   | 34 ++++++++
>>  .../dt-bindings/reset/starfive,jh7110-crg.h   | 28 +++++++
>>  4 files changed, 145 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
>> new file mode 100644
>> index 000000000000..b64ccd84200a
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
>> @@ -0,0 +1,82 @@
>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/clock/starfive,jh7110-stgcrg.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: StarFive JH7110 System-Top-Group Clock and Reset Generator
>> +
>> +maintainers:
>> +  - Xingyu Wu <xingyu.wu@starfivetech.com>
>> +
>> +properties:
>> +  compatible:
>> +    const: starfive,jh7110-stgcrg
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  clocks:
>> +    items:
>> +      - description: Main Oscillator (24 MHz)
>> +      - description: HIFI4 core
>> +      - description: STG AXI/AHB
>> +      - description: USB (125 MHz)
>> +      - description: CPU Bus
>> +      - description: HIFI4 Axi
>> +      - description: NOC STG Bus
>> +      - description: APB Bus
>> +
>> +  clock-names:
>> +    items:
>> +      - const: osc
>> +      - const: hifi4_core
>> +      - const: stg_axiahb
>> +      - const: usb_125m
>> +      - const: cpu_bus
>> +      - const: hifi4_axi
>> +      - const: nocstg_bus
>> +      - const: apb_bus
>> +
>> +  '#clock-cells':
>> +    const: 1
>> +    description:
>> +      See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
>> +
>> +  '#reset-cells':
>> +    const: 1
>> +    description:
>> +      See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - clocks
>> +  - clock-names
>> +  - '#clock-cells'
>> +  - '#reset-cells'
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/starfive,jh7110-crg.h>
>> +
>> +    stgcrg: clock-controller@10230000 {
>> +        compatible = "starfive,jh7110-stgcrg";
>> +        reg = <0x10230000 0x10000>;
>> +        clocks = <&osc>,
>> +                 <&syscrg JH7110_SYSCLK_HIFI4_CORE>,
>> +                 <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
>> +                 <&syscrg JH7110_SYSCLK_USB_125M>,
>> +                 <&syscrg JH7110_SYSCLK_CPU_BUS>,
>> +                 <&syscrg JH7110_SYSCLK_HIFI4_AXI>,
>> +                 <&syscrg JH7110_SYSCLK_NOCSTG_BUS>,
>> +                 <&syscrg JH7110_SYSCLK_APB_BUS>;
>> +        clock-names = "osc", "hifi4_core",
>> +                      "stg_axiahb", "usb_125m",
>> +                      "cpu_bus", "hifi4_axi",
>> +                      "nocstg_bus", "apb_bus";
>> +        #clock-cells = <1>;
>> +        #reset-cells = <1>;
>> +    };
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 93eb504c3b21..2e70c9f21989 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -19914,6 +19914,7 @@ F:      arch/riscv/boot/dts/starfive/
>>  STARFIVE JH71X0 CLOCK DRIVERS
>>  M:     Emil Renner Berthing <kernel@esmil.dk>
>>  M:     Hal Feng <hal.feng@starfivetech.com>
>> +M:     Xingyu Wu <xingyu.wu@starfivetech.com>
>>  S:     Maintained
>>  F:     Documentation/devicetree/bindings/clock/starfive,jh71*.yaml
>>  F:     drivers/clk/starfive/clk-starfive-jh71*
>> diff --git a/include/dt-bindings/clock/starfive,jh7110-crg.h b/include/dt-bindings/clock/starfive,jh7110-crg.h
>> index 5e4f21ca0642..5ac8a4d90a7a 100644
>> --- a/include/dt-bindings/clock/starfive,jh7110-crg.h
>> +++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
>> @@ -1,6 +1,7 @@
>>  /* SPDX-License-Identifier: GPL-2.0 OR MIT */
>>  /*
>>   * Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
>> + * Copyright 2022 StarFive Technology Co., Ltd.
>>   */
>>
>>  #ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
>> @@ -222,4 +223,37 @@
>>
>>  #define JH7110_AONCLK_END                      14
> 
> Hi Xingyu,
> 
> The clock and reset names below have been shortened from the very long
> names in the documentation. I see you've come to the same shortened
> names as I used in the first STGCRG driver I pushed, which is great,
> but I find it highly unlikely to have happened without looking at /
> copying my code like you did for the SYSCRG and AONCRG drivers Hal has
> posted. Unfortunately the commit message above doesn't reflect that,
> so please add a
> Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
> Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>

Thanks. But these STG/ISP/VOUT drivers are transplanted from 7110-SDK wrote
by myself one year ago and followed 7100 clock drivers framework and structure
at that time. And I haven't seen your STGCRG driver before. I improved these
to follow these SYSCRG and AONCRG drivers' framework. So you could look like copying
your code but these are still little different like these clock and reset name.

But I don't know if I am right. I follow your code framework to write it and
I should add 'Co-developed-by' and 'Signed-off-by' to reflect that. It that right?

> 
> I do have some updated suggestions for short names below though:
> 
>> +/* STGCRG clocks */
>> +#define JH7110_STGCLK_HIFI4_CLK_CORE           0
>> +#define JH7110_STGCLK_USB0_APB                 1
>> +#define JH7110_STGCLK_USB0_UTMI_APB            2 unli
>> +#define JH7110_STGCLK_USB0_AXI                 3
>> +#define JH7110_STGCLK_USB0_LPM                 4
>> +#define JH7110_STGCLK_USB0_STB                 5
>> +#define JH7110_STGCLK_USB0_APP_125             6
>> +#define JH7110_STGCLK_USB0_REFCLK              7
>> +#define JH7110_STGCLK_PCIE0_AXI_MST0           8
>> +#define JH7110_STGCLK_PCIE0_APB                        9
>> +#define JH7110_STGCLK_PCIE0_TL                 10
>> +#define JH7110_STGCLK_PCIE1_AXI_MST0           11
>> +#define JH7110_STGCLK_PCIE1_APB                        12
>> +#define JH7110_STGCLK_PCIE1_TL                 13
>> +#define JH7110_STGCLK_PCIE01_SLV_DEC_MAINCLK   14
> 
> Does PCIE01 here mean that the clock is used by both pcie0 and pcie1?
> If so then maybe just call it JH7110_PCIE_SLV_MAIN

Yes, it is used by both pcie0 and pcie1. Will modify it.

> 
>> +#define JH7110_STGCLK_SEC_HCLK                 15
> 
> For other clocks I think "hclk" means ahb clock, so maybe JH7110_STGCLK_SEC_AHB

Will modify it.

> 
>> +#define JH7110_STGCLK_SEC_MISCAHB              16
> 
> I find something like JH7110_STGCLK_SEC_MISC_AHB a little easier to read.

Will modify it.

> 
>> +#define JH7110_STGCLK_GRP0_MAIN                        17
>> +#define JH7110_STGCLK_GRP0_BUS                 18
>> +#define JH7110_STGCLK_GRP0_STG                 19
>> +#define JH7110_STGCLK_GRP1_MAIN                        20
>> +#define JH7110_STGCLK_GRP1_BUS                 21
>> +#define JH7110_STGCLK_GRP1_STG                 22
>> +#define JH7110_STGCLK_GRP1_HIFI                        23
>> +#define JH7110_STGCLK_E2_RTC                   24
>> +#define JH7110_STGCLK_E2_CORE                  25
>> +#define JH7110_STGCLK_E2_DBG                   26
>> +#define JH7110_STGCLK_DMA1P_AXI                        27
>> +#define JH7110_STGCLK_DMA1P_AHB                        28
>> +
>> +#define JH7110_STGCLK_END                      29
>> +
>>  #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
>> diff --git a/include/dt-bindings/reset/starfive,jh7110-crg.h b/include/dt-bindings/reset/starfive,jh7110-crg.h
>> index d78e38690ceb..4a865ded78b8 100644
>> --- a/include/dt-bindings/reset/starfive,jh7110-crg.h
>> +++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
>> @@ -1,6 +1,7 @@
>>  /* SPDX-License-Identifier: GPL-2.0 OR MIT */
>>  /*
>>   * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
>> + * Copyright (C) 2022 StarFive Technology Co., Ltd.
>>   */
>>
>>  #ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
>> @@ -151,4 +152,31 @@
>>
>>  #define JH7110_AONRST_END                      8
>>
>> +/* STGCRG resets */
>> +#define JH7110_STGRST_SYSCON                   0
>> +#define JH7110_STGRST_HIFI4_CORE               1
>> +#define JH7110_STGRST_HIFI4_AXI                        2
>> +#define JH7110_STGRST_SEC_TOP_HRESETN          3
> 
> JH7110_STGRST_SEC_AHB to match the clock above.

Will modify it.

> 
>> +#define JH7110_STGRST_E24_CORE                 4
>> +#define JH7110_STGRST_DMA1P_AXI                        5
>> +#define JH7110_STGRST_DMA1P_AHB                        6
>> +#define JH7110_STGRST_USB0_AXI                 7
>> +#define JH7110_STGRST_USB0_APB                 8
>> +#define JH7110_STGRST_USB0_UTMI_APB            9
>> +#define JH7110_STGRST_USB0_PWRUP               10
>> +#define JH7110_STGRST_PCIE0_AXI_MST0           11
>> +#define JH7110_STGRST_PCIE0_AXI_SLV0           12
>> +#define JH7110_STGRST_PCIE0_AXI_SLV            13
>> +#define JH7110_STGRST_PCIE0_BRG                        14
>> +#define JH7110_STGRST_PCIE0_CORE               15
>> +#define JH7110_STGRST_PCIE0_APB                        16
>> +#define JH7110_STGRST_PCIE1_AXI_MST0           17
>> +#define JH7110_STGRST_PCIE1_AXI_SLV0           18
>> +#define JH7110_STGRST_PCIE1_AXI_SLV            19
>> +#define JH7110_STGRST_PCIE1_BRG                        20
>> +#define JH7110_STGRST_PCIE1_CORE               21
>> +#define JH7110_STGRST_PCIE1_APB                        22
>> +
>> +#define JH7110_STGRST_END                      23
>> +
>>  #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
>> --
>> 2.25.1
>>
>>
>> _______________________________________________
>> linux-riscv mailing list
>> linux-riscv@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-riscv

Best regards

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 09/11] clk: starfive: Add StarFive JH7110 Video-Output clock driver
  2023-03-02 15:48   ` Emil Renner Berthing
@ 2023-03-03  3:37     ` Xingyu Wu
  2023-03-03  9:23       ` Emil Renner Berthing
  0 siblings, 1 reply; 33+ messages in thread
From: Xingyu Wu @ 2023-03-03  3:37 UTC (permalink / raw)
  To: Emil Renner Berthing
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On 2023/3/2 23:48, Emil Renner Berthing wrote:
> On Tue, 21 Feb 2023 at 09:40, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
>>
>> Add driver for the StarFive JH7110 Video-Output clock controller.
>>
>> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
>> ---
>>  drivers/clk/starfive/Kconfig                  |  11 +
>>  drivers/clk/starfive/Makefile                 |   1 +
>>  .../clk/starfive/clk-starfive-jh7110-vout.c   | 261 ++++++++++++++++++
>>  3 files changed, 273 insertions(+)
>>  create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-vout.c
>>
>> diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
>> index 59499acb95f7..5ebf1ed08627 100644
>> --- a/drivers/clk/starfive/Kconfig
>> +++ b/drivers/clk/starfive/Kconfig
>> @@ -64,3 +64,14 @@ config CLK_STARFIVE_JH7110_ISP
>>         help
>>           Say yes here to support the Image-Signal-Process clock controller
>>           on the StarFive JH7110 SoC.
>> +
>> +config CLK_STARFIVE_JH7110_VOUT
>> +       tristate "StarFive JH7110 Video-Output clock support"
>> +       depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
>> +       select AUXILIARY_BUS
>> +       select CLK_STARFIVE_JH71X0
>> +       select RESET_STARFIVE_JH7110
>> +       default CLK_STARFIVE_JH7110_SYS
> 
> default m if ARCH_STARFIVE

Will modify it.

> 
>> +       help
>> +         Say yes here to support the Video-Output clock controller
>> +         on the StarFive JH7110 SoC.
>> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
>> index 76fb9f8d628b..841377e45bb6 100644
>> --- a/drivers/clk/starfive/Makefile
>> +++ b/drivers/clk/starfive/Makefile
>> @@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS)   += clk-starfive-jh7110-sys.o
>>  obj-$(CONFIG_CLK_STARFIVE_JH7110_AON)  += clk-starfive-jh7110-aon.o
>>  obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)  += clk-starfive-jh7110-stg.o
>>  obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP)  += clk-starfive-jh7110-isp.o
>> +obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
>> diff --git a/drivers/clk/starfive/clk-starfive-jh7110-vout.c b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
>> new file mode 100644
>> index 000000000000..d786537563a4
>> --- /dev/null
>> +++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
>> @@ -0,0 +1,261 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * StarFive JH7110 Video-Output Clock Driver
>> + *
>> + * Copyright (C) 2022 StarFive Technology Co., Ltd.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/reset.h>
>> +
>> +#include <dt-bindings/clock/starfive,jh7110-crg.h>
>> +
>> +#include "clk-starfive-jh71x0.h"
>> +
>> +/* external clocks */
>> +#define JH7110_VOUTCLK_VOUT_SRC                        (JH7110_VOUTCLK_END + 0)
>> +#define JH7110_VOUTCLK_VOUT_TOP_AHB            (JH7110_VOUTCLK_END + 1)
>> +#define JH7110_VOUTCLK_VOUT_TOP_AXI            (JH7110_VOUTCLK_END + 2)
>> +#define JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK   (JH7110_VOUTCLK_END + 3)
>> +#define JH7110_VOUTCLK_I2STX0_BCLK             (JH7110_VOUTCLK_END + 4)
>> +#define JH7110_VOUTCLK_HDMITX0_PIXELCLK                (JH7110_VOUTCLK_END + 5)
>> +#define JH7110_VOUTCLK_EXT_END                 (JH7110_VOUTCLK_END + 6)
>> +
>> +static const struct jh71x0_clk_data jh7110_voutclk_data[] = {
>> +       /* divider */
>> +       JH71X0__DIV(JH7110_VOUTCLK_APB, "apb", 8, JH7110_VOUTCLK_VOUT_TOP_AHB),
>> +       JH71X0__DIV(JH7110_VOUTCLK_DC8200_PIX, "dc8200_pix", 63, JH7110_VOUTCLK_VOUT_SRC),
>> +       JH71X0__DIV(JH7110_VOUTCLK_DSI_SYS, "dsi_sys", 31, JH7110_VOUTCLK_VOUT_SRC),
>> +       JH71X0__DIV(JH7110_VOUTCLK_TX_ESC, "tx_esc", 31, JH7110_VOUTCLK_VOUT_TOP_AHB),
>> +       /* dc8200 */
>> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_AXI, "dc8200_axi", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
>> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_CORE, "dc8200_core", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
>> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_AHB, "dc8200_ahb", 0, JH7110_VOUTCLK_VOUT_TOP_AHB),
>> +       JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX0, "dc8200_pix0", 0, 2,
>> +                   JH7110_VOUTCLK_DC8200_PIX,
>> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
>> +       JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX1, "dc8200_pix1", 0, 2,
>> +                   JH7110_VOUTCLK_DC8200_PIX,
>> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
>> +       /* LCD */
>> +       JH71X0_GMUX(JH7110_VOUTCLK_DOM_VOUT_TOP_LCD, "dom_vout_top_lcd", 0, 2,
>> +                   JH7110_VOUTCLK_DC8200_PIX0,
>> +                   JH7110_VOUTCLK_DC8200_PIX1),
>> +       /* dsiTx */
>> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_APB, "dsiTx_apb", 0, JH7110_VOUTCLK_DSI_SYS),
>> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_SYS, "dsiTx_sys", 0, JH7110_VOUTCLK_DSI_SYS),
>> +       JH71X0_GMUX(JH7110_VOUTCLK_DSITX_DPI, "dsiTx_dpi", 0, 2,
>> +                   JH7110_VOUTCLK_DC8200_PIX,
>> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
>> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_TXESC, "dsiTx_txesc", 0, JH7110_VOUTCLK_TX_ESC),
>> +       /* mipitx DPHY */
>> +       JH71X0_GATE(JH7110_VOUTCLK_MIPITX_DPHY_TXESC, "mipitx_dphy_txesc", 0,
>> +                   JH7110_VOUTCLK_TX_ESC),
>> +       /* hdmi */
>> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_MCLK, "hdmi_tx_mclk", 0,
>> +                   JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK),
>> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_BCLK, "hdmi_tx_bclk", 0,
>> +                   JH7110_VOUTCLK_I2STX0_BCLK),
>> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_SYS, "hdmi_tx_sys", 0, JH7110_VOUTCLK_APB),
>> +};
>> +
>> +struct vout_top_crg {
>> +       struct clk_bulk_data *top_clks;
>> +       struct reset_control *top_rst;
>> +       int top_clks_num;
>> +       void __iomem *base;
>> +};
>> +
>> +static struct clk_bulk_data jh7110_vout_top_clks[] = {
>> +       { .id = "vout_src" },
>> +       { .id = "vout_top_ahb" }
>> +};
>> +
>> +static struct vout_top_crg *top_crg_from(void __iomem **base)
>> +{
>> +       return container_of(base, struct vout_top_crg, base);
>> +}
>> +
>> +static int jh7110_vout_top_crg_get(struct jh71x0_clk_priv *priv, struct vout_top_crg *top)
>> +{
>> +       int ret;
>> +
>> +       top->top_clks = jh7110_vout_top_clks;
>> +       top->top_clks_num = ARRAY_SIZE(jh7110_vout_top_clks);
>> +       ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
>> +       if (ret) {
>> +               dev_err(priv->dev, "top clks get failed: %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       /* The reset should be shared and other Vout modules will use its. */
>> +       top->top_rst = devm_reset_control_get_shared(priv->dev, NULL);
>> +       if (IS_ERR(top->top_rst)) {
>> +               dev_err(priv->dev, "top rst get failed\n");
>> +               return PTR_ERR(top->top_rst);
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int jh7110_vout_top_crg_enable(struct vout_top_crg *top)
>> +{
>> +       int ret;
>> +
>> +       ret = clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
>> +       if (ret)
>> +               return ret;
> 
> Hmm.. do all the clocks used as input really need to be enabled for
> any one of the vout clocks to work?
> 
> In other words: suppose you just need a single clock in the VOUTCRG
> domain. Do we really need to turn on all the input clocks for the
> VOUTCRG for that one clock to work? Normally I'd expect the clock
> framework to make sure all parents of that clock are enabled.

It must enable core clock and ahb clock before reading or writing VOUTCRG registers
otherwise it would be failed to read and write. And it is even crash if it don't
enable core clock before reading or writing ISPCRG registers.
This serious problem was found when debugging earlier.

> 
>> +
>> +       return reset_control_deassert(top->top_rst);
>> +}
>> +
>> +static void jh7110_vout_top_crg_disable(struct vout_top_crg *top)
>> +{
>> +       clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
>> +}
>> +
>> +static struct clk_hw *jh7110_voutclk_get(struct of_phandle_args *clkspec, void *data)
>> +{
>> +       struct jh71x0_clk_priv *priv = data;
>> +       unsigned int idx = clkspec->args[0];
>> +
>> +       if (idx < JH7110_VOUTCLK_END)
>> +               return &priv->reg[idx].hw;
>> +
>> +       return ERR_PTR(-EINVAL);
>> +}
>> +
>> +static int jh7110_voutcrg_probe(struct platform_device *pdev)
>> +{
>> +       struct jh71x0_clk_priv *priv;
>> +       struct vout_top_crg *top;
>> +       unsigned int idx;
>> +       int ret;
>> +
>> +       priv = devm_kzalloc(&pdev->dev,
>> +                           struct_size(priv, reg, JH7110_VOUTCLK_END),
>> +                           GFP_KERNEL);
>> +       if (!priv)
>> +               return -ENOMEM;
>> +
>> +       top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
>> +       if (!top)
>> +               return -ENOMEM;
>> +
>> +       spin_lock_init(&priv->rmw_lock);
>> +       priv->dev = &pdev->dev;
>> +       priv->base = devm_platform_ioremap_resource(pdev, 0);
>> +       if (IS_ERR(priv->base))
>> +               return PTR_ERR(priv->base);
>> +
>> +       top->base = priv->base;
>> +       dev_set_drvdata(priv->dev, (void *)(&top->base));
>> +
>> +       pm_runtime_enable(priv->dev);
>> +       ret = pm_runtime_get_sync(priv->dev);
>> +       if (ret < 0) {
>> +               dev_err(priv->dev, "failed to turn power: %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       ret = jh7110_vout_top_crg_get(priv, top);
>> +       if (ret)
>> +               goto err_clk;
>> +
>> +       ret = jh7110_vout_top_crg_enable(top);
>> +       if (ret)
>> +               goto err_clk;
>> +
>> +       for (idx = 0; idx < JH7110_VOUTCLK_END; idx++) {
>> +               u32 max = jh7110_voutclk_data[idx].max;
>> +               struct clk_parent_data parents[4] = {};
>> +               struct clk_init_data init = {
>> +                       .name = jh7110_voutclk_data[idx].name,
>> +                       .ops = starfive_jh71x0_clk_ops(max),
>> +                       .parent_data = parents,
>> +                       .num_parents =
>> +                               ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
>> +                       .flags = jh7110_voutclk_data[idx].flags,
>> +               };
>> +               struct jh71x0_clk *clk = &priv->reg[idx];
>> +               unsigned int i;
>> +               char *fw_name[JH7110_VOUTCLK_EXT_END - JH7110_VOUTCLK_END] = {
> 
> this can be const char *const fw_name[...] right?
> 
>> +                       "vout_src",
>> +                       "vout_top_ahb",
>> +                       "vout_top_axi",
>> +                       "vout_top_hdmitx0_mclk",
>> +                       "i2stx0_bclk",
>> +                       "hdmitx0_pixelclk"
>> +               };
>> +
>> +               for (i = 0; i < init.num_parents; i++) {
>> +                       unsigned int pidx = jh7110_voutclk_data[idx].parents[i];
>> +
>> +                       if (pidx < JH7110_VOUTCLK_END)
>> +                               parents[i].hw = &priv->reg[pidx].hw;
>> +                       else if (pidx < JH7110_VOUTCLK_EXT_END)
>> +                               parents[i].fw_name = fw_name[pidx - JH7110_VOUTCLK_END];
>> +               }
>> +
>> +               clk->hw.init = &init;
>> +               clk->idx = idx;
>> +               clk->max_div = max & JH71X0_CLK_DIV_MASK;
>> +
>> +               ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
>> +               if (ret)
>> +                       goto err_exit;
>> +       }
>> +
>> +       ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_voutclk_get, priv);
>> +       if (ret)
>> +               goto err_exit;
>> +
>> +       ret = jh7110_reset_controller_register(priv, "reset-vout", 4);
>> +       if (ret)
>> +               goto err_exit;
>> +
>> +       return 0;
>> +
>> +err_exit:
>> +       jh7110_vout_top_crg_disable(top);
>> +err_clk:
>> +       pm_runtime_put_sync(priv->dev);
>> +       pm_runtime_disable(priv->dev);
>> +       return ret;
>> +}
>> +
>> +static int jh7110_voutcrg_remove(struct platform_device *pdev)
>> +{
>> +       void __iomem **base = dev_get_drvdata(&pdev->dev);
>> +       struct vout_top_crg *top = top_crg_from(base);
>> +
>> +       jh7110_vout_top_crg_disable(top);
>> +       pm_runtime_disable(&pdev->dev);
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct of_device_id jh7110_voutcrg_match[] = {
>> +       { .compatible = "starfive,jh7110-voutcrg" },
>> +       { /* sentinel */ }
>> +};
>> +MODULE_DEVICE_TABLE(of, jh7110_voutcrg_match);
>> +
>> +static struct platform_driver jh7110_voutcrg_driver = {
>> +       .probe = jh7110_voutcrg_probe,
>> +       .remove = jh7110_voutcrg_remove,
>> +       .driver = {
>> +               .name = "clk-starfive-jh7110-vout",
>> +               .of_match_table = jh7110_voutcrg_match,
>> +       },
>> +};
>> +module_platform_driver(jh7110_voutcrg_driver);
>> +
>> +MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
>> +MODULE_DESCRIPTION("StarFive JH7110 Video-Output clock driver");
>> +MODULE_LICENSE("GPL");
>> --
>> 2.25.1
>>
>>
>> _______________________________________________
>> linux-riscv mailing list
>> linux-riscv@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-riscv

Best regards,
Xingyu Wu

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 06/11] clk: starfive: Add StarFive JH7110 Image-Signal-Process clock driver
  2023-03-02 15:39   ` Emil Renner Berthing
@ 2023-03-03  3:59     ` Xingyu Wu
  2023-03-03  9:01       ` Emil Renner Berthing
  0 siblings, 1 reply; 33+ messages in thread
From: Xingyu Wu @ 2023-03-03  3:59 UTC (permalink / raw)
  To: Emil Renner Berthing
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On 2023/3/2 23:39, Emil Renner Berthing wrote:
> On Tue, 21 Feb 2023 at 09:36, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
>>
>> Add driver for the StarFive JH7110 Image-Signal-Process clock controller.
>>
>> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
>> ---
>>  drivers/clk/starfive/Kconfig                  |  11 +
>>  drivers/clk/starfive/Makefile                 |   1 +
>>  .../clk/starfive/clk-starfive-jh7110-isp.c    | 254 ++++++++++++++++++
>>  3 files changed, 266 insertions(+)
>>  create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-isp.c
>>
>> diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
>> index a462b6e53543..59499acb95f7 100644
>> --- a/drivers/clk/starfive/Kconfig
>> +++ b/drivers/clk/starfive/Kconfig
>> @@ -53,3 +53,14 @@ config CLK_STARFIVE_JH7110_STG
>>         help
>>           Say yes here to support the System-Top-Group clock controller
>>           on the StarFive JH7110 SoC.
>> +
>> +config CLK_STARFIVE_JH7110_ISP
>> +       tristate "StarFive JH7110 Image-Signal-Process clock support"
>> +       depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
>> +       select AUXILIARY_BUS
>> +       select CLK_STARFIVE_JH71X0
>> +       select RESET_STARFIVE_JH7110
>> +       default CLK_STARFIVE_JH7110_SYS
> 
> default m if ARCH_STARFIVE

Oh, the ISPCRG and VOUTCRG depend on SYSCRG because it need to enable core clock.
So I should modify that:

default m if CLK_STARFIVE_JH7110_SYS

It that OK?

> 
>> +       help
>> +         Say yes here to support the Image-Signal-Process clock controller
>> +         on the StarFive JH7110 SoC.
>> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
>> index b81e97ee2659..76fb9f8d628b 100644
>> --- a/drivers/clk/starfive/Makefile
>> +++ b/drivers/clk/starfive/Makefile
>> @@ -7,3 +7,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
>>  obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS)  += clk-starfive-jh7110-sys.o
>>  obj-$(CONFIG_CLK_STARFIVE_JH7110_AON)  += clk-starfive-jh7110-aon.o
>>  obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)  += clk-starfive-jh7110-stg.o
>> +obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP)  += clk-starfive-jh7110-isp.o
>> diff --git a/drivers/clk/starfive/clk-starfive-jh7110-isp.c b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
>> new file mode 100644
>> index 000000000000..b5bce1ac22e0
>> --- /dev/null
>> +++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
>> @@ -0,0 +1,254 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * StarFive JH7110 Image-Signal-Process Clock Driver
>> + *
>> + * Copyright (C) 2022 StarFive Technology Co., Ltd.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/reset.h>
>> +
>> +#include <dt-bindings/clock/starfive,jh7110-crg.h>
>> +
>> +#include "clk-starfive-jh71x0.h"
>> +
>> +/* external clocks */
>> +#define JH7110_ISPCLK_ISP_TOP_CORE             (JH7110_ISPCLK_END + 0)
>> +#define JH7110_ISPCLK_ISP_TOP_AXI              (JH7110_ISPCLK_END + 1)
>> +#define JH7110_ISPCLK_NOC_BUS_ISP_AXI          (JH7110_ISPCLK_END + 2)
>> +#define JH7110_ISPCLK_DVP_CLK                  (JH7110_ISPCLK_END + 3)
>> +#define JH7110_ISPCLK_EXT_END                  (JH7110_ISPCLK_END + 4)
>> +
>> +static const struct jh71x0_clk_data jh7110_ispclk_data[] = {
>> +       /* syscon */
>> +       JH71X0__DIV(JH7110_ISPCLK_DOM4_APB_FUNC, "dom4_apb_func", 15,
>> +                   JH7110_ISPCLK_ISP_TOP_AXI),
>> +       JH71X0__DIV(JH7110_ISPCLK_MIPI_RX0_PXL, "mipi_rx0_pxl", 8,
>> +                   JH7110_ISPCLK_ISP_TOP_CORE),
>> +       JH71X0__INV(JH7110_ISPCLK_DVP_INV, "dvp_inv", JH7110_ISPCLK_DVP_CLK),
>> +       /* vin */
>> +       JH71X0__DIV(JH7110_ISPCLK_M31DPHY_CFGCLK_IN, "m31dphy_cfgclk_in", 16,
>> +                   JH7110_ISPCLK_ISP_TOP_CORE),
>> +       JH71X0__DIV(JH7110_ISPCLK_M31DPHY_REFCLK_IN, "m31dphy_refclk_in", 16,
>> +                   JH7110_ISPCLK_ISP_TOP_CORE),
>> +       JH71X0__DIV(JH7110_ISPCLK_M31DPHY_TXCLKESC_LAN0, "m31dphy_txclkesc_lan0", 60,
>> +                   JH7110_ISPCLK_ISP_TOP_CORE),
>> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PCLK, "vin_pclk", CLK_IGNORE_UNUSED,
>> +                   JH7110_ISPCLK_DOM4_APB_FUNC),
>> +       JH71X0__DIV(JH7110_ISPCLK_VIN_SYS_CLK, "vin_sys_clk", 8, JH7110_ISPCLK_ISP_TOP_CORE),
>> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF0, "vin_pixel_clk_if0", CLK_IGNORE_UNUSED,
>> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
>> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF1, "vin_pixel_clk_if1", CLK_IGNORE_UNUSED,
>> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
>> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF2, "vin_pixel_clk_if2", CLK_IGNORE_UNUSED,
>> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
>> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF3, "vin_pixel_clk_if3", CLK_IGNORE_UNUSED,
>> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
>> +       JH71X0__MUX(JH7110_ISPCLK_VIN_CLK_P_AXIWR, "vin_clk_p_axiwr", 2,
>> +                   JH7110_ISPCLK_MIPI_RX0_PXL,
>> +                   JH7110_ISPCLK_DVP_INV),
>> +       /* ispv2_top_wrapper */
>> +       JH71X0_GMUX(JH7110_ISPCLK_ISPV2_TOP_WRAPPER_CLK_C, "ispv2_top_wrapper_clk_c",
>> +                   CLK_IGNORE_UNUSED, 2,
>> +                   JH7110_ISPCLK_MIPI_RX0_PXL,
>> +                   JH7110_ISPCLK_DVP_INV),
>> +};
> 
> Are all the clocks marked CLK_IGNORE_UNUSED here critical or are they
> just marked like so because the corresponding drivers don't yet claim
> the clocks they need? Please mark the clocks that can never be turned
> off CLK_IS_CRITICAL and remove the flag from the rest of the clocks.

Thanks, I will test it carefully and modify it.

> 
>> +struct isp_top_crg {
>> +       struct clk_bulk_data *top_clks;
>> +       struct reset_control *top_rsts;
>> +       int top_clks_num;
>> +       void __iomem *base;
>> +};
>> +
>> +static struct clk_bulk_data jh7110_isp_top_clks[] = {
>> +       { .id = "isp_top_core" },
>> +       { .id = "isp_top_axi" }
>> +};
>> +
>> +static struct isp_top_crg *top_crg_from(void __iomem **base)
>> +{
>> +       return container_of(base, struct isp_top_crg, base);
>> +}
>> +
>> +static int jh7110_isp_top_crg_get(struct jh71x0_clk_priv *priv, struct isp_top_crg *top)
>> +{
>> +       int ret;
>> +
>> +       top->top_clks = jh7110_isp_top_clks;
>> +       top->top_clks_num = ARRAY_SIZE(jh7110_isp_top_clks);
>> +       ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
>> +       if (ret) {
>> +               dev_err(priv->dev, "top clks get failed: %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       /* The resets should be shared and other ISP modules will use its. */
>> +       top->top_rsts = devm_reset_control_array_get_shared(priv->dev);
>> +       if (IS_ERR(top->top_rsts)) {
>> +               dev_err(priv->dev, "top rsts get failed\n");
>> +               return PTR_ERR(top->top_rsts);
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int jh7110_isp_top_crg_enable(struct isp_top_crg *top)
>> +{
>> +       int ret;
>> +
>> +       ret = clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
>> +       if (ret)
>> +               return ret;
>> +
>> +       return reset_control_deassert(top->top_rsts);
>> +}
>> +
>> +static void jh7110_isp_top_crg_disable(struct isp_top_crg *top)
>> +{
>> +       clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
>> +}
>> +
>> +static struct clk_hw *jh7110_ispclk_get(struct of_phandle_args *clkspec, void *data)
>> +{
>> +       struct jh71x0_clk_priv *priv = data;
>> +       unsigned int idx = clkspec->args[0];
>> +
>> +       if (idx < JH7110_ISPCLK_END)
>> +               return &priv->reg[idx].hw;
>> +
>> +       return ERR_PTR(-EINVAL);
>> +}
>> +
>> +static int jh7110_ispcrg_probe(struct platform_device *pdev)
>> +{
>> +       struct jh71x0_clk_priv *priv;
>> +       struct isp_top_crg *top;
>> +       unsigned int idx;
>> +       int ret;
>> +
>> +       priv = devm_kzalloc(&pdev->dev,
>> +                           struct_size(priv, reg, JH7110_ISPCLK_END),
>> +                           GFP_KERNEL);
>> +       if (!priv)
>> +               return -ENOMEM;
>> +
>> +       top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
>> +       if (!top)
>> +               return -ENOMEM;
>> +
>> +       spin_lock_init(&priv->rmw_lock);
>> +       priv->dev = &pdev->dev;
>> +       priv->base = devm_platform_ioremap_resource(pdev, 0);
>> +       if (IS_ERR(priv->base))
>> +               return PTR_ERR(priv->base);
>> +
>> +       top->base = priv->base;
>> +       dev_set_drvdata(priv->dev, (void *)(&top->base));
>> +
>> +       pm_runtime_enable(priv->dev);
>> +       ret = pm_runtime_get_sync(priv->dev);
>> +       if (ret < 0) {
>> +               dev_err(priv->dev, "failed to turn on power: %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       ret = jh7110_isp_top_crg_get(priv, top);
>> +       if (ret)
>> +               goto err_clk;
>> +
>> +       ret = jh7110_isp_top_crg_enable(top);
>> +       if (ret)
>> +               goto err_clk;
>> +
>> +       for (idx = 0; idx < JH7110_ISPCLK_END; idx++) {
>> +               u32 max = jh7110_ispclk_data[idx].max;
>> +               struct clk_parent_data parents[4] = {};
>> +               struct clk_init_data init = {
>> +                       .name = jh7110_ispclk_data[idx].name,
>> +                       .ops = starfive_jh71x0_clk_ops(max),
>> +                       .parent_data = parents,
>> +                       .num_parents =
>> +                               ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
>> +                       .flags = jh7110_ispclk_data[idx].flags,
>> +               };
>> +               struct jh71x0_clk *clk = &priv->reg[idx];
>> +               unsigned int i;
>> +               char *fw_name[JH7110_ISPCLK_EXT_END - JH7110_ISPCLK_END] = {
>> +                       "isp_top_core",
>> +                       "isp_top_axi",
>> +                       "noc_bus_isp_axi",
>> +                       "dvp_clk"
>> +               };
>> +
>> +               for (i = 0; i < init.num_parents; i++) {
>> +                       unsigned int pidx = jh7110_ispclk_data[idx].parents[i];
>> +
>> +                       if (pidx < JH7110_ISPCLK_END)
>> +                               parents[i].hw = &priv->reg[pidx].hw;
>> +                       else
>> +                               parents[i].fw_name = fw_name[pidx - JH7110_ISPCLK_END];
>> +               }
>> +
>> +               clk->hw.init = &init;
>> +               clk->idx = idx;
>> +               clk->max_div = max & JH71X0_CLK_DIV_MASK;
>> +
>> +               ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
>> +               if (ret)
>> +                       goto err_exit;
>> +       }
>> +
>> +       ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_ispclk_get, priv);
>> +       if (ret)
>> +               goto err_exit;
>> +
>> +       ret = jh7110_reset_controller_register(priv, "reset-isp", 3);
>> +       if (ret)
>> +               goto err_exit;
>> +
>> +       return 0;
>> +
>> +err_exit:
>> +       jh7110_isp_top_crg_disable(top);
>> +err_clk:
>> +       pm_runtime_put_sync(priv->dev);
>> +       pm_runtime_disable(priv->dev);
>> +       return ret;
>> +}
>> +
>> +static int jh7110_ispcrg_remove(struct platform_device *pdev)
>> +{
>> +       void __iomem **base = dev_get_drvdata(&pdev->dev);
>> +       struct isp_top_crg *top = top_crg_from(base);
>> +
>> +       jh7110_isp_top_crg_disable(top);
>> +       pm_runtime_disable(&pdev->dev);
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct of_device_id jh7110_ispcrg_match[] = {
>> +       { .compatible = "starfive,jh7110-ispcrg" },
>> +       { /* sentinel */ }
>> +};
>> +MODULE_DEVICE_TABLE(of, jh7110_ispcrg_match);
>> +
>> +static struct platform_driver jh7110_ispcrg_driver = {
>> +       .probe = jh7110_ispcrg_probe,
>> +       .remove = jh7110_ispcrg_remove,
>> +       .driver = {
>> +               .name = "clk-starfive-jh7110-isp",
>> +               .of_match_table = jh7110_ispcrg_match,
>> +       },
>> +};
>> +module_platform_driver(jh7110_ispcrg_driver);
>> +
>> +MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
>> +MODULE_DESCRIPTION("StarFive JH7110 Image-Signal-Process clock driver");
>> +MODULE_LICENSE("GPL");
>> --
>> 2.25.1
>>
>>
>> _______________________________________________
>> linux-riscv mailing list
>> linux-riscv@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-riscv

Best regards,
Xingyu Wu

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 06/11] clk: starfive: Add StarFive JH7110 Image-Signal-Process clock driver
  2023-03-03  3:59     ` Xingyu Wu
@ 2023-03-03  9:01       ` Emil Renner Berthing
  2023-03-03  9:14         ` Xingyu Wu
  0 siblings, 1 reply; 33+ messages in thread
From: Emil Renner Berthing @ 2023-03-03  9:01 UTC (permalink / raw)
  To: Xingyu Wu
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On Fri, 3 Mar 2023 at 04:59, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
> On 2023/3/2 23:39, Emil Renner Berthing wrote:
> > On Tue, 21 Feb 2023 at 09:36, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
> >>
> >> Add driver for the StarFive JH7110 Image-Signal-Process clock controller.
> >>
> >> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
> >> ---
> >>  drivers/clk/starfive/Kconfig                  |  11 +
> >>  drivers/clk/starfive/Makefile                 |   1 +
> >>  .../clk/starfive/clk-starfive-jh7110-isp.c    | 254 ++++++++++++++++++
> >>  3 files changed, 266 insertions(+)
> >>  create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-isp.c
> >>
> >> diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
> >> index a462b6e53543..59499acb95f7 100644
> >> --- a/drivers/clk/starfive/Kconfig
> >> +++ b/drivers/clk/starfive/Kconfig
> >> @@ -53,3 +53,14 @@ config CLK_STARFIVE_JH7110_STG
> >>         help
> >>           Say yes here to support the System-Top-Group clock controller
> >>           on the StarFive JH7110 SoC.
> >> +
> >> +config CLK_STARFIVE_JH7110_ISP
> >> +       tristate "StarFive JH7110 Image-Signal-Process clock support"
> >> +       depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
> >> +       select AUXILIARY_BUS
> >> +       select CLK_STARFIVE_JH71X0
> >> +       select RESET_STARFIVE_JH7110
> >> +       default CLK_STARFIVE_JH7110_SYS
> >
> > default m if ARCH_STARFIVE
>
> Oh, the ISPCRG and VOUTCRG depend on SYSCRG because it need to enable core clock.
> So I should modify that:
>
> default m if CLK_STARFIVE_JH7110_SYS
>
> It that OK?

No, this symbol already has a "depends on CLK_STARFIVE_JH7110_SYS &&
JH71XX_PMU", so just do like the other drivers and default m if
ARCH_STARFIVE.

Btw. I don't see anything in the code depending on the PMU driver. Am
I just missing something could that dependency be removed?

> >
> >> +       help
> >> +         Say yes here to support the Image-Signal-Process clock controller
> >> +         on the StarFive JH7110 SoC.
> >> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
> >> index b81e97ee2659..76fb9f8d628b 100644
> >> --- a/drivers/clk/starfive/Makefile
> >> +++ b/drivers/clk/starfive/Makefile
> >> @@ -7,3 +7,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS)  += clk-starfive-jh7110-sys.o
> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_AON)  += clk-starfive-jh7110-aon.o
> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)  += clk-starfive-jh7110-stg.o
> >> +obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP)  += clk-starfive-jh7110-isp.o
> >> diff --git a/drivers/clk/starfive/clk-starfive-jh7110-isp.c b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
> >> new file mode 100644
> >> index 000000000000..b5bce1ac22e0
> >> --- /dev/null
> >> +++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
> >> @@ -0,0 +1,254 @@
> >> +// SPDX-License-Identifier: GPL-2.0
> >> +/*
> >> + * StarFive JH7110 Image-Signal-Process Clock Driver
> >> + *
> >> + * Copyright (C) 2022 StarFive Technology Co., Ltd.
> >> + */
> >> +
> >> +#include <linux/clk.h>
> >> +#include <linux/clk-provider.h>
> >> +#include <linux/io.h>
> >> +#include <linux/of.h>
> >> +#include <linux/platform_device.h>
> >> +#include <linux/pm_runtime.h>
> >> +#include <linux/reset.h>
> >> +
> >> +#include <dt-bindings/clock/starfive,jh7110-crg.h>
> >> +
> >> +#include "clk-starfive-jh71x0.h"
> >> +
> >> +/* external clocks */
> >> +#define JH7110_ISPCLK_ISP_TOP_CORE             (JH7110_ISPCLK_END + 0)
> >> +#define JH7110_ISPCLK_ISP_TOP_AXI              (JH7110_ISPCLK_END + 1)
> >> +#define JH7110_ISPCLK_NOC_BUS_ISP_AXI          (JH7110_ISPCLK_END + 2)
> >> +#define JH7110_ISPCLK_DVP_CLK                  (JH7110_ISPCLK_END + 3)
> >> +#define JH7110_ISPCLK_EXT_END                  (JH7110_ISPCLK_END + 4)
> >> +
> >> +static const struct jh71x0_clk_data jh7110_ispclk_data[] = {
> >> +       /* syscon */
> >> +       JH71X0__DIV(JH7110_ISPCLK_DOM4_APB_FUNC, "dom4_apb_func", 15,
> >> +                   JH7110_ISPCLK_ISP_TOP_AXI),
> >> +       JH71X0__DIV(JH7110_ISPCLK_MIPI_RX0_PXL, "mipi_rx0_pxl", 8,
> >> +                   JH7110_ISPCLK_ISP_TOP_CORE),
> >> +       JH71X0__INV(JH7110_ISPCLK_DVP_INV, "dvp_inv", JH7110_ISPCLK_DVP_CLK),
> >> +       /* vin */
> >> +       JH71X0__DIV(JH7110_ISPCLK_M31DPHY_CFGCLK_IN, "m31dphy_cfgclk_in", 16,
> >> +                   JH7110_ISPCLK_ISP_TOP_CORE),
> >> +       JH71X0__DIV(JH7110_ISPCLK_M31DPHY_REFCLK_IN, "m31dphy_refclk_in", 16,
> >> +                   JH7110_ISPCLK_ISP_TOP_CORE),
> >> +       JH71X0__DIV(JH7110_ISPCLK_M31DPHY_TXCLKESC_LAN0, "m31dphy_txclkesc_lan0", 60,
> >> +                   JH7110_ISPCLK_ISP_TOP_CORE),
> >> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PCLK, "vin_pclk", CLK_IGNORE_UNUSED,
> >> +                   JH7110_ISPCLK_DOM4_APB_FUNC),
> >> +       JH71X0__DIV(JH7110_ISPCLK_VIN_SYS_CLK, "vin_sys_clk", 8, JH7110_ISPCLK_ISP_TOP_CORE),
> >> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF0, "vin_pixel_clk_if0", CLK_IGNORE_UNUSED,
> >> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
> >> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF1, "vin_pixel_clk_if1", CLK_IGNORE_UNUSED,
> >> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
> >> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF2, "vin_pixel_clk_if2", CLK_IGNORE_UNUSED,
> >> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
> >> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF3, "vin_pixel_clk_if3", CLK_IGNORE_UNUSED,
> >> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
> >> +       JH71X0__MUX(JH7110_ISPCLK_VIN_CLK_P_AXIWR, "vin_clk_p_axiwr", 2,
> >> +                   JH7110_ISPCLK_MIPI_RX0_PXL,
> >> +                   JH7110_ISPCLK_DVP_INV),
> >> +       /* ispv2_top_wrapper */
> >> +       JH71X0_GMUX(JH7110_ISPCLK_ISPV2_TOP_WRAPPER_CLK_C, "ispv2_top_wrapper_clk_c",
> >> +                   CLK_IGNORE_UNUSED, 2,
> >> +                   JH7110_ISPCLK_MIPI_RX0_PXL,
> >> +                   JH7110_ISPCLK_DVP_INV),
> >> +};
> >
> > Are all the clocks marked CLK_IGNORE_UNUSED here critical or are they
> > just marked like so because the corresponding drivers don't yet claim
> > the clocks they need? Please mark the clocks that can never be turned
> > off CLK_IS_CRITICAL and remove the flag from the rest of the clocks.
>
> Thanks, I will test it carefully and modify it.
>
> >
> >> +struct isp_top_crg {
> >> +       struct clk_bulk_data *top_clks;
> >> +       struct reset_control *top_rsts;
> >> +       int top_clks_num;
> >> +       void __iomem *base;
> >> +};
> >> +
> >> +static struct clk_bulk_data jh7110_isp_top_clks[] = {
> >> +       { .id = "isp_top_core" },
> >> +       { .id = "isp_top_axi" }
> >> +};
> >> +
> >> +static struct isp_top_crg *top_crg_from(void __iomem **base)
> >> +{
> >> +       return container_of(base, struct isp_top_crg, base);
> >> +}
> >> +
> >> +static int jh7110_isp_top_crg_get(struct jh71x0_clk_priv *priv, struct isp_top_crg *top)
> >> +{
> >> +       int ret;
> >> +
> >> +       top->top_clks = jh7110_isp_top_clks;
> >> +       top->top_clks_num = ARRAY_SIZE(jh7110_isp_top_clks);
> >> +       ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
> >> +       if (ret) {
> >> +               dev_err(priv->dev, "top clks get failed: %d\n", ret);
> >> +               return ret;
> >> +       }
> >> +
> >> +       /* The resets should be shared and other ISP modules will use its. */
> >> +       top->top_rsts = devm_reset_control_array_get_shared(priv->dev);
> >> +       if (IS_ERR(top->top_rsts)) {
> >> +               dev_err(priv->dev, "top rsts get failed\n");
> >> +               return PTR_ERR(top->top_rsts);
> >> +       }
> >> +
> >> +       return 0;
> >> +}
> >> +
> >> +static int jh7110_isp_top_crg_enable(struct isp_top_crg *top)
> >> +{
> >> +       int ret;
> >> +
> >> +       ret = clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
> >> +       if (ret)
> >> +               return ret;
> >> +
> >> +       return reset_control_deassert(top->top_rsts);
> >> +}
> >> +
> >> +static void jh7110_isp_top_crg_disable(struct isp_top_crg *top)
> >> +{
> >> +       clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
> >> +}
> >> +
> >> +static struct clk_hw *jh7110_ispclk_get(struct of_phandle_args *clkspec, void *data)
> >> +{
> >> +       struct jh71x0_clk_priv *priv = data;
> >> +       unsigned int idx = clkspec->args[0];
> >> +
> >> +       if (idx < JH7110_ISPCLK_END)
> >> +               return &priv->reg[idx].hw;
> >> +
> >> +       return ERR_PTR(-EINVAL);
> >> +}
> >> +
> >> +static int jh7110_ispcrg_probe(struct platform_device *pdev)
> >> +{
> >> +       struct jh71x0_clk_priv *priv;
> >> +       struct isp_top_crg *top;
> >> +       unsigned int idx;
> >> +       int ret;
> >> +
> >> +       priv = devm_kzalloc(&pdev->dev,
> >> +                           struct_size(priv, reg, JH7110_ISPCLK_END),
> >> +                           GFP_KERNEL);
> >> +       if (!priv)
> >> +               return -ENOMEM;
> >> +
> >> +       top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
> >> +       if (!top)
> >> +               return -ENOMEM;
> >> +
> >> +       spin_lock_init(&priv->rmw_lock);
> >> +       priv->dev = &pdev->dev;
> >> +       priv->base = devm_platform_ioremap_resource(pdev, 0);
> >> +       if (IS_ERR(priv->base))
> >> +               return PTR_ERR(priv->base);
> >> +
> >> +       top->base = priv->base;
> >> +       dev_set_drvdata(priv->dev, (void *)(&top->base));
> >> +
> >> +       pm_runtime_enable(priv->dev);
> >> +       ret = pm_runtime_get_sync(priv->dev);
> >> +       if (ret < 0) {
> >> +               dev_err(priv->dev, "failed to turn on power: %d\n", ret);
> >> +               return ret;
> >> +       }
> >> +
> >> +       ret = jh7110_isp_top_crg_get(priv, top);
> >> +       if (ret)
> >> +               goto err_clk;
> >> +
> >> +       ret = jh7110_isp_top_crg_enable(top);
> >> +       if (ret)
> >> +               goto err_clk;
> >> +
> >> +       for (idx = 0; idx < JH7110_ISPCLK_END; idx++) {
> >> +               u32 max = jh7110_ispclk_data[idx].max;
> >> +               struct clk_parent_data parents[4] = {};
> >> +               struct clk_init_data init = {
> >> +                       .name = jh7110_ispclk_data[idx].name,
> >> +                       .ops = starfive_jh71x0_clk_ops(max),
> >> +                       .parent_data = parents,
> >> +                       .num_parents =
> >> +                               ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
> >> +                       .flags = jh7110_ispclk_data[idx].flags,
> >> +               };
> >> +               struct jh71x0_clk *clk = &priv->reg[idx];
> >> +               unsigned int i;
> >> +               char *fw_name[JH7110_ISPCLK_EXT_END - JH7110_ISPCLK_END] = {
> >> +                       "isp_top_core",
> >> +                       "isp_top_axi",
> >> +                       "noc_bus_isp_axi",
> >> +                       "dvp_clk"
> >> +               };
> >> +
> >> +               for (i = 0; i < init.num_parents; i++) {
> >> +                       unsigned int pidx = jh7110_ispclk_data[idx].parents[i];
> >> +
> >> +                       if (pidx < JH7110_ISPCLK_END)
> >> +                               parents[i].hw = &priv->reg[pidx].hw;
> >> +                       else
> >> +                               parents[i].fw_name = fw_name[pidx - JH7110_ISPCLK_END];
> >> +               }
> >> +
> >> +               clk->hw.init = &init;
> >> +               clk->idx = idx;
> >> +               clk->max_div = max & JH71X0_CLK_DIV_MASK;
> >> +
> >> +               ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
> >> +               if (ret)
> >> +                       goto err_exit;
> >> +       }
> >> +
> >> +       ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_ispclk_get, priv);
> >> +       if (ret)
> >> +               goto err_exit;
> >> +
> >> +       ret = jh7110_reset_controller_register(priv, "reset-isp", 3);
> >> +       if (ret)
> >> +               goto err_exit;
> >> +
> >> +       return 0;
> >> +
> >> +err_exit:
> >> +       jh7110_isp_top_crg_disable(top);
> >> +err_clk:
> >> +       pm_runtime_put_sync(priv->dev);
> >> +       pm_runtime_disable(priv->dev);
> >> +       return ret;
> >> +}
> >> +
> >> +static int jh7110_ispcrg_remove(struct platform_device *pdev)
> >> +{
> >> +       void __iomem **base = dev_get_drvdata(&pdev->dev);
> >> +       struct isp_top_crg *top = top_crg_from(base);
> >> +
> >> +       jh7110_isp_top_crg_disable(top);
> >> +       pm_runtime_disable(&pdev->dev);
> >> +
> >> +       return 0;
> >> +}
> >> +
> >> +static const struct of_device_id jh7110_ispcrg_match[] = {
> >> +       { .compatible = "starfive,jh7110-ispcrg" },
> >> +       { /* sentinel */ }
> >> +};
> >> +MODULE_DEVICE_TABLE(of, jh7110_ispcrg_match);
> >> +
> >> +static struct platform_driver jh7110_ispcrg_driver = {
> >> +       .probe = jh7110_ispcrg_probe,
> >> +       .remove = jh7110_ispcrg_remove,
> >> +       .driver = {
> >> +               .name = "clk-starfive-jh7110-isp",
> >> +               .of_match_table = jh7110_ispcrg_match,
> >> +       },
> >> +};
> >> +module_platform_driver(jh7110_ispcrg_driver);
> >> +
> >> +MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
> >> +MODULE_DESCRIPTION("StarFive JH7110 Image-Signal-Process clock driver");
> >> +MODULE_LICENSE("GPL");
> >> --
> >> 2.25.1
> >>
> >>
> >> _______________________________________________
> >> linux-riscv mailing list
> >> linux-riscv@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/linux-riscv
>
> Best regards,
> Xingyu Wu

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 06/11] clk: starfive: Add StarFive JH7110 Image-Signal-Process clock driver
  2023-03-03  9:01       ` Emil Renner Berthing
@ 2023-03-03  9:14         ` Xingyu Wu
  0 siblings, 0 replies; 33+ messages in thread
From: Xingyu Wu @ 2023-03-03  9:14 UTC (permalink / raw)
  To: Emil Renner Berthing
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On 2023/3/3 17:01, Emil Renner Berthing wrote:
> On Fri, 3 Mar 2023 at 04:59, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
>> On 2023/3/2 23:39, Emil Renner Berthing wrote:
>> > On Tue, 21 Feb 2023 at 09:36, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
>> >>
>> >> Add driver for the StarFive JH7110 Image-Signal-Process clock controller.
>> >>
>> >> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
>> >> ---
>> >>  drivers/clk/starfive/Kconfig                  |  11 +
>> >>  drivers/clk/starfive/Makefile                 |   1 +
>> >>  .../clk/starfive/clk-starfive-jh7110-isp.c    | 254 ++++++++++++++++++
>> >>  3 files changed, 266 insertions(+)
>> >>  create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-isp.c
>> >>
>> >> diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
>> >> index a462b6e53543..59499acb95f7 100644
>> >> --- a/drivers/clk/starfive/Kconfig
>> >> +++ b/drivers/clk/starfive/Kconfig
>> >> @@ -53,3 +53,14 @@ config CLK_STARFIVE_JH7110_STG
>> >>         help
>> >>           Say yes here to support the System-Top-Group clock controller
>> >>           on the StarFive JH7110 SoC.
>> >> +
>> >> +config CLK_STARFIVE_JH7110_ISP
>> >> +       tristate "StarFive JH7110 Image-Signal-Process clock support"
>> >> +       depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
>> >> +       select AUXILIARY_BUS
>> >> +       select CLK_STARFIVE_JH71X0
>> >> +       select RESET_STARFIVE_JH7110
>> >> +       default CLK_STARFIVE_JH7110_SYS
>> >
>> > default m if ARCH_STARFIVE
>>
>> Oh, the ISPCRG and VOUTCRG depend on SYSCRG because it need to enable core clock.
>> So I should modify that:
>>
>> default m if CLK_STARFIVE_JH7110_SYS
>>
>> It that OK?
> 
> No, this symbol already has a "depends on CLK_STARFIVE_JH7110_SYS &&
> JH71XX_PMU", so just do like the other drivers and default m if
> ARCH_STARFIVE.

OK, I will modify it.

> 
> Btw. I don't see anything in the code depending on the PMU driver. Am
> I just missing something could that dependency be removed?

This dependency is represented in the JH7110 device tree file and use
'power-domains' node. The VOUTCRG and ISPCRG also need to turn on power
before reading and writing registers. Uses 'pm_runtime_enable' and PMU
would help me turn on their power.

> 
>> >
>> >> +       help
>> >> +         Say yes here to support the Image-Signal-Process clock controller
>> >> +         on the StarFive JH7110 SoC.
>> >> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
>> >> index b81e97ee2659..76fb9f8d628b 100644
>> >> --- a/drivers/clk/starfive/Makefile
>> >> +++ b/drivers/clk/starfive/Makefile
>> >> @@ -7,3 +7,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
>> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS)  += clk-starfive-jh7110-sys.o
>> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_AON)  += clk-starfive-jh7110-aon.o
>> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)  += clk-starfive-jh7110-stg.o
>> >> +obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP)  += clk-starfive-jh7110-isp.o
>> >> diff --git a/drivers/clk/starfive/clk-starfive-jh7110-isp.c b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
>> >> new file mode 100644
>> >> index 000000000000..b5bce1ac22e0
>> >> --- /dev/null
>> >> +++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
>> >> @@ -0,0 +1,254 @@
>> >> +// SPDX-License-Identifier: GPL-2.0
>> >> +/*
>> >> + * StarFive JH7110 Image-Signal-Process Clock Driver
>> >> + *
>> >> + * Copyright (C) 2022 StarFive Technology Co., Ltd.
>> >> + */
>> >> +
>> >> +#include <linux/clk.h>
>> >> +#include <linux/clk-provider.h>
>> >> +#include <linux/io.h>
>> >> +#include <linux/of.h>
>> >> +#include <linux/platform_device.h>
>> >> +#include <linux/pm_runtime.h>
>> >> +#include <linux/reset.h>
>> >> +
>> >> +#include <dt-bindings/clock/starfive,jh7110-crg.h>
>> >> +
>> >> +#include "clk-starfive-jh71x0.h"
>> >> +
>> >> +/* external clocks */
>> >> +#define JH7110_ISPCLK_ISP_TOP_CORE             (JH7110_ISPCLK_END + 0)
>> >> +#define JH7110_ISPCLK_ISP_TOP_AXI              (JH7110_ISPCLK_END + 1)
>> >> +#define JH7110_ISPCLK_NOC_BUS_ISP_AXI          (JH7110_ISPCLK_END + 2)
>> >> +#define JH7110_ISPCLK_DVP_CLK                  (JH7110_ISPCLK_END + 3)
>> >> +#define JH7110_ISPCLK_EXT_END                  (JH7110_ISPCLK_END + 4)
>> >> +
>> >> +static const struct jh71x0_clk_data jh7110_ispclk_data[] = {
>> >> +       /* syscon */
>> >> +       JH71X0__DIV(JH7110_ISPCLK_DOM4_APB_FUNC, "dom4_apb_func", 15,
>> >> +                   JH7110_ISPCLK_ISP_TOP_AXI),
>> >> +       JH71X0__DIV(JH7110_ISPCLK_MIPI_RX0_PXL, "mipi_rx0_pxl", 8,
>> >> +                   JH7110_ISPCLK_ISP_TOP_CORE),
>> >> +       JH71X0__INV(JH7110_ISPCLK_DVP_INV, "dvp_inv", JH7110_ISPCLK_DVP_CLK),
>> >> +       /* vin */
>> >> +       JH71X0__DIV(JH7110_ISPCLK_M31DPHY_CFGCLK_IN, "m31dphy_cfgclk_in", 16,
>> >> +                   JH7110_ISPCLK_ISP_TOP_CORE),
>> >> +       JH71X0__DIV(JH7110_ISPCLK_M31DPHY_REFCLK_IN, "m31dphy_refclk_in", 16,
>> >> +                   JH7110_ISPCLK_ISP_TOP_CORE),
>> >> +       JH71X0__DIV(JH7110_ISPCLK_M31DPHY_TXCLKESC_LAN0, "m31dphy_txclkesc_lan0", 60,
>> >> +                   JH7110_ISPCLK_ISP_TOP_CORE),
>> >> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PCLK, "vin_pclk", CLK_IGNORE_UNUSED,
>> >> +                   JH7110_ISPCLK_DOM4_APB_FUNC),
>> >> +       JH71X0__DIV(JH7110_ISPCLK_VIN_SYS_CLK, "vin_sys_clk", 8, JH7110_ISPCLK_ISP_TOP_CORE),
>> >> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF0, "vin_pixel_clk_if0", CLK_IGNORE_UNUSED,
>> >> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
>> >> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF1, "vin_pixel_clk_if1", CLK_IGNORE_UNUSED,
>> >> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
>> >> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF2, "vin_pixel_clk_if2", CLK_IGNORE_UNUSED,
>> >> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
>> >> +       JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_CLK_IF3, "vin_pixel_clk_if3", CLK_IGNORE_UNUSED,
>> >> +                   JH7110_ISPCLK_MIPI_RX0_PXL),
>> >> +       JH71X0__MUX(JH7110_ISPCLK_VIN_CLK_P_AXIWR, "vin_clk_p_axiwr", 2,
>> >> +                   JH7110_ISPCLK_MIPI_RX0_PXL,
>> >> +                   JH7110_ISPCLK_DVP_INV),
>> >> +       /* ispv2_top_wrapper */
>> >> +       JH71X0_GMUX(JH7110_ISPCLK_ISPV2_TOP_WRAPPER_CLK_C, "ispv2_top_wrapper_clk_c",
>> >> +                   CLK_IGNORE_UNUSED, 2,
>> >> +                   JH7110_ISPCLK_MIPI_RX0_PXL,
>> >> +                   JH7110_ISPCLK_DVP_INV),
>> >> +};
>> >
>> > Are all the clocks marked CLK_IGNORE_UNUSED here critical or are they
>> > just marked like so because the corresponding drivers don't yet claim
>> > the clocks they need? Please mark the clocks that can never be turned
>> > off CLK_IS_CRITICAL and remove the flag from the rest of the clocks.
>>
>> Thanks, I will test it carefully and modify it.
>>
>> >
>> >> +struct isp_top_crg {
>> >> +       struct clk_bulk_data *top_clks;
>> >> +       struct reset_control *top_rsts;
>> >> +       int top_clks_num;
>> >> +       void __iomem *base;
>> >> +};
>> >> +
>> >> +static struct clk_bulk_data jh7110_isp_top_clks[] = {
>> >> +       { .id = "isp_top_core" },
>> >> +       { .id = "isp_top_axi" }
>> >> +};
>> >> +
>> >> +static struct isp_top_crg *top_crg_from(void __iomem **base)
>> >> +{
>> >> +       return container_of(base, struct isp_top_crg, base);
>> >> +}
>> >> +
>> >> +static int jh7110_isp_top_crg_get(struct jh71x0_clk_priv *priv, struct isp_top_crg *top)
>> >> +{
>> >> +       int ret;
>> >> +
>> >> +       top->top_clks = jh7110_isp_top_clks;
>> >> +       top->top_clks_num = ARRAY_SIZE(jh7110_isp_top_clks);
>> >> +       ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
>> >> +       if (ret) {
>> >> +               dev_err(priv->dev, "top clks get failed: %d\n", ret);
>> >> +               return ret;
>> >> +       }
>> >> +
>> >> +       /* The resets should be shared and other ISP modules will use its. */
>> >> +       top->top_rsts = devm_reset_control_array_get_shared(priv->dev);
>> >> +       if (IS_ERR(top->top_rsts)) {
>> >> +               dev_err(priv->dev, "top rsts get failed\n");
>> >> +               return PTR_ERR(top->top_rsts);
>> >> +       }
>> >> +
>> >> +       return 0;
>> >> +}
>> >> +
>> >> +static int jh7110_isp_top_crg_enable(struct isp_top_crg *top)
>> >> +{
>> >> +       int ret;
>> >> +
>> >> +       ret = clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
>> >> +       if (ret)
>> >> +               return ret;
>> >> +
>> >> +       return reset_control_deassert(top->top_rsts);
>> >> +}
>> >> +
>> >> +static void jh7110_isp_top_crg_disable(struct isp_top_crg *top)
>> >> +{
>> >> +       clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
>> >> +}
>> >> +
>> >> +static struct clk_hw *jh7110_ispclk_get(struct of_phandle_args *clkspec, void *data)
>> >> +{
>> >> +       struct jh71x0_clk_priv *priv = data;
>> >> +       unsigned int idx = clkspec->args[0];
>> >> +
>> >> +       if (idx < JH7110_ISPCLK_END)
>> >> +               return &priv->reg[idx].hw;
>> >> +
>> >> +       return ERR_PTR(-EINVAL);
>> >> +}
>> >> +
>> >> +static int jh7110_ispcrg_probe(struct platform_device *pdev)
>> >> +{
>> >> +       struct jh71x0_clk_priv *priv;
>> >> +       struct isp_top_crg *top;
>> >> +       unsigned int idx;
>> >> +       int ret;
>> >> +
>> >> +       priv = devm_kzalloc(&pdev->dev,
>> >> +                           struct_size(priv, reg, JH7110_ISPCLK_END),
>> >> +                           GFP_KERNEL);
>> >> +       if (!priv)
>> >> +               return -ENOMEM;
>> >> +
>> >> +       top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
>> >> +       if (!top)
>> >> +               return -ENOMEM;
>> >> +
>> >> +       spin_lock_init(&priv->rmw_lock);
>> >> +       priv->dev = &pdev->dev;
>> >> +       priv->base = devm_platform_ioremap_resource(pdev, 0);
>> >> +       if (IS_ERR(priv->base))
>> >> +               return PTR_ERR(priv->base);
>> >> +
>> >> +       top->base = priv->base;
>> >> +       dev_set_drvdata(priv->dev, (void *)(&top->base));
>> >> +
>> >> +       pm_runtime_enable(priv->dev);
>> >> +       ret = pm_runtime_get_sync(priv->dev);
>> >> +       if (ret < 0) {
>> >> +               dev_err(priv->dev, "failed to turn on power: %d\n", ret);
>> >> +               return ret;
>> >> +       }
>> >> +
>> >> +       ret = jh7110_isp_top_crg_get(priv, top);
>> >> +       if (ret)
>> >> +               goto err_clk;
>> >> +
>> >> +       ret = jh7110_isp_top_crg_enable(top);
>> >> +       if (ret)
>> >> +               goto err_clk;
>> >> +
>> >> +       for (idx = 0; idx < JH7110_ISPCLK_END; idx++) {
>> >> +               u32 max = jh7110_ispclk_data[idx].max;
>> >> +               struct clk_parent_data parents[4] = {};
>> >> +               struct clk_init_data init = {
>> >> +                       .name = jh7110_ispclk_data[idx].name,
>> >> +                       .ops = starfive_jh71x0_clk_ops(max),
>> >> +                       .parent_data = parents,
>> >> +                       .num_parents =
>> >> +                               ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
>> >> +                       .flags = jh7110_ispclk_data[idx].flags,
>> >> +               };
>> >> +               struct jh71x0_clk *clk = &priv->reg[idx];
>> >> +               unsigned int i;
>> >> +               char *fw_name[JH7110_ISPCLK_EXT_END - JH7110_ISPCLK_END] = {
>> >> +                       "isp_top_core",
>> >> +                       "isp_top_axi",
>> >> +                       "noc_bus_isp_axi",
>> >> +                       "dvp_clk"
>> >> +               };
>> >> +
>> >> +               for (i = 0; i < init.num_parents; i++) {
>> >> +                       unsigned int pidx = jh7110_ispclk_data[idx].parents[i];
>> >> +
>> >> +                       if (pidx < JH7110_ISPCLK_END)
>> >> +                               parents[i].hw = &priv->reg[pidx].hw;
>> >> +                       else
>> >> +                               parents[i].fw_name = fw_name[pidx - JH7110_ISPCLK_END];
>> >> +               }
>> >> +
>> >> +               clk->hw.init = &init;
>> >> +               clk->idx = idx;
>> >> +               clk->max_div = max & JH71X0_CLK_DIV_MASK;
>> >> +
>> >> +               ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
>> >> +               if (ret)
>> >> +                       goto err_exit;
>> >> +       }
>> >> +
>> >> +       ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_ispclk_get, priv);
>> >> +       if (ret)
>> >> +               goto err_exit;
>> >> +
>> >> +       ret = jh7110_reset_controller_register(priv, "reset-isp", 3);
>> >> +       if (ret)
>> >> +               goto err_exit;
>> >> +
>> >> +       return 0;
>> >> +
>> >> +err_exit:
>> >> +       jh7110_isp_top_crg_disable(top);
>> >> +err_clk:
>> >> +       pm_runtime_put_sync(priv->dev);
>> >> +       pm_runtime_disable(priv->dev);
>> >> +       return ret;
>> >> +}
>> >> +
>> >> +static int jh7110_ispcrg_remove(struct platform_device *pdev)
>> >> +{
>> >> +       void __iomem **base = dev_get_drvdata(&pdev->dev);
>> >> +       struct isp_top_crg *top = top_crg_from(base);
>> >> +
>> >> +       jh7110_isp_top_crg_disable(top);
>> >> +       pm_runtime_disable(&pdev->dev);
>> >> +
>> >> +       return 0;
>> >> +}
>> >> +
>> >> +static const struct of_device_id jh7110_ispcrg_match[] = {
>> >> +       { .compatible = "starfive,jh7110-ispcrg" },
>> >> +       { /* sentinel */ }
>> >> +};
>> >> +MODULE_DEVICE_TABLE(of, jh7110_ispcrg_match);
>> >> +
>> >> +static struct platform_driver jh7110_ispcrg_driver = {
>> >> +       .probe = jh7110_ispcrg_probe,
>> >> +       .remove = jh7110_ispcrg_remove,
>> >> +       .driver = {
>> >> +               .name = "clk-starfive-jh7110-isp",
>> >> +               .of_match_table = jh7110_ispcrg_match,
>> >> +       },
>> >> +};
>> >> +module_platform_driver(jh7110_ispcrg_driver);
>> >> +
>> >> +MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
>> >> +MODULE_DESCRIPTION("StarFive JH7110 Image-Signal-Process clock driver");
>> >> +MODULE_LICENSE("GPL");
>> >> --
>> >> 2.25.1
>> >>
>> >>
>> >> _______________________________________________
>> >> linux-riscv mailing list
>> >> linux-riscv@lists.infradead.org
>> >> http://lists.infradead.org/mailman/listinfo/linux-riscv
>>
>> Best regards,
>> Xingyu Wu


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 09/11] clk: starfive: Add StarFive JH7110 Video-Output clock driver
  2023-03-03  3:37     ` Xingyu Wu
@ 2023-03-03  9:23       ` Emil Renner Berthing
  2023-03-03  9:44         ` Xingyu Wu
  0 siblings, 1 reply; 33+ messages in thread
From: Emil Renner Berthing @ 2023-03-03  9:23 UTC (permalink / raw)
  To: Xingyu Wu
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On Fri, 3 Mar 2023 at 04:37, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
>
> On 2023/3/2 23:48, Emil Renner Berthing wrote:
> > On Tue, 21 Feb 2023 at 09:40, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
> >>
> >> Add driver for the StarFive JH7110 Video-Output clock controller.
> >>
> >> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
> >> ---
> >>  drivers/clk/starfive/Kconfig                  |  11 +
> >>  drivers/clk/starfive/Makefile                 |   1 +
> >>  .../clk/starfive/clk-starfive-jh7110-vout.c   | 261 ++++++++++++++++++
> >>  3 files changed, 273 insertions(+)
> >>  create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-vout.c
> >>
> >> diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
> >> index 59499acb95f7..5ebf1ed08627 100644
> >> --- a/drivers/clk/starfive/Kconfig
> >> +++ b/drivers/clk/starfive/Kconfig
> >> @@ -64,3 +64,14 @@ config CLK_STARFIVE_JH7110_ISP
> >>         help
> >>           Say yes here to support the Image-Signal-Process clock controller
> >>           on the StarFive JH7110 SoC.
> >> +
> >> +config CLK_STARFIVE_JH7110_VOUT
> >> +       tristate "StarFive JH7110 Video-Output clock support"
> >> +       depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
> >> +       select AUXILIARY_BUS
> >> +       select CLK_STARFIVE_JH71X0
> >> +       select RESET_STARFIVE_JH7110
> >> +       default CLK_STARFIVE_JH7110_SYS
> >
> > default m if ARCH_STARFIVE
>
> Will modify it.
>
> >
> >> +       help
> >> +         Say yes here to support the Video-Output clock controller
> >> +         on the StarFive JH7110 SoC.
> >> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
> >> index 76fb9f8d628b..841377e45bb6 100644
> >> --- a/drivers/clk/starfive/Makefile
> >> +++ b/drivers/clk/starfive/Makefile
> >> @@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS)   += clk-starfive-jh7110-sys.o
> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_AON)  += clk-starfive-jh7110-aon.o
> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)  += clk-starfive-jh7110-stg.o
> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP)  += clk-starfive-jh7110-isp.o
> >> +obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
> >> diff --git a/drivers/clk/starfive/clk-starfive-jh7110-vout.c b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
> >> new file mode 100644
> >> index 000000000000..d786537563a4
> >> --- /dev/null
> >> +++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
> >> @@ -0,0 +1,261 @@
> >> +// SPDX-License-Identifier: GPL-2.0
> >> +/*
> >> + * StarFive JH7110 Video-Output Clock Driver
> >> + *
> >> + * Copyright (C) 2022 StarFive Technology Co., Ltd.
> >> + */
> >> +
> >> +#include <linux/clk.h>
> >> +#include <linux/clk-provider.h>
> >> +#include <linux/io.h>
> >> +#include <linux/of.h>
> >> +#include <linux/platform_device.h>
> >> +#include <linux/pm_runtime.h>
> >> +#include <linux/reset.h>
> >> +
> >> +#include <dt-bindings/clock/starfive,jh7110-crg.h>
> >> +
> >> +#include "clk-starfive-jh71x0.h"
> >> +
> >> +/* external clocks */
> >> +#define JH7110_VOUTCLK_VOUT_SRC                        (JH7110_VOUTCLK_END + 0)
> >> +#define JH7110_VOUTCLK_VOUT_TOP_AHB            (JH7110_VOUTCLK_END + 1)
> >> +#define JH7110_VOUTCLK_VOUT_TOP_AXI            (JH7110_VOUTCLK_END + 2)
> >> +#define JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK   (JH7110_VOUTCLK_END + 3)
> >> +#define JH7110_VOUTCLK_I2STX0_BCLK             (JH7110_VOUTCLK_END + 4)
> >> +#define JH7110_VOUTCLK_HDMITX0_PIXELCLK                (JH7110_VOUTCLK_END + 5)
> >> +#define JH7110_VOUTCLK_EXT_END                 (JH7110_VOUTCLK_END + 6)
> >> +
> >> +static const struct jh71x0_clk_data jh7110_voutclk_data[] = {
> >> +       /* divider */
> >> +       JH71X0__DIV(JH7110_VOUTCLK_APB, "apb", 8, JH7110_VOUTCLK_VOUT_TOP_AHB),
> >> +       JH71X0__DIV(JH7110_VOUTCLK_DC8200_PIX, "dc8200_pix", 63, JH7110_VOUTCLK_VOUT_SRC),
> >> +       JH71X0__DIV(JH7110_VOUTCLK_DSI_SYS, "dsi_sys", 31, JH7110_VOUTCLK_VOUT_SRC),
> >> +       JH71X0__DIV(JH7110_VOUTCLK_TX_ESC, "tx_esc", 31, JH7110_VOUTCLK_VOUT_TOP_AHB),
> >> +       /* dc8200 */
> >> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_AXI, "dc8200_axi", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
> >> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_CORE, "dc8200_core", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
> >> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_AHB, "dc8200_ahb", 0, JH7110_VOUTCLK_VOUT_TOP_AHB),
> >> +       JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX0, "dc8200_pix0", 0, 2,
> >> +                   JH7110_VOUTCLK_DC8200_PIX,
> >> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
> >> +       JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX1, "dc8200_pix1", 0, 2,
> >> +                   JH7110_VOUTCLK_DC8200_PIX,
> >> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
> >> +       /* LCD */
> >> +       JH71X0_GMUX(JH7110_VOUTCLK_DOM_VOUT_TOP_LCD, "dom_vout_top_lcd", 0, 2,
> >> +                   JH7110_VOUTCLK_DC8200_PIX0,
> >> +                   JH7110_VOUTCLK_DC8200_PIX1),
> >> +       /* dsiTx */
> >> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_APB, "dsiTx_apb", 0, JH7110_VOUTCLK_DSI_SYS),
> >> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_SYS, "dsiTx_sys", 0, JH7110_VOUTCLK_DSI_SYS),
> >> +       JH71X0_GMUX(JH7110_VOUTCLK_DSITX_DPI, "dsiTx_dpi", 0, 2,
> >> +                   JH7110_VOUTCLK_DC8200_PIX,
> >> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
> >> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_TXESC, "dsiTx_txesc", 0, JH7110_VOUTCLK_TX_ESC),
> >> +       /* mipitx DPHY */
> >> +       JH71X0_GATE(JH7110_VOUTCLK_MIPITX_DPHY_TXESC, "mipitx_dphy_txesc", 0,
> >> +                   JH7110_VOUTCLK_TX_ESC),
> >> +       /* hdmi */
> >> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_MCLK, "hdmi_tx_mclk", 0,
> >> +                   JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK),
> >> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_BCLK, "hdmi_tx_bclk", 0,
> >> +                   JH7110_VOUTCLK_I2STX0_BCLK),
> >> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_SYS, "hdmi_tx_sys", 0, JH7110_VOUTCLK_APB),
> >> +};
> >> +
> >> +struct vout_top_crg {
> >> +       struct clk_bulk_data *top_clks;
> >> +       struct reset_control *top_rst;
> >> +       int top_clks_num;
> >> +       void __iomem *base;
> >> +};
> >> +
> >> +static struct clk_bulk_data jh7110_vout_top_clks[] = {
> >> +       { .id = "vout_src" },
> >> +       { .id = "vout_top_ahb" }
> >> +};
> >> +
> >> +static struct vout_top_crg *top_crg_from(void __iomem **base)
> >> +{
> >> +       return container_of(base, struct vout_top_crg, base);
> >> +}
> >> +
> >> +static int jh7110_vout_top_crg_get(struct jh71x0_clk_priv *priv, struct vout_top_crg *top)
> >> +{
> >> +       int ret;
> >> +
> >> +       top->top_clks = jh7110_vout_top_clks;
> >> +       top->top_clks_num = ARRAY_SIZE(jh7110_vout_top_clks);
> >> +       ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
> >> +       if (ret) {
> >> +               dev_err(priv->dev, "top clks get failed: %d\n", ret);
> >> +               return ret;
> >> +       }
> >> +
> >> +       /* The reset should be shared and other Vout modules will use its. */
> >> +       top->top_rst = devm_reset_control_get_shared(priv->dev, NULL);
> >> +       if (IS_ERR(top->top_rst)) {
> >> +               dev_err(priv->dev, "top rst get failed\n");
> >> +               return PTR_ERR(top->top_rst);
> >> +       }
> >> +
> >> +       return 0;
> >> +}
> >> +
> >> +static int jh7110_vout_top_crg_enable(struct vout_top_crg *top)
> >> +{
> >> +       int ret;
> >> +
> >> +       ret = clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
> >> +       if (ret)
> >> +               return ret;
> >
> > Hmm.. do all the clocks used as input really need to be enabled for
> > any one of the vout clocks to work?
> >
> > In other words: suppose you just need a single clock in the VOUTCRG
> > domain. Do we really need to turn on all the input clocks for the
> > VOUTCRG for that one clock to work? Normally I'd expect the clock
> > framework to make sure all parents of that clock are enabled.
>
> It must enable core clock and ahb clock before reading or writing VOUTCRG registers
> otherwise it would be failed to read and write. And it is even crash if it don't
> enable core clock before reading or writing ISPCRG registers.
> This serious problem was found when debugging earlier.

Ah sorry. I see now that you're only claiming the core and AHB bus.
That makes sense.

So now the question is if there are similar clocks that need to be
claimed by the AON, STG and ISP CRGs. They're most likely already
turned on by u-boot or by default which is why we don't see errors,
but Linux should still claim them if the driver needs them.

> >
> >> +
> >> +       return reset_control_deassert(top->top_rst);
> >> +}
> >> +
> >> +static void jh7110_vout_top_crg_disable(struct vout_top_crg *top)
> >> +{
> >> +       clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
> >> +}
> >> +
> >> +static struct clk_hw *jh7110_voutclk_get(struct of_phandle_args *clkspec, void *data)
> >> +{
> >> +       struct jh71x0_clk_priv *priv = data;
> >> +       unsigned int idx = clkspec->args[0];
> >> +
> >> +       if (idx < JH7110_VOUTCLK_END)
> >> +               return &priv->reg[idx].hw;
> >> +
> >> +       return ERR_PTR(-EINVAL);
> >> +}
> >> +
> >> +static int jh7110_voutcrg_probe(struct platform_device *pdev)
> >> +{
> >> +       struct jh71x0_clk_priv *priv;
> >> +       struct vout_top_crg *top;
> >> +       unsigned int idx;
> >> +       int ret;
> >> +
> >> +       priv = devm_kzalloc(&pdev->dev,
> >> +                           struct_size(priv, reg, JH7110_VOUTCLK_END),
> >> +                           GFP_KERNEL);
> >> +       if (!priv)
> >> +               return -ENOMEM;
> >> +
> >> +       top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
> >> +       if (!top)
> >> +               return -ENOMEM;
> >> +
> >> +       spin_lock_init(&priv->rmw_lock);
> >> +       priv->dev = &pdev->dev;
> >> +       priv->base = devm_platform_ioremap_resource(pdev, 0);
> >> +       if (IS_ERR(priv->base))
> >> +               return PTR_ERR(priv->base);
> >> +
> >> +       top->base = priv->base;
> >> +       dev_set_drvdata(priv->dev, (void *)(&top->base));
> >> +
> >> +       pm_runtime_enable(priv->dev);
> >> +       ret = pm_runtime_get_sync(priv->dev);
> >> +       if (ret < 0) {
> >> +               dev_err(priv->dev, "failed to turn power: %d\n", ret);
> >> +               return ret;
> >> +       }
> >> +
> >> +       ret = jh7110_vout_top_crg_get(priv, top);
> >> +       if (ret)
> >> +               goto err_clk;
> >> +
> >> +       ret = jh7110_vout_top_crg_enable(top);
> >> +       if (ret)
> >> +               goto err_clk;
> >> +
> >> +       for (idx = 0; idx < JH7110_VOUTCLK_END; idx++) {
> >> +               u32 max = jh7110_voutclk_data[idx].max;
> >> +               struct clk_parent_data parents[4] = {};
> >> +               struct clk_init_data init = {
> >> +                       .name = jh7110_voutclk_data[idx].name,
> >> +                       .ops = starfive_jh71x0_clk_ops(max),
> >> +                       .parent_data = parents,
> >> +                       .num_parents =
> >> +                               ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
> >> +                       .flags = jh7110_voutclk_data[idx].flags,
> >> +               };
> >> +               struct jh71x0_clk *clk = &priv->reg[idx];
> >> +               unsigned int i;
> >> +               char *fw_name[JH7110_VOUTCLK_EXT_END - JH7110_VOUTCLK_END] = {
> >
> > this can be const char *const fw_name[...] right?
> >
> >> +                       "vout_src",
> >> +                       "vout_top_ahb",
> >> +                       "vout_top_axi",
> >> +                       "vout_top_hdmitx0_mclk",
> >> +                       "i2stx0_bclk",
> >> +                       "hdmitx0_pixelclk"
> >> +               };
> >> +
> >> +               for (i = 0; i < init.num_parents; i++) {
> >> +                       unsigned int pidx = jh7110_voutclk_data[idx].parents[i];
> >> +
> >> +                       if (pidx < JH7110_VOUTCLK_END)
> >> +                               parents[i].hw = &priv->reg[pidx].hw;
> >> +                       else if (pidx < JH7110_VOUTCLK_EXT_END)
> >> +                               parents[i].fw_name = fw_name[pidx - JH7110_VOUTCLK_END];
> >> +               }
> >> +
> >> +               clk->hw.init = &init;
> >> +               clk->idx = idx;
> >> +               clk->max_div = max & JH71X0_CLK_DIV_MASK;
> >> +
> >> +               ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
> >> +               if (ret)
> >> +                       goto err_exit;
> >> +       }
> >> +
> >> +       ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_voutclk_get, priv);
> >> +       if (ret)
> >> +               goto err_exit;
> >> +
> >> +       ret = jh7110_reset_controller_register(priv, "reset-vout", 4);
> >> +       if (ret)
> >> +               goto err_exit;
> >> +
> >> +       return 0;
> >> +
> >> +err_exit:
> >> +       jh7110_vout_top_crg_disable(top);
> >> +err_clk:
> >> +       pm_runtime_put_sync(priv->dev);
> >> +       pm_runtime_disable(priv->dev);
> >> +       return ret;
> >> +}
> >> +
> >> +static int jh7110_voutcrg_remove(struct platform_device *pdev)
> >> +{
> >> +       void __iomem **base = dev_get_drvdata(&pdev->dev);
> >> +       struct vout_top_crg *top = top_crg_from(base);
> >> +
> >> +       jh7110_vout_top_crg_disable(top);
> >> +       pm_runtime_disable(&pdev->dev);
> >> +
> >> +       return 0;
> >> +}
> >> +
> >> +static const struct of_device_id jh7110_voutcrg_match[] = {
> >> +       { .compatible = "starfive,jh7110-voutcrg" },
> >> +       { /* sentinel */ }
> >> +};
> >> +MODULE_DEVICE_TABLE(of, jh7110_voutcrg_match);
> >> +
> >> +static struct platform_driver jh7110_voutcrg_driver = {
> >> +       .probe = jh7110_voutcrg_probe,
> >> +       .remove = jh7110_voutcrg_remove,
> >> +       .driver = {
> >> +               .name = "clk-starfive-jh7110-vout",
> >> +               .of_match_table = jh7110_voutcrg_match,
> >> +       },
> >> +};
> >> +module_platform_driver(jh7110_voutcrg_driver);
> >> +
> >> +MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
> >> +MODULE_DESCRIPTION("StarFive JH7110 Video-Output clock driver");
> >> +MODULE_LICENSE("GPL");
> >> --
> >> 2.25.1
> >>
> >>
> >> _______________________________________________
> >> linux-riscv mailing list
> >> linux-riscv@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/linux-riscv
>
> Best regards,
> Xingyu Wu

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 09/11] clk: starfive: Add StarFive JH7110 Video-Output clock driver
  2023-03-03  9:23       ` Emil Renner Berthing
@ 2023-03-03  9:44         ` Xingyu Wu
  2023-03-03  9:51           ` Emil Renner Berthing
  0 siblings, 1 reply; 33+ messages in thread
From: Xingyu Wu @ 2023-03-03  9:44 UTC (permalink / raw)
  To: Emil Renner Berthing
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On 2023/3/3 17:23, Emil Renner Berthing wrote:
> On Fri, 3 Mar 2023 at 04:37, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
>>
>> On 2023/3/2 23:48, Emil Renner Berthing wrote:
>> > On Tue, 21 Feb 2023 at 09:40, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
>> >>
>> >> Add driver for the StarFive JH7110 Video-Output clock controller.
>> >>
>> >> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
>> >> ---
>> >>  drivers/clk/starfive/Kconfig                  |  11 +
>> >>  drivers/clk/starfive/Makefile                 |   1 +
>> >>  .../clk/starfive/clk-starfive-jh7110-vout.c   | 261 ++++++++++++++++++
>> >>  3 files changed, 273 insertions(+)
>> >>  create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-vout.c
>> >>
>> >> diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
>> >> index 59499acb95f7..5ebf1ed08627 100644
>> >> --- a/drivers/clk/starfive/Kconfig
>> >> +++ b/drivers/clk/starfive/Kconfig
>> >> @@ -64,3 +64,14 @@ config CLK_STARFIVE_JH7110_ISP
>> >>         help
>> >>           Say yes here to support the Image-Signal-Process clock controller
>> >>           on the StarFive JH7110 SoC.
>> >> +
>> >> +config CLK_STARFIVE_JH7110_VOUT
>> >> +       tristate "StarFive JH7110 Video-Output clock support"
>> >> +       depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
>> >> +       select AUXILIARY_BUS
>> >> +       select CLK_STARFIVE_JH71X0
>> >> +       select RESET_STARFIVE_JH7110
>> >> +       default CLK_STARFIVE_JH7110_SYS
>> >
>> > default m if ARCH_STARFIVE
>>
>> Will modify it.
>>
>> >
>> >> +       help
>> >> +         Say yes here to support the Video-Output clock controller
>> >> +         on the StarFive JH7110 SoC.
>> >> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
>> >> index 76fb9f8d628b..841377e45bb6 100644
>> >> --- a/drivers/clk/starfive/Makefile
>> >> +++ b/drivers/clk/starfive/Makefile
>> >> @@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS)   += clk-starfive-jh7110-sys.o
>> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_AON)  += clk-starfive-jh7110-aon.o
>> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)  += clk-starfive-jh7110-stg.o
>> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP)  += clk-starfive-jh7110-isp.o
>> >> +obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
>> >> diff --git a/drivers/clk/starfive/clk-starfive-jh7110-vout.c b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
>> >> new file mode 100644
>> >> index 000000000000..d786537563a4
>> >> --- /dev/null
>> >> +++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
>> >> @@ -0,0 +1,261 @@
>> >> +// SPDX-License-Identifier: GPL-2.0
>> >> +/*
>> >> + * StarFive JH7110 Video-Output Clock Driver
>> >> + *
>> >> + * Copyright (C) 2022 StarFive Technology Co., Ltd.
>> >> + */
>> >> +
>> >> +#include <linux/clk.h>
>> >> +#include <linux/clk-provider.h>
>> >> +#include <linux/io.h>
>> >> +#include <linux/of.h>
>> >> +#include <linux/platform_device.h>
>> >> +#include <linux/pm_runtime.h>
>> >> +#include <linux/reset.h>
>> >> +
>> >> +#include <dt-bindings/clock/starfive,jh7110-crg.h>
>> >> +
>> >> +#include "clk-starfive-jh71x0.h"
>> >> +
>> >> +/* external clocks */
>> >> +#define JH7110_VOUTCLK_VOUT_SRC                        (JH7110_VOUTCLK_END + 0)
>> >> +#define JH7110_VOUTCLK_VOUT_TOP_AHB            (JH7110_VOUTCLK_END + 1)
>> >> +#define JH7110_VOUTCLK_VOUT_TOP_AXI            (JH7110_VOUTCLK_END + 2)
>> >> +#define JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK   (JH7110_VOUTCLK_END + 3)
>> >> +#define JH7110_VOUTCLK_I2STX0_BCLK             (JH7110_VOUTCLK_END + 4)
>> >> +#define JH7110_VOUTCLK_HDMITX0_PIXELCLK                (JH7110_VOUTCLK_END + 5)
>> >> +#define JH7110_VOUTCLK_EXT_END                 (JH7110_VOUTCLK_END + 6)
>> >> +
>> >> +static const struct jh71x0_clk_data jh7110_voutclk_data[] = {
>> >> +       /* divider */
>> >> +       JH71X0__DIV(JH7110_VOUTCLK_APB, "apb", 8, JH7110_VOUTCLK_VOUT_TOP_AHB),
>> >> +       JH71X0__DIV(JH7110_VOUTCLK_DC8200_PIX, "dc8200_pix", 63, JH7110_VOUTCLK_VOUT_SRC),
>> >> +       JH71X0__DIV(JH7110_VOUTCLK_DSI_SYS, "dsi_sys", 31, JH7110_VOUTCLK_VOUT_SRC),
>> >> +       JH71X0__DIV(JH7110_VOUTCLK_TX_ESC, "tx_esc", 31, JH7110_VOUTCLK_VOUT_TOP_AHB),
>> >> +       /* dc8200 */
>> >> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_AXI, "dc8200_axi", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
>> >> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_CORE, "dc8200_core", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
>> >> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_AHB, "dc8200_ahb", 0, JH7110_VOUTCLK_VOUT_TOP_AHB),
>> >> +       JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX0, "dc8200_pix0", 0, 2,
>> >> +                   JH7110_VOUTCLK_DC8200_PIX,
>> >> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
>> >> +       JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX1, "dc8200_pix1", 0, 2,
>> >> +                   JH7110_VOUTCLK_DC8200_PIX,
>> >> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
>> >> +       /* LCD */
>> >> +       JH71X0_GMUX(JH7110_VOUTCLK_DOM_VOUT_TOP_LCD, "dom_vout_top_lcd", 0, 2,
>> >> +                   JH7110_VOUTCLK_DC8200_PIX0,
>> >> +                   JH7110_VOUTCLK_DC8200_PIX1),
>> >> +       /* dsiTx */
>> >> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_APB, "dsiTx_apb", 0, JH7110_VOUTCLK_DSI_SYS),
>> >> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_SYS, "dsiTx_sys", 0, JH7110_VOUTCLK_DSI_SYS),
>> >> +       JH71X0_GMUX(JH7110_VOUTCLK_DSITX_DPI, "dsiTx_dpi", 0, 2,
>> >> +                   JH7110_VOUTCLK_DC8200_PIX,
>> >> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
>> >> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_TXESC, "dsiTx_txesc", 0, JH7110_VOUTCLK_TX_ESC),
>> >> +       /* mipitx DPHY */
>> >> +       JH71X0_GATE(JH7110_VOUTCLK_MIPITX_DPHY_TXESC, "mipitx_dphy_txesc", 0,
>> >> +                   JH7110_VOUTCLK_TX_ESC),
>> >> +       /* hdmi */
>> >> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_MCLK, "hdmi_tx_mclk", 0,
>> >> +                   JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK),
>> >> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_BCLK, "hdmi_tx_bclk", 0,
>> >> +                   JH7110_VOUTCLK_I2STX0_BCLK),
>> >> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_SYS, "hdmi_tx_sys", 0, JH7110_VOUTCLK_APB),
>> >> +};
>> >> +
>> >> +struct vout_top_crg {
>> >> +       struct clk_bulk_data *top_clks;
>> >> +       struct reset_control *top_rst;
>> >> +       int top_clks_num;
>> >> +       void __iomem *base;
>> >> +};
>> >> +
>> >> +static struct clk_bulk_data jh7110_vout_top_clks[] = {
>> >> +       { .id = "vout_src" },
>> >> +       { .id = "vout_top_ahb" }
>> >> +};
>> >> +
>> >> +static struct vout_top_crg *top_crg_from(void __iomem **base)
>> >> +{
>> >> +       return container_of(base, struct vout_top_crg, base);
>> >> +}
>> >> +
>> >> +static int jh7110_vout_top_crg_get(struct jh71x0_clk_priv *priv, struct vout_top_crg *top)
>> >> +{
>> >> +       int ret;
>> >> +
>> >> +       top->top_clks = jh7110_vout_top_clks;
>> >> +       top->top_clks_num = ARRAY_SIZE(jh7110_vout_top_clks);
>> >> +       ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
>> >> +       if (ret) {
>> >> +               dev_err(priv->dev, "top clks get failed: %d\n", ret);
>> >> +               return ret;
>> >> +       }
>> >> +
>> >> +       /* The reset should be shared and other Vout modules will use its. */
>> >> +       top->top_rst = devm_reset_control_get_shared(priv->dev, NULL);
>> >> +       if (IS_ERR(top->top_rst)) {
>> >> +               dev_err(priv->dev, "top rst get failed\n");
>> >> +               return PTR_ERR(top->top_rst);
>> >> +       }
>> >> +
>> >> +       return 0;
>> >> +}
>> >> +
>> >> +static int jh7110_vout_top_crg_enable(struct vout_top_crg *top)
>> >> +{
>> >> +       int ret;
>> >> +
>> >> +       ret = clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
>> >> +       if (ret)
>> >> +               return ret;
>> >
>> > Hmm.. do all the clocks used as input really need to be enabled for
>> > any one of the vout clocks to work?
>> >
>> > In other words: suppose you just need a single clock in the VOUTCRG
>> > domain. Do we really need to turn on all the input clocks for the
>> > VOUTCRG for that one clock to work? Normally I'd expect the clock
>> > framework to make sure all parents of that clock are enabled.
>>
>> It must enable core clock and ahb clock before reading or writing VOUTCRG registers
>> otherwise it would be failed to read and write. And it is even crash if it don't
>> enable core clock before reading or writing ISPCRG registers.
>> This serious problem was found when debugging earlier.
> 
> Ah sorry. I see now that you're only claiming the core and AHB bus.
> That makes sense.
> 
> So now the question is if there are similar clocks that need to be
> claimed by the AON, STG and ISP CRGs. They're most likely already
> turned on by u-boot or by default which is why we don't see errors,
> but Linux should still claim them if the driver needs them.

Oh, just VOUTCRG and ISPCRG should actively enable the clock. The clocks like bus clock
are enabled by default about AONCRG and STGCRG. And these clocks already uses CLK_IS_CRITICAL
in SYSCRG to make sure it would not be disabled.

> 
>> >
>> >> +
>> >> +       return reset_control_deassert(top->top_rst);
>> >> +}
>> >> +
>> >> +static void jh7110_vout_top_crg_disable(struct vout_top_crg *top)
>> >> +{
>> >> +       clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
>> >> +}
>> >> +
>> >> +static struct clk_hw *jh7110_voutclk_get(struct of_phandle_args *clkspec, void *data)
>> >> +{
>> >> +       struct jh71x0_clk_priv *priv = data;
>> >> +       unsigned int idx = clkspec->args[0];
>> >> +
>> >> +       if (idx < JH7110_VOUTCLK_END)
>> >> +               return &priv->reg[idx].hw;
>> >> +
>> >> +       return ERR_PTR(-EINVAL);
>> >> +}
>> >> +
>> >> +static int jh7110_voutcrg_probe(struct platform_device *pdev)
>> >> +{
>> >> +       struct jh71x0_clk_priv *priv;
>> >> +       struct vout_top_crg *top;
>> >> +       unsigned int idx;
>> >> +       int ret;
>> >> +
>> >> +       priv = devm_kzalloc(&pdev->dev,
>> >> +                           struct_size(priv, reg, JH7110_VOUTCLK_END),
>> >> +                           GFP_KERNEL);
>> >> +       if (!priv)
>> >> +               return -ENOMEM;
>> >> +
>> >> +       top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
>> >> +       if (!top)
>> >> +               return -ENOMEM;
>> >> +
>> >> +       spin_lock_init(&priv->rmw_lock);
>> >> +       priv->dev = &pdev->dev;
>> >> +       priv->base = devm_platform_ioremap_resource(pdev, 0);
>> >> +       if (IS_ERR(priv->base))
>> >> +               return PTR_ERR(priv->base);
>> >> +
>> >> +       top->base = priv->base;
>> >> +       dev_set_drvdata(priv->dev, (void *)(&top->base));
>> >> +
>> >> +       pm_runtime_enable(priv->dev);
>> >> +       ret = pm_runtime_get_sync(priv->dev);
>> >> +       if (ret < 0) {
>> >> +               dev_err(priv->dev, "failed to turn power: %d\n", ret);
>> >> +               return ret;
>> >> +       }
>> >> +
>> >> +       ret = jh7110_vout_top_crg_get(priv, top);
>> >> +       if (ret)
>> >> +               goto err_clk;
>> >> +
>> >> +       ret = jh7110_vout_top_crg_enable(top);
>> >> +       if (ret)
>> >> +               goto err_clk;
>> >> +
>> >> +       for (idx = 0; idx < JH7110_VOUTCLK_END; idx++) {
>> >> +               u32 max = jh7110_voutclk_data[idx].max;
>> >> +               struct clk_parent_data parents[4] = {};
>> >> +               struct clk_init_data init = {
>> >> +                       .name = jh7110_voutclk_data[idx].name,
>> >> +                       .ops = starfive_jh71x0_clk_ops(max),
>> >> +                       .parent_data = parents,
>> >> +                       .num_parents =
>> >> +                               ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
>> >> +                       .flags = jh7110_voutclk_data[idx].flags,
>> >> +               };
>> >> +               struct jh71x0_clk *clk = &priv->reg[idx];
>> >> +               unsigned int i;
>> >> +               char *fw_name[JH7110_VOUTCLK_EXT_END - JH7110_VOUTCLK_END] = {
>> >
>> > this can be const char *const fw_name[...] right?
>> >
>> >> +                       "vout_src",
>> >> +                       "vout_top_ahb",
>> >> +                       "vout_top_axi",
>> >> +                       "vout_top_hdmitx0_mclk",
>> >> +                       "i2stx0_bclk",
>> >> +                       "hdmitx0_pixelclk"
>> >> +               };
>> >> +
>> >> +               for (i = 0; i < init.num_parents; i++) {
>> >> +                       unsigned int pidx = jh7110_voutclk_data[idx].parents[i];
>> >> +
>> >> +                       if (pidx < JH7110_VOUTCLK_END)
>> >> +                               parents[i].hw = &priv->reg[pidx].hw;
>> >> +                       else if (pidx < JH7110_VOUTCLK_EXT_END)
>> >> +                               parents[i].fw_name = fw_name[pidx - JH7110_VOUTCLK_END];
>> >> +               }
>> >> +
>> >> +               clk->hw.init = &init;
>> >> +               clk->idx = idx;
>> >> +               clk->max_div = max & JH71X0_CLK_DIV_MASK;
>> >> +
>> >> +               ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
>> >> +               if (ret)
>> >> +                       goto err_exit;
>> >> +       }
>> >> +
>> >> +       ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_voutclk_get, priv);
>> >> +       if (ret)
>> >> +               goto err_exit;
>> >> +
>> >> +       ret = jh7110_reset_controller_register(priv, "reset-vout", 4);
>> >> +       if (ret)
>> >> +               goto err_exit;
>> >> +
>> >> +       return 0;
>> >> +
>> >> +err_exit:
>> >> +       jh7110_vout_top_crg_disable(top);
>> >> +err_clk:
>> >> +       pm_runtime_put_sync(priv->dev);
>> >> +       pm_runtime_disable(priv->dev);
>> >> +       return ret;
>> >> +}
>> >> +
>> >> +static int jh7110_voutcrg_remove(struct platform_device *pdev)
>> >> +{
>> >> +       void __iomem **base = dev_get_drvdata(&pdev->dev);
>> >> +       struct vout_top_crg *top = top_crg_from(base);
>> >> +
>> >> +       jh7110_vout_top_crg_disable(top);
>> >> +       pm_runtime_disable(&pdev->dev);
>> >> +
>> >> +       return 0;
>> >> +}
>> >> +
>> >> +static const struct of_device_id jh7110_voutcrg_match[] = {
>> >> +       { .compatible = "starfive,jh7110-voutcrg" },
>> >> +       { /* sentinel */ }
>> >> +};
>> >> +MODULE_DEVICE_TABLE(of, jh7110_voutcrg_match);
>> >> +
>> >> +static struct platform_driver jh7110_voutcrg_driver = {
>> >> +       .probe = jh7110_voutcrg_probe,
>> >> +       .remove = jh7110_voutcrg_remove,
>> >> +       .driver = {
>> >> +               .name = "clk-starfive-jh7110-vout",
>> >> +               .of_match_table = jh7110_voutcrg_match,
>> >> +       },
>> >> +};
>> >> +module_platform_driver(jh7110_voutcrg_driver);
>> >> +
>> >> +MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
>> >> +MODULE_DESCRIPTION("StarFive JH7110 Video-Output clock driver");
>> >> +MODULE_LICENSE("GPL");
>> >> --
>> >> 2.25.1
>> >>
>> >>
>> >> _______________________________________________
>> >> linux-riscv mailing list
>> >> linux-riscv@lists.infradead.org
>> >> http://lists.infradead.org/mailman/listinfo/linux-riscv

Best regards,
Xingyu Wu


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v2 09/11] clk: starfive: Add StarFive JH7110 Video-Output clock driver
  2023-03-03  9:44         ` Xingyu Wu
@ 2023-03-03  9:51           ` Emil Renner Berthing
  0 siblings, 0 replies; 33+ messages in thread
From: Emil Renner Berthing @ 2023-03-03  9:51 UTC (permalink / raw)
  To: Xingyu Wu
  Cc: linux-riscv, devicetree, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Philipp Zabel, Emil Renner Berthing,
	Rob Herring, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Hal Feng, linux-kernel, linux-clk

On Fri, 3 Mar 2023 at 10:44, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
> On 2023/3/3 17:23, Emil Renner Berthing wrote:
> > On Fri, 3 Mar 2023 at 04:37, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
> >>
> >> On 2023/3/2 23:48, Emil Renner Berthing wrote:
> >> > On Tue, 21 Feb 2023 at 09:40, Xingyu Wu <xingyu.wu@starfivetech.com> wrote:
> >> >>
> >> >> Add driver for the StarFive JH7110 Video-Output clock controller.
> >> >>
> >> >> Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
> >> >> ---
> >> >>  drivers/clk/starfive/Kconfig                  |  11 +
> >> >>  drivers/clk/starfive/Makefile                 |   1 +
> >> >>  .../clk/starfive/clk-starfive-jh7110-vout.c   | 261 ++++++++++++++++++
> >> >>  3 files changed, 273 insertions(+)
> >> >>  create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-vout.c
> >> >>
> >> >> diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
> >> >> index 59499acb95f7..5ebf1ed08627 100644
> >> >> --- a/drivers/clk/starfive/Kconfig
> >> >> +++ b/drivers/clk/starfive/Kconfig
> >> >> @@ -64,3 +64,14 @@ config CLK_STARFIVE_JH7110_ISP
> >> >>         help
> >> >>           Say yes here to support the Image-Signal-Process clock controller
> >> >>           on the StarFive JH7110 SoC.
> >> >> +
> >> >> +config CLK_STARFIVE_JH7110_VOUT
> >> >> +       tristate "StarFive JH7110 Video-Output clock support"
> >> >> +       depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
> >> >> +       select AUXILIARY_BUS
> >> >> +       select CLK_STARFIVE_JH71X0
> >> >> +       select RESET_STARFIVE_JH7110
> >> >> +       default CLK_STARFIVE_JH7110_SYS
> >> >
> >> > default m if ARCH_STARFIVE
> >>
> >> Will modify it.
> >>
> >> >
> >> >> +       help
> >> >> +         Say yes here to support the Video-Output clock controller
> >> >> +         on the StarFive JH7110 SoC.
> >> >> diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
> >> >> index 76fb9f8d628b..841377e45bb6 100644
> >> >> --- a/drivers/clk/starfive/Makefile
> >> >> +++ b/drivers/clk/starfive/Makefile
> >> >> @@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS)   += clk-starfive-jh7110-sys.o
> >> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_AON)  += clk-starfive-jh7110-aon.o
> >> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_STG)  += clk-starfive-jh7110-stg.o
> >> >>  obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP)  += clk-starfive-jh7110-isp.o
> >> >> +obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
> >> >> diff --git a/drivers/clk/starfive/clk-starfive-jh7110-vout.c b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
> >> >> new file mode 100644
> >> >> index 000000000000..d786537563a4
> >> >> --- /dev/null
> >> >> +++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
> >> >> @@ -0,0 +1,261 @@
> >> >> +// SPDX-License-Identifier: GPL-2.0
> >> >> +/*
> >> >> + * StarFive JH7110 Video-Output Clock Driver
> >> >> + *
> >> >> + * Copyright (C) 2022 StarFive Technology Co., Ltd.
> >> >> + */
> >> >> +
> >> >> +#include <linux/clk.h>
> >> >> +#include <linux/clk-provider.h>
> >> >> +#include <linux/io.h>
> >> >> +#include <linux/of.h>
> >> >> +#include <linux/platform_device.h>
> >> >> +#include <linux/pm_runtime.h>
> >> >> +#include <linux/reset.h>
> >> >> +
> >> >> +#include <dt-bindings/clock/starfive,jh7110-crg.h>
> >> >> +
> >> >> +#include "clk-starfive-jh71x0.h"
> >> >> +
> >> >> +/* external clocks */
> >> >> +#define JH7110_VOUTCLK_VOUT_SRC                        (JH7110_VOUTCLK_END + 0)
> >> >> +#define JH7110_VOUTCLK_VOUT_TOP_AHB            (JH7110_VOUTCLK_END + 1)
> >> >> +#define JH7110_VOUTCLK_VOUT_TOP_AXI            (JH7110_VOUTCLK_END + 2)
> >> >> +#define JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK   (JH7110_VOUTCLK_END + 3)
> >> >> +#define JH7110_VOUTCLK_I2STX0_BCLK             (JH7110_VOUTCLK_END + 4)
> >> >> +#define JH7110_VOUTCLK_HDMITX0_PIXELCLK                (JH7110_VOUTCLK_END + 5)
> >> >> +#define JH7110_VOUTCLK_EXT_END                 (JH7110_VOUTCLK_END + 6)
> >> >> +
> >> >> +static const struct jh71x0_clk_data jh7110_voutclk_data[] = {
> >> >> +       /* divider */
> >> >> +       JH71X0__DIV(JH7110_VOUTCLK_APB, "apb", 8, JH7110_VOUTCLK_VOUT_TOP_AHB),
> >> >> +       JH71X0__DIV(JH7110_VOUTCLK_DC8200_PIX, "dc8200_pix", 63, JH7110_VOUTCLK_VOUT_SRC),
> >> >> +       JH71X0__DIV(JH7110_VOUTCLK_DSI_SYS, "dsi_sys", 31, JH7110_VOUTCLK_VOUT_SRC),
> >> >> +       JH71X0__DIV(JH7110_VOUTCLK_TX_ESC, "tx_esc", 31, JH7110_VOUTCLK_VOUT_TOP_AHB),
> >> >> +       /* dc8200 */
> >> >> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_AXI, "dc8200_axi", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
> >> >> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_CORE, "dc8200_core", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
> >> >> +       JH71X0_GATE(JH7110_VOUTCLK_DC8200_AHB, "dc8200_ahb", 0, JH7110_VOUTCLK_VOUT_TOP_AHB),
> >> >> +       JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX0, "dc8200_pix0", 0, 2,
> >> >> +                   JH7110_VOUTCLK_DC8200_PIX,
> >> >> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
> >> >> +       JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX1, "dc8200_pix1", 0, 2,
> >> >> +                   JH7110_VOUTCLK_DC8200_PIX,
> >> >> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
> >> >> +       /* LCD */
> >> >> +       JH71X0_GMUX(JH7110_VOUTCLK_DOM_VOUT_TOP_LCD, "dom_vout_top_lcd", 0, 2,
> >> >> +                   JH7110_VOUTCLK_DC8200_PIX0,
> >> >> +                   JH7110_VOUTCLK_DC8200_PIX1),
> >> >> +       /* dsiTx */
> >> >> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_APB, "dsiTx_apb", 0, JH7110_VOUTCLK_DSI_SYS),
> >> >> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_SYS, "dsiTx_sys", 0, JH7110_VOUTCLK_DSI_SYS),
> >> >> +       JH71X0_GMUX(JH7110_VOUTCLK_DSITX_DPI, "dsiTx_dpi", 0, 2,
> >> >> +                   JH7110_VOUTCLK_DC8200_PIX,
> >> >> +                   JH7110_VOUTCLK_HDMITX0_PIXELCLK),
> >> >> +       JH71X0_GATE(JH7110_VOUTCLK_DSITX_TXESC, "dsiTx_txesc", 0, JH7110_VOUTCLK_TX_ESC),
> >> >> +       /* mipitx DPHY */
> >> >> +       JH71X0_GATE(JH7110_VOUTCLK_MIPITX_DPHY_TXESC, "mipitx_dphy_txesc", 0,
> >> >> +                   JH7110_VOUTCLK_TX_ESC),
> >> >> +       /* hdmi */
> >> >> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_MCLK, "hdmi_tx_mclk", 0,
> >> >> +                   JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK),
> >> >> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_BCLK, "hdmi_tx_bclk", 0,
> >> >> +                   JH7110_VOUTCLK_I2STX0_BCLK),
> >> >> +       JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_SYS, "hdmi_tx_sys", 0, JH7110_VOUTCLK_APB),
> >> >> +};
> >> >> +
> >> >> +struct vout_top_crg {
> >> >> +       struct clk_bulk_data *top_clks;
> >> >> +       struct reset_control *top_rst;
> >> >> +       int top_clks_num;
> >> >> +       void __iomem *base;
> >> >> +};
> >> >> +
> >> >> +static struct clk_bulk_data jh7110_vout_top_clks[] = {
> >> >> +       { .id = "vout_src" },
> >> >> +       { .id = "vout_top_ahb" }
> >> >> +};
> >> >> +
> >> >> +static struct vout_top_crg *top_crg_from(void __iomem **base)
> >> >> +{
> >> >> +       return container_of(base, struct vout_top_crg, base);
> >> >> +}
> >> >> +
> >> >> +static int jh7110_vout_top_crg_get(struct jh71x0_clk_priv *priv, struct vout_top_crg *top)
> >> >> +{
> >> >> +       int ret;
> >> >> +
> >> >> +       top->top_clks = jh7110_vout_top_clks;
> >> >> +       top->top_clks_num = ARRAY_SIZE(jh7110_vout_top_clks);
> >> >> +       ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
> >> >> +       if (ret) {
> >> >> +               dev_err(priv->dev, "top clks get failed: %d\n", ret);
> >> >> +               return ret;
> >> >> +       }
> >> >> +
> >> >> +       /* The reset should be shared and other Vout modules will use its. */
> >> >> +       top->top_rst = devm_reset_control_get_shared(priv->dev, NULL);
> >> >> +       if (IS_ERR(top->top_rst)) {
> >> >> +               dev_err(priv->dev, "top rst get failed\n");
> >> >> +               return PTR_ERR(top->top_rst);
> >> >> +       }
> >> >> +
> >> >> +       return 0;
> >> >> +}
> >> >> +
> >> >> +static int jh7110_vout_top_crg_enable(struct vout_top_crg *top)
> >> >> +{
> >> >> +       int ret;
> >> >> +
> >> >> +       ret = clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
> >> >> +       if (ret)
> >> >> +               return ret;
> >> >
> >> > Hmm.. do all the clocks used as input really need to be enabled for
> >> > any one of the vout clocks to work?
> >> >
> >> > In other words: suppose you just need a single clock in the VOUTCRG
> >> > domain. Do we really need to turn on all the input clocks for the
> >> > VOUTCRG for that one clock to work? Normally I'd expect the clock
> >> > framework to make sure all parents of that clock are enabled.
> >>
> >> It must enable core clock and ahb clock before reading or writing VOUTCRG registers
> >> otherwise it would be failed to read and write. And it is even crash if it don't
> >> enable core clock before reading or writing ISPCRG registers.
> >> This serious problem was found when debugging earlier.
> >
> > Ah sorry. I see now that you're only claiming the core and AHB bus.
> > That makes sense.
> >
> > So now the question is if there are similar clocks that need to be
> > claimed by the AON, STG and ISP CRGs. They're most likely already
> > turned on by u-boot or by default which is why we don't see errors,
> > but Linux should still claim them if the driver needs them.
>
> Oh, just VOUTCRG and ISPCRG should actively enable the clock. The clocks like bus clock
> are enabled by default about AONCRG and STGCRG. And these clocks already uses CLK_IS_CRITICAL
> in SYSCRG to make sure it would not be disabled.

Oh, so maybe those clocks are not critical, but just need to be
claimed and turned on by the AONCRG and STGCRG drivers before use?

> >
> >> >
> >> >> +
> >> >> +       return reset_control_deassert(top->top_rst);
> >> >> +}
> >> >> +
> >> >> +static void jh7110_vout_top_crg_disable(struct vout_top_crg *top)
> >> >> +{
> >> >> +       clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
> >> >> +}
> >> >> +
> >> >> +static struct clk_hw *jh7110_voutclk_get(struct of_phandle_args *clkspec, void *data)
> >> >> +{
> >> >> +       struct jh71x0_clk_priv *priv = data;
> >> >> +       unsigned int idx = clkspec->args[0];
> >> >> +
> >> >> +       if (idx < JH7110_VOUTCLK_END)
> >> >> +               return &priv->reg[idx].hw;
> >> >> +
> >> >> +       return ERR_PTR(-EINVAL);
> >> >> +}
> >> >> +
> >> >> +static int jh7110_voutcrg_probe(struct platform_device *pdev)
> >> >> +{
> >> >> +       struct jh71x0_clk_priv *priv;
> >> >> +       struct vout_top_crg *top;
> >> >> +       unsigned int idx;
> >> >> +       int ret;
> >> >> +
> >> >> +       priv = devm_kzalloc(&pdev->dev,
> >> >> +                           struct_size(priv, reg, JH7110_VOUTCLK_END),
> >> >> +                           GFP_KERNEL);
> >> >> +       if (!priv)
> >> >> +               return -ENOMEM;
> >> >> +
> >> >> +       top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
> >> >> +       if (!top)
> >> >> +               return -ENOMEM;
> >> >> +
> >> >> +       spin_lock_init(&priv->rmw_lock);
> >> >> +       priv->dev = &pdev->dev;
> >> >> +       priv->base = devm_platform_ioremap_resource(pdev, 0);
> >> >> +       if (IS_ERR(priv->base))
> >> >> +               return PTR_ERR(priv->base);
> >> >> +
> >> >> +       top->base = priv->base;
> >> >> +       dev_set_drvdata(priv->dev, (void *)(&top->base));
> >> >> +
> >> >> +       pm_runtime_enable(priv->dev);
> >> >> +       ret = pm_runtime_get_sync(priv->dev);
> >> >> +       if (ret < 0) {
> >> >> +               dev_err(priv->dev, "failed to turn power: %d\n", ret);
> >> >> +               return ret;
> >> >> +       }
> >> >> +
> >> >> +       ret = jh7110_vout_top_crg_get(priv, top);
> >> >> +       if (ret)
> >> >> +               goto err_clk;
> >> >> +
> >> >> +       ret = jh7110_vout_top_crg_enable(top);
> >> >> +       if (ret)
> >> >> +               goto err_clk;
> >> >> +
> >> >> +       for (idx = 0; idx < JH7110_VOUTCLK_END; idx++) {
> >> >> +               u32 max = jh7110_voutclk_data[idx].max;
> >> >> +               struct clk_parent_data parents[4] = {};
> >> >> +               struct clk_init_data init = {
> >> >> +                       .name = jh7110_voutclk_data[idx].name,
> >> >> +                       .ops = starfive_jh71x0_clk_ops(max),
> >> >> +                       .parent_data = parents,
> >> >> +                       .num_parents =
> >> >> +                               ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
> >> >> +                       .flags = jh7110_voutclk_data[idx].flags,
> >> >> +               };
> >> >> +               struct jh71x0_clk *clk = &priv->reg[idx];
> >> >> +               unsigned int i;
> >> >> +               char *fw_name[JH7110_VOUTCLK_EXT_END - JH7110_VOUTCLK_END] = {
> >> >
> >> > this can be const char *const fw_name[...] right?
> >> >
> >> >> +                       "vout_src",
> >> >> +                       "vout_top_ahb",
> >> >> +                       "vout_top_axi",
> >> >> +                       "vout_top_hdmitx0_mclk",
> >> >> +                       "i2stx0_bclk",
> >> >> +                       "hdmitx0_pixelclk"
> >> >> +               };
> >> >> +
> >> >> +               for (i = 0; i < init.num_parents; i++) {
> >> >> +                       unsigned int pidx = jh7110_voutclk_data[idx].parents[i];
> >> >> +
> >> >> +                       if (pidx < JH7110_VOUTCLK_END)
> >> >> +                               parents[i].hw = &priv->reg[pidx].hw;
> >> >> +                       else if (pidx < JH7110_VOUTCLK_EXT_END)
> >> >> +                               parents[i].fw_name = fw_name[pidx - JH7110_VOUTCLK_END];
> >> >> +               }
> >> >> +
> >> >> +               clk->hw.init = &init;
> >> >> +               clk->idx = idx;
> >> >> +               clk->max_div = max & JH71X0_CLK_DIV_MASK;
> >> >> +
> >> >> +               ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
> >> >> +               if (ret)
> >> >> +                       goto err_exit;
> >> >> +       }
> >> >> +
> >> >> +       ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_voutclk_get, priv);
> >> >> +       if (ret)
> >> >> +               goto err_exit;
> >> >> +
> >> >> +       ret = jh7110_reset_controller_register(priv, "reset-vout", 4);
> >> >> +       if (ret)
> >> >> +               goto err_exit;
> >> >> +
> >> >> +       return 0;
> >> >> +
> >> >> +err_exit:
> >> >> +       jh7110_vout_top_crg_disable(top);
> >> >> +err_clk:
> >> >> +       pm_runtime_put_sync(priv->dev);
> >> >> +       pm_runtime_disable(priv->dev);
> >> >> +       return ret;
> >> >> +}
> >> >> +
> >> >> +static int jh7110_voutcrg_remove(struct platform_device *pdev)
> >> >> +{
> >> >> +       void __iomem **base = dev_get_drvdata(&pdev->dev);
> >> >> +       struct vout_top_crg *top = top_crg_from(base);
> >> >> +
> >> >> +       jh7110_vout_top_crg_disable(top);
> >> >> +       pm_runtime_disable(&pdev->dev);
> >> >> +
> >> >> +       return 0;
> >> >> +}
> >> >> +
> >> >> +static const struct of_device_id jh7110_voutcrg_match[] = {
> >> >> +       { .compatible = "starfive,jh7110-voutcrg" },
> >> >> +       { /* sentinel */ }
> >> >> +};
> >> >> +MODULE_DEVICE_TABLE(of, jh7110_voutcrg_match);
> >> >> +
> >> >> +static struct platform_driver jh7110_voutcrg_driver = {
> >> >> +       .probe = jh7110_voutcrg_probe,
> >> >> +       .remove = jh7110_voutcrg_remove,
> >> >> +       .driver = {
> >> >> +               .name = "clk-starfive-jh7110-vout",
> >> >> +               .of_match_table = jh7110_voutcrg_match,
> >> >> +       },
> >> >> +};
> >> >> +module_platform_driver(jh7110_voutcrg_driver);
> >> >> +
> >> >> +MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
> >> >> +MODULE_DESCRIPTION("StarFive JH7110 Video-Output clock driver");
> >> >> +MODULE_LICENSE("GPL");
> >> >> --
> >> >> 2.25.1
> >> >>
> >> >>
> >> >> _______________________________________________
> >> >> linux-riscv mailing list
> >> >> linux-riscv@lists.infradead.org
> >> >> http://lists.infradead.org/mailman/listinfo/linux-riscv
>
> Best regards,
> Xingyu Wu
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2023-03-03  9:52 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-21  8:33 [PATCH v2 00/11] Add new partial clock and reset drivers for StarFive JH7110 Xingyu Wu
2023-02-21  8:33 ` [PATCH v2 01/11] dt-bindings: clock: Add StarFive JH7110 System-Top-Group clock and reset generator Xingyu Wu
2023-02-21 11:25   ` Krzysztof Kozlowski
2023-02-21 13:01     ` Xingyu Wu
2023-02-21 13:37       ` Krzysztof Kozlowski
2023-02-22  1:48         ` Xingyu Wu
2023-03-02 15:05   ` Emil Renner Berthing
2023-03-03  3:14     ` Xingyu Wu
2023-02-21  8:33 ` [PATCH v2 02/11] reset: starfive: jh7110: Add StarFive System-Top-Group reset support Xingyu Wu
2023-02-21  8:33 ` [PATCH v2 03/11] clk: starfive: Add StarFive JH7110 System-Top-Group clock driver Xingyu Wu
2023-03-02 15:16   ` Emil Renner Berthing
2023-02-21  8:33 ` [PATCH v2 04/11] dt-bindings: clock: Add StarFive JH7110 Image-Signal-Process clock and reset generator Xingyu Wu
2023-02-21 11:26   ` Krzysztof Kozlowski
2023-02-21  8:33 ` [PATCH v2 05/11] reset: starfive: jh7110: Add StarFive Image-Signal-Process reset support Xingyu Wu
2023-02-21  8:33 ` [PATCH v2 06/11] clk: starfive: Add StarFive JH7110 Image-Signal-Process clock driver Xingyu Wu
2023-03-02 15:39   ` Emil Renner Berthing
2023-03-03  3:59     ` Xingyu Wu
2023-03-03  9:01       ` Emil Renner Berthing
2023-03-03  9:14         ` Xingyu Wu
2023-02-21  8:33 ` [PATCH v2 07/11] dt-bindings: clock: Add StarFive JH7110 Video-Output clock and reset generator Xingyu Wu
2023-02-21 11:27   ` Krzysztof Kozlowski
2023-02-21  8:33 ` [PATCH v2 08/11] reset: starfive: jh7110: Add StarFive Video-Output reset support Xingyu Wu
2023-02-21  8:33 ` [PATCH v2 09/11] clk: starfive: Add StarFive JH7110 Video-Output clock driver Xingyu Wu
2023-03-02 15:48   ` Emil Renner Berthing
2023-03-03  3:37     ` Xingyu Wu
2023-03-03  9:23       ` Emil Renner Berthing
2023-03-03  9:44         ` Xingyu Wu
2023-03-03  9:51           ` Emil Renner Berthing
2023-02-21  8:33 ` [PATCH v2 10/11] riscv: dts: starfive: jh7110: Add DVP and HDMI TX pixel external clocks Xingyu Wu
2023-02-27 19:55   ` Conor Dooley
2023-02-28  1:40     ` Xingyu Wu
2023-02-21  8:33 ` [PATCH v2 11/11] riscv: dts: starfive: jh7110: Add STGCRG/ISPCRG/VOUTCRG nodes Xingyu Wu
2023-02-27 19:53   ` Conor Dooley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).