Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] pmdomain: rockchip: Add RK3572 boot peripheral domains
@ 2026-10-26  3:21 Cunhao Lu via B4 Relay
  2026-10-26  3:21 ` [PATCH v3 1/2] dt-bindings: power: rockchip: Add RK3572 power domains Cunhao Lu via B4 Relay
  2026-10-26  3:21 ` [PATCH v3 2/2] pmdomain: rockchip: Add RK3572 boot peripheral domains Cunhao Lu via B4 Relay
  0 siblings, 2 replies; 7+ messages in thread
From: Cunhao Lu via B4 Relay @ 2026-10-26  3:21 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Elaine Zhang, Ulf Hansson
  Cc: Cunhao Lu, devicetree, linux-arm-kernel, linux-rockchip,
	linux-kernel, linux-pm, Finley Xiao

This is one of the subsystem submissions for RK3572 support.

This series adds the RK3572 power-controller binding and power IDs,
followed by support for the NVM0, NVM1, PHP, and VOP power domains.
The driver uses the system GRF to check firmware shift-ready status.

The RK3572 SoC has eight CPU cores: two Cortex-A73 cores and six
Cortex-A53 cores. It also integrates an Arm Mali-G310V2 MC1 GPU.
The OK3572-C board provides two Gigabit Ethernet ports, three USB3 Type-A
ports, a Type-C dual-role port, eMMC, microSD, and UART.

Power-on progress and restoration are tracked separately so that a
failed transition can be retried without losing pending memory resets or
QoS state. The shared Rockchip power-domain code is updated to support
the RK3572 register layout and retry behavior.

Testing was performed with Debian 13 minimal and Linux 7.3 on the
OK3572-C with the FET3572-C module. Shared peripheral tests were run with
the system booted from SD, while eMMC validation covered the complete
boot chain.

Passed functionality:

- SD and eMMC complete the firmware, kernel, and root filesystem
  boot chain.
- UART console works at 1500000 baud.
- SD read/write and data persistence checks pass.
- All eight CPUs start; CPU frequency scaling and hotplug checks pass.
- Both Ethernet ports obtain IPv4 addresses and pass bidirectional file
  transfers.
- All three Type-A ports pass USB2 and USB3 enumeration, data transfers,
  and reconnect persistence checks.
- Type-C host and device modes pass in both plug orientations. Physical
  reconnects correctly select the expected device, host, and device roles
  in sequence.

Stability:

- Repeated cold and software reboots complete on SD and eMMC without
  data integrity failures or power-domain transition failures.
- A combined CPU, memory, network, SD, and USB3 stress test completes
  without a crash, lockup, CPU offline event, or thermal shutdown.
- Ethernet error and drop counters do not increase during bidirectional
  network tests.

Power-domain fault-path validation:

- Host tests extracted the transition logic and memory operations from
  the driver and simulated register failures during power-status checks,
  memory chain/off/on operations, idle exit, and firmware shift-ready checks.
- The tests also cover retries, shutdown after a failed power-on,
  clock-enable failure, regulator loss, and domains without a firmware
  shift-ready mask. QoS preservation and memory-reset counts were checked.
- The simulated tests pass ASan and UBSan.

Build and checks:

- The kernel, modules, and board DTB build successfully.
- The series passes checkpatch with --strict; only generic reminders about
  new MAINTAINERS entries remain.

Untested hardware and paths:

- NPU
- PCIe
- GPU, video output, and audio
- CPU rates above 1.2 GHz and voltage scaling
- Other low-speed external interfaces

Some files in this series are derived from the Forlinx OK3572-C BSP
Alpha1. Thanks to Forlinx for their support.
Thanks also to Rockchip's David Wu, Elaine Zhang, Finley Xiao, Frank
Wang, William Wu, and Ye Zhang for providing the driver source files.

AI assistance:

- Codex / DeepSeek V4.1 Flash were used for:
  - Reviewing and adjusting code style to follow community conventions
  - Automating tests
  - Collecting data

Signed-off-by: Cunhao Lu <1579567540@qq.com>
---
Changes in v3:
- Track incomplete shutdowns to preserve QoS and complete firmware updates.
- Preserve pending memory resets across shutdown and cancel unfinished
  power-on requests.
- Attempt to restore the domain after power-off errors, while preserving
  the original error returned to genpd.
- Link to v2:
  https://patch.msgid.link/20261023-add-board-ok3572-c-pmdomain-v2-0-79ddd42e92c1@qq.com

Changes in v2:
- Split the original RK3572 support series by subsystem.
- Track low-level power-on and restoration separately. Retain unfinished
  memory resets across retries, avoid repeating completed resets, and
  preserve QoS snapshots when shutting down after a failed power-on.
- Link to v1:
  https://patch.msgid.link/20261022-add-board-ok3572-c-v1-0-0b0fd85a31ee@qq.com

---
Raw dmesg: see v2 cover letter.

To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Conor Dooley <conor+dt@kernel.org>
To: Heiko Stuebner <heiko@sntech.de>
To: Elaine Zhang <zhangqing@rock-chips.com>
To: Ulf Hansson <ulfh@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-rockchip@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pm@vger.kernel.org

---
Finley Xiao (2):
      dt-bindings: power: rockchip: Add RK3572 power domains
      pmdomain: rockchip: Add RK3572 boot peripheral domains

 .../bindings/power/rockchip,power-controller.yaml  |  17 ++
 drivers/pmdomain/rockchip/pm-domains.c             | 187 ++++++++++++++++++---
 .../power/rockchip,rk3572-power-controller.h       |  30 ++++
 3 files changed, 214 insertions(+), 20 deletions(-)
---
base-commit: a804c5742bff224d4cb4d25dd383554d598be32b
change-id: 20261023-add-board-ok3572-c-pmdomain-2f02da11386e

Best regards,
--  
Cunhao Lu <1579567540@qq.com>




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

* [PATCH v3 1/2] dt-bindings: power: rockchip: Add RK3572 power domains
  2026-10-26  3:21 [PATCH v3 0/2] pmdomain: rockchip: Add RK3572 boot peripheral domains Cunhao Lu via B4 Relay
@ 2026-10-26  3:21 ` Cunhao Lu via B4 Relay
  2026-10-26  3:21 ` [PATCH v3 2/2] pmdomain: rockchip: Add RK3572 boot peripheral domains Cunhao Lu via B4 Relay
  1 sibling, 0 replies; 7+ messages in thread
From: Cunhao Lu via B4 Relay @ 2026-10-26  3:21 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Elaine Zhang, Ulf Hansson
  Cc: Cunhao Lu, devicetree, linux-arm-kernel, linux-rockchip,
	linux-kernel, linux-pm, Finley Xiao

From: Finley Xiao <finley.xiao@rock-chips.com>

Define the RK3572 power-domain IDs. The driver uses the system GRF to
check firmware shift-ready status after powering on a domain.

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>

- Added the rockchip,grf property.
- Made the phandle required only for RK3572.

Signed-off-by: Cunhao Lu <1579567540@qq.com>
---
 .../bindings/power/rockchip,power-controller.yaml  | 17 ++++++++++++
 .../power/rockchip,rk3572-power-controller.h       | 30 ++++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml b/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml
index b41db576f95d..f8afb0fabe80 100644
--- a/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml
+++ b/Documentation/devicetree/bindings/power/rockchip,power-controller.yaml
@@ -43,6 +43,7 @@ properties:
       - rockchip,rk3528-power-controller
       - rockchip,rk3562-power-controller
       - rockchip,rk3568-power-controller
+      - rockchip,rk3572-power-controller
       - rockchip,rk3576-power-controller
       - rockchip,rk3588-power-controller
       - rockchip,rv1126-power-controller
@@ -57,6 +58,22 @@ properties:
   "#size-cells":
     const: 0
 
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: System GRF with firewall readiness status.
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          const: rockchip,rk3572-power-controller
+    then:
+      required:
+        - rockchip,grf
+    else:
+      properties:
+        rockchip,grf: false
+
 required:
   - compatible
   - "#power-domain-cells"
diff --git a/include/dt-bindings/power/rockchip,rk3572-power-controller.h b/include/dt-bindings/power/rockchip,rk3572-power-controller.h
new file mode 100644
index 000000000000..c2316fa859df
--- /dev/null
+++ b/include/dt-bindings/power/rockchip,rk3572-power-controller.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2026 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao@rock-chips.com>
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3572_POWER_CONTROLLER_H__
+#define __DT_BINDINGS_POWER_RK3572_POWER_CONTROLLER_H__
+
+/* VD_NPU */
+#define RK3572_PD_NPU		0
+
+/* VD_GPU */
+#define RK3572_PD_GPU		1
+
+/* VD_LOGIC */
+#define RK3572_PD_NVM0		2
+#define RK3572_PD_NVM1		3
+#define RK3572_PD_DSMC		4
+#define RK3572_PD_PHP		5
+#define RK3572_PD_AUDIO		6
+#define RK3572_PD_IMG		7
+#define RK3572_PD_VDEC		8
+#define RK3572_PD_VI		9
+#define RK3572_PD_VENC		10
+#define RK3572_PD_VO		11
+#define RK3572_PD_VOP		12
+#define RK3572_PD_VOP_PRE	13
+
+#endif

-- 
2.34.1




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

* [PATCH v3 2/2] pmdomain: rockchip: Add RK3572 boot peripheral domains
  2026-10-26  3:21 [PATCH v3 0/2] pmdomain: rockchip: Add RK3572 boot peripheral domains Cunhao Lu via B4 Relay
  2026-10-26  3:21 ` [PATCH v3 1/2] dt-bindings: power: rockchip: Add RK3572 power domains Cunhao Lu via B4 Relay
@ 2026-10-26  3:21 ` Cunhao Lu via B4 Relay
  2026-10-26  8:47   ` Finley Xiao
  1 sibling, 1 reply; 7+ messages in thread
From: Cunhao Lu via B4 Relay @ 2026-10-26  3:21 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Elaine Zhang, Ulf Hansson
  Cc: Cunhao Lu, devicetree, linux-arm-kernel, linux-rockchip,
	linux-kernel, linux-pm, Finley Xiao

From: Finley Xiao <finley.xiao@rock-chips.com>

Add support for the RK3572 NVM0, NVM1, PHP, and VOP power domains.

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>

- Returned firmware shift-ready wait errors to callers.
- Kept the domain pending after a firmware shift-ready wait failure.
- Retried power-on without repeating completed memory resets.
- Recorded low-level power-on and restoration stages before hardware
  operations so retries complete unfinished low-level work.
- Kept memory resets pending across failures, including when memory is off.
- Preserved QoS snapshots after a failed power-on and cleared progress
  after successful power-on or shutdown.
- Tracked incomplete shutdowns to preserve QoS and complete firmware updates.
- Preserved pending memory resets across shutdown and cancelled unfinished
  power-on requests.
- Attempt to restore the domain after power-off errors, while preserving
  the original error returned to genpd.

Co-developed-by: Cunhao Lu <1579567540@qq.com>
Signed-off-by: Cunhao Lu <1579567540@qq.com>
---
Changes in v3:
- Track incomplete shutdowns to preserve QoS and complete firmware updates.
- Preserve pending memory resets across shutdown and cancel unfinished
  power-on requests.
- Attempt to restore the domain after power-off errors, while preserving
  the original error returned to genpd.

Changes in v2:
- Record low-level power-on and restoration stages before hardware
  operations, so a retry cannot skip unfinished low-level work.
- Retain pending memory resets even if memory is off on retry, and
  avoid repeating completed resets during restoration.
- Preserve QoS snapshots across failed power-on and shutdown; clear
  progress after successful power-on or shutdown.
---
 drivers/pmdomain/rockchip/pm-domains.c | 187 +++++++++++++++++++++++++++++----
 1 file changed, 167 insertions(+), 20 deletions(-)

diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c
index e193f978d5f3..668d208dea55 100644
--- a/drivers/pmdomain/rockchip/pm-domains.c
+++ b/drivers/pmdomain/rockchip/pm-domains.c
@@ -39,6 +39,7 @@
 #include <dt-bindings/power/rockchip,rk3528-power.h>
 #include <dt-bindings/power/rockchip,rk3562-power.h>
 #include <dt-bindings/power/rk3568-power.h>
+#include <dt-bindings/power/rockchip,rk3572-power-controller.h>
 #include <dt-bindings/power/rockchip,rk3576-power.h>
 #include <dt-bindings/power/rk3588-power.h>
 
@@ -59,6 +60,9 @@ struct rockchip_domain_info {
 	u32 pwr_offset;
 	u32 mem_offset;
 	u32 req_offset;
+	u32 status_offset;
+	u32 firewall_mask;
+	u32 clk_ungate_offset;
 };
 
 struct rockchip_pmu_info {
@@ -72,6 +76,8 @@ struct rockchip_pmu_info {
 	u32 mem_status_offset;
 	u32 repair_status_offset;
 	u32 clk_ungate_offset;
+	u32 firewall_status_offset;
+	bool chain_status_inverted;
 
 	u32 core_pwrcnt_offset;
 	u32 gpu_pwrcnt_offset;
@@ -90,6 +96,13 @@ struct rockchip_pmu_info {
 #define QOS_SATURATION		0x14
 #define QOS_EXTCONTROL		0x18
 
+enum rockchip_pd_power_state {
+	ROCKCHIP_PD_IDLE,
+	ROCKCHIP_PD_ON_HW,
+	ROCKCHIP_PD_ON_RESTORE,
+	ROCKCHIP_PD_OFF,
+};
+
 struct rockchip_pm_domain {
 	struct generic_pm_domain genpd;
 	const struct rockchip_domain_info *info;
@@ -101,11 +114,14 @@ struct rockchip_pm_domain {
 	struct clk_bulk_data *clks;
 	struct device_node *node;
 	struct regulator *supply;
+	enum rockchip_pd_power_state power_state;
+	bool mem_reset_pending;
 };
 
 struct rockchip_pmu {
 	struct device *dev;
 	struct regmap *regmap;
+	struct regmap *grf;
 	const struct rockchip_pmu_info *info;
 	struct mutex mutex; /* mutex lock for pmu */
 	struct genpd_onecell_data genpd_data;
@@ -373,15 +389,16 @@ static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)
 	const struct rockchip_domain_info *pd_info = pd->info;
 	unsigned int val;
 
-	regmap_read(pmu->regmap, pmu->info->idle_offset, &val);
+	regmap_read(pmu->regmap, pmu->info->idle_offset + pd_info->status_offset, &val);
 	return (val & pd_info->idle_mask) == pd_info->idle_mask;
 }
 
-static unsigned int rockchip_pmu_read_ack(struct rockchip_pmu *pmu)
+static unsigned int rockchip_pmu_read_ack(struct rockchip_pm_domain *pd)
 {
+	struct rockchip_pmu *pmu = pd->pmu;
 	unsigned int val;
 
-	regmap_read(pmu->regmap, pmu->info->ack_offset, &val);
+	regmap_read(pmu->regmap, pmu->info->ack_offset + pd->info->status_offset, &val);
 	return val;
 }
 
@@ -400,7 +417,8 @@ static int rockchip_pmu_ungate_clk(struct rockchip_pm_domain *pd, bool ungate)
 
 	val = ungate ? (pd_info->clk_ungate_mask | clk_ungate_w_mask) :
 			clk_ungate_w_mask;
-	regmap_write(pmu->regmap, pmu->info->clk_ungate_offset, val);
+	regmap_write(pmu->regmap, pmu->info->clk_ungate_offset +
+		     pd_info->clk_ungate_offset, val);
 
 	return 0;
 }
@@ -431,7 +449,7 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
 
 	/* Wait util idle_ack = 1 */
 	target_ack = idle ? pd_info->ack_mask : 0;
-	ret = readx_poll_timeout_atomic(rockchip_pmu_read_ack, pmu, val,
+	ret = readx_poll_timeout_atomic(rockchip_pmu_read_ack, pd, val,
 					(val & pd_info->ack_mask) == target_ack,
 					0, 10000);
 	if (ret) {
@@ -543,6 +561,9 @@ static bool rockchip_pmu_domain_is_chain_on(struct rockchip_pm_domain *pd)
 	regmap_read(pmu->regmap,
 		    pmu->info->chain_status_offset + pd->info->mem_offset, &val);
 
+	if (pmu->info->chain_status_inverted)
+		return !(val & pd->info->mem_status_mask);
+
 	/* 1'b1: power on, 1'b0: power off */
 	return val & pd->info->mem_status_mask;
 }
@@ -600,16 +621,13 @@ static int rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
 	struct rockchip_pmu *pmu = pd->pmu;
 	struct generic_pm_domain *genpd = &pd->genpd;
 	u32 pd_pwr_offset = pd->info->pwr_offset;
-	bool is_on, is_mem_on = false;
+	bool is_on;
 	struct arm_smccc_res res;
 	int ret;
 
 	if (pd->info->pwr_mask == 0)
 		return 0;
 
-	if (on && pd->info->mem_status_mask)
-		is_mem_on = rockchip_pmu_domain_is_mem_on(pd);
-
 	if (pd->info->pwr_w_mask)
 		regmap_write(pmu->regmap, pmu->info->pwr_offset + pd_pwr_offset,
 			     on ? pd->info->pwr_w_mask :
@@ -620,13 +638,13 @@ static int rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
 
 	wmb();
 
-	if (is_mem_on) {
+	if (on && pd->mem_reset_pending) {
 		ret = rockchip_pmu_domain_mem_reset(pd);
 		if (ret)
 			return ret;
+		pd->mem_reset_pending = false;
 	}
 
-
 	ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_on, pd, is_on,
 					is_on == on, 0, 10000);
 	if (ret) {
@@ -644,14 +662,29 @@ static int rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
 	return 0;
 }
 
+static int rockchip_pmu_wait_firewall(struct rockchip_pm_domain *pd)
+{
+	struct rockchip_pmu *pmu = pd->pmu;
+	u32 mask = pd->info->firewall_mask;
+	u32 val;
+
+	if (!mask)
+		return 0;
+
+	return regmap_read_poll_timeout(pmu->grf, pmu->info->firewall_status_offset,
+				       val, (val & mask) == mask, 0, 10000);
+}
+
 static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
 {
 	struct rockchip_pmu *pmu = pd->pmu;
+	bool is_on;
 	int ret;
 
 	guard(mutex)(&pmu->mutex);
 
-	if (rockchip_pmu_domain_is_on(pd) == power_on)
+	is_on = rockchip_pmu_domain_is_on(pd);
+	if (is_on == power_on && pd->power_state == ROCKCHIP_PD_IDLE)
 		return 0;
 
 	ret = clk_bulk_enable(pd->num_clks, pd->clks);
@@ -662,18 +695,38 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
 
 	rockchip_pmu_ungate_clk(pd, true);
 
-	if (!power_on) {
-		rockchip_pmu_save_qos(pd);
+	if (power_on) {
+		if (pd->power_state == ROCKCHIP_PD_IDLE ||
+		    pd->power_state == ROCKCHIP_PD_OFF ||
+		    (pd->power_state == ROCKCHIP_PD_ON_RESTORE && !is_on)) {
+			/* A failed reset may still be forcing memory off. */
+			pd->mem_reset_pending |= pd->info->mem_status_mask &&
+				rockchip_pmu_domain_is_mem_on(pd);
+			pd->power_state = ROCKCHIP_PD_ON_HW;
+		}
+
+		/* A status bit alone does not prove the low-level sequence finished. */
+		if (pd->power_state == ROCKCHIP_PD_ON_HW) {
+			ret = rockchip_do_pmu_set_power_domain(pd, true);
+			if (ret < 0)
+				goto out;
+			pd->power_state = ROCKCHIP_PD_ON_RESTORE;
+		}
+	} else {
+		if (pd->power_state == ROCKCHIP_PD_IDLE)
+			rockchip_pmu_save_qos(pd);
+		pd->power_state = ROCKCHIP_PD_OFF;
 
 		/* if powering down, idle request to NIU first */
 		ret = rockchip_pmu_set_idle_request(pd, true);
 		if (ret < 0)
 			goto out;
-	}
 
-	ret = rockchip_do_pmu_set_power_domain(pd, power_on);
-	if (ret < 0)
-		goto out;
+		/* Cancel a pending power-on even if its status is still off. */
+		ret = rockchip_do_pmu_set_power_domain(pd, false);
+		if (ret < 0)
+			goto out;
+	}
 
 	if (power_on) {
 		/* if powering up, leave idle mode */
@@ -681,8 +734,14 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
 		if (ret < 0)
 			goto out;
 
+		ret = rockchip_pmu_wait_firewall(pd);
+		if (ret)
+			goto out;
+
 		rockchip_pmu_restore_qos(pd);
+		pd->mem_reset_pending = false;
 	}
+	pd->power_state = ROCKCHIP_PD_IDLE;
 
 out:
 	rockchip_pmu_ungate_clk(pd, false);
@@ -733,11 +792,18 @@ static int rockchip_pd_power_on(struct generic_pm_domain *domain)
 static int rockchip_pd_power_off(struct generic_pm_domain *domain)
 {
 	struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
-	int ret;
+	int ret, err;
 
 	ret = rockchip_pd_power(pd, false);
-	if (ret)
+	if (ret) {
+		/* genpd still considers the domain on after a failed power-off. */
+		err = rockchip_pd_power(pd, true);
+		if (err)
+			dev_err(pd->pmu->dev,
+				"failed to restore domain '%s' after power-off failure: %d\n",
+				domain->name, err);
 		return ret;
+	}
 
 	rockchip_pd_regulator_disable(pd);
 	return ret;
@@ -1064,6 +1130,11 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
 	mutex_init(&pmu->mutex);
 
 	pmu->info = pmu_info;
+	if (pmu_info->firewall_status_offset) {
+		pmu->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+		if (IS_ERR(pmu->grf))
+			return dev_err_probe(dev, PTR_ERR(pmu->grf), "failed to get system GRF\n");
+	}
 
 	pmu->genpd_data.domains = pmu->domains;
 	pmu->genpd_data.num_domains = pmu_info->num_domains;
@@ -1313,6 +1384,62 @@ static const struct rockchip_domain_info rk3568_pm_domains[] = {
 	[RK3568_PD_PIPE]	= DOMAIN_RK3568("pipe", BIT(8), BIT(11), false, false),
 };
 
+static const struct rockchip_domain_info rk3572_pm_domains[] = {
+	[RK3572_PD_NVM1] = {
+		.name = "nvm1",
+		.pwr_mask = BIT(4),
+		.pwr_w_mask = BIT(20),
+		.mem_status_mask = BIT(4),
+		.repair_status_mask = BIT(3),
+		.req_mask = BIT(6),
+		.req_w_mask = BIT(22),
+		.idle_mask = BIT(6),
+		.ack_mask = BIT(6),
+		.clk_ungate_mask = BIT(6),
+	},
+	[RK3572_PD_PHP] = {
+		.name = "php",
+		.pwr_mask = BIT(7),
+		.pwr_w_mask = BIT(23),
+		.mem_status_mask = BIT(7),
+		.repair_status_mask = BIT(5),
+		.req_mask = BIT(9),
+		.req_w_mask = BIT(25),
+		.idle_mask = BIT(9),
+		.ack_mask = BIT(9),
+		.clk_ungate_mask = BIT(9),
+		.firewall_mask = BIT(28),
+	},
+	[RK3572_PD_VOP] = {
+		.name = "vop",
+		.pwr_mask = BIT(12),
+		.pwr_w_mask = BIT(28),
+		.mem_status_mask = BIT(12),
+		.repair_status_mask = BIT(10),
+		.req_mask = BIT(14),
+		.req_w_mask = BIT(30),
+		.idle_mask = BIT(14),
+		.ack_mask = BIT(14),
+		.clk_ungate_mask = BIT(14),
+		.firewall_mask = BIT(23),
+	},
+	[RK3572_PD_NVM0] = {
+		.name = "nvm0",
+		.pwr_mask = BIT(15),
+		.pwr_w_mask = BIT(31),
+		.mem_status_mask = BIT(15),
+		.repair_status_mask = BIT(13),
+		.req_mask = BIT(0),
+		.req_w_mask = BIT(16),
+		.idle_mask = BIT(0),
+		.ack_mask = BIT(0),
+		.clk_ungate_mask = BIT(0),
+		.req_offset = 4,
+		.status_offset = 4,
+		.clk_ungate_offset = 4,
+	},
+};
+
 static const struct rockchip_domain_info rk3576_pm_domains[] = {
 	[RK3576_PD_NPU]		= DOMAIN_RK3576("npu",    0x0, BIT(0),  BIT(0), 0,       0x0, 0,       0,       0,       false),
 	[RK3576_PD_NVM]		= DOMAIN_RK3576("nvm",    0x0, BIT(6),  0,      BIT(6),  0x4, BIT(2),  BIT(18), BIT(2),  false),
@@ -1536,6 +1663,23 @@ static const struct rockchip_pmu_info rk3568_pmu = {
 	.domain_info = rk3568_pm_domains,
 };
 
+static const struct rockchip_pmu_info rk3572_pmu = {
+	.pwr_offset = 0x210,
+	.status_offset = 0x230,
+	.chain_status_offset = 0x250,
+	.chain_status_inverted = true,
+	.mem_status_offset = 0x260,
+	.mem_pwr_offset = 0x300,
+	.req_offset = 0x110,
+	.idle_offset = 0x130,
+	.ack_offset = 0x120,
+	.repair_status_offset = 0x570,
+	.clk_ungate_offset = 0x150,
+	.firewall_status_offset = 0x140,
+	.num_domains = ARRAY_SIZE(rk3572_pm_domains),
+	.domain_info = rk3572_pm_domains,
+};
+
 static const struct rockchip_pmu_info rk3576_pmu = {
 	.pwr_offset = 0x210,
 	.status_offset = 0x230,
@@ -1648,6 +1792,9 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = {
 		.data = (void *)&rk3568_pmu,
 	},
 	{
+		.compatible = "rockchip,rk3572-power-controller",
+		.data = &rk3572_pmu,
+	}, {
 		.compatible = "rockchip,rk3576-power-controller",
 		.data = (void *)&rk3576_pmu,
 	},

-- 
2.34.1




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

* Re: [PATCH v3 2/2] pmdomain: rockchip: Add RK3572 boot peripheral domains
  2026-10-26  3:21 ` [PATCH v3 2/2] pmdomain: rockchip: Add RK3572 boot peripheral domains Cunhao Lu via B4 Relay
@ 2026-10-26  8:47   ` Finley Xiao
  2026-10-26 11:37     ` Finley Xiao
  0 siblings, 1 reply; 7+ messages in thread
From: Finley Xiao @ 2026-10-26  8:47 UTC (permalink / raw)
  To: 1579567540, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Heiko Stuebner, Elaine Zhang, Ulf Hansson
  Cc: devicetree, linux-arm-kernel, linux-rockchip, linux-kernel,
	linux-pm


在 2026/10/26 11:21, Cunhao Lu via B4 Relay 写道:
> From: Finley Xiao <finley.xiao@rock-chips.com>
>
> Add support for the RK3572 NVM0, NVM1, PHP, and VOP power domains.
>
> Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
>
> - Returned firmware shift-ready wait errors to callers.
> - Kept the domain pending after a firmware shift-ready wait failure.
> - Retried power-on without repeating completed memory resets.
> - Recorded low-level power-on and restoration stages before hardware
>    operations so retries complete unfinished low-level work.
> - Kept memory resets pending across failures, including when memory is off.
> - Preserved QoS snapshots after a failed power-on and cleared progress
>    after successful power-on or shutdown.
> - Tracked incomplete shutdowns to preserve QoS and complete firmware updates.
> - Preserved pending memory resets across shutdown and cancelled unfinished
>    power-on requests.
> - Attempt to restore the domain after power-off errors, while preserving
>    the original error returned to genpd.
>
> Co-developed-by: Cunhao Lu <1579567540@qq.com>
> Signed-off-by: Cunhao Lu <1579567540@qq.com>
> ---
> Changes in v3:
> - Track incomplete shutdowns to preserve QoS and complete firmware updates.
> - Preserve pending memory resets across shutdown and cancel unfinished
>    power-on requests.
> - Attempt to restore the domain after power-off errors, while preserving
>    the original error returned to genpd.
>
> Changes in v2:
> - Record low-level power-on and restoration stages before hardware
>    operations, so a retry cannot skip unfinished low-level work.
> - Retain pending memory resets even if memory is off on retry, and
>    avoid repeating completed resets during restoration.
> - Preserve QoS snapshots across failed power-on and shutdown; clear
>    progress after successful power-on or shutdown.
> ---
>   drivers/pmdomain/rockchip/pm-domains.c | 187 +++++++++++++++++++++++++++++----
>   1 file changed, 167 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c
> index e193f978d5f3..668d208dea55 100644
> --- a/drivers/pmdomain/rockchip/pm-domains.c
> +++ b/drivers/pmdomain/rockchip/pm-domains.c
> @@ -39,6 +39,7 @@
>   #include <dt-bindings/power/rockchip,rk3528-power.h>
>   #include <dt-bindings/power/rockchip,rk3562-power.h>
>   #include <dt-bindings/power/rk3568-power.h>
> +#include <dt-bindings/power/rockchip,rk3572-power-controller.h>
>   #include <dt-bindings/power/rockchip,rk3576-power.h>
>   #include <dt-bindings/power/rk3588-power.h>
>   
> @@ -59,6 +60,9 @@ struct rockchip_domain_info {
>   	u32 pwr_offset;
>   	u32 mem_offset;
>   	u32 req_offset;
> +	u32 status_offset;
> +	u32 firewall_mask;
> +	u32 clk_ungate_offset;
>   };
>   
>   struct rockchip_pmu_info {
> @@ -72,6 +76,8 @@ struct rockchip_pmu_info {
>   	u32 mem_status_offset;
>   	u32 repair_status_offset;
>   	u32 clk_ungate_offset;
> +	u32 firewall_status_offset;
> +	bool chain_status_inverted;
>   
please keep the abbreviation consistent with the other struct
members and use fw_mask / fw_status_offset instead of firewall_mask /
firewall_status_offset.
>   	u32 core_pwrcnt_offset;
>   	u32 gpu_pwrcnt_offset;
> @@ -90,6 +96,13 @@ struct rockchip_pmu_info {
>   #define QOS_SATURATION		0x14
>   #define QOS_EXTCONTROL		0x18
>   
> +enum rockchip_pd_power_state {
> +	ROCKCHIP_PD_IDLE,
> +	ROCKCHIP_PD_ON_HW,
> +	ROCKCHIP_PD_ON_RESTORE,
> +	ROCKCHIP_PD_OFF,
> +};
> +
>   struct rockchip_pm_domain {
>   	struct generic_pm_domain genpd;
>   	const struct rockchip_domain_info *info;
> @@ -101,11 +114,14 @@ struct rockchip_pm_domain {
>   	struct clk_bulk_data *clks;
>   	struct device_node *node;
>   	struct regulator *supply;
> +	enum rockchip_pd_power_state power_state;
> +	bool mem_reset_pending;
>   };
>   
>   struct rockchip_pmu {
>   	struct device *dev;
>   	struct regmap *regmap;
> +	struct regmap *grf;
>   	const struct rockchip_pmu_info *info;
>   	struct mutex mutex; /* mutex lock for pmu */
>   	struct genpd_onecell_data genpd_data;
> @@ -373,15 +389,16 @@ static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)
>   	const struct rockchip_domain_info *pd_info = pd->info;
>   	unsigned int val;
>   
> -	regmap_read(pmu->regmap, pmu->info->idle_offset, &val);
> +	regmap_read(pmu->regmap, pmu->info->idle_offset + pd_info->status_offset, &val);
>   	return (val & pd_info->idle_mask) == pd_info->idle_mask;
>   }
>   
> -static unsigned int rockchip_pmu_read_ack(struct rockchip_pmu *pmu)
> +static unsigned int rockchip_pmu_read_ack(struct rockchip_pm_domain *pd)
>   {
> +	struct rockchip_pmu *pmu = pd->pmu;
>   	unsigned int val;
>   
> -	regmap_read(pmu->regmap, pmu->info->ack_offset, &val);
> +	regmap_read(pmu->regmap, pmu->info->ack_offset + pd->info->status_offset, &val);
>   	return val;
>   }
>   
> @@ -400,7 +417,8 @@ static int rockchip_pmu_ungate_clk(struct rockchip_pm_domain *pd, bool ungate)
>   
>   	val = ungate ? (pd_info->clk_ungate_mask | clk_ungate_w_mask) :
>   			clk_ungate_w_mask;
> -	regmap_write(pmu->regmap, pmu->info->clk_ungate_offset, val);
> +	regmap_write(pmu->regmap, pmu->info->clk_ungate_offset +
> +		     pd_info->clk_ungate_offset, val);
>   
>   	return 0;
>   }
> @@ -431,7 +449,7 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
>   
>   	/* Wait util idle_ack = 1 */
>   	target_ack = idle ? pd_info->ack_mask : 0;
> -	ret = readx_poll_timeout_atomic(rockchip_pmu_read_ack, pmu, val,
> +	ret = readx_poll_timeout_atomic(rockchip_pmu_read_ack, pd, val,
>   					(val & pd_info->ack_mask) == target_ack,
>   					0, 10000);
>   	if (ret) {
> @@ -543,6 +561,9 @@ static bool rockchip_pmu_domain_is_chain_on(struct rockchip_pm_domain *pd)
>   	regmap_read(pmu->regmap,
>   		    pmu->info->chain_status_offset + pd->info->mem_offset, &val);
>   
> +	if (pmu->info->chain_status_inverted)
> +		return !(val & pd->info->mem_status_mask);
> +
>   	/* 1'b1: power on, 1'b0: power off */
>   	return val & pd->info->mem_status_mask;
>   }
> @@ -600,16 +621,13 @@ static int rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
>   	struct rockchip_pmu *pmu = pd->pmu;
>   	struct generic_pm_domain *genpd = &pd->genpd;
>   	u32 pd_pwr_offset = pd->info->pwr_offset;
> -	bool is_on, is_mem_on = false;
> +	bool is_on;
>   	struct arm_smccc_res res;
>   	int ret;
>   
>   	if (pd->info->pwr_mask == 0)
>   		return 0;
>   
> -	if (on && pd->info->mem_status_mask)
> -		is_mem_on = rockchip_pmu_domain_is_mem_on(pd);
> -
>   	if (pd->info->pwr_w_mask)
>   		regmap_write(pmu->regmap, pmu->info->pwr_offset + pd_pwr_offset,
>   			     on ? pd->info->pwr_w_mask :
> @@ -620,13 +638,13 @@ static int rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
>   
>   	wmb();
>   
> -	if (is_mem_on) {
> +	if (on && pd->mem_reset_pending) {
>   		ret = rockchip_pmu_domain_mem_reset(pd);
>   		if (ret)
>   			return ret;
> +		pd->mem_reset_pending = false;
>   	}
>   
> -
>   	ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_on, pd, is_on,
>   					is_on == on, 0, 10000);
>   	if (ret) {
> @@ -644,14 +662,29 @@ static int rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
>   	return 0;
>   }
>   
> +static int rockchip_pmu_wait_firewall(struct rockchip_pm_domain *pd)
> +{
> +	struct rockchip_pmu *pmu = pd->pmu;
> +	u32 mask = pd->info->firewall_mask;
> +	u32 val;
> +
> +	if (!mask)
> +		return 0;
> +
> +	return regmap_read_poll_timeout(pmu->grf, pmu->info->firewall_status_offset,
> +				       val, (val & mask) == mask, 0, 10000);
> +}
> +
>   static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
>   {
>   	struct rockchip_pmu *pmu = pd->pmu;
> +	bool is_on;
>   	int ret;
>   
>   	guard(mutex)(&pmu->mutex);
>   
> -	if (rockchip_pmu_domain_is_on(pd) == power_on)
> +	is_on = rockchip_pmu_domain_is_on(pd);
> +	if (is_on == power_on && pd->power_state == ROCKCHIP_PD_IDLE)
>   		return 0;
>   
>   	ret = clk_bulk_enable(pd->num_clks, pd->clks);
> @@ -662,18 +695,38 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
>   
>   	rockchip_pmu_ungate_clk(pd, true);
>   
> -	if (!power_on) {
> -		rockchip_pmu_save_qos(pd);
> +	if (power_on) {
> +		if (pd->power_state == ROCKCHIP_PD_IDLE ||
> +		    pd->power_state == ROCKCHIP_PD_OFF ||
> +		    (pd->power_state == ROCKCHIP_PD_ON_RESTORE && !is_on)) {
> +			/* A failed reset may still be forcing memory off. */
> +			pd->mem_reset_pending |= pd->info->mem_status_mask &&
> +				rockchip_pmu_domain_is_mem_on(pd);
> +			pd->power_state = ROCKCHIP_PD_ON_HW;
> +		}
> +
> +		/* A status bit alone does not prove the low-level sequence finished. */
> +		if (pd->power_state == ROCKCHIP_PD_ON_HW) {
> +			ret = rockchip_do_pmu_set_power_domain(pd, true);
> +			if (ret < 0)
> +				goto out;
> +			pd->power_state = ROCKCHIP_PD_ON_RESTORE;
> +		}
> +	} else {
> +		if (pd->power_state == ROCKCHIP_PD_IDLE)
> +			rockchip_pmu_save_qos(pd);
> +		pd->power_state = ROCKCHIP_PD_OFF;
>   
>   		/* if powering down, idle request to NIU first */
>   		ret = rockchip_pmu_set_idle_request(pd, true);
>   		if (ret < 0)
>   			goto out;
> -	}
>   
> -	ret = rockchip_do_pmu_set_power_domain(pd, power_on);
> -	if (ret < 0)
> -		goto out;
> +		/* Cancel a pending power-on even if its status is still off. */
> +		ret = rockchip_do_pmu_set_power_domain(pd, false);
> +		if (ret < 0)
> +			goto out;
> +	}
>   
>   	if (power_on) {
>   		/* if powering up, leave idle mode */
> @@ -681,8 +734,14 @@ static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
>   		if (ret < 0)
>   			goto out;
>   
> +		ret = rockchip_pmu_wait_firewall(pd);
> +		if (ret)
> +			goto out;
> +
>   		rockchip_pmu_restore_qos(pd);
> +		pd->mem_reset_pending = false;
>   	}
> +	pd->power_state = ROCKCHIP_PD_IDLE;
>   
>   out:
>   	rockchip_pmu_ungate_clk(pd, false);
> @@ -733,11 +792,18 @@ static int rockchip_pd_power_on(struct generic_pm_domain *domain)
>   static int rockchip_pd_power_off(struct generic_pm_domain *domain)
>   {
>   	struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
> -	int ret;
> +	int ret, err;
>   
>   	ret = rockchip_pd_power(pd, false);
> -	if (ret)
> +	if (ret) {
> +		/* genpd still considers the domain on after a failed power-off. */
> +		err = rockchip_pd_power(pd, true);
> +		if (err)
> +			dev_err(pd->pmu->dev,
> +				"failed to restore domain '%s' after power-off failure: %d\n",
> +				domain->name, err);
>   		return ret;
> +	}

The changes to rockchip_pd_power()/rockchip_pd_power_off() (the
power_state state machine, mem_reset_pending, and the restore after
a failed power-off) are generic rework of the shared power path;
they are not required for basic RK3572 support and they affect all
the other SoCs. Please split them out of this series.


>   
>   	rockchip_pd_regulator_disable(pd);
>   	return ret;
> @@ -1064,6 +1130,11 @@ static int rockchip_pm_domain_probe(struct platform_device *pdev)
>   	mutex_init(&pmu->mutex);
>   
>   	pmu->info = pmu_info;
> +	if (pmu_info->firewall_status_offset) {
> +		pmu->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
> +		if (IS_ERR(pmu->grf))
> +			return dev_err_probe(dev, PTR_ERR(pmu->grf), "failed to get system GRF\n");
> +	}
>   
>   	pmu->genpd_data.domains = pmu->domains;
>   	pmu->genpd_data.num_domains = pmu_info->num_domains;
> @@ -1313,6 +1384,62 @@ static const struct rockchip_domain_info rk3568_pm_domains[] = {
>   	[RK3568_PD_PIPE]	= DOMAIN_RK3568("pipe", BIT(8), BIT(11), false, false),
>   };
>   
> +static const struct rockchip_domain_info rk3572_pm_domains[] = {
> +	[RK3572_PD_NVM1] = {
> +		.name = "nvm1",
> +		.pwr_mask = BIT(4),
> +		.pwr_w_mask = BIT(20),
> +		.mem_status_mask = BIT(4),
> +		.repair_status_mask = BIT(3),
> +		.req_mask = BIT(6),
> +		.req_w_mask = BIT(22),
> +		.idle_mask = BIT(6),
> +		.ack_mask = BIT(6),
> +		.clk_ungate_mask = BIT(6),
> +	},
> +	[RK3572_PD_PHP] = {
> +		.name = "php",
> +		.pwr_mask = BIT(7),
> +		.pwr_w_mask = BIT(23),
> +		.mem_status_mask = BIT(7),
> +		.repair_status_mask = BIT(5),
> +		.req_mask = BIT(9),
> +		.req_w_mask = BIT(25),
> +		.idle_mask = BIT(9),
> +		.ack_mask = BIT(9),
> +		.clk_ungate_mask = BIT(9),
> +		.firewall_mask = BIT(28),
> +	},
> +	[RK3572_PD_VOP] = {
> +		.name = "vop",
> +		.pwr_mask = BIT(12),
> +		.pwr_w_mask = BIT(28),
> +		.mem_status_mask = BIT(12),
> +		.repair_status_mask = BIT(10),
> +		.req_mask = BIT(14),
> +		.req_w_mask = BIT(30),
> +		.idle_mask = BIT(14),
> +		.ack_mask = BIT(14),
> +		.clk_ungate_mask = BIT(14),
> +		.firewall_mask = BIT(23),
> +	},
> +	[RK3572_PD_NVM0] = {
> +		.name = "nvm0",
> +		.pwr_mask = BIT(15),
> +		.pwr_w_mask = BIT(31),
> +		.mem_status_mask = BIT(15),
> +		.repair_status_mask = BIT(13),
> +		.req_mask = BIT(0),
> +		.req_w_mask = BIT(16),
> +		.idle_mask = BIT(0),
> +		.ack_mask = BIT(0),
> +		.clk_ungate_mask = BIT(0),
> +		.req_offset = 4,
> +		.status_offset = 4,
> +		.clk_ungate_offset = 4,
> +	},
> +};
1. Only 4 of the 14 domains are added here. The internal implementation
    covers npu, gpu, nvm0, nvm1, dsmc, php, audio, img, vdec, vi, venc,
    vo, vop and vop_pre. Please add the remaining domains.

    Note that the npu domain also needs the voltage-domain handshake from
    the internal code (vd_offset = 0x220, per-domain vd_en and a
    rockchip_pmu_vd_on() call before powering on the domain), so either
    include that support as well, or leave out npu until it is ready.

2. Please use a DOMAIN_RK3572 macro like the other SoCs in this
    driver (see DOMAIN_RK3576).
> +
>   static const struct rockchip_domain_info rk3576_pm_domains[] = {
>   	[RK3576_PD_NPU]		= DOMAIN_RK3576("npu",    0x0, BIT(0),  BIT(0), 0,       0x0, 0,       0,       0,       false),
>   	[RK3576_PD_NVM]		= DOMAIN_RK3576("nvm",    0x0, BIT(6),  0,      BIT(6),  0x4, BIT(2),  BIT(18), BIT(2),  false),
> @@ -1536,6 +1663,23 @@ static const struct rockchip_pmu_info rk3568_pmu = {
>   	.domain_info = rk3568_pm_domains,
>   };
>   
> +static const struct rockchip_pmu_info rk3572_pmu = {
> +	.pwr_offset = 0x210,
> +	.status_offset = 0x230,
> +	.chain_status_offset = 0x250,
> +	.chain_status_inverted = true,
> +	.mem_status_offset = 0x260,
> +	.mem_pwr_offset = 0x300,
> +	.req_offset = 0x110,
> +	.idle_offset = 0x130,
> +	.ack_offset = 0x120,
> +	.repair_status_offset = 0x570,
> +	.clk_ungate_offset = 0x150,
> +	.firewall_status_offset = 0x140,
> +	.num_domains = ARRAY_SIZE(rk3572_pm_domains),
> +	.domain_info = rk3572_pm_domains,
> +};
> +
>   static const struct rockchip_pmu_info rk3576_pmu = {
>   	.pwr_offset = 0x210,
>   	.status_offset = 0x230,
> @@ -1648,6 +1792,9 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = {
>   		.data = (void *)&rk3568_pmu,
>   	},
>   	{
> +		.compatible = "rockchip,rk3572-power-controller",
> +		.data = &rk3572_pmu,
> +	}, {
>   		.compatible = "rockchip,rk3576-power-controller",
>   		.data = (void *)&rk3576_pmu,
>   	},
>
-- 
Best regards,

底层平台中心 肖锋(Finley Xiao)
************************************************************************************
瑞芯微电子股份有限公司
Rockchip Electronics Co., Ltd.
福建省福州市铜盘路软件大道89号软件园A区21号楼 350003
No.21 Building, A District, Fuzhou Software Park, Fuzhou, Fujian 350003, P.R. China
Tel: 0591-83991906-8602 Mobile: 18506057603
************************************************************************************



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

* Re: [PATCH v3 2/2] pmdomain: rockchip: Add RK3572 boot peripheral domains
  2026-10-26  8:47   ` Finley Xiao
@ 2026-10-26 11:37     ` Finley Xiao
  2026-10-26 11:53       ` Heiko Stuebner
  0 siblings, 1 reply; 7+ messages in thread
From: Finley Xiao @ 2026-10-26 11:37 UTC (permalink / raw)
  To: 1579567540, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Heiko Stuebner, Elaine Zhang, Ulf Hansson
  Cc: devicetree, linux-arm-kernel, linux-rockchip, linux-kernel,
	linux-pm


在 2026/10/26 16:47, Finley Xiao 写道:
>
> 在 2026/10/26 11:21, Cunhao Lu via B4 Relay 写道:
>> From: Finley Xiao <finley.xiao@rock-chips.com>
>>
>> Add support for the RK3572 NVM0, NVM1, PHP, and VOP power domains.
>>
>> Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>

I have to point out that the changes (the shutdown/restore
rework, pending-state tracking, etc.) were not made by me, and I have
not reviewed them in detail. Therefore, I should not remain as the
author (From:) of this patch, nor should my Signed-off-by be kept on
it.


>>
>> - Returned firmware shift-ready wait errors to callers.
>> - Kept the domain pending after a firmware shift-ready wait failure.
>> - Retried power-on without repeating completed memory resets.
>> - Recorded low-level power-on and restoration stages before hardware
>>    operations so retries complete unfinished low-level work.
>> - Kept memory resets pending across failures, including when memory 
>> is off.
>> - Preserved QoS snapshots after a failed power-on and cleared progress
>>    after successful power-on or shutdown.
>> - Tracked incomplete shutdowns to preserve QoS and complete firmware 
>> updates.
>> - Preserved pending memory resets across shutdown and cancelled 
>> unfinished
>>    power-on requests.
>> - Attempt to restore the domain after power-off errors, while preserving
>>    the original error returned to genpd.
>>
>> Co-developed-by: Cunhao Lu <1579567540@qq.com>
>> Signed-off-by: Cunhao Lu <1579567540@qq.com>
>> ---
>> Changes in v3:
>> - Track incomplete shutdowns to preserve QoS and complete firmware 
>> updates.
>> - Preserve pending memory resets across shutdown and cancel unfinished
>>    power-on requests.
>> - Attempt to restore the domain after power-off errors, while preserving
>>    the original error returned to genpd.
>>
>> Changes in v2:
>> - Record low-level power-on and restoration stages before hardware
>>    operations, so a retry cannot skip unfinished low-level work.
>> - Retain pending memory resets even if memory is off on retry, and
>>    avoid repeating completed resets during restoration.
>> - Preserve QoS snapshots across failed power-on and shutdown; clear
>>    progress after successful power-on or shutdown.
>> ---
>>   drivers/pmdomain/rockchip/pm-domains.c | 187 
>> +++++++++++++++++++++++++++++----
>>   1 file changed, 167 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/pmdomain/rockchip/pm-domains.c 
>> b/drivers/pmdomain/rockchip/pm-domains.c
>> index e193f978d5f3..668d208dea55 100644
>> --- a/drivers/pmdomain/rockchip/pm-domains.c
>> +++ b/drivers/pmdomain/rockchip/pm-domains.c
>> @@ -39,6 +39,7 @@
>>   #include <dt-bindings/power/rockchip,rk3528-power.h>
>>   #include <dt-bindings/power/rockchip,rk3562-power.h>
>>   #include <dt-bindings/power/rk3568-power.h>
>> +#include <dt-bindings/power/rockchip,rk3572-power-controller.h>
>>   #include <dt-bindings/power/rockchip,rk3576-power.h>
>>   #include <dt-bindings/power/rk3588-power.h>
>>   @@ -59,6 +60,9 @@ struct rockchip_domain_info {
>>       u32 pwr_offset;
>>       u32 mem_offset;
>>       u32 req_offset;
>> +    u32 status_offset;
>> +    u32 firewall_mask;
>> +    u32 clk_ungate_offset;
>>   };
>>     struct rockchip_pmu_info {
>> @@ -72,6 +76,8 @@ struct rockchip_pmu_info {
>>       u32 mem_status_offset;
>>       u32 repair_status_offset;
>>       u32 clk_ungate_offset;
>> +    u32 firewall_status_offset;
>> +    bool chain_status_inverted;
> please keep the abbreviation consistent with the other struct
> members and use fw_mask / fw_status_offset instead of firewall_mask /
> firewall_status_offset.
>>       u32 core_pwrcnt_offset;
>>       u32 gpu_pwrcnt_offset;
>> @@ -90,6 +96,13 @@ struct rockchip_pmu_info {
>>   #define QOS_SATURATION        0x14
>>   #define QOS_EXTCONTROL        0x18
>>   +enum rockchip_pd_power_state {
>> +    ROCKCHIP_PD_IDLE,
>> +    ROCKCHIP_PD_ON_HW,
>> +    ROCKCHIP_PD_ON_RESTORE,
>> +    ROCKCHIP_PD_OFF,
>> +};
>> +
>>   struct rockchip_pm_domain {
>>       struct generic_pm_domain genpd;
>>       const struct rockchip_domain_info *info;
>> @@ -101,11 +114,14 @@ struct rockchip_pm_domain {
>>       struct clk_bulk_data *clks;
>>       struct device_node *node;
>>       struct regulator *supply;
>> +    enum rockchip_pd_power_state power_state;
>> +    bool mem_reset_pending;
>>   };
>>     struct rockchip_pmu {
>>       struct device *dev;
>>       struct regmap *regmap;
>> +    struct regmap *grf;
>>       const struct rockchip_pmu_info *info;
>>       struct mutex mutex; /* mutex lock for pmu */
>>       struct genpd_onecell_data genpd_data;
>> @@ -373,15 +389,16 @@ static bool rockchip_pmu_domain_is_idle(struct 
>> rockchip_pm_domain *pd)
>>       const struct rockchip_domain_info *pd_info = pd->info;
>>       unsigned int val;
>>   -    regmap_read(pmu->regmap, pmu->info->idle_offset, &val);
>> +    regmap_read(pmu->regmap, pmu->info->idle_offset + 
>> pd_info->status_offset, &val);
>>       return (val & pd_info->idle_mask) == pd_info->idle_mask;
>>   }
>>   -static unsigned int rockchip_pmu_read_ack(struct rockchip_pmu *pmu)
>> +static unsigned int rockchip_pmu_read_ack(struct rockchip_pm_domain 
>> *pd)
>>   {
>> +    struct rockchip_pmu *pmu = pd->pmu;
>>       unsigned int val;
>>   -    regmap_read(pmu->regmap, pmu->info->ack_offset, &val);
>> +    regmap_read(pmu->regmap, pmu->info->ack_offset + 
>> pd->info->status_offset, &val);
>>       return val;
>>   }
>>   @@ -400,7 +417,8 @@ static int rockchip_pmu_ungate_clk(struct 
>> rockchip_pm_domain *pd, bool ungate)
>>         val = ungate ? (pd_info->clk_ungate_mask | clk_ungate_w_mask) :
>>               clk_ungate_w_mask;
>> -    regmap_write(pmu->regmap, pmu->info->clk_ungate_offset, val);
>> +    regmap_write(pmu->regmap, pmu->info->clk_ungate_offset +
>> +             pd_info->clk_ungate_offset, val);
>>         return 0;
>>   }
>> @@ -431,7 +449,7 @@ static int rockchip_pmu_set_idle_request(struct 
>> rockchip_pm_domain *pd,
>>         /* Wait util idle_ack = 1 */
>>       target_ack = idle ? pd_info->ack_mask : 0;
>> -    ret = readx_poll_timeout_atomic(rockchip_pmu_read_ack, pmu, val,
>> +    ret = readx_poll_timeout_atomic(rockchip_pmu_read_ack, pd, val,
>>                       (val & pd_info->ack_mask) == target_ack,
>>                       0, 10000);
>>       if (ret) {
>> @@ -543,6 +561,9 @@ static bool 
>> rockchip_pmu_domain_is_chain_on(struct rockchip_pm_domain *pd)
>>       regmap_read(pmu->regmap,
>>               pmu->info->chain_status_offset + pd->info->mem_offset, 
>> &val);
>>   +    if (pmu->info->chain_status_inverted)
>> +        return !(val & pd->info->mem_status_mask);
>> +
>>       /* 1'b1: power on, 1'b0: power off */
>>       return val & pd->info->mem_status_mask;
>>   }
>> @@ -600,16 +621,13 @@ static int 
>> rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
>>       struct rockchip_pmu *pmu = pd->pmu;
>>       struct generic_pm_domain *genpd = &pd->genpd;
>>       u32 pd_pwr_offset = pd->info->pwr_offset;
>> -    bool is_on, is_mem_on = false;
>> +    bool is_on;
>>       struct arm_smccc_res res;
>>       int ret;
>>         if (pd->info->pwr_mask == 0)
>>           return 0;
>>   -    if (on && pd->info->mem_status_mask)
>> -        is_mem_on = rockchip_pmu_domain_is_mem_on(pd);
>> -
>>       if (pd->info->pwr_w_mask)
>>           regmap_write(pmu->regmap, pmu->info->pwr_offset + 
>> pd_pwr_offset,
>>                    on ? pd->info->pwr_w_mask :
>> @@ -620,13 +638,13 @@ static int 
>> rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
>>         wmb();
>>   -    if (is_mem_on) {
>> +    if (on && pd->mem_reset_pending) {
>>           ret = rockchip_pmu_domain_mem_reset(pd);
>>           if (ret)
>>               return ret;
>> +        pd->mem_reset_pending = false;
>>       }
>>   -
>>       ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_on, pd, 
>> is_on,
>>                       is_on == on, 0, 10000);
>>       if (ret) {
>> @@ -644,14 +662,29 @@ static int 
>> rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
>>       return 0;
>>   }
>>   +static int rockchip_pmu_wait_firewall(struct rockchip_pm_domain *pd)
>> +{
>> +    struct rockchip_pmu *pmu = pd->pmu;
>> +    u32 mask = pd->info->firewall_mask;
>> +    u32 val;
>> +
>> +    if (!mask)
>> +        return 0;
>> +
>> +    return regmap_read_poll_timeout(pmu->grf, 
>> pmu->info->firewall_status_offset,
>> +                       val, (val & mask) == mask, 0, 10000);
>> +}
>> +
>>   static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool 
>> power_on)
>>   {
>>       struct rockchip_pmu *pmu = pd->pmu;
>> +    bool is_on;
>>       int ret;
>>         guard(mutex)(&pmu->mutex);
>>   -    if (rockchip_pmu_domain_is_on(pd) == power_on)
>> +    is_on = rockchip_pmu_domain_is_on(pd);
>> +    if (is_on == power_on && pd->power_state == ROCKCHIP_PD_IDLE)
>>           return 0;
>>         ret = clk_bulk_enable(pd->num_clks, pd->clks);
>> @@ -662,18 +695,38 @@ static int rockchip_pd_power(struct 
>> rockchip_pm_domain *pd, bool power_on)
>>         rockchip_pmu_ungate_clk(pd, true);
>>   -    if (!power_on) {
>> -        rockchip_pmu_save_qos(pd);
>> +    if (power_on) {
>> +        if (pd->power_state == ROCKCHIP_PD_IDLE ||
>> +            pd->power_state == ROCKCHIP_PD_OFF ||
>> +            (pd->power_state == ROCKCHIP_PD_ON_RESTORE && !is_on)) {
>> +            /* A failed reset may still be forcing memory off. */
>> +            pd->mem_reset_pending |= pd->info->mem_status_mask &&
>> +                rockchip_pmu_domain_is_mem_on(pd);
>> +            pd->power_state = ROCKCHIP_PD_ON_HW;
>> +        }
>> +
>> +        /* A status bit alone does not prove the low-level sequence 
>> finished. */
>> +        if (pd->power_state == ROCKCHIP_PD_ON_HW) {
>> +            ret = rockchip_do_pmu_set_power_domain(pd, true);
>> +            if (ret < 0)
>> +                goto out;
>> +            pd->power_state = ROCKCHIP_PD_ON_RESTORE;
>> +        }
>> +    } else {
>> +        if (pd->power_state == ROCKCHIP_PD_IDLE)
>> +            rockchip_pmu_save_qos(pd);
>> +        pd->power_state = ROCKCHIP_PD_OFF;
>>             /* if powering down, idle request to NIU first */
>>           ret = rockchip_pmu_set_idle_request(pd, true);
>>           if (ret < 0)
>>               goto out;
>> -    }
>>   -    ret = rockchip_do_pmu_set_power_domain(pd, power_on);
>> -    if (ret < 0)
>> -        goto out;
>> +        /* Cancel a pending power-on even if its status is still 
>> off. */
>> +        ret = rockchip_do_pmu_set_power_domain(pd, false);
>> +        if (ret < 0)
>> +            goto out;
>> +    }
>>         if (power_on) {
>>           /* if powering up, leave idle mode */
>> @@ -681,8 +734,14 @@ static int rockchip_pd_power(struct 
>> rockchip_pm_domain *pd, bool power_on)
>>           if (ret < 0)
>>               goto out;
>>   +        ret = rockchip_pmu_wait_firewall(pd);
>> +        if (ret)
>> +            goto out;
>> +
>>           rockchip_pmu_restore_qos(pd);
>> +        pd->mem_reset_pending = false;
>>       }
>> +    pd->power_state = ROCKCHIP_PD_IDLE;
>>     out:
>>       rockchip_pmu_ungate_clk(pd, false);
>> @@ -733,11 +792,18 @@ static int rockchip_pd_power_on(struct 
>> generic_pm_domain *domain)
>>   static int rockchip_pd_power_off(struct generic_pm_domain *domain)
>>   {
>>       struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
>> -    int ret;
>> +    int ret, err;
>>         ret = rockchip_pd_power(pd, false);
>> -    if (ret)
>> +    if (ret) {
>> +        /* genpd still considers the domain on after a failed 
>> power-off. */
>> +        err = rockchip_pd_power(pd, true);
>> +        if (err)
>> +            dev_err(pd->pmu->dev,
>> +                "failed to restore domain '%s' after power-off 
>> failure: %d\n",
>> +                domain->name, err);
>>           return ret;
>> +    }
>
> The changes to rockchip_pd_power()/rockchip_pd_power_off() (the
> power_state state machine, mem_reset_pending, and the restore after
> a failed power-off) are generic rework of the shared power path;
> they are not required for basic RK3572 support and they affect all
> the other SoCs. Please split them out of this series.
>
>
>>         rockchip_pd_regulator_disable(pd);
>>       return ret;
>> @@ -1064,6 +1130,11 @@ static int rockchip_pm_domain_probe(struct 
>> platform_device *pdev)
>>       mutex_init(&pmu->mutex);
>>         pmu->info = pmu_info;
>> +    if (pmu_info->firewall_status_offset) {
>> +        pmu->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
>> +        if (IS_ERR(pmu->grf))
>> +            return dev_err_probe(dev, PTR_ERR(pmu->grf), "failed to 
>> get system GRF\n");
>> +    }
>>         pmu->genpd_data.domains = pmu->domains;
>>       pmu->genpd_data.num_domains = pmu_info->num_domains;
>> @@ -1313,6 +1384,62 @@ static const struct rockchip_domain_info 
>> rk3568_pm_domains[] = {
>>       [RK3568_PD_PIPE]    = DOMAIN_RK3568("pipe", BIT(8), BIT(11), 
>> false, false),
>>   };
>>   +static const struct rockchip_domain_info rk3572_pm_domains[] = {
>> +    [RK3572_PD_NVM1] = {
>> +        .name = "nvm1",
>> +        .pwr_mask = BIT(4),
>> +        .pwr_w_mask = BIT(20),
>> +        .mem_status_mask = BIT(4),
>> +        .repair_status_mask = BIT(3),
>> +        .req_mask = BIT(6),
>> +        .req_w_mask = BIT(22),
>> +        .idle_mask = BIT(6),
>> +        .ack_mask = BIT(6),
>> +        .clk_ungate_mask = BIT(6),
>> +    },
>> +    [RK3572_PD_PHP] = {
>> +        .name = "php",
>> +        .pwr_mask = BIT(7),
>> +        .pwr_w_mask = BIT(23),
>> +        .mem_status_mask = BIT(7),
>> +        .repair_status_mask = BIT(5),
>> +        .req_mask = BIT(9),
>> +        .req_w_mask = BIT(25),
>> +        .idle_mask = BIT(9),
>> +        .ack_mask = BIT(9),
>> +        .clk_ungate_mask = BIT(9),
>> +        .firewall_mask = BIT(28),
>> +    },
>> +    [RK3572_PD_VOP] = {
>> +        .name = "vop",
>> +        .pwr_mask = BIT(12),
>> +        .pwr_w_mask = BIT(28),
>> +        .mem_status_mask = BIT(12),
>> +        .repair_status_mask = BIT(10),
>> +        .req_mask = BIT(14),
>> +        .req_w_mask = BIT(30),
>> +        .idle_mask = BIT(14),
>> +        .ack_mask = BIT(14),
>> +        .clk_ungate_mask = BIT(14),
>> +        .firewall_mask = BIT(23),
>> +    },
>> +    [RK3572_PD_NVM0] = {
>> +        .name = "nvm0",
>> +        .pwr_mask = BIT(15),
>> +        .pwr_w_mask = BIT(31),
>> +        .mem_status_mask = BIT(15),
>> +        .repair_status_mask = BIT(13),
>> +        .req_mask = BIT(0),
>> +        .req_w_mask = BIT(16),
>> +        .idle_mask = BIT(0),
>> +        .ack_mask = BIT(0),
>> +        .clk_ungate_mask = BIT(0),
>> +        .req_offset = 4,
>> +        .status_offset = 4,
>> +        .clk_ungate_offset = 4,
>> +    },
>> +};
> 1. Only 4 of the 14 domains are added here. The internal implementation
>    covers npu, gpu, nvm0, nvm1, dsmc, php, audio, img, vdec, vi, venc,
>    vo, vop and vop_pre. Please add the remaining domains.
>
>    Note that the npu domain also needs the voltage-domain handshake from
>    the internal code (vd_offset = 0x220, per-domain vd_en and a
>    rockchip_pmu_vd_on() call before powering on the domain), so either
>    include that support as well, or leave out npu until it is ready.
>
> 2. Please use a DOMAIN_RK3572 macro like the other SoCs in this
>    driver (see DOMAIN_RK3576).
>> +
>>   static const struct rockchip_domain_info rk3576_pm_domains[] = {
>>       [RK3576_PD_NPU]        = DOMAIN_RK3576("npu",    0x0, BIT(0),  
>> BIT(0), 0,       0x0, 0,       0,       0, false),
>>       [RK3576_PD_NVM]        = DOMAIN_RK3576("nvm",    0x0, BIT(6),  
>> 0,      BIT(6),  0x4, BIT(2),  BIT(18), BIT(2), false),
>> @@ -1536,6 +1663,23 @@ static const struct rockchip_pmu_info 
>> rk3568_pmu = {
>>       .domain_info = rk3568_pm_domains,
>>   };
>>   +static const struct rockchip_pmu_info rk3572_pmu = {
>> +    .pwr_offset = 0x210,
>> +    .status_offset = 0x230,
>> +    .chain_status_offset = 0x250,
>> +    .chain_status_inverted = true,
>> +    .mem_status_offset = 0x260,
>> +    .mem_pwr_offset = 0x300,
>> +    .req_offset = 0x110,
>> +    .idle_offset = 0x130,
>> +    .ack_offset = 0x120,
>> +    .repair_status_offset = 0x570,
>> +    .clk_ungate_offset = 0x150,
>> +    .firewall_status_offset = 0x140,
>> +    .num_domains = ARRAY_SIZE(rk3572_pm_domains),
>> +    .domain_info = rk3572_pm_domains,
>> +};
>> +
>>   static const struct rockchip_pmu_info rk3576_pmu = {
>>       .pwr_offset = 0x210,
>>       .status_offset = 0x230,
>> @@ -1648,6 +1792,9 @@ static const struct of_device_id 
>> rockchip_pm_domain_dt_match[] = {
>>           .data = (void *)&rk3568_pmu,
>>       },
>>       {
>> +        .compatible = "rockchip,rk3572-power-controller",
>> +        .data = &rk3572_pmu,
>> +    }, {
>>           .compatible = "rockchip,rk3576-power-controller",
>>           .data = (void *)&rk3576_pmu,
>>       },
>>
-- 
Best regards,

底层平台中心 肖锋(Finley Xiao)
************************************************************************************
瑞芯微电子股份有限公司
Rockchip Electronics Co., Ltd.
福建省福州市铜盘路软件大道89号软件园A区21号楼 350003
No.21 Building, A District, Fuzhou Software Park, Fuzhou, Fujian 350003, P.R. China
Tel: 0591-83991906-8602 Mobile: 18506057603
************************************************************************************



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

* Re: [PATCH v3 2/2] pmdomain: rockchip: Add RK3572 boot peripheral domains
  2026-10-26 11:37     ` Finley Xiao
@ 2026-10-26 11:53       ` Heiko Stuebner
  2026-10-27  1:10         ` Finley Xiao
  0 siblings, 1 reply; 7+ messages in thread
From: Heiko Stuebner @ 2026-10-26 11:53 UTC (permalink / raw)
  To: 1579567540, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Elaine Zhang, Ulf Hansson, Finley Xiao
  Cc: devicetree, linux-arm-kernel, linux-rockchip, linux-kernel,
	linux-pm

Hi Finley,

Am Montag, 26. Oktober 2026, 12:37:06 Mitteleuropäische Normalzeit schrieb Finley Xiao:
> 
> 在 2026/10/26 16:47, Finley Xiao 写道:
> >
> > 在 2026/10/26 11:21, Cunhao Lu via B4 Relay 写道:
> >> From: Finley Xiao <finley.xiao@rock-chips.com>
> >>
> >> Add support for the RK3572 NVM0, NVM1, PHP, and VOP power domains.
> >>
> >> Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
> 
> I have to point out that the changes (the shutdown/restore
> rework, pending-state tracking, etc.) were not made by me, and I have
> not reviewed them in detail. Therefore, I should not remain as the
> author (From:) of this patch, nor should my Signed-off-by be kept on
> it.

As this seemingly comes from the vendor-tree, _some_ Rockchip authorship
should be kept I think?

Do you have a suggestion who that should be other than you? :-)

I guess as you suggested splitting this anyway, that authorship
could also be split.


Thanks
Heiko






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

* Re: [PATCH v3 2/2] pmdomain: rockchip: Add RK3572 boot peripheral domains
  2026-10-26 11:53       ` Heiko Stuebner
@ 2026-10-27  1:10         ` Finley Xiao
  0 siblings, 0 replies; 7+ messages in thread
From: Finley Xiao @ 2026-10-27  1:10 UTC (permalink / raw)
  To: Heiko Stuebner, 1579567540, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Elaine Zhang, Ulf Hansson
  Cc: devicetree, linux-arm-kernel, linux-rockchip, linux-kernel,
	linux-pm


在 2026/10/26 19:53, Heiko Stuebner 写道:
> Hi Finley,
>
> Am Montag, 26. Oktober 2026, 12:37:06 Mitteleuropäische Normalzeit schrieb Finley Xiao:
>> 在 2026/10/26 16:47, Finley Xiao 写道:
>>> 在 2026/10/26 11:21, Cunhao Lu via B4 Relay 写道:
>>>> From: Finley Xiao <finley.xiao@rock-chips.com>
>>>>
>>>> Add support for the RK3572 NVM0, NVM1, PHP, and VOP power domains.
>>>>
>>>> Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
>> I have to point out that the changes (the shutdown/restore
>> rework, pending-state tracking, etc.) were not made by me, and I have
>> not reviewed them in detail. Therefore, I should not remain as the
>> author (From:) of this patch, nor should my Signed-off-by be kept on
>> it.
> As this seemingly comes from the vendor-tree, _some_ Rockchip authorship
> should be kept I think?
>
> Do you have a suggestion who that should be other than you? :-)
We have never carried code like this, and the other parts also
differ significantly from the Rockchip kernel. It does not appear
to be our original code.
>
> I guess as you suggested splitting this anyway, that authorship
> could also be split.
>
>
> Thanks
> Heiko

-- 
Best regards,

底层平台中心 肖锋(Finley Xiao)
************************************************************************************
瑞芯微电子股份有限公司
Rockchip Electronics Co., Ltd.
福建省福州市铜盘路软件大道89号软件园A区21号楼 350003
No.21 Building, A District, Fuzhou Software Park, Fuzhou, Fujian 350003, P.R. China
Tel: 0591-83991906-8602 Mobile: 18506057603
************************************************************************************



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

end of thread, other threads:[~2026-10-27  1:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-26  3:21 [PATCH v3 0/2] pmdomain: rockchip: Add RK3572 boot peripheral domains Cunhao Lu via B4 Relay
2026-10-26  3:21 ` [PATCH v3 1/2] dt-bindings: power: rockchip: Add RK3572 power domains Cunhao Lu via B4 Relay
2026-10-26  3:21 ` [PATCH v3 2/2] pmdomain: rockchip: Add RK3572 boot peripheral domains Cunhao Lu via B4 Relay
2026-10-26  8:47   ` Finley Xiao
2026-10-26 11:37     ` Finley Xiao
2026-10-26 11:53       ` Heiko Stuebner
2026-10-27  1:10         ` Finley Xiao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox