* [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC
@ 2026-10-08 12:33 Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 01/15] clk: starfive: jh7110-sys: Fix memory leak in reset controller register Changhuang Liang
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
The JHB100 SoC includes CRG (Clock and Reset Generator) for multiple
subsystems:
The JHB100 SoC is divided into multiple subsystems, and basically
each subsystem includes a CRG(Clock and Reset Generator):
- sys0crg/sys1crg/sys2crg/
- per0crg/per1crg/per2crg/per3crg/
- voutcrg
- vcecrg
- gpu0crg/gpu1crg
- cpucrg
- usbcrg
- host0crg/host1crg
- pcierpcrg
- husb0crg/husb1crg
- husbcmncrg
- husbd0crg/husbd1crg
- npucrg
In the current series, we will only add the following CRG:
- sys0crg/sys1crg/sys2crg/
- per0crg/per1crg/per2crg/per3crg/
The remaining CRG will be implemented in future series.
changes since v5:
- Remove the bindings related patch.
patch 4 (in v6):
- jh71x0_crg_probe(): report invalid parent indices with
dev_err_probe() instead of returning a bare -EINVAL, so the failing
clock name and index are visible in the log.
- Add #include <linux/property.h>.
patch 8 (in v6):
- Change the JH71X0_CLK_FRAC_MAX condition check to an else if.
patch 5/6/7/10/11/12/13 (in v6):
- Document the CLK_IS_CRITICAL and CLK_IGNORE_UNUSED policies.
v5: https://lore.kernel.org/all/20260930124317.5648-1-changhuang.liang@starfivetech.com/
v4: https://lore.kernel.org/all/20260920120044.194901-1-changhuang.liang@starfivetech.com/
v3: https://lore.kernel.org/all/20260807112923.191627-1-changhuang.liang@starfivetech.com/
v2: https://lore.kernel.org/all/20260508053632.818548-1-changhuang.liang@starfivetech.com/
v1: https://lore.kernel.org/all/20260402105523.447523-1-changhuang.liang@starfivetech.com/
Changhuang Liang (15):
clk: starfive: jh7110-sys: Fix memory leak in reset controller
register
clk: starfive: jh71x0: Move reset controller registration to jh71x0
common code
reset: starfive: jh7110: Match auxiliary device names to jh71x0 clk
driver
clk: starfive: jh71x0: Add generic CRG probe helper
clk: starfive: Add JHB100 System-0 clock generator driver
clk: starfive: Add JHB100 System-1 clock generator driver
clk: starfive: Add JHB100 System-2 clock generator driver
clk: starfive: Introduce idiv ops for inverted divider clocks
clk: starfive: Expand the storage of clock parent index
clk: starfive: Add StarFive JHB100 Peripheral-0 clock driver
clk: starfive: Add StarFive JHB100 Peripheral-1 clock driver
clk: starfive: Add StarFive JHB100 Peripheral-2 clock driver
clk: starfive: Add StarFive JHB100 Peripheral-3 clock driver
reset: starfive: jh71x0: Support discontiguous reset IDs
reset: starfive: Add StarFive JHB100 reset driver
MAINTAINERS | 13 +
drivers/clk/starfive/Kconfig | 72 +-
drivers/clk/starfive/Makefile | 8 +
.../clk/starfive/clk-starfive-jh7110-aon.c | 2 +-
.../clk/starfive/clk-starfive-jh7110-isp.c | 2 +-
.../clk/starfive/clk-starfive-jh7110-stg.c | 2 +-
.../clk/starfive/clk-starfive-jh7110-sys.c | 57 +-
.../clk/starfive/clk-starfive-jh7110-vout.c | 2 +-
drivers/clk/starfive/clk-starfive-jh7110.h | 4 -
drivers/clk/starfive/clk-starfive-jh71x0.c | 165 ++++-
drivers/clk/starfive/clk-starfive-jh71x0.h | 24 +-
.../clk/starfive/clk-starfive-jhb100-per0.c | 617 ++++++++++++++++++
.../clk/starfive/clk-starfive-jhb100-per1.c | 162 +++++
.../clk/starfive/clk-starfive-jhb100-per2.c | 182 ++++++
.../clk/starfive/clk-starfive-jhb100-per3.c | 140 ++++
.../clk/starfive/clk-starfive-jhb100-sys0.c | 156 +++++
.../clk/starfive/clk-starfive-jhb100-sys1.c | 118 ++++
.../clk/starfive/clk-starfive-jhb100-sys2.c | 135 ++++
drivers/reset/starfive/Kconfig | 9 +
drivers/reset/starfive/Makefile | 1 +
.../reset/starfive/reset-starfive-jh7110.c | 10 +-
.../reset/starfive/reset-starfive-jh71x0.c | 99 ++-
.../reset/starfive/reset-starfive-jh71x0.h | 19 +
.../reset/starfive/reset-starfive-jhb100.c | 303 +++++++++
24 files changed, 2216 insertions(+), 86 deletions(-)
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-per0.c
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-per1.c
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-per2.c
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-per3.c
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-sys0.c
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-sys1.c
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-sys2.c
create mode 100644 drivers/reset/starfive/reset-starfive-jhb100.c
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 01/15] clk: starfive: jh7110-sys: Fix memory leak in reset controller register
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 02/15] clk: starfive: jh71x0: Move reset controller registration to jh71x0 common code Changhuang Liang
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
auxiliary_device_init() returns an error before device_initialize() is
called, so the release callback never runs on this path and the rdev
allocated in jh7110_reset_controller_register() is leaked.
Free rdev when auxiliary_device_init() fails.
Fixes: edab7204afe5 ("clk: starfive: Add StarFive JH7110 system clock driver")
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
drivers/clk/starfive/clk-starfive-jh7110-sys.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-sys.c b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
index 847c0a39e5ab..1d460a03f936 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
@@ -360,8 +360,10 @@ int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
adev->id = adev_id;
ret = auxiliary_device_init(adev);
- if (ret)
+ if (ret) {
+ kfree(rdev);
return ret;
+ }
ret = auxiliary_device_add(adev);
if (ret) {
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 02/15] clk: starfive: jh71x0: Move reset controller registration to jh71x0 common code
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 01/15] clk: starfive: jh7110-sys: Fix memory leak in reset controller register Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 03/15] reset: starfive: jh7110: Match auxiliary device names to jh71x0 clk driver Changhuang Liang
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
jh7110_reset_controller_register() is only tied to the JH7110 system
clock driver by its location. Its logic is generic: allocate a
struct jh71x0_reset_adev, point it at the CRG register base and add it
as an auxiliary device for the reset driver to bind to.
Move it to clk-starfive-jh71x0.c as jh71x0_reset_controller_register()
so that the clock drivers of other StarFive SoCs can reuse it, and make
CLK_STARFIVE_JH71X0 select AUXILIARY_BUS accordingly.
The auxiliary device ID is dropped: every CRG already uses a distinct
auxiliary device name, so the ID is not needed to keep the device names
unique, and it is always 0 now.
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
drivers/clk/starfive/Kconfig | 2 +-
.../clk/starfive/clk-starfive-jh7110-aon.c | 2 +-
.../clk/starfive/clk-starfive-jh7110-isp.c | 2 +-
.../clk/starfive/clk-starfive-jh7110-stg.c | 2 +-
.../clk/starfive/clk-starfive-jh7110-sys.c | 59 +------------------
.../clk/starfive/clk-starfive-jh7110-vout.c | 2 +-
drivers/clk/starfive/clk-starfive-jh7110.h | 4 --
drivers/clk/starfive/clk-starfive-jh71x0.c | 54 +++++++++++++++++
drivers/clk/starfive/clk-starfive-jh71x0.h | 2 +
9 files changed, 62 insertions(+), 67 deletions(-)
diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index bd29358ffeec..51716655554f 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -2,6 +2,7 @@
config CLK_STARFIVE_JH71X0
bool
+ select AUXILIARY_BUS
config CLK_STARFIVE_JH7100
bool "StarFive JH7100 clock support"
@@ -32,7 +33,6 @@ config CLK_STARFIVE_JH7110_PLL
config CLK_STARFIVE_JH7110_SYS
bool "StarFive JH7110 system clock support"
depends on ARCH_STARFIVE || COMPILE_TEST
- select AUXILIARY_BUS
select CLK_STARFIVE_JH71X0
select RESET_STARFIVE_JH7110 if RESET_CONTROLLER
select CLK_STARFIVE_JH7110_PLL
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-aon.c b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
index 6f67587f4335..66f1c56a7169 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-aon.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
@@ -121,7 +121,7 @@ static int jh7110_aoncrg_probe(struct platform_device *pdev)
if (ret)
return ret;
- return jh7110_reset_controller_register(priv, "rst-aon", 1);
+ return jh71x0_reset_controller_register(priv, "rst-aon");
}
static const struct of_device_id jh7110_aoncrg_match[] = {
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-isp.c b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
index c02c8b29a123..f8222d3c81ee 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-isp.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
@@ -180,7 +180,7 @@ static int jh7110_ispcrg_probe(struct platform_device *pdev)
if (ret)
goto err_exit;
- ret = jh7110_reset_controller_register(priv, "rst-isp", 3);
+ ret = jh71x0_reset_controller_register(priv, "rst-isp");
if (ret)
goto err_exit;
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-stg.c b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
index 2a5ad0e07d1d..5ae63e18aa4f 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-stg.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
@@ -139,7 +139,7 @@ static int jh7110_stgcrg_probe(struct platform_device *pdev)
if (ret)
return ret;
- return jh7110_reset_controller_register(priv, "rst-stg", 2);
+ return jh71x0_reset_controller_register(priv, "rst-stg");
}
static const struct of_device_id jh7110_stgcrg_match[] = {
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-sys.c b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
index 1d460a03f936..6c5e9c54dfcd 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
@@ -6,15 +6,11 @@
* Copyright (C) 2022 StarFive Technology Co., Ltd.
*/
-#include <linux/auxiliary_bus.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <soc/starfive/reset-starfive-jh71x0.h>
#include <dt-bindings/clock/starfive,jh7110-crg.h>
@@ -323,59 +319,6 @@ static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
JH7110_SYSCLK_OSC),
};
-static void jh7110_reset_unregister_adev(void *_adev)
-{
- struct auxiliary_device *adev = _adev;
-
- auxiliary_device_delete(adev);
- auxiliary_device_uninit(adev);
-}
-
-static void jh7110_reset_adev_release(struct device *dev)
-{
- struct auxiliary_device *adev = to_auxiliary_dev(dev);
- struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
-
- kfree(rdev);
-}
-
-int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
- const char *adev_name,
- u32 adev_id)
-{
- struct jh71x0_reset_adev *rdev;
- struct auxiliary_device *adev;
- int ret;
-
- rdev = kzalloc_obj(*rdev);
- if (!rdev)
- return -ENOMEM;
-
- rdev->base = priv->base;
-
- adev = &rdev->adev;
- adev->name = adev_name;
- adev->dev.parent = priv->dev;
- adev->dev.release = jh7110_reset_adev_release;
- adev->id = adev_id;
-
- ret = auxiliary_device_init(adev);
- if (ret) {
- kfree(rdev);
- return ret;
- }
-
- ret = auxiliary_device_add(adev);
- if (ret) {
- auxiliary_device_uninit(adev);
- return ret;
- }
-
- return devm_add_action_or_reset(priv->dev,
- jh7110_reset_unregister_adev, adev);
-}
-EXPORT_SYMBOL_GPL(jh7110_reset_controller_register);
-
/*
* This clock notifier is called when the rate of PLL0 clock is to be changed.
* The cpu_root clock should save the current parent clock and switch its parent
@@ -525,7 +468,7 @@ static int __init jh7110_syscrg_probe(struct platform_device *pdev)
if (ret)
return ret;
- return jh7110_reset_controller_register(priv, "rst-sys", 0);
+ return jh71x0_reset_controller_register(priv, "rst-sys");
}
static const struct of_device_id jh7110_syscrg_match[] = {
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-vout.c b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
index aeba42cd3c44..14e5b8286671 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-vout.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
@@ -189,7 +189,7 @@ static int jh7110_voutcrg_probe(struct platform_device *pdev)
if (ret)
goto err_exit;
- ret = jh7110_reset_controller_register(priv, "rst-vo", 4);
+ ret = jh71x0_reset_controller_register(priv, "rst-vo");
if (ret)
goto err_exit;
diff --git a/drivers/clk/starfive/clk-starfive-jh7110.h b/drivers/clk/starfive/clk-starfive-jh7110.h
index 0659adae4d76..55374ee24d4d 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110.h
+++ b/drivers/clk/starfive/clk-starfive-jh7110.h
@@ -10,8 +10,4 @@ struct jh7110_top_sysclk {
int top_clks_num;
};
-int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
- const char *adev_name,
- u32 adev_id);
-
#endif
diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.c b/drivers/clk/starfive/clk-starfive-jh71x0.c
index 80e9157347eb..2cc71f49ddee 100644
--- a/drivers/clk/starfive/clk-starfive-jh71x0.c
+++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
@@ -5,10 +5,13 @@
* Copyright (C) 2021-2022 Emil Renner Berthing <kernel@esmil.dk>
*/
+#include <linux/auxiliary_bus.h>
#include <linux/clk-provider.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/io.h>
+#include <linux/slab.h>
+#include <soc/starfive/reset-starfive-jh71x0.h>
#include "clk-starfive-jh71x0.h"
@@ -337,3 +340,54 @@ struct clk_hw *jh71x0_clk_get(struct of_phandle_args *clkspec, void *data)
return ERR_PTR(-EINVAL);
}
EXPORT_SYMBOL_GPL(jh71x0_clk_get);
+
+static void jh71x0_reset_unregister_adev(void *_adev)
+{
+ struct auxiliary_device *adev = _adev;
+
+ auxiliary_device_delete(adev);
+ auxiliary_device_uninit(adev);
+}
+
+static void jh71x0_reset_adev_release(struct device *dev)
+{
+ struct auxiliary_device *adev = to_auxiliary_dev(dev);
+ struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
+
+ kfree(rdev);
+}
+
+int jh71x0_reset_controller_register(struct jh71x0_clk_priv *priv,
+ const char *adev_name)
+{
+ struct jh71x0_reset_adev *rdev;
+ struct auxiliary_device *adev;
+ int ret;
+
+ rdev = kzalloc_obj(*rdev);
+ if (!rdev)
+ return -ENOMEM;
+
+ rdev->base = priv->base;
+
+ adev = &rdev->adev;
+ adev->name = adev_name;
+ adev->dev.parent = priv->dev;
+ adev->dev.release = jh71x0_reset_adev_release;
+
+ ret = auxiliary_device_init(adev);
+ if (ret) {
+ kfree(rdev);
+ return ret;
+ }
+
+ ret = auxiliary_device_add(adev);
+ if (ret) {
+ auxiliary_device_uninit(adev);
+ return ret;
+ }
+
+ return devm_add_action_or_reset(priv->dev,
+ jh71x0_reset_unregister_adev, adev);
+}
+EXPORT_SYMBOL_GPL(jh71x0_reset_controller_register);
diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.h b/drivers/clk/starfive/clk-starfive-jh71x0.h
index 9d5dec1d5cd1..322a05157faf 100644
--- a/drivers/clk/starfive/clk-starfive-jh71x0.h
+++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
@@ -123,5 +123,7 @@ struct jh71x0_clk_priv {
const struct clk_ops *starfive_jh71x0_clk_ops(u32 max);
struct clk_hw *jh71x0_clk_get(struct of_phandle_args *clkspec, void *data);
+int jh71x0_reset_controller_register(struct jh71x0_clk_priv *priv,
+ const char *adev_name);
#endif
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 03/15] reset: starfive: jh7110: Match auxiliary device names to jh71x0 clk driver
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 01/15] clk: starfive: jh7110-sys: Fix memory leak in reset controller register Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 02/15] clk: starfive: jh71x0: Move reset controller registration to jh71x0 common code Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 04/15] clk: starfive: jh71x0: Add generic CRG probe helper Changhuang Liang
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
The JH7110 reset driver binds to auxiliary devices created by the
StarFive clock driver. As part of moving the reset controller registration
helper into clk-starfive-jh71x0.c so that it can be shared by other
StarFive SoCs, the auxiliary device names are now prefixed with
"clk_starfive_jh71x0" instead of "clk_starfive_jh7110_sys".
Update the auxiliary_device_id table accordingly, otherwise the reset
driver fails to probe.
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
drivers/reset/starfive/reset-starfive-jh7110.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/reset/starfive/reset-starfive-jh7110.c b/drivers/reset/starfive/reset-starfive-jh7110.c
index 29a43f0f2ad6..c936e61156a2 100644
--- a/drivers/reset/starfive/reset-starfive-jh7110.c
+++ b/drivers/reset/starfive/reset-starfive-jh7110.c
@@ -69,23 +69,23 @@ static int jh7110_reset_probe(struct auxiliary_device *adev,
static const struct auxiliary_device_id jh7110_reset_ids[] = {
{
- .name = "clk_starfive_jh7110_sys.rst-sys",
+ .name = "clk_starfive_jh71x0.rst-sys",
.driver_data = (kernel_ulong_t)&jh7110_sys_info,
},
{
- .name = "clk_starfive_jh7110_sys.rst-aon",
+ .name = "clk_starfive_jh71x0.rst-aon",
.driver_data = (kernel_ulong_t)&jh7110_aon_info,
},
{
- .name = "clk_starfive_jh7110_sys.rst-stg",
+ .name = "clk_starfive_jh71x0.rst-stg",
.driver_data = (kernel_ulong_t)&jh7110_stg_info,
},
{
- .name = "clk_starfive_jh7110_sys.rst-isp",
+ .name = "clk_starfive_jh71x0.rst-isp",
.driver_data = (kernel_ulong_t)&jh7110_isp_info,
},
{
- .name = "clk_starfive_jh7110_sys.rst-vo",
+ .name = "clk_starfive_jh71x0.rst-vo",
.driver_data = (kernel_ulong_t)&jh7110_vout_info,
},
{ /* sentinel */ }
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 04/15] clk: starfive: jh71x0: Add generic CRG probe helper
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
` (2 preceding siblings ...)
2026-10-08 12:33 ` [PATCH v6 03/15] reset: starfive: jh7110: Match auxiliary device names to jh71x0 clk driver Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 05/15] clk: starfive: Add JHB100 System-0 clock generator driver Changhuang Liang
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
The StarFive JHB100 SoC has several clock and reset generators (CRGs)
which share the same probe flow: map the registers, register all the
clocks described by a table, add the clock provider and register the
auxiliary reset device.
Add jh71x0_crg_probe() together with struct jh71x0_crg_domain_info so
that each CRG driver only needs to provide its clock table, external
clock names and reset auxiliary device name. The reset auxiliary device
is registered with jh71x0_reset_controller_register().
The clock index space of these CRGs is sparse, so also make
jh71x0_clk_get() reject indexes that were never registered when the
domain info is available.
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
drivers/clk/starfive/clk-starfive-jh71x0.c | 98 +++++++++++++++++++++-
drivers/clk/starfive/clk-starfive-jh71x0.h | 12 +++
2 files changed, 107 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.c b/drivers/clk/starfive/clk-starfive-jh71x0.c
index 2cc71f49ddee..c5ee82db3c92 100644
--- a/drivers/clk/starfive/clk-starfive-jh71x0.c
+++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
@@ -10,6 +10,8 @@
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
#include <linux/slab.h>
#include <soc/starfive/reset-starfive-jh71x0.h>
@@ -334,10 +336,14 @@ struct clk_hw *jh71x0_clk_get(struct of_phandle_args *clkspec, void *data)
struct jh71x0_clk_priv *priv = data;
unsigned int idx = clkspec->args[0];
- if (idx < priv->num_reg)
- return &priv->reg[idx].hw;
+ if (idx >= priv->num_reg)
+ return ERR_PTR(-EINVAL);
- return ERR_PTR(-EINVAL);
+ /* Index space is sparse: reject holes that were never registered. */
+ if (priv->info && !priv->info->clk_data[idx].name)
+ return ERR_PTR(-ENOENT);
+
+ return &priv->reg[idx].hw;
}
EXPORT_SYMBOL_GPL(jh71x0_clk_get);
@@ -391,3 +397,89 @@ int jh71x0_reset_controller_register(struct jh71x0_clk_priv *priv,
jh71x0_reset_unregister_adev, adev);
}
EXPORT_SYMBOL_GPL(jh71x0_reset_controller_register);
+
+int jh71x0_crg_probe(struct platform_device *pdev)
+{
+ const struct jh71x0_crg_domain_info *info;
+ struct jh71x0_clk_priv *priv;
+ unsigned int idx;
+ int ret;
+
+ info = device_get_match_data(&pdev->dev);
+ if (!info)
+ return -ENODEV;
+
+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, reg, info->num_clk),
+ GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ spin_lock_init(&priv->rmw_lock);
+ priv->info = info;
+ priv->num_reg = info->num_clk;
+ priv->dev = &pdev->dev;
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+ if (info->power_domain) {
+ ret = devm_pm_runtime_enable(priv->dev);
+ if (ret)
+ return dev_err_probe(priv->dev, ret,
+ "failed to enable runtime PM\n");
+ }
+
+ for (idx = 0; idx < info->num_clk; idx++) {
+ u32 max = info->clk_data[idx].max;
+ struct clk_parent_data parents[4] = {};
+ struct clk_init_data init = {
+ .name = info->clk_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 = info->clk_data[idx].flags,
+ };
+ struct jh71x0_clk *clk = &priv->reg[idx];
+ unsigned int i;
+
+ if (!init.name)
+ continue;
+
+ if (init.num_parents > ARRAY_SIZE(parents))
+ return dev_err_probe(priv->dev, -EINVAL,
+ "clock %s: too many parents (%u > %zu)\n",
+ init.name, init.num_parents, ARRAY_SIZE(parents));
+
+ for (i = 0; i < init.num_parents; i++) {
+ unsigned int pidx = info->clk_data[idx].parents[i];
+
+ if (pidx < info->num_clk) {
+ parents[i].hw = &priv->reg[pidx].hw;
+ } else {
+ if (pidx - info->num_clk >= info->num_ext_clk)
+ return dev_err_probe(priv->dev, -EINVAL,
+ "clock %s: invalid parent index %u\n",
+ init.name, pidx);
+
+ parents[i].fw_name = info->ext_clk[pidx - info->num_clk];
+ }
+ }
+
+ 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 dev_err_probe(priv->dev, ret, "Failed to register clock %s\n",
+ init.name);
+ }
+
+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh71x0_clk_get, priv);
+ if (ret)
+ return ret;
+
+ return jh71x0_reset_controller_register(priv, info->rst_name);
+}
+EXPORT_SYMBOL_GPL(jh71x0_crg_probe);
diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.h b/drivers/clk/starfive/clk-starfive-jh71x0.h
index 322a05157faf..2a1f0fb4cbb1 100644
--- a/drivers/clk/starfive/clk-starfive-jh71x0.h
+++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
@@ -5,6 +5,7 @@
#include <linux/bits.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/spinlock.h>
/* register fields */
@@ -109,6 +110,15 @@ struct jh71x0_clk {
unsigned int max_div;
};
+struct jh71x0_crg_domain_info {
+ const struct jh71x0_clk_data *clk_data;
+ unsigned int num_clk;
+ const char * const *ext_clk;
+ unsigned int num_ext_clk;
+ const char *rst_name;
+ bool power_domain;
+};
+
struct jh71x0_clk_priv {
/* protect clk enable and set rate/parent from happening at the same time */
spinlock_t rmw_lock;
@@ -116,6 +126,7 @@ struct jh71x0_clk_priv {
void __iomem *base;
struct clk *original_clk;
struct notifier_block pll_clk_nb;
+ const struct jh71x0_crg_domain_info *info;
struct clk_hw *pll[3];
unsigned int num_reg;
struct jh71x0_clk reg[] __counted_by(num_reg);
@@ -125,5 +136,6 @@ const struct clk_ops *starfive_jh71x0_clk_ops(u32 max);
struct clk_hw *jh71x0_clk_get(struct of_phandle_args *clkspec, void *data);
int jh71x0_reset_controller_register(struct jh71x0_clk_priv *priv,
const char *adev_name);
+int jh71x0_crg_probe(struct platform_device *pdev);
#endif
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 05/15] clk: starfive: Add JHB100 System-0 clock generator driver
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
` (3 preceding siblings ...)
2026-10-08 12:33 ` [PATCH v6 04/15] clk: starfive: jh71x0: Add generic CRG probe helper Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 06/15] clk: starfive: Add JHB100 System-1 " Changhuang Liang
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
Add support for JHB100 System-0 clock generator (SYS0CRG).
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
MAINTAINERS | 7 +
drivers/clk/starfive/Kconfig | 10 ++
drivers/clk/starfive/Makefile | 2 +
.../clk/starfive/clk-starfive-jhb100-sys0.c | 156 ++++++++++++++++++
4 files changed, 175 insertions(+)
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-sys0.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 155165267892..fcba280781b4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26633,6 +26633,13 @@ F: Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml
F: drivers/phy/starfive/phy-jh7110-pcie.c
F: drivers/phy/starfive/phy-jh7110-usb.c
+STARFIVE JHB100 CLOCK DRIVERS
+M: Changhuang Liang <changhuang.liang@starfivetech.com>
+S: Supported
+F: Documentation/devicetree/bindings/clock/starfive,jhb1*.yaml
+F: drivers/clk/starfive/clk-starfive-jhb1*
+F: include/dt-bindings/clock/starfive,jhb1*.h
+
STARFIVE JHB100 DEVICETREES
M: Changhuang Liang <changhuang.liang@starfivetech.com>
L: linux-riscv@lists.infradead.org
diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index 51716655554f..cd5b7754403e 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -72,3 +72,13 @@ config CLK_STARFIVE_JH7110_VOUT
help
Say yes here to support the Video-Output clock controller
on the StarFive JH7110 SoC.
+
+config CLK_STARFIVE_JHB100_SYS0
+ bool "StarFive JHB100 system-0 clock support"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ select CLK_STARFIVE_JH71X0
+ select RESET_STARFIVE_JHB100 if RESET_CONTROLLER
+ default ARCH_STARFIVE
+ help
+ Say yes here to support the system-0 clock controller on the
+ StarFive JHB100 SoC.
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
index 199ac0f37a2f..d2ba83d7d02c 100644
--- a/drivers/clk/starfive/Makefile
+++ b/drivers/clk/starfive/Makefile
@@ -10,3 +10,5 @@ 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
+
+obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS0) += clk-starfive-jhb100-sys0.o
diff --git a/drivers/clk/starfive/clk-starfive-jhb100-sys0.c b/drivers/clk/starfive/clk-starfive-jhb100-sys0.c
new file mode 100644
index 000000000000..edab54f228ad
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jhb100-sys0.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive JHB100 System-0 Clock Driver
+ *
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ *
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#include <dt-bindings/clock/starfive,jhb100-crg.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include "clk-starfive-jh71x0.h"
+
+#define JHB100_SYS0CLK_NUM_CLKS (JHB100_SYS0CLK_GPU1_NCNOC_INIT + 1)
+
+/* external clocks */
+#define JHB100_SYS0CLK_OSC (JHB100_SYS0CLK_NUM_CLKS + 0)
+#define JHB100_SYS0CLK_PLL0 (JHB100_SYS0CLK_NUM_CLKS + 1)
+#define JHB100_SYS0CLK_PLL1 (JHB100_SYS0CLK_NUM_CLKS + 2)
+#define JHB100_SYS0CLK_PLL2 (JHB100_SYS0CLK_NUM_CLKS + 3)
+
+static const char * const jhb100_sys0_ext_clk[] = {
+ "osc",
+ "pll0",
+ "pll1",
+ "pll2",
+};
+
+/*
+ * Regarding the CLK_IS_CRITICAL flag:
+ * Clocks flagged CLK_IS_CRITICAL feed logic that has to keep running whether
+ * or not a consumer holds them, such as the bus interconnect and always-on
+ * blocks. Gating them hangs the system, so they must never be disabled.
+ */
+static const struct jh71x0_clk_data jhb100_sys0crg_clk_data[] = {
+ /* bmcpcierp */
+ JH71X0__DIV(JHB100_SYS0CLK_BMCPCIERP_NCNOC_MAIN, "bmcpcierp_ncnoc_main", 6,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0__DIV(JHB100_SYS0CLK_BMCPCIERP_NCNOC_CFG, "bmcpcierp_ncnoc_cfg", 12,
+ JHB100_SYS0CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS0CLK_PCIE_REF_CML, "pcie_ref_cml", 24,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0_GATE(JHB100_SYS0CLK_BMCPCIERP_NCNOC_DATA_INIT, "bmcpcierp_ncnoc_data_init",
+ CLK_IS_CRITICAL, JHB100_SYS0CLK_BMCPCIERP_NCNOC_MAIN),
+ JH71X0_GATE(JHB100_SYS0CLK_BMCPCIERP_NCNOC_CFG_INIT, "bmcpcierp_ncnoc_cfg_init",
+ CLK_IS_CRITICAL, JHB100_SYS0CLK_BMCPCIERP_NCNOC_CFG),
+ JH71X0_GATE(JHB100_SYS0CLK_BMCPCIERP_NCNOC_TARG, "bmcpcierp_ncnoc_targ",
+ CLK_IS_CRITICAL, JHB100_SYS0CLK_BMCPCIERP_NCNOC_MAIN),
+ JH71X0_GATE(JHB100_SYS0CLK_BMCPCIERP_PCU, "bmcpcierp_pcu",
+ CLK_IS_CRITICAL, JHB100_SYS0CLK_OSC),
+ /* hostss0 */
+ JH71X0__DIV(JHB100_SYS0CLK_HOSTSS0_NCNOC_CFG, "hostss0_ncnoc_cfg", 12,
+ JHB100_SYS0CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS0CLK_HOSTSS0_NCNOC_DATA, "hostss0_ncnoc_data", 6,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0__DIV(JHB100_SYS0CLK_HOSTSS0_PHY_SCAN_400, "hostss0_phy_scan_400", 6,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0__DIV(JHB100_SYS0CLK_GPIO_ESPI0_EXT, "gpio_espi0_ext", 14,
+ JHB100_SYS0CLK_PLL2),
+ /* bmcusb */
+ JH71X0__DIV(JHB100_SYS0CLK_BMCUSB_NCNOC_INIT, "bmcusb_ncnoc_init", 6,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0__DIV(JHB100_SYS0CLK_BMCUSB_NCNOC_TARG, "bmcusb_ncnoc_targ", 6,
+ JHB100_SYS0CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS0CLK_BMCUSB_SCANCLK, "bmcusb_scanclk", 5,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0_GATE(JHB100_SYS0CLK_BMCUSB_480M_SCANCLK, "bmcusb_480m_scanclk",
+ CLK_IS_CRITICAL, JHB100_SYS0CLK_BMCUSB_SCANCLK),
+ /* vce */
+ JH71X0__DIV(JHB100_SYS0CLK_VCE_NCNOC_INIT, "vce_ncnoc_init", 10,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0__DIV(JHB100_SYS0CLK_VCE_NCNOC_TARG, "vce_ncnoc_targ", 12,
+ JHB100_SYS0CLK_PLL1),
+ /* bmcperiph2 */
+ JH71X0__DIV(JHB100_SYS0CLK_BMCPER2_NCNOC_INIT, "bmcper2_ncnoc_init", 6,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0__DIV(JHB100_SYS0CLK_BMCPER2_NCNOC_TARG, "bmcper2_ncnoc_targ", 12,
+ JHB100_SYS0CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS0CLK_BMCPER2_CFG_400, "bmcper2_cfg_400", 8,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0__DIV(JHB100_SYS0CLK_BMCPER2_CFG_125, "bmcper2_cfg_125", 10,
+ JHB100_SYS0CLK_PLL1),
+ /* hostss1 */
+ JH71X0__DIV(JHB100_SYS0CLK_HOSTSS1_NCNOC_DATA, "hostss1_ncnoc_data", 6,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0__DIV(JHB100_SYS0CLK_HOSTSS1_PHY_SCAN_400, "hostss1_phy_scan_400", 6,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0_GATE(JHB100_SYS0CLK_HOSTSS1_PHY_SCAN_400_ICG_BUF,
+ "hostss1_phy_scan_400_icg_buf", CLK_IS_CRITICAL,
+ JHB100_SYS0CLK_HOSTSS1_PHY_SCAN_400),
+ /* npu */
+ JH71X0__DIV(JHB100_SYS0CLK_NPU_NCNOC_INIT, "npu_ncnoc_init", 6,
+ JHB100_SYS0CLK_PLL0),
+ /* vout */
+ JH71X0__DIV(JHB100_SYS0CLK_VOUT_NCNOC_INIT, "vout_ncnoc_init", 6,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0__DIV(JHB100_SYS0CLK_VOUT_AUX, "vout_aux", 150,
+ JHB100_SYS0CLK_PLL0),
+ /* bmcperiph3 */
+ JH71X0__DIV(JHB100_SYS0CLK_BMCPER3_NCNOC_INIT, "bmcper3_ncnoc_init", 6,
+ JHB100_SYS0CLK_PLL0),
+ /* hostusb */
+ JH71X0__DIV(JHB100_SYS0CLK_HOSTUSB_NCNOC_INIT, "hostusb_ncnoc_init", 6,
+ JHB100_SYS0CLK_PLL0),
+ /* hostusbcmn */
+ JH71X0__DIV(JHB100_SYS0CLK_HOSTUSBCMN_CFG_480, "hostusbcmn_cfg_480", 5,
+ JHB100_SYS0CLK_PLL0),
+ /* bmcperiph1 */
+ JH71X0__DIV(JHB100_SYS0CLK_BMCPER1_NCNOC_INIT, "bmcper1_ncnoc_init", 6,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0__DIV(JHB100_SYS0CLK_BMCPER1_CFG_800, "bmcper1_cfg_800", 4,
+ JHB100_SYS0CLK_PLL0),
+ /* bmcperiph0 */
+ JH71X0__DIV(JHB100_SYS0CLK_BMCPER0_NCNOC_INIT, "bmcper0_ncnoc_init", 6,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0__DIV(JHB100_SYS0CLK_BMCPER0_CFG_400, "bmcper0_cfg_400", 8,
+ JHB100_SYS0CLK_PLL0),
+ JH71X0__DIV(JHB100_SYS0CLK_BMCPER0_CFG_800, "bmcper0_cfg_800", 8,
+ JHB100_SYS0CLK_PLL0),
+ /* gpu0 */
+ JH71X0__DIV(JHB100_SYS0CLK_GPU0_NCNOC_INIT, "gpu0_ncnoc_init", 10,
+ JHB100_SYS0CLK_PLL0),
+ /* gpu1 */
+ JH71X0__DIV(JHB100_SYS0CLK_GPU1_NCNOC_INIT, "gpu1_ncnoc_init", 10,
+ JHB100_SYS0CLK_PLL0),
+};
+
+static const struct jh71x0_crg_domain_info jhb100_sys0crg_info = {
+ .clk_data = jhb100_sys0crg_clk_data,
+ .num_clk = ARRAY_SIZE(jhb100_sys0crg_clk_data),
+ .ext_clk = jhb100_sys0_ext_clk,
+ .num_ext_clk = ARRAY_SIZE(jhb100_sys0_ext_clk),
+ .rst_name = "jhb100-r-sys0",
+ .power_domain = false,
+};
+
+static const struct of_device_id jhb100_sys0crg_match[] = {
+ {
+ .compatible = "starfive,jhb100-sys0crg",
+ .data = &jhb100_sys0crg_info,
+ },
+ { /* sentinel */ }
+};
+
+static struct platform_driver jhb100_sys0crg_driver = {
+ .probe = jh71x0_crg_probe,
+ .driver = {
+ .name = "clk-starfive-jhb100-sys0",
+ .of_match_table = jhb100_sys0crg_match,
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver(jhb100_sys0crg_driver);
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 06/15] clk: starfive: Add JHB100 System-1 clock generator driver
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
` (4 preceding siblings ...)
2026-10-08 12:33 ` [PATCH v6 05/15] clk: starfive: Add JHB100 System-0 clock generator driver Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 07/15] clk: starfive: Add JHB100 System-2 " Changhuang Liang
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
Add support for JHB100 System-1 clock generator (SYS1CRG).
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
drivers/clk/starfive/Kconfig | 10 ++
drivers/clk/starfive/Makefile | 1 +
.../clk/starfive/clk-starfive-jhb100-sys1.c | 118 ++++++++++++++++++
3 files changed, 129 insertions(+)
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-sys1.c
diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index cd5b7754403e..11da8bcc4046 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -82,3 +82,13 @@ config CLK_STARFIVE_JHB100_SYS0
help
Say yes here to support the system-0 clock controller on the
StarFive JHB100 SoC.
+
+config CLK_STARFIVE_JHB100_SYS1
+ bool "StarFive JHB100 system-1 clock support"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ select CLK_STARFIVE_JH71X0
+ select RESET_STARFIVE_JHB100 if RESET_CONTROLLER
+ default ARCH_STARFIVE
+ help
+ Say yes here to support the system-1 clock controller on the
+ StarFive JHB100 SoC.
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
index d2ba83d7d02c..0061550e0f7e 100644
--- a/drivers/clk/starfive/Makefile
+++ b/drivers/clk/starfive/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP) += clk-starfive-jh7110-isp.o
obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS0) += clk-starfive-jhb100-sys0.o
+obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS1) += clk-starfive-jhb100-sys1.o
diff --git a/drivers/clk/starfive/clk-starfive-jhb100-sys1.c b/drivers/clk/starfive/clk-starfive-jhb100-sys1.c
new file mode 100644
index 000000000000..db37b243db18
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jhb100-sys1.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive JHB100 System-1 Clock Driver
+ *
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ *
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#include <dt-bindings/clock/starfive,jhb100-crg.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include "clk-starfive-jh71x0.h"
+
+#define JHB100_SYS1CLK_NUM_CLKS (JHB100_SYS1CLK_BMCPER3_CFG_125 + 1)
+
+/* external clocks */
+#define JHB100_SYS1CLK_OSC (JHB100_SYS1CLK_NUM_CLKS + 0)
+#define JHB100_SYS1CLK_PLL0 (JHB100_SYS1CLK_NUM_CLKS + 1)
+#define JHB100_SYS1CLK_PLL1 (JHB100_SYS1CLK_NUM_CLKS + 2)
+#define JHB100_SYS1CLK_PLL2 (JHB100_SYS1CLK_NUM_CLKS + 3)
+#define JHB100_SYS1CLK_PLL4 (JHB100_SYS1CLK_NUM_CLKS + 4)
+#define JHB100_SYS1CLK_PLL5 (JHB100_SYS1CLK_NUM_CLKS + 5)
+#define JHB100_SYS1CLK_NPU_NCNOC_INIT (JHB100_SYS1CLK_NUM_CLKS + 6)
+
+static const char * const jhb100_sys1_ext_clk[] = {
+ "osc",
+ "pll0",
+ "pll1",
+ "pll2",
+ "pll4",
+ "pll5",
+ "npu_ncnoc_init",
+};
+
+/*
+ * Regarding the CLK_IS_CRITICAL flag:
+ * Clocks flagged CLK_IS_CRITICAL feed logic that has to keep running whether
+ * or not a consumer holds them, such as the bus interconnect and always-on
+ * blocks. Gating them hangs the system, so they must never be disabled.
+ *
+ * Regarding the CLK_IGNORE_UNUSED flag:
+ * Clocks flagged CLK_IGNORE_UNUSED are not consumed by any driver. The flag
+ * keeps them in their hardware default state (enabled) instead of letting
+ * the clock framework gate them once it disables unused clocks. If this
+ * flag needs to be removed later, it must be ensured that these clocks will
+ * not be disabled even if they are not consumed.
+ */
+static const struct jh71x0_clk_data jhb100_sys1crg_clk_data[] = {
+ /* root */
+ JH71X0__DIV(JHB100_SYS1CLK_APB_MAIN_SYS1, "apb_main_sys1", 12,
+ JHB100_SYS1CLK_PLL1),
+ /* sensor */
+ JH71X0_GATE(JHB100_SYS1CLK_APB_SENSOR_ICG_BUF, "apb_sensor_icg_buf",
+ CLK_IS_CRITICAL, JHB100_SYS1CLK_APB_MAIN_SYS1),
+ /* hostss1 */
+ JH71X0__DIV(JHB100_SYS1CLK_GPIO_ESPI1_EXT, "gpio_espi1_ext", 14,
+ JHB100_SYS1CLK_PLL2),
+ JH71X0__DIV(JHB100_SYS1CLK_HOSTSS1_NCNOC_CFG, "hostss1_ncnoc_cfg", 12,
+ JHB100_SYS1CLK_PLL1),
+ JH71X0_GATE(JHB100_SYS1CLK_HOSTSS1_PHY_SCAN_1000_ICG_BUF,
+ "hostss1_phy_scan_1000_icg_buf", CLK_IS_CRITICAL,
+ JHB100_SYS1CLK_PLL1),
+ /* npu */
+ JH71X0__DIV(JHB100_SYS1CLK_NPU_NCNOC_CFG, "npu_ncnoc_cfg", 6,
+ JHB100_SYS1CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS1CLK_NPU_CORE_DIV, "npu_core_div", 10,
+ JHB100_SYS1CLK_PLL0),
+ JH71X0_GATE(JHB100_SYS1CLK_DOM_NPU_CORE_CLK, "dom_npu_core_clk",
+ CLK_IS_CRITICAL, JHB100_SYS1CLK_NPU_CORE_DIV),
+ JH71X0_GATE(JHB100_SYS1CLK_DOM_NPU_BUS_CLK, "dom_npu_bus_clk",
+ CLK_IS_CRITICAL, JHB100_SYS1CLK_NPU_NCNOC_INIT),
+ JH71X0_GATE(JHB100_SYS1CLK_DOM_NPU_INIT_CLK, "dom_npu_init_clk",
+ CLK_IS_CRITICAL, JHB100_SYS1CLK_NPU_NCNOC_CFG),
+ JH71X0_GATE(JHB100_SYS1CLK_DOM_NPU_OSC_CLK, "dom_npu_osc_clk",
+ CLK_IS_CRITICAL, JHB100_SYS1CLK_OSC),
+ /* vout */
+ JH71X0__DIV(JHB100_SYS1CLK_VOUT_NCNOC_TARG, "vout_ncnoc_targ", 12,
+ JHB100_SYS1CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS1CLK_VOUT_PIX0, "vout_pix0", 4,
+ JHB100_SYS1CLK_PLL4),
+ JH71X0__DIV(JHB100_SYS1CLK_VOUT_PIX1, "vout_pix1", 4,
+ JHB100_SYS1CLK_PLL5),
+ /* bmcperiph3 */
+ JH71X0__DIV(JHB100_SYS1CLK_BMCPER3_NCNOC_TARG, "bmcper3_ncnoc_targ", 12,
+ JHB100_SYS1CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS1CLK_BMCPER3_CFG_125, "bmcper3_cfg_125", 10,
+ JHB100_SYS1CLK_PLL1),
+};
+
+static const struct jh71x0_crg_domain_info jhb100_sys1crg_info = {
+ .clk_data = jhb100_sys1crg_clk_data,
+ .num_clk = ARRAY_SIZE(jhb100_sys1crg_clk_data),
+ .ext_clk = jhb100_sys1_ext_clk,
+ .num_ext_clk = ARRAY_SIZE(jhb100_sys1_ext_clk),
+ .rst_name = "jhb100-r-sys1",
+ .power_domain = false,
+};
+
+static const struct of_device_id jhb100_sys1crg_match[] = {
+ {
+ .compatible = "starfive,jhb100-sys1crg",
+ .data = &jhb100_sys1crg_info,
+ },
+ { /* sentinel */ }
+};
+
+static struct platform_driver jhb100_sys1crg_driver = {
+ .probe = jh71x0_crg_probe,
+ .driver = {
+ .name = "clk-starfive-jhb100-sys1",
+ .of_match_table = jhb100_sys1crg_match,
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver(jhb100_sys1crg_driver);
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 07/15] clk: starfive: Add JHB100 System-2 clock generator driver
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
` (5 preceding siblings ...)
2026-10-08 12:33 ` [PATCH v6 06/15] clk: starfive: Add JHB100 System-1 " Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 08/15] clk: starfive: Introduce idiv ops for inverted divider clocks Changhuang Liang
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
Add support for JHB100 System-2 clock generator (SYS2CRG).
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
drivers/clk/starfive/Kconfig | 10 ++
drivers/clk/starfive/Makefile | 1 +
.../clk/starfive/clk-starfive-jhb100-sys2.c | 135 ++++++++++++++++++
3 files changed, 146 insertions(+)
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-sys2.c
diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index 11da8bcc4046..cfaac934a8e0 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -92,3 +92,13 @@ config CLK_STARFIVE_JHB100_SYS1
help
Say yes here to support the system-1 clock controller on the
StarFive JHB100 SoC.
+
+config CLK_STARFIVE_JHB100_SYS2
+ bool "StarFive JHB100 system-2 clock support"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ select CLK_STARFIVE_JH71X0
+ select RESET_STARFIVE_JHB100 if RESET_CONTROLLER
+ default ARCH_STARFIVE
+ help
+ Say yes here to support the system-2 clock controller on the
+ StarFive JHB100 SoC.
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
index 0061550e0f7e..29cdef20575e 100644
--- a/drivers/clk/starfive/Makefile
+++ b/drivers/clk/starfive/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS0) += clk-starfive-jhb100-sys0.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS1) += clk-starfive-jhb100-sys1.o
+obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS2) += clk-starfive-jhb100-sys2.o
diff --git a/drivers/clk/starfive/clk-starfive-jhb100-sys2.c b/drivers/clk/starfive/clk-starfive-jhb100-sys2.c
new file mode 100644
index 000000000000..405f45a3042a
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jhb100-sys2.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive JHB100 System-2 Clock Driver
+ *
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ *
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#include <dt-bindings/clock/starfive,jhb100-crg.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include "clk-starfive-jh71x0.h"
+
+#define JHB100_SYS2CLK_NUM_CLKS (JHB100_SYS2CLK_MAIN_ICG_EN_JTAG1 + 1)
+
+/* external clocks */
+#define JHB100_SYS2CLK_OSC (JHB100_SYS2CLK_NUM_CLKS + 0)
+#define JHB100_SYS2CLK_PLL1 (JHB100_SYS2CLK_NUM_CLKS + 1)
+#define JHB100_SYS2CLK_GPU0_NCNOC_INIT (JHB100_SYS2CLK_NUM_CLKS + 2)
+#define JHB100_SYS2CLK_GPU1_NCNOC_INIT (JHB100_SYS2CLK_NUM_CLKS + 3)
+
+static const char * const jhb100_sys2_ext_clk[] = {
+ "osc",
+ "pll1",
+ "gpu0_ncnoc_init",
+ "gpu1_ncnoc_init",
+};
+
+/*
+ * Regarding the CLK_IS_CRITICAL flag:
+ * Clocks flagged CLK_IS_CRITICAL feed logic that has to keep running whether
+ * or not a consumer holds them, such as the bus interconnect and always-on
+ * blocks. Gating them hangs the system, so they must never be disabled.
+ */
+static const struct jh71x0_clk_data jhb100_sys2crg_clk_data[] = {
+ /* jtag mst*/
+ JH71X0__DIV(JHB100_SYS2CLK_JTAGM0_HCLK, "jtagm0_hclk", 6,
+ JHB100_SYS2CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS2CLK_JTAGM1_HCLK, "jtagm1_hclk", 6,
+ JHB100_SYS2CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS2CLK_JTAGM0_ATPG, "jtagm0_atpg", 12,
+ JHB100_SYS2CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS2CLK_JTAGM1_ATPG, "jtagm1_atpg", 12,
+ JHB100_SYS2CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS2CLK_JTAGM0_ATPG_TCLOCK, "jtagm0_atpg_tclock", 2,
+ JHB100_SYS2CLK_JTAGM0_ATPG),
+ JH71X0__DIV(JHB100_SYS2CLK_JTAGM1_ATPG_TCLOCK, "jtagm1_atpg_tclock", 2,
+ JHB100_SYS2CLK_JTAGM1_ATPG),
+ JH71X0_GATE(JHB100_SYS2CLK_JTAG0_MST_WRAP_HCLK, "jtag0_mst_wrap_hclk",
+ CLK_IGNORE_UNUSED, JHB100_SYS2CLK_JTAGM0_HCLK),
+ JH71X0_GATE(JHB100_SYS2CLK_JTAG0_MST_WRAP_CLK_JTAG, "jtag0_mst_wrap_clk_jtag",
+ CLK_IGNORE_UNUSED, JHB100_SYS2CLK_JTAGM0_HCLK),
+ JH71X0_GATE(JHB100_SYS2CLK_JTAG0_MST_WRAP_APB_PCLK, "jtag0_mst_wrap_apb_pclk",
+ CLK_IGNORE_UNUSED, JHB100_SYS2CLK_JTAGM0_ATPG),
+ JH71X0_GATE(JHB100_SYS2CLK_JTAG0_MST_WRAP_ATPG_TCLOCK, "jtag0_mst_wrap_atpg_tclock",
+ CLK_IGNORE_UNUSED, JHB100_SYS2CLK_JTAGM0_ATPG),
+ JH71X0_GATE(JHB100_SYS2CLK_JTAG1_MST_WRAP_HCLK, "jtag1_mst_wrap_hclk",
+ CLK_IGNORE_UNUSED, JHB100_SYS2CLK_JTAGM1_HCLK),
+ JH71X0_GATE(JHB100_SYS2CLK_JTAG1_MST_WRAP_CLK_JTAG, "jtag1_mst_wrap_clk_jtag",
+ CLK_IGNORE_UNUSED, JHB100_SYS2CLK_JTAGM1_HCLK),
+ JH71X0_GATE(JHB100_SYS2CLK_JTAG1_MST_WRAP_APB_PCLK, "jtag1_mst_wrap_apb_pclk",
+ CLK_IGNORE_UNUSED, JHB100_SYS2CLK_JTAGM1_ATPG),
+ JH71X0_GATE(JHB100_SYS2CLK_JTAG1_MST_WRAP_ATPG_TCLOCK, "jtag1_mst_wrap_atpg_tclock",
+ CLK_IGNORE_UNUSED, JHB100_SYS2CLK_JTAGM1_ATPG),
+ /* hostusbcmn */
+ JH71X0__DIV(JHB100_SYS2CLK_HOSTUSB_NCNOC_TARG, "hostusb_ncnoc_targ", 12,
+ JHB100_SYS2CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS2CLK_HOSTUSBCMN_CFG_500, "hostusbcmn_cfg_500", 4,
+ JHB100_SYS2CLK_PLL1),
+ /* bmcperiph1 */
+ JH71X0__DIV(JHB100_SYS2CLK_BMCPER1_NCNOC_TARG, "bmcper1_ncnoc_targ", 6,
+ JHB100_SYS2CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS2CLK_BMCPER1_CFG_250, "bmcper1_cfg_250", 5,
+ JHB100_SYS2CLK_PLL1),
+ JH71X0__DIV(JHB100_SYS2CLK_BMCPER1_CFG_143_DFT, "bmcper1_cfg_143_dft", 8,
+ JHB100_SYS2CLK_PLL1),
+ JH71X0_GATE(JHB100_SYS2CLK_BMCPER1_CFG_143, "bmcper1_cfg_143", CLK_IS_CRITICAL,
+ JHB100_SYS2CLK_BMCPER1_CFG_143_DFT),
+ /* bmcperiph0 */
+ JH71X0__DIV(JHB100_SYS2CLK_BMCPER0_NCNOC_TARG, "bmcper0_ncnoc_targ", 6,
+ JHB100_SYS2CLK_PLL1),
+ /* gpu0 */
+ JH71X0__DIV(JHB100_SYS2CLK_GPU0_NCNOC_TARG, "gpu0_ncnoc_targ", 12,
+ JHB100_SYS2CLK_PLL1),
+ JH71X0_GATE(JHB100_SYS2CLK_GPU0_BUS_CLK, "gpu0_bus_clk", CLK_IS_CRITICAL,
+ JHB100_SYS2CLK_GPU0_NCNOC_INIT),
+ JH71X0_GATE(JHB100_SYS2CLK_GPU0_APB_CLK, "gpu0_apb_clk", CLK_IS_CRITICAL,
+ JHB100_SYS2CLK_GPU0_NCNOC_TARG),
+ JH71X0_GATE(JHB100_SYS2CLK_GPU0_OSC_CLK, "gpu0_osc_clk", CLK_IS_CRITICAL,
+ JHB100_SYS2CLK_OSC),
+ /* gpu1 */
+ JH71X0__DIV(JHB100_SYS2CLK_GPU1_NCNOC_TARG, "gpu1_ncnoc_targ", 12,
+ JHB100_SYS2CLK_PLL1),
+ JH71X0_GATE(JHB100_SYS2CLK_GPU1_BUS_CLK, "gpu1_bus_clk", CLK_IS_CRITICAL,
+ JHB100_SYS2CLK_GPU1_NCNOC_INIT),
+ JH71X0_GATE(JHB100_SYS2CLK_GPU1_APB_CLK, "gpu1_apb_clk", CLK_IS_CRITICAL,
+ JHB100_SYS2CLK_GPU1_NCNOC_TARG),
+ JH71X0_GATE(JHB100_SYS2CLK_GPU1_OSC_CLK, "gpu1_osc_clk", CLK_IS_CRITICAL,
+ JHB100_SYS2CLK_OSC),
+ /* main icg */
+ JH71X0_GATE(JHB100_SYS2CLK_MAIN_ICG_EN_JTAG0, "main_icg_en_jtag0", 0,
+ JHB100_SYS2CLK_JTAGM0_HCLK),
+ JH71X0_GATE(JHB100_SYS2CLK_MAIN_ICG_EN_JTAG1, "main_icg_en_jtag1", 0,
+ JHB100_SYS2CLK_JTAGM1_HCLK),
+};
+
+static const struct jh71x0_crg_domain_info jhb100_sys2crg_info = {
+ .clk_data = jhb100_sys2crg_clk_data,
+ .num_clk = ARRAY_SIZE(jhb100_sys2crg_clk_data),
+ .ext_clk = jhb100_sys2_ext_clk,
+ .num_ext_clk = ARRAY_SIZE(jhb100_sys2_ext_clk),
+ .rst_name = "jhb100-r-sys2",
+ .power_domain = false,
+};
+
+static const struct of_device_id jhb100_sys2crg_match[] = {
+ {
+ .compatible = "starfive,jhb100-sys2crg",
+ .data = &jhb100_sys2crg_info,
+ },
+ { /* sentinel */ }
+};
+
+static struct platform_driver jhb100_sys2crg_driver = {
+ .probe = jh71x0_crg_probe,
+ .driver = {
+ .name = "clk-starfive-jhb100-sys2",
+ .of_match_table = jhb100_sys2crg_match,
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver(jhb100_sys2crg_driver);
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 08/15] clk: starfive: Introduce idiv ops for inverted divider clocks
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
` (6 preceding siblings ...)
2026-10-08 12:33 ` [PATCH v6 07/15] clk: starfive: Add JHB100 System-2 " Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 09/15] clk: starfive: Expand the storage of clock parent index Changhuang Liang
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
Some StarFive clocks only advertise the divider and invert capabilities
(via JH71X0_CLK_INVERT, without ENABLE). Add the JH71X0_IDIV() macro
to declare such clocks, and jh71x0_clk_idiv_ops, which combines the
divider rate operations with get_phase/set_phase.
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
drivers/clk/starfive/clk-starfive-jh71x0.c | 13 ++++++++++++-
drivers/clk/starfive/clk-starfive-jh71x0.h | 8 ++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.c b/drivers/clk/starfive/clk-starfive-jh71x0.c
index c5ee82db3c92..224fcc3d08db 100644
--- a/drivers/clk/starfive/clk-starfive-jh71x0.c
+++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
@@ -303,6 +303,15 @@ static const struct clk_ops jh71x0_clk_inv_ops = {
.debug_init = jh71x0_clk_debug_init,
};
+static const struct clk_ops jh71x0_clk_idiv_ops = {
+ .get_phase = jh71x0_clk_get_phase,
+ .set_phase = jh71x0_clk_set_phase,
+ .recalc_rate = jh71x0_clk_recalc_rate,
+ .determine_rate = jh71x0_clk_determine_rate,
+ .set_rate = jh71x0_clk_set_rate,
+ .debug_init = jh71x0_clk_debug_init,
+};
+
const struct clk_ops *starfive_jh71x0_clk_ops(u32 max)
{
if (max & JH71X0_CLK_DIV_MASK) {
@@ -313,7 +322,9 @@ const struct clk_ops *starfive_jh71x0_clk_ops(u32 max)
}
if (max & JH71X0_CLK_ENABLE)
return &jh71x0_clk_gdiv_ops;
- if (max == JH71X0_CLK_FRAC_MAX)
+ else if (max & JH71X0_CLK_INVERT)
+ return &jh71x0_clk_idiv_ops;
+ else if (max == JH71X0_CLK_FRAC_MAX)
return &jh71x0_clk_fdiv_ops;
return &jh71x0_clk_div_ops;
}
diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.h b/drivers/clk/starfive/clk-starfive-jh71x0.h
index 2a1f0fb4cbb1..4cb3c2ef9525 100644
--- a/drivers/clk/starfive/clk-starfive-jh71x0.h
+++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
@@ -104,6 +104,14 @@ struct jh71x0_clk_data {
.parents = { [0] = _parent }, \
}
+#define JH71X0_IDIV(_idx, _name, _flags, _max, _parent) \
+[_idx] = { \
+ .name = _name, \
+ .flags = _flags, \
+ .max = JH71X0_CLK_INVERT | (_max), \
+ .parents = { [0] = _parent }, \
+}
+
struct jh71x0_clk {
struct clk_hw hw;
unsigned int idx;
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 09/15] clk: starfive: Expand the storage of clock parent index
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
` (7 preceding siblings ...)
2026-10-08 12:33 ` [PATCH v6 08/15] clk: starfive: Introduce idiv ops for inverted divider clocks Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 10/15] clk: starfive: Add StarFive JHB100 Peripheral-0 clock driver Changhuang Liang
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
Expand the storage of clock parent index for per0 domain, which parent
index over 255. So change u8 to u16.
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
---
drivers/clk/starfive/clk-starfive-jh71x0.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/starfive/clk-starfive-jh71x0.h b/drivers/clk/starfive/clk-starfive-jh71x0.h
index 4cb3c2ef9525..198f6d005415 100644
--- a/drivers/clk/starfive/clk-starfive-jh71x0.h
+++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
@@ -27,7 +27,7 @@ struct jh71x0_clk_data {
const char *name;
unsigned long flags;
u32 max;
- u8 parents[4];
+ u16 parents[4];
};
#define JH71X0_GATE(_idx, _name, _flags, _parent) \
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 10/15] clk: starfive: Add StarFive JHB100 Peripheral-0 clock driver
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
` (8 preceding siblings ...)
2026-10-08 12:33 ` [PATCH v6 09/15] clk: starfive: Expand the storage of clock parent index Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 11/15] clk: starfive: Add StarFive JHB100 Peripheral-1 " Changhuang Liang
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
Add driver for the StarFive JHB100 Peripheral-0 clock controller.
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
drivers/clk/starfive/Kconfig | 10 +
drivers/clk/starfive/Makefile | 1 +
.../clk/starfive/clk-starfive-jhb100-per0.c | 617 ++++++++++++++++++
3 files changed, 628 insertions(+)
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-per0.c
diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index cfaac934a8e0..b2a05bbb450f 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -73,6 +73,16 @@ config CLK_STARFIVE_JH7110_VOUT
Say yes here to support the Video-Output clock controller
on the StarFive JH7110 SoC.
+config CLK_STARFIVE_JHB100_PER0
+ bool "StarFive JHB100 peripheral-0 clock support"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ select CLK_STARFIVE_JH71X0
+ select RESET_STARFIVE_JHB100 if RESET_CONTROLLER
+ default ARCH_STARFIVE
+ help
+ Say yes here to support the peripheral-0 clock controller
+ on the StarFive JHB100 SoC.
+
config CLK_STARFIVE_JHB100_SYS0
bool "StarFive JHB100 system-0 clock support"
depends on ARCH_STARFIVE || COMPILE_TEST
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
index 29cdef20575e..352717886295 100644
--- a/drivers/clk/starfive/Makefile
+++ b/drivers/clk/starfive/Makefile
@@ -11,6 +11,7 @@ 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
+obj-$(CONFIG_CLK_STARFIVE_JHB100_PER0) += clk-starfive-jhb100-per0.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS0) += clk-starfive-jhb100-sys0.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS1) += clk-starfive-jhb100-sys1.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS2) += clk-starfive-jhb100-sys2.o
diff --git a/drivers/clk/starfive/clk-starfive-jhb100-per0.c b/drivers/clk/starfive/clk-starfive-jhb100-per0.c
new file mode 100644
index 000000000000..ef6e6906cd2f
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jhb100-per0.c
@@ -0,0 +1,617 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive JHB100 Peripheral-0 Clock Driver
+ *
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ *
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#include <dt-bindings/clock/starfive,jhb100-crg.h>
+#include <linux/platform_device.h>
+
+#include "clk-starfive-jh71x0.h"
+
+#define JHB100_PER0CLK_NUM_CLKS (JHB100_PER0CLK_MAIN_ICG_EN_TRNG + 1)
+
+/* external clocks */
+#define JHB100_PER0CLK_OSC (JHB100_PER0CLK_NUM_CLKS + 0)
+#define JHB100_PER0CLK_PLL6 (JHB100_PER0CLK_NUM_CLKS + 1)
+#define JHB100_PER0CLK_CFG_400 (JHB100_PER0CLK_NUM_CLKS + 2)
+#define JHB100_PER0CLK_CFG_800 (JHB100_PER0CLK_NUM_CLKS + 3)
+#define JHB100_PER0CLK_NCNOC_INIT (JHB100_PER0CLK_NUM_CLKS + 4)
+#define JHB100_PER0CLK_NCNOC_TARG (JHB100_PER0CLK_NUM_CLKS + 5)
+
+static const char * const jhb100_per0_ext_clk[] = {
+ "osc",
+ "pll6",
+ "cfg_400",
+ "cfg_800",
+ "ncnoc_init",
+ "ncnoc_targ",
+};
+
+/*
+ * Regarding the CLK_IS_CRITICAL flag:
+ * What is special here is the UART*-related clocks. On the JHB100, the secure
+ * core may consume one UART, while the AP core consumes another. Different
+ * core boards may select different UARTs, so we usually want to keep all UART*
+ * clocks always on to prevent the AP core from turning off the clock for the
+ * secure core's UART.
+ * UART0-3 are usually used by the HOST side, and there will be no driver on
+ * the BMC side to consume these clocks. Therefore, these clocks need to be
+ * enabled for the host to consume.
+ *
+ * Regarding the CLK_IGNORE_UNUSED flag:
+ * Clocks flagged CLK_IGNORE_UNUSED are not consumed by any driver. The flag
+ * keeps them in their hardware default state (enabled) instead of letting
+ * the clock framework gate them once it disables unused clocks. If this
+ * flag needs to be removed later, it must be ensured that these clocks will
+ * not be disabled even if they are not consumed.
+ */
+static const struct jh71x0_clk_data jhb100_per0crg_clk_data[] = {
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C0, "cdr_i3c0", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C1, "cdr_i3c1", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C2, "cdr_i3c2", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C3, "cdr_i3c3", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C4, "cdr_i3c4", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C5, "cdr_i3c5", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C6, "cdr_i3c6", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C7, "cdr_i3c7", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C8, "cdr_i3c8", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C9, "cdr_i3c9", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C10, "cdr_i3c10", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C11, "cdr_i3c11", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C12, "cdr_i3c12", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C13, "cdr_i3c13", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C14, "cdr_i3c14", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0_GATE(JHB100_PER0CLK_CDR_I3C15, "cdr_i3c15", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_800),
+ JH71X0__DIV(JHB100_PER0CLK_200, "per0_200", 3,
+ JHB100_PER0CLK_NCNOC_INIT),
+ JH71X0__DIV(JHB100_PER0CLK_600_DIV6, "per0_600_div6", 6,
+ JHB100_PER0CLK_NCNOC_INIT),
+ JH71X0__DIV(JHB100_PER0CLK_600_DIV6_DIV5, "per0_600_div6_div5", 5,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_TIMER0_DUALTIMER0, "timer0_dualtimer0", 0,
+ JHB100_PER0CLK_600_DIV6_DIV5),
+ JH71X0_GATE(JHB100_PER0CLK_TIMER1_DUALTIMER0, "timer1_dualtimer0", 0,
+ JHB100_PER0CLK_600_DIV6_DIV5),
+ JH71X0_GATE(JHB100_PER0CLK_TIMER0_DUALTIMER1, "timer0_dualtimer1", 0,
+ JHB100_PER0CLK_600_DIV6_DIV5),
+ JH71X0_GATE(JHB100_PER0CLK_TIMER1_DUALTIMER1, "timer1_dualtimer1", 0,
+ JHB100_PER0CLK_600_DIV6_DIV5),
+ JH71X0_GATE(JHB100_PER0CLK_TIMER0_DUALTIMER2, "timer0_dualtimer2", 0,
+ JHB100_PER0CLK_600_DIV6_DIV5),
+ JH71X0_GATE(JHB100_PER0CLK_TIMER1_DUALTIMER2, "timer1_dualtimer2", 0,
+ JHB100_PER0CLK_600_DIV6_DIV5),
+ JH71X0__DIV(JHB100_PER0CLK_1200_PH0_LVDS0, "1200_ph0_lvds0", 2,
+ JHB100_PER0CLK_PH0_LTPI0),
+ JH71X0__DIV(JHB100_PER0CLK_1200_PH0_LVDS1, "1200_ph0_lvds1", 2,
+ JHB100_PER0CLK_PH0_LTPI1),
+ JH71X0__DIV(JHB100_PER0CLK_1200_CORE0, "1200_core0", 2,
+ JHB100_PER0CLK_PLL6),
+ JH71X0__DIV(JHB100_PER0CLK_1200_CORE1, "1200_core1", 2,
+ JHB100_PER0CLK_PLL6),
+ JH71X0__DIV(JHB100_PER0CLK_1200_SHIFT90_LVDS0, "1200_shift90_lvds0", 2,
+ JHB100_PER0CLK_PH90_LTPI0),
+ JH71X0__DIV(JHB100_PER0CLK_1200_SHIFT90_LVDS1, "1200_shift90_lvds1", 2,
+ JHB100_PER0CLK_PH90_LTPI1),
+ JH71X0__DIV(JHB100_PER0CLK_1200_DIV5_CORE0, "1200_div5_core0", 5,
+ JHB100_PER0CLK_1200_CORE0),
+ JH71X0__DIV(JHB100_PER0CLK_1200_DIV5_CORE1, "1200_div5_core1", 5,
+ JHB100_PER0CLK_1200_CORE1),
+ JH71X0__DIV(JHB100_PER0CLK_PH0_LTPI0, "ph0_ltpi0", 48,
+ JHB100_PER0CLK_PLL6),
+ JH71X0__DIV(JHB100_PER0CLK_PH0_LTPI1, "ph0_ltpi1", 48,
+ JHB100_PER0CLK_PLL6),
+ JH71X0_IDIV(JHB100_PER0CLK_PH90_LTPI0, "ph90_ltpi0", 0, 48,
+ JHB100_PER0CLK_PLL6),
+ JH71X0_IDIV(JHB100_PER0CLK_PH90_LTPI1, "ph90_ltpi1", 0, 48,
+ JHB100_PER0CLK_PLL6),
+ JH71X0__DIV(JHB100_PER0CLK_240_CORE_LTPI0, "240_core_ltpi0", 4,
+ JHB100_PER0CLK_1200_DIV5_CORE0),
+ JH71X0__DIV(JHB100_PER0CLK_240_CORE_LTPI1, "240_core_ltpi1", 4,
+ JHB100_PER0CLK_1200_DIV5_CORE1),
+ JH71X0_GATE(JHB100_PER0CLK_AXI_DMA_I2C_INIT, "axi_dma_i2c_init", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_400),
+ JH71X0_GATE(JHB100_PER0CLK_AXI_DMA_I3C_INIT, "axi_dma_i3c_init", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_400),
+ JH71X0_GATE(JHB100_PER0CLK_AXI_DMA_UART_INIT, "axi_dma_uart_init", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_CFG_400),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_DMAC0, "core_dmac0", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_DMAC1, "core_dmac1", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_DMAC2, "core_dmac2", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C0, "hdr_tx_i3c0", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C1, "hdr_tx_i3c1", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C2, "hdr_tx_i3c2", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C3, "hdr_tx_i3c3", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C4, "hdr_tx_i3c4", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C5, "hdr_tx_i3c5", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C6, "hdr_tx_i3c6", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C7, "hdr_tx_i3c7", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C8, "hdr_tx_i3c8", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C9, "hdr_tx_i3c9", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C10, "hdr_tx_i3c10", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C11, "hdr_tx_i3c11", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C12, "hdr_tx_i3c12", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C13, "hdr_tx_i3c13", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C14, "hdr_tx_i3c14", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HDR_TX_I3C15, "hdr_tx_i3c15", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C0, "core_i2c0", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C1, "core_i2c1", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C2, "core_i2c2", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C3, "core_i2c3", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C4, "core_i2c4", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C5, "core_i2c5", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C6, "core_i2c6", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C7, "core_i2c7", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C8, "core_i2c8", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C9, "core_i2c9", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C10, "core_i2c10", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C11, "core_i2c11", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C12, "core_i2c12", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C13, "core_i2c13", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C14, "core_i2c14", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I2C15, "core_i2c15", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_WDOGCLK_WDT0, "wdogclk_wdt0", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_WDOGCLK_WDT1, "wdogclk_wdt1", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_WDOGCLK_WDT2, "wdogclk_wdt2", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_WDOGCLK_WDT3, "wdogclk_wdt3", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_WDOGCLK_WDT_EXTERNAL, "wdogclk_wdt_external",
+ CLK_IGNORE_UNUSED, JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_SCLK_UART4, "sclk_uart4", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_SCLK_UART5, "sclk_uart5", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_SCLK_UART6, "sclk_uart6", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_SCLK_UART7, "sclk_uart7", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_SCLK_UART8, "sclk_uart8", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_SCLK_UART9, "sclk_uart9", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_SCLK_UART10, "sclk_uart10", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_SCLK_UART11, "sclk_uart11", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_SCLK_UART12, "sclk_uart12", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_SCLK_UART13, "sclk_uart13", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_SCLK_UART14, "sclk_uart14", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_PCLK_DMA_UART_CFG, "pclk_dma_uart_cfg", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_PCLK_DMA_I2C_CFG, "pclk_dma_i2c_cfg", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_PCLK_DMA_I3C_CFG, "pclk_dma_i3c_cfg", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_PCLK_DUALTIMER0, "pclk_dualtimer0", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_PCLK_DUALTIMER1, "pclk_dualtimer1", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_PCLK_DUALTIMER2, "pclk_dualtimer2", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_HCLK_TRNG, "hclk_trng", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C0, "apb_i2c0", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C1, "apb_i2c1", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C2, "apb_i2c2", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C3, "apb_i2c3", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C4, "apb_i2c4", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C5, "apb_i2c5", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C6, "apb_i2c6", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C7, "apb_i2c7", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C8, "apb_i2c8", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C9, "apb_i2c9", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C10, "apb_i2c10", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C11, "apb_i2c11", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C12, "apb_i2c12", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C13, "apb_i2c13", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C14, "apb_i2c14", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2C15, "apb_i2c15", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF0, "apb_i2cf0", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF1, "apb_i2cf1", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF2, "apb_i2cf2", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF3, "apb_i2cf3", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF4, "apb_i2cf4", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF5, "apb_i2cf5", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF6, "apb_i2cf6", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF7, "apb_i2cf7", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF8, "apb_i2cf8", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF9, "apb_i2cf9", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF10, "apb_i2cf10", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF11, "apb_i2cf11", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF12, "apb_i2cf12", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF13, "apb_i2cf13", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF14, "apb_i2cf14", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I2CF15, "apb_i2cf15", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C0, "apb_i3c0", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C1, "apb_i3c1", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C2, "apb_i3c2", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C3, "apb_i3c3", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C4, "apb_i3c4", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C5, "apb_i3c5", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C6, "apb_i3c6", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C7, "apb_i3c7", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C8, "apb_i3c8", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C9, "apb_i3c9", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C10, "apb_i3c10", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C11, "apb_i3c11", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C12, "apb_i3c12", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C13, "apb_i3c13", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C14, "apb_i3c14", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_I3C15, "apb_i3c15", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART0, "apb_uart0", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART1, "apb_uart1", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART2, "apb_uart2", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART3, "apb_uart3", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART4, "apb_uart4", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART5, "apb_uart5", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART6, "apb_uart6", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART7, "apb_uart7", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART8, "apb_uart8", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART9, "apb_uart9", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART10, "apb_uart10", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART11, "apb_uart11", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART12, "apb_uart12", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART13, "apb_uart13", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_APB_UART14, "apb_uart14", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C0, "dma_i3c0", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C1, "dma_i3c1", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C2, "dma_i3c2", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C3, "dma_i3c3", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C4, "dma_i3c4", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C5, "dma_i3c5", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C6, "dma_i3c6", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C7, "dma_i3c7", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C8, "dma_i3c8", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C9, "dma_i3c9", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C10, "dma_i3c10", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C11, "dma_i3c11", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C12, "dma_i3c12", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C13, "dma_i3c13", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C14, "dma_i3c14", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_DMA_I3C15, "dma_i3c15", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C0, "core_i3c0", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C1, "core_i3c1", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C2, "core_i3c2", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C3, "core_i3c3", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C4, "core_i3c4", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C5, "core_i3c5", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C6, "core_i3c6", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C7, "core_i3c7", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C8, "core_i3c8", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C9, "core_i3c9", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C10, "core_i3c10", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C11, "core_i3c11", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C12, "core_i3c12", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C13, "core_i3c13", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C14, "core_i3c14", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_CORE_I3C15, "core_i3c15", CLK_IGNORE_UNUSED,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_DMAC_AXI_PERIPH0_HS_CLK_I2C, "dmac_axi_periph0_hs_clk_i2c",
+ CLK_IGNORE_UNUSED, JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C0, "main_icg_en_i3c0", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C1, "main_icg_en_i3c1", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C2, "main_icg_en_i3c2", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C3, "main_icg_en_i3c3", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C4, "main_icg_en_i3c4", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C5, "main_icg_en_i3c5", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C6, "main_icg_en_i3c6", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C7, "main_icg_en_i3c7", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C8, "main_icg_en_i3c8", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C9, "main_icg_en_i3c9", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C10, "main_icg_en_i3c10", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C11, "main_icg_en_i3c11", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C12, "main_icg_en_i3c12", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C13, "main_icg_en_i3c13", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C14, "main_icg_en_i3c14", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I3C15, "main_icg_en_i3c15", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER0, "main_icg_en_dualtimer0",
+ CLK_IS_CRITICAL, JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER1, "main_icg_en_dualtimer1",
+ CLK_IS_CRITICAL, JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER2, "main_icg_en_dualtimer2",
+ CLK_IS_CRITICAL, JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_LTPI0, "main_icg_en_ltpi0", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_LTPI1, "main_icg_en_ltpi1", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_DMAC_I2C, "main_icg_en_dmac_i2c",
+ CLK_IS_CRITICAL, JHB100_PER0CLK_CFG_400),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_DMAC_I3C, "main_icg_en_dmac_i3c",
+ CLK_IS_CRITICAL, JHB100_PER0CLK_CFG_400),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_DMAC_UART, "main_icg_en_dmac_uart",
+ CLK_IS_CRITICAL, JHB100_PER0CLK_CFG_400),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL4, "main_icg_en_sol4", 0,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL5, "main_icg_en_sol5", 0,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL6, "main_icg_en_sol6", 0,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL7, "main_icg_en_sol7", 0,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL8, "main_icg_en_sol8", 0,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL9, "main_icg_en_sol9", 0,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL10, "main_icg_en_sol10", 0,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL11, "main_icg_en_sol11", 0,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL12, "main_icg_en_sol12", 0,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL13, "main_icg_en_sol13", 0,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SOL14, "main_icg_en_sol14", 0,
+ JHB100_PER0CLK_200),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C0, "main_icg_en_i2c0", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C1, "main_icg_en_i2c1", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C2, "main_icg_en_i2c2", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C3, "main_icg_en_i2c3", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C4, "main_icg_en_i2c4", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C5, "main_icg_en_i2c5", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C6, "main_icg_en_i2c6", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C7, "main_icg_en_i2c7", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C8, "main_icg_en_i2c8", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C9, "main_icg_en_i2c9", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C10, "main_icg_en_i2c10", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C11, "main_icg_en_i2c11", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C12, "main_icg_en_i2c12", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C13, "main_icg_en_i2c13", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C14, "main_icg_en_i2c14", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_I2C15, "main_icg_en_i2c15", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_WDT0, "main_icg_en_wdt0", 0,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_WDT1, "main_icg_en_wdt1", 0,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_WDT2, "main_icg_en_wdt2", 0,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_WDT3, "main_icg_en_wdt3", 0,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_WDT_EXTERNAL, "main_icg_en_wdt_external", 0,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART4, "main_icg_en_uart4", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART5, "main_icg_en_uart5", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART6, "main_icg_en_uart6", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART7, "main_icg_en_uart7", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART8, "main_icg_en_uart8", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART9, "main_icg_en_uart9", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART10, "main_icg_en_uart10", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART11, "main_icg_en_uart11", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART12, "main_icg_en_uart12", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART13, "main_icg_en_uart13", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_UART14, "main_icg_en_uart14", CLK_IS_CRITICAL,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_LDO0, "main_icg_en_ldo0", 0,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_LDO1, "main_icg_en_ldo1", 0,
+ JHB100_PER0CLK_OSC),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SENSORS_PERIPH0, "main_icg_en_sensors_periph0", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_SENSORS_DMAC, "main_icg_en_sensors_dmac", 0,
+ JHB100_PER0CLK_600_DIV6),
+ JH71X0_GATE(JHB100_PER0CLK_MAIN_ICG_EN_TRNG, "main_icg_en_trng", 0,
+ JHB100_PER0CLK_NCNOC_TARG),
+};
+
+static const struct jh71x0_crg_domain_info jhb100_per0crg_info = {
+ .clk_data = jhb100_per0crg_clk_data,
+ .num_clk = ARRAY_SIZE(jhb100_per0crg_clk_data),
+ .ext_clk = jhb100_per0_ext_clk,
+ .num_ext_clk = ARRAY_SIZE(jhb100_per0_ext_clk),
+ .rst_name = "jhb100-r-per0",
+ .power_domain = false,
+};
+
+static const struct of_device_id jhb100_per0crg_match[] = {
+ {
+ .compatible = "starfive,jhb100-per0crg",
+ .data = &jhb100_per0crg_info,
+ },
+ { /* sentinel */ }
+};
+
+static struct platform_driver jhb100_per0crg_driver = {
+ .probe = jh71x0_crg_probe,
+ .driver = {
+ .name = "clk-starfive-jhb100-per0",
+ .of_match_table = jhb100_per0crg_match,
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver(jhb100_per0crg_driver);
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 11/15] clk: starfive: Add StarFive JHB100 Peripheral-1 clock driver
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
` (9 preceding siblings ...)
2026-10-08 12:33 ` [PATCH v6 10/15] clk: starfive: Add StarFive JHB100 Peripheral-0 clock driver Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 12/15] clk: starfive: Add StarFive JHB100 Peripheral-2 " Changhuang Liang
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
Add driver for the StarFive JHB100 Peripheral-1 clock controller.
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
drivers/clk/starfive/Kconfig | 10 ++
drivers/clk/starfive/Makefile | 1 +
.../clk/starfive/clk-starfive-jhb100-per1.c | 162 ++++++++++++++++++
3 files changed, 173 insertions(+)
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-per1.c
diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index b2a05bbb450f..62727ce3aef3 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -83,6 +83,16 @@ config CLK_STARFIVE_JHB100_PER0
Say yes here to support the peripheral-0 clock controller
on the StarFive JHB100 SoC.
+config CLK_STARFIVE_JHB100_PER1
+ bool "StarFive JHB100 peripheral-1 clock support"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ select CLK_STARFIVE_JH71X0
+ select RESET_STARFIVE_JHB100 if RESET_CONTROLLER
+ default ARCH_STARFIVE
+ help
+ Say yes here to support the peripheral-1 clock controller
+ on the StarFive JHB100 SoC.
+
config CLK_STARFIVE_JHB100_SYS0
bool "StarFive JHB100 system-0 clock support"
depends on ARCH_STARFIVE || COMPILE_TEST
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
index 352717886295..279e0cdfc99b 100644
--- a/drivers/clk/starfive/Makefile
+++ b/drivers/clk/starfive/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP) += clk-starfive-jh7110-isp.o
obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_PER0) += clk-starfive-jhb100-per0.o
+obj-$(CONFIG_CLK_STARFIVE_JHB100_PER1) += clk-starfive-jhb100-per1.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS0) += clk-starfive-jhb100-sys0.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS1) += clk-starfive-jhb100-sys1.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS2) += clk-starfive-jhb100-sys2.o
diff --git a/drivers/clk/starfive/clk-starfive-jhb100-per1.c b/drivers/clk/starfive/clk-starfive-jhb100-per1.c
new file mode 100644
index 000000000000..1f56563bc77e
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jhb100-per1.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive JHB100 Peripheral-1 Clock Driver
+ *
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ *
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#include <dt-bindings/clock/starfive,jhb100-crg.h>
+#include <linux/platform_device.h>
+
+#include "clk-starfive-jh71x0.h"
+
+#define JHB100_PER1CLK_NUM_CLKS (JHB100_PER1CLK_MAIN_ICG_EN_UFS + 1)
+
+/* external clocks */
+#define JHB100_PER1CLK_PLL7 (JHB100_PER1CLK_NUM_CLKS + 0)
+#define JHB100_PER1CLK_NCNOC_INIT (JHB100_PER1CLK_NUM_CLKS + 1)
+#define JHB100_PER1CLK_CFG_800 (JHB100_PER1CLK_NUM_CLKS + 2)
+#define JHB100_PER1CLK_NCNOC_TARG (JHB100_PER1CLK_NUM_CLKS + 3)
+#define JHB100_PER1CLK_CFG_143 (JHB100_PER1CLK_NUM_CLKS + 4)
+
+static const char * const jhb100_per1_ext_clk[] = {
+ "pll7",
+ "ncnoc_init",
+ "cfg_800",
+ "ncnoc_targ",
+ "cfg_143",
+};
+
+/*
+ * Regarding the CLK_IS_CRITICAL flag:
+ * Clocks flagged CLK_IS_CRITICAL feed logic that has to keep running whether
+ * or not a consumer holds them, such as the bus interconnect and always-on
+ * blocks. Gating them hangs the system, so they must never be disabled.
+ *
+ * Regarding the CLK_IGNORE_UNUSED flag:
+ * Clocks flagged CLK_IGNORE_UNUSED are not consumed by any driver. The flag
+ * keeps them in their hardware default state (enabled) instead of letting
+ * the clock framework gate them once it disables unused clocks. If this
+ * flag needs to be removed later, it must be ensured that these clocks will
+ * not be disabled even if they are not consumed.
+ */
+static const struct jh71x0_clk_data jhb100_per1crg_clk_data[] = {
+ JH71X0__DIV(JHB100_PER1CLK_100, "per1_100", 8, JHB100_PER1CLK_NCNOC_INIT),
+ JH71X0__DIV(JHB100_PER1CLK_1, "per1_1", 100, JHB100_PER1CLK_100),
+ JH71X0__DIV(JHB100_PER1CLK_200_DIVN0, "200_divn0", 256,
+ JHB100_PER1CLK_CFG_800),
+ JH71X0__DIV(JHB100_PER1CLK_200_DIVN1, "200_divn1", 256,
+ JHB100_PER1CLK_CFG_800),
+ JH71X0__DIV(JHB100_PER1CLK_200_DIVN2, "200_divn2", 256,
+ JHB100_PER1CLK_CFG_800),
+ JH71X0__DIV(JHB100_PER1CLK_200_DIVN3, "200_divn3", 256,
+ JHB100_PER1CLK_CFG_800),
+ JH71X0__DIV(JHB100_PER1CLK_200_CCLK_DIV, "200_cclk_div", 2046,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_SGPIO0_PCLK, "sgpio0_pclk", CLK_IGNORE_UNUSED,
+ JHB100_PER1CLK_100),
+ JH71X0_GATE(JHB100_PER1CLK_SGPIO0_DCLK, "sgpio0_dclk", 0,
+ JHB100_PER1CLK_100),
+ JH71X0_GATE(JHB100_PER1CLK_SGPIO1_PCLK, "sgpio1_pclk", CLK_IGNORE_UNUSED,
+ JHB100_PER1CLK_100),
+ JH71X0_GATE(JHB100_PER1CLK_SGPIO1_DCLK, "sgpio1_dclk", 0,
+ JHB100_PER1CLK_100),
+ JH71X0_GATE(JHB100_PER1CLK_EMMC0_BCLK, "emmc0_bclk", 0,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_EMMC0_CCLK, "emmc0_cclk", 0,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_DMAC1_1CH_CORE, "dmac1_1ch_core", 0,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_DMAC1_1CH_ACLK, "dmac1_1ch_aclk", 0,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_DMAC2_1CH_CORE, "dmac2_1ch_core", 0,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_DMAC2_1CH_ACLK, "dmac2_1ch_aclk", 0,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_DMAC3_1CH_CORE, "dmac3_1ch_core", 0,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_DMAC3_1CH_ACLK, "dmac3_1ch_aclk", 0,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_DMAC0_2CH_CORE, "dmac0_2ch_core", 0,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_DMAC0_2CH_ACLK, "dmac0_2ch_aclk", 0,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0__DIV(JHB100_PER1CLK_UFS_REF, "ufs_ref", 75,
+ JHB100_PER1CLK_PLL7),
+ JH71X0__DIV(JHB100_PER1CLK_UFS_300, "ufs_300", 2,
+ JHB100_PER1CLK_NCNOC_INIT),
+ JH71X0__DIV(JHB100_PER1CLK_UFS_150, "ufs_150", 12,
+ JHB100_PER1CLK_NCNOC_INIT),
+ JH71X0__DIV(JHB100_PER1CLK_UFS_400, "ufs_400", 2,
+ JHB100_PER1CLK_CFG_800),
+ JH71X0__DIV(JHB100_PER1CLK_UFS_75, "ufs_75", 2,
+ JHB100_PER1CLK_UFS_150),
+ JH71X0__DIV(JHB100_PER1CLK_UFS_37_5, "ufs_37_5", 2,
+ JHB100_PER1CLK_UFS_75),
+ JH71X0__DIV(JHB100_PER1CLK_UFS_7_5, "ufs_7_5", 10,
+ JHB100_PER1CLK_UFS_75),
+ JH71X0__DIV(JHB100_PER1CLK_UFS_1_875, "ufs_1_875", 4,
+ JHB100_PER1CLK_UFS_7_5),
+ JH71X0__DIV(JHB100_PER1CLK_UFS_7_143, "ufs_7_143", 20,
+ JHB100_PER1CLK_CFG_143),
+ JH71X0__DIV(JHB100_PER1CLK_UFS_3_5715, "ufs_3_5715", 2,
+ JHB100_PER1CLK_UFS_7_143),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_SFC0, "main_icg_en_sfc0", CLK_IS_CRITICAL,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_SFC1, "main_icg_en_sfc1", CLK_IS_CRITICAL,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_SFC2, "main_icg_en_sfc2", CLK_IS_CRITICAL,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_SPI0, "main_icg_en_spi0", 0,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_EMMC0, "main_icg_en_emmc0", 0,
+ JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_SGPIO0, "main_icg_en_sgpio0", 0,
+ JHB100_PER1CLK_100),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_SGPIO1, "main_icg_en_sgpio1", 0,
+ JHB100_PER1CLK_100),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_SENSORS_PERIPH1, "main_icg_en_sensors_periph1", 0,
+ JHB100_PER1CLK_100),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SFC0, "main_icg_en_dmac_sfc0",
+ CLK_IS_CRITICAL, JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SFC1, "main_icg_en_dmac_sfc1",
+ CLK_IS_CRITICAL, JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SFC2, "main_icg_en_dmac_sfc2",
+ CLK_IS_CRITICAL, JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SPI0, "main_icg_en_dmac_spi0",
+ CLK_IS_CRITICAL, JHB100_PER1CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_RAS, "main_icg_en_ras", 0,
+ JHB100_PER1CLK_100),
+ JH71X0_GATE(JHB100_PER1CLK_MAIN_ICG_EN_UFS, "main_icg_en_ufs", 0,
+ JHB100_PER1CLK_100),
+};
+
+static const struct jh71x0_crg_domain_info jhb100_per1crg_info = {
+ .clk_data = jhb100_per1crg_clk_data,
+ .num_clk = ARRAY_SIZE(jhb100_per1crg_clk_data),
+ .ext_clk = jhb100_per1_ext_clk,
+ .num_ext_clk = ARRAY_SIZE(jhb100_per1_ext_clk),
+ .rst_name = "jhb100-r-per1",
+ .power_domain = false,
+};
+
+static const struct of_device_id jhb100_per1crg_match[] = {
+ {
+ .compatible = "starfive,jhb100-per1crg",
+ .data = &jhb100_per1crg_info,
+ },
+ { /* sentinel */ }
+};
+
+static struct platform_driver jhb100_per1crg_driver = {
+ .probe = jh71x0_crg_probe,
+ .driver = {
+ .name = "clk-starfive-jhb100-per1",
+ .of_match_table = jhb100_per1crg_match,
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver(jhb100_per1crg_driver);
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 12/15] clk: starfive: Add StarFive JHB100 Peripheral-2 clock driver
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
` (10 preceding siblings ...)
2026-10-08 12:33 ` [PATCH v6 11/15] clk: starfive: Add StarFive JHB100 Peripheral-1 " Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 13/15] clk: starfive: Add StarFive JHB100 Peripheral-3 " Changhuang Liang
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
Add driver for the StarFive JHB100 Peripheral-2 clock controller.
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
drivers/clk/starfive/Kconfig | 10 +
drivers/clk/starfive/Makefile | 1 +
.../clk/starfive/clk-starfive-jhb100-per2.c | 182 ++++++++++++++++++
3 files changed, 193 insertions(+)
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-per2.c
diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index 62727ce3aef3..57a3838475e9 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -93,6 +93,16 @@ config CLK_STARFIVE_JHB100_PER1
Say yes here to support the peripheral-1 clock controller
on the StarFive JHB100 SoC.
+config CLK_STARFIVE_JHB100_PER2
+ bool "StarFive JHB100 peripheral-2 clock support"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ select CLK_STARFIVE_JH71X0
+ select RESET_STARFIVE_JHB100 if RESET_CONTROLLER
+ default ARCH_STARFIVE
+ help
+ Say yes here to support the peripheral-2 clock controller
+ on the StarFive JHB100 SoC.
+
config CLK_STARFIVE_JHB100_SYS0
bool "StarFive JHB100 system-0 clock support"
depends on ARCH_STARFIVE || COMPILE_TEST
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
index 279e0cdfc99b..ca9347d38023 100644
--- a/drivers/clk/starfive/Makefile
+++ b/drivers/clk/starfive/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_PER0) += clk-starfive-jhb100-per0.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_PER1) += clk-starfive-jhb100-per1.o
+obj-$(CONFIG_CLK_STARFIVE_JHB100_PER2) += clk-starfive-jhb100-per2.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS0) += clk-starfive-jhb100-sys0.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS1) += clk-starfive-jhb100-sys1.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS2) += clk-starfive-jhb100-sys2.o
diff --git a/drivers/clk/starfive/clk-starfive-jhb100-per2.c b/drivers/clk/starfive/clk-starfive-jhb100-per2.c
new file mode 100644
index 000000000000..213f0fd9a260
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jhb100-per2.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive JHB100 Peripheral-2 Clock Driver
+ *
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ *
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#include <dt-bindings/clock/starfive,jhb100-crg.h>
+#include <linux/platform_device.h>
+
+#include "clk-starfive-jh71x0.h"
+
+#define JHB100_PER2CLK_NUM_CLKS (JHB100_PER2CLK_MAIN_ICG_EN_GMAC3 + 1)
+
+/* external clocks */
+#define JHB100_PER2CLK_NCNOC_INIT (JHB100_PER2CLK_NUM_CLKS + 0)
+#define JHB100_PER2CLK_CFG_400 (JHB100_PER2CLK_NUM_CLKS + 1)
+#define JHB100_PER2CLK_CFG_125 (JHB100_PER2CLK_NUM_CLKS + 2)
+#define JHB100_PER2CLK_GMAC2_RGMII_RX (JHB100_PER2CLK_NUM_CLKS + 3)
+#define JHB100_PER2CLK_GMAC2_RMII_REF (JHB100_PER2CLK_NUM_CLKS + 4)
+#define JHB100_PER2CLK_GMAC3_SGMII_TX (JHB100_PER2CLK_NUM_CLKS + 5)
+#define JHB100_PER2CLK_GMAC3_SGMII_RX (JHB100_PER2CLK_NUM_CLKS + 6)
+#define JHB100_PER2CLK_OSC (JHB100_PER2CLK_NUM_CLKS + 7)
+
+static const char * const jhb100_per2_ext_clk[] = {
+ "ncnoc_init",
+ "cfg_400",
+ "cfg_125",
+ "gmac2_rgmii_rx",
+ "gmac2_rmii_ref",
+ "gmac3_sgmii_tx",
+ "gmac3_sgmii_rx",
+ "osc",
+};
+
+/*
+ * Regarding the CLK_IGNORE_UNUSED flag:
+ * Clocks flagged CLK_IGNORE_UNUSED are not consumed by any driver. The flag
+ * keeps them in their hardware default state (enabled) instead of letting
+ * the clock framework gate them once it disables unused clocks. If this
+ * flag needs to be removed later, it must be ensured that these clocks will
+ * not be disabled even if they are not consumed.
+ */
+static const struct jh71x0_clk_data jhb100_per2crg_clk_data[] = {
+ JH71X0__DIV(JHB100_PER2CLK_300, "per2_300", 2,
+ JHB100_PER2CLK_NCNOC_INIT),
+ JH71X0__DIV(JHB100_PER2CLK_100, "per2_100", 4,
+ JHB100_PER2CLK_CFG_400),
+ JH71X0__DIV(JHB100_PER2CLK_50, "per2_50", 2,
+ JHB100_PER2CLK_100),
+ JH71X0__DIV(JHB100_PER2CLK_GMAC2_RMII_50, "gmac2_rmii_50", 2,
+ JHB100_PER2CLK_100),
+ JH71X0__DIV(JHB100_PER2CLK_CAN0_CORE_DIV, "can0_core_div", 20,
+ JHB100_PER2CLK_CFG_400),
+ JH71X0__DIV(JHB100_PER2CLK_CAN1_CORE_DIV, "can1_core_div", 20,
+ JHB100_PER2CLK_CFG_400),
+ JH71X0__DIV(JHB100_PER2CLK_CAN0_TIMER, "can0_timer", 100,
+ JHB100_PER2CLK_100),
+ JH71X0__DIV(JHB100_PER2CLK_CAN1_TIMER, "can1_timer", 100,
+ JHB100_PER2CLK_100),
+ JH71X0__DIV(JHB100_PER2CLK_RTC_CORE_DIV, "rtc_core_div", 763,
+ JHB100_PER2CLK_OSC),
+ JH71X0__MUX(JHB100_PER2CLK_GMAC2_RMII_MUX_DLY, "gmac2_rmii_mux_dly", 0, 2,
+ JHB100_PER2CLK_GMAC2_RMII_REF,
+ JHB100_PER2CLK_GMAC2_RMII_50),
+ JH71X0__DIV(JHB100_PER2CLK_GMAC2_RMII_DIV, "gmac2_rmii_div", 20,
+ JHB100_PER2CLK_GMAC2_RMII_MUX_DLY),
+ JH71X0__MUX(JHB100_PER2CLK_GMAC2_RGMII_125_MUX, "gmac2_rgmii_125_mux", 0, 2,
+ JHB100_PER2CLK_GMAC2_RGMII_RX,
+ JHB100_PER2CLK_CFG_125),
+ JH71X0__DIV(JHB100_PER2CLK_GMAC2_RGMII_DIV, "gmac2_rgmii_div", 50,
+ JHB100_PER2CLK_CFG_125),
+ JH71X0__MUX(JHB100_PER2CLK_GMAC2_TX_MUX, "gmac2_tx_mux", 0, 2,
+ JHB100_PER2CLK_GMAC2_RMII_DIV,
+ JHB100_PER2CLK_GMAC2_RGMII_DIV),
+ JH71X0__INV(JHB100_PER2CLK_GMAC2_TX_180_BUF, "gmac2_tx_180_buf",
+ JHB100_PER2CLK_GMAC2_TX_MUX),
+ JH71X0__MUX(JHB100_PER2CLK_GMAC2_RX_MUX_DLY, "gmac2_rx_mux_dly", 0, 2,
+ JHB100_PER2CLK_GMAC2_RMII_DIV,
+ JHB100_PER2CLK_GMAC2_RGMII_125_MUX),
+ JH71X0__INV(JHB100_PER2CLK_GMAC2_RX_180_BUF, "gmac2_rx_180_buf",
+ JHB100_PER2CLK_GMAC2_RX_MUX_DLY),
+ JH71X0__MUX(JHB100_PER2CLK_GMAC2_TXCK_MUX_DLY, "gmac2_txck_mux_dly", 0, 2,
+ JHB100_PER2CLK_GMAC2_RMII_50,
+ JHB100_PER2CLK_GMAC2_TX_MUX),
+ JH71X0__MUX(JHB100_PER2CLK_GMAC3_TX_125_MUX, "gmac3_tx_125_mux", 0, 2,
+ JHB100_PER2CLK_GMAC3_SGMII_TX,
+ JHB100_PER2CLK_CFG_125),
+ JH71X0__MUX(JHB100_PER2CLK_GMAC3_RX_125_MUX, "gmac3_rx_125_mux", 0, 2,
+ JHB100_PER2CLK_GMAC3_SGMII_RX,
+ JHB100_PER2CLK_CFG_125),
+ JH71X0__DIV(JHB100_PER2CLK_GMAC3_TX_DIV, "gmac3_tx_div", 50,
+ JHB100_PER2CLK_GMAC3_TX_125_MUX),
+ JH71X0__DIV(JHB100_PER2CLK_GMAC3_RX_DIV, "gmac3_rx_div", 50,
+ JHB100_PER2CLK_GMAC3_RX_125_MUX),
+ JH71X0_GATE(JHB100_PER2CLK_SENSORS_PERIPH2, "sensors_periph2", 0,
+ JHB100_PER2CLK_100),
+ JH71X0_GATE(JHB100_PER2CLK_FAN_TACH_PCLK, "fan_tach_pclk", 0,
+ JHB100_PER2CLK_100),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER0_RMIIANDRGMII_TX_I, "ether0_rmiiandrgmii_tx_i",
+ CLK_IGNORE_UNUSED, JHB100_PER2CLK_GMAC2_TX_MUX),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER0_RMIIANDRGMII_RX_I, "ether0_rmiiandrgmii_rx_i",
+ CLK_IGNORE_UNUSED, JHB100_PER2CLK_GMAC2_RX_MUX_DLY),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER0_RMIIANDRGMII_TX_180_I, "ether0_rmiiandrgmii_tx_180_i",
+ CLK_IGNORE_UNUSED, JHB100_PER2CLK_GMAC2_TX_180_BUF),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER0_RMIIANDRGMII_RX_180_I, "ether0_rmiiandrgmii_rx_180_i",
+ CLK_IGNORE_UNUSED, JHB100_PER2CLK_GMAC2_RX_180_BUF),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER0_RMIIANDRGMII_PTP_REF_I, "ether0_rmiiandrgmii_ptp_ref_i",
+ 0, JHB100_PER2CLK_50),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER0_RMIIANDRGMII_RMII_I, "ether0_rmiiandrgmii_rmii_i",
+ CLK_IGNORE_UNUSED, JHB100_PER2CLK_GMAC2_RMII_MUX_DLY),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER0_RMIIANDRGMII_CSR_I, "ether0_rmiiandrgmii_csr_i",
+ 0, JHB100_PER2CLK_100),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER0_RMIIANDRGMII_ACLK_I, "ether0_rmiiandrgmii_aclk_i",
+ 0, JHB100_PER2CLK_300),
+ JH71X0_GATE(JHB100_PER2CLK_RMIIANDRGMII_IOMUX_GMAC2_TXCK, "rmiiandrgmii_iomux_gmac2_txck",
+ CLK_IGNORE_UNUSED, JHB100_PER2CLK_GMAC2_TXCK_MUX_DLY),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER1_SGMII_TX_I, "ether1_sgmii_tx_i",
+ CLK_IGNORE_UNUSED, JHB100_PER2CLK_GMAC3_TX_DIV),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER1_SGMII_RX_I, "ether1_sgmii_rx_i",
+ CLK_IGNORE_UNUSED, JHB100_PER2CLK_GMAC3_RX_DIV),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER1_SGMII_TX_125_I, "ether1_sgmii_tx_125_i",
+ CLK_IGNORE_UNUSED, JHB100_PER2CLK_GMAC3_TX_125_MUX),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER1_SGMII_RX_125_I, "ether1_sgmii_rx_125_i",
+ CLK_IGNORE_UNUSED, JHB100_PER2CLK_GMAC3_RX_125_MUX),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER1_SGMII_PTP_REF_I, "ether1_sgmii_ptp_ref_i",
+ CLK_IGNORE_UNUSED, JHB100_PER2CLK_50),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER1_SGMII_CSR_I, "ether1_sgmii_csr_i",
+ 0, JHB100_PER2CLK_100),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER1_SGMII_ACLK_I, "ether1_sgmii_aclk_i",
+ 0, JHB100_PER2CLK_300),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER1_SGMII_PHY_PCLK_I, "ether1_sgmii_phy_pclk_i",
+ 0, JHB100_PER2CLK_100),
+ JH71X0_GATE(JHB100_PER2CLK_ETHER1_SGMII_REF_25_I, "ether1_sgmii_ref_25_i",
+ CLK_IGNORE_UNUSED, JHB100_PER2CLK_OSC),
+ JH71X0_GATE(JHB100_PER2CLK_MAIN_ICG_EN_CAN0, "main_icg_en_can0", 0,
+ JHB100_PER2CLK_100),
+ JH71X0_GATE(JHB100_PER2CLK_MAIN_ICG_EN_CAN1, "main_icg_en_can1", 0,
+ JHB100_PER2CLK_100),
+ JH71X0_GATE(JHB100_PER2CLK_MAIN_ICG_EN_DMAC_8CH, "main_icg_en_dmac_8ch", 0,
+ JHB100_PER2CLK_100),
+ JH71X0_GATE(JHB100_PER2CLK_MAIN_ICG_EN_RTC_SCAN, "main_icg_en_rtc_scan", 0,
+ JHB100_PER2CLK_100),
+ JH71X0_GATE(JHB100_PER2CLK_MAIN_ICG_EN_ADC0, "main_icg_en_adc0", 0,
+ JHB100_PER2CLK_100),
+ JH71X0_GATE(JHB100_PER2CLK_MAIN_ICG_EN_ADC1, "main_icg_en_adc1", 0,
+ JHB100_PER2CLK_100),
+ JH71X0_GATE(JHB100_PER2CLK_MAIN_ICG_EN_GMAC2, "main_icg_en_gmac2", 0,
+ JHB100_PER2CLK_100),
+ JH71X0_GATE(JHB100_PER2CLK_MAIN_ICG_EN_GMAC3, "main_icg_en_gmac3", 0,
+ JHB100_PER2CLK_100),
+};
+
+static const struct jh71x0_crg_domain_info jhb100_per2crg_info = {
+ .clk_data = jhb100_per2crg_clk_data,
+ .num_clk = ARRAY_SIZE(jhb100_per2crg_clk_data),
+ .ext_clk = jhb100_per2_ext_clk,
+ .num_ext_clk = ARRAY_SIZE(jhb100_per2_ext_clk),
+ .rst_name = "jhb100-r-per2",
+ .power_domain = false,
+};
+
+static const struct of_device_id jhb100_per2crg_match[] = {
+ {
+ .compatible = "starfive,jhb100-per2crg",
+ .data = &jhb100_per2crg_info,
+ },
+ { /* sentinel */ }
+};
+
+static struct platform_driver jhb100_per2crg_driver = {
+ .probe = jh71x0_crg_probe,
+ .driver = {
+ .name = "clk-starfive-jhb100-per2",
+ .of_match_table = jhb100_per2crg_match,
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver(jhb100_per2crg_driver);
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 13/15] clk: starfive: Add StarFive JHB100 Peripheral-3 clock driver
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
` (11 preceding siblings ...)
2026-10-08 12:33 ` [PATCH v6 12/15] clk: starfive: Add StarFive JHB100 Peripheral-2 " Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 14/15] reset: starfive: jh71x0: Support discontiguous reset IDs Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 15/15] reset: starfive: Add StarFive JHB100 reset driver Changhuang Liang
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
Add driver for the StarFive JHB100 Peripheral-3 clock controller.
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
drivers/clk/starfive/Kconfig | 10 ++
drivers/clk/starfive/Makefile | 1 +
.../clk/starfive/clk-starfive-jhb100-per3.c | 140 ++++++++++++++++++
3 files changed, 151 insertions(+)
create mode 100644 drivers/clk/starfive/clk-starfive-jhb100-per3.c
diff --git a/drivers/clk/starfive/Kconfig b/drivers/clk/starfive/Kconfig
index 57a3838475e9..1c9dd5d47cb8 100644
--- a/drivers/clk/starfive/Kconfig
+++ b/drivers/clk/starfive/Kconfig
@@ -103,6 +103,16 @@ config CLK_STARFIVE_JHB100_PER2
Say yes here to support the peripheral-2 clock controller
on the StarFive JHB100 SoC.
+config CLK_STARFIVE_JHB100_PER3
+ bool "StarFive JHB100 peripheral-3 clock support"
+ depends on ARCH_STARFIVE || COMPILE_TEST
+ select CLK_STARFIVE_JH71X0
+ select RESET_STARFIVE_JHB100 if RESET_CONTROLLER
+ default ARCH_STARFIVE
+ help
+ Say yes here to support the peripheral-3 clock controller
+ on the StarFive JHB100 SoC.
+
config CLK_STARFIVE_JHB100_SYS0
bool "StarFive JHB100 system-0 clock support"
depends on ARCH_STARFIVE || COMPILE_TEST
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
index ca9347d38023..2c4554c2e70e 100644
--- a/drivers/clk/starfive/Makefile
+++ b/drivers/clk/starfive/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_PER0) += clk-starfive-jhb100-per0.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_PER1) += clk-starfive-jhb100-per1.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_PER2) += clk-starfive-jhb100-per2.o
+obj-$(CONFIG_CLK_STARFIVE_JHB100_PER3) += clk-starfive-jhb100-per3.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS0) += clk-starfive-jhb100-sys0.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS1) += clk-starfive-jhb100-sys1.o
obj-$(CONFIG_CLK_STARFIVE_JHB100_SYS2) += clk-starfive-jhb100-sys2.o
diff --git a/drivers/clk/starfive/clk-starfive-jhb100-per3.c b/drivers/clk/starfive/clk-starfive-jhb100-per3.c
new file mode 100644
index 000000000000..aa023a74ad72
--- /dev/null
+++ b/drivers/clk/starfive/clk-starfive-jhb100-per3.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive JHB100 Peripheral-3 Clock Driver
+ *
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ *
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ *
+ */
+
+#include <dt-bindings/clock/starfive,jhb100-crg.h>
+#include <linux/platform_device.h>
+
+#include "clk-starfive-jh71x0.h"
+
+#define JHB100_PER3CLK_NUM_CLKS (JHB100_PER3CLK_MAIN_ICG_EN_GMAC1 + 1)
+
+/* external clocks */
+#define JHB100_PER3CLK_NCNOC_INIT (JHB100_PER3CLK_NUM_CLKS + 0)
+#define JHB100_PER3CLK_NCNOC_TARG (JHB100_PER3CLK_NUM_CLKS + 1)
+#define JHB100_PER3CLK_CFG_125 (JHB100_PER3CLK_NUM_CLKS + 2)
+#define JHB100_PER3CLK_GMAC0_RMII_RCLKI (JHB100_PER3CLK_NUM_CLKS + 3)
+#define JHB100_PER3CLK_GMAC1_SGMII_TX (JHB100_PER3CLK_NUM_CLKS + 4)
+#define JHB100_PER3CLK_GMAC1_SGMII_RX (JHB100_PER3CLK_NUM_CLKS + 5)
+#define JHB100_PER3CLK_OSC (JHB100_PER3CLK_NUM_CLKS + 6)
+
+static const char * const jhb100_per3_ext_clk[] = {
+ "ncnoc_init",
+ "ncnoc_targ",
+ "cfg_125",
+ "gmac0_rmii_rclki",
+ "gmac1_sgmii_tx",
+ "gmac1_sgmii_rx",
+ "osc",
+};
+
+/*
+ * Regarding the CLK_IGNORE_UNUSED flag:
+ * Clocks flagged CLK_IGNORE_UNUSED are not consumed by any driver. The flag
+ * keeps them in their hardware default state (enabled) instead of letting
+ * the clock framework gate them once it disables unused clocks. If this
+ * flag needs to be removed later, it must be ensured that these clocks will
+ * not be disabled even if they are not consumed.
+ */
+static const struct jh71x0_clk_data jhb100_per3crg_clk_data[] = {
+ JH71X0__DIV(JHB100_PER3CLK_300, "per3_300", 256,
+ JHB100_PER3CLK_NCNOC_INIT),
+ JH71X0__DIV(JHB100_PER3CLK_200, "per3_200", 256,
+ JHB100_PER3CLK_NCNOC_INIT),
+ JH71X0__DIV(JHB100_PER3CLK_GMAC1_PTP_REF, "gmac1_ptp_ref", 2,
+ JHB100_PER3CLK_NCNOC_TARG),
+ JH71X0__MUX(JHB100_PER3CLK_GMAC1_TX_125_MUX, "gmac1_tx_125_mux", 0, 2,
+ JHB100_PER3CLK_GMAC1_SGMII_TX,
+ JHB100_PER3CLK_CFG_125),
+ JH71X0__DIV(JHB100_PER3CLK_GMAC1_TX, "gmac1_tx", 50,
+ JHB100_PER3CLK_GMAC1_TX_125_MUX),
+ JH71X0__MUX(JHB100_PER3CLK_GMAC1_RX_125_MUX, "gmac1_rx_125_mux", 0, 2,
+ JHB100_PER3CLK_GMAC1_SGMII_RX,
+ JHB100_PER3CLK_CFG_125),
+ JH71X0__DIV(JHB100_PER3CLK_GMAC1_RX, "gmac1_rx", 50,
+ JHB100_PER3CLK_GMAC1_RX_125_MUX),
+ JH71X0__DIV(JHB100_PER3CLK_GMAC0_PTP_REF, "gmac0_ptp_ref", 2,
+ JHB100_PER3CLK_NCNOC_TARG),
+ JH71X0__DIV(JHB100_PER3CLK_GMAC0_RMII_PLL, "gmac0_rmii_pll", 2,
+ JHB100_PER3CLK_NCNOC_TARG),
+ JH71X0__MUX(JHB100_PER3CLK_GMAC0_RMII_MUX, "gmac0_rmii_mux", 0, 2,
+ JHB100_PER3CLK_GMAC0_RMII_PLL,
+ JHB100_PER3CLK_GMAC0_RMII_RCLKI),
+ JH71X0__DIV(JHB100_PER3CLK_GMAC0_RMII_MUX_DIV2, "gmac0_rmii_mux_div2", 20,
+ JHB100_PER3CLK_GMAC0_RMII_MUX),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_RMII_CLK_TX_I, "ether0_rmii_clk_tx_i",
+ CLK_IGNORE_UNUSED, JHB100_PER3CLK_GMAC0_RMII_MUX_DIV2),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_RMII_CLK_RX_I, "ether0_rmii_clk_rx_i",
+ CLK_IGNORE_UNUSED, JHB100_PER3CLK_GMAC0_RMII_MUX_DIV2),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_RMII_CLK_PTP_REF_I, "ether0_rmii_clk_ptp_ref_i",
+ 0, JHB100_PER3CLK_GMAC0_PTP_REF),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_RMII_CLK_RMII_I, "ether0_rmii_clk_rmii_i",
+ CLK_IGNORE_UNUSED, JHB100_PER3CLK_GMAC0_RMII_MUX),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_RMII_CLK_CSR_I, "ether0_rmii_clk_csr_i",
+ 0, JHB100_PER3CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_RMII_ACLK_I, "ether0_rmii_aclk_i",
+ 0, JHB100_PER3CLK_300),
+ JH71X0_GATE(JHB100_PER3CLK_GMAC0_RMII_RCLKO, "gmac0_rmii_rclko",
+ CLK_IGNORE_UNUSED, JHB100_PER3CLK_GMAC0_RMII_PLL),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_SGMII_CLK_TX_I, "ether0_sgmii_clk_tx_i",
+ CLK_IGNORE_UNUSED, JHB100_PER3CLK_GMAC1_TX),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_SGMII_CLK_RX_I, "ether0_sgmii_clk_rx_i",
+ CLK_IGNORE_UNUSED, JHB100_PER3CLK_GMAC1_RX),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_SGMII_CLK_TX_125_I, "ether0_sgmii_clk_tx_125_i",
+ CLK_IGNORE_UNUSED, JHB100_PER3CLK_GMAC1_TX_125_MUX),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_SGMII_CLK_RX_125_I, "ether0_sgmii_clk_rx_125_i",
+ CLK_IGNORE_UNUSED, JHB100_PER3CLK_GMAC1_RX_125_MUX),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_SGMII_CLK_PTP_REF_I, "ether0_sgmii_clk_ptp_ref_i",
+ 0, JHB100_PER3CLK_GMAC1_PTP_REF),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_SGMII_CLK_REF_25_I, "ether0_sgmii_clk_ref_25_i",
+ CLK_IGNORE_UNUSED, JHB100_PER3CLK_OSC),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_SGMII_CLK_CSR_I, "ether0_sgmii_clk_csr_i",
+ 0, JHB100_PER3CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_SGMII_ACLK_I, "ether0_sgmii_aclk_i",
+ 0, JHB100_PER3CLK_300),
+ JH71X0_GATE(JHB100_PER3CLK_ETHER0_SGMII_PHY_PCLK_I, "ether0_sgmii_phy_pclk_i",
+ CLK_IGNORE_UNUSED, JHB100_PER3CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER3CLK_MAIN_ICG_EN_SENSORS_PERIPH3, "main_icg_en_sensors_periph3", 0,
+ JHB100_PER3CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER3CLK_MAIN_ICG_EN_PECI0, "main_icg_en_peci0", 0,
+ JHB100_PER3CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER3CLK_MAIN_ICG_EN_PECI1, "main_icg_en_peci1", 0,
+ JHB100_PER3CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER3CLK_MAIN_ICG_EN_GMAC0, "main_icg_en_gmac0",
+ 0, JHB100_PER3CLK_NCNOC_TARG),
+ JH71X0_GATE(JHB100_PER3CLK_MAIN_ICG_EN_GMAC1, "main_icg_en_gmac1",
+ 0, JHB100_PER3CLK_NCNOC_TARG),
+};
+
+static const struct jh71x0_crg_domain_info jhb100_per3crg_info = {
+ .clk_data = jhb100_per3crg_clk_data,
+ .num_clk = ARRAY_SIZE(jhb100_per3crg_clk_data),
+ .ext_clk = jhb100_per3_ext_clk,
+ .num_ext_clk = ARRAY_SIZE(jhb100_per3_ext_clk),
+ .rst_name = "jhb100-r-per3",
+ .power_domain = false,
+};
+
+static const struct of_device_id jhb100_per3crg_match[] = {
+ {
+ .compatible = "starfive,jhb100-per3crg",
+ .data = &jhb100_per3crg_info,
+ },
+ { /* sentinel */ }
+};
+
+static struct platform_driver jhb100_per3crg_driver = {
+ .probe = jh71x0_crg_probe,
+ .driver = {
+ .name = "clk-starfive-jhb100-per3",
+ .of_match_table = jhb100_per3crg_match,
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver(jhb100_per3crg_driver);
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 14/15] reset: starfive: jh71x0: Support discontiguous reset IDs
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
` (12 preceding siblings ...)
2026-10-08 12:33 ` [PATCH v6 13/15] clk: starfive: Add StarFive JHB100 Peripheral-3 " Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 15/15] reset: starfive: Add StarFive JHB100 reset driver Changhuang Liang
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
The reset IDs exposed to consumers of the StarFive JHB100 reset
controllers do not map one-to-one to the hardware reset bits.
Add struct jh71x0_reset_info, which describes the number of resets, the
assert/status register offsets and, for discontiguous controllers, a
table mapping reset IDs to hardware bits. Add
reset_starfive_jh71x0_register_with_info() to register such a
controller, and translate the reset ID in the update and status
callbacks when a map is provided.
Existing users of reset_starfive_jh71x0_register() are unaffected.
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
.../reset/starfive/reset-starfive-jh71x0.c | 99 ++++++++++++++++---
.../reset/starfive/reset-starfive-jh71x0.h | 19 ++++
2 files changed, 107 insertions(+), 11 deletions(-)
diff --git a/drivers/reset/starfive/reset-starfive-jh71x0.c b/drivers/reset/starfive/reset-starfive-jh71x0.c
index 29ce3486752f..fd1c755a0017 100644
--- a/drivers/reset/starfive/reset-starfive-jh71x0.c
+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
@@ -14,6 +14,8 @@
#include "reset-starfive-jh71x0.h"
+#define JH71X0_RESET_ID_INVALID ULONG_MAX
+
struct jh71x0_reset {
struct reset_controller_dev rcdev;
/* protect registers against concurrent read-modify-write */
@@ -21,6 +23,11 @@ struct jh71x0_reset {
void __iomem *assert;
void __iomem *status;
const u32 *asserted;
+
+ /* Only exists in reset controllers that use the
+ * reset_starfive_jh71x0_register_with_info helper.
+ */
+ const struct jh71x0_reset_info *info;
};
static inline struct jh71x0_reset *
@@ -29,19 +36,40 @@ jh71x0_reset_from(struct reset_controller_dev *rcdev)
return container_of(rcdev, struct jh71x0_reset, rcdev);
}
+static unsigned long
+jh71x0_reset_id_to_hw_id(const struct jh71x0_reset_map *map, unsigned int nr_resets,
+ unsigned long reset_id)
+{
+ for (u32 i = 0; i < nr_resets; i++) {
+ if (map[i].reset_id == reset_id)
+ return map[i].hw_id;
+ }
+
+ return JH71X0_RESET_ID_INVALID;
+}
+
static int jh71x0_reset_update(struct reset_controller_dev *rcdev,
unsigned long id, bool assert)
{
struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
- unsigned long offset = id / 32;
- u32 mask = BIT(id % 32);
- void __iomem *reg_assert = data->assert + offset * sizeof(u32);
- void __iomem *reg_status = data->status + offset * sizeof(u32);
- u32 done = data->asserted ? data->asserted[offset] & mask : 0;
- u32 value;
- unsigned long flags;
+ unsigned long offset, flags;
+ void __iomem *reg_assert;
+ void __iomem *reg_status;
+ u32 mask, done, value;
int ret;
+ if (data->info && data->info->discontiguous) {
+ id = jh71x0_reset_id_to_hw_id(data->info->map, data->info->nr_resets, id);
+ if (id == JH71X0_RESET_ID_INVALID)
+ return -EINVAL;
+ }
+
+ offset = id / 32;
+ mask = BIT(id % 32);
+ reg_assert = data->assert + offset * sizeof(u32);
+ reg_status = data->status + offset * sizeof(u32);
+ done = data->asserted ? data->asserted[offset] & mask : 0;
+
if (!assert)
done ^= mask;
@@ -89,10 +117,20 @@ static int jh71x0_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
- unsigned long offset = id / 32;
- u32 mask = BIT(id % 32);
- void __iomem *reg_status = data->status + offset * sizeof(u32);
- u32 value = readl(reg_status);
+ void __iomem *reg_status;
+ unsigned long offset;
+ u32 mask, value;
+
+ if (data->info && data->info->discontiguous) {
+ id = jh71x0_reset_id_to_hw_id(data->info->map, data->info->nr_resets, id);
+ if (id == JH71X0_RESET_ID_INVALID)
+ return -EINVAL;
+ }
+
+ offset = id / 32;
+ mask = BIT(id % 32);
+ reg_status = data->status + offset * sizeof(u32);
+ value = readl(reg_status);
if (!data->asserted)
return !(value & mask);
@@ -132,3 +170,42 @@ int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_no
return devm_reset_controller_register(dev, &data->rcdev);
}
EXPORT_SYMBOL_GPL(reset_starfive_jh71x0_register);
+
+int reset_starfive_jh71x0_register_with_info(struct device *dev, struct device_node *of_node,
+ void __iomem *assert, void __iomem *status,
+ const u32 *asserted,
+ const struct jh71x0_reset_info *info,
+ struct module *owner)
+{
+ struct jh71x0_reset *data;
+ int ret;
+
+ if (info->discontiguous && (!info->map || !info->nr_resets))
+ return dev_err_probe(dev, -EINVAL,
+ "discontiguous controller without a valid ID map\n");
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->rcdev.ops = &jh71x0_reset_ops;
+ data->rcdev.owner = owner;
+ data->rcdev.nr_resets = info->nr_resets;
+ data->rcdev.dev = dev;
+ data->rcdev.of_node = of_node;
+
+ spin_lock_init(&data->lock);
+ data->assert = assert;
+ data->status = status;
+ data->asserted = asserted;
+ data->info = info;
+
+ ret = devm_reset_controller_register(dev, &data->rcdev);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to register reset controller\n");
+
+ dev_info(dev, "Registered %u resets\n", data->rcdev.nr_resets);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(reset_starfive_jh71x0_register_with_info);
diff --git a/drivers/reset/starfive/reset-starfive-jh71x0.h b/drivers/reset/starfive/reset-starfive-jh71x0.h
index db7d39a87f87..36f198139602 100644
--- a/drivers/reset/starfive/reset-starfive-jh71x0.h
+++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
@@ -6,9 +6,28 @@
#ifndef __RESET_STARFIVE_JH71X0_H
#define __RESET_STARFIVE_JH71X0_H
+struct jh71x0_reset_map {
+ unsigned long reset_id;
+ unsigned long hw_id;
+};
+
+struct jh71x0_reset_info {
+ unsigned int nr_resets;
+ unsigned int assert_offset;
+ unsigned int status_offset;
+ bool discontiguous;
+ const struct jh71x0_reset_map *map;
+};
+
int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
void __iomem *assert, void __iomem *status,
const u32 *asserted, unsigned int nr_resets,
struct module *owner);
+int reset_starfive_jh71x0_register_with_info(struct device *dev, struct device_node *of_node,
+ void __iomem *assert, void __iomem *status,
+ const u32 *asserted,
+ const struct jh71x0_reset_info *info,
+ struct module *owner);
+
#endif /* __RESET_STARFIVE_JH71X0_H */
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v6 15/15] reset: starfive: Add StarFive JHB100 reset driver
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
` (13 preceding siblings ...)
2026-10-08 12:33 ` [PATCH v6 14/15] reset: starfive: jh71x0: Support discontiguous reset IDs Changhuang Liang
@ 2026-10-08 12:33 ` Changhuang Liang
14 siblings, 0 replies; 16+ messages in thread
From: Changhuang Liang @ 2026-10-08 12:33 UTC (permalink / raw)
To: Brian Masney, Jerome Brunet, Stephen Boyd, Philipp Zabel,
Emil Renner Berthing
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-clk,
linux-kernel, linux-riscv, Hal Feng, Changhuang Liang
Add auxiliary reset driver to support StarFive JHB100 SoC.
Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
---
MAINTAINERS | 6 +
drivers/reset/starfive/Kconfig | 9 +
drivers/reset/starfive/Makefile | 1 +
.../reset/starfive/reset-starfive-jhb100.c | 303 ++++++++++++++++++
4 files changed, 319 insertions(+)
create mode 100644 drivers/reset/starfive/reset-starfive-jhb100.c
diff --git a/MAINTAINERS b/MAINTAINERS
index fcba280781b4..d6039e440efb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26660,6 +26660,12 @@ S: Maintained
F: Documentation/devicetree/bindings/pinctrl/starfive,jhb1*.yaml
F: drivers/pinctrl/starfive/pinctrl-starfive-jhb1*
+STARFIVE JHB100 RESET CONTROLLER DRIVERS
+M: Changhuang Liang <changhuang.liang@starfivetech.com>
+S: Supported
+F: drivers/reset/starfive/reset-starfive-jhb1*
+F: include/dt-bindings/reset/starfive,jhb1*.h
+
STATIC BRANCH/CALL
M: Peter Zijlstra <peterz@infradead.org>
M: Josh Poimboeuf <jpoimboe@kernel.org>
diff --git a/drivers/reset/starfive/Kconfig b/drivers/reset/starfive/Kconfig
index d832339f61bc..84baefbaee14 100644
--- a/drivers/reset/starfive/Kconfig
+++ b/drivers/reset/starfive/Kconfig
@@ -19,3 +19,12 @@ config RESET_STARFIVE_JH7110
default ARCH_STARFIVE
help
This enables the reset controller driver for the StarFive JH7110 SoC.
+
+config RESET_STARFIVE_JHB100
+ bool "StarFive JHB100 Reset Driver"
+ depends on CLK_STARFIVE_JH71X0 || COMPILE_TEST
+ select AUXILIARY_BUS
+ select RESET_STARFIVE_JH71X0
+ default ARCH_STARFIVE
+ help
+ This enables the reset controller driver for the StarFive JHB100 SoC.
diff --git a/drivers/reset/starfive/Makefile b/drivers/reset/starfive/Makefile
index 7a44b66fb9d5..d781103355d3 100644
--- a/drivers/reset/starfive/Makefile
+++ b/drivers/reset/starfive/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
obj-$(CONFIG_RESET_STARFIVE_JH7110) += reset-starfive-jh7110.o
+obj-$(CONFIG_RESET_STARFIVE_JHB100) += reset-starfive-jhb100.o
diff --git a/drivers/reset/starfive/reset-starfive-jhb100.c b/drivers/reset/starfive/reset-starfive-jhb100.c
new file mode 100644
index 000000000000..f1fd22179a88
--- /dev/null
+++ b/drivers/reset/starfive/reset-starfive-jhb100.c
@@ -0,0 +1,303 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Reset driver for the StarFive JHB100 SoC
+ *
+ * Copyright (C) 2024 StarFive Technology Co., Ltd.
+ *
+ * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
+ */
+
+#include <dt-bindings/reset/starfive,jhb100-crg.h>
+#include <linux/auxiliary_bus.h>
+#include <soc/starfive/reset-starfive-jh71x0.h>
+
+#include "reset-starfive-jh71x0.h"
+
+#define NUM_RESETS(x) ((x) + 1)
+
+static const struct jh71x0_reset_map jhb100_sys0_map[] = {
+ { JHB100_SYS0RST_RESOURCE_ARB, 0 },
+ { JHB100_SYS0RST_SYS0_IOMUX_PRESETN, 3 },
+ { JHB100_SYS0RST_SYS0H_IOMUX_PRESETN, 4 },
+ { JHB100_SYS0RST_RST_ADAPTOR_TIMEOUT_RSTN, 5 },
+ { JHB100_SYS0RST_BMCPCIERP_RSTN_BUS, 14 },
+ { JHB100_SYS0RST_BMCPCIERP_RSTN_CRG, 15 },
+ { JHB100_SYS0RST_HOSTSS0_RSTN_BUS_ESPI, 16 },
+ { JHB100_SYS0RST_HOSTSS0_RSTN_BUS_PCIE, 17 },
+ { JHB100_SYS0RST_HOSTSS0_RSTN_CRG, 18 },
+ { JHB100_SYS0RST_BMCPERIPH2_RSTN_CRG, 19 },
+ { JHB100_SYS0RST_BMCPERIPH2_RSTN_BUS, 20 },
+ { JHB100_SYS0RST_VCE_RSTN_CRG, 21 },
+ { JHB100_SYS0RST_VCE_RSTN_BUS, 22 },
+ { JHB100_SYS0RST_BMCUSB_RSTN_BUS, 23 },
+ { JHB100_SYS0RST_BMCUSB_RSTN_CRG, 24 },
+};
+
+static const struct jh71x0_reset_info jhb100_sys0_info = {
+ .nr_resets = ARRAY_SIZE(jhb100_sys0_map),
+ .assert_offset = 0x12c,
+ .status_offset = 0x130,
+ .discontiguous = true,
+ .map = jhb100_sys0_map,
+};
+
+static const struct jh71x0_reset_map jhb100_sys1_map[] = {
+ { JHB100_SYS1RST_SYS1_IOMUX_PRESETN, 1 },
+ { JHB100_SYS1RST_MAIN_RSTN_CHIPTOP_SENSOR, 5 },
+ { JHB100_SYS1RST_VOUT_RSTN_HOST0, 8 },
+ { JHB100_SYS1RST_VOUT_RSTN_HOST1, 9 },
+ { JHB100_SYS1RST_HOSTSS1_RSTN_BUS_ESPI, 10 },
+ { JHB100_SYS1RST_HOSTSS1_RSTN_BUS_PCIE, 11 },
+ { JHB100_SYS1RST_HOSTSS1_RSTN_CRG, 12 },
+ { JHB100_SYS1RST_BMCPERIPH3_RSTN_CRG, 13 },
+ { JHB100_SYS1RST_BMCPERIPH3_RSTN_BUS, 14 },
+};
+
+static const struct jh71x0_reset_info jhb100_sys1_info = {
+ .nr_resets = ARRAY_SIZE(jhb100_sys1_map),
+ .assert_offset = 0x54,
+ .status_offset = 0x58,
+ .discontiguous = true,
+ .map = jhb100_sys1_map,
+};
+
+static const struct jh71x0_reset_map jhb100_sys2_map[] = {
+ { JHB100_SYS2RST_JTAG0_MST_WRAP_HRESETN, 2 },
+ { JHB100_SYS2RST_JTAG0_MST_WRAP_APB_PRESETN, 3 },
+ { JHB100_SYS2RST_JTAG1_MST_WRAP_HRESETN, 4 },
+ { JHB100_SYS2RST_JTAG1_MST_WRAP_APB_PRESETN, 5 },
+ { JHB100_SYS2RST_HUSBCMN_HOSTCMN_RSTN_BUS_NCNOC_INIT, 8 },
+ { JHB100_SYS2RST_HUSBCMN_RSTN_HOSTCMN_CRG, 9 },
+ { JHB100_SYS2RST_HUSBCMN_HOSTUSB0_RSTN_BUS_NCNOC_BMC_TARG, 10 },
+ { JHB100_SYS2RST_HUSBCMN_HOSTUSB0_RSTN_BUS_NCNOC_HOST_TARG, 11 },
+ { JHB100_SYS2RST_HUSBCMN_RSTN_BMC_CRG, 12 },
+ { JHB100_SYS2RST_HUSBCMN_RSTN_HOSTUSB0_CRG, 13 },
+ { JHB100_SYS2RST_HUSBCMN_HOSTUSB1_RSTN_BUS_NCNOC_BMC_TARG, 14 },
+ { JHB100_SYS2RST_HUSBCMN_HOSTUSB1_RSTN_BUS_NCNOC_HOST_TARG, 15 },
+ { JHB100_SYS2RST_HUSBCMN_RSTN_HOSTUSB1_CRG, 16 },
+ { JHB100_SYS2RST_BMCPERIPH1_RSTN_CRG, 17 },
+ { JHB100_SYS2RST_BMCPERIPH1_RSTN_BUS, 18 },
+ { JHB100_SYS2RST_BMCPERIPH0_RSTN_CRG, 19 },
+ { JHB100_SYS2RST_BMCPERIPH0_RSTN_BUS, 20 },
+ { JHB100_SYS2RST_GPU0_RSTN_CRG, 21 },
+ { JHB100_SYS2RST_GPU0_RSTN_BUS, 22 },
+ { JHB100_SYS2RST_GPU0_HOST_PCIE_RST_N, 23 },
+ { JHB100_SYS2RST_GPU1_RSTN_CRG, 24 },
+ { JHB100_SYS2RST_GPU1_RSTN_BUS, 25 },
+ { JHB100_SYS2RST_GPU1_HOST_PCIE_RST_N, 26 },
+};
+
+static const struct jh71x0_reset_info jhb100_sys2_info = {
+ .nr_resets = ARRAY_SIZE(jhb100_sys2_map),
+ .assert_offset = 0x88,
+ .status_offset = 0x8c,
+ .discontiguous = true,
+ .map = jhb100_sys2_map,
+};
+
+static const struct jh71x0_reset_map jhb100_per0_map[] = {
+ { JHB100_PER0RST_MAIN_RSTN_UART4, 1 },
+ { JHB100_PER0RST_MAIN_RSTN_UART5, 2 },
+ { JHB100_PER0RST_MAIN_RSTN_UART6, 3 },
+ { JHB100_PER0RST_MAIN_RSTN_UART7, 4 },
+ { JHB100_PER0RST_MAIN_RSTN_UART8, 5 },
+ { JHB100_PER0RST_MAIN_RSTN_UART9, 6 },
+ { JHB100_PER0RST_MAIN_RSTN_UART10, 7 },
+ { JHB100_PER0RST_MAIN_RSTN_UART11, 8 },
+ { JHB100_PER0RST_MAIN_RSTN_UART12, 9 },
+ { JHB100_PER0RST_MAIN_RSTN_UART13, 10 },
+ { JHB100_PER0RST_MAIN_RSTN_UART14, 11 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C0, 12 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C1, 13 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C2, 14 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C3, 15 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C4, 16 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C5, 17 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C6, 18 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C7, 19 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C8, 20 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C9, 21 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C10, 22 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C11, 23 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C12, 24 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C13, 25 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C14, 26 },
+ { JHB100_PER0RST_MAIN_RSTN_I2C15, 27 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C0, 28 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C1, 29 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C2, 30 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C3, 31 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C4, 32 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C5, 33 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C6, 34 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C7, 35 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C8, 36 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C9, 37 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C10, 38 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C11, 39 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C12, 40 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C13, 41 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C14, 42 },
+ { JHB100_PER0RST_MAIN_RSTN_I3C15, 43 },
+ { JHB100_PER0RST_MAIN_RSTN_WDT0, 44 },
+ { JHB100_PER0RST_MAIN_RSTN_WDT1, 45 },
+ { JHB100_PER0RST_MAIN_RSTN_WDT2, 46 },
+ { JHB100_PER0RST_MAIN_RSTN_WDT3, 47 },
+ { JHB100_PER0RST_MAIN_RSTN_WDT4, 48 },
+ { JHB100_PER0RST_MAIN_RSTN_DUALTIMER0, 49 },
+ { JHB100_PER0RST_MAIN_RSTN_DUALTIMER1, 50 },
+ { JHB100_PER0RST_MAIN_RSTN_DUALTIMER2, 51 },
+ { JHB100_PER0RST_MAIN_RSTN_TRNG, 52 },
+ { JHB100_PER0RST_MAIN_RSTN_DMAC0, 53 },
+ { JHB100_PER0RST_MAIN_RSTN_DMAC1, 54 },
+ { JHB100_PER0RST_MAIN_RSTN_DMAC2, 55 },
+ { JHB100_PER0RST_MAIN_RSTN_LTPI0, 56 },
+ { JHB100_PER0RST_MAIN_RSTN_LTPI1, 57 },
+ { JHB100_PER0RST_MAIN_RSTN_SOL4, 58 },
+ { JHB100_PER0RST_MAIN_RSTN_SOL5, 59 },
+ { JHB100_PER0RST_MAIN_RSTN_SOL6, 60 },
+ { JHB100_PER0RST_MAIN_RSTN_SOL7, 61 },
+ { JHB100_PER0RST_MAIN_RSTN_SOL8, 62 },
+ { JHB100_PER0RST_MAIN_RSTN_SOL9, 63 },
+ { JHB100_PER0RST_MAIN_RSTN_SOL10, 64 },
+ { JHB100_PER0RST_MAIN_RSTN_SOL11, 65 },
+ { JHB100_PER0RST_MAIN_RSTN_SOL12, 66 },
+ { JHB100_PER0RST_MAIN_RSTN_SOL13, 67 },
+ { JHB100_PER0RST_MAIN_RSTN_SOL14, 68 },
+ { JHB100_PER0RST_MAIN_RSTN_LDO0, 69 },
+ { JHB100_PER0RST_MAIN_RSTN_LDO1, 70 },
+ { JHB100_PER0RST_MAIN_RSTN_PERIPH0_SENSORS, 71 },
+ { JHB100_PER0RST_MAIN_RSTN_DMAC0_SENSORS, 72 },
+ { JHB100_PER0RST_SYSCON_PRESETN, 73 },
+ { JHB100_PER0RST_GPIO_IOMUX_PRESETN, 74 },
+ { JHB100_PER0RST_UART_MUX_REG_WRAP, 75 },
+};
+
+static const struct jh71x0_reset_info jhb100_per0_info = {
+ .nr_resets = ARRAY_SIZE(jhb100_per0_map),
+ .assert_offset = 0x554,
+ .status_offset = 0x560,
+ .discontiguous = true,
+ .map = jhb100_per0_map,
+};
+
+static const struct jh71x0_reset_map jhb100_per1_map[] = {
+ { JHB100_PER1RST_IOMUX_PRESETN, 0 },
+ { JHB100_PER1RST_SYSCON_PRESETN, 1 },
+ { JHB100_PER1RST_MAIN_RSTN_SFC0, 2 },
+ { JHB100_PER1RST_MAIN_RSTN_SFC1, 3 },
+ { JHB100_PER1RST_MAIN_RSTN_SFC2, 4 },
+ { JHB100_PER1RST_MAIN_RSTN_SPI0, 5 },
+ { JHB100_PER1RST_MAIN_RSTN_PERIPH1_SENSORS, 6 },
+ { JHB100_PER1RST_MAIN_RSTN_SGPIO0, 7 },
+ { JHB100_PER1RST_MAIN_RSTN_SGPIO1, 8 },
+ { JHB100_PER1RST_MAIN_RSTN_EMMC0, 9 },
+ { JHB100_PER1RST_MAIN_RSTN_UFS, 11 },
+ { JHB100_PER1RST_MAIN_RSTN_UFS_PHY, 12 },
+ { JHB100_PER1RST_MAIN_RSTN_DMAC_SFC0, 13 },
+ { JHB100_PER1RST_MAIN_RSTN_DMAC_SFC1, 14 },
+ { JHB100_PER1RST_MAIN_RSTN_DMAC_SFC2, 15 },
+ { JHB100_PER1RST_MAIN_RSTN_DMAC_SPI0, 16 },
+ { JHB100_PER1RST_MAIN_RSTN_PERIPH1_RAS, 17 },
+};
+
+static const struct jh71x0_reset_info jhb100_per1_info = {
+ .nr_resets = ARRAY_SIZE(jhb100_per1_map),
+ .assert_offset = 0x134,
+ .status_offset = 0x138,
+ .discontiguous = true,
+ .map = jhb100_per1_map,
+};
+
+static const struct jh71x0_reset_map jhb100_per2_map[] = {
+ { JHB100_PER2RST_IOMUX_PRESETN, 0 },
+ { JHB100_PER2RST_POK_IOMUX_PRESETN, 1 },
+ { JHB100_PER2RST_SYSREG_RSTN, 2 },
+ { JHB100_PER2RST_MAIN_RSTN_CAN0, 3 },
+ { JHB100_PER2RST_MAIN_RSTN_CAN1, 4 },
+ { JHB100_PER2RST_FAN_TACH_PRESETN, 5 },
+ { JHB100_PER2RST_MAIN_RSTN_GMAC2, 7 },
+ { JHB100_PER2RST_MAIN_RSTN_GMAC3, 8 },
+ { JHB100_PER2RST_MAIN_RSTN_DMAC_8CH, 9 },
+ { JHB100_PER2RST_MAIN_RSTN_RTC, 10 },
+ { JHB100_PER2RST_ADC0_PRESETN, 11 },
+ { JHB100_PER2RST_ADC0_IOMUX_PRESETN, 12 },
+ { JHB100_PER2RST_ADC1_PRESETN, 13 },
+ { JHB100_PER2RST_ADC1_IOMUX_PRESETN, 14 },
+ { JHB100_PER2RST_MAIN_RSTN_PERIPH2_SENSORS, 15 },
+};
+
+static const struct jh71x0_reset_info jhb100_per2_info = {
+ .nr_resets = ARRAY_SIZE(jhb100_per2_map),
+ .assert_offset = 0x11c,
+ .status_offset = 0x120,
+ .discontiguous = true,
+ .map = jhb100_per2_map,
+};
+
+static const struct jh71x0_reset_info jhb100_per3_info = {
+ .nr_resets = NUM_RESETS(JHB100_PER3RST_IOMUX_PRESETN),
+ .assert_offset = 0x98,
+ .status_offset = 0x9c,
+ .discontiguous = false,
+};
+
+static int jhb100_reset_probe(struct auxiliary_device *adev,
+ const struct auxiliary_device_id *id)
+{
+ const struct jh71x0_reset_info *info =
+ (const struct jh71x0_reset_info *)(id->driver_data);
+ struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
+ void __iomem *base = rdev->base;
+
+ if (!info || !base)
+ return -ENODEV;
+
+ return reset_starfive_jh71x0_register_with_info(&adev->dev, adev->dev.parent->of_node,
+ base + info->assert_offset,
+ base + info->status_offset,
+ NULL, info, NULL);
+}
+
+static const struct auxiliary_device_id jhb100_reset_ids[] = {
+ {
+ .name = "clk_starfive_jh71x0.jhb100-r-sys0",
+ .driver_data = (kernel_ulong_t)&jhb100_sys0_info,
+ },
+ {
+ .name = "clk_starfive_jh71x0.jhb100-r-sys1",
+ .driver_data = (kernel_ulong_t)&jhb100_sys1_info,
+ },
+ {
+ .name = "clk_starfive_jh71x0.jhb100-r-sys2",
+ .driver_data = (kernel_ulong_t)&jhb100_sys2_info,
+ },
+ {
+ .name = "clk_starfive_jh71x0.jhb100-r-per0",
+ .driver_data = (kernel_ulong_t)&jhb100_per0_info,
+ },
+ {
+ .name = "clk_starfive_jh71x0.jhb100-r-per1",
+ .driver_data = (kernel_ulong_t)&jhb100_per1_info,
+ },
+ {
+ .name = "clk_starfive_jh71x0.jhb100-r-per2",
+ .driver_data = (kernel_ulong_t)&jhb100_per2_info,
+ },
+ {
+ .name = "clk_starfive_jh71x0.jhb100-r-per3",
+ .driver_data = (kernel_ulong_t)&jhb100_per3_info,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(auxiliary, jhb100_reset_ids);
+
+static struct auxiliary_driver jhb100_reset_driver = {
+ .probe = jhb100_reset_probe,
+ .id_table = jhb100_reset_ids,
+};
+module_auxiliary_driver(jhb100_reset_driver);
+
+MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
+MODULE_DESCRIPTION("StarFive JHB100 reset driver");
+MODULE_LICENSE("GPL");
--
2.25.1
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-10-08 20:09 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-08 12:33 [PATCH v6 00/15] Add basic clocks and resets for JHB100 SoC Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 01/15] clk: starfive: jh7110-sys: Fix memory leak in reset controller register Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 02/15] clk: starfive: jh71x0: Move reset controller registration to jh71x0 common code Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 03/15] reset: starfive: jh7110: Match auxiliary device names to jh71x0 clk driver Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 04/15] clk: starfive: jh71x0: Add generic CRG probe helper Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 05/15] clk: starfive: Add JHB100 System-0 clock generator driver Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 06/15] clk: starfive: Add JHB100 System-1 " Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 07/15] clk: starfive: Add JHB100 System-2 " Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 08/15] clk: starfive: Introduce idiv ops for inverted divider clocks Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 09/15] clk: starfive: Expand the storage of clock parent index Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 10/15] clk: starfive: Add StarFive JHB100 Peripheral-0 clock driver Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 11/15] clk: starfive: Add StarFive JHB100 Peripheral-1 " Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 12/15] clk: starfive: Add StarFive JHB100 Peripheral-2 " Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 13/15] clk: starfive: Add StarFive JHB100 Peripheral-3 " Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 14/15] reset: starfive: jh71x0: Support discontiguous reset IDs Changhuang Liang
2026-10-08 12:33 ` [PATCH v6 15/15] reset: starfive: Add StarFive JHB100 reset driver Changhuang Liang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®