-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge tag 'pmdomain-v6.15' of git://git.kernel.org/pub/scm/linux/kern…
…el/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 ...
- Loading branch information
Showing
29 changed files
with
1,032 additions
and
83 deletions.
There are no files selected for viewing
53 changes: 53 additions & 0 deletions
53
Documentation/devicetree/bindings/firmware/thead,th1520-aon.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
%YAML 1.2 | ||
--- | ||
$id: http://devicetree.org/schemas/firmware/thead,th1520-aon.yaml# | ||
$schema: http://devicetree.org/meta-schemas/core.yaml# | ||
|
||
title: T-HEAD TH1520 AON (Always-On) Firmware | ||
|
||
description: | | ||
The Always-On (AON) subsystem in the TH1520 SoC is responsible for managing | ||
low-power states, system wakeup events, and power management tasks. It is | ||
designed to operate independently in a dedicated power domain, allowing it to | ||
remain functional even during the SoC's deep sleep states. | ||
At the heart of the AON subsystem is the E902, a low-power core that executes | ||
firmware responsible for coordinating tasks such as power domain control, | ||
clock management, and system wakeup signaling. Communication between the main | ||
SoC and the AON subsystem is handled through a mailbox interface, which | ||
enables message-based interactions with the AON firmware. | ||
maintainers: | ||
- Michal Wilczynski <m.wilczynski@samsung.com> | ||
|
||
properties: | ||
compatible: | ||
const: thead,th1520-aon | ||
|
||
mboxes: | ||
maxItems: 1 | ||
|
||
mbox-names: | ||
items: | ||
- const: aon | ||
|
||
"#power-domain-cells": | ||
const: 1 | ||
|
||
required: | ||
- compatible | ||
- mboxes | ||
- mbox-names | ||
- "#power-domain-cells" | ||
|
||
additionalProperties: false | ||
|
||
examples: | ||
- | | ||
aon: aon { | ||
compatible = "thead,th1520-aon"; | ||
mboxes = <&mbox_910t 1>; | ||
mbox-names = "aon"; | ||
#power-domain-cells = <1>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ properties: | |
compatible: | ||
enum: | ||
- allwinner,sun20i-d1-ppu | ||
- allwinner,sun8i-v853-ppu | ||
|
||
reg: | ||
maxItems: 1 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (C) 2021 Alibaba Group Holding Limited. | ||
* Copyright (c) 2024 Samsung Electronics Co., Ltd. | ||
* Author: Michal Wilczynski <m.wilczynski@samsung.com> | ||
*/ | ||
|
||
#include <linux/device.h> | ||
#include <linux/firmware/thead/thead,th1520-aon.h> | ||
#include <linux/mailbox_client.h> | ||
#include <linux/mailbox_controller.h> | ||
#include <linux/slab.h> | ||
|
||
#define MAX_RX_TIMEOUT (msecs_to_jiffies(3000)) | ||
#define MAX_TX_TIMEOUT 500 | ||
|
||
struct th1520_aon_chan { | ||
struct mbox_chan *ch; | ||
struct th1520_aon_rpc_ack_common ack_msg; | ||
struct mbox_client cl; | ||
struct completion done; | ||
|
||
/* make sure only one RPC is performed at a time */ | ||
struct mutex transaction_lock; | ||
}; | ||
|
||
struct th1520_aon_msg_req_set_resource_power_mode { | ||
struct th1520_aon_rpc_msg_hdr hdr; | ||
u16 resource; | ||
u16 mode; | ||
u16 reserved[10]; | ||
} __packed __aligned(1); | ||
|
||
/* | ||
* This type is used to indicate error response for most functions. | ||
*/ | ||
enum th1520_aon_error_codes { | ||
LIGHT_AON_ERR_NONE = 0, /* Success */ | ||
LIGHT_AON_ERR_VERSION = 1, /* Incompatible API version */ | ||
LIGHT_AON_ERR_CONFIG = 2, /* Configuration error */ | ||
LIGHT_AON_ERR_PARM = 3, /* Bad parameter */ | ||
LIGHT_AON_ERR_NOACCESS = 4, /* Permission error (no access) */ | ||
LIGHT_AON_ERR_LOCKED = 5, /* Permission error (locked) */ | ||
LIGHT_AON_ERR_UNAVAILABLE = 6, /* Unavailable (out of resources) */ | ||
LIGHT_AON_ERR_NOTFOUND = 7, /* Not found */ | ||
LIGHT_AON_ERR_NOPOWER = 8, /* No power */ | ||
LIGHT_AON_ERR_IPC = 9, /* Generic IPC error */ | ||
LIGHT_AON_ERR_BUSY = 10, /* Resource is currently busy/active */ | ||
LIGHT_AON_ERR_FAIL = 11, /* General I/O failure */ | ||
LIGHT_AON_ERR_LAST | ||
}; | ||
|
||
static int th1520_aon_linux_errmap[LIGHT_AON_ERR_LAST] = { | ||
0, /* LIGHT_AON_ERR_NONE */ | ||
-EINVAL, /* LIGHT_AON_ERR_VERSION */ | ||
-EINVAL, /* LIGHT_AON_ERR_CONFIG */ | ||
-EINVAL, /* LIGHT_AON_ERR_PARM */ | ||
-EACCES, /* LIGHT_AON_ERR_NOACCESS */ | ||
-EACCES, /* LIGHT_AON_ERR_LOCKED */ | ||
-ERANGE, /* LIGHT_AON_ERR_UNAVAILABLE */ | ||
-EEXIST, /* LIGHT_AON_ERR_NOTFOUND */ | ||
-EPERM, /* LIGHT_AON_ERR_NOPOWER */ | ||
-EPIPE, /* LIGHT_AON_ERR_IPC */ | ||
-EBUSY, /* LIGHT_AON_ERR_BUSY */ | ||
-EIO, /* LIGHT_AON_ERR_FAIL */ | ||
}; | ||
|
||
static inline int th1520_aon_to_linux_errno(int errno) | ||
{ | ||
if (errno >= LIGHT_AON_ERR_NONE && errno < LIGHT_AON_ERR_LAST) | ||
return th1520_aon_linux_errmap[errno]; | ||
|
||
return -EIO; | ||
} | ||
|
||
static void th1520_aon_rx_callback(struct mbox_client *c, void *rx_msg) | ||
{ | ||
struct th1520_aon_chan *aon_chan = | ||
container_of(c, struct th1520_aon_chan, cl); | ||
struct th1520_aon_rpc_msg_hdr *hdr = | ||
(struct th1520_aon_rpc_msg_hdr *)rx_msg; | ||
u8 recv_size = sizeof(struct th1520_aon_rpc_msg_hdr) + hdr->size; | ||
|
||
if (recv_size != sizeof(struct th1520_aon_rpc_ack_common)) { | ||
dev_err(c->dev, "Invalid ack size, not completing\n"); | ||
return; | ||
} | ||
|
||
memcpy(&aon_chan->ack_msg, rx_msg, recv_size); | ||
complete(&aon_chan->done); | ||
} | ||
|
||
/** | ||
* th1520_aon_call_rpc() - Send an RPC request to the TH1520 AON subsystem | ||
* @aon_chan: Pointer to the AON channel structure | ||
* @msg: Pointer to the message (RPC payload) that will be sent | ||
* | ||
* This function sends an RPC message to the TH1520 AON subsystem via mailbox. | ||
* It takes the provided @msg buffer, formats it with version and service flags, | ||
* then blocks until the RPC completes or times out. The completion is signaled | ||
* by the `aon_chan->done` completion, which is waited upon for a duration | ||
* defined by `MAX_RX_TIMEOUT`. | ||
* | ||
* Return: | ||
* * 0 on success | ||
* * -ETIMEDOUT if the RPC call times out | ||
* * A negative error code if the mailbox send fails or if AON responds with | ||
* a non-zero error code (converted via th1520_aon_to_linux_errno()). | ||
*/ | ||
int th1520_aon_call_rpc(struct th1520_aon_chan *aon_chan, void *msg) | ||
{ | ||
struct th1520_aon_rpc_msg_hdr *hdr = msg; | ||
int ret; | ||
|
||
mutex_lock(&aon_chan->transaction_lock); | ||
reinit_completion(&aon_chan->done); | ||
|
||
RPC_SET_VER(hdr, TH1520_AON_RPC_VERSION); | ||
RPC_SET_SVC_ID(hdr, hdr->svc); | ||
RPC_SET_SVC_FLAG_MSG_TYPE(hdr, RPC_SVC_MSG_TYPE_DATA); | ||
RPC_SET_SVC_FLAG_ACK_TYPE(hdr, RPC_SVC_MSG_NEED_ACK); | ||
|
||
ret = mbox_send_message(aon_chan->ch, msg); | ||
if (ret < 0) { | ||
dev_err(aon_chan->cl.dev, "RPC send msg failed: %d\n", ret); | ||
goto out; | ||
} | ||
|
||
if (!wait_for_completion_timeout(&aon_chan->done, MAX_RX_TIMEOUT)) { | ||
dev_err(aon_chan->cl.dev, "RPC send msg timeout\n"); | ||
mutex_unlock(&aon_chan->transaction_lock); | ||
return -ETIMEDOUT; | ||
} | ||
|
||
ret = aon_chan->ack_msg.err_code; | ||
|
||
out: | ||
mutex_unlock(&aon_chan->transaction_lock); | ||
|
||
return th1520_aon_to_linux_errno(ret); | ||
} | ||
EXPORT_SYMBOL_GPL(th1520_aon_call_rpc); | ||
|
||
/** | ||
* th1520_aon_power_update() - Change power state of a resource via TH1520 AON | ||
* @aon_chan: Pointer to the AON channel structure | ||
* @rsrc: Resource ID whose power state needs to be updated | ||
* @power_on: Boolean indicating whether the resource should be powered on (true) | ||
* or powered off (false) | ||
* | ||
* This function requests the TH1520 AON subsystem to set the power mode of the | ||
* given resource (@rsrc) to either on or off. It constructs the message in | ||
* `struct th1520_aon_msg_req_set_resource_power_mode` and then invokes | ||
* th1520_aon_call_rpc() to make the request. If the AON call fails, an error | ||
* message is logged along with the specific return code. | ||
* | ||
* Return: | ||
* * 0 on success | ||
* * A negative error code in case of failures (propagated from | ||
* th1520_aon_call_rpc()). | ||
*/ | ||
int th1520_aon_power_update(struct th1520_aon_chan *aon_chan, u16 rsrc, | ||
bool power_on) | ||
{ | ||
struct th1520_aon_msg_req_set_resource_power_mode msg = {}; | ||
struct th1520_aon_rpc_msg_hdr *hdr = &msg.hdr; | ||
int ret; | ||
|
||
hdr->svc = TH1520_AON_RPC_SVC_PM; | ||
hdr->func = TH1520_AON_PM_FUNC_SET_RESOURCE_POWER_MODE; | ||
hdr->size = TH1520_AON_RPC_MSG_NUM; | ||
|
||
RPC_SET_BE16(&msg.resource, 0, rsrc); | ||
RPC_SET_BE16(&msg.resource, 2, | ||
(power_on ? TH1520_AON_PM_PW_MODE_ON : | ||
TH1520_AON_PM_PW_MODE_OFF)); | ||
|
||
ret = th1520_aon_call_rpc(aon_chan, &msg); | ||
if (ret) | ||
dev_err(aon_chan->cl.dev, "failed to power %s resource %d ret %d\n", | ||
power_on ? "up" : "off", rsrc, ret); | ||
|
||
return ret; | ||
} | ||
EXPORT_SYMBOL_GPL(th1520_aon_power_update); | ||
|
||
/** | ||
* th1520_aon_init() - Initialize TH1520 AON firmware protocol interface | ||
* @dev: Device pointer for the AON subsystem | ||
* | ||
* This function initializes the TH1520 AON firmware protocol interface by: | ||
* - Allocating and initializing the AON channel structure | ||
* - Setting up the mailbox client | ||
* - Requesting the AON mailbox channel | ||
* - Initializing synchronization primitives | ||
* | ||
* Return: | ||
* * Valid pointer to th1520_aon_chan structure on success | ||
* * ERR_PTR(-ENOMEM) if memory allocation fails | ||
* * ERR_PTR() with other negative error codes from mailbox operations | ||
*/ | ||
struct th1520_aon_chan *th1520_aon_init(struct device *dev) | ||
{ | ||
struct th1520_aon_chan *aon_chan; | ||
struct mbox_client *cl; | ||
int ret; | ||
|
||
aon_chan = kzalloc(sizeof(*aon_chan), GFP_KERNEL); | ||
if (!aon_chan) | ||
return ERR_PTR(-ENOMEM); | ||
|
||
cl = &aon_chan->cl; | ||
cl->dev = dev; | ||
cl->tx_block = true; | ||
cl->tx_tout = MAX_TX_TIMEOUT; | ||
cl->rx_callback = th1520_aon_rx_callback; | ||
|
||
aon_chan->ch = mbox_request_channel_byname(cl, "aon"); | ||
if (IS_ERR(aon_chan->ch)) { | ||
dev_err(dev, "Failed to request aon mbox chan\n"); | ||
ret = PTR_ERR(aon_chan->ch); | ||
kfree(aon_chan); | ||
return ERR_PTR(ret); | ||
} | ||
|
||
mutex_init(&aon_chan->transaction_lock); | ||
init_completion(&aon_chan->done); | ||
|
||
return aon_chan; | ||
} | ||
EXPORT_SYMBOL_GPL(th1520_aon_init); | ||
|
||
/** | ||
* th1520_aon_deinit() - Clean up TH1520 AON firmware protocol interface | ||
* @aon_chan: Pointer to the AON channel structure to clean up | ||
* | ||
* This function cleans up resources allocated by th1520_aon_init(): | ||
* - Frees the mailbox channel | ||
* - Frees the AON channel | ||
*/ | ||
void th1520_aon_deinit(struct th1520_aon_chan *aon_chan) | ||
{ | ||
mbox_free_channel(aon_chan->ch); | ||
kfree(aon_chan); | ||
} | ||
EXPORT_SYMBOL_GPL(th1520_aon_deinit); | ||
|
||
MODULE_AUTHOR("Michal Wilczynski <m.wilczynski@samsung.com>"); | ||
MODULE_DESCRIPTION("T-HEAD TH1520 Always-On firmware protocol library"); | ||
MODULE_LICENSE("GPL"); |
Oops, something went wrong.