devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RESEND 0/7] clk: spacemit: add K1 reset support
@ 2025-03-21 15:18 Alex Elder
  2025-03-21 15:18 ` [PATCH RESEND 1/7] dt-bindings: soc: spacemit: define spacemit,k1-ccu resets Alex Elder
                   ` (6 more replies)
  0 siblings, 7 replies; 34+ messages in thread
From: Alex Elder @ 2025-03-21 15:18 UTC (permalink / raw)
  To: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, dlan
  Cc: heylenay, guodong, paul.walmsley, palmer, aou, spacemit,
	devicetree, linux-clk, linux-riscv, linux-kernel

(Resending as requested by Yixun, this timing adding the SpacemiT
mailing list to the CC list.)

This series adds reset controller support for the SpacemiT K1 SoC.
It is based on Linux v6.14-rc1.

It is built upon the clock controller driver that Haylen Chu
currently has out for review (currently at v5):
  https://lore.kernel.org/lkml/20250306175750.22480-2-heylenay@4d2.org/

It also depends on two commits that will land in v6.15: 5728c92ae1123
("mfd: syscon: Restore device_node_to_regmap() for non-syscon nodes")
and 7ff4faba63571 ("pinctrl: spacemit: enable config option").

The first patch adds three more system controller CCU nodes to those
implemented by the SpacemiT K1.  The second updates the existing clock
driver with a structure used for OF match data, allowing both clocks
and resets to be specified.  The third provides code that implements
reset functionality.  The fourth defines groups of reset controls
implemented by the CCUs that have alraady been defined.  The fifth
makes it possible for a CCU to be defined with resets but no clocks.
The sixth defines three new CCUs which define only resets.  And the
last patch defines these additional syscon nodes in "k1.dtsi".

All of these patches are available here:
  https://github.com/riscstar/linux/tree/outgoing/reset-v1

					-Alex

Alex Elder (7):
  dt-bindings: soc: spacemit: define spacemit,k1-ccu resets
  clk: spacemit: define struct k1_ccu_data
  clk: spacemit: add reset controller support
  clk: spacemit: define existing syscon resets
  clk: spacemit: make clocks optional
  clk: spacemit: define new syscons with only resets
  riscv: dts: spacemit: add reset support for the K1 SoC

 .../soc/spacemit/spacemit,k1-syscon.yaml      |  13 +-
 arch/riscv/boot/dts/spacemit/k1.dtsi          |  18 +
 drivers/clk/spacemit/ccu-k1.c                 | 393 +++++++++++++++++-
 include/dt-bindings/clock/spacemit,k1-ccu.h   | 134 ++++++
 4 files changed, 539 insertions(+), 19 deletions(-)

-- 
2.43.0


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

* [PATCH RESEND 1/7] dt-bindings: soc: spacemit: define spacemit,k1-ccu resets
  2025-03-21 15:18 [PATCH RESEND 0/7] clk: spacemit: add K1 reset support Alex Elder
@ 2025-03-21 15:18 ` Alex Elder
  2025-03-21 20:42   ` Rob Herring
  2025-03-21 22:25   ` Yixun Lan
  2025-03-21 15:18 ` [PATCH RESEND 2/7] clk: spacemit: define struct k1_ccu_data Alex Elder
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 34+ messages in thread
From: Alex Elder @ 2025-03-21 15:18 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, p.zabel, mturquette, sboyd, dlan
  Cc: heylenay, guodong, paul.walmsley, palmer, aou, spacemit,
	devicetree, linux-clk, linux-riscv, linux-kernel

There are additional SpacemiT syscon CCUs whose registers control both
clocks and resets:  RCPU, RCPU2, and APBC2. Unlike those defined
previously, these will initially support only resets.  They do not
incorporate power domain functionality.

Define the index values for resets associated with all SpacemiT K1
syscon nodes, including those with clocks already defined, as well as
the new ones (without clocks).

Signed-off-by: Alex Elder <elder@riscstar.com>
---
 .../soc/spacemit/spacemit,k1-syscon.yaml      |  13 +-
 include/dt-bindings/clock/spacemit,k1-ccu.h   | 134 ++++++++++++++++++
 2 files changed, 143 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
index 07a6728e6f864..333c28e075b6c 100644
--- a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
+++ b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
@@ -19,6 +19,9 @@ properties:
       - spacemit,k1-syscon-apbc
       - spacemit,k1-syscon-apmu
       - spacemit,k1-syscon-mpmu
+      - spacemit,k1-syscon-rcpu
+      - spacemit,k1-syscon-rcpu2
+      - spacemit,k1-syscon-apbc2
 
   reg:
     maxItems: 1
@@ -57,13 +60,15 @@ allOf:
       properties:
         compatible:
           contains:
-            const: spacemit,k1-syscon-apbc
+            enum:
+              - spacemit,k1-syscon-apmu
+              - spacemit,k1-syscon-mpmu
     then:
-      properties:
-        "#power-domain-cells": false
-    else:
       required:
         - "#power-domain-cells"
+    else:
+      properties:
+        "#power-domain-cells": false
 
 additionalProperties: false
 
diff --git a/include/dt-bindings/clock/spacemit,k1-ccu.h b/include/dt-bindings/clock/spacemit,k1-ccu.h
index 4a0c7163257e3..a1e1b1fe714ce 100644
--- a/include/dt-bindings/clock/spacemit,k1-ccu.h
+++ b/include/dt-bindings/clock/spacemit,k1-ccu.h
@@ -78,6 +78,9 @@
 #define CLK_APB			31
 #define CLK_WDT_BUS		32
 
+/*	MPMU resets	*/
+#define RST_WDT			0
+
 /*	APBC clocks	*/
 #define CLK_UART0		0
 #define CLK_UART2		1
@@ -109,6 +112,7 @@
 #define CLK_PWM17		27
 #define CLK_PWM18		28
 #define CLK_PWM19		29
+
 #define CLK_SSP3		30
 #define CLK_RTC			31
 #define CLK_TWSI0		32
@@ -180,6 +184,60 @@
 #define CLK_TSEN_BUS		98
 #define CLK_IPC_AP2AUD_BUS	99
 
+/*	APBC resets	*/
+
+#define RST_UART0		0
+#define RST_UART2		1
+#define RST_UART3		2
+#define RST_UART4		3
+#define RST_UART5		4
+#define RST_UART6		5
+#define RST_UART7		6
+#define RST_UART8		7
+#define RST_UART9		8
+#define RST_GPIO		9
+#define RST_PWM0		10
+#define RST_PWM1		11
+#define RST_PWM2		12
+#define RST_PWM3		13
+#define RST_PWM4		14
+#define RST_PWM5		15
+#define RST_PWM6		16
+#define RST_PWM7		17
+#define RST_PWM8		18
+#define RST_PWM9		19
+#define RST_PWM10		20
+#define RST_PWM11		21
+#define RST_PWM12		22
+#define RST_PWM13		23
+#define RST_PWM14		24
+#define RST_PWM15		25
+#define RST_PWM16		26
+#define RST_PWM17		27
+#define RST_PWM18		28
+#define RST_PWM19		29
+#define RST_SSP3		30
+#define RST_RTC			31
+#define RST_TWSI0		32
+#define RST_TWSI1		33
+#define RST_TWSI2		34
+#define RST_TWSI4		35
+#define RST_TWSI5		36
+#define RST_TWSI6		37
+#define RST_TWSI7		38
+#define RST_TWSI8		39
+#define RST_TIMERS1		40
+#define RST_TIMERS2		41
+#define RST_AIB			42
+#define RST_ONEWIRE		43
+#define RST_SSPA0		44
+#define RST_SSPA1		45
+#define RST_DRO			46
+#define RST_IR			47
+#define RST_TSEN		48
+#define RST_IPC_AP2AUD		49
+#define RST_CAN0		50
+
 /*	APMU clocks	*/
 #define CLK_CCI550		0
 #define CLK_CPU_C0_HI		1
@@ -244,4 +302,80 @@
 #define CLK_V2D			60
 #define CLK_EMMC_BUS		61
 
+/*	APMU resets	*/
+
+#define RST_CCIC_4X		0
+#define RST_CCIC1_PHY		1
+#define RST_SDH_AXI		2
+#define RST_SDH0		3
+#define RST_SDH1		4
+#define RST_SDH2		5
+#define RST_USBP1_AXI		6
+#define RST_USB_AXI		7
+#define RST_USB3_0		8
+#define RST_QSPI		9
+#define RST_QSPI_BUS		10
+#define RST_DMA			11
+#define RST_AES			12
+#define RST_VPU			13
+#define RST_GPU			14
+#define RST_EMMC		15
+#define RST_EMMC_X		16
+#define RST_AUDIO		17
+#define RST_HDMI		18
+#define RST_PCIE0		19
+#define RST_PCIE1		20
+#define RST_PCIE2		21
+#define RST_EMAC0		22
+#define RST_EMAC1		23
+#define RST_JPG			24
+#define RST_CCIC2PHY		25
+#define RST_CCIC3PHY		26
+#define RST_CSI			27
+#define RST_ISP_CPP		28
+#define RST_ISP_BUS		29
+#define RST_ISP			30
+#define RST_ISP_CI		31
+#define RST_DPU_MCLK		32
+#define RST_DPU_ESC		33
+#define RST_DPU_HCLK		34
+#define RST_DPU_SPIBUS		35
+#define RST_DPU_SPI_HBUS	36
+#define RST_V2D			37
+#define RST_MIPI		38
+#define RST_MC			39
+
+/*	RCPU resets	*/
+
+#define RST_RCPU_SSP0		0
+#define RST_RCPU_I2C0		1
+#define RST_RCPU_UART1		2
+#define RST_RCPU_IR		3
+#define RST_RCPU_CAN		4
+#define RST_RCPU_UART0		5
+#define RST_RCPU_HDMI_AUDIO	6
+
+/*	RCPU2 resets	*/
+
+#define RST_RCPU2_PWM0		0
+#define RST_RCPU2_PWM1		1
+#define RST_RCPU2_PWM2		2
+#define RST_RCPU2_PWM3		3
+#define RST_RCPU2_PWM4		4
+#define RST_RCPU2_PWM5		5
+#define RST_RCPU2_PWM6		6
+#define RST_RCPU2_PWM7		7
+#define RST_RCPU2_PWM8		8
+#define RST_RCPU2_PWM9		9
+
+/*	APBC2 resets	*/
+
+#define RST_APBC2_UART1		0
+#define RST_APBC2_SSP2		1
+#define RST_APBC2_TWSI3		2
+#define RST_APBC2_RTC		3
+#define RST_APBC2_TIMERS0	4
+#define RST_APBC2_KPC		5
+#define RST_APBC2_GPIO		6
+
 #endif /* _DT_BINDINGS_SPACEMIT_CCU_H_ */
-- 
2.43.0


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

* [PATCH RESEND 2/7] clk: spacemit: define struct k1_ccu_data
  2025-03-21 15:18 [PATCH RESEND 0/7] clk: spacemit: add K1 reset support Alex Elder
  2025-03-21 15:18 ` [PATCH RESEND 1/7] dt-bindings: soc: spacemit: define spacemit,k1-ccu resets Alex Elder
@ 2025-03-21 15:18 ` Alex Elder
  2025-03-22 15:50   ` Yixun Lan
  2025-03-24 11:53   ` Haylen Chu
  2025-03-21 15:18 ` [PATCH RESEND 3/7] clk: spacemit: add reset controller support Alex Elder
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 34+ messages in thread
From: Alex Elder @ 2025-03-21 15:18 UTC (permalink / raw)
  To: p.zabel, mturquette, sboyd, dlan
  Cc: robh, krzk+dt, conor+dt, heylenay, guodong, paul.walmsley, palmer,
	aou, spacemit, devicetree, linux-clk, linux-riscv, linux-kernel

Define a new structure type to be used for describing the OF match data.
Rather than using the array of spacemit_ccu_clk structures for match
data, we use this structure instead.

Move the definition of the spacemit_ccu_clk structure closer to the top
of the source file, and add the new structure definition below it.

Shorten the name of spacemit_ccu_register() to be k1_ccu_register().

Signed-off-by: Alex Elder <elder@riscstar.com>
---
 drivers/clk/spacemit/ccu-k1.c | 58 ++++++++++++++++++++++++++---------
 1 file changed, 43 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
index 44db48ae71313..f7367271396a0 100644
--- a/drivers/clk/spacemit/ccu-k1.c
+++ b/drivers/clk/spacemit/ccu-k1.c
@@ -129,6 +129,15 @@
 #define APMU_EMAC0_CLK_RES_CTRL		0x3e4
 #define APMU_EMAC1_CLK_RES_CTRL		0x3ec
 
+struct spacemit_ccu_clk {
+	int id;
+	struct clk_hw *hw;
+};
+
+struct k1_ccu_data {
+	struct spacemit_ccu_clk *clk;		/* array with sentinel */
+};
+
 /*	APBS clocks start	*/
 
 /* Frequency of pll{1,2} should not be updated at runtime */
@@ -1359,11 +1368,6 @@ static CCU_GATE_DEFINE(emmc_bus_clk, CCU_PARENT_HW(pmua_aclk),
 		       0);
 /*	APMU clocks end		*/
 
-struct spacemit_ccu_clk {
-	int id;
-	struct clk_hw *hw;
-};
-
 static struct spacemit_ccu_clk k1_ccu_apbs_clks[] = {
 	{ CLK_PLL1,		&pll1.common.hw },
 	{ CLK_PLL2,		&pll2.common.hw },
@@ -1403,6 +1407,10 @@ static struct spacemit_ccu_clk k1_ccu_apbs_clks[] = {
 	{ 0,			NULL },
 };
 
+static const struct k1_ccu_data k1_ccu_apbs_data = {
+	.clk		= k1_ccu_apbs_clks,
+};
+
 static struct spacemit_ccu_clk k1_ccu_mpmu_clks[] = {
 	{ CLK_PLL1_307P2,	&pll1_d8_307p2.common.hw },
 	{ CLK_PLL1_76P8,	&pll1_d32_76p8.common.hw },
@@ -1440,6 +1448,10 @@ static struct spacemit_ccu_clk k1_ccu_mpmu_clks[] = {
 	{ 0,			NULL },
 };
 
+static const struct k1_ccu_data k1_ccu_mpmu_data = {
+	.clk		= k1_ccu_mpmu_clks,
+};
+
 static struct spacemit_ccu_clk k1_ccu_apbc_clks[] = {
 	{ CLK_UART0,		&uart0_clk.common.hw },
 	{ CLK_UART2,		&uart2_clk.common.hw },
@@ -1544,6 +1556,10 @@ static struct spacemit_ccu_clk k1_ccu_apbc_clks[] = {
 	{ 0,			NULL },
 };
 
+static const struct k1_ccu_data k1_ccu_apbc_data = {
+	.clk		= k1_ccu_apbc_clks,
+};
+
 static struct spacemit_ccu_clk k1_ccu_apmu_clks[] = {
 	{ CLK_CCI550,		&cci550_clk.common.hw },
 	{ CLK_CPU_C0_HI,	&cpu_c0_hi_clk.common.hw },
@@ -1610,9 +1626,13 @@ static struct spacemit_ccu_clk k1_ccu_apmu_clks[] = {
 	{ 0,			NULL },
 };
 
-static int spacemit_ccu_register(struct device *dev,
-				 struct regmap *regmap, struct regmap *lock_regmap,
-				 const struct spacemit_ccu_clk *clks)
+static const struct k1_ccu_data k1_ccu_apmu_data = {
+	.clk		= k1_ccu_apmu_clks,
+};
+
+static int k1_ccu_register(struct device *dev, struct regmap *regmap,
+			   struct regmap *lock_regmap,
+			   struct spacemit_ccu_clk *clks)
 {
 	const struct spacemit_ccu_clk *clk;
 	int i, ret, max_id = 0;
@@ -1648,15 +1668,24 @@ static int spacemit_ccu_register(struct device *dev,
 
 	clk_data->num = max_id + 1;
 
-	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+	if (ret)
+		dev_err(dev, "error %d adding clock hardware provider\n", ret);
+
+	return ret;
 }
 
 static int k1_ccu_probe(struct platform_device *pdev)
 {
 	struct regmap *base_regmap, *lock_regmap = NULL;
 	struct device *dev = &pdev->dev;
+	const struct k1_ccu_data *data;
 	int ret;
 
+	data = of_device_get_match_data(dev);
+	if (!data)
+		return -EINVAL;
+
 	base_regmap = device_node_to_regmap(dev->of_node);
 	if (IS_ERR(base_regmap))
 		return dev_err_probe(dev, PTR_ERR(base_regmap),
@@ -1677,8 +1706,7 @@ static int k1_ccu_probe(struct platform_device *pdev)
 					     "failed to get lock regmap\n");
 	}
 
-	ret = spacemit_ccu_register(dev, base_regmap, lock_regmap,
-				    of_device_get_match_data(dev));
+	ret = k1_ccu_register(dev, base_regmap, lock_regmap, data->clk);
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to register clocks\n");
 
@@ -1688,19 +1716,19 @@ static int k1_ccu_probe(struct platform_device *pdev)
 static const struct of_device_id of_k1_ccu_match[] = {
 	{
 		.compatible	= "spacemit,k1-pll",
-		.data		= k1_ccu_apbs_clks,
+		.data		= &k1_ccu_apbs_data,
 	},
 	{
 		.compatible	= "spacemit,k1-syscon-mpmu",
-		.data		= k1_ccu_mpmu_clks,
+		.data		= &k1_ccu_mpmu_data,
 	},
 	{
 		.compatible	= "spacemit,k1-syscon-apbc",
-		.data		= k1_ccu_apbc_clks,
+		.data		= &k1_ccu_apbc_data,
 	},
 	{
 		.compatible	= "spacemit,k1-syscon-apmu",
-		.data		= k1_ccu_apmu_clks,
+		.data		= &k1_ccu_apmu_data,
 	},
 	{ }
 };
-- 
2.43.0


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

* [PATCH RESEND 3/7] clk: spacemit: add reset controller support
  2025-03-21 15:18 [PATCH RESEND 0/7] clk: spacemit: add K1 reset support Alex Elder
  2025-03-21 15:18 ` [PATCH RESEND 1/7] dt-bindings: soc: spacemit: define spacemit,k1-ccu resets Alex Elder
  2025-03-21 15:18 ` [PATCH RESEND 2/7] clk: spacemit: define struct k1_ccu_data Alex Elder
@ 2025-03-21 15:18 ` Alex Elder
  2025-03-22 16:19   ` Yixun Lan
  2025-03-24 12:20   ` Haylen Chu
  2025-03-21 15:18 ` [PATCH RESEND 4/7] clk: spacemit: define existing syscon resets Alex Elder
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 34+ messages in thread
From: Alex Elder @ 2025-03-21 15:18 UTC (permalink / raw)
  To: p.zabel, mturquette, sboyd, dlan
  Cc: robh, krzk+dt, conor+dt, heylenay, guodong, paul.walmsley, palmer,
	aou, spacemit, devicetree, linux-clk, linux-riscv, linux-kernel

Define ccu_reset_data as a structure that contains the constant
register offset and bitmasks used to assert and deassert a reset
control on a SpacemiT K1 CCU. Define ccu_reset_controller_data as
a structure that contains the address of an array of those structures
and a count of the number of elements in the array.

Add a pointer to a ccu_reset_controller_data structure to the
k1_ccu_data structure.  Reset support is optional for SpacemiT CCUs;
the new pointer field will be null for CCUs without any resets.

Finally, define a new ccu_reset_controller structure, which (for
a CCU with resets) contains a pointer to the constant reset data,
the regmap to be used for the controller, and an embedded a reset
controller structure.

Each reset control is asserted or deasserted by updating bits in
a register.  The bits used are defined by an assert mask and a
deassert mask.  In some cases, one (non-zero) mask asserts reset
and a different (non-zero) mask deasserts it.  Otherwise one mask
is nonzero, and the other is zero.  Either way, the bits in
both masks are cleared, then either the assert mask or the deassert
mask is set in a register to affect the state of a reset control.

Signed-off-by: Alex Elder <elder@riscstar.com>
---
 drivers/clk/spacemit/ccu-k1.c | 93 +++++++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
index f7367271396a0..6d879411c6c05 100644
--- a/drivers/clk/spacemit/ccu-k1.c
+++ b/drivers/clk/spacemit/ccu-k1.c
@@ -10,6 +10,7 @@
 #include <linux/minmax.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/reset-controller.h>
 
 #include "ccu_common.h"
 #include "ccu_pll.h"
@@ -134,8 +135,26 @@ struct spacemit_ccu_clk {
 	struct clk_hw *hw;
 };
 
+struct ccu_reset_data {
+	u32 offset;
+	u32 assert_mask;
+	u32 deassert_mask;
+};
+
+struct ccu_reset_controller_data {
+	u32 count;
+	const struct ccu_reset_data *data;	/* array */
+};
+
 struct k1_ccu_data {
 	struct spacemit_ccu_clk *clk;		/* array with sentinel */
+	const struct ccu_reset_controller_data *rst_data;
+};
+
+struct ccu_reset_controller {
+	struct regmap *regmap;
+	const struct ccu_reset_controller_data *data;
+	struct reset_controller_dev rcdev;
 };
 
 /*	APBS clocks start	*/
@@ -1630,6 +1649,48 @@ static const struct k1_ccu_data k1_ccu_apmu_data = {
 	.clk		= k1_ccu_apmu_clks,
 };
 
+static struct ccu_reset_controller *
+rcdev_to_controller(struct reset_controller_dev *rcdev)
+{
+	return container_of(rcdev, struct ccu_reset_controller, rcdev);
+}
+
+static int
+k1_rst_update(struct reset_controller_dev *rcdev, unsigned long id, bool assert)
+{
+	struct ccu_reset_controller *controller = rcdev_to_controller(rcdev);
+	struct regmap *regmap = controller->regmap;
+	const struct ccu_reset_data *data;
+	u32 val;
+	int ret;
+
+	data = &controller->data->data[id];
+
+	ret = regmap_read(regmap, data->offset, &val);
+	if (ret)
+		return ret;
+
+	val &= ~(data->assert_mask | data->deassert_mask);
+	val |= assert ? data->assert_mask : data->deassert_mask;
+
+	return regmap_write(regmap, data->offset, val);
+}
+
+static int k1_rst_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	return k1_rst_update(rcdev, id, true);
+}
+
+static int k1_rst_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	return k1_rst_update(rcdev, id, false);
+}
+
+static const struct reset_control_ops k1_reset_control_ops = {
+	.assert		= k1_rst_assert,
+	.deassert	= k1_rst_deassert,
+};
+
 static int k1_ccu_register(struct device *dev, struct regmap *regmap,
 			   struct regmap *lock_regmap,
 			   struct spacemit_ccu_clk *clks)
@@ -1675,6 +1736,33 @@ static int k1_ccu_register(struct device *dev, struct regmap *regmap,
 	return ret;
 }
 
+static int
+k1_reset_controller_register(struct device *dev, struct regmap *regmap,
+			     const struct ccu_reset_controller_data *data)
+{
+	struct ccu_reset_controller *controller;
+	struct reset_controller_dev *rcdev;
+
+	/* Resets are optional */
+	if (!data)
+		return 0;
+
+	controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL);
+	if (!controller)
+		return -ENOMEM;
+
+	controller->regmap = regmap;
+	controller->data = data;
+
+	rcdev = &controller->rcdev;
+	rcdev->owner = THIS_MODULE;
+	rcdev->nr_resets = data->count;
+	rcdev->ops = &k1_reset_control_ops;
+	rcdev->of_node = dev->of_node;
+
+	return devm_reset_controller_register(dev, rcdev);
+}
+
 static int k1_ccu_probe(struct platform_device *pdev)
 {
 	struct regmap *base_regmap, *lock_regmap = NULL;
@@ -1710,6 +1798,11 @@ static int k1_ccu_probe(struct platform_device *pdev)
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to register clocks\n");
 
+	ret = k1_reset_controller_register(dev, base_regmap, data->rst_data);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to register reset controller\n");
+
 	return 0;
 }
 
-- 
2.43.0


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

* [PATCH RESEND 4/7] clk: spacemit: define existing syscon resets
  2025-03-21 15:18 [PATCH RESEND 0/7] clk: spacemit: add K1 reset support Alex Elder
                   ` (2 preceding siblings ...)
  2025-03-21 15:18 ` [PATCH RESEND 3/7] clk: spacemit: add reset controller support Alex Elder
@ 2025-03-21 15:18 ` Alex Elder
  2025-03-22 16:29   ` Yixun Lan
  2025-03-21 15:18 ` [PATCH RESEND 5/7] clk: spacemit: make clocks optional Alex Elder
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 34+ messages in thread
From: Alex Elder @ 2025-03-21 15:18 UTC (permalink / raw)
  To: p.zabel, mturquette, sboyd, dlan
  Cc: robh, krzk+dt, conor+dt, heylenay, guodong, paul.walmsley, palmer,
	aou, spacemit, devicetree, linux-clk, linux-riscv, linux-kernel

Define reset controls associated with the MPMU, APBC, and APMU
SpacemiT K1 CCUs.  These already have clocks associated with them.

Signed-off-by: Alex Elder <elder@riscstar.com>
---
 drivers/clk/spacemit/ccu-k1.c | 132 ++++++++++++++++++++++++++++++++++
 1 file changed, 132 insertions(+)

diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
index 6d879411c6c05..be8abd27753cb 100644
--- a/drivers/clk/spacemit/ccu-k1.c
+++ b/drivers/clk/spacemit/ccu-k1.c
@@ -151,6 +151,13 @@ struct k1_ccu_data {
 	const struct ccu_reset_controller_data *rst_data;
 };
 
+#define RST_DATA(_offset, _assert_mask, _deassert_mask)	\
+	{						\
+		.offset		= (_offset),		\
+		.assert_mask	= (_assert_mask),	\
+		.deassert_mask	= (_deassert_mask),	\
+	}
+
 struct ccu_reset_controller {
 	struct regmap *regmap;
 	const struct ccu_reset_controller_data *data;
@@ -1428,6 +1435,7 @@ static struct spacemit_ccu_clk k1_ccu_apbs_clks[] = {
 
 static const struct k1_ccu_data k1_ccu_apbs_data = {
 	.clk		= k1_ccu_apbs_clks,
+	/* No resets in the APBS CCU */
 };
 
 static struct spacemit_ccu_clk k1_ccu_mpmu_clks[] = {
@@ -1467,8 +1475,18 @@ static struct spacemit_ccu_clk k1_ccu_mpmu_clks[] = {
 	{ 0,			NULL },
 };
 
+static const struct ccu_reset_data mpmu_reset_data[] = {
+	[RST_WDT]	= RST_DATA(MPMU_WDTPCR,			BIT(2), 0),
+};
+
+static const struct ccu_reset_controller_data mpmu_reset_controller_data = {
+	.count		= ARRAY_SIZE(mpmu_reset_data),
+	.data		= mpmu_reset_data,
+};
+
 static const struct k1_ccu_data k1_ccu_mpmu_data = {
 	.clk		= k1_ccu_mpmu_clks,
+	.rst_data	= &mpmu_reset_controller_data,
 };
 
 static struct spacemit_ccu_clk k1_ccu_apbc_clks[] = {
@@ -1575,8 +1593,68 @@ static struct spacemit_ccu_clk k1_ccu_apbc_clks[] = {
 	{ 0,			NULL },
 };
 
+static const struct ccu_reset_data apbc_reset_data[] = {
+	[RST_UART0]	= RST_DATA(APBC_UART1_CLK_RST,		BIT(2),	0),
+	[RST_UART2]	= RST_DATA(APBC_UART2_CLK_RST,		BIT(2), 0),
+	[RST_GPIO]	= RST_DATA(APBC_GPIO_CLK_RST,		BIT(2), 0),
+	[RST_PWM0]	= RST_DATA(APBC_PWM0_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM1]	= RST_DATA(APBC_PWM1_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM2]	= RST_DATA(APBC_PWM2_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM3]	= RST_DATA(APBC_PWM3_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM4]	= RST_DATA(APBC_PWM4_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM5]	= RST_DATA(APBC_PWM5_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM6]	= RST_DATA(APBC_PWM6_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM7]	= RST_DATA(APBC_PWM7_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM8]	= RST_DATA(APBC_PWM8_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM9]	= RST_DATA(APBC_PWM9_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM10]	= RST_DATA(APBC_PWM10_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM11]	= RST_DATA(APBC_PWM11_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM12]	= RST_DATA(APBC_PWM12_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM13]	= RST_DATA(APBC_PWM13_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM14]	= RST_DATA(APBC_PWM14_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM15]	= RST_DATA(APBC_PWM15_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM16]	= RST_DATA(APBC_PWM16_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM17]	= RST_DATA(APBC_PWM17_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM18]	= RST_DATA(APBC_PWM18_CLK_RST,		BIT(2), BIT(0)),
+	[RST_PWM19]	= RST_DATA(APBC_PWM19_CLK_RST,		BIT(2), BIT(0)),
+	[RST_SSP3]	= RST_DATA(APBC_SSP3_CLK_RST,		BIT(2), 0),
+	[RST_UART3]	= RST_DATA(APBC_UART3_CLK_RST,		BIT(2), 0),
+	[RST_RTC]	= RST_DATA(APBC_RTC_CLK_RST,		BIT(2), 0),
+	[RST_TWSI0]	= RST_DATA(APBC_TWSI0_CLK_RST,		BIT(2), 0),
+	[RST_TIMERS1]	= RST_DATA(APBC_TIMERS1_CLK_RST,	BIT(2), 0),
+	[RST_AIB]	= RST_DATA(APBC_AIB_CLK_RST,		BIT(2), 0),
+	[RST_TIMERS2]	= RST_DATA(APBC_TIMERS2_CLK_RST,	BIT(2), 0),
+	[RST_ONEWIRE]	= RST_DATA(APBC_ONEWIRE_CLK_RST,	BIT(2), 0),
+	[RST_SSPA0]	= RST_DATA(APBC_SSPA0_CLK_RST,		BIT(2), 0),
+	[RST_SSPA1]	= RST_DATA(APBC_SSPA1_CLK_RST,		BIT(2), 0),
+	[RST_DRO]	= RST_DATA(APBC_DRO_CLK_RST,		BIT(2), 0),
+	[RST_IR]	= RST_DATA(APBC_IR_CLK_RST,		BIT(2), 0),
+	[RST_TWSI1]	= RST_DATA(APBC_TWSI1_CLK_RST,		BIT(2), 0),
+	[RST_TSEN]	= RST_DATA(APBC_TSEN_CLK_RST,		BIT(2), 0),
+	[RST_TWSI2]	= RST_DATA(APBC_TWSI2_CLK_RST,		BIT(2), 0),
+	[RST_TWSI4]	= RST_DATA(APBC_TWSI4_CLK_RST,		BIT(2), 0),
+	[RST_TWSI5]	= RST_DATA(APBC_TWSI5_CLK_RST,		BIT(2), 0),
+	[RST_TWSI6]	= RST_DATA(APBC_TWSI6_CLK_RST,		BIT(2), 0),
+	[RST_TWSI7]	= RST_DATA(APBC_TWSI7_CLK_RST,		BIT(2), 0),
+	[RST_TWSI8]	= RST_DATA(APBC_TWSI8_CLK_RST,		BIT(2), 0),
+	[RST_IPC_AP2AUD] = RST_DATA(APBC_IPC_AP2AUD_CLK_RST,	BIT(2), 0),
+	[RST_UART4]	= RST_DATA(APBC_UART4_CLK_RST,		BIT(2), 0),
+	[RST_UART5]	= RST_DATA(APBC_UART5_CLK_RST,		BIT(2), 0),
+	[RST_UART6]	= RST_DATA(APBC_UART6_CLK_RST,		BIT(2), 0),
+	[RST_UART7]	= RST_DATA(APBC_UART7_CLK_RST,		BIT(2), 0),
+	[RST_UART8]	= RST_DATA(APBC_UART8_CLK_RST,		BIT(2), 0),
+	[RST_UART9]	= RST_DATA(APBC_UART9_CLK_RST,		BIT(2), 0),
+	[RST_CAN0]	= RST_DATA(APBC_CAN0_CLK_RST,		BIT(2), 0),
+};
+
+static const struct ccu_reset_controller_data apbc_reset_controller_data = {
+	.count		= ARRAY_SIZE(apbc_reset_data),
+	.data		= apbc_reset_data,
+};
+
 static const struct k1_ccu_data k1_ccu_apbc_data = {
 	.clk		= k1_ccu_apbc_clks,
+	.rst_data	= &apbc_reset_controller_data,
 };
 
 static struct spacemit_ccu_clk k1_ccu_apmu_clks[] = {
@@ -1645,8 +1723,62 @@ static struct spacemit_ccu_clk k1_ccu_apmu_clks[] = {
 	{ 0,			NULL },
 };
 
+static const struct ccu_reset_data apmu_reset_data[] = {
+	[RST_CCIC_4X]	= RST_DATA(APMU_CCIC_CLK_RES_CTRL,	0, BIT(1)),
+	[RST_CCIC1_PHY] = RST_DATA(APMU_CCIC_CLK_RES_CTRL,	0, BIT(2)),
+	[RST_SDH_AXI]	= RST_DATA(APMU_SDH0_CLK_RES_CTRL,	0, BIT(0)),
+	[RST_SDH0]	= RST_DATA(APMU_SDH0_CLK_RES_CTRL,	0, BIT(1)),
+	[RST_SDH1]	= RST_DATA(APMU_SDH1_CLK_RES_CTRL,	0, BIT(1)),
+	[RST_SDH2]	= RST_DATA(APMU_SDH2_CLK_RES_CTRL,	0, BIT(1)),
+	[RST_USBP1_AXI] = RST_DATA(APMU_USB_CLK_RES_CTRL,	0, BIT(4)),
+	[RST_USB_AXI]	= RST_DATA(APMU_USB_CLK_RES_CTRL,	0, BIT(0)),
+	[RST_USB3_0]	= RST_DATA(APMU_USB_CLK_RES_CTRL,	0,
+				      BIT(9)|BIT(10)|BIT(11)),
+	[RST_QSPI]	= RST_DATA(APMU_QSPI_CLK_RES_CTRL,	0, BIT(1)),
+	[RST_QSPI_BUS] = RST_DATA(APMU_QSPI_CLK_RES_CTRL,	0, BIT(0)),
+	[RST_DMA]	= RST_DATA(APMU_DMA_CLK_RES_CTRL,	0, BIT(0)),
+	[RST_AES]	= RST_DATA(APMU_AES_CLK_RES_CTRL,	0, BIT(4)),
+	[RST_VPU]	= RST_DATA(APMU_VPU_CLK_RES_CTRL,	0, BIT(0)),
+	[RST_GPU]	= RST_DATA(APMU_GPU_CLK_RES_CTRL,	0, BIT(1)),
+	[RST_EMMC]	= RST_DATA(APMU_PMUA_EM_CLK_RES_CTRL,	0, BIT(1)),
+	[RST_EMMC_X]	= RST_DATA(APMU_PMUA_EM_CLK_RES_CTRL,	0, BIT(0)),
+	[RST_AUDIO]	= RST_DATA(APMU_AUDIO_CLK_RES_CTRL,	0,
+				   BIT(0) | BIT(2) | BIT(3)),
+	[RST_HDMI]	= RST_DATA(APMU_HDMI_CLK_RES_CTRL,	0, BIT(9)),
+	[RST_PCIE0]	= RST_DATA(APMU_PCIE_CLK_RES_CTRL_0,	BIT(8),
+				   BIT(3) | BIT(4) | BIT(5)),
+	[RST_PCIE1]	= RST_DATA(APMU_PCIE_CLK_RES_CTRL_1,	BIT(8),
+				   BIT(3) | BIT(4) | BIT(5)),
+	[RST_PCIE2]	= RST_DATA(APMU_PCIE_CLK_RES_CTRL_2,	BIT(8),
+				   BIT(3) | BIT(4) | BIT(5)),
+	[RST_EMAC0]	= RST_DATA(APMU_EMAC0_CLK_RES_CTRL,	0, BIT(1)),
+	[RST_EMAC1]	= RST_DATA(APMU_EMAC1_CLK_RES_CTRL,	0, BIT(1)),
+	[RST_JPG]	= RST_DATA(APMU_JPG_CLK_RES_CTRL,	0, BIT(0)),
+	[RST_CCIC2PHY]	= RST_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL,	0, BIT(2)),
+	[RST_CCIC3PHY]	= RST_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL,	0, BIT(29)),
+	[RST_CSI]	= RST_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL,	0, BIT(1)),
+	[RST_ISP]	= RST_DATA(APMU_ISP_CLK_RES_CTRL,	0, BIT(0)),
+	[RST_ISP_CPP]	= RST_DATA(APMU_ISP_CLK_RES_CTRL,	0, BIT(27)),
+	[RST_ISP_BUS]	= RST_DATA(APMU_ISP_CLK_RES_CTRL,	0, BIT(3)),
+	[RST_ISP_CI]	= RST_DATA(APMU_ISP_CLK_RES_CTRL,	0, BIT(16)),
+	[RST_DPU_MCLK]	= RST_DATA(APMU_LCD_CLK_RES_CTRL2,	0, BIT(9)),
+	[RST_DPU_ESC]	= RST_DATA(APMU_LCD_CLK_RES_CTRL1,	0, BIT(3)),
+	[RST_DPU_HCLK]	= RST_DATA(APMU_LCD_CLK_RES_CTRL1,	0, BIT(4)),
+	[RST_DPU_SPIBUS] = RST_DATA(APMU_LCD_SPI_CLK_RES_CTRL,	0, BIT(4)),
+	[RST_DPU_SPI_HBUS] = RST_DATA(APMU_LCD_SPI_CLK_RES_CTRL, 0, BIT(2)),
+	[RST_V2D]	= RST_DATA(APMU_LCD_CLK_RES_CTRL1,	0, BIT(27)),
+	[RST_MIPI]	= RST_DATA(APMU_LCD_CLK_RES_CTRL1,	0, BIT(15)),
+	[RST_MC]	= RST_DATA(APMU_PMUA_MC_CTRL,		0, BIT(0)),
+};
+
+static const struct ccu_reset_controller_data apmu_reset_controller_data = {
+	.count		= ARRAY_SIZE(apmu_reset_data),
+	.data		= apmu_reset_data,
+};
+
 static const struct k1_ccu_data k1_ccu_apmu_data = {
 	.clk		= k1_ccu_apmu_clks,
+	.rst_data	= &apmu_reset_controller_data,
 };
 
 static struct ccu_reset_controller *
-- 
2.43.0


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

* [PATCH RESEND 5/7] clk: spacemit: make clocks optional
  2025-03-21 15:18 [PATCH RESEND 0/7] clk: spacemit: add K1 reset support Alex Elder
                   ` (3 preceding siblings ...)
  2025-03-21 15:18 ` [PATCH RESEND 4/7] clk: spacemit: define existing syscon resets Alex Elder
@ 2025-03-21 15:18 ` Alex Elder
  2025-03-21 15:18 ` [PATCH RESEND 6/7] clk: spacemit: define new syscons with only resets Alex Elder
  2025-03-21 15:18 ` [PATCH RESEND 7/7] riscv: dts: spacemit: add reset support for the K1 SoC Alex Elder
  6 siblings, 0 replies; 34+ messages in thread
From: Alex Elder @ 2025-03-21 15:18 UTC (permalink / raw)
  To: p.zabel, mturquette, sboyd, dlan
  Cc: robh, krzk+dt, conor+dt, heylenay, guodong, paul.walmsley, palmer,
	aou, spacemit, devicetree, linux-clk, linux-riscv, linux-kernel

There are some syscon devices that support both clocks and resets,
but for now only their reset functionality is required.  Make
defining clocks optional for a SpacemiT CCU, though at least one
clock or at least one reset controller must be defined.

Signed-off-by: Alex Elder <elder@riscstar.com>
---
 drivers/clk/spacemit/ccu-k1.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
index be8abd27753cb..17e321c25959a 100644
--- a/drivers/clk/spacemit/ccu-k1.c
+++ b/drivers/clk/spacemit/ccu-k1.c
@@ -1830,6 +1830,10 @@ static int k1_ccu_register(struct device *dev, struct regmap *regmap,
 	const struct spacemit_ccu_clk *clk;
 	int i, ret, max_id = 0;
 
+	/* Clocks are optional */
+	if (!clks)
+		return 0;
+
 	for (clk = clks; clk->hw; clk++)
 		max_id = max(max_id, clk->id);
 
@@ -1903,7 +1907,7 @@ static int k1_ccu_probe(struct platform_device *pdev)
 	int ret;
 
 	data = of_device_get_match_data(dev);
-	if (!data)
+	if (!data || !(data->clk || data->rst_data))
 		return -EINVAL;
 
 	base_regmap = device_node_to_regmap(dev->of_node);
-- 
2.43.0


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

* [PATCH RESEND 6/7] clk: spacemit: define new syscons with only resets
  2025-03-21 15:18 [PATCH RESEND 0/7] clk: spacemit: add K1 reset support Alex Elder
                   ` (4 preceding siblings ...)
  2025-03-21 15:18 ` [PATCH RESEND 5/7] clk: spacemit: make clocks optional Alex Elder
@ 2025-03-21 15:18 ` Alex Elder
  2025-03-22 16:42   ` Yixun Lan
  2025-03-21 15:18 ` [PATCH RESEND 7/7] riscv: dts: spacemit: add reset support for the K1 SoC Alex Elder
  6 siblings, 1 reply; 34+ messages in thread
From: Alex Elder @ 2025-03-21 15:18 UTC (permalink / raw)
  To: p.zabel, mturquette, sboyd, dlan
  Cc: robh, krzk+dt, conor+dt, heylenay, paul.walmsley, palmer, aou,
	spacemit, devicetree, linux-clk, linux-riscv, linux-kernel

Enable support for three additional syscon CCUs which support reset
controls but no clocks:  ARCPU, RCPU2, and APBC2.

Signed-off-by: Alex Elder <elder@riscstar.com>
---
 drivers/clk/spacemit/ccu-k1.c | 106 ++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)

diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
index 17e321c25959a..bf5a3e2048619 100644
--- a/drivers/clk/spacemit/ccu-k1.c
+++ b/drivers/clk/spacemit/ccu-k1.c
@@ -130,6 +130,37 @@
 #define APMU_EMAC0_CLK_RES_CTRL		0x3e4
 #define APMU_EMAC1_CLK_RES_CTRL		0x3ec
 
+/* RCPU register offsets */
+#define RCPU_SSP0_CLK_RST		0x0028
+#define RCPU_I2C0_CLK_RST		0x0030
+#define RCPU_UART1_CLK_RST		0x003c
+#define RCPU_CAN_CLK_RST		0x0048
+#define RCPU_IR_CLK_RST			0x004c
+#define RCPU_UART0_CLK_RST		0x00d8
+/* XXX Next one is part of the AUD_AUDCLOCK region @ 0xc0882000 */
+#define AUDIO_HDMI_CLK_CTRL		0x2044
+
+/* RCPU2 register offsets */
+#define RCPU2_PWM0_CLK_RST		0x0000
+#define RCPU2_PWM1_CLK_RST		0x0004
+#define RCPU2_PWM2_CLK_RST		0x0008
+#define RCPU2_PWM3_CLK_RST		0x000c
+#define RCPU2_PWM4_CLK_RST		0x0010
+#define RCPU2_PWM5_CLK_RST		0x0014
+#define RCPU2_PWM6_CLK_RST		0x0018
+#define RCPU2_PWM7_CLK_RST		0x001c
+#define RCPU2_PWM8_CLK_RST		0x0020
+#define RCPU2_PWM9_CLK_RST		0x0024
+
+/* APBC2 register offsets */
+#define APBC2_UART1_CLK_RST		0x0000
+#define APBC2_SSP2_CLK_RST		0x0004
+#define APBC2_TWSI3_CLK_RST		0x0008
+#define APBC2_RTC_CLK_RST		0x000c
+#define APBC2_TIMERS0_CLK_RST		0x0010
+#define APBC2_KPC_CLK_RST		0x0014
+#define APBC2_GPIO_CLK_RST		0x001c
+
 struct spacemit_ccu_clk {
 	int id;
 	struct clk_hw *hw;
@@ -1781,6 +1812,69 @@ static const struct k1_ccu_data k1_ccu_apmu_data = {
 	.rst_data	= &apmu_reset_controller_data,
 };
 
+static const struct ccu_reset_data rcpu_reset_data[] = {
+	[RST_RCPU_SSP0]		= RST_DATA(RCPU_SSP0_CLK_RST,	0, BIT(0)),
+	[RST_RCPU_I2C0]		= RST_DATA(RCPU_I2C0_CLK_RST,	0, BIT(0)),
+	[RST_RCPU_UART1]	= RST_DATA(RCPU_UART1_CLK_RST,	0, BIT(0)),
+	[RST_RCPU_IR]		= RST_DATA(RCPU_CAN_CLK_RST,	0, BIT(0)),
+	[RST_RCPU_CAN]		= RST_DATA(RCPU_IR_CLK_RST,	0, BIT(0)),
+	[RST_RCPU_UART0]	= RST_DATA(RCPU_UART0_CLK_RST,	0, BIT(0)),
+	[RST_RCPU_HDMI_AUDIO]	= RST_DATA(AUDIO_HDMI_CLK_CTRL,	0, BIT(0)),
+};
+
+static const struct ccu_reset_controller_data rcpu_reset_controller_data = {
+	.count		= ARRAY_SIZE(rcpu_reset_data),
+	.data		= rcpu_reset_data,
+};
+
+static struct k1_ccu_data k1_ccu_rcpu_data = {
+	/* No clocks in the RCPU CCU */
+	.rst_data	= &rcpu_reset_controller_data,
+};
+
+static const struct ccu_reset_data rcpu2_reset_data[] = {
+	[RST_RCPU2_PWM0]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
+	[RST_RCPU2_PWM1]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
+	[RST_RCPU2_PWM2]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
+	[RST_RCPU2_PWM3]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
+	[RST_RCPU2_PWM4]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
+	[RST_RCPU2_PWM5]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
+	[RST_RCPU2_PWM6]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
+	[RST_RCPU2_PWM7]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
+	[RST_RCPU2_PWM8]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
+	[RST_RCPU2_PWM9]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
+};
+
+static const struct ccu_reset_controller_data rcpu2_reset_controller_data = {
+	.count		= ARRAY_SIZE(rcpu2_reset_data),
+	.data		= rcpu2_reset_data,
+};
+
+static struct k1_ccu_data k1_ccu_rcpu2_data = {
+	/* No clocks in the RCPU2 CCU */
+	.rst_data	= &rcpu2_reset_controller_data,
+};
+
+static const struct ccu_reset_data apbc2_reset_data[] = {
+	[RST_APBC2_UART1]	= RST_DATA(APBC2_UART1_CLK_RST,	BIT(2), (0)),
+	[RST_APBC2_SSP2]	= RST_DATA(APBC2_SSP2_CLK_RST,	BIT(2), (0)),
+	[RST_APBC2_TWSI3]	= RST_DATA(APBC2_TWSI3_CLK_RST,	BIT(2), (0)),
+	[RST_APBC2_RTC]		= RST_DATA(APBC2_RTC_CLK_RST,	BIT(2), (0)),
+	[RST_APBC2_TIMERS0]	= RST_DATA(APBC2_TIMERS0_CLK_RST, BIT(2), (0)),
+	[RST_APBC2_KPC]		= RST_DATA(APBC2_KPC_CLK_RST,	BIT(2), (0)),
+	[RST_APBC2_GPIO]	= RST_DATA(APBC2_GPIO_CLK_RST,	BIT(2), (0)),
+};
+
+static const struct ccu_reset_controller_data apbc2_reset_controller_data = {
+	.count		= ARRAY_SIZE(apbc2_reset_data),
+	.data		= apbc2_reset_data,
+};
+
+static struct k1_ccu_data k1_ccu_apbc2_data = {
+	/* No clocks in the RCPU2 CCU */
+	.rst_data	= &apbc2_reset_controller_data,
+};
+
 static struct ccu_reset_controller *
 rcdev_to_controller(struct reset_controller_dev *rcdev)
 {
@@ -1959,6 +2053,18 @@ static const struct of_device_id of_k1_ccu_match[] = {
 		.compatible	= "spacemit,k1-syscon-apmu",
 		.data		= &k1_ccu_apmu_data,
 	},
+	{
+		.compatible	= "spacemit,k1-syscon-rcpu",
+		.data		= &k1_ccu_rcpu_data,
+	},
+	{
+		.compatible	= "spacemit,k1-syscon-rcpu2",
+		.data		= &k1_ccu_rcpu2_data,
+	},
+	{
+		.compatible	= "spacemit,k1-syscon-apbc2",
+		.data		= &k1_ccu_apbc2_data,
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, of_k1_ccu_match);
-- 
2.43.0


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

* [PATCH RESEND 7/7] riscv: dts: spacemit: add reset support for the K1 SoC
  2025-03-21 15:18 [PATCH RESEND 0/7] clk: spacemit: add K1 reset support Alex Elder
                   ` (5 preceding siblings ...)
  2025-03-21 15:18 ` [PATCH RESEND 6/7] clk: spacemit: define new syscons with only resets Alex Elder
@ 2025-03-21 15:18 ` Alex Elder
  2025-03-22 16:48   ` Yixun Lan
  6 siblings, 1 reply; 34+ messages in thread
From: Alex Elder @ 2025-03-21 15:18 UTC (permalink / raw)
  To: p.zabel, mturquette, sboyd, dlan
  Cc: robh, krzk+dt, conor+dt, heylenay, guodong, paul.walmsley, palmer,
	aou, spacemit, devicetree, linux-clk, linux-riscv, linux-kernel

Define syscon nodes for the RCPU, RCPU2, and APBC2 SpacemiT CCUS, which
currently support resets but not clocks in the SpacemiT K1.

Signed-off-by: Alex Elder <elder@riscstar.com>
---
 arch/riscv/boot/dts/spacemit/k1.dtsi | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi
index 09a9100986b19..f86d1b58c6d35 100644
--- a/arch/riscv/boot/dts/spacemit/k1.dtsi
+++ b/arch/riscv/boot/dts/spacemit/k1.dtsi
@@ -350,6 +350,18 @@ soc {
 		dma-noncoherent;
 		ranges;
 
+		syscon_rcpu: system-controller@c0880000 {
+			compatible = "spacemit,k1-syscon-rcpu";
+			reg = <0x0 0xc0880000 0x0 0x2048>;
+			#reset-cells = <1>;
+		};
+
+		syscon_rcpu2: system-controller@c0888000 {
+			compatible = "spacemit,k1-syscon-rcpu2";
+			reg = <0x0 0xc0888000 0x0 0x28>;
+			#reset-cells = <1>;
+		};
+
 		syscon_apbc: system-control@d4015000 {
 			compatible = "spacemit,k1-syscon-apbc";
 			reg = <0x0 0xd4015000 0x0 0x1000>;
@@ -518,6 +530,12 @@ clint: timer@e4000000 {
 					      <&cpu7_intc 3>, <&cpu7_intc 7>;
 		};
 
+		syscon_apbc2: system-controller@f0610000 {
+			compatible = "spacemit,k1-syscon-apbc2";
+			reg = <0x0 0xf0610000 0x0 0x20>;
+			#reset-cells = <1>;
+		};
+
 		sec_uart1: serial@f0612000 {
 			compatible = "spacemit,k1-uart", "intel,xscale-uart";
 			reg = <0x0 0xf0612000 0x0 0x100>;
-- 
2.43.0


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

* Re: [PATCH RESEND 1/7] dt-bindings: soc: spacemit: define spacemit,k1-ccu resets
  2025-03-21 15:18 ` [PATCH RESEND 1/7] dt-bindings: soc: spacemit: define spacemit,k1-ccu resets Alex Elder
@ 2025-03-21 20:42   ` Rob Herring
  2025-03-21 22:25   ` Yixun Lan
  1 sibling, 0 replies; 34+ messages in thread
From: Rob Herring @ 2025-03-21 20:42 UTC (permalink / raw)
  To: Alex Elder
  Cc: krzk+dt, conor+dt, p.zabel, mturquette, sboyd, dlan, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

On Fri, Mar 21, 2025 at 10:18:24AM -0500, Alex Elder wrote:
> There are additional SpacemiT syscon CCUs whose registers control both
> clocks and resets:  RCPU, RCPU2, and APBC2. Unlike those defined
> previously, these will initially support only resets.  They do not
> incorporate power domain functionality.
> 
> Define the index values for resets associated with all SpacemiT K1
> syscon nodes, including those with clocks already defined, as well as
> the new ones (without clocks).
> 
> Signed-off-by: Alex Elder <elder@riscstar.com>
> ---
>  .../soc/spacemit/spacemit,k1-syscon.yaml      |  13 +-
>  include/dt-bindings/clock/spacemit,k1-ccu.h   | 134 ++++++++++++++++++
>  2 files changed, 143 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
> index 07a6728e6f864..333c28e075b6c 100644
> --- a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
> +++ b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
> @@ -19,6 +19,9 @@ properties:
>        - spacemit,k1-syscon-apbc
>        - spacemit,k1-syscon-apmu
>        - spacemit,k1-syscon-mpmu
> +      - spacemit,k1-syscon-rcpu
> +      - spacemit,k1-syscon-rcpu2
> +      - spacemit,k1-syscon-apbc2
>  
>    reg:
>      maxItems: 1
> @@ -57,13 +60,15 @@ allOf:
>        properties:
>          compatible:
>            contains:
> -            const: spacemit,k1-syscon-apbc
> +            enum:
> +              - spacemit,k1-syscon-apmu
> +              - spacemit,k1-syscon-mpmu
>      then:
> -      properties:
> -        "#power-domain-cells": false
> -    else:
>        required:
>          - "#power-domain-cells"
> +    else:
> +      properties:
> +        "#power-domain-cells": false
>  
>  additionalProperties: false
>  
> diff --git a/include/dt-bindings/clock/spacemit,k1-ccu.h b/include/dt-bindings/clock/spacemit,k1-ccu.h
> index 4a0c7163257e3..a1e1b1fe714ce 100644
> --- a/include/dt-bindings/clock/spacemit,k1-ccu.h
> +++ b/include/dt-bindings/clock/spacemit,k1-ccu.h
> @@ -78,6 +78,9 @@
>  #define CLK_APB			31
>  #define CLK_WDT_BUS		32
>  
> +/*	MPMU resets	*/
> +#define RST_WDT			0
> +
>  /*	APBC clocks	*/
>  #define CLK_UART0		0
>  #define CLK_UART2		1
> @@ -109,6 +112,7 @@
>  #define CLK_PWM17		27
>  #define CLK_PWM18		28
>  #define CLK_PWM19		29
> +

Stray change?

Otherwise,

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>

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

* Re: [PATCH RESEND 1/7] dt-bindings: soc: spacemit: define spacemit,k1-ccu resets
  2025-03-21 15:18 ` [PATCH RESEND 1/7] dt-bindings: soc: spacemit: define spacemit,k1-ccu resets Alex Elder
  2025-03-21 20:42   ` Rob Herring
@ 2025-03-21 22:25   ` Yixun Lan
  2025-03-22 14:27     ` Alex Elder
  1 sibling, 1 reply; 34+ messages in thread
From: Yixun Lan @ 2025-03-21 22:25 UTC (permalink / raw)
  To: Alex Elder
  Cc: robh, krzk+dt, conor+dt, p.zabel, mturquette, sboyd, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

hi Alex:

On 10:18 Fri 21 Mar     , Alex Elder wrote:
> There are additional SpacemiT syscon CCUs whose registers control both
> clocks and resets:  RCPU, RCPU2, and APBC2. Unlike those defined
> previously, these will initially support only resets.  They do not
> incorporate power domain functionality.
> 
> Define the index values for resets associated with all SpacemiT K1
> syscon nodes, including those with clocks already defined, as well as
> the new ones (without clocks).
> 
> Signed-off-by: Alex Elder <elder@riscstar.com>
> ---
>  .../soc/spacemit/spacemit,k1-syscon.yaml      |  13 +-
>  include/dt-bindings/clock/spacemit,k1-ccu.h   | 134 ++++++++++++++++++
>  2 files changed, 143 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
> index 07a6728e6f864..333c28e075b6c 100644
> --- a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
> +++ b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
> @@ -19,6 +19,9 @@ properties:
>        - spacemit,k1-syscon-apbc
>        - spacemit,k1-syscon-apmu
>        - spacemit,k1-syscon-mpmu
> +      - spacemit,k1-syscon-rcpu
> +      - spacemit,k1-syscon-rcpu2
> +      - spacemit,k1-syscon-apbc2
>  
>    reg:
>      maxItems: 1
> @@ -57,13 +60,15 @@ allOf:
>        properties:
>          compatible:
>            contains:
> -            const: spacemit,k1-syscon-apbc
> +            enum:
> +              - spacemit,k1-syscon-apmu
> +              - spacemit,k1-syscon-mpmu
>      then:
> -      properties:
> -        "#power-domain-cells": false
> -    else:
>        required:
>          - "#power-domain-cells"
> +    else:
> +      properties:
> +        "#power-domain-cells": false
>  
>  additionalProperties: false
>  
> diff --git a/include/dt-bindings/clock/spacemit,k1-ccu.h b/include/dt-bindings/clock/spacemit,k1-ccu.h
> index 4a0c7163257e3..a1e1b1fe714ce 100644
> --- a/include/dt-bindings/clock/spacemit,k1-ccu.h
> +++ b/include/dt-bindings/clock/spacemit,k1-ccu.h
> @@ -78,6 +78,9 @@
>  #define CLK_APB			31
>  #define CLK_WDT_BUS		32
>  
> +/*	MPMU resets	*/
> +#define RST_WDT			0
> +
>  /*	APBC clocks	*/
>  #define CLK_UART0		0
>  #define CLK_UART2		1
> @@ -109,6 +112,7 @@
>  #define CLK_PWM17		27
>  #define CLK_PWM18		28
>  #define CLK_PWM19		29
> +
as Rob point out, this isn't necessary, not related to reset

>  #define CLK_SSP3		30
>  #define CLK_RTC			31
>  #define CLK_TWSI0		32
> @@ -180,6 +184,60 @@
>  #define CLK_TSEN_BUS		98
>  #define CLK_IPC_AP2AUD_BUS	99
>  
> +/*	APBC resets	*/
> +
I'd also suggest to drop above blank line, keep style consistent
with others in this file, some same below that I won't comment
> +#define RST_UART0		0
> +#define RST_UART2		1
> +#define RST_UART3		2
> +#define RST_UART4		3
> +#define RST_UART5		4
> +#define RST_UART6		5
> +#define RST_UART7		6
> +#define RST_UART8		7
> +#define RST_UART9		8
> +#define RST_GPIO		9
> +#define RST_PWM0		10
> +#define RST_PWM1		11
> +#define RST_PWM2		12
> +#define RST_PWM3		13
> +#define RST_PWM4		14
> +#define RST_PWM5		15
> +#define RST_PWM6		16
> +#define RST_PWM7		17
> +#define RST_PWM8		18
> +#define RST_PWM9		19
> +#define RST_PWM10		20
> +#define RST_PWM11		21
> +#define RST_PWM12		22
> +#define RST_PWM13		23
> +#define RST_PWM14		24
> +#define RST_PWM15		25
> +#define RST_PWM16		26
> +#define RST_PWM17		27
> +#define RST_PWM18		28
> +#define RST_PWM19		29
> +#define RST_SSP3		30
> +#define RST_RTC			31
> +#define RST_TWSI0		32
> +#define RST_TWSI1		33
> +#define RST_TWSI2		34
> +#define RST_TWSI4		35
> +#define RST_TWSI5		36
> +#define RST_TWSI6		37
> +#define RST_TWSI7		38
> +#define RST_TWSI8		39
> +#define RST_TIMERS1		40
> +#define RST_TIMERS2		41
> +#define RST_AIB			42
> +#define RST_ONEWIRE		43
> +#define RST_SSPA0		44
> +#define RST_SSPA1		45
> +#define RST_DRO			46
> +#define RST_IR			47
> +#define RST_TSEN		48
> +#define RST_IPC_AP2AUD		49
> +#define RST_CAN0		50
> +
>  /*	APMU clocks	*/
>  #define CLK_CCI550		0
>  #define CLK_CPU_C0_HI		1
> @@ -244,4 +302,80 @@
>  #define CLK_V2D			60
>  #define CLK_EMMC_BUS		61
>  
> +/*	APMU resets	*/
> +
> +#define RST_CCIC_4X		0
> +#define RST_CCIC1_PHY		1
> +#define RST_SDH_AXI		2
> +#define RST_SDH0		3
> +#define RST_SDH1		4
> +#define RST_SDH2		5
> +#define RST_USBP1_AXI		6
> +#define RST_USB_AXI		7
> +#define RST_USB3_0		8
> +#define RST_QSPI		9
> +#define RST_QSPI_BUS		10
> +#define RST_DMA			11
> +#define RST_AES			12
> +#define RST_VPU			13
> +#define RST_GPU			14
> +#define RST_EMMC		15
> +#define RST_EMMC_X		16
> +#define RST_AUDIO		17
> +#define RST_HDMI		18
> +#define RST_PCIE0		19
> +#define RST_PCIE1		20
> +#define RST_PCIE2		21
> +#define RST_EMAC0		22
> +#define RST_EMAC1		23
> +#define RST_JPG			24
> +#define RST_CCIC2PHY		25
> +#define RST_CCIC3PHY		26
> +#define RST_CSI			27
> +#define RST_ISP_CPP		28
> +#define RST_ISP_BUS		29
> +#define RST_ISP			30
> +#define RST_ISP_CI		31
> +#define RST_DPU_MCLK		32
> +#define RST_DPU_ESC		33
> +#define RST_DPU_HCLK		34
> +#define RST_DPU_SPIBUS		35
> +#define RST_DPU_SPI_HBUS	36
> +#define RST_V2D			37
> +#define RST_MIPI		38
> +#define RST_MC			39
> +
> +/*	RCPU resets	*/
> +
> +#define RST_RCPU_SSP0		0
> +#define RST_RCPU_I2C0		1
> +#define RST_RCPU_UART1		2
> +#define RST_RCPU_IR		3
> +#define RST_RCPU_CAN		4
> +#define RST_RCPU_UART0		5
> +#define RST_RCPU_HDMI_AUDIO	6
> +
> +/*	RCPU2 resets	*/
> +
> +#define RST_RCPU2_PWM0		0
> +#define RST_RCPU2_PWM1		1
> +#define RST_RCPU2_PWM2		2
> +#define RST_RCPU2_PWM3		3
> +#define RST_RCPU2_PWM4		4
> +#define RST_RCPU2_PWM5		5
> +#define RST_RCPU2_PWM6		6
> +#define RST_RCPU2_PWM7		7
> +#define RST_RCPU2_PWM8		8
> +#define RST_RCPU2_PWM9		9
> +
> +/*	APBC2 resets	*/
> +
> +#define RST_APBC2_UART1		0
> +#define RST_APBC2_SSP2		1
> +#define RST_APBC2_TWSI3		2
> +#define RST_APBC2_RTC		3
> +#define RST_APBC2_TIMERS0	4
> +#define RST_APBC2_KPC		5
> +#define RST_APBC2_GPIO		6
> +
>  #endif /* _DT_BINDINGS_SPACEMIT_CCU_H_ */
> -- 
> 2.43.0
> 
> 

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55

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

* Re: [PATCH RESEND 1/7] dt-bindings: soc: spacemit: define spacemit,k1-ccu resets
  2025-03-21 22:25   ` Yixun Lan
@ 2025-03-22 14:27     ` Alex Elder
  2025-03-22 16:51       ` Yixun Lan
  0 siblings, 1 reply; 34+ messages in thread
From: Alex Elder @ 2025-03-22 14:27 UTC (permalink / raw)
  To: Yixun Lan
  Cc: robh, krzk+dt, conor+dt, p.zabel, mturquette, sboyd, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

On 3/21/25 5:25 PM, Yixun Lan wrote:
> hi Alex:
> 
> On 10:18 Fri 21 Mar     , Alex Elder wrote:
>> There are additional SpacemiT syscon CCUs whose registers control both
>> clocks and resets:  RCPU, RCPU2, and APBC2. Unlike those defined
>> previously, these will initially support only resets.  They do not
>> incorporate power domain functionality.
>>
>> Define the index values for resets associated with all SpacemiT K1
>> syscon nodes, including those with clocks already defined, as well as
>> the new ones (without clocks).
>>
>> Signed-off-by: Alex Elder <elder@riscstar.com>
>> ---
>>   .../soc/spacemit/spacemit,k1-syscon.yaml      |  13 +-
>>   include/dt-bindings/clock/spacemit,k1-ccu.h   | 134 ++++++++++++++++++
>>   2 files changed, 143 insertions(+), 4 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
>> index 07a6728e6f864..333c28e075b6c 100644
>> --- a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
>> +++ b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
>> @@ -19,6 +19,9 @@ properties:
>>         - spacemit,k1-syscon-apbc
>>         - spacemit,k1-syscon-apmu
>>         - spacemit,k1-syscon-mpmu
>> +      - spacemit,k1-syscon-rcpu
>> +      - spacemit,k1-syscon-rcpu2
>> +      - spacemit,k1-syscon-apbc2
>>   
>>     reg:
>>       maxItems: 1

. . .

32
>> @@ -180,6 +184,60 @@
>>   #define CLK_TSEN_BUS		98
>>   #define CLK_IPC_AP2AUD_BUS	99
>>   
>> +/*	APBC resets	*/
>> +
> I'd also suggest to drop above blank line, keep style consistent
> with others in this file, some same below that I won't comment

OK, I'll fix the weird extra line and will drop these blank
lines as you suggest in v2.  I'll post another version after
Sunday.  I recognize the merge window means I can't expect
reviews during that time, but this code is waiting for the
clock code to get accepted anyway.

Thanks a lot.

					-Alex

>> +#define RST_UART0		0
>> +#define RST_UART2		1
>> +#define RST_UART3		2
>> +#define RST_UART4		3
>> +#define RST_UART5		4

. . .

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

* Re: [PATCH RESEND 2/7] clk: spacemit: define struct k1_ccu_data
  2025-03-21 15:18 ` [PATCH RESEND 2/7] clk: spacemit: define struct k1_ccu_data Alex Elder
@ 2025-03-22 15:50   ` Yixun Lan
  2025-03-23 12:43     ` Alex Elder
  2025-03-28 17:24     ` Alex Elder
  2025-03-24 11:53   ` Haylen Chu
  1 sibling, 2 replies; 34+ messages in thread
From: Yixun Lan @ 2025-03-22 15:50 UTC (permalink / raw)
  To: Alex Elder
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

Hi Alex:

this patch change relate to clock only, so how about let's fold
it into clk patches (which now has not been merged), so we make
the code right at first place? cause some moving around and renaming

On 10:18 Fri 21 Mar     , Alex Elder wrote:
> Define a new structure type to be used for describing the OF match data.
> Rather than using the array of spacemit_ccu_clk structures for match
> data, we use this structure instead.
> 
> Move the definition of the spacemit_ccu_clk structure closer to the top
> of the source file, and add the new structure definition below it.
> 
> Shorten the name of spacemit_ccu_register() to be k1_ccu_register().
any good reason to change this? it make the code style inconsistent,
do you just change it for shorten function, or want it to be more k1
specific, so next SoC - e.g maybe k2? will introduce another function?

> 
> Signed-off-by: Alex Elder <elder@riscstar.com>
> ---
>  drivers/clk/spacemit/ccu-k1.c | 58 ++++++++++++++++++++++++++---------
>  1 file changed, 43 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
> index 44db48ae71313..f7367271396a0 100644
> --- a/drivers/clk/spacemit/ccu-k1.c
> +++ b/drivers/clk/spacemit/ccu-k1.c
> @@ -129,6 +129,15 @@
>  #define APMU_EMAC0_CLK_RES_CTRL		0x3e4
>  #define APMU_EMAC1_CLK_RES_CTRL		0x3ec
>  
> +struct spacemit_ccu_clk {
> +	int id;
> +	struct clk_hw *hw;
> +};
> +
> +struct k1_ccu_data {
> +	struct spacemit_ccu_clk *clk;		/* array with sentinel */
> +};
> +
>  /*	APBS clocks start	*/
>  
>  /* Frequency of pll{1,2} should not be updated at runtime */
> @@ -1359,11 +1368,6 @@ static CCU_GATE_DEFINE(emmc_bus_clk, CCU_PARENT_HW(pmua_aclk),
>  		       0);
>  /*	APMU clocks end		*/
>  
> -struct spacemit_ccu_clk {
> -	int id;
> -	struct clk_hw *hw;
> -};
> -
>  static struct spacemit_ccu_clk k1_ccu_apbs_clks[] = {
>  	{ CLK_PLL1,		&pll1.common.hw },
>  	{ CLK_PLL2,		&pll2.common.hw },
> @@ -1403,6 +1407,10 @@ static struct spacemit_ccu_clk k1_ccu_apbs_clks[] = {
>  	{ 0,			NULL },
>  };
>  
> +static const struct k1_ccu_data k1_ccu_apbs_data = {
> +	.clk		= k1_ccu_apbs_clks,
> +};
> +
>  static struct spacemit_ccu_clk k1_ccu_mpmu_clks[] = {
>  	{ CLK_PLL1_307P2,	&pll1_d8_307p2.common.hw },
>  	{ CLK_PLL1_76P8,	&pll1_d32_76p8.common.hw },
> @@ -1440,6 +1448,10 @@ static struct spacemit_ccu_clk k1_ccu_mpmu_clks[] = {
>  	{ 0,			NULL },
>  };
>  
> +static const struct k1_ccu_data k1_ccu_mpmu_data = {
> +	.clk		= k1_ccu_mpmu_clks,
> +};
> +
>  static struct spacemit_ccu_clk k1_ccu_apbc_clks[] = {
>  	{ CLK_UART0,		&uart0_clk.common.hw },
>  	{ CLK_UART2,		&uart2_clk.common.hw },
> @@ -1544,6 +1556,10 @@ static struct spacemit_ccu_clk k1_ccu_apbc_clks[] = {
>  	{ 0,			NULL },
>  };
>  
> +static const struct k1_ccu_data k1_ccu_apbc_data = {
> +	.clk		= k1_ccu_apbc_clks,
> +};
> +
>  static struct spacemit_ccu_clk k1_ccu_apmu_clks[] = {
>  	{ CLK_CCI550,		&cci550_clk.common.hw },
>  	{ CLK_CPU_C0_HI,	&cpu_c0_hi_clk.common.hw },
> @@ -1610,9 +1626,13 @@ static struct spacemit_ccu_clk k1_ccu_apmu_clks[] = {
>  	{ 0,			NULL },
>  };
>  
> -static int spacemit_ccu_register(struct device *dev,
> -				 struct regmap *regmap, struct regmap *lock_regmap,
> -				 const struct spacemit_ccu_clk *clks)
> +static const struct k1_ccu_data k1_ccu_apmu_data = {
> +	.clk		= k1_ccu_apmu_clks,
> +};
> +
> +static int k1_ccu_register(struct device *dev, struct regmap *regmap,
> +			   struct regmap *lock_regmap,
> +			   struct spacemit_ccu_clk *clks)
>  {
>  	const struct spacemit_ccu_clk *clk;
>  	int i, ret, max_id = 0;
> @@ -1648,15 +1668,24 @@ static int spacemit_ccu_register(struct device *dev,
>  
>  	clk_data->num = max_id + 1;
>  
> -	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
> +	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
> +	if (ret)
> +		dev_err(dev, "error %d adding clock hardware provider\n", ret);
> +
> +	return ret;
I'd use "return 0;", nothing different, just explicitly short

ok, I can understand this change ease debug procedure once there is problem.
(but I'm fine with either way, failure should rarely happen & will
identify early)

>  }
>  
>  static int k1_ccu_probe(struct platform_device *pdev)
>  {
>  	struct regmap *base_regmap, *lock_regmap = NULL;
>  	struct device *dev = &pdev->dev;
> +	const struct k1_ccu_data *data;
>  	int ret;
>  
> +	data = of_device_get_match_data(dev);
> +	if (!data)
> +		return -EINVAL;
> +
>  	base_regmap = device_node_to_regmap(dev->of_node);
>  	if (IS_ERR(base_regmap))
>  		return dev_err_probe(dev, PTR_ERR(base_regmap),
> @@ -1677,8 +1706,7 @@ static int k1_ccu_probe(struct platform_device *pdev)
>  					     "failed to get lock regmap\n");
>  	}
>  
> -	ret = spacemit_ccu_register(dev, base_regmap, lock_regmap,
> -				    of_device_get_match_data(dev));
> +	ret = k1_ccu_register(dev, base_regmap, lock_regmap, data->clk);
>  	if (ret)
>  		return dev_err_probe(dev, ret, "failed to register clocks\n");
>  
> @@ -1688,19 +1716,19 @@ static int k1_ccu_probe(struct platform_device *pdev)
>  static const struct of_device_id of_k1_ccu_match[] = {
>  	{
>  		.compatible	= "spacemit,k1-pll",
> -		.data		= k1_ccu_apbs_clks,
> +		.data		= &k1_ccu_apbs_data,
>  	},
>  	{
>  		.compatible	= "spacemit,k1-syscon-mpmu",
> -		.data		= k1_ccu_mpmu_clks,
> +		.data		= &k1_ccu_mpmu_data,
>  	},
>  	{
>  		.compatible	= "spacemit,k1-syscon-apbc",
> -		.data		= k1_ccu_apbc_clks,
> +		.data		= &k1_ccu_apbc_data,
>  	},
>  	{
>  		.compatible	= "spacemit,k1-syscon-apmu",
> -		.data		= k1_ccu_apmu_clks,
> +		.data		= &k1_ccu_apmu_data,
>  	},
>  	{ }
	{ /* sentinel */ }
>  };
> -- 
> 2.43.0
> 

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55

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

* Re: [PATCH RESEND 3/7] clk: spacemit: add reset controller support
  2025-03-21 15:18 ` [PATCH RESEND 3/7] clk: spacemit: add reset controller support Alex Elder
@ 2025-03-22 16:19   ` Yixun Lan
  2025-03-23 13:23     ` Alex Elder
  2025-03-24 12:20   ` Haylen Chu
  1 sibling, 1 reply; 34+ messages in thread
From: Yixun Lan @ 2025-03-22 16:19 UTC (permalink / raw)
  To: Alex Elder
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

Hi Alex:

On 10:18 Fri 21 Mar     , Alex Elder wrote:
> Define ccu_reset_data as a structure that contains the constant
> register offset and bitmasks used to assert and deassert a reset
> control on a SpacemiT K1 CCU. Define ccu_reset_controller_data as
> a structure that contains the address of an array of those structures
> and a count of the number of elements in the array.
> 
> Add a pointer to a ccu_reset_controller_data structure to the
> k1_ccu_data structure.  Reset support is optional for SpacemiT CCUs;
> the new pointer field will be null for CCUs without any resets.
> 
> Finally, define a new ccu_reset_controller structure, which (for
> a CCU with resets) contains a pointer to the constant reset data,
> the regmap to be used for the controller, and an embedded a reset
> controller structure.
> 
> Each reset control is asserted or deasserted by updating bits in
> a register.  The bits used are defined by an assert mask and a
> deassert mask.  In some cases, one (non-zero) mask asserts reset
> and a different (non-zero) mask deasserts it.  Otherwise one mask
> is nonzero, and the other is zero.  Either way, the bits in
> both masks are cleared, then either the assert mask or the deassert
> mask is set in a register to affect the state of a reset control.
> 
> Signed-off-by: Alex Elder <elder@riscstar.com>
> ---
>  drivers/clk/spacemit/ccu-k1.c | 93 +++++++++++++++++++++++++++++++++++
>  1 file changed, 93 insertions(+)
> 
> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
> index f7367271396a0..6d879411c6c05 100644
> --- a/drivers/clk/spacemit/ccu-k1.c
> +++ b/drivers/clk/spacemit/ccu-k1.c
> @@ -10,6 +10,7 @@
>  #include <linux/minmax.h>
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
> +#include <linux/reset-controller.h>
>  
>  #include "ccu_common.h"
>  #include "ccu_pll.h"
> @@ -134,8 +135,26 @@ struct spacemit_ccu_clk {
>  	struct clk_hw *hw;
>  };
>  
> +struct ccu_reset_data {
> +	u32 offset;
> +	u32 assert_mask;
> +	u32 deassert_mask;
> +};
> +
> +struct ccu_reset_controller_data {
> +	u32 count;
> +	const struct ccu_reset_data *data;	/* array */
> +};
> +
>  struct k1_ccu_data {
>  	struct spacemit_ccu_clk *clk;		/* array with sentinel */
> +	const struct ccu_reset_controller_data *rst_data;
> +};
> +
> +struct ccu_reset_controller {
> +	struct regmap *regmap;
> +	const struct ccu_reset_controller_data *data;
> +	struct reset_controller_dev rcdev;
>  };
>  
>  /*	APBS clocks start	*/
> @@ -1630,6 +1649,48 @@ static const struct k1_ccu_data k1_ccu_apmu_data = {
>  	.clk		= k1_ccu_apmu_clks,
>  };
>  
> +static struct ccu_reset_controller *
> +rcdev_to_controller(struct reset_controller_dev *rcdev)
I'd suggest to avoid the line break to make it slightly more readable, intuitive
as the 80 column limit isn't hard rule

there are maybe more place similar to this, I won't add more comments
https://github.com/torvalds/linux/commit/bdc48fa11e46f867ea4d75fa59ee87a7f48be144

> +{
> +	return container_of(rcdev, struct ccu_reset_controller, rcdev);
> +}
since this function is only used once, open-code it?
but I'd fine with either way if you prefer to keep it

> +
> +static int
> +k1_rst_update(struct reset_controller_dev *rcdev, unsigned long id, bool assert)
s/k1_rst_update/k1_reset_update/g
this is a taste change, but I found more people follow this when grep driver/reset
> +{
> +	struct ccu_reset_controller *controller = rcdev_to_controller(rcdev);
> +	struct regmap *regmap = controller->regmap;
> +	const struct ccu_reset_data *data;
> +	u32 val;
> +	int ret;
> +
> +	data = &controller->data->data[id];
> +
> +	ret = regmap_read(regmap, data->offset, &val);
> +	if (ret)
> +		return ret;
> +
> +	val &= ~(data->assert_mask | data->deassert_mask);
> +	val |= assert ? data->assert_mask : data->deassert_mask;
> +
> +	return regmap_write(regmap, data->offset, val);
> +}
> +
> +static int k1_rst_assert(struct reset_controller_dev *rcdev, unsigned long id)
same reason, rst -> reset, more below
> +{
> +	return k1_rst_update(rcdev, id, true);
> +}
> +
> +static int k1_rst_deassert(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> +	return k1_rst_update(rcdev, id, false);
> +}
> +
> +static const struct reset_control_ops k1_reset_control_ops = {
> +	.assert		= k1_rst_assert,
> +	.deassert	= k1_rst_deassert,
> +};
> +
>  static int k1_ccu_register(struct device *dev, struct regmap *regmap,
>  			   struct regmap *lock_regmap,
>  			   struct spacemit_ccu_clk *clks)
> @@ -1675,6 +1736,33 @@ static int k1_ccu_register(struct device *dev, struct regmap *regmap,
>  	return ret;
>  }
>  
> +static int
> +k1_reset_controller_register(struct device *dev, struct regmap *regmap,
> +			     const struct ccu_reset_controller_data *data)
> +{
> +	struct ccu_reset_controller *controller;
> +	struct reset_controller_dev *rcdev;
> +
> +	/* Resets are optional */
> +	if (!data)
> +		return 0;
> +
> +	controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL);
> +	if (!controller)
> +		return -ENOMEM;
> +
> +	controller->regmap = regmap;
> +	controller->data = data;
> +
> +	rcdev = &controller->rcdev;
..
> +	rcdev->owner = THIS_MODULE;
move to last?
> +	rcdev->nr_resets = data->count;
> +	rcdev->ops = &k1_reset_control_ops;
> +	rcdev->of_node = dev->of_node;
> +
> +	return devm_reset_controller_register(dev, rcdev);
> +}
> +
>  static int k1_ccu_probe(struct platform_device *pdev)
>  {
>  	struct regmap *base_regmap, *lock_regmap = NULL;
> @@ -1710,6 +1798,11 @@ static int k1_ccu_probe(struct platform_device *pdev)
>  	if (ret)
>  		return dev_err_probe(dev, ret, "failed to register clocks\n");
>  
> +	ret = k1_reset_controller_register(dev, base_regmap, data->rst_data);
..
> +	if (ret)
> +		return dev_err_probe(dev, ret,
> +				     "failed to register reset controller\n");
same 100 column reason
> +
>  	return 0;
>  }
>  
> -- 
> 2.43.0
> 

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55

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

* Re: [PATCH RESEND 4/7] clk: spacemit: define existing syscon resets
  2025-03-21 15:18 ` [PATCH RESEND 4/7] clk: spacemit: define existing syscon resets Alex Elder
@ 2025-03-22 16:29   ` Yixun Lan
  2025-03-23 13:23     ` Alex Elder
  0 siblings, 1 reply; 34+ messages in thread
From: Yixun Lan @ 2025-03-22 16:29 UTC (permalink / raw)
  To: Alex Elder
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

On 10:18 Fri 21 Mar     , Alex Elder wrote:
> Define reset controls associated with the MPMU, APBC, and APMU
> SpacemiT K1 CCUs.  These already have clocks associated with them.
> 
> Signed-off-by: Alex Elder <elder@riscstar.com>
> ---
>  drivers/clk/spacemit/ccu-k1.c | 132 ++++++++++++++++++++++++++++++++++
>  1 file changed, 132 insertions(+)
> 
> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
> index 6d879411c6c05..be8abd27753cb 100644
> --- a/drivers/clk/spacemit/ccu-k1.c
> +++ b/drivers/clk/spacemit/ccu-k1.c
..  
> +static const struct ccu_reset_data apmu_reset_data[] = {
> +	[RST_CCIC_4X]	= RST_DATA(APMU_CCIC_CLK_RES_CTRL,	0, BIT(1)),
> +	[RST_CCIC1_PHY] = RST_DATA(APMU_CCIC_CLK_RES_CTRL,	0, BIT(2)),
> +	[RST_SDH_AXI]	= RST_DATA(APMU_SDH0_CLK_RES_CTRL,	0, BIT(0)),
> +	[RST_SDH0]	= RST_DATA(APMU_SDH0_CLK_RES_CTRL,	0, BIT(1)),
> +	[RST_SDH1]	= RST_DATA(APMU_SDH1_CLK_RES_CTRL,	0, BIT(1)),
> +	[RST_SDH2]	= RST_DATA(APMU_SDH2_CLK_RES_CTRL,	0, BIT(1)),
> +	[RST_USBP1_AXI] = RST_DATA(APMU_USB_CLK_RES_CTRL,	0, BIT(4)),
> +	[RST_USB_AXI]	= RST_DATA(APMU_USB_CLK_RES_CTRL,	0, BIT(0)),
..
> +	[RST_USB3_0]	= RST_DATA(APMU_USB_CLK_RES_CTRL,	0, 
> +				      BIT(9)|BIT(10)|BIT(11)),
100 column if possible, also add one space between "BIT(9) | BIT(10) .."
continuous bits can just use GENMASK for short?
but may result slightly unreadable, anyway, either way is fine by me

> +	[RST_QSPI]	= RST_DATA(APMU_QSPI_CLK_RES_CTRL,	0, BIT(1)),
> +	[RST_QSPI_BUS] = RST_DATA(APMU_QSPI_CLK_RES_CTRL,	0, BIT(0)),
> +	[RST_DMA]	= RST_DATA(APMU_DMA_CLK_RES_CTRL,	0, BIT(0)),
> +	[RST_AES]	= RST_DATA(APMU_AES_CLK_RES_CTRL,	0, BIT(4)),
> +	[RST_VPU]	= RST_DATA(APMU_VPU_CLK_RES_CTRL,	0, BIT(0)),
> +	[RST_GPU]	= RST_DATA(APMU_GPU_CLK_RES_CTRL,	0, BIT(1)),
> +	[RST_EMMC]	= RST_DATA(APMU_PMUA_EM_CLK_RES_CTRL,	0, BIT(1)),
> +	[RST_EMMC_X]	= RST_DATA(APMU_PMUA_EM_CLK_RES_CTRL,	0, BIT(0)),
> +	[RST_AUDIO]	= RST_DATA(APMU_AUDIO_CLK_RES_CTRL,	0,
> +				   BIT(0) | BIT(2) | BIT(3)),
> +	[RST_HDMI]	= RST_DATA(APMU_HDMI_CLK_RES_CTRL,	0, BIT(9)),
> +	[RST_PCIE0]	= RST_DATA(APMU_PCIE_CLK_RES_CTRL_0,	BIT(8),
> +				   BIT(3) | BIT(4) | BIT(5)),
> +	[RST_PCIE1]	= RST_DATA(APMU_PCIE_CLK_RES_CTRL_1,	BIT(8),
> +				   BIT(3) | BIT(4) | BIT(5)),
> +	[RST_PCIE2]	= RST_DATA(APMU_PCIE_CLK_RES_CTRL_2,	BIT(8),
> +				   BIT(3) | BIT(4) | BIT(5)),
> +	[RST_EMAC0]	= RST_DATA(APMU_EMAC0_CLK_RES_CTRL,	0, BIT(1)),
> +	[RST_EMAC1]	= RST_DATA(APMU_EMAC1_CLK_RES_CTRL,	0, BIT(1)),
> +	[RST_JPG]	= RST_DATA(APMU_JPG_CLK_RES_CTRL,	0, BIT(0)),
> +	[RST_CCIC2PHY]	= RST_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL,	0, BIT(2)),
> +	[RST_CCIC3PHY]	= RST_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL,	0, BIT(29)),
> +	[RST_CSI]	= RST_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL,	0, BIT(1)),
> +	[RST_ISP]	= RST_DATA(APMU_ISP_CLK_RES_CTRL,	0, BIT(0)),
> +	[RST_ISP_CPP]	= RST_DATA(APMU_ISP_CLK_RES_CTRL,	0, BIT(27)),
> +	[RST_ISP_BUS]	= RST_DATA(APMU_ISP_CLK_RES_CTRL,	0, BIT(3)),
> +	[RST_ISP_CI]	= RST_DATA(APMU_ISP_CLK_RES_CTRL,	0, BIT(16)),
> +	[RST_DPU_MCLK]	= RST_DATA(APMU_LCD_CLK_RES_CTRL2,	0, BIT(9)),
> +	[RST_DPU_ESC]	= RST_DATA(APMU_LCD_CLK_RES_CTRL1,	0, BIT(3)),
> +	[RST_DPU_HCLK]	= RST_DATA(APMU_LCD_CLK_RES_CTRL1,	0, BIT(4)),
> +	[RST_DPU_SPIBUS] = RST_DATA(APMU_LCD_SPI_CLK_RES_CTRL,	0, BIT(4)),
> +	[RST_DPU_SPI_HBUS] = RST_DATA(APMU_LCD_SPI_CLK_RES_CTRL, 0, BIT(2)),
> +	[RST_V2D]	= RST_DATA(APMU_LCD_CLK_RES_CTRL1,	0, BIT(27)),
> +	[RST_MIPI]	= RST_DATA(APMU_LCD_CLK_RES_CTRL1,	0, BIT(15)),
> +	[RST_MC]	= RST_DATA(APMU_PMUA_MC_CTRL,		0, BIT(0)),
> +};
> +
> +static const struct ccu_reset_controller_data apmu_reset_controller_data = {
> +	.count		= ARRAY_SIZE(apmu_reset_data),
> +	.data		= apmu_reset_data,
> +};
> +
>  static const struct k1_ccu_data k1_ccu_apmu_data = {
>  	.clk		= k1_ccu_apmu_clks,
> +	.rst_data	= &apmu_reset_controller_data,
>  };
>  
>  static struct ccu_reset_controller *
> -- 
> 2.43.0
> 

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55

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

* Re: [PATCH RESEND 6/7] clk: spacemit: define new syscons with only resets
  2025-03-21 15:18 ` [PATCH RESEND 6/7] clk: spacemit: define new syscons with only resets Alex Elder
@ 2025-03-22 16:42   ` Yixun Lan
  2025-03-23 13:23     ` Alex Elder
  0 siblings, 1 reply; 34+ messages in thread
From: Yixun Lan @ 2025-03-22 16:42 UTC (permalink / raw)
  To: Alex Elder
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	paul.walmsley, palmer, aou, spacemit, devicetree, linux-clk,
	linux-riscv, linux-kernel

Hi Alex:

It occur to me it's a little odd to implemnt reset driver
for RCPU block, but after check with vendor the RCPU region can
be accessed both by ACPU and RCPU, then I'm fine with this.

ACPU - RISC-V Main CPU, with mmu, running Linux
RCPU - real time CPU, without mmu, running RT-OS

On 10:18 Fri 21 Mar     , Alex Elder wrote:
> Enable support for three additional syscon CCUs which support reset
> controls but no clocks:  ARCPU, RCPU2, and APBC2.
> 
> Signed-off-by: Alex Elder <elder@riscstar.com>
> ---
>  drivers/clk/spacemit/ccu-k1.c | 106 ++++++++++++++++++++++++++++++++++
>  1 file changed, 106 insertions(+)
> 
> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
> index 17e321c25959a..bf5a3e2048619 100644
> --- a/drivers/clk/spacemit/ccu-k1.c
> +++ b/drivers/clk/spacemit/ccu-k1.c
> @@ -130,6 +130,37 @@
>  #define APMU_EMAC0_CLK_RES_CTRL		0x3e4
>  #define APMU_EMAC1_CLK_RES_CTRL		0x3ec
>  
> +/* RCPU register offsets */
> +#define RCPU_SSP0_CLK_RST		0x0028
> +#define RCPU_I2C0_CLK_RST		0x0030
> +#define RCPU_UART1_CLK_RST		0x003c
> +#define RCPU_CAN_CLK_RST		0x0048
> +#define RCPU_IR_CLK_RST			0x004c
> +#define RCPU_UART0_CLK_RST		0x00d8
> +/* XXX Next one is part of the AUD_AUDCLOCK region @ 0xc0882000 */
this comment looks odd, XXX?
> +#define AUDIO_HDMI_CLK_CTRL		0x2044
> +
> +/* RCPU2 register offsets */
> +#define RCPU2_PWM0_CLK_RST		0x0000
> +#define RCPU2_PWM1_CLK_RST		0x0004
> +#define RCPU2_PWM2_CLK_RST		0x0008
> +#define RCPU2_PWM3_CLK_RST		0x000c
> +#define RCPU2_PWM4_CLK_RST		0x0010
> +#define RCPU2_PWM5_CLK_RST		0x0014
> +#define RCPU2_PWM6_CLK_RST		0x0018
> +#define RCPU2_PWM7_CLK_RST		0x001c
> +#define RCPU2_PWM8_CLK_RST		0x0020
> +#define RCPU2_PWM9_CLK_RST		0x0024
> +
> +/* APBC2 register offsets */
> +#define APBC2_UART1_CLK_RST		0x0000
> +#define APBC2_SSP2_CLK_RST		0x0004
> +#define APBC2_TWSI3_CLK_RST		0x0008
> +#define APBC2_RTC_CLK_RST		0x000c
> +#define APBC2_TIMERS0_CLK_RST		0x0010
> +#define APBC2_KPC_CLK_RST		0x0014
> +#define APBC2_GPIO_CLK_RST		0x001c
> +
>  struct spacemit_ccu_clk {
>  	int id;
>  	struct clk_hw *hw;
> @@ -1781,6 +1812,69 @@ static const struct k1_ccu_data k1_ccu_apmu_data = {
>  	.rst_data	= &apmu_reset_controller_data,
>  };
>  
> +static const struct ccu_reset_data rcpu_reset_data[] = {
> +	[RST_RCPU_SSP0]		= RST_DATA(RCPU_SSP0_CLK_RST,	0, BIT(0)),
> +	[RST_RCPU_I2C0]		= RST_DATA(RCPU_I2C0_CLK_RST,	0, BIT(0)),
> +	[RST_RCPU_UART1]	= RST_DATA(RCPU_UART1_CLK_RST,	0, BIT(0)),
> +	[RST_RCPU_IR]		= RST_DATA(RCPU_CAN_CLK_RST,	0, BIT(0)),
> +	[RST_RCPU_CAN]		= RST_DATA(RCPU_IR_CLK_RST,	0, BIT(0)),
> +	[RST_RCPU_UART0]	= RST_DATA(RCPU_UART0_CLK_RST,	0, BIT(0)),
> +	[RST_RCPU_HDMI_AUDIO]	= RST_DATA(AUDIO_HDMI_CLK_CTRL,	0, BIT(0)),
> +};
> +
> +static const struct ccu_reset_controller_data rcpu_reset_controller_data = {
> +	.count		= ARRAY_SIZE(rcpu_reset_data),
> +	.data		= rcpu_reset_data,
> +};
> +
> +static struct k1_ccu_data k1_ccu_rcpu_data = {
> +	/* No clocks in the RCPU CCU */
> +	.rst_data	= &rcpu_reset_controller_data,
> +};
> +
> +static const struct ccu_reset_data rcpu2_reset_data[] = {
> +	[RST_RCPU2_PWM0]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> +	[RST_RCPU2_PWM1]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> +	[RST_RCPU2_PWM2]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> +	[RST_RCPU2_PWM3]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> +	[RST_RCPU2_PWM4]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> +	[RST_RCPU2_PWM5]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> +	[RST_RCPU2_PWM6]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> +	[RST_RCPU2_PWM7]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> +	[RST_RCPU2_PWM8]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> +	[RST_RCPU2_PWM9]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> +};
> +
> +static const struct ccu_reset_controller_data rcpu2_reset_controller_data = {
> +	.count		= ARRAY_SIZE(rcpu2_reset_data),
> +	.data		= rcpu2_reset_data,
> +};
> +
> +static struct k1_ccu_data k1_ccu_rcpu2_data = {
> +	/* No clocks in the RCPU2 CCU */
> +	.rst_data	= &rcpu2_reset_controller_data,
> +};
> +
> +static const struct ccu_reset_data apbc2_reset_data[] = {
> +	[RST_APBC2_UART1]	= RST_DATA(APBC2_UART1_CLK_RST,	BIT(2), (0)),
> +	[RST_APBC2_SSP2]	= RST_DATA(APBC2_SSP2_CLK_RST,	BIT(2), (0)),
> +	[RST_APBC2_TWSI3]	= RST_DATA(APBC2_TWSI3_CLK_RST,	BIT(2), (0)),
> +	[RST_APBC2_RTC]		= RST_DATA(APBC2_RTC_CLK_RST,	BIT(2), (0)),
> +	[RST_APBC2_TIMERS0]	= RST_DATA(APBC2_TIMERS0_CLK_RST, BIT(2), (0)),
> +	[RST_APBC2_KPC]		= RST_DATA(APBC2_KPC_CLK_RST,	BIT(2), (0)),
> +	[RST_APBC2_GPIO]	= RST_DATA(APBC2_GPIO_CLK_RST,	BIT(2), (0)),
> +};
> +
> +static const struct ccu_reset_controller_data apbc2_reset_controller_data = {
> +	.count		= ARRAY_SIZE(apbc2_reset_data),
> +	.data		= apbc2_reset_data,
> +};
> +
> +static struct k1_ccu_data k1_ccu_apbc2_data = {
> +	/* No clocks in the RCPU2 CCU */
> +	.rst_data	= &apbc2_reset_controller_data,
> +};
> +
>  static struct ccu_reset_controller *
>  rcdev_to_controller(struct reset_controller_dev *rcdev)
>  {
> @@ -1959,6 +2053,18 @@ static const struct of_device_id of_k1_ccu_match[] = {
>  		.compatible	= "spacemit,k1-syscon-apmu",
>  		.data		= &k1_ccu_apmu_data,
>  	},
> +	{
> +		.compatible	= "spacemit,k1-syscon-rcpu",
> +		.data		= &k1_ccu_rcpu_data,
> +	},
> +	{
> +		.compatible	= "spacemit,k1-syscon-rcpu2",
> +		.data		= &k1_ccu_rcpu2_data,
> +	},
> +	{
> +		.compatible	= "spacemit,k1-syscon-apbc2",
> +		.data		= &k1_ccu_apbc2_data,
> +	},
>  	{ }
>  };
>  MODULE_DEVICE_TABLE(of, of_k1_ccu_match);
> -- 
> 2.43.0
> 

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55

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

* Re: [PATCH RESEND 7/7] riscv: dts: spacemit: add reset support for the K1 SoC
  2025-03-21 15:18 ` [PATCH RESEND 7/7] riscv: dts: spacemit: add reset support for the K1 SoC Alex Elder
@ 2025-03-22 16:48   ` Yixun Lan
  2025-03-23 13:23     ` Alex Elder
  0 siblings, 1 reply; 34+ messages in thread
From: Yixun Lan @ 2025-03-22 16:48 UTC (permalink / raw)
  To: Alex Elder
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

On 10:18 Fri 21 Mar     , Alex Elder wrote:
> Define syscon nodes for the RCPU, RCPU2, and APBC2 SpacemiT CCUS, which
> currently support resets but not clocks in the SpacemiT K1.
> 
> Signed-off-by: Alex Elder <elder@riscstar.com>
> ---
>  arch/riscv/boot/dts/spacemit/k1.dtsi | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi
> index 09a9100986b19..f86d1b58c6d35 100644
> --- a/arch/riscv/boot/dts/spacemit/k1.dtsi
> +++ b/arch/riscv/boot/dts/spacemit/k1.dtsi
> @@ -350,6 +350,18 @@ soc {
>  		dma-noncoherent;
>  		ranges;
>  
> +		syscon_rcpu: system-controller@c0880000 {
I'm not sure if syscon_rcpu is good name to go, it's AUDIO Peripherals
in docs, see

7.2 Main CPU Domain Address Mapping
https://developer.spacemit.com/documentation?token=LzJyw97BCipK1dkUygrcbT0NnMg
> +			compatible = "spacemit,k1-syscon-rcpu";
> +			reg = <0x0 0xc0880000 0x0 0x2048>;
> +			#reset-cells = <1>;
> +		};
> +
> +		syscon_rcpu2: system-controller@c0888000 {
not found this address mapping in above docs link
> +			compatible = "spacemit,k1-syscon-rcpu2";
> +			reg = <0x0 0xc0888000 0x0 0x28>;
> +			#reset-cells = <1>;
> +		};
> +
>  		syscon_apbc: system-control@d4015000 {
>  			compatible = "spacemit,k1-syscon-apbc";
>  			reg = <0x0 0xd4015000 0x0 0x1000>;
> @@ -518,6 +530,12 @@ clint: timer@e4000000 {
>  					      <&cpu7_intc 3>, <&cpu7_intc 7>;
>  		};
>  
> +		syscon_apbc2: system-controller@f0610000 {
> +			compatible = "spacemit,k1-syscon-apbc2";
> +			reg = <0x0 0xf0610000 0x0 0x20>;
> +			#reset-cells = <1>;
> +		};
> +
>  		sec_uart1: serial@f0612000 {
>  			compatible = "spacemit,k1-uart", "intel,xscale-uart";
>  			reg = <0x0 0xf0612000 0x0 0x100>;
> -- 
> 2.43.0
> 

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55

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

* Re: [PATCH RESEND 1/7] dt-bindings: soc: spacemit: define spacemit,k1-ccu resets
  2025-03-22 14:27     ` Alex Elder
@ 2025-03-22 16:51       ` Yixun Lan
  0 siblings, 0 replies; 34+ messages in thread
From: Yixun Lan @ 2025-03-22 16:51 UTC (permalink / raw)
  To: Alex Elder
  Cc: robh, krzk+dt, conor+dt, p.zabel, mturquette, sboyd, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

Hi Alex:

On 09:27 Sat 22 Mar     , Alex Elder wrote:
> On 3/21/25 5:25 PM, Yixun Lan wrote:
> > hi Alex:
> > 
> > On 10:18 Fri 21 Mar     , Alex Elder wrote:
> >> There are additional SpacemiT syscon CCUs whose registers control both
> >> clocks and resets:  RCPU, RCPU2, and APBC2. Unlike those defined
> >> previously, these will initially support only resets.  They do not
> >> incorporate power domain functionality.
> >>
> >> Define the index values for resets associated with all SpacemiT K1
> >> syscon nodes, including those with clocks already defined, as well as
> >> the new ones (without clocks).
> >>
> >> Signed-off-by: Alex Elder <elder@riscstar.com>
> >> ---
> >>   .../soc/spacemit/spacemit,k1-syscon.yaml      |  13 +-
> >>   include/dt-bindings/clock/spacemit,k1-ccu.h   | 134 ++++++++++++++++++
> >>   2 files changed, 143 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
> >> index 07a6728e6f864..333c28e075b6c 100644
> >> --- a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
> >> +++ b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
> >> @@ -19,6 +19,9 @@ properties:
> >>         - spacemit,k1-syscon-apbc
> >>         - spacemit,k1-syscon-apmu
> >>         - spacemit,k1-syscon-mpmu
> >> +      - spacemit,k1-syscon-rcpu
> >> +      - spacemit,k1-syscon-rcpu2
> >> +      - spacemit,k1-syscon-apbc2
> >>   
> >>     reg:
> >>       maxItems: 1
> 
> . . .
> 
> 32
> >> @@ -180,6 +184,60 @@
> >>   #define CLK_TSEN_BUS		98
> >>   #define CLK_IPC_AP2AUD_BUS	99
> >>   
> >> +/*	APBC resets	*/
> >> +
> > I'd also suggest to drop above blank line, keep style consistent
> > with others in this file, some same below that I won't comment
> 
> OK, I'll fix the weird extra line and will drop these blank
> lines as you suggest in v2.  I'll post another version after
> Sunday.  I recognize the merge window means I can't expect
> reviews during that time, but this code is waiting for the
> clock code to get accepted anyway.
> 
no need to hurry, we will postpone clock to next merge window,
let's give more time for people to review, thanks

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55

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

* Re: [PATCH RESEND 2/7] clk: spacemit: define struct k1_ccu_data
  2025-03-22 15:50   ` Yixun Lan
@ 2025-03-23 12:43     ` Alex Elder
  2025-03-23 13:04       ` Yixun Lan
  2025-03-28 17:24     ` Alex Elder
  1 sibling, 1 reply; 34+ messages in thread
From: Alex Elder @ 2025-03-23 12:43 UTC (permalink / raw)
  To: Yixun Lan
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

On 3/22/25 10:50 AM, Yixun Lan wrote:
> Hi Alex:
> 
> this patch change relate to clock only, so how about let's fold
> it into clk patches (which now has not been merged), so we make
> the code right at first place? cause some moving around and renaming

No I don't want to do that.

The clock patches are Haylen's and the are getting closer to
acceptance.  Let's not confuse things by adding a bunch of new
functionality.  Get those patches in, and mine can follow not
too long after that.

					-Alex
> 
> On 10:18 Fri 21 Mar     , Alex Elder wrote:
>> Define a new structure type to be used for describing the OF match data.
>> Rather than using the array of spacemit_ccu_clk structures for match
>> data, we use this structure instead.
>>
>> Move the definition of the spacemit_ccu_clk structure closer to the top
>> of the source file, and add the new structure definition below it.
>>
>> Shorten the name of spacemit_ccu_register() to be k1_ccu_register().
> any good reason to change this? it make the code style inconsistent,
> do you just change it for shorten function, or want it to be more k1
> specific, so next SoC - e.g maybe k2? will introduce another function?
> 
>>
>> Signed-off-by: Alex Elder <elder@riscstar.com>
>> ---
>>   drivers/clk/spacemit/ccu-k1.c | 58 ++++++++++++++++++++++++++---------
>>   1 file changed, 43 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
>> index 44db48ae71313..f7367271396a0 100644
>> --- a/drivers/clk/spacemit/ccu-k1.c
>> +++ b/drivers/clk/spacemit/ccu-k1.c
>> @@ -129,6 +129,15 @@
>>   #define APMU_EMAC0_CLK_RES_CTRL		0x3e4
>>   #define APMU_EMAC1_CLK_RES_CTRL		0x3ec
>>   
>> +struct spacemit_ccu_clk {
>> +	int id;
>> +	struct clk_hw *hw;
>> +};
>> +
>> +struct k1_ccu_data {
>> +	struct spacemit_ccu_clk *clk;		/* array with sentinel */
>> +};
>> +
>>   /*	APBS clocks start	*/
>>   
>>   /* Frequency of pll{1,2} should not be updated at runtime */
>> @@ -1359,11 +1368,6 @@ static CCU_GATE_DEFINE(emmc_bus_clk, CCU_PARENT_HW(pmua_aclk),
>>   		       0);
>>   /*	APMU clocks end		*/
>>   
>> -struct spacemit_ccu_clk {
>> -	int id;
>> -	struct clk_hw *hw;
>> -};
>> -
>>   static struct spacemit_ccu_clk k1_ccu_apbs_clks[] = {
>>   	{ CLK_PLL1,		&pll1.common.hw },
>>   	{ CLK_PLL2,		&pll2.common.hw },
>> @@ -1403,6 +1407,10 @@ static struct spacemit_ccu_clk k1_ccu_apbs_clks[] = {
>>   	{ 0,			NULL },
>>   };
>>   
>> +static const struct k1_ccu_data k1_ccu_apbs_data = {
>> +	.clk		= k1_ccu_apbs_clks,
>> +};
>> +
>>   static struct spacemit_ccu_clk k1_ccu_mpmu_clks[] = {
>>   	{ CLK_PLL1_307P2,	&pll1_d8_307p2.common.hw },
>>   	{ CLK_PLL1_76P8,	&pll1_d32_76p8.common.hw },
>> @@ -1440,6 +1448,10 @@ static struct spacemit_ccu_clk k1_ccu_mpmu_clks[] = {
>>   	{ 0,			NULL },
>>   };
>>   
>> +static const struct k1_ccu_data k1_ccu_mpmu_data = {
>> +	.clk		= k1_ccu_mpmu_clks,
>> +};
>> +
>>   static struct spacemit_ccu_clk k1_ccu_apbc_clks[] = {
>>   	{ CLK_UART0,		&uart0_clk.common.hw },
>>   	{ CLK_UART2,		&uart2_clk.common.hw },
>> @@ -1544,6 +1556,10 @@ static struct spacemit_ccu_clk k1_ccu_apbc_clks[] = {
>>   	{ 0,			NULL },
>>   };
>>   
>> +static const struct k1_ccu_data k1_ccu_apbc_data = {
>> +	.clk		= k1_ccu_apbc_clks,
>> +};
>> +
>>   static struct spacemit_ccu_clk k1_ccu_apmu_clks[] = {
>>   	{ CLK_CCI550,		&cci550_clk.common.hw },
>>   	{ CLK_CPU_C0_HI,	&cpu_c0_hi_clk.common.hw },
>> @@ -1610,9 +1626,13 @@ static struct spacemit_ccu_clk k1_ccu_apmu_clks[] = {
>>   	{ 0,			NULL },
>>   };
>>   
>> -static int spacemit_ccu_register(struct device *dev,
>> -				 struct regmap *regmap, struct regmap *lock_regmap,
>> -				 const struct spacemit_ccu_clk *clks)
>> +static const struct k1_ccu_data k1_ccu_apmu_data = {
>> +	.clk		= k1_ccu_apmu_clks,
>> +};
>> +
>> +static int k1_ccu_register(struct device *dev, struct regmap *regmap,
>> +			   struct regmap *lock_regmap,
>> +			   struct spacemit_ccu_clk *clks)
>>   {
>>   	const struct spacemit_ccu_clk *clk;
>>   	int i, ret, max_id = 0;
>> @@ -1648,15 +1668,24 @@ static int spacemit_ccu_register(struct device *dev,
>>   
>>   	clk_data->num = max_id + 1;
>>   
>> -	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
>> +	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
>> +	if (ret)
>> +		dev_err(dev, "error %d adding clock hardware provider\n", ret);
>> +
>> +	return ret;
> I'd use "return 0;", nothing different, just explicitly short
> 
> ok, I can understand this change ease debug procedure once there is problem.
> (but I'm fine with either way, failure should rarely happen & will
> identify early)
> 
>>   }
>>   
>>   static int k1_ccu_probe(struct platform_device *pdev)
>>   {
>>   	struct regmap *base_regmap, *lock_regmap = NULL;
>>   	struct device *dev = &pdev->dev;
>> +	const struct k1_ccu_data *data;
>>   	int ret;
>>   
>> +	data = of_device_get_match_data(dev);
>> +	if (!data)
>> +		return -EINVAL;
>> +
>>   	base_regmap = device_node_to_regmap(dev->of_node);
>>   	if (IS_ERR(base_regmap))
>>   		return dev_err_probe(dev, PTR_ERR(base_regmap),
>> @@ -1677,8 +1706,7 @@ static int k1_ccu_probe(struct platform_device *pdev)
>>   					     "failed to get lock regmap\n");
>>   	}
>>   
>> -	ret = spacemit_ccu_register(dev, base_regmap, lock_regmap,
>> -				    of_device_get_match_data(dev));
>> +	ret = k1_ccu_register(dev, base_regmap, lock_regmap, data->clk);
>>   	if (ret)
>>   		return dev_err_probe(dev, ret, "failed to register clocks\n");
>>   
>> @@ -1688,19 +1716,19 @@ static int k1_ccu_probe(struct platform_device *pdev)
>>   static const struct of_device_id of_k1_ccu_match[] = {
>>   	{
>>   		.compatible	= "spacemit,k1-pll",
>> -		.data		= k1_ccu_apbs_clks,
>> +		.data		= &k1_ccu_apbs_data,
>>   	},
>>   	{
>>   		.compatible	= "spacemit,k1-syscon-mpmu",
>> -		.data		= k1_ccu_mpmu_clks,
>> +		.data		= &k1_ccu_mpmu_data,
>>   	},
>>   	{
>>   		.compatible	= "spacemit,k1-syscon-apbc",
>> -		.data		= k1_ccu_apbc_clks,
>> +		.data		= &k1_ccu_apbc_data,
>>   	},
>>   	{
>>   		.compatible	= "spacemit,k1-syscon-apmu",
>> -		.data		= k1_ccu_apmu_clks,
>> +		.data		= &k1_ccu_apmu_data,
>>   	},
>>   	{ }
> 	{ /* sentinel */ }
>>   };
>> -- 
>> 2.43.0
>>
> 


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

* Re: [PATCH RESEND 2/7] clk: spacemit: define struct k1_ccu_data
  2025-03-23 12:43     ` Alex Elder
@ 2025-03-23 13:04       ` Yixun Lan
  2025-03-23 22:30         ` Alex Elder
  0 siblings, 1 reply; 34+ messages in thread
From: Yixun Lan @ 2025-03-23 13:04 UTC (permalink / raw)
  To: Alex Elder
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

On 07:43 Sun 23 Mar     , Alex Elder wrote:
> On 3/22/25 10:50 AM, Yixun Lan wrote:
> > Hi Alex:
> > 
> > this patch change relate to clock only, so how about let's fold
> > it into clk patches (which now has not been merged), so we make
> > the code right at first place? cause some moving around and renaming
> 
> No I don't want to do that.
> 
> The clock patches are Haylen's and the are getting closer to
> acceptance.  Let's not confuse things by adding a bunch of new
> functionality.  Get those patches in, and mine can follow not
> too long after that.
> 

I only mean patch [2/7], not all patches, as it's still clock related
but, either way fine by me if you insist

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55

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

* Re: [PATCH RESEND 3/7] clk: spacemit: add reset controller support
  2025-03-22 16:19   ` Yixun Lan
@ 2025-03-23 13:23     ` Alex Elder
  2025-03-24  6:40       ` Yixun Lan
  0 siblings, 1 reply; 34+ messages in thread
From: Alex Elder @ 2025-03-23 13:23 UTC (permalink / raw)
  To: Yixun Lan
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

On 3/22/25 11:19 AM, Yixun Lan wrote:
> Hi Alex:
> 
> On 10:18 Fri 21 Mar     , Alex Elder wrote:
>> Define ccu_reset_data as a structure that contains the constant
>> register offset and bitmasks used to assert and deassert a reset
>> control on a SpacemiT K1 CCU. Define ccu_reset_controller_data as
>> a structure that contains the address of an array of those structures
>> and a count of the number of elements in the array.
>>
>> Add a pointer to a ccu_reset_controller_data structure to the
>> k1_ccu_data structure.  Reset support is optional for SpacemiT CCUs;
>> the new pointer field will be null for CCUs without any resets.
>>
>> Finally, define a new ccu_reset_controller structure, which (for
>> a CCU with resets) contains a pointer to the constant reset data,
>> the regmap to be used for the controller, and an embedded a reset
>> controller structure.
>>
>> Each reset control is asserted or deasserted by updating bits in
>> a register.  The bits used are defined by an assert mask and a
>> deassert mask.  In some cases, one (non-zero) mask asserts reset
>> and a different (non-zero) mask deasserts it.  Otherwise one mask
>> is nonzero, and the other is zero.  Either way, the bits in
>> both masks are cleared, then either the assert mask or the deassert
>> mask is set in a register to affect the state of a reset control.
>>
>> Signed-off-by: Alex Elder <elder@riscstar.com>
>> ---
>>   drivers/clk/spacemit/ccu-k1.c | 93 +++++++++++++++++++++++++++++++++++
>>   1 file changed, 93 insertions(+)
>>
>> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
>> index f7367271396a0..6d879411c6c05 100644
>> --- a/drivers/clk/spacemit/ccu-k1.c
>> +++ b/drivers/clk/spacemit/ccu-k1.c
>> @@ -10,6 +10,7 @@
>>   #include <linux/minmax.h>
>>   #include <linux/module.h>
>>   #include <linux/platform_device.h>
>> +#include <linux/reset-controller.h>
>>   
>>   #include "ccu_common.h"
>>   #include "ccu_pll.h"
>> @@ -134,8 +135,26 @@ struct spacemit_ccu_clk {
>>   	struct clk_hw *hw;
>>   };
>>   
>> +struct ccu_reset_data {
>> +	u32 offset;
>> +	u32 assert_mask;
>> +	u32 deassert_mask;
>> +};
>> +
>> +struct ccu_reset_controller_data {
>> +	u32 count;
>> +	const struct ccu_reset_data *data;	/* array */
>> +};
>> +
>>   struct k1_ccu_data {
>>   	struct spacemit_ccu_clk *clk;		/* array with sentinel */
>> +	const struct ccu_reset_controller_data *rst_data;
>> +};
>> +
>> +struct ccu_reset_controller {
>> +	struct regmap *regmap;
>> +	const struct ccu_reset_controller_data *data;
>> +	struct reset_controller_dev rcdev;
>>   };
>>   
>>   /*	APBS clocks start	*/
>> @@ -1630,6 +1649,48 @@ static const struct k1_ccu_data k1_ccu_apmu_data = {
>>   	.clk		= k1_ccu_apmu_clks,
>>   };
>>   
>> +static struct ccu_reset_controller *
>> +rcdev_to_controller(struct reset_controller_dev *rcdev)
> I'd suggest to avoid the line break to make it slightly more readable, intuitive
> as the 80 column limit isn't hard rule
> 
> there are maybe more place similar to this, I won't add more comments
> https://github.com/torvalds/linux/commit/bdc48fa11e46f867ea4d75fa59ee87a7f48be144

I disagree with this suggestion.  I personally find this
more readable.  As the first line of the patch you link to,
"80 columns is still preferred".  And regardless, it is my
(strong) preference to work within 80 columns in almost all
cases.

>> +{
>> +	return container_of(rcdev, struct ccu_reset_controller, rcdev);
>> +}
> since this function is only used once, open-code it?
> but I'd fine with either way if you prefer to keep it

The "to_<containing_type>()" function pattern is extremely
common, but I like this suggestion, given it's used only
once.  I'll implement it in v2.

> 
>> +
>> +static int
>> +k1_rst_update(struct reset_controller_dev *rcdev, unsigned long id, bool assert)
> s/k1_rst_update/k1_reset_update/g
> this is a taste change, but I found more people follow this when grep driver/reset

I actually had reset (not rst) before, throughout.  But it made
a few lines too long, leading to line wraps, so I did this.

In addition, there was a sort of consistency with the use of
"clk" instead of "clock", though I do recognize that abbreviation
goes way back to when Mike implemented the common clock framework.

I'll switch back to "reset" (and "RESET") in names, but be warned
I'll add some line breaks to fit within 80 columns.

>> +{
>> +	struct ccu_reset_controller *controller = rcdev_to_controller(rcdev);
>> +	struct regmap *regmap = controller->regmap;
>> +	const struct ccu_reset_data *data;
>> +	u32 val;
>> +	int ret;
>> +
>> +	data = &controller->data->data[id];
>> +
>> +	ret = regmap_read(regmap, data->offset, &val);
>> +	if (ret)
>> +		return ret;
>> +
>> +	val &= ~(data->assert_mask | data->deassert_mask);
>> +	val |= assert ? data->assert_mask : data->deassert_mask;
>> +
>> +	return regmap_write(regmap, data->offset, val);
>> +}
>> +
>> +static int k1_rst_assert(struct reset_controller_dev *rcdev, unsigned long id)
> same reason, rst -> reset, more below
>> +{
>> +	return k1_rst_update(rcdev, id, true);
>> +}
>> +
>> +static int k1_rst_deassert(struct reset_controller_dev *rcdev, unsigned long id)
>> +{
>> +	return k1_rst_update(rcdev, id, false);
>> +}
>> +
>> +static const struct reset_control_ops k1_reset_control_ops = {
>> +	.assert		= k1_rst_assert,
>> +	.deassert	= k1_rst_deassert,
>> +};
>> +
>>   static int k1_ccu_register(struct device *dev, struct regmap *regmap,
>>   			   struct regmap *lock_regmap,
>>   			   struct spacemit_ccu_clk *clks)
>> @@ -1675,6 +1736,33 @@ static int k1_ccu_register(struct device *dev, struct regmap *regmap,
>>   	return ret;
>>   }
>>   
>> +static int
>> +k1_reset_controller_register(struct device *dev, struct regmap *regmap,
>> +			     const struct ccu_reset_controller_data *data)
>> +{
>> +	struct ccu_reset_controller *controller;
>> +	struct reset_controller_dev *rcdev;
>> +
>> +	/* Resets are optional */
>> +	if (!data)
>> +		return 0;
>> +
>> +	controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL);
>> +	if (!controller)
>> +		return -ENOMEM;
>> +
>> +	controller->regmap = regmap;
>> +	controller->data = data;
>> +
>> +	rcdev = &controller->rcdev;
> ..
>> +	rcdev->owner = THIS_MODULE;
> move to last?

You mean move nr_resets to last?  I'll do that.  I'll
order the assignments in the order they're defined in
"reset-controller.h".

>> +	rcdev->nr_resets = data->count;
>> +	rcdev->ops = &k1_reset_control_ops;
>> +	rcdev->of_node = dev->of_node;
>> +
>> +	return devm_reset_controller_register(dev, rcdev);
>> +}
>> +
>>   static int k1_ccu_probe(struct platform_device *pdev)
>>   {
>>   	struct regmap *base_regmap, *lock_regmap = NULL;
>> @@ -1710,6 +1798,11 @@ static int k1_ccu_probe(struct platform_device *pdev)
>>   	if (ret)
>>   		return dev_err_probe(dev, ret, "failed to register clocks\n");
>>   
>> +	ret = k1_reset_controller_register(dev, base_regmap, data->rst_data);
> ..
>> +	if (ret)
>> +		return dev_err_probe(dev, ret,
>> +				     "failed to register reset controller\n");
> same 100 column reason

This one I might go beyond columns, because it's only a few characters.

					-Alex

>> +
>>   	return 0;
>>   }
>>   
>> -- 
>> 2.43.0
>>
> 


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

* Re: [PATCH RESEND 4/7] clk: spacemit: define existing syscon resets
  2025-03-22 16:29   ` Yixun Lan
@ 2025-03-23 13:23     ` Alex Elder
  2025-03-24  6:24       ` Yixun Lan
  0 siblings, 1 reply; 34+ messages in thread
From: Alex Elder @ 2025-03-23 13:23 UTC (permalink / raw)
  To: Yixun Lan
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

On 3/22/25 11:29 AM, Yixun Lan wrote:
> On 10:18 Fri 21 Mar     , Alex Elder wrote:
>> Define reset controls associated with the MPMU, APBC, and APMU
>> SpacemiT K1 CCUs.  These already have clocks associated with them.
>>
>> Signed-off-by: Alex Elder <elder@riscstar.com>
>> ---
>>   drivers/clk/spacemit/ccu-k1.c | 132 ++++++++++++++++++++++++++++++++++
>>   1 file changed, 132 insertions(+)
>>
>> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
>> index 6d879411c6c05..be8abd27753cb 100644
>> --- a/drivers/clk/spacemit/ccu-k1.c
>> +++ b/drivers/clk/spacemit/ccu-k1.c
> ..
>> +static const struct ccu_reset_data apmu_reset_data[] = {
>> +	[RST_CCIC_4X]	= RST_DATA(APMU_CCIC_CLK_RES_CTRL,	0, BIT(1)),
>> +	[RST_CCIC1_PHY] = RST_DATA(APMU_CCIC_CLK_RES_CTRL,	0, BIT(2)),
>> +	[RST_SDH_AXI]	= RST_DATA(APMU_SDH0_CLK_RES_CTRL,	0, BIT(0)),
>> +	[RST_SDH0]	= RST_DATA(APMU_SDH0_CLK_RES_CTRL,	0, BIT(1)),
>> +	[RST_SDH1]	= RST_DATA(APMU_SDH1_CLK_RES_CTRL,	0, BIT(1)),
>> +	[RST_SDH2]	= RST_DATA(APMU_SDH2_CLK_RES_CTRL,	0, BIT(1)),
>> +	[RST_USBP1_AXI] = RST_DATA(APMU_USB_CLK_RES_CTRL,	0, BIT(4)),
>> +	[RST_USB_AXI]	= RST_DATA(APMU_USB_CLK_RES_CTRL,	0, BIT(0)),
> ..
>> +	[RST_USB3_0]	= RST_DATA(APMU_USB_CLK_RES_CTRL,	0,
>> +				      BIT(9)|BIT(10)|BIT(11)),
> 100 column if possible, also add one space between "BIT(9) | BIT(10) .."
> continuous bits can just use GENMASK for short?

You'll notice that every place that has multiple bits in the mask
also have a line break.  I kind of liked that as a way to highlight
that fact (i.e., it goes beyond my preference for 80 columns).

I will definitely add spaces, that was a mistake not to.

I will not define this with GENMASK().  In this case each bit
represents a single reset, and so each one is significant on
its own.  It is *not* a mask of contiguous bits, it's a set
of bits that happen to have consecutive positions.

					-Alex

> but may result slightly unreadable, anyway, either way is fine by me
> 
>> +	[RST_QSPI]	= RST_DATA(APMU_QSPI_CLK_RES_CTRL,	0, BIT(1)),
>> +	[RST_QSPI_BUS] = RST_DATA(APMU_QSPI_CLK_RES_CTRL,	0, BIT(0)),
>> +	[RST_DMA]	= RST_DATA(APMU_DMA_CLK_RES_CTRL,	0, BIT(0)),
>> +	[RST_AES]	= RST_DATA(APMU_AES_CLK_RES_CTRL,	0, BIT(4)),
>> +	[RST_VPU]	= RST_DATA(APMU_VPU_CLK_RES_CTRL,	0, BIT(0)),
>> +	[RST_GPU]	= RST_DATA(APMU_GPU_CLK_RES_CTRL,	0, BIT(1)),
>> +	[RST_EMMC]	= RST_DATA(APMU_PMUA_EM_CLK_RES_CTRL,	0, BIT(1)),
>> +	[RST_EMMC_X]	= RST_DATA(APMU_PMUA_EM_CLK_RES_CTRL,	0, BIT(0)),
>> +	[RST_AUDIO]	= RST_DATA(APMU_AUDIO_CLK_RES_CTRL,	0,
>> +				   BIT(0) | BIT(2) | BIT(3)),
>> +	[RST_HDMI]	= RST_DATA(APMU_HDMI_CLK_RES_CTRL,	0, BIT(9)),
>> +	[RST_PCIE0]	= RST_DATA(APMU_PCIE_CLK_RES_CTRL_0,	BIT(8),
>> +				   BIT(3) | BIT(4) | BIT(5)),
>> +	[RST_PCIE1]	= RST_DATA(APMU_PCIE_CLK_RES_CTRL_1,	BIT(8),
>> +				   BIT(3) | BIT(4) | BIT(5)),
>> +	[RST_PCIE2]	= RST_DATA(APMU_PCIE_CLK_RES_CTRL_2,	BIT(8),
>> +				   BIT(3) | BIT(4) | BIT(5)),
>> +	[RST_EMAC0]	= RST_DATA(APMU_EMAC0_CLK_RES_CTRL,	0, BIT(1)),
>> +	[RST_EMAC1]	= RST_DATA(APMU_EMAC1_CLK_RES_CTRL,	0, BIT(1)),
>> +	[RST_JPG]	= RST_DATA(APMU_JPG_CLK_RES_CTRL,	0, BIT(0)),
>> +	[RST_CCIC2PHY]	= RST_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL,	0, BIT(2)),
>> +	[RST_CCIC3PHY]	= RST_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL,	0, BIT(29)),
>> +	[RST_CSI]	= RST_DATA(APMU_CSI_CCIC2_CLK_RES_CTRL,	0, BIT(1)),
>> +	[RST_ISP]	= RST_DATA(APMU_ISP_CLK_RES_CTRL,	0, BIT(0)),
>> +	[RST_ISP_CPP]	= RST_DATA(APMU_ISP_CLK_RES_CTRL,	0, BIT(27)),
>> +	[RST_ISP_BUS]	= RST_DATA(APMU_ISP_CLK_RES_CTRL,	0, BIT(3)),
>> +	[RST_ISP_CI]	= RST_DATA(APMU_ISP_CLK_RES_CTRL,	0, BIT(16)),
>> +	[RST_DPU_MCLK]	= RST_DATA(APMU_LCD_CLK_RES_CTRL2,	0, BIT(9)),
>> +	[RST_DPU_ESC]	= RST_DATA(APMU_LCD_CLK_RES_CTRL1,	0, BIT(3)),
>> +	[RST_DPU_HCLK]	= RST_DATA(APMU_LCD_CLK_RES_CTRL1,	0, BIT(4)),
>> +	[RST_DPU_SPIBUS] = RST_DATA(APMU_LCD_SPI_CLK_RES_CTRL,	0, BIT(4)),
>> +	[RST_DPU_SPI_HBUS] = RST_DATA(APMU_LCD_SPI_CLK_RES_CTRL, 0, BIT(2)),
>> +	[RST_V2D]	= RST_DATA(APMU_LCD_CLK_RES_CTRL1,	0, BIT(27)),
>> +	[RST_MIPI]	= RST_DATA(APMU_LCD_CLK_RES_CTRL1,	0, BIT(15)),
>> +	[RST_MC]	= RST_DATA(APMU_PMUA_MC_CTRL,		0, BIT(0)),
>> +};
>> +
>> +static const struct ccu_reset_controller_data apmu_reset_controller_data = {
>> +	.count		= ARRAY_SIZE(apmu_reset_data),
>> +	.data		= apmu_reset_data,
>> +};
>> +
>>   static const struct k1_ccu_data k1_ccu_apmu_data = {
>>   	.clk		= k1_ccu_apmu_clks,
>> +	.rst_data	= &apmu_reset_controller_data,
>>   };
>>   
>>   static struct ccu_reset_controller *
>> -- 
>> 2.43.0
>>
> 


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

* Re: [PATCH RESEND 6/7] clk: spacemit: define new syscons with only resets
  2025-03-22 16:42   ` Yixun Lan
@ 2025-03-23 13:23     ` Alex Elder
  2025-03-24  6:21       ` Yixun Lan
  0 siblings, 1 reply; 34+ messages in thread
From: Alex Elder @ 2025-03-23 13:23 UTC (permalink / raw)
  To: Yixun Lan
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	paul.walmsley, palmer, aou, spacemit, devicetree, linux-clk,
	linux-riscv, linux-kernel

On 3/22/25 11:42 AM, Yixun Lan wrote:
> Hi Alex:
> 
> It occur to me it's a little odd to implemnt reset driver
> for RCPU block, but after check with vendor the RCPU region can
> be accessed both by ACPU and RCPU, then I'm fine with this.

I implemented just the resets that were found in the downstream
code.

I first implemented a separate reset driver, very simple, which
only implemented the resets.  I had a separate DTS binding (like
was done for the PLLs).  I was ready to post it for review, then
noticed that the registers used were shared with clocks.  So I
merged all of that separate code into the clock driver, as you
see here.

> ACPU - RISC-V Main CPU, with mmu, running Linux
> RCPU - real time CPU, without mmu, running RT-OS

I didn't realize there was a separate CPU running its
own OS.  Is this managed as a remoteproc by the RISC-V AP?
The reset signals, I hope, are only touched by the AP
and not the real-time CPU.  Can you provide any further
information about this?

> On 10:18 Fri 21 Mar     , Alex Elder wrote:
>> Enable support for three additional syscon CCUs which support reset
>> controls but no clocks:  ARCPU, RCPU2, and APBC2.
>>
>> Signed-off-by: Alex Elder <elder@riscstar.com>
>> ---
>>   drivers/clk/spacemit/ccu-k1.c | 106 ++++++++++++++++++++++++++++++++++
>>   1 file changed, 106 insertions(+)
>>
>> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
>> index 17e321c25959a..bf5a3e2048619 100644
>> --- a/drivers/clk/spacemit/ccu-k1.c
>> +++ b/drivers/clk/spacemit/ccu-k1.c
>> @@ -130,6 +130,37 @@
>>   #define APMU_EMAC0_CLK_RES_CTRL		0x3e4
>>   #define APMU_EMAC1_CLK_RES_CTRL		0x3ec
>>   
>> +/* RCPU register offsets */
>> +#define RCPU_SSP0_CLK_RST		0x0028
>> +#define RCPU_I2C0_CLK_RST		0x0030
>> +#define RCPU_UART1_CLK_RST		0x003c
>> +#define RCPU_CAN_CLK_RST		0x0048
>> +#define RCPU_IR_CLK_RST			0x004c
>> +#define RCPU_UART0_CLK_RST		0x00d8
>> +/* XXX Next one is part of the AUD_AUDCLOCK region @ 0xc0882000 */
> this comment looks odd, XXX?

Yeah, I meant to remove that before sending but I forgot.

The downstream code treats this one register as being
part of the RCPU memory region, and extends that region
to be 0x2048 bytes to "fit" it.

The hardware documentation actually defines a different
"RCPU Audio Clock" memory region, and it might be more
correct (though less convenient) to define that as a
distinct region of memory.

What do you think?

					-Alex

>> +#define AUDIO_HDMI_CLK_CTRL		0x2044
>> +
>> +/* RCPU2 register offsets */
>> +#define RCPU2_PWM0_CLK_RST		0x0000
>> +#define RCPU2_PWM1_CLK_RST		0x0004
>> +#define RCPU2_PWM2_CLK_RST		0x0008
>> +#define RCPU2_PWM3_CLK_RST		0x000c
>> +#define RCPU2_PWM4_CLK_RST		0x0010
>> +#define RCPU2_PWM5_CLK_RST		0x0014
>> +#define RCPU2_PWM6_CLK_RST		0x0018
>> +#define RCPU2_PWM7_CLK_RST		0x001c
>> +#define RCPU2_PWM8_CLK_RST		0x0020
>> +#define RCPU2_PWM9_CLK_RST		0x0024
>> +
>> +/* APBC2 register offsets */
>> +#define APBC2_UART1_CLK_RST		0x0000
>> +#define APBC2_SSP2_CLK_RST		0x0004
>> +#define APBC2_TWSI3_CLK_RST		0x0008
>> +#define APBC2_RTC_CLK_RST		0x000c
>> +#define APBC2_TIMERS0_CLK_RST		0x0010
>> +#define APBC2_KPC_CLK_RST		0x0014
>> +#define APBC2_GPIO_CLK_RST		0x001c
>> +
>>   struct spacemit_ccu_clk {
>>   	int id;
>>   	struct clk_hw *hw;
>> @@ -1781,6 +1812,69 @@ static const struct k1_ccu_data k1_ccu_apmu_data = {
>>   	.rst_data	= &apmu_reset_controller_data,
>>   };
>>   
>> +static const struct ccu_reset_data rcpu_reset_data[] = {
>> +	[RST_RCPU_SSP0]		= RST_DATA(RCPU_SSP0_CLK_RST,	0, BIT(0)),
>> +	[RST_RCPU_I2C0]		= RST_DATA(RCPU_I2C0_CLK_RST,	0, BIT(0)),
>> +	[RST_RCPU_UART1]	= RST_DATA(RCPU_UART1_CLK_RST,	0, BIT(0)),
>> +	[RST_RCPU_IR]		= RST_DATA(RCPU_CAN_CLK_RST,	0, BIT(0)),
>> +	[RST_RCPU_CAN]		= RST_DATA(RCPU_IR_CLK_RST,	0, BIT(0)),
>> +	[RST_RCPU_UART0]	= RST_DATA(RCPU_UART0_CLK_RST,	0, BIT(0)),
>> +	[RST_RCPU_HDMI_AUDIO]	= RST_DATA(AUDIO_HDMI_CLK_CTRL,	0, BIT(0)),
>> +};
>> +
>> +static const struct ccu_reset_controller_data rcpu_reset_controller_data = {
>> +	.count		= ARRAY_SIZE(rcpu_reset_data),
>> +	.data		= rcpu_reset_data,
>> +};
>> +
>> +static struct k1_ccu_data k1_ccu_rcpu_data = {
>> +	/* No clocks in the RCPU CCU */
>> +	.rst_data	= &rcpu_reset_controller_data,
>> +};
>> +
>> +static const struct ccu_reset_data rcpu2_reset_data[] = {
>> +	[RST_RCPU2_PWM0]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>> +	[RST_RCPU2_PWM1]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>> +	[RST_RCPU2_PWM2]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>> +	[RST_RCPU2_PWM3]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>> +	[RST_RCPU2_PWM4]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>> +	[RST_RCPU2_PWM5]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>> +	[RST_RCPU2_PWM6]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>> +	[RST_RCPU2_PWM7]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>> +	[RST_RCPU2_PWM8]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>> +	[RST_RCPU2_PWM9]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>> +};
>> +
>> +static const struct ccu_reset_controller_data rcpu2_reset_controller_data = {
>> +	.count		= ARRAY_SIZE(rcpu2_reset_data),
>> +	.data		= rcpu2_reset_data,
>> +};
>> +
>> +static struct k1_ccu_data k1_ccu_rcpu2_data = {
>> +	/* No clocks in the RCPU2 CCU */
>> +	.rst_data	= &rcpu2_reset_controller_data,
>> +};
>> +
>> +static const struct ccu_reset_data apbc2_reset_data[] = {
>> +	[RST_APBC2_UART1]	= RST_DATA(APBC2_UART1_CLK_RST,	BIT(2), (0)),
>> +	[RST_APBC2_SSP2]	= RST_DATA(APBC2_SSP2_CLK_RST,	BIT(2), (0)),
>> +	[RST_APBC2_TWSI3]	= RST_DATA(APBC2_TWSI3_CLK_RST,	BIT(2), (0)),
>> +	[RST_APBC2_RTC]		= RST_DATA(APBC2_RTC_CLK_RST,	BIT(2), (0)),
>> +	[RST_APBC2_TIMERS0]	= RST_DATA(APBC2_TIMERS0_CLK_RST, BIT(2), (0)),
>> +	[RST_APBC2_KPC]		= RST_DATA(APBC2_KPC_CLK_RST,	BIT(2), (0)),
>> +	[RST_APBC2_GPIO]	= RST_DATA(APBC2_GPIO_CLK_RST,	BIT(2), (0)),
>> +};
>> +
>> +static const struct ccu_reset_controller_data apbc2_reset_controller_data = {
>> +	.count		= ARRAY_SIZE(apbc2_reset_data),
>> +	.data		= apbc2_reset_data,
>> +};
>> +
>> +static struct k1_ccu_data k1_ccu_apbc2_data = {
>> +	/* No clocks in the RCPU2 CCU */
>> +	.rst_data	= &apbc2_reset_controller_data,
>> +};
>> +
>>   static struct ccu_reset_controller *
>>   rcdev_to_controller(struct reset_controller_dev *rcdev)
>>   {
>> @@ -1959,6 +2053,18 @@ static const struct of_device_id of_k1_ccu_match[] = {
>>   		.compatible	= "spacemit,k1-syscon-apmu",
>>   		.data		= &k1_ccu_apmu_data,
>>   	},
>> +	{
>> +		.compatible	= "spacemit,k1-syscon-rcpu",
>> +		.data		= &k1_ccu_rcpu_data,
>> +	},
>> +	{
>> +		.compatible	= "spacemit,k1-syscon-rcpu2",
>> +		.data		= &k1_ccu_rcpu2_data,
>> +	},
>> +	{
>> +		.compatible	= "spacemit,k1-syscon-apbc2",
>> +		.data		= &k1_ccu_apbc2_data,
>> +	},
>>   	{ }
>>   };
>>   MODULE_DEVICE_TABLE(of, of_k1_ccu_match);
>> -- 
>> 2.43.0
>>
> 


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

* Re: [PATCH RESEND 7/7] riscv: dts: spacemit: add reset support for the K1 SoC
  2025-03-22 16:48   ` Yixun Lan
@ 2025-03-23 13:23     ` Alex Elder
  2025-03-24  6:06       ` Yixun Lan
  0 siblings, 1 reply; 34+ messages in thread
From: Alex Elder @ 2025-03-23 13:23 UTC (permalink / raw)
  To: Yixun Lan
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

On 3/22/25 11:48 AM, Yixun Lan wrote:
> On 10:18 Fri 21 Mar     , Alex Elder wrote:
>> Define syscon nodes for the RCPU, RCPU2, and APBC2 SpacemiT CCUS, which
>> currently support resets but not clocks in the SpacemiT K1.
>>
>> Signed-off-by: Alex Elder <elder@riscstar.com>
>> ---
>>   arch/riscv/boot/dts/spacemit/k1.dtsi | 18 ++++++++++++++++++
>>   1 file changed, 18 insertions(+)
>>
>> diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi
>> index 09a9100986b19..f86d1b58c6d35 100644
>> --- a/arch/riscv/boot/dts/spacemit/k1.dtsi
>> +++ b/arch/riscv/boot/dts/spacemit/k1.dtsi
>> @@ -350,6 +350,18 @@ soc {
>>   		dma-noncoherent;
>>   		ranges;
>>   
>> +		syscon_rcpu: system-controller@c0880000 {
> I'm not sure if syscon_rcpu is good name to go, it's AUDIO Peripherals
> in docs, see
> 
> 7.2 Main CPU Domain Address Mapping
> https://developer.spacemit.com/documentation?token=LzJyw97BCipK1dkUygrcbT0NnMg

They call it "AUD_MCUSYSCTRL section <RCPU(0xC0880000)>",
where the registers layouts are defined, and the register
names use the "RCPU" prefix by convention.

I guess I could use "AUDIO" instead, but I think it's
"RCPU" is a little better because of the way things in
the region are named.  It's a little like how "pll" is
used for the DT node name for things in the "APBS" region.
I don't really like that, because the connection between
the two isn't very clear.

>> +			compatible = "spacemit,k1-syscon-rcpu";
>> +			reg = <0x0 0xc0880000 0x0 0x2048>;
>> +			#reset-cells = <1>;
>> +		};
>> +
>> +		syscon_rcpu2: system-controller@c0888000 {
> not found this address mapping in above docs link

You're right.  I was following what the downstream code did.
I'll gladly just include this in the main "RCPU" node.

Thank you very much for the review Yixun.

					-Alex

>> +			compatible = "spacemit,k1-syscon-rcpu2";
>> +			reg = <0x0 0xc0888000 0x0 0x28>;
>> +			#reset-cells = <1>;
>> +		};
>> +
>>   		syscon_apbc: system-control@d4015000 {
>>   			compatible = "spacemit,k1-syscon-apbc";
>>   			reg = <0x0 0xd4015000 0x0 0x1000>;
>> @@ -518,6 +530,12 @@ clint: timer@e4000000 {
>>   					      <&cpu7_intc 3>, <&cpu7_intc 7>;
>>   		};
>>   
>> +		syscon_apbc2: system-controller@f0610000 {
>> +			compatible = "spacemit,k1-syscon-apbc2";
>> +			reg = <0x0 0xf0610000 0x0 0x20>;
>> +			#reset-cells = <1>;
>> +		};
>> +
>>   		sec_uart1: serial@f0612000 {
>>   			compatible = "spacemit,k1-uart", "intel,xscale-uart";
>>   			reg = <0x0 0xf0612000 0x0 0x100>;
>> -- 
>> 2.43.0
>>
> 


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

* Re: [PATCH RESEND 2/7] clk: spacemit: define struct k1_ccu_data
  2025-03-23 13:04       ` Yixun Lan
@ 2025-03-23 22:30         ` Alex Elder
  0 siblings, 0 replies; 34+ messages in thread
From: Alex Elder @ 2025-03-23 22:30 UTC (permalink / raw)
  To: Yixun Lan
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

On 3/23/25 8:04 AM, Yixun Lan wrote:
> On 07:43 Sun 23 Mar     , Alex Elder wrote:
>> On 3/22/25 10:50 AM, Yixun Lan wrote:
>>> Hi Alex:
>>>
>>> this patch change relate to clock only, so how about let's fold
>>> it into clk patches (which now has not been merged), so we make
>>> the code right at first place? cause some moving around and renaming
>>
>> No I don't want to do that.
>>
>> The clock patches are Haylen's and the are getting closer to
>> acceptance.  Let's not confuse things by adding a bunch of new
>> functionality.  Get those patches in, and mine can follow not
>> too long after that.
>>
> 
> I only mean patch [2/7], not all patches, as it's still clock related
> but, either way fine by me if you insist

I see.  It would be great for Haylen to implement this, it's a
better way to do it anyway--you can define the number of
elements in the array using ARRAY_SIZE() this way also (rather
than having to count them at runtime).

Haylen is welcome to use my patch as the basis of this, but
if it doesn't get into that code I'll add it.

					-Alex

> 


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

* Re: [PATCH RESEND 7/7] riscv: dts: spacemit: add reset support for the K1 SoC
  2025-03-23 13:23     ` Alex Elder
@ 2025-03-24  6:06       ` Yixun Lan
  0 siblings, 0 replies; 34+ messages in thread
From: Yixun Lan @ 2025-03-24  6:06 UTC (permalink / raw)
  To: Alex Elder
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

Hi Alex:

On 08:23 Sun 23 Mar     , Alex Elder wrote:
> On 3/22/25 11:48 AM, Yixun Lan wrote:
> > On 10:18 Fri 21 Mar     , Alex Elder wrote:
> >> Define syscon nodes for the RCPU, RCPU2, and APBC2 SpacemiT CCUS, which
> >> currently support resets but not clocks in the SpacemiT K1.
> >>
> >> Signed-off-by: Alex Elder <elder@riscstar.com>
> >> ---
> >>   arch/riscv/boot/dts/spacemit/k1.dtsi | 18 ++++++++++++++++++
> >>   1 file changed, 18 insertions(+)
> >>
> >> diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi
> >> index 09a9100986b19..f86d1b58c6d35 100644
> >> --- a/arch/riscv/boot/dts/spacemit/k1.dtsi
> >> +++ b/arch/riscv/boot/dts/spacemit/k1.dtsi
> >> @@ -350,6 +350,18 @@ soc {
> >>   		dma-noncoherent;
> >>   		ranges;
> >>   
> >> +		syscon_rcpu: system-controller@c0880000 {
> > I'm not sure if syscon_rcpu is good name to go, it's AUDIO Peripherals
> > in docs, see
> > 
> > 7.2 Main CPU Domain Address Mapping
> > https://developer.spacemit.com/documentation?token=LzJyw97BCipK1dkUygrcbT0NnMg
> 
> They call it "AUD_MCUSYSCTRL section <RCPU(0xC0880000)>",
> where the registers layouts are defined, and the register
> names use the "RCPU" prefix by convention.
> 
> I guess I could use "AUDIO" instead, but I think it's
> "RCPU" is a little better because of the way things in
> the region are named.  It's a little like how "pll" is
> used for the DT node name for things in the "APBS" region.
> I don't really like that, because the connection between
> the two isn't very clear.
> 
ok, by whatever you choose, I'd be fine
in case you go with RCPU, can you put a comment above? explain
there is slightly a devergence with docs from SpacemiT's web

also I noticed the io size you written here is smaller than described in
docs which I think usually it's fine (docs may give larger number - 0x80000)
just make sure you checked? so all real io region will be covered, same
for rcpu2

> >> +			compatible = "spacemit,k1-syscon-rcpu";
> >> +			reg = <0x0 0xc0880000 0x0 0x2048>;
> >> +			#reset-cells = <1>;
> >> +		};
> >> +
> >> +		syscon_rcpu2: system-controller@c0888000 {
> > not found this address mapping in above docs link
> 
> You're right.  I was following what the downstream code did.
> I'll gladly just include this in the main "RCPU" node.
> 
> Thank you very much for the review Yixun.
> 
> 					-Alex
> 
> >> +			compatible = "spacemit,k1-syscon-rcpu2";
> >> +			reg = <0x0 0xc0888000 0x0 0x28>;
> >> +			#reset-cells = <1>;
> >> +		};
> >> +
> >>   		syscon_apbc: system-control@d4015000 {
> >>   			compatible = "spacemit,k1-syscon-apbc";
> >>   			reg = <0x0 0xd4015000 0x0 0x1000>;
> >> @@ -518,6 +530,12 @@ clint: timer@e4000000 {
> >>   					      <&cpu7_intc 3>, <&cpu7_intc 7>;
> >>   		};
> >>   
> >> +		syscon_apbc2: system-controller@f0610000 {
> >> +			compatible = "spacemit,k1-syscon-apbc2";
> >> +			reg = <0x0 0xf0610000 0x0 0x20>;
> >> +			#reset-cells = <1>;
> >> +		};
> >> +
> >>   		sec_uart1: serial@f0612000 {
> >>   			compatible = "spacemit,k1-uart", "intel,xscale-uart";
> >>   			reg = <0x0 0xf0612000 0x0 0x100>;
> >> -- 
> >> 2.43.0
> >>
> > 
> 
> 

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55

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

* Re: [PATCH RESEND 6/7] clk: spacemit: define new syscons with only resets
  2025-03-23 13:23     ` Alex Elder
@ 2025-03-24  6:21       ` Yixun Lan
  2025-03-28 17:24         ` Alex Elder
  0 siblings, 1 reply; 34+ messages in thread
From: Yixun Lan @ 2025-03-24  6:21 UTC (permalink / raw)
  To: Alex Elder
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	paul.walmsley, palmer, aou, spacemit, devicetree, linux-clk,
	linux-riscv, linux-kernel

Hi Alex:

On 08:23 Sun 23 Mar     , Alex Elder wrote:
> On 3/22/25 11:42 AM, Yixun Lan wrote:
> > Hi Alex:
> > 
> > It occur to me it's a little odd to implemnt reset driver
> > for RCPU block, but after check with vendor the RCPU region can
> > be accessed both by ACPU and RCPU, then I'm fine with this.
> 
> I implemented just the resets that were found in the downstream
> code.
> 
> I first implemented a separate reset driver, very simple, which
> only implemented the resets.  I had a separate DTS binding (like
> was done for the PLLs).  I was ready to post it for review, then
> noticed that the registers used were shared with clocks.  So I
> merged all of that separate code into the clock driver, as you
> see here.
> 
ok

> > ACPU - RISC-V Main CPU, with mmu, running Linux
> > RCPU - real time CPU, without mmu, running RT-OS
> 
> I didn't realize there was a separate CPU running its
> own OS.  Is this managed as a remoteproc by the RISC-V AP?
> The reset signals, I hope, are only touched by the AP
> and not the real-time CPU.  Can you provide any further
> information about this?
> 
As far as I know, the RCPU region can be acccesed via AP and real-time CPU
from hardware perspective, there is no guarantee of isolation,
so maybe software should take care of this in case only one side can touch

for remoteproc, I haven't checked, and it's unrelated to this discussion
(doesn't change shared resource fact whether remoteproc supported or not)

> > On 10:18 Fri 21 Mar     , Alex Elder wrote:
> >> Enable support for three additional syscon CCUs which support reset
> >> controls but no clocks:  ARCPU, RCPU2, and APBC2.
> >>
> >> Signed-off-by: Alex Elder <elder@riscstar.com>
> >> ---
> >>   drivers/clk/spacemit/ccu-k1.c | 106 ++++++++++++++++++++++++++++++++++
> >>   1 file changed, 106 insertions(+)
> >>
> >> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
> >> index 17e321c25959a..bf5a3e2048619 100644
> >> --- a/drivers/clk/spacemit/ccu-k1.c
> >> +++ b/drivers/clk/spacemit/ccu-k1.c
> >> @@ -130,6 +130,37 @@
> >>   #define APMU_EMAC0_CLK_RES_CTRL		0x3e4
> >>   #define APMU_EMAC1_CLK_RES_CTRL		0x3ec
> >>   
> >> +/* RCPU register offsets */
> >> +#define RCPU_SSP0_CLK_RST		0x0028
> >> +#define RCPU_I2C0_CLK_RST		0x0030
> >> +#define RCPU_UART1_CLK_RST		0x003c
> >> +#define RCPU_CAN_CLK_RST		0x0048
> >> +#define RCPU_IR_CLK_RST			0x004c
> >> +#define RCPU_UART0_CLK_RST		0x00d8
> >> +/* XXX Next one is part of the AUD_AUDCLOCK region @ 0xc0882000 */
> > this comment looks odd, XXX?
> 
> Yeah, I meant to remove that before sending but I forgot.
> 
> The downstream code treats this one register as being
> part of the RCPU memory region, and extends that region
> to be 0x2048 bytes to "fit" it.
> 
> The hardware documentation actually defines a different
> "RCPU Audio Clock" memory region, and it might be more
> correct (though less convenient) to define that as a
> distinct region of memory.
> 
> What do you think?
> 
I'm not sure, but from DT perspective, is it an independent device?
if yes, then need to describe as a distinct region..
> 					-Alex
> 
> >> +#define AUDIO_HDMI_CLK_CTRL		0x2044
> >> +
> >> +/* RCPU2 register offsets */
> >> +#define RCPU2_PWM0_CLK_RST		0x0000
> >> +#define RCPU2_PWM1_CLK_RST		0x0004
> >> +#define RCPU2_PWM2_CLK_RST		0x0008
> >> +#define RCPU2_PWM3_CLK_RST		0x000c
> >> +#define RCPU2_PWM4_CLK_RST		0x0010
> >> +#define RCPU2_PWM5_CLK_RST		0x0014
> >> +#define RCPU2_PWM6_CLK_RST		0x0018
> >> +#define RCPU2_PWM7_CLK_RST		0x001c
> >> +#define RCPU2_PWM8_CLK_RST		0x0020
> >> +#define RCPU2_PWM9_CLK_RST		0x0024
> >> +
> >> +/* APBC2 register offsets */
> >> +#define APBC2_UART1_CLK_RST		0x0000
> >> +#define APBC2_SSP2_CLK_RST		0x0004
> >> +#define APBC2_TWSI3_CLK_RST		0x0008
> >> +#define APBC2_RTC_CLK_RST		0x000c
> >> +#define APBC2_TIMERS0_CLK_RST		0x0010
> >> +#define APBC2_KPC_CLK_RST		0x0014
> >> +#define APBC2_GPIO_CLK_RST		0x001c
> >> +
> >>   struct spacemit_ccu_clk {
> >>   	int id;
> >>   	struct clk_hw *hw;
> >> @@ -1781,6 +1812,69 @@ static const struct k1_ccu_data k1_ccu_apmu_data = {
> >>   	.rst_data	= &apmu_reset_controller_data,
> >>   };
> >>   
> >> +static const struct ccu_reset_data rcpu_reset_data[] = {
> >> +	[RST_RCPU_SSP0]		= RST_DATA(RCPU_SSP0_CLK_RST,	0, BIT(0)),
> >> +	[RST_RCPU_I2C0]		= RST_DATA(RCPU_I2C0_CLK_RST,	0, BIT(0)),
> >> +	[RST_RCPU_UART1]	= RST_DATA(RCPU_UART1_CLK_RST,	0, BIT(0)),
> >> +	[RST_RCPU_IR]		= RST_DATA(RCPU_CAN_CLK_RST,	0, BIT(0)),
> >> +	[RST_RCPU_CAN]		= RST_DATA(RCPU_IR_CLK_RST,	0, BIT(0)),
> >> +	[RST_RCPU_UART0]	= RST_DATA(RCPU_UART0_CLK_RST,	0, BIT(0)),
> >> +	[RST_RCPU_HDMI_AUDIO]	= RST_DATA(AUDIO_HDMI_CLK_CTRL,	0, BIT(0)),
> >> +};
> >> +
> >> +static const struct ccu_reset_controller_data rcpu_reset_controller_data = {
> >> +	.count		= ARRAY_SIZE(rcpu_reset_data),
> >> +	.data		= rcpu_reset_data,
> >> +};
> >> +
> >> +static struct k1_ccu_data k1_ccu_rcpu_data = {
> >> +	/* No clocks in the RCPU CCU */
> >> +	.rst_data	= &rcpu_reset_controller_data,
> >> +};
> >> +
> >> +static const struct ccu_reset_data rcpu2_reset_data[] = {
> >> +	[RST_RCPU2_PWM0]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> >> +	[RST_RCPU2_PWM1]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> >> +	[RST_RCPU2_PWM2]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> >> +	[RST_RCPU2_PWM3]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> >> +	[RST_RCPU2_PWM4]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> >> +	[RST_RCPU2_PWM5]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> >> +	[RST_RCPU2_PWM6]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> >> +	[RST_RCPU2_PWM7]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> >> +	[RST_RCPU2_PWM8]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> >> +	[RST_RCPU2_PWM9]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
> >> +};
> >> +
> >> +static const struct ccu_reset_controller_data rcpu2_reset_controller_data = {
> >> +	.count		= ARRAY_SIZE(rcpu2_reset_data),
> >> +	.data		= rcpu2_reset_data,
> >> +};
> >> +
> >> +static struct k1_ccu_data k1_ccu_rcpu2_data = {
> >> +	/* No clocks in the RCPU2 CCU */
> >> +	.rst_data	= &rcpu2_reset_controller_data,
> >> +};
> >> +
> >> +static const struct ccu_reset_data apbc2_reset_data[] = {
> >> +	[RST_APBC2_UART1]	= RST_DATA(APBC2_UART1_CLK_RST,	BIT(2), (0)),
> >> +	[RST_APBC2_SSP2]	= RST_DATA(APBC2_SSP2_CLK_RST,	BIT(2), (0)),
> >> +	[RST_APBC2_TWSI3]	= RST_DATA(APBC2_TWSI3_CLK_RST,	BIT(2), (0)),
> >> +	[RST_APBC2_RTC]		= RST_DATA(APBC2_RTC_CLK_RST,	BIT(2), (0)),
> >> +	[RST_APBC2_TIMERS0]	= RST_DATA(APBC2_TIMERS0_CLK_RST, BIT(2), (0)),
> >> +	[RST_APBC2_KPC]		= RST_DATA(APBC2_KPC_CLK_RST,	BIT(2), (0)),
> >> +	[RST_APBC2_GPIO]	= RST_DATA(APBC2_GPIO_CLK_RST,	BIT(2), (0)),
> >> +};
> >> +
> >> +static const struct ccu_reset_controller_data apbc2_reset_controller_data = {
> >> +	.count		= ARRAY_SIZE(apbc2_reset_data),
> >> +	.data		= apbc2_reset_data,
> >> +};
> >> +
> >> +static struct k1_ccu_data k1_ccu_apbc2_data = {
> >> +	/* No clocks in the RCPU2 CCU */
> >> +	.rst_data	= &apbc2_reset_controller_data,
> >> +};
> >> +
> >>   static struct ccu_reset_controller *
> >>   rcdev_to_controller(struct reset_controller_dev *rcdev)
> >>   {
> >> @@ -1959,6 +2053,18 @@ static const struct of_device_id of_k1_ccu_match[] = {
> >>   		.compatible	= "spacemit,k1-syscon-apmu",
> >>   		.data		= &k1_ccu_apmu_data,
> >>   	},
> >> +	{
> >> +		.compatible	= "spacemit,k1-syscon-rcpu",
> >> +		.data		= &k1_ccu_rcpu_data,
> >> +	},
> >> +	{
> >> +		.compatible	= "spacemit,k1-syscon-rcpu2",
> >> +		.data		= &k1_ccu_rcpu2_data,
> >> +	},
> >> +	{
> >> +		.compatible	= "spacemit,k1-syscon-apbc2",
> >> +		.data		= &k1_ccu_apbc2_data,
> >> +	},
> >>   	{ }
> >>   };
> >>   MODULE_DEVICE_TABLE(of, of_k1_ccu_match);
> >> -- 
> >> 2.43.0
> >>
> > 
> 

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55

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

* Re: [PATCH RESEND 4/7] clk: spacemit: define existing syscon resets
  2025-03-23 13:23     ` Alex Elder
@ 2025-03-24  6:24       ` Yixun Lan
  0 siblings, 0 replies; 34+ messages in thread
From: Yixun Lan @ 2025-03-24  6:24 UTC (permalink / raw)
  To: Alex Elder
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

Hi Alex:

On 08:23 Sun 23 Mar     , Alex Elder wrote:
> On 3/22/25 11:29 AM, Yixun Lan wrote:
> > On 10:18 Fri 21 Mar     , Alex Elder wrote:
> >> Define reset controls associated with the MPMU, APBC, and APMU
> >> SpacemiT K1 CCUs.  These already have clocks associated with them.
> >>
> >> Signed-off-by: Alex Elder <elder@riscstar.com>
> >> ---
> >>   drivers/clk/spacemit/ccu-k1.c | 132 ++++++++++++++++++++++++++++++++++
> >>   1 file changed, 132 insertions(+)
> >>
> >> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
> >> index 6d879411c6c05..be8abd27753cb 100644
> >> --- a/drivers/clk/spacemit/ccu-k1.c
> >> +++ b/drivers/clk/spacemit/ccu-k1.c
> > ..
> >> +static const struct ccu_reset_data apmu_reset_data[] = {
> >> +	[RST_CCIC_4X]	= RST_DATA(APMU_CCIC_CLK_RES_CTRL,	0, BIT(1)),
> >> +	[RST_CCIC1_PHY] = RST_DATA(APMU_CCIC_CLK_RES_CTRL,	0, BIT(2)),
> >> +	[RST_SDH_AXI]	= RST_DATA(APMU_SDH0_CLK_RES_CTRL,	0, BIT(0)),
> >> +	[RST_SDH0]	= RST_DATA(APMU_SDH0_CLK_RES_CTRL,	0, BIT(1)),
> >> +	[RST_SDH1]	= RST_DATA(APMU_SDH1_CLK_RES_CTRL,	0, BIT(1)),
> >> +	[RST_SDH2]	= RST_DATA(APMU_SDH2_CLK_RES_CTRL,	0, BIT(1)),
> >> +	[RST_USBP1_AXI] = RST_DATA(APMU_USB_CLK_RES_CTRL,	0, BIT(4)),
> >> +	[RST_USB_AXI]	= RST_DATA(APMU_USB_CLK_RES_CTRL,	0, BIT(0)),
> > ..
> >> +	[RST_USB3_0]	= RST_DATA(APMU_USB_CLK_RES_CTRL,	0,
> >> +				      BIT(9)|BIT(10)|BIT(11)),
> > 100 column if possible, also add one space between "BIT(9) | BIT(10) .."
> > continuous bits can just use GENMASK for short?
> 
> You'll notice that every place that has multiple bits in the mask
> also have a line break.  I kind of liked that as a way to highlight
> that fact (i.e., it goes beyond my preference for 80 columns).
> 
ok

> I will definitely add spaces, that was a mistake not to.
> 
> I will not define this with GENMASK().  In this case each bit
> represents a single reset, and so each one is significant on
> its own.  It is *not* a mask of contiguous bits, it's a set
> of bits that happen to have consecutive positions.
> 
ok

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55

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

* Re: [PATCH RESEND 3/7] clk: spacemit: add reset controller support
  2025-03-23 13:23     ` Alex Elder
@ 2025-03-24  6:40       ` Yixun Lan
  0 siblings, 0 replies; 34+ messages in thread
From: Yixun Lan @ 2025-03-24  6:40 UTC (permalink / raw)
  To: Alex Elder
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

Hi Alex:

On 08:23 Sun 23 Mar     , Alex Elder wrote:
> On 3/22/25 11:19 AM, Yixun Lan wrote:
> > Hi Alex:
> > 
> > On 10:18 Fri 21 Mar     , Alex Elder wrote:
> >> Define ccu_reset_data as a structure that contains the constant
> >> register offset and bitmasks used to assert and deassert a reset
> >> control on a SpacemiT K1 CCU. Define ccu_reset_controller_data as
> >> a structure that contains the address of an array of those structures
> >> and a count of the number of elements in the array.
> >>
> >> Add a pointer to a ccu_reset_controller_data structure to the
> >> k1_ccu_data structure.  Reset support is optional for SpacemiT CCUs;
> >> the new pointer field will be null for CCUs without any resets.
> >>
> >> Finally, define a new ccu_reset_controller structure, which (for
> >> a CCU with resets) contains a pointer to the constant reset data,
> >> the regmap to be used for the controller, and an embedded a reset
> >> controller structure.
> >>
> >> Each reset control is asserted or deasserted by updating bits in
> >> a register.  The bits used are defined by an assert mask and a
> >> deassert mask.  In some cases, one (non-zero) mask asserts reset
> >> and a different (non-zero) mask deasserts it.  Otherwise one mask
> >> is nonzero, and the other is zero.  Either way, the bits in
> >> both masks are cleared, then either the assert mask or the deassert
> >> mask is set in a register to affect the state of a reset control.
> >>
> >> Signed-off-by: Alex Elder <elder@riscstar.com>
> >> ---
> >>   drivers/clk/spacemit/ccu-k1.c | 93 +++++++++++++++++++++++++++++++++++
> >>   1 file changed, 93 insertions(+)
> >>
> >> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
> >> index f7367271396a0..6d879411c6c05 100644
> >> --- a/drivers/clk/spacemit/ccu-k1.c
> >> +++ b/drivers/clk/spacemit/ccu-k1.c
> >> @@ -10,6 +10,7 @@
> >>   #include <linux/minmax.h>
> >>   #include <linux/module.h>
> >>   #include <linux/platform_device.h>
> >> +#include <linux/reset-controller.h>
> >>   
> >>   #include "ccu_common.h"
> >>   #include "ccu_pll.h"
> >> @@ -134,8 +135,26 @@ struct spacemit_ccu_clk {
> >>   	struct clk_hw *hw;
> >>   };
> >>   
> >> +struct ccu_reset_data {
> >> +	u32 offset;
> >> +	u32 assert_mask;
> >> +	u32 deassert_mask;
> >> +};
> >> +
> >> +struct ccu_reset_controller_data {
> >> +	u32 count;
> >> +	const struct ccu_reset_data *data;	/* array */
> >> +};
> >> +
> >>   struct k1_ccu_data {
> >>   	struct spacemit_ccu_clk *clk;		/* array with sentinel */
> >> +	const struct ccu_reset_controller_data *rst_data;
> >> +};
> >> +
> >> +struct ccu_reset_controller {
> >> +	struct regmap *regmap;
> >> +	const struct ccu_reset_controller_data *data;
> >> +	struct reset_controller_dev rcdev;
> >>   };
> >>   
> >>   /*	APBS clocks start	*/
> >> @@ -1630,6 +1649,48 @@ static const struct k1_ccu_data k1_ccu_apmu_data = {
> >>   	.clk		= k1_ccu_apmu_clks,
> >>   };
> >>   
> >> +static struct ccu_reset_controller *
> >> +rcdev_to_controller(struct reset_controller_dev *rcdev)
> > I'd suggest to avoid the line break to make it slightly more readable, intuitive
> > as the 80 column limit isn't hard rule
> > 
> > there are maybe more place similar to this, I won't add more comments
> > https://github.com/torvalds/linux/commit/bdc48fa11e46f867ea4d75fa59ee87a7f48be144
> 
> I disagree with this suggestion.  I personally find this
> more readable.  As the first line of the patch you link to,
> "80 columns is still preferred".  And regardless, it is my
> (strong) preference to work within 80 columns in almost all
> cases.
> 

I can understand this isn't *hard* rule, and even subsystem maintainer
may has their own preference, but for contributing SpacemiT, 
I'd hope we could reach certain consensus, so will have sorts of consistent
coding style, I've been requested several times to extend to 100
columns (see link below), and I do agree it will end at less lines which
makes the code more readable..

https://lore.kernel.org/all/20250302-04-gpio-irq-threecell-v2-1-34f13ad37ea4@gentoo.org
> >> +{
> >> +	return container_of(rcdev, struct ccu_reset_controller, rcdev);
> >> +}
> > since this function is only used once, open-code it?
> > but I'd fine with either way if you prefer to keep it
> 
> The "to_<containing_type>()" function pattern is extremely
> common, but I like this suggestion, given it's used only
> once.  I'll implement it in v2.
> 
> > 
> >> +
> >> +static int
> >> +k1_rst_update(struct reset_controller_dev *rcdev, unsigned long id, bool assert)
> > s/k1_rst_update/k1_reset_update/g
> > this is a taste change, but I found more people follow this when grep driver/reset
> 
> I actually had reset (not rst) before, throughout.  But it made
> a few lines too long, leading to line wraps, so I did this.
> 
> In addition, there was a sort of consistency with the use of
> "clk" instead of "clock", though I do recognize that abbreviation
> goes way back to when Mike implemented the common clock framework.
> 
> I'll switch back to "reset" (and "RESET") in names, but be warned
> I'll add some line breaks to fit within 80 columns.
> 
> >> +{
> >> +	struct ccu_reset_controller *controller = rcdev_to_controller(rcdev);
> >> +	struct regmap *regmap = controller->regmap;
> >> +	const struct ccu_reset_data *data;
> >> +	u32 val;
> >> +	int ret;
> >> +
> >> +	data = &controller->data->data[id];
> >> +
> >> +	ret = regmap_read(regmap, data->offset, &val);
> >> +	if (ret)
> >> +		return ret;
> >> +
> >> +	val &= ~(data->assert_mask | data->deassert_mask);
> >> +	val |= assert ? data->assert_mask : data->deassert_mask;
> >> +
> >> +	return regmap_write(regmap, data->offset, val);
> >> +}
> >> +
> >> +static int k1_rst_assert(struct reset_controller_dev *rcdev, unsigned long id)
> > same reason, rst -> reset, more below
> >> +{
> >> +	return k1_rst_update(rcdev, id, true);
> >> +}
> >> +
> >> +static int k1_rst_deassert(struct reset_controller_dev *rcdev, unsigned long id)
> >> +{
> >> +	return k1_rst_update(rcdev, id, false);
> >> +}
> >> +
> >> +static const struct reset_control_ops k1_reset_control_ops = {
> >> +	.assert		= k1_rst_assert,
> >> +	.deassert	= k1_rst_deassert,
> >> +};
> >> +
> >>   static int k1_ccu_register(struct device *dev, struct regmap *regmap,
> >>   			   struct regmap *lock_regmap,
> >>   			   struct spacemit_ccu_clk *clks)
> >> @@ -1675,6 +1736,33 @@ static int k1_ccu_register(struct device *dev, struct regmap *regmap,
> >>   	return ret;
> >>   }
> >>   
> >> +static int
> >> +k1_reset_controller_register(struct device *dev, struct regmap *regmap,
> >> +			     const struct ccu_reset_controller_data *data)
> >> +{
> >> +	struct ccu_reset_controller *controller;
> >> +	struct reset_controller_dev *rcdev;
> >> +
> >> +	/* Resets are optional */
> >> +	if (!data)
> >> +		return 0;
> >> +
> >> +	controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL);
> >> +	if (!controller)
> >> +		return -ENOMEM;
> >> +
> >> +	controller->regmap = regmap;
> >> +	controller->data = data;
> >> +
> >> +	rcdev = &controller->rcdev;
> > ..
> >> +	rcdev->owner = THIS_MODULE;
> > move to last?
> 
> You mean move nr_resets to last?  I'll do that.  I'll
> order the assignments in the order they're defined in
> "reset-controller.h".
> 
I mean after rcdev->of_node, suggested based on alphabet letter,
but I do see people group them based on functionality..
so whatever you decide, fine by me

> >> +	rcdev->nr_resets = data->count;
> >> +	rcdev->ops = &k1_reset_control_ops;
> >> +	rcdev->of_node = dev->of_node;
> >> +
> >> +	return devm_reset_controller_register(dev, rcdev);
> >> +}
> >> +
> >>   static int k1_ccu_probe(struct platform_device *pdev)
> >>   {
> >>   	struct regmap *base_regmap, *lock_regmap = NULL;
> >> @@ -1710,6 +1798,11 @@ static int k1_ccu_probe(struct platform_device *pdev)
> >>   	if (ret)
> >>   		return dev_err_probe(dev, ret, "failed to register clocks\n");
> >>   
> >> +	ret = k1_reset_controller_register(dev, base_regmap, data->rst_data);
> > ..
> >> +	if (ret)
> >> +		return dev_err_probe(dev, ret,
> >> +				     "failed to register reset controller\n");
> > same 100 column reason
> 
> This one I might go beyond columns, because it's only a few characters.
> 
yes, we have rules not to break strings, but sometimes, I found even
better when not breaking the whole line (better to do grep)
 
thanks for your work!

-- 
Yixun Lan (dlan)
Gentoo Linux Developer
GPG Key ID AABEFD55

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

* Re: [PATCH RESEND 2/7] clk: spacemit: define struct k1_ccu_data
  2025-03-21 15:18 ` [PATCH RESEND 2/7] clk: spacemit: define struct k1_ccu_data Alex Elder
  2025-03-22 15:50   ` Yixun Lan
@ 2025-03-24 11:53   ` Haylen Chu
  2025-03-24 12:17     ` Alex Elder
  1 sibling, 1 reply; 34+ messages in thread
From: Haylen Chu @ 2025-03-24 11:53 UTC (permalink / raw)
  To: Alex Elder, p.zabel, mturquette, sboyd, dlan
  Cc: robh, krzk+dt, conor+dt, guodong, paul.walmsley, palmer, aou,
	spacemit, devicetree, linux-clk, linux-riscv, linux-kernel

On Fri, Mar 21, 2025 at 10:18:25AM -0500, Alex Elder wrote:
> Define a new structure type to be used for describing the OF match data.
> Rather than using the array of spacemit_ccu_clk structures for match
> data, we use this structure instead.
> 
> Move the definition of the spacemit_ccu_clk structure closer to the top
> of the source file, and add the new structure definition below it.
> 
> Shorten the name of spacemit_ccu_register() to be k1_ccu_register().

I've read your conversation about moving parts of the patch into the
clock series, I'm of course willing to :)

> Signed-off-by: Alex Elder <elder@riscstar.com>
> ---
>  drivers/clk/spacemit/ccu-k1.c | 58 ++++++++++++++++++++++++++---------
>  1 file changed, 43 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
> index 44db48ae71313..f7367271396a0 100644
> --- a/drivers/clk/spacemit/ccu-k1.c
> +++ b/drivers/clk/spacemit/ccu-k1.c
> @@ -129,6 +129,15 @@
>  #define APMU_EMAC0_CLK_RES_CTRL		0x3e4
>  #define APMU_EMAC1_CLK_RES_CTRL		0x3ec
>  
> +struct spacemit_ccu_clk {
> +	int id;
> +	struct clk_hw *hw;
> +};
> +
> +struct k1_ccu_data {
> +	struct spacemit_ccu_clk *clk;		/* array with sentinel */
> +};

This is something like what I've dropped in v5 of the clock series so I
doubt whether it should be added back in clock series again, as at that
point there's no reason for an extra structure: Alex, is it okay for you
to keep the change in reset series?

...

> +static int k1_ccu_register(struct device *dev, struct regmap *regmap,
> +			   struct regmap *lock_regmap,
> +			   struct spacemit_ccu_clk *clks)
>  {
>  	const struct spacemit_ccu_clk *clk;
>  	int i, ret, max_id = 0;
> @@ -1648,15 +1668,24 @@ static int spacemit_ccu_register(struct device *dev,
>  
>  	clk_data->num = max_id + 1;
>  
> -	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
> +	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
> +	if (ret)
> +		dev_err(dev, "error %d adding clock hardware provider\n", ret);

This error message definitely should go in the clock series.

> +	return ret;
>  }

>  static int k1_ccu_probe(struct platform_device *pdev)
>  {
>  	struct regmap *base_regmap, *lock_regmap = NULL;
>  	struct device *dev = &pdev->dev;
> +	const struct k1_ccu_data *data;
>  	int ret;
>  
> +	data = of_device_get_match_data(dev);
> +	if (!data)
> +		return -EINVAL;

Looking through the reset series, I don't see a reason that
of_device_get_match_data() could return NULL. This is also something
you've asked me to drop in v4 of the clock series, so I guess it isn't
necessary.

>  	base_regmap = device_node_to_regmap(dev->of_node);
>  	if (IS_ERR(base_regmap))
>  		return dev_err_probe(dev, PTR_ERR(base_regmap),
> @@ -1677,8 +1706,7 @@ static int k1_ccu_probe(struct platform_device *pdev)
>  					     "failed to get lock regmap\n");
>  	}
>  
> -	ret = spacemit_ccu_register(dev, base_regmap, lock_regmap,
> -				    of_device_get_match_data(dev));
> +	ret = k1_ccu_register(dev, base_regmap, lock_regmap, data->clk);
>  	if (ret)
>  		return dev_err_probe(dev, ret, "failed to register clocks\n");

For using ARRAY_SIZE() to simplify runtime code, it's mostly okay since
binding IDs are continuous 0-based integers. But I split the handling of
TWSI8 into another patch, which creates a hole in the range and breaks
the assumption. Do you think the TWSI8 commit should be merged back in
the clock driver one?

Best regards,
Haylen Chu

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

* Re: [PATCH RESEND 2/7] clk: spacemit: define struct k1_ccu_data
  2025-03-24 11:53   ` Haylen Chu
@ 2025-03-24 12:17     ` Alex Elder
  0 siblings, 0 replies; 34+ messages in thread
From: Alex Elder @ 2025-03-24 12:17 UTC (permalink / raw)
  To: Haylen Chu, p.zabel, mturquette, sboyd, dlan
  Cc: robh, krzk+dt, conor+dt, guodong, paul.walmsley, palmer, aou,
	spacemit, devicetree, linux-clk, linux-riscv, linux-kernel

On 3/24/25 6:53 AM, Haylen Chu wrote:
> On Fri, Mar 21, 2025 at 10:18:25AM -0500, Alex Elder wrote:
>> Define a new structure type to be used for describing the OF match data.
>> Rather than using the array of spacemit_ccu_clk structures for match
>> data, we use this structure instead.
>>
>> Move the definition of the spacemit_ccu_clk structure closer to the top
>> of the source file, and add the new structure definition below it.
>>
>> Shorten the name of spacemit_ccu_register() to be k1_ccu_register().
> 
> I've read your conversation about moving parts of the patch into the
> clock series, I'm of course willing to :)
> 
>> Signed-off-by: Alex Elder <elder@riscstar.com>
>> ---
>>   drivers/clk/spacemit/ccu-k1.c | 58 ++++++++++++++++++++++++++---------
>>   1 file changed, 43 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
>> index 44db48ae71313..f7367271396a0 100644
>> --- a/drivers/clk/spacemit/ccu-k1.c
>> +++ b/drivers/clk/spacemit/ccu-k1.c
>> @@ -129,6 +129,15 @@
>>   #define APMU_EMAC0_CLK_RES_CTRL		0x3e4
>>   #define APMU_EMAC1_CLK_RES_CTRL		0x3ec
>>   
>> +struct spacemit_ccu_clk {
>> +	int id;
>> +	struct clk_hw *hw;
>> +};
>> +
>> +struct k1_ccu_data {
>> +	struct spacemit_ccu_clk *clk;		/* array with sentinel */
>> +};
> 
> This is something like what I've dropped in v5 of the clock series so I
> doubt whether it should be added back in clock series again, as at that
> point there's no reason for an extra structure: Alex, is it okay for you
> to keep the change in reset series?

That's perfectly fine with me.  It's not necessary yet, so it's
just fine for you to do things the way you did, and I'll add this
in as part of the reset series.

> ...
> 
>> +static int k1_ccu_register(struct device *dev, struct regmap *regmap,
>> +			   struct regmap *lock_regmap,
>> +			   struct spacemit_ccu_clk *clks)
>>   {
>>   	const struct spacemit_ccu_clk *clk;
>>   	int i, ret, max_id = 0;
>> @@ -1648,15 +1668,24 @@ static int spacemit_ccu_register(struct device *dev,
>>   
>>   	clk_data->num = max_id + 1;
>>   
>> -	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
>> +	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
>> +	if (ret)
>> +		dev_err(dev, "error %d adding clock hardware provider\n", ret);
> 
> This error message definitely should go in the clock series.
> 
>> +	return ret;
>>   }
> 
>>   static int k1_ccu_probe(struct platform_device *pdev)
>>   {
>>   	struct regmap *base_regmap, *lock_regmap = NULL;
>>   	struct device *dev = &pdev->dev;
>> +	const struct k1_ccu_data *data;
>>   	int ret;
>>   
>> +	data = of_device_get_match_data(dev);
>> +	if (!data)
>> +		return -EINVAL;
> 
> Looking through the reset series, I don't see a reason that
> of_device_get_match_data() could return NULL. This is also something
> you've asked me to drop in v4 of the clock series, so I guess it isn't
> necessary.

You are correct.  I'll drop it.  I contemplated this and thought
it's useful to tell the reader it's necessary to not be null, but
you can tell it has to be by inspection.


>>   	base_regmap = device_node_to_regmap(dev->of_node);
>>   	if (IS_ERR(base_regmap))
>>   		return dev_err_probe(dev, PTR_ERR(base_regmap),
>> @@ -1677,8 +1706,7 @@ static int k1_ccu_probe(struct platform_device *pdev)
>>   					     "failed to get lock regmap\n");
>>   	}
>>   
>> -	ret = spacemit_ccu_register(dev, base_regmap, lock_regmap,
>> -				    of_device_get_match_data(dev));
>> +	ret = k1_ccu_register(dev, base_regmap, lock_regmap, data->clk);
>>   	if (ret)
>>   		return dev_err_probe(dev, ret, "failed to register clocks\n");
> 
> For using ARRAY_SIZE() to simplify runtime code, it's mostly okay since
> binding IDs are continuous 0-based integers. But I split the handling of
> TWSI8 into another patch, which creates a hole in the range and breaks
> the assumption. Do you think the TWSI8 commit should be merged back in
> the clock driver one?

I didn't understand the reason why you separated the TWSI8 into a
separate commit.  Now I know.  The hole in the range doesn't really
matter much; you already initialize your ->hws[] array of pointers
with ERR_PTR(-ENOENT), so any holes are handled properly.

					-Alex
> 
> Best regards,
> Haylen Chu


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

* Re: [PATCH RESEND 3/7] clk: spacemit: add reset controller support
  2025-03-21 15:18 ` [PATCH RESEND 3/7] clk: spacemit: add reset controller support Alex Elder
  2025-03-22 16:19   ` Yixun Lan
@ 2025-03-24 12:20   ` Haylen Chu
  2025-03-24 12:52     ` Alex Elder
  1 sibling, 1 reply; 34+ messages in thread
From: Haylen Chu @ 2025-03-24 12:20 UTC (permalink / raw)
  To: Alex Elder, p.zabel, mturquette, sboyd, dlan
  Cc: robh, krzk+dt, conor+dt, guodong, paul.walmsley, palmer, aou,
	spacemit, devicetree, linux-clk, linux-riscv, linux-kernel

On Fri, Mar 21, 2025 at 10:18:26AM -0500, Alex Elder wrote:
> Define ccu_reset_data as a structure that contains the constant
> register offset and bitmasks used to assert and deassert a reset
> control on a SpacemiT K1 CCU. Define ccu_reset_controller_data as
> a structure that contains the address of an array of those structures
> and a count of the number of elements in the array.
> 
> Add a pointer to a ccu_reset_controller_data structure to the
> k1_ccu_data structure.  Reset support is optional for SpacemiT CCUs;
> the new pointer field will be null for CCUs without any resets.
> 
> Finally, define a new ccu_reset_controller structure, which (for
> a CCU with resets) contains a pointer to the constant reset data,
> the regmap to be used for the controller, and an embedded a reset
> controller structure.
> 
> Each reset control is asserted or deasserted by updating bits in
> a register.  The bits used are defined by an assert mask and a
> deassert mask.  In some cases, one (non-zero) mask asserts reset
> and a different (non-zero) mask deasserts it.  Otherwise one mask
> is nonzero, and the other is zero.  Either way, the bits in
> both masks are cleared, then either the assert mask or the deassert
> mask is set in a register to affect the state of a reset control.
> 
> Signed-off-by: Alex Elder <elder@riscstar.com>
> ---
>  drivers/clk/spacemit/ccu-k1.c | 93 +++++++++++++++++++++++++++++++++++
>  1 file changed, 93 insertions(+)
> 
> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
> index f7367271396a0..6d879411c6c05 100644
> --- a/drivers/clk/spacemit/ccu-k1.c
> +++ b/drivers/clk/spacemit/ccu-k1.c

...

> +static int
> +k1_rst_update(struct reset_controller_dev *rcdev, unsigned long id, bool assert)
> +{
> +	struct ccu_reset_controller *controller = rcdev_to_controller(rcdev);
> +	struct regmap *regmap = controller->regmap;
> +	const struct ccu_reset_data *data;
> +	u32 val;
> +	int ret;
> +
> +	data = &controller->data->data[id];
> +
> +	ret = regmap_read(regmap, data->offset, &val);
> +	if (ret)
> +		return ret;
> +
> +	val &= ~(data->assert_mask | data->deassert_mask);
> +	val |= assert ? data->assert_mask : data->deassert_mask;
> +
> +	return regmap_write(regmap, data->offset, val);
> +}

I don't think it's safe to write the regmap based on a value read
earlier without the regmap's inner lock held: it's totally fine for the
clock part to issue an update of the register at the same time. Without
knowledge on it, reset code may rollback the clock bits written by clock
code earlier to the original value. That's why I keep using ccu_update()
everywhere and dropped ccu_write().

Thanks,
Haylen Chu

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

* Re: [PATCH RESEND 3/7] clk: spacemit: add reset controller support
  2025-03-24 12:20   ` Haylen Chu
@ 2025-03-24 12:52     ` Alex Elder
  0 siblings, 0 replies; 34+ messages in thread
From: Alex Elder @ 2025-03-24 12:52 UTC (permalink / raw)
  To: Haylen Chu, p.zabel, mturquette, sboyd, dlan
  Cc: robh, krzk+dt, conor+dt, guodong, paul.walmsley, palmer, aou,
	spacemit, devicetree, linux-clk, linux-riscv, linux-kernel

On 3/24/25 7:20 AM, Haylen Chu wrote:
> On Fri, Mar 21, 2025 at 10:18:26AM -0500, Alex Elder wrote:
>> Define ccu_reset_data as a structure that contains the constant
>> register offset and bitmasks used to assert and deassert a reset
>> control on a SpacemiT K1 CCU. Define ccu_reset_controller_data as
>> a structure that contains the address of an array of those structures
>> and a count of the number of elements in the array.
>>
>> Add a pointer to a ccu_reset_controller_data structure to the
>> k1_ccu_data structure.  Reset support is optional for SpacemiT CCUs;
>> the new pointer field will be null for CCUs without any resets.
>>
>> Finally, define a new ccu_reset_controller structure, which (for
>> a CCU with resets) contains a pointer to the constant reset data,
>> the regmap to be used for the controller, and an embedded a reset
>> controller structure.
>>
>> Each reset control is asserted or deasserted by updating bits in
>> a register.  The bits used are defined by an assert mask and a
>> deassert mask.  In some cases, one (non-zero) mask asserts reset
>> and a different (non-zero) mask deasserts it.  Otherwise one mask
>> is nonzero, and the other is zero.  Either way, the bits in
>> both masks are cleared, then either the assert mask or the deassert
>> mask is set in a register to affect the state of a reset control.
>>
>> Signed-off-by: Alex Elder <elder@riscstar.com>
>> ---
>>   drivers/clk/spacemit/ccu-k1.c | 93 +++++++++++++++++++++++++++++++++++
>>   1 file changed, 93 insertions(+)
>>
>> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
>> index f7367271396a0..6d879411c6c05 100644
>> --- a/drivers/clk/spacemit/ccu-k1.c
>> +++ b/drivers/clk/spacemit/ccu-k1.c
> 
> ...
> 
>> +static int
>> +k1_rst_update(struct reset_controller_dev *rcdev, unsigned long id, bool assert)
>> +{
>> +	struct ccu_reset_controller *controller = rcdev_to_controller(rcdev);
>> +	struct regmap *regmap = controller->regmap;
>> +	const struct ccu_reset_data *data;
>> +	u32 val;
>> +	int ret;
>> +
>> +	data = &controller->data->data[id];
>> +
>> +	ret = regmap_read(regmap, data->offset, &val);
>> +	if (ret)
>> +		return ret;
>> +
>> +	val &= ~(data->assert_mask | data->deassert_mask);
>> +	val |= assert ? data->assert_mask : data->deassert_mask;
>> +
>> +	return regmap_write(regmap, data->offset, val);
>> +}
> 
> I don't think it's safe to write the regmap based on a value read
> earlier without the regmap's inner lock held: it's totally fine for the
> clock part to issue an update of the register at the same time. Without
> knowledge on it, reset code may rollback the clock bits written by clock
> code earlier to the original value. That's why I keep using ccu_update()
> everywhere and dropped ccu_write().

That's a great point, thank you.  I'll modify it to use
regmap_update_bits(), which is better anyway.

					-Alex

> 
> Thanks,
> Haylen Chu


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

* Re: [PATCH RESEND 2/7] clk: spacemit: define struct k1_ccu_data
  2025-03-22 15:50   ` Yixun Lan
  2025-03-23 12:43     ` Alex Elder
@ 2025-03-28 17:24     ` Alex Elder
  1 sibling, 0 replies; 34+ messages in thread
From: Alex Elder @ 2025-03-28 17:24 UTC (permalink / raw)
  To: Yixun Lan
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	guodong, paul.walmsley, palmer, aou, spacemit, devicetree,
	linux-clk, linux-riscv, linux-kernel

On 3/22/25 10:50 AM, Yixun Lan wrote:
> Hi Alex:
> 
> this patch change relate to clock only, so how about let's fold
> it into clk patches (which now has not been merged), so we make
> the code right at first place? cause some moving around and renaming

I realize now I didn't respond to your other comments.

You suggested incorporating this change in the clock patches,
but I believe Haylen wants to avoid doing that (or doesn't want
to use all of it, anyway).

> 
> On 10:18 Fri 21 Mar     , Alex Elder wrote:
>> Define a new structure type to be used for describing the OF match data.
>> Rather than using the array of spacemit_ccu_clk structures for match
>> data, we use this structure instead.
>>
>> Move the definition of the spacemit_ccu_clk structure closer to the top
>> of the source file, and add the new structure definition below it.
>>
>> Shorten the name of spacemit_ccu_register() to be k1_ccu_register().
> any good reason to change this? it make the code style inconsistent,
> do you just change it for shorten function, or want it to be more k1
> specific, so next SoC - e.g maybe k2? will introduce another function?

I think I was trying to shorten things.  At this point it's hard
to know which things are K1-specific and which things will be
generic for anything from SpacemiT.  Once something new comes
along the code will be updated based on what needs to change.

That said, I'll not rename this, and I will use "spacemit" rather
than "k1" in all of the new symbols I create.

>>
>> Signed-off-by: Alex Elder <elder@riscstar.com>
>> ---
>>   drivers/clk/spacemit/ccu-k1.c | 58 ++++++++++++++++++++++++++---------
>>   1 file changed, 43 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
>> index 44db48ae71313..f7367271396a0 100644
>> --- a/drivers/clk/spacemit/ccu-k1.c
>> +++ b/drivers/clk/spacemit/ccu-k1.c
>> @@ -129,6 +129,15 @@
>>   #define APMU_EMAC0_CLK_RES_CTRL		0x3e4
>>   #define APMU_EMAC1_CLK_RES_CTRL		0x3ec
>>   
>> +struct spacemit_ccu_clk {
>> +	int id;
>> +	struct clk_hw *hw;
>> +};
>> +
>> +struct k1_ccu_data {
>> +	struct spacemit_ccu_clk *clk;		/* array with sentinel */
>> +};
>> +
>>   /*	APBS clocks start	*/
>>   
>>   /* Frequency of pll{1,2} should not be updated at runtime */
>> @@ -1359,11 +1368,6 @@ static CCU_GATE_DEFINE(emmc_bus_clk, CCU_PARENT_HW(pmua_aclk),
>>   		       0);
>>   /*	APMU clocks end		*/
>>   
>> -struct spacemit_ccu_clk {
>> -	int id;
>> -	struct clk_hw *hw;
>> -};
>> -
>>   static struct spacemit_ccu_clk k1_ccu_apbs_clks[] = {
>>   	{ CLK_PLL1,		&pll1.common.hw },
>>   	{ CLK_PLL2,		&pll2.common.hw },
>> @@ -1403,6 +1407,10 @@ static struct spacemit_ccu_clk k1_ccu_apbs_clks[] = {
>>   	{ 0,			NULL },
>>   };
>>   
>> +static const struct k1_ccu_data k1_ccu_apbs_data = {
>> +	.clk		= k1_ccu_apbs_clks,
>> +};
>> +
>>   static struct spacemit_ccu_clk k1_ccu_mpmu_clks[] = {
>>   	{ CLK_PLL1_307P2,	&pll1_d8_307p2.common.hw },
>>   	{ CLK_PLL1_76P8,	&pll1_d32_76p8.common.hw },
>> @@ -1440,6 +1448,10 @@ static struct spacemit_ccu_clk k1_ccu_mpmu_clks[] = {
>>   	{ 0,			NULL },
>>   };
>>   
>> +static const struct k1_ccu_data k1_ccu_mpmu_data = {
>> +	.clk		= k1_ccu_mpmu_clks,
>> +};
>> +
>>   static struct spacemit_ccu_clk k1_ccu_apbc_clks[] = {
>>   	{ CLK_UART0,		&uart0_clk.common.hw },
>>   	{ CLK_UART2,		&uart2_clk.common.hw },
>> @@ -1544,6 +1556,10 @@ static struct spacemit_ccu_clk k1_ccu_apbc_clks[] = {
>>   	{ 0,			NULL },
>>   };
>>   
>> +static const struct k1_ccu_data k1_ccu_apbc_data = {
>> +	.clk		= k1_ccu_apbc_clks,
>> +};
>> +
>>   static struct spacemit_ccu_clk k1_ccu_apmu_clks[] = {
>>   	{ CLK_CCI550,		&cci550_clk.common.hw },
>>   	{ CLK_CPU_C0_HI,	&cpu_c0_hi_clk.common.hw },
>> @@ -1610,9 +1626,13 @@ static struct spacemit_ccu_clk k1_ccu_apmu_clks[] = {
>>   	{ 0,			NULL },
>>   };
>>   
>> -static int spacemit_ccu_register(struct device *dev,
>> -				 struct regmap *regmap, struct regmap *lock_regmap,
>> -				 const struct spacemit_ccu_clk *clks)
>> +static const struct k1_ccu_data k1_ccu_apmu_data = {
>> +	.clk		= k1_ccu_apmu_clks,
>> +};
>> +
>> +static int k1_ccu_register(struct device *dev, struct regmap *regmap,
>> +			   struct regmap *lock_regmap,
>> +			   struct spacemit_ccu_clk *clks)
>>   {
>>   	const struct spacemit_ccu_clk *clk;
>>   	int i, ret, max_id = 0;
>> @@ -1648,15 +1668,24 @@ static int spacemit_ccu_register(struct device *dev,
>>   
>>   	clk_data->num = max_id + 1;
>>   
>> -	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
>> +	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
>> +	if (ret)
>> +		dev_err(dev, "error %d adding clock hardware provider\n", ret);
>> +
>> +	return ret;
> I'd use "return 0;", nothing different, just explicitly short

That would mean the caller doesn't know about this error.
Why do that?  The caller is free to ignore it (but really,
shouldn't).  I think it's important to pass this information
back.  I'm going to keep this "return ret" in v2.

> 
> ok, I can understand this change ease debug procedure once there is problem.
> (but I'm fine with either way, failure should rarely happen & will
> identify early)
> 
>>   }
>>   
>>   static int k1_ccu_probe(struct platform_device *pdev)
>>   {
>>   	struct regmap *base_regmap, *lock_regmap = NULL;
>>   	struct device *dev = &pdev->dev;
>> +	const struct k1_ccu_data *data;
>>   	int ret;
>>   
>> +	data = of_device_get_match_data(dev);
>> +	if (!data)
>> +		return -EINVAL;
>> +
>>   	base_regmap = device_node_to_regmap(dev->of_node);
>>   	if (IS_ERR(base_regmap))
>>   		return dev_err_probe(dev, PTR_ERR(base_regmap),
>> @@ -1677,8 +1706,7 @@ static int k1_ccu_probe(struct platform_device *pdev)
>>   					     "failed to get lock regmap\n");
>>   	}
>>   
>> -	ret = spacemit_ccu_register(dev, base_regmap, lock_regmap,
>> -				    of_device_get_match_data(dev));
>> +	ret = k1_ccu_register(dev, base_regmap, lock_regmap, data->clk);
>>   	if (ret)
>>   		return dev_err_probe(dev, ret, "failed to register clocks\n");
>>   
>> @@ -1688,19 +1716,19 @@ static int k1_ccu_probe(struct platform_device *pdev)
>>   static const struct of_device_id of_k1_ccu_match[] = {
>>   	{
>>   		.compatible	= "spacemit,k1-pll",
>> -		.data		= k1_ccu_apbs_clks,
>> +		.data		= &k1_ccu_apbs_data,
>>   	},
>>   	{
>>   		.compatible	= "spacemit,k1-syscon-mpmu",
>> -		.data		= k1_ccu_mpmu_clks,
>> +		.data		= &k1_ccu_mpmu_data,
>>   	},
>>   	{
>>   		.compatible	= "spacemit,k1-syscon-apbc",
>> -		.data		= k1_ccu_apbc_clks,
>> +		.data		= &k1_ccu_apbc_data,
>>   	},
>>   	{
>>   		.compatible	= "spacemit,k1-syscon-apmu",
>> -		.data		= k1_ccu_apmu_clks,
>> +		.data		= &k1_ccu_apmu_data,
>>   	},
>>   	{ }
> 	{ /* sentinel */ }

I think this is unnecessary but I'll do it--you're the SpacemiT
maintainer so you can define the style you want.

					-Alex

>>   };
>> -- 
>> 2.43.0
>>
> 


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

* Re: [PATCH RESEND 6/7] clk: spacemit: define new syscons with only resets
  2025-03-24  6:21       ` Yixun Lan
@ 2025-03-28 17:24         ` Alex Elder
  0 siblings, 0 replies; 34+ messages in thread
From: Alex Elder @ 2025-03-28 17:24 UTC (permalink / raw)
  To: Yixun Lan
  Cc: p.zabel, mturquette, sboyd, robh, krzk+dt, conor+dt, heylenay,
	paul.walmsley, palmer, aou, spacemit, devicetree, linux-clk,
	linux-riscv, linux-kernel

On 3/24/25 1:21 AM, Yixun Lan wrote:
> Hi Alex:
> 
> On 08:23 Sun 23 Mar     , Alex Elder wrote:
>> On 3/22/25 11:42 AM, Yixun Lan wrote:
>>> Hi Alex:
>>>
>>> It occur to me it's a little odd to implemnt reset driver
>>> for RCPU block, but after check with vendor the RCPU region can
>>> be accessed both by ACPU and RCPU, then I'm fine with this.
>>
>> I implemented just the resets that were found in the downstream
>> code.
>>
>> I first implemented a separate reset driver, very simple, which
>> only implemented the resets.  I had a separate DTS binding (like
>> was done for the PLLs).  I was ready to post it for review, then
>> noticed that the registers used were shared with clocks.  So I
>> merged all of that separate code into the clock driver, as you
>> see here.
>>
> ok
> 
>>> ACPU - RISC-V Main CPU, with mmu, running Linux
>>> RCPU - real time CPU, without mmu, running RT-OS
>>
>> I didn't realize there was a separate CPU running its
>> own OS.  Is this managed as a remoteproc by the RISC-V AP?
>> The reset signals, I hope, are only touched by the AP
>> and not the real-time CPU.  Can you provide any further
>> information about this?
>>
> As far as I know, the RCPU region can be acccesed via AP and real-time CPU
> from hardware perspective, there is no guarantee of isolation,
> so maybe software should take care of this in case only one side can touch

The downstream code implements clocks and resets that are
apparently associated with that real-time CPU.  Now that
you've pointed this out, I investigated a little further.

In "k1-x.dtsi" I see these used (in downstram):
   CLK_RCPU_UART1 and RESET_RCPU_UART1
   CLK_RCPU_I2C0 and RESET_RCPU_I2C0
   CLK_RCPU_IR and RESET_RCPU_IR
   CLK_RCPU_CAN, CLK_RCPU_CAN_BUS, and RESET_RCPU_CAN
   CLK_RCPU2_PWM0 through CLK_RCPU2_PWM9 and
   RESET_RCPU2_PWM0 through RESET_RCPU2_PWM9

In "k1-x-hdmi.dtsi" I see these used:
   CLK_RCPU_HDMIAUDIO and RESET_RCPU_HDMIAUDIO

Also, the memory region associated with the "RCPU2"
really is 0xc0888000 in the downstream code, even though
that isn't seen in the documentation.

Yixun, do you think we should remove code that supports
RCPU resets *and* clocks, until we really need it (and
we understand better how/why they're used)?


In the next version of my reset series (which I plan to
send today) I will keep the RCPU resets.

> for remoteproc, I haven't checked, and it's unrelated to this discussion
> (doesn't change shared resource fact whether remoteproc supported or not)

I don't understand why the AP would manage multiple
clocks and resets for a separate processor.  I'm not
going to look at that now though.

>>> On 10:18 Fri 21 Mar     , Alex Elder wrote:
>>>> Enable support for three additional syscon CCUs which support reset
>>>> controls but no clocks:  ARCPU, RCPU2, and APBC2.
>>>>
>>>> Signed-off-by: Alex Elder <elder@riscstar.com>
>>>> ---
>>>>    drivers/clk/spacemit/ccu-k1.c | 106 ++++++++++++++++++++++++++++++++++
>>>>    1 file changed, 106 insertions(+)
>>>>
>>>> diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
>>>> index 17e321c25959a..bf5a3e2048619 100644
>>>> --- a/drivers/clk/spacemit/ccu-k1.c
>>>> +++ b/drivers/clk/spacemit/ccu-k1.c
>>>> @@ -130,6 +130,37 @@
>>>>    #define APMU_EMAC0_CLK_RES_CTRL		0x3e4
>>>>    #define APMU_EMAC1_CLK_RES_CTRL		0x3ec
>>>>    
>>>> +/* RCPU register offsets */
>>>> +#define RCPU_SSP0_CLK_RST		0x0028
>>>> +#define RCPU_I2C0_CLK_RST		0x0030
>>>> +#define RCPU_UART1_CLK_RST		0x003c
>>>> +#define RCPU_CAN_CLK_RST		0x0048
>>>> +#define RCPU_IR_CLK_RST			0x004c
>>>> +#define RCPU_UART0_CLK_RST		0x00d8
>>>> +/* XXX Next one is part of the AUD_AUDCLOCK region @ 0xc0882000 */
>>> this comment looks odd, XXX?
>>
>> Yeah, I meant to remove that before sending but I forgot.
>>
>> The downstream code treats this one register as being
>> part of the RCPU memory region, and extends that region
>> to be 0x2048 bytes to "fit" it.
>>
>> The hardware documentation actually defines a different
>> "RCPU Audio Clock" memory region, and it might be more
>> correct (though less convenient) to define that as a
>> distinct region of memory.
>>
>> What do you think?
>>
> I'm not sure, but from DT perspective, is it an independent device?
> if yes, then need to describe as a distinct region..

I think we should just remove these definitions.  And
because of that, I'm going to leave this as-is (included
with the existing RCPU memory region and device) in the
next version of my code.  If we decide to keep them, I
can separate them later.

					-Alex

>> 					-Alex
>>
>>>> +#define AUDIO_HDMI_CLK_CTRL		0x2044
>>>> +
>>>> +/* RCPU2 register offsets */
>>>> +#define RCPU2_PWM0_CLK_RST		0x0000
>>>> +#define RCPU2_PWM1_CLK_RST		0x0004
>>>> +#define RCPU2_PWM2_CLK_RST		0x0008
>>>> +#define RCPU2_PWM3_CLK_RST		0x000c
>>>> +#define RCPU2_PWM4_CLK_RST		0x0010
>>>> +#define RCPU2_PWM5_CLK_RST		0x0014
>>>> +#define RCPU2_PWM6_CLK_RST		0x0018
>>>> +#define RCPU2_PWM7_CLK_RST		0x001c
>>>> +#define RCPU2_PWM8_CLK_RST		0x0020
>>>> +#define RCPU2_PWM9_CLK_RST		0x0024
>>>> +
>>>> +/* APBC2 register offsets */
>>>> +#define APBC2_UART1_CLK_RST		0x0000
>>>> +#define APBC2_SSP2_CLK_RST		0x0004
>>>> +#define APBC2_TWSI3_CLK_RST		0x0008
>>>> +#define APBC2_RTC_CLK_RST		0x000c
>>>> +#define APBC2_TIMERS0_CLK_RST		0x0010
>>>> +#define APBC2_KPC_CLK_RST		0x0014
>>>> +#define APBC2_GPIO_CLK_RST		0x001c
>>>> +
>>>>    struct spacemit_ccu_clk {
>>>>    	int id;
>>>>    	struct clk_hw *hw;
>>>> @@ -1781,6 +1812,69 @@ static const struct k1_ccu_data k1_ccu_apmu_data = {
>>>>    	.rst_data	= &apmu_reset_controller_data,
>>>>    };
>>>>    
>>>> +static const struct ccu_reset_data rcpu_reset_data[] = {
>>>> +	[RST_RCPU_SSP0]		= RST_DATA(RCPU_SSP0_CLK_RST,	0, BIT(0)),
>>>> +	[RST_RCPU_I2C0]		= RST_DATA(RCPU_I2C0_CLK_RST,	0, BIT(0)),
>>>> +	[RST_RCPU_UART1]	= RST_DATA(RCPU_UART1_CLK_RST,	0, BIT(0)),
>>>> +	[RST_RCPU_IR]		= RST_DATA(RCPU_CAN_CLK_RST,	0, BIT(0)),
>>>> +	[RST_RCPU_CAN]		= RST_DATA(RCPU_IR_CLK_RST,	0, BIT(0)),
>>>> +	[RST_RCPU_UART0]	= RST_DATA(RCPU_UART0_CLK_RST,	0, BIT(0)),
>>>> +	[RST_RCPU_HDMI_AUDIO]	= RST_DATA(AUDIO_HDMI_CLK_CTRL,	0, BIT(0)),
>>>> +};
>>>> +
>>>> +static const struct ccu_reset_controller_data rcpu_reset_controller_data = {
>>>> +	.count		= ARRAY_SIZE(rcpu_reset_data),
>>>> +	.data		= rcpu_reset_data,
>>>> +};
>>>> +
>>>> +static struct k1_ccu_data k1_ccu_rcpu_data = {
>>>> +	/* No clocks in the RCPU CCU */
>>>> +	.rst_data	= &rcpu_reset_controller_data,
>>>> +};
>>>> +
>>>> +static const struct ccu_reset_data rcpu2_reset_data[] = {
>>>> +	[RST_RCPU2_PWM0]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>>>> +	[RST_RCPU2_PWM1]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>>>> +	[RST_RCPU2_PWM2]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>>>> +	[RST_RCPU2_PWM3]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>>>> +	[RST_RCPU2_PWM4]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>>>> +	[RST_RCPU2_PWM5]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>>>> +	[RST_RCPU2_PWM6]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>>>> +	[RST_RCPU2_PWM7]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>>>> +	[RST_RCPU2_PWM8]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>>>> +	[RST_RCPU2_PWM9]	= RST_DATA(RCPU2_PWM9_CLK_RST,	BIT(2), BIT(0)),
>>>> +};
>>>> +
>>>> +static const struct ccu_reset_controller_data rcpu2_reset_controller_data = {
>>>> +	.count		= ARRAY_SIZE(rcpu2_reset_data),
>>>> +	.data		= rcpu2_reset_data,
>>>> +};
>>>> +
>>>> +static struct k1_ccu_data k1_ccu_rcpu2_data = {
>>>> +	/* No clocks in the RCPU2 CCU */
>>>> +	.rst_data	= &rcpu2_reset_controller_data,
>>>> +};
>>>> +
>>>> +static const struct ccu_reset_data apbc2_reset_data[] = {
>>>> +	[RST_APBC2_UART1]	= RST_DATA(APBC2_UART1_CLK_RST,	BIT(2), (0)),
>>>> +	[RST_APBC2_SSP2]	= RST_DATA(APBC2_SSP2_CLK_RST,	BIT(2), (0)),
>>>> +	[RST_APBC2_TWSI3]	= RST_DATA(APBC2_TWSI3_CLK_RST,	BIT(2), (0)),
>>>> +	[RST_APBC2_RTC]		= RST_DATA(APBC2_RTC_CLK_RST,	BIT(2), (0)),
>>>> +	[RST_APBC2_TIMERS0]	= RST_DATA(APBC2_TIMERS0_CLK_RST, BIT(2), (0)),
>>>> +	[RST_APBC2_KPC]		= RST_DATA(APBC2_KPC_CLK_RST,	BIT(2), (0)),
>>>> +	[RST_APBC2_GPIO]	= RST_DATA(APBC2_GPIO_CLK_RST,	BIT(2), (0)),
>>>> +};
>>>> +
>>>> +static const struct ccu_reset_controller_data apbc2_reset_controller_data = {
>>>> +	.count		= ARRAY_SIZE(apbc2_reset_data),
>>>> +	.data		= apbc2_reset_data,
>>>> +};
>>>> +
>>>> +static struct k1_ccu_data k1_ccu_apbc2_data = {
>>>> +	/* No clocks in the RCPU2 CCU */
>>>> +	.rst_data	= &apbc2_reset_controller_data,
>>>> +};
>>>> +
>>>>    static struct ccu_reset_controller *
>>>>    rcdev_to_controller(struct reset_controller_dev *rcdev)
>>>>    {
>>>> @@ -1959,6 +2053,18 @@ static const struct of_device_id of_k1_ccu_match[] = {
>>>>    		.compatible	= "spacemit,k1-syscon-apmu",
>>>>    		.data		= &k1_ccu_apmu_data,
>>>>    	},
>>>> +	{
>>>> +		.compatible	= "spacemit,k1-syscon-rcpu",
>>>> +		.data		= &k1_ccu_rcpu_data,
>>>> +	},
>>>> +	{
>>>> +		.compatible	= "spacemit,k1-syscon-rcpu2",
>>>> +		.data		= &k1_ccu_rcpu2_data,
>>>> +	},
>>>> +	{
>>>> +		.compatible	= "spacemit,k1-syscon-apbc2",
>>>> +		.data		= &k1_ccu_apbc2_data,
>>>> +	},
>>>>    	{ }
>>>>    };
>>>>    MODULE_DEVICE_TABLE(of, of_k1_ccu_match);
>>>> -- 
>>>> 2.43.0
>>>>
>>>
>>
> 


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

end of thread, other threads:[~2025-03-28 17:24 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-21 15:18 [PATCH RESEND 0/7] clk: spacemit: add K1 reset support Alex Elder
2025-03-21 15:18 ` [PATCH RESEND 1/7] dt-bindings: soc: spacemit: define spacemit,k1-ccu resets Alex Elder
2025-03-21 20:42   ` Rob Herring
2025-03-21 22:25   ` Yixun Lan
2025-03-22 14:27     ` Alex Elder
2025-03-22 16:51       ` Yixun Lan
2025-03-21 15:18 ` [PATCH RESEND 2/7] clk: spacemit: define struct k1_ccu_data Alex Elder
2025-03-22 15:50   ` Yixun Lan
2025-03-23 12:43     ` Alex Elder
2025-03-23 13:04       ` Yixun Lan
2025-03-23 22:30         ` Alex Elder
2025-03-28 17:24     ` Alex Elder
2025-03-24 11:53   ` Haylen Chu
2025-03-24 12:17     ` Alex Elder
2025-03-21 15:18 ` [PATCH RESEND 3/7] clk: spacemit: add reset controller support Alex Elder
2025-03-22 16:19   ` Yixun Lan
2025-03-23 13:23     ` Alex Elder
2025-03-24  6:40       ` Yixun Lan
2025-03-24 12:20   ` Haylen Chu
2025-03-24 12:52     ` Alex Elder
2025-03-21 15:18 ` [PATCH RESEND 4/7] clk: spacemit: define existing syscon resets Alex Elder
2025-03-22 16:29   ` Yixun Lan
2025-03-23 13:23     ` Alex Elder
2025-03-24  6:24       ` Yixun Lan
2025-03-21 15:18 ` [PATCH RESEND 5/7] clk: spacemit: make clocks optional Alex Elder
2025-03-21 15:18 ` [PATCH RESEND 6/7] clk: spacemit: define new syscons with only resets Alex Elder
2025-03-22 16:42   ` Yixun Lan
2025-03-23 13:23     ` Alex Elder
2025-03-24  6:21       ` Yixun Lan
2025-03-28 17:24         ` Alex Elder
2025-03-21 15:18 ` [PATCH RESEND 7/7] riscv: dts: spacemit: add reset support for the K1 SoC Alex Elder
2025-03-22 16:48   ` Yixun Lan
2025-03-23 13:23     ` Alex Elder
2025-03-24  6:06       ` Yixun Lan

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