Skip to content

Commit 2a2274e

Browse files
committed
Merge tag 'pmdomain-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm
Pull pmdomain updates from Ulf Hansson: "pmdomain core: - Add dev_pm_genpd_rpm_always_on() to support more fine-grained PM pmdomain providers: - arm: Remove redundant state verification for the SCMI PM domain - bcm: Add system-wakeup support for bcm2835 via GENPD_FLAG_ACTIVE_WAKEUP - rockchip: Add support for regulators - rockchip: Use SMC call to properly inform firmware - sunxi: Add V853 ppu support - thead: Add support for RISC-V TH1520 power-domains firmware: - Add support for the AON firmware protocol for RISC-V THEAD cpuidle-psci: - Update section in MAINTAINERS for cpuidle-psci - Add trace support for PSCI domain-idlestates" * tag 'pmdomain-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm: (29 commits) firmware: thead: add CONFIG_MAILBOX dependency firmware: thead,th1520-aon: Fix use after free in th1520_aon_init() pmdomain: arm: scmi_pm_domain: Remove redundant state verification pmdomain: thead: fix TH1520_AON_PROTOCOL dependency pmdomain: thead: Add power-domain driver for TH1520 dt-bindings: power: Add TH1520 SoC power domains firmware: thead: Add AON firmware protocol driver dt-bindings: firmware: thead,th1520: Add support for firmware node pmdomain: rockchip: add regulator dependency pmdomain: rockchip: add regulator support pmdomain: rockchip: fix rockchip_pd_power error handling pmdomain: rockchip: reduce indentation in rockchip_pd_power pmdomain: rockchip: forward rockchip_do_pmu_set_power_domain errors pmdomain: rockchip: cleanup mutex handling in rockchip_pd_power dt-bindings: power: rockchip: add regulator support pmdomain: rockchip: Fix build error pmdomain: imx: gpcv2: use proper helper for property detection MAINTAINERS: Update section for cpuidle-psci pmdomain: rockchip: Check if SMC could be handled by TA cpuidle: psci: Add trace for PSCI domain idle ...
2 parents 0163c88 + 51f0b89 commit 2a2274e

File tree

29 files changed

+1032
-83
lines changed

29 files changed

+1032
-83
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/firmware/thead,th1520-aon.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: T-HEAD TH1520 AON (Always-On) Firmware
8+
9+
description: |
10+
The Always-On (AON) subsystem in the TH1520 SoC is responsible for managing
11+
low-power states, system wakeup events, and power management tasks. It is
12+
designed to operate independently in a dedicated power domain, allowing it to
13+
remain functional even during the SoC's deep sleep states.
14+
15+
At the heart of the AON subsystem is the E902, a low-power core that executes
16+
firmware responsible for coordinating tasks such as power domain control,
17+
clock management, and system wakeup signaling. Communication between the main
18+
SoC and the AON subsystem is handled through a mailbox interface, which
19+
enables message-based interactions with the AON firmware.
20+
21+
maintainers:
22+
- Michal Wilczynski <m.wilczynski@samsung.com>
23+
24+
properties:
25+
compatible:
26+
const: thead,th1520-aon
27+
28+
mboxes:
29+
maxItems: 1
30+
31+
mbox-names:
32+
items:
33+
- const: aon
34+
35+
"#power-domain-cells":
36+
const: 1
37+
38+
required:
39+
- compatible
40+
- mboxes
41+
- mbox-names
42+
- "#power-domain-cells"
43+
44+
additionalProperties: false
45+
46+
examples:
47+
- |
48+
aon: aon {
49+
compatible = "thead,th1520-aon";
50+
mboxes = <&mbox_910t 1>;
51+
mbox-names = "aon";
52+
#power-domain-cells = <1>;
53+
};

Documentation/devicetree/bindings/power/allwinner,sun20i-d1-ppu.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ properties:
1717
compatible:
1818
enum:
1919
- allwinner,sun20i-d1-ppu
20+
- allwinner,sun8i-v853-ppu
2021

2122
reg:
2223
maxItems: 1

Documentation/devicetree/bindings/power/rockchip,power-controller.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ $defs:
132132
A number of phandles to clocks that need to be enabled
133133
while power domain switches state.
134134
135+
domain-supply:
136+
description: domain regulator supply.
137+
135138
pm_qos:
136139
$ref: /schemas/types.yaml#/definitions/phandle-array
137140
items:

MAINTAINERS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6103,9 +6103,11 @@ F: include/linux/platform_data/cpuidle-exynos.h
61036103
CPUIDLE DRIVER - ARM PSCI
61046104
M: Lorenzo Pieralisi <lpieralisi@kernel.org>
61056105
M: Sudeep Holla <sudeep.holla@arm.com>
6106+
M: Ulf Hansson <ulf.hansson@linaro.org>
61066107
L: linux-pm@vger.kernel.org
61076108
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
61086109
S: Supported
6110+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git
61096111
F: drivers/cpuidle/cpuidle-psci.c
61106112

61116113
CPUIDLE DRIVER - ARM PSCI PM DOMAIN
@@ -20510,15 +20512,20 @@ L: linux-riscv@lists.infradead.org
2051020512
S: Maintained
2051120513
T: git https://github.com/pdp7/linux.git
2051220514
F: Documentation/devicetree/bindings/clock/thead,th1520-clk-ap.yaml
20515+
F: Documentation/devicetree/bindings/firmware/thead,th1520-aon.yaml
2051320516
F: Documentation/devicetree/bindings/mailbox/thead,th1520-mbox.yaml
2051420517
F: Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml
2051520518
F: Documentation/devicetree/bindings/pinctrl/thead,th1520-pinctrl.yaml
2051620519
F: arch/riscv/boot/dts/thead/
2051720520
F: drivers/clk/thead/clk-th1520-ap.c
20521+
F: drivers/firmware/thead,th1520-aon.c
2051820522
F: drivers/mailbox/mailbox-th1520.c
2051920523
F: drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c
2052020524
F: drivers/pinctrl/pinctrl-th1520.c
20525+
F: drivers/pmdomain/thead/
2052120526
F: include/dt-bindings/clock/thead,th1520-clk-ap.h
20527+
F: include/dt-bindings/power/thead,th1520-power.h
20528+
F: include/linux/firmware/thead/thead,th1520-aon.h
2052220529

2052320530
RNBD BLOCK DRIVERS
2052420531
M: Md. Haris Iqbal <haris.iqbal@ionos.com>

drivers/cpuidle/cpuidle-psci.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/syscore_ops.h>
2626

2727
#include <asm/cpuidle.h>
28+
#include <trace/events/power.h>
2829

2930
#include "cpuidle-psci.h"
3031
#include "dt_idle_states.h"
@@ -74,7 +75,9 @@ static __cpuidle int __psci_enter_domain_idle_state(struct cpuidle_device *dev,
7475
if (!state)
7576
state = states[idx];
7677

78+
trace_psci_domain_idle_enter(dev->cpu, state, s2idle);
7779
ret = psci_cpu_suspend_enter(state) ? -1 : idx;
80+
trace_psci_domain_idle_exit(dev->cpu, state, s2idle);
7881

7982
if (s2idle)
8083
dev_pm_genpd_resume(pd_dev);

drivers/firmware/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,16 @@ config SYSFB_SIMPLEFB
212212

213213
If unsure, say Y.
214214

215+
config TH1520_AON_PROTOCOL
216+
tristate "Always-On firmware protocol"
217+
depends on ARCH_THEAD || COMPILE_TEST
218+
depends on MAILBOX
219+
help
220+
Power, clock, and resource management capabilities on the TH1520 SoC are
221+
managed by the E902 core. Firmware running on this core communicates with
222+
the kernel through the Always-On protocol, using hardware mailbox as a medium.
223+
Say yes if you need such capabilities.
224+
215225
config TI_SCI_PROTOCOL
216226
tristate "TI System Control Interface (TISCI) Message Protocol"
217227
depends on TI_MESSAGE_MANAGER

drivers/firmware/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
1818
obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o
1919
obj-$(CONFIG_SYSFB) += sysfb.o
2020
obj-$(CONFIG_SYSFB_SIMPLEFB) += sysfb_simplefb.o
21+
obj-$(CONFIG_TH1520_AON_PROTOCOL) += thead,th1520-aon.o
2122
obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o
2223
obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
2324
obj-$(CONFIG_TURRIS_MOX_RWTM) += turris-mox-rwtm.o

drivers/firmware/thead,th1520-aon.c

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (C) 2021 Alibaba Group Holding Limited.
4+
* Copyright (c) 2024 Samsung Electronics Co., Ltd.
5+
* Author: Michal Wilczynski <m.wilczynski@samsung.com>
6+
*/
7+
8+
#include <linux/device.h>
9+
#include <linux/firmware/thead/thead,th1520-aon.h>
10+
#include <linux/mailbox_client.h>
11+
#include <linux/mailbox_controller.h>
12+
#include <linux/slab.h>
13+
14+
#define MAX_RX_TIMEOUT (msecs_to_jiffies(3000))
15+
#define MAX_TX_TIMEOUT 500
16+
17+
struct th1520_aon_chan {
18+
struct mbox_chan *ch;
19+
struct th1520_aon_rpc_ack_common ack_msg;
20+
struct mbox_client cl;
21+
struct completion done;
22+
23+
/* make sure only one RPC is performed at a time */
24+
struct mutex transaction_lock;
25+
};
26+
27+
struct th1520_aon_msg_req_set_resource_power_mode {
28+
struct th1520_aon_rpc_msg_hdr hdr;
29+
u16 resource;
30+
u16 mode;
31+
u16 reserved[10];
32+
} __packed __aligned(1);
33+
34+
/*
35+
* This type is used to indicate error response for most functions.
36+
*/
37+
enum th1520_aon_error_codes {
38+
LIGHT_AON_ERR_NONE = 0, /* Success */
39+
LIGHT_AON_ERR_VERSION = 1, /* Incompatible API version */
40+
LIGHT_AON_ERR_CONFIG = 2, /* Configuration error */
41+
LIGHT_AON_ERR_PARM = 3, /* Bad parameter */
42+
LIGHT_AON_ERR_NOACCESS = 4, /* Permission error (no access) */
43+
LIGHT_AON_ERR_LOCKED = 5, /* Permission error (locked) */
44+
LIGHT_AON_ERR_UNAVAILABLE = 6, /* Unavailable (out of resources) */
45+
LIGHT_AON_ERR_NOTFOUND = 7, /* Not found */
46+
LIGHT_AON_ERR_NOPOWER = 8, /* No power */
47+
LIGHT_AON_ERR_IPC = 9, /* Generic IPC error */
48+
LIGHT_AON_ERR_BUSY = 10, /* Resource is currently busy/active */
49+
LIGHT_AON_ERR_FAIL = 11, /* General I/O failure */
50+
LIGHT_AON_ERR_LAST
51+
};
52+
53+
static int th1520_aon_linux_errmap[LIGHT_AON_ERR_LAST] = {
54+
0, /* LIGHT_AON_ERR_NONE */
55+
-EINVAL, /* LIGHT_AON_ERR_VERSION */
56+
-EINVAL, /* LIGHT_AON_ERR_CONFIG */
57+
-EINVAL, /* LIGHT_AON_ERR_PARM */
58+
-EACCES, /* LIGHT_AON_ERR_NOACCESS */
59+
-EACCES, /* LIGHT_AON_ERR_LOCKED */
60+
-ERANGE, /* LIGHT_AON_ERR_UNAVAILABLE */
61+
-EEXIST, /* LIGHT_AON_ERR_NOTFOUND */
62+
-EPERM, /* LIGHT_AON_ERR_NOPOWER */
63+
-EPIPE, /* LIGHT_AON_ERR_IPC */
64+
-EBUSY, /* LIGHT_AON_ERR_BUSY */
65+
-EIO, /* LIGHT_AON_ERR_FAIL */
66+
};
67+
68+
static inline int th1520_aon_to_linux_errno(int errno)
69+
{
70+
if (errno >= LIGHT_AON_ERR_NONE && errno < LIGHT_AON_ERR_LAST)
71+
return th1520_aon_linux_errmap[errno];
72+
73+
return -EIO;
74+
}
75+
76+
static void th1520_aon_rx_callback(struct mbox_client *c, void *rx_msg)
77+
{
78+
struct th1520_aon_chan *aon_chan =
79+
container_of(c, struct th1520_aon_chan, cl);
80+
struct th1520_aon_rpc_msg_hdr *hdr =
81+
(struct th1520_aon_rpc_msg_hdr *)rx_msg;
82+
u8 recv_size = sizeof(struct th1520_aon_rpc_msg_hdr) + hdr->size;
83+
84+
if (recv_size != sizeof(struct th1520_aon_rpc_ack_common)) {
85+
dev_err(c->dev, "Invalid ack size, not completing\n");
86+
return;
87+
}
88+
89+
memcpy(&aon_chan->ack_msg, rx_msg, recv_size);
90+
complete(&aon_chan->done);
91+
}
92+
93+
/**
94+
* th1520_aon_call_rpc() - Send an RPC request to the TH1520 AON subsystem
95+
* @aon_chan: Pointer to the AON channel structure
96+
* @msg: Pointer to the message (RPC payload) that will be sent
97+
*
98+
* This function sends an RPC message to the TH1520 AON subsystem via mailbox.
99+
* It takes the provided @msg buffer, formats it with version and service flags,
100+
* then blocks until the RPC completes or times out. The completion is signaled
101+
* by the `aon_chan->done` completion, which is waited upon for a duration
102+
* defined by `MAX_RX_TIMEOUT`.
103+
*
104+
* Return:
105+
* * 0 on success
106+
* * -ETIMEDOUT if the RPC call times out
107+
* * A negative error code if the mailbox send fails or if AON responds with
108+
* a non-zero error code (converted via th1520_aon_to_linux_errno()).
109+
*/
110+
int th1520_aon_call_rpc(struct th1520_aon_chan *aon_chan, void *msg)
111+
{
112+
struct th1520_aon_rpc_msg_hdr *hdr = msg;
113+
int ret;
114+
115+
mutex_lock(&aon_chan->transaction_lock);
116+
reinit_completion(&aon_chan->done);
117+
118+
RPC_SET_VER(hdr, TH1520_AON_RPC_VERSION);
119+
RPC_SET_SVC_ID(hdr, hdr->svc);
120+
RPC_SET_SVC_FLAG_MSG_TYPE(hdr, RPC_SVC_MSG_TYPE_DATA);
121+
RPC_SET_SVC_FLAG_ACK_TYPE(hdr, RPC_SVC_MSG_NEED_ACK);
122+
123+
ret = mbox_send_message(aon_chan->ch, msg);
124+
if (ret < 0) {
125+
dev_err(aon_chan->cl.dev, "RPC send msg failed: %d\n", ret);
126+
goto out;
127+
}
128+
129+
if (!wait_for_completion_timeout(&aon_chan->done, MAX_RX_TIMEOUT)) {
130+
dev_err(aon_chan->cl.dev, "RPC send msg timeout\n");
131+
mutex_unlock(&aon_chan->transaction_lock);
132+
return -ETIMEDOUT;
133+
}
134+
135+
ret = aon_chan->ack_msg.err_code;
136+
137+
out:
138+
mutex_unlock(&aon_chan->transaction_lock);
139+
140+
return th1520_aon_to_linux_errno(ret);
141+
}
142+
EXPORT_SYMBOL_GPL(th1520_aon_call_rpc);
143+
144+
/**
145+
* th1520_aon_power_update() - Change power state of a resource via TH1520 AON
146+
* @aon_chan: Pointer to the AON channel structure
147+
* @rsrc: Resource ID whose power state needs to be updated
148+
* @power_on: Boolean indicating whether the resource should be powered on (true)
149+
* or powered off (false)
150+
*
151+
* This function requests the TH1520 AON subsystem to set the power mode of the
152+
* given resource (@rsrc) to either on or off. It constructs the message in
153+
* `struct th1520_aon_msg_req_set_resource_power_mode` and then invokes
154+
* th1520_aon_call_rpc() to make the request. If the AON call fails, an error
155+
* message is logged along with the specific return code.
156+
*
157+
* Return:
158+
* * 0 on success
159+
* * A negative error code in case of failures (propagated from
160+
* th1520_aon_call_rpc()).
161+
*/
162+
int th1520_aon_power_update(struct th1520_aon_chan *aon_chan, u16 rsrc,
163+
bool power_on)
164+
{
165+
struct th1520_aon_msg_req_set_resource_power_mode msg = {};
166+
struct th1520_aon_rpc_msg_hdr *hdr = &msg.hdr;
167+
int ret;
168+
169+
hdr->svc = TH1520_AON_RPC_SVC_PM;
170+
hdr->func = TH1520_AON_PM_FUNC_SET_RESOURCE_POWER_MODE;
171+
hdr->size = TH1520_AON_RPC_MSG_NUM;
172+
173+
RPC_SET_BE16(&msg.resource, 0, rsrc);
174+
RPC_SET_BE16(&msg.resource, 2,
175+
(power_on ? TH1520_AON_PM_PW_MODE_ON :
176+
TH1520_AON_PM_PW_MODE_OFF));
177+
178+
ret = th1520_aon_call_rpc(aon_chan, &msg);
179+
if (ret)
180+
dev_err(aon_chan->cl.dev, "failed to power %s resource %d ret %d\n",
181+
power_on ? "up" : "off", rsrc, ret);
182+
183+
return ret;
184+
}
185+
EXPORT_SYMBOL_GPL(th1520_aon_power_update);
186+
187+
/**
188+
* th1520_aon_init() - Initialize TH1520 AON firmware protocol interface
189+
* @dev: Device pointer for the AON subsystem
190+
*
191+
* This function initializes the TH1520 AON firmware protocol interface by:
192+
* - Allocating and initializing the AON channel structure
193+
* - Setting up the mailbox client
194+
* - Requesting the AON mailbox channel
195+
* - Initializing synchronization primitives
196+
*
197+
* Return:
198+
* * Valid pointer to th1520_aon_chan structure on success
199+
* * ERR_PTR(-ENOMEM) if memory allocation fails
200+
* * ERR_PTR() with other negative error codes from mailbox operations
201+
*/
202+
struct th1520_aon_chan *th1520_aon_init(struct device *dev)
203+
{
204+
struct th1520_aon_chan *aon_chan;
205+
struct mbox_client *cl;
206+
int ret;
207+
208+
aon_chan = kzalloc(sizeof(*aon_chan), GFP_KERNEL);
209+
if (!aon_chan)
210+
return ERR_PTR(-ENOMEM);
211+
212+
cl = &aon_chan->cl;
213+
cl->dev = dev;
214+
cl->tx_block = true;
215+
cl->tx_tout = MAX_TX_TIMEOUT;
216+
cl->rx_callback = th1520_aon_rx_callback;
217+
218+
aon_chan->ch = mbox_request_channel_byname(cl, "aon");
219+
if (IS_ERR(aon_chan->ch)) {
220+
dev_err(dev, "Failed to request aon mbox chan\n");
221+
ret = PTR_ERR(aon_chan->ch);
222+
kfree(aon_chan);
223+
return ERR_PTR(ret);
224+
}
225+
226+
mutex_init(&aon_chan->transaction_lock);
227+
init_completion(&aon_chan->done);
228+
229+
return aon_chan;
230+
}
231+
EXPORT_SYMBOL_GPL(th1520_aon_init);
232+
233+
/**
234+
* th1520_aon_deinit() - Clean up TH1520 AON firmware protocol interface
235+
* @aon_chan: Pointer to the AON channel structure to clean up
236+
*
237+
* This function cleans up resources allocated by th1520_aon_init():
238+
* - Frees the mailbox channel
239+
* - Frees the AON channel
240+
*/
241+
void th1520_aon_deinit(struct th1520_aon_chan *aon_chan)
242+
{
243+
mbox_free_channel(aon_chan->ch);
244+
kfree(aon_chan);
245+
}
246+
EXPORT_SYMBOL_GPL(th1520_aon_deinit);
247+
248+
MODULE_AUTHOR("Michal Wilczynski <m.wilczynski@samsung.com>");
249+
MODULE_DESCRIPTION("T-HEAD TH1520 Always-On firmware protocol library");
250+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)