This patch serises are to add PLL clocks driver and providers by writing
and reading syscon registers for the StarFive JH7110 RISC-V SoC. And add
documentation and nodes to describe StarFive System Controller(syscon)
Registers. This patch serises are based on Linux 6.4.
PLLs are high speed, low jitter frequency synthesizers in JH7110.
Each PLL clock works in integer mode or fraction mode by some dividers,
and the dividers are set in several syscon registers.
The formula for calculating frequency is:
Fvco = Fref * (NI + NF) / M / Q1
The first patch adds docunmentation to describe PLL clock bindings,
and the second patch adds documentation to decribe syscon registers.
The patch 3 modifies the SYSCRG bindings and adds PLL clock inputs.
The patch 4 adds driver to support PLL clocks for JH7110.
The patch 5 modifies the system clock driver and can select the PLL clock
source from PLL clocks driver. And the patch 6 adds the
stg/sys/aon syscon nodes for JH7110 SoC. The last patch modifies the
syscrg node in JH7110 dts file.
Changes since v6:
- Rebased on Linux 6.5-rc2.
- Patch 1 added the 'the' in front of 'JH7110' and changed the PLL clock
names from 'JH7110_CLK_PLL?_OUT' to 'JH7110_PLLCLK_PLL?_OUT' in the
binding of PLL.
- Patch 2 modified the value of 'reg' in example to fix the error.
- Patch 4 and 7 changed the PLL clock names from 'JH7110_CLK_PLL?_OUT'
to 'JH7110_PLLCLK_PLL?_OUT' in the driver and dts.
- Patch 5 added clk_put() and a better way to detect if the pll
references are specified in the device tree or not.
v6: https://lore.kernel.org/all/[email protected]/
Changes since v5:
- Rebased on Linux 6.4.
- Patch 1 fixed some grammatical mistake.
- Patch 2 added the selection about properties from different syscon
modules and madethe example completed.
- Patch 3 dropped the 'optional' PLL clocks.
v5: https://lore.kernel.org/all/[email protected]/
Changes since v4:
- Rebased on Linux 6.4-rc6.
- Patch 2 dropped the example node about sys-syscon.
- Patch 3 used PLL clocks as one of optional items in SYSCRG bindings.
- Patch 4 used the patch instead about PLL clocks driver from Emil.
- Patch 5 retained the fixed factor PLL clocks as the optional source
about PLL clocks in SYSCRG clock driver.
- Patch 6 added the child node clock-controller as the complete
sys-syscon node and patch 7 dropped this part.
v4: https://lore.kernel.org/all/[email protected]/
Changes since v3:
- Rebased on Linux 6.4-rc1.
- Dropped the 'power-controller' property and used 'power-domain-cells'
instead in syscon binding.
- Used the data by of_device_id to get the syscon registers'
configuration include offset, mask and shift.
v3: https://lore.kernel.org/all/[email protected]/
Changes since v2:
- Rebased on latest JH7110 basic clock drivers.
- Added the complete documentation to describe syscon register.
- Added syscon node in JH7110 dts file.
- Modified the clock rate selection to match the closest rate in
PLL driver when setting rate.
v2: https://lore.kernel.org/all/[email protected]/
Changes since v1:
- Changed PLL clock node to be child of syscon node in dts.
- Modifed the definitions and names of function in PLL clock driver.
- Added commit to update syscon and syscrg dt-bindings.
v1: https://lore.kernel.org/all/[email protected]/
William Qiu (2):
dt-bindings: soc: starfive: Add StarFive syscon module
riscv: dts: starfive: jh7110: Add syscon nodes
Xingyu Wu (5):
dt-bindings: clock: Add StarFive JH7110 PLL clock generator
dt-bindings: clock: jh7110-syscrg: Add PLL clock inputs
clk: starfive: Add StarFive JH7110 PLL clock driver
clk: starfive: jh7110-sys: Add PLL clocks source from DTS
riscv: dts: starfive: jh7110: Add PLL clocks source in SYSCRG node
.../bindings/clock/starfive,jh7110-pll.yaml | 46 ++
.../clock/starfive,jh7110-syscrg.yaml | 18 +-
.../soc/starfive/starfive,jh7110-syscon.yaml | 93 ++++
MAINTAINERS | 13 +
arch/riscv/boot/dts/starfive/jh7110.dtsi | 30 +-
drivers/clk/starfive/Kconfig | 9 +
drivers/clk/starfive/Makefile | 1 +
.../clk/starfive/clk-starfive-jh7110-pll.c | 507 ++++++++++++++++++
.../clk/starfive/clk-starfive-jh7110-sys.c | 66 ++-
.../dt-bindings/clock/starfive,jh7110-crg.h | 6 +
10 files changed, 763 insertions(+), 26 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
create mode 100644 Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-pll.c
--
2.25.1
Add bindings for the PLL clock generator on the JH7110 RISC-V SoC.
Reviewed-by: Conor Dooley <[email protected]>
Reviewed-by: Krzysztof Kozlowski <[email protected]>
Signed-off-by: Xingyu Wu <[email protected]>
---
.../bindings/clock/starfive,jh7110-pll.yaml | 46 +++++++++++++++++++
.../dt-bindings/clock/starfive,jh7110-crg.h | 6 +++
2 files changed, 52 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
new file mode 100644
index 000000000000..be8300ce86d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/starfive,jh7110-pll.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH7110 PLL Clock Generator
+
+description:
+ These PLLs are high speed, low jitter frequency synthesizers in the JH7110.
+ Each PLL works in integer mode or fraction mode, with configuration
+ registers in the sys syscon. So the PLLs node should be a child of
+ SYS-SYSCON node.
+ The formula for calculating frequency is
+ Fvco = Fref * (NI + NF) / M / Q1
+
+maintainers:
+ - Xingyu Wu <[email protected]>
+
+properties:
+ compatible:
+ const: starfive,jh7110-pll
+
+ clocks:
+ maxItems: 1
+ description: Main Oscillator (24 MHz)
+
+ '#clock-cells':
+ const: 1
+ description:
+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
+
+required:
+ - compatible
+ - clocks
+ - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller {
+ compatible = "starfive,jh7110-pll";
+ clocks = <&osc>;
+ #clock-cells = <1>;
+ };
diff --git a/include/dt-bindings/clock/starfive,jh7110-crg.h b/include/dt-bindings/clock/starfive,jh7110-crg.h
index 06257bfd9ac1..3fb5e31c3be4 100644
--- a/include/dt-bindings/clock/starfive,jh7110-crg.h
+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
@@ -6,6 +6,12 @@
#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
#define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
+/* PLL clocks */
+#define JH7110_PLLCLK_PLL0_OUT 0
+#define JH7110_PLLCLK_PLL1_OUT 1
+#define JH7110_PLLCLK_PLL2_OUT 2
+#define JH7110_PLLCLK_END 3
+
/* SYSCRG clocks */
#define JH7110_SYSCLK_CPU_ROOT 0
#define JH7110_SYSCLK_CPU_CORE 1
--
2.25.1
Add PLL clock inputs from PLL clock generator.
Reviewed-by: Emil Renner Berthing <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
Signed-off-by: Xingyu Wu <[email protected]>
---
.../bindings/clock/starfive,jh7110-syscrg.yaml | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
index 84373ae31644..5ba0a885aa80 100644
--- a/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
@@ -27,6 +27,9 @@ properties:
- description: External I2S RX left/right channel clock
- description: External TDM clock
- description: External audio master clock
+ - description: PLL0
+ - description: PLL1
+ - description: PLL2
- items:
- description: Main Oscillator (24 MHz)
@@ -38,6 +41,9 @@ properties:
- description: External I2S RX left/right channel clock
- description: External TDM clock
- description: External audio master clock
+ - description: PLL0
+ - description: PLL1
+ - description: PLL2
clock-names:
oneOf:
@@ -52,6 +58,9 @@ properties:
- const: i2srx_lrck_ext
- const: tdm_ext
- const: mclk_ext
+ - const: pll0_out
+ - const: pll1_out
+ - const: pll2_out
- items:
- const: osc
@@ -63,6 +72,9 @@ properties:
- const: i2srx_lrck_ext
- const: tdm_ext
- const: mclk_ext
+ - const: pll0_out
+ - const: pll1_out
+ - const: pll2_out
'#clock-cells':
const: 1
@@ -93,12 +105,14 @@ examples:
<&gmac1_rgmii_rxin>,
<&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
<&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
- <&tdm_ext>, <&mclk_ext>;
+ <&tdm_ext>, <&mclk_ext>,
+ <&pllclk 0>, <&pllclk 1>, <&pllclk 2>;
clock-names = "osc", "gmac1_rmii_refin",
"gmac1_rgmii_rxin",
"i2stx_bclk_ext", "i2stx_lrck_ext",
"i2srx_bclk_ext", "i2srx_lrck_ext",
- "tdm_ext", "mclk_ext";
+ "tdm_ext", "mclk_ext",
+ "pll0_out", "pll1_out", "pll2_out";
#clock-cells = <1>;
#reset-cells = <1>;
};
--
2.25.1
From: William Qiu <[email protected]>
Add documentation to describe StarFive System Controller Registers.
Reviewed-by: Emil Renner Berthing <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
Co-developed-by: Xingyu Wu <[email protected]>
Signed-off-by: Xingyu Wu <[email protected]>
Signed-off-by: William Qiu <[email protected]>
---
.../soc/starfive/starfive,jh7110-syscon.yaml | 93 +++++++++++++++++++
MAINTAINERS | 7 ++
2 files changed, 100 insertions(+)
create mode 100644 Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
diff --git a/Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml b/Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
new file mode 100644
index 000000000000..0039319e91fe
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/starfive/starfive,jh7110-syscon.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JH7110 SoC system controller
+
+maintainers:
+ - William Qiu <[email protected]>
+
+description:
+ The StarFive JH7110 SoC system controller provides register information such
+ as offset, mask and shift to configure related modules such as MMC and PCIe.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: starfive,jh7110-sys-syscon
+ - const: syscon
+ - const: simple-mfd
+ - items:
+ - enum:
+ - starfive,jh7110-aon-syscon
+ - starfive,jh7110-stg-syscon
+ - const: syscon
+
+ reg:
+ maxItems: 1
+
+ clock-controller:
+ $ref: /schemas/clock/starfive,jh7110-pll.yaml#
+ type: object
+
+ "#power-domain-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: starfive,jh7110-sys-syscon
+ then:
+ required:
+ - clock-controller
+ else:
+ properties:
+ clock-controller: false
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: starfive,jh7110-aon-syscon
+ then:
+ required:
+ - "#power-domain-cells"
+ else:
+ properties:
+ "#power-domain-cells": false
+
+additionalProperties: false
+
+examples:
+ - |
+ syscon@10240000 {
+ compatible = "starfive,jh7110-stg-syscon", "syscon";
+ reg = <0x10240000 0x1000>;
+ };
+
+ syscon@13030000 {
+ compatible = "starfive,jh7110-sys-syscon", "syscon", "simple-mfd";
+ reg = <0x13030000 0x1000>;
+
+ clock-controller {
+ compatible = "starfive,jh7110-pll";
+ clocks = <&osc>;
+ #clock-cells = <1>;
+ };
+ };
+
+ syscon@17010000 {
+ compatible = "starfive,jh7110-aon-syscon", "syscon";
+ reg = <0x17010000 0x1000>;
+ #power-domain-cells = <1>;
+ };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index aee340630eca..44b4358c3c3a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20282,6 +20282,12 @@ S: Supported
F: Documentation/devicetree/bindings/mmc/starfive*
F: drivers/mmc/host/dw_mmc-starfive.c
+STARFIVE JH7110 SYSCON
+M: William Qiu <[email protected]>
+M: Xingyu Wu <[email protected]>
+S: Supported
+F: Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
+
STARFIVE JH7110 TDM DRIVER
M: Walker Chen <[email protected]>
S: Maintained
@@ -20331,6 +20337,7 @@ STARFIVE SOC DRIVERS
M: Conor Dooley <[email protected]>
S: Maintained
T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
+F: Documentation/devicetree/bindings/soc/starfive/
F: drivers/soc/starfive/
STARFIVE TRNG DRIVER
--
2.25.1
Add PLL clocks input from PLL clocks driver in SYSCRG node.
Reviewed-by: Emil Renner Berthing <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
Signed-off-by: Xingyu Wu <[email protected]>
---
arch/riscv/boot/dts/starfive/jh7110.dtsi | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
index c49f5570625c..0067f1fd2cb1 100644
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
@@ -485,12 +485,16 @@ syscrg: clock-controller@13020000 {
<&gmac1_rgmii_rxin>,
<&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
<&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
- <&tdm_ext>, <&mclk_ext>;
+ <&tdm_ext>, <&mclk_ext>,
+ <&pllclk JH7110_PLLCLK_PLL0_OUT>,
+ <&pllclk JH7110_PLLCLK_PLL1_OUT>,
+ <&pllclk JH7110_PLLCLK_PLL2_OUT>;
clock-names = "osc", "gmac1_rmii_refin",
"gmac1_rgmii_rxin",
"i2stx_bclk_ext", "i2stx_lrck_ext",
"i2srx_bclk_ext", "i2srx_lrck_ext",
- "tdm_ext", "mclk_ext";
+ "tdm_ext", "mclk_ext",
+ "pll0_out", "pll1_out", "pll2_out";
#clock-cells = <1>;
#reset-cells = <1>;
};
--
2.25.1
From: William Qiu <[email protected]>
Add stg_syscon/sys_syscon/aon_syscon/PLL nodes for JH7110 SoC.
Reviewed-by: Emil Renner Berthing <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
Co-developed-by: Xingyu Wu <[email protected]>
Signed-off-by: Xingyu Wu <[email protected]>
Signed-off-by: William Qiu <[email protected]>
---
arch/riscv/boot/dts/starfive/jh7110.dtsi | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
index ec2e70011a73..c49f5570625c 100644
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
@@ -386,6 +386,11 @@ i2c2: i2c@10050000 {
status = "disabled";
};
+ stg_syscon: syscon@10240000 {
+ compatible = "starfive,jh7110-stg-syscon", "syscon";
+ reg = <0x0 0x10240000 0x0 0x1000>;
+ };
+
uart3: serial@12000000 {
compatible = "snps,dw-apb-uart";
reg = <0x0 0x12000000 0x0 0x10000>;
@@ -490,6 +495,17 @@ syscrg: clock-controller@13020000 {
#reset-cells = <1>;
};
+ sys_syscon: syscon@13030000 {
+ compatible = "starfive,jh7110-sys-syscon", "syscon", "simple-mfd";
+ reg = <0x0 0x13030000 0x0 0x1000>;
+
+ pllclk: clock-controller {
+ compatible = "starfive,jh7110-pll";
+ clocks = <&osc>;
+ #clock-cells = <1>;
+ };
+ };
+
sysgpio: pinctrl@13040000 {
compatible = "starfive,jh7110-sys-pinctrl";
reg = <0x0 0x13040000 0x0 0x10000>;
@@ -529,6 +545,12 @@ aoncrg: clock-controller@17000000 {
#reset-cells = <1>;
};
+ aon_syscon: syscon@17010000 {
+ compatible = "starfive,jh7110-aon-syscon", "syscon";
+ reg = <0x0 0x17010000 0x0 0x1000>;
+ #power-domain-cells = <1>;
+ };
+
aongpio: pinctrl@17020000 {
compatible = "starfive,jh7110-aon-pinctrl";
reg = <0x0 0x17020000 0x0 0x10000>;
--
2.25.1
Add driver for the StarFive JH7110 PLL clock controller
and they work by reading and setting syscon registers.
Co-developed-by: Emil Renner Berthing <[email protected]>
Signed-off-by: Emil Renner Berthing <[email protected]>
Signed-off-by: Xingyu Wu <[email protected]>
---
MAINTAINERS | 6 +
drivers/clk/starfive/Kconfig | 8 +
drivers/clk/starfive/Makefile | 1 +
.../clk/starfive/clk-starfive-jh7110-pll.c | 507 ++++++++++++++++++
4 files changed, 522 insertions(+)
create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-pll.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 44b4358c3c3a..2065829321b7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20282,6 +20282,12 @@ S: Supported
F: Documentation/devicetree/bindings/mmc/starfive*
F: drivers/mmc/host/dw_mmc-starfive.c
+STARFIVE JH7110 PLL CLOCK DRIVER
+M: Xingyu Wu <[email protected]>
+S: Supported
+F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
+F: drivers/clk/starfive/clk-starfive-jh7110-pll.c
+
STARFIVE JH7110 SYSCON
M: William Qiu <[email protected]>
M: Xingyu Wu <[email protected]>
diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index 5d2333106f13..5195f7be5213 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -21,6 +21,14 @@ config CLK_STARFIVE_JH7100_AUDIO
Say Y or M here to support the audio clocks on the StarFive JH7100
SoC.
+config CLK_STARFIVE_JH7110_PLL
+ bool "StarFive JH7110 PLL clock support"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ default ARCH_STARFIVE
+ help
+ Say yes here to support the PLL clock controller on the
+ StarFive JH7110 SoC.
+
config CLK_STARFIVE_JH7110_SYS
bool "StarFive JH7110 system clock support"
depends on ARCH_STARFIVE || COMPILE_TEST
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
index f3df7d957b1e..b48e539e52b0 100644
--- a/drivers/clk/starfive/Makefile
+++ b/drivers/clk/starfive/Makefile
@@ -4,5 +4,6 @@ obj-$(CONFIG_CLK_STARFIVE_JH71X0) += clk-starfive-jh71x0.o
obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
+obj-$(CONFIG_CLK_STARFIVE_JH7110_PLL) += clk-starfive-jh7110-pll.o
obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-pll.c b/drivers/clk/starfive/clk-starfive-jh7110-pll.c
new file mode 100644
index 000000000000..3598390e8fd0
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.c
@@ -0,0 +1,507 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive JH7110 PLL Clock Generator Driver
+ *
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
+ * Copyright (C) 2023 Emil Renner Berthing <[email protected]>
+ *
+ * This driver is about to register JH7110 PLL clock generator and support ops.
+ * The JH7110 have three PLL clock, PLL0, PLL1 and PLL2.
+ * Each PLL clocks work in integer mode or fraction mode by some dividers,
+ * and the configuration registers and dividers are set in several syscon registers.
+ * The formula for calculating frequency is:
+ * Fvco = Fref * (NI + NF) / M / Q1
+ * Fref: OSC source clock rate
+ * NI: integer frequency dividing ratio of feedback divider, set by fbdiv[11:0].
+ * NF: fractional frequency dividing ratio, set by frac[23:0]. NF = frac[23:0] / 2^24 = 0 ~ 0.999.
+ * M: frequency dividing ratio of pre-divider, set by prediv[5:0].
+ * Q1: frequency dividing ratio of post divider, set by 2^postdiv1[1:0], eg. 1, 2, 4 or 8.
+ */
+
+#include <linux/bits.h>
+#include <linux/clk-provider.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/starfive,jh7110-crg.h>
+
+/* this driver expects a 24MHz input frequency from the oscillator */
+#define JH7110_PLL_OSC_RATE 24000000UL
+
+#define JH7110_PLL0_PD_OFFSET 0x18
+#define JH7110_PLL0_DACPD_SHIFT 24
+#define JH7110_PLL0_DACPD_MASK BIT(24)
+#define JH7110_PLL0_DSMPD_SHIFT 25
+#define JH7110_PLL0_DSMPD_MASK BIT(25)
+#define JH7110_PLL0_FBDIV_OFFSET 0x1c
+#define JH7110_PLL0_FBDIV_SHIFT 0
+#define JH7110_PLL0_FBDIV_MASK GENMASK(11, 0)
+#define JH7110_PLL0_FRAC_OFFSET 0x20
+#define JH7110_PLL0_PREDIV_OFFSET 0x24
+
+#define JH7110_PLL1_PD_OFFSET 0x24
+#define JH7110_PLL1_DACPD_SHIFT 15
+#define JH7110_PLL1_DACPD_MASK BIT(15)
+#define JH7110_PLL1_DSMPD_SHIFT 16
+#define JH7110_PLL1_DSMPD_MASK BIT(16)
+#define JH7110_PLL1_FBDIV_OFFSET 0x24
+#define JH7110_PLL1_FBDIV_SHIFT 17
+#define JH7110_PLL1_FBDIV_MASK GENMASK(28, 17)
+#define JH7110_PLL1_FRAC_OFFSET 0x28
+#define JH7110_PLL1_PREDIV_OFFSET 0x2c
+
+#define JH7110_PLL2_PD_OFFSET 0x2c
+#define JH7110_PLL2_DACPD_SHIFT 15
+#define JH7110_PLL2_DACPD_MASK BIT(15)
+#define JH7110_PLL2_DSMPD_SHIFT 16
+#define JH7110_PLL2_DSMPD_MASK BIT(16)
+#define JH7110_PLL2_FBDIV_OFFSET 0x2c
+#define JH7110_PLL2_FBDIV_SHIFT 17
+#define JH7110_PLL2_FBDIV_MASK GENMASK(28, 17)
+#define JH7110_PLL2_FRAC_OFFSET 0x30
+#define JH7110_PLL2_PREDIV_OFFSET 0x34
+
+#define JH7110_PLL_FRAC_SHIFT 0
+#define JH7110_PLL_FRAC_MASK GENMASK(23, 0)
+#define JH7110_PLL_POSTDIV1_SHIFT 28
+#define JH7110_PLL_POSTDIV1_MASK GENMASK(29, 28)
+#define JH7110_PLL_PREDIV_SHIFT 0
+#define JH7110_PLL_PREDIV_MASK GENMASK(5, 0)
+
+enum jh7110_pll_mode {
+ JH7110_PLL_MODE_FRACTION,
+ JH7110_PLL_MODE_INTEGER,
+};
+
+struct jh7110_pll_preset {
+ unsigned long freq;
+ u32 frac; /* frac value should be decimals multiplied by 2^24 */
+ unsigned fbdiv : 12; /* fbdiv value should be 8 to 4095 */
+ unsigned prediv : 6;
+ unsigned postdiv1 : 2;
+ unsigned mode : 1;
+};
+
+struct jh7110_pll_info {
+ char *name;
+ const struct jh7110_pll_preset *presets;
+ unsigned int npresets;
+ struct {
+ unsigned int pd;
+ unsigned int fbdiv;
+ unsigned int frac;
+ unsigned int prediv;
+ } offsets;
+ struct {
+ u32 dacpd;
+ u32 dsmpd;
+ u32 fbdiv;
+ } masks;
+ struct {
+ char dacpd;
+ char dsmpd;
+ char fbdiv;
+ } shifts;
+};
+
+#define _JH7110_PLL(_idx, _name, _presets) \
+ [_idx] = { \
+ .name = _name, \
+ .presets = _presets, \
+ .npresets = ARRAY_SIZE(_presets), \
+ .offsets = { \
+ .pd = JH7110_PLL##_idx##_PD_OFFSET, \
+ .fbdiv = JH7110_PLL##_idx##_FBDIV_OFFSET, \
+ .frac = JH7110_PLL##_idx##_FRAC_OFFSET, \
+ .prediv = JH7110_PLL##_idx##_PREDIV_OFFSET, \
+ }, \
+ .masks = { \
+ .dacpd = JH7110_PLL##_idx##_DACPD_MASK, \
+ .dsmpd = JH7110_PLL##_idx##_DSMPD_MASK, \
+ .fbdiv = JH7110_PLL##_idx##_FBDIV_MASK, \
+ }, \
+ .shifts = { \
+ .dacpd = JH7110_PLL##_idx##_DACPD_SHIFT, \
+ .dsmpd = JH7110_PLL##_idx##_DSMPD_SHIFT, \
+ .fbdiv = JH7110_PLL##_idx##_FBDIV_SHIFT, \
+ }, \
+ }
+#define JH7110_PLL(idx, name, presets) _JH7110_PLL(idx, name, presets)
+
+struct jh7110_pll_data {
+ struct clk_hw hw;
+ unsigned int idx;
+};
+
+struct jh7110_pll_priv {
+ struct device *dev;
+ struct regmap *regmap;
+ struct jh7110_pll_data pll[JH7110_PLLCLK_END];
+};
+
+struct jh7110_pll_regvals {
+ u32 dacpd;
+ u32 dsmpd;
+ u32 fbdiv;
+ u32 frac;
+ u32 postdiv1;
+ u32 prediv;
+};
+
+/*
+ * Because the pll frequency is relatively fixed,
+ * it cannot be set arbitrarily, so it needs a specific configuration.
+ * PLL0 frequency should be multiple of 125MHz (USB frequency).
+ */
+static const struct jh7110_pll_preset jh7110_pll0_presets[] = {
+ {
+ .freq = 375000000,
+ .fbdiv = 125,
+ .prediv = 8,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ }, {
+ .freq = 500000000,
+ .fbdiv = 125,
+ .prediv = 6,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ }, {
+ .freq = 625000000,
+ .fbdiv = 625,
+ .prediv = 24,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ }, {
+ .freq = 750000000,
+ .fbdiv = 125,
+ .prediv = 4,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ }, {
+ .freq = 875000000,
+ .fbdiv = 875,
+ .prediv = 24,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ }, {
+ .freq = 1000000000,
+ .fbdiv = 125,
+ .prediv = 3,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ }, {
+ .freq = 1250000000,
+ .fbdiv = 625,
+ .prediv = 12,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ }, {
+ .freq = 1375000000,
+ .fbdiv = 1375,
+ .prediv = 24,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ }, {
+ .freq = 1500000000,
+ .fbdiv = 125,
+ .prediv = 2,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ },
+};
+
+static const struct jh7110_pll_preset jh7110_pll1_presets[] = {
+ {
+ .freq = 1066000000,
+ .fbdiv = 533,
+ .prediv = 12,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ }, {
+ .freq = 1200000000,
+ .fbdiv = 50,
+ .prediv = 1,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ }, {
+ .freq = 1400000000,
+ .fbdiv = 350,
+ .prediv = 6,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ }, {
+ .freq = 1600000000,
+ .fbdiv = 200,
+ .prediv = 3,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ },
+};
+
+static const struct jh7110_pll_preset jh7110_pll2_presets[] = {
+ {
+ .freq = 1188000000,
+ .fbdiv = 99,
+ .prediv = 2,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ }, {
+ .freq = 1228800000,
+ .fbdiv = 256,
+ .prediv = 5,
+ .postdiv1 = 0,
+ .mode = JH7110_PLL_MODE_INTEGER,
+ },
+};
+
+static const struct jh7110_pll_info jh7110_plls[JH7110_PLLCLK_END] = {
+ JH7110_PLL(JH7110_PLLCLK_PLL0_OUT, "pll0_out", jh7110_pll0_presets),
+ JH7110_PLL(JH7110_PLLCLK_PLL1_OUT, "pll1_out", jh7110_pll1_presets),
+ JH7110_PLL(JH7110_PLLCLK_PLL2_OUT, "pll2_out", jh7110_pll2_presets),
+};
+
+static struct jh7110_pll_data *jh7110_pll_data_from(struct clk_hw *hw)
+{
+ return container_of(hw, struct jh7110_pll_data, hw);
+}
+
+static struct jh7110_pll_priv *jh7110_pll_priv_from(struct jh7110_pll_data *pll)
+{
+ return container_of(pll, struct jh7110_pll_priv, pll[pll->idx]);
+}
+
+static void jh7110_pll_regvals_get(struct regmap *regmap,
+ const struct jh7110_pll_info *info,
+ struct jh7110_pll_regvals *ret)
+{
+ u32 val;
+
+ regmap_read(regmap, info->offsets.pd, &val);
+ ret->dacpd = (val & info->masks.dacpd) >> info->shifts.dacpd;
+ ret->dsmpd = (val & info->masks.dsmpd) >> info->shifts.dsmpd;
+
+ regmap_read(regmap, info->offsets.fbdiv, &val);
+ ret->fbdiv = (val & info->masks.fbdiv) >> info->shifts.fbdiv;
+
+ regmap_read(regmap, info->offsets.frac, &val);
+ ret->frac = (val & JH7110_PLL_FRAC_MASK) >> JH7110_PLL_FRAC_SHIFT;
+ ret->postdiv1 = (val & JH7110_PLL_POSTDIV1_MASK) >> JH7110_PLL_POSTDIV1_SHIFT;
+
+ regmap_read(regmap, info->offsets.prediv, &val);
+ ret->prediv = (val & JH7110_PLL_PREDIV_MASK) >> JH7110_PLL_PREDIV_SHIFT;
+}
+
+static unsigned long jh7110_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct jh7110_pll_data *pll = jh7110_pll_data_from(hw);
+ struct jh7110_pll_priv *priv = jh7110_pll_priv_from(pll);
+ struct jh7110_pll_regvals val;
+ unsigned long rate;
+
+ jh7110_pll_regvals_get(priv->regmap, &jh7110_plls[pll->idx], &val);
+
+ /*
+ * dacpd = dsmpd = 0: fraction mode
+ * dacpd = dsmpd = 1: integer mode, frac value ignored
+ *
+ * rate = parent * (fbdiv + frac/2^24) / prediv / 2^postdiv1
+ * = (parent * fbdiv + parent * frac / 2^24) / (prediv * 2^postdiv1)
+ */
+ if (val.dacpd == 0 && val.dsmpd == 0)
+ rate = parent_rate * val.frac / (1UL << 24);
+ else if (val.dacpd == 1 && val.dsmpd == 1)
+ rate = 0;
+ else
+ return 0;
+
+ rate += parent_rate * val.fbdiv;
+ rate /= val.prediv << val.postdiv1;
+
+ return rate;
+}
+
+static int jh7110_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ struct jh7110_pll_data *pll = jh7110_pll_data_from(hw);
+ const struct jh7110_pll_info *info = &jh7110_plls[pll->idx];
+ const struct jh7110_pll_preset *selected = &info->presets[0];
+ unsigned int idx;
+
+ /* if the parent rate doesn't match our expectations the presets won't work */
+ if (req->best_parent_rate != JH7110_PLL_OSC_RATE) {
+ req->rate = jh7110_pll_recalc_rate(hw, req->best_parent_rate);
+ return 0;
+ }
+
+ /* find highest rate lower or equal to the requested rate */
+ for (idx = 1; idx < info->npresets; idx++) {
+ const struct jh7110_pll_preset *val = &info->presets[idx];
+
+ if (req->rate < val->freq)
+ break;
+
+ selected = val;
+ }
+
+ req->rate = selected->freq;
+ return 0;
+}
+
+static int jh7110_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct jh7110_pll_data *pll = jh7110_pll_data_from(hw);
+ struct jh7110_pll_priv *priv = jh7110_pll_priv_from(pll);
+ const struct jh7110_pll_info *info = &jh7110_plls[pll->idx];
+ const struct jh7110_pll_preset *val;
+ unsigned int idx;
+
+ /* if the parent rate doesn't match our expectations the presets won't work */
+ if (parent_rate != JH7110_PLL_OSC_RATE)
+ return -EINVAL;
+
+ for (idx = 0, val = &info->presets[0]; idx < info->npresets; idx++, val++) {
+ if (val->freq == rate)
+ goto found;
+ }
+ return -EINVAL;
+
+found:
+ if (val->mode == JH7110_PLL_MODE_FRACTION)
+ regmap_update_bits(priv->regmap, info->offsets.frac, JH7110_PLL_FRAC_MASK,
+ val->frac << JH7110_PLL_FRAC_SHIFT);
+
+ regmap_update_bits(priv->regmap, info->offsets.pd, info->masks.dacpd,
+ (u32)val->mode << info->shifts.dacpd);
+ regmap_update_bits(priv->regmap, info->offsets.pd, info->masks.dsmpd,
+ (u32)val->mode << info->shifts.dsmpd);
+ regmap_update_bits(priv->regmap, info->offsets.prediv, JH7110_PLL_PREDIV_MASK,
+ (u32)val->prediv << JH7110_PLL_PREDIV_SHIFT);
+ regmap_update_bits(priv->regmap, info->offsets.fbdiv, info->masks.fbdiv,
+ val->fbdiv << info->shifts.fbdiv);
+ regmap_update_bits(priv->regmap, info->offsets.frac, JH7110_PLL_POSTDIV1_MASK,
+ (u32)val->postdiv1 << JH7110_PLL_POSTDIV1_SHIFT);
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int jh7110_pll_registers_read(struct seq_file *s, void *unused)
+{
+ struct jh7110_pll_data *pll = s->private;
+ struct jh7110_pll_priv *priv = jh7110_pll_priv_from(pll);
+ struct jh7110_pll_regvals val;
+
+ jh7110_pll_regvals_get(priv->regmap, &jh7110_plls[pll->idx], &val);
+
+ seq_printf(s, "fbdiv=%u\n"
+ "frac=%u\n"
+ "prediv=%u\n"
+ "postdiv1=%u\n"
+ "dacpd=%u\n"
+ "dsmpd=%u\n",
+ val.fbdiv, val.frac, val.prediv, val.postdiv1,
+ val.dacpd, val.dsmpd);
+
+ return 0;
+}
+
+static int jh7110_pll_registers_open(struct inode *inode, struct file *f)
+{
+ return single_open(f, jh7110_pll_registers_read, inode->i_private);
+}
+
+static const struct file_operations jh7110_pll_registers_ops = {
+ .owner = THIS_MODULE,
+ .open = jh7110_pll_registers_open,
+ .release = single_release,
+ .read = seq_read,
+ .llseek = seq_lseek
+};
+
+static void jh7110_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
+{
+ struct jh7110_pll_data *pll = jh7110_pll_data_from(hw);
+
+ debugfs_create_file("registers", 0400, dentry, pll,
+ &jh7110_pll_registers_ops);
+}
+#else
+#define jh7110_pll_debug_init NULL
+#endif
+
+static const struct clk_ops jh7110_pll_ops = {
+ .recalc_rate = jh7110_pll_recalc_rate,
+ .determine_rate = jh7110_pll_determine_rate,
+ .set_rate = jh7110_pll_set_rate,
+ .debug_init = jh7110_pll_debug_init,
+};
+
+static struct clk_hw *jh7110_pll_get(struct of_phandle_args *clkspec, void *data)
+{
+ struct jh7110_pll_priv *priv = data;
+ unsigned int idx = clkspec->args[0];
+
+ if (idx < JH7110_PLLCLK_END)
+ return &priv->pll[idx].hw;
+
+ return ERR_PTR(-EINVAL);
+}
+
+static int jh7110_pll_probe(struct platform_device *pdev)
+{
+ struct jh7110_pll_priv *priv;
+ unsigned int idx;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = &pdev->dev;
+ priv->regmap = syscon_node_to_regmap(priv->dev->of_node->parent);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ for (idx = 0; idx < JH7110_PLLCLK_END; idx++) {
+ struct clk_parent_data parents = {
+ .index = 0,
+ };
+ struct clk_init_data init = {
+ .name = jh7110_plls[idx].name,
+ .ops = &jh7110_pll_ops,
+ .parent_data = &parents,
+ .num_parents = 1,
+ .flags = 0,
+ };
+ struct jh7110_pll_data *pll = &priv->pll[idx];
+
+ pll->hw.init = &init;
+ pll->idx = idx;
+
+ ret = devm_clk_hw_register(&pdev->dev, &pll->hw);
+ if (ret)
+ return ret;
+ }
+
+ return devm_of_clk_add_hw_provider(&pdev->dev, jh7110_pll_get, priv);
+}
+
+static const struct of_device_id jh7110_pll_match[] = {
+ { .compatible = "starfive,jh7110-pll" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jh7110_pll_match);
+
+static struct platform_driver jh7110_pll_driver = {
+ .driver = {
+ .name = "clk-starfive-jh7110-pll",
+ .of_match_table = jh7110_pll_match,
+ },
+};
+builtin_platform_driver_probe(jh7110_pll_driver, jh7110_pll_probe);
--
2.25.1
Hey Xingyu,
On Mon, Jul 17, 2023 at 10:30:33AM +0800, Xingyu Wu wrote:
> This patch serises are to add PLL clocks driver and providers by writing
> and reading syscon registers for the StarFive JH7110 RISC-V SoC. And add
> documentation and nodes to describe StarFive System Controller(syscon)
> Registers. This patch serises are based on Linux 6.4.
>
> PLLs are high speed, low jitter frequency synthesizers in JH7110.
> Each PLL clock works in integer mode or fraction mode by some dividers,
> and the dividers are set in several syscon registers.
> The formula for calculating frequency is:
> Fvco = Fref * (NI + NF) / M / Q1
>
> The first patch adds docunmentation to describe PLL clock bindings,
> and the second patch adds documentation to decribe syscon registers.
> The patch 3 modifies the SYSCRG bindings and adds PLL clock inputs.
> The patch 4 adds driver to support PLL clocks for JH7110.
> The patch 5 modifies the system clock driver and can select the PLL clock
> source from PLL clocks driver. And the patch 6 adds the
> stg/sys/aon syscon nodes for JH7110 SoC. The last patch modifies the
> syscrg node in JH7110 dts file.
Just FYI, I have picked up the binding & clock portions of this series
and your other one adding the stg syscon. I've pushed them out here for
the test robots to have a look:
https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/log/?h=clk-starfive
If that passes, my plan is to send Stephen a PR for the lot, later this
week.
Thanks,
Conor.
On 2023/7/18 2:14, Conor Dooley wrote:
> Hey Xingyu,
>
> On Mon, Jul 17, 2023 at 10:30:33AM +0800, Xingyu Wu wrote:
>> This patch serises are to add PLL clocks driver and providers by writing
>> and reading syscon registers for the StarFive JH7110 RISC-V SoC. And add
>> documentation and nodes to describe StarFive System Controller(syscon)
>> Registers. This patch serises are based on Linux 6.4.
>>
>> PLLs are high speed, low jitter frequency synthesizers in JH7110.
>> Each PLL clock works in integer mode or fraction mode by some dividers,
>> and the dividers are set in several syscon registers.
>> The formula for calculating frequency is:
>> Fvco = Fref * (NI + NF) / M / Q1
>>
>> The first patch adds docunmentation to describe PLL clock bindings,
>> and the second patch adds documentation to decribe syscon registers.
>> The patch 3 modifies the SYSCRG bindings and adds PLL clock inputs.
>> The patch 4 adds driver to support PLL clocks for JH7110.
>> The patch 5 modifies the system clock driver and can select the PLL clock
>> source from PLL clocks driver. And the patch 6 adds the
>> stg/sys/aon syscon nodes for JH7110 SoC. The last patch modifies the
>> syscrg node in JH7110 dts file.
>
> Just FYI, I have picked up the binding & clock portions of this series
> and your other one adding the stg syscon. I've pushed them out here for
> the test robots to have a look:
> https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/log/?h=clk-starfive
>
> If that passes, my plan is to send Stephen a PR for the lot, later this
> week.
>
Great. Thank you for everything.
Best regards,
Xingyu Wu
On Mon, 17 Jul 2023 at 04:30, Xingyu Wu <[email protected]> wrote:
>
> Add bindings for the PLL clock generator on the JH7110 RISC-V SoC.
>
> Reviewed-by: Conor Dooley <[email protected]>
> Reviewed-by: Krzysztof Kozlowski <[email protected]>
Reviewed-by: Emil Renner Berthing <[email protected]>
> Signed-off-by: Xingyu Wu <[email protected]>
> ---
> .../bindings/clock/starfive,jh7110-pll.yaml | 46 +++++++++++++++++++
> .../dt-bindings/clock/starfive,jh7110-crg.h | 6 +++
> 2 files changed, 52 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
>
> diff --git a/Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml b/Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
> new file mode 100644
> index 000000000000..be8300ce86d0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
> @@ -0,0 +1,46 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/starfive,jh7110-pll.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: StarFive JH7110 PLL Clock Generator
> +
> +description:
> + These PLLs are high speed, low jitter frequency synthesizers in the JH7110.
> + Each PLL works in integer mode or fraction mode, with configuration
> + registers in the sys syscon. So the PLLs node should be a child of
> + SYS-SYSCON node.
> + The formula for calculating frequency is
> + Fvco = Fref * (NI + NF) / M / Q1
> +
> +maintainers:
> + - Xingyu Wu <[email protected]>
> +
> +properties:
> + compatible:
> + const: starfive,jh7110-pll
> +
> + clocks:
> + maxItems: 1
> + description: Main Oscillator (24 MHz)
> +
> + '#clock-cells':
> + const: 1
> + description:
> + See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
> +
> +required:
> + - compatible
> + - clocks
> + - '#clock-cells'
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + clock-controller {
> + compatible = "starfive,jh7110-pll";
> + clocks = <&osc>;
> + #clock-cells = <1>;
> + };
> diff --git a/include/dt-bindings/clock/starfive,jh7110-crg.h b/include/dt-bindings/clock/starfive,jh7110-crg.h
> index 06257bfd9ac1..3fb5e31c3be4 100644
> --- a/include/dt-bindings/clock/starfive,jh7110-crg.h
> +++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
> @@ -6,6 +6,12 @@
> #ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
> #define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
>
> +/* PLL clocks */
> +#define JH7110_PLLCLK_PLL0_OUT 0
> +#define JH7110_PLLCLK_PLL1_OUT 1
> +#define JH7110_PLLCLK_PLL2_OUT 2
> +#define JH7110_PLLCLK_END 3
> +
> /* SYSCRG clocks */
> #define JH7110_SYSCLK_CPU_ROOT 0
> #define JH7110_SYSCLK_CPU_CORE 1
> --
> 2.25.1
>
From: Conor Dooley <[email protected]>
On Mon, 17 Jul 2023 10:30:33 +0800, Xingyu Wu wrote:
> This patch serises are to add PLL clocks driver and providers by writing
> and reading syscon registers for the StarFive JH7110 RISC-V SoC. And add
> documentation and nodes to describe StarFive System Controller(syscon)
> Registers. This patch serises are based on Linux 6.4.
>
> PLLs are high speed, low jitter frequency synthesizers in JH7110.
> Each PLL clock works in integer mode or fraction mode by some dividers,
> and the dividers are set in several syscon registers.
> The formula for calculating frequency is:
> Fvco = Fref * (NI + NF) / M / Q1
>
> [...]
Applied to riscv-dt-for-next, thanks!
[6/7] riscv: dts: starfive: jh7110: Add syscon nodes
https://git.kernel.org/conor/c/3fcbcfc496f0
[7/7] riscv: dts: starfive: jh7110: Add PLL clocks source in SYSCRG node
https://git.kernel.org/conor/c/3e6670a28b00
Thanks,
Conor.