* [PATCH RFC v2 0/4] firmware: ti_sci: Introduce BOARDCFG_MANAGED mode for Jacinto family
@ 2025-11-27 8:38 Thomas Richard (TI.com)
2025-11-27 8:38 ` [PATCH RFC v2 1/4] firmware: ti_sci: add BOARDCFG_MANAGED mode support Thomas Richard (TI.com)
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Thomas Richard (TI.com) @ 2025-11-27 8:38 UTC (permalink / raw)
To: Nishanth Menon, Tero Kristo, Santosh Shilimkar, Michael Turquette,
Stephen Boyd
Cc: Gregory CLEMENT, richard.genoud, Udit Kumar, Prasanth Mantena,
Abhash Kumar, Thomas Petazzoni, linux-arm-kernel, linux-kernel,
linux-clk, Thomas Richard (TI.com)
This iteration introduces a key improvement: the ti_sci driver now restores
SCI clock parents during resume as the firmware is not able to do it.
On the interrupt management side, the driver has been updated to use hlist
for storing requested IRQs.
Regarding documentation, Nishanth requested references for
BOARDCFG_MANAGED mode. While the relevant documentation is not yet publicly
available, I will update the commit message with the appropriate links as
soon as it becomes accessible.
Signed-off-by: Thomas Richard (TI.com) <thomas.richard@bootlin.com>
---
Changes in v2:
- ti_sci: use hlist to store IRQs.
- sci-clk: add context_restore operation
- ti_sci: restore clock parents during resume
- Link to v1: https://lore.kernel.org/r/20251017-ti-sci-jacinto-s2r-restore-irq-v1-0-34d4339d247a@bootlin.com
---
Thomas Richard (TI.com) (4):
firmware: ti_sci: add BOARDCFG_MANAGED mode support
firmware: ti_sci: handle IRQ restore in BOARDCFG_MANAGED mode during resume
clk: keystone: sci-clk: add restore_context() operation
firmware: ti_sci: restore clock context during resume in BOARDCFG_MANAGED mode
drivers/clk/keystone/sci-clk.c | 25 +++++--
drivers/firmware/ti_sci.c | 160 +++++++++++++++++++++++++++++++++++++----
drivers/firmware/ti_sci.h | 2 +
3 files changed, 170 insertions(+), 17 deletions(-)
---
base-commit: cb6649f6217c0331b885cf787f1d175963e2a1d2
change-id: 20251010-ti-sci-jacinto-s2r-restore-irq-428e008fd10c
prerequisite-message-id: 20251014-ti-sci-io-isolation-v1-1-67c7ce5d1b63@bootlin.com
prerequisite-patch-id: 7bbf6ca9fb85214b5360548506ccca7fae2e5a16
prerequisite-message-id: 20251014-ti-sci-pm-ops-cleanup-v1-1-70b50b73ac85@bootlin.com
prerequisite-patch-id: 257a5848d5631504c9549ad94e4b41a93f980978
Best regards,
--
Thomas Richard (TI.com) <thomas.richard@bootlin.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH RFC v2 1/4] firmware: ti_sci: add BOARDCFG_MANAGED mode support
2025-11-27 8:38 [PATCH RFC v2 0/4] firmware: ti_sci: Introduce BOARDCFG_MANAGED mode for Jacinto family Thomas Richard (TI.com)
@ 2025-11-27 8:38 ` Thomas Richard (TI.com)
2025-11-27 8:38 ` [PATCH RFC v2 2/4] firmware: ti_sci: handle IRQ restore in BOARDCFG_MANAGED mode during resume Thomas Richard (TI.com)
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Thomas Richard (TI.com) @ 2025-11-27 8:38 UTC (permalink / raw)
To: Nishanth Menon, Tero Kristo, Santosh Shilimkar, Michael Turquette,
Stephen Boyd
Cc: Gregory CLEMENT, richard.genoud, Udit Kumar, Prasanth Mantena,
Abhash Kumar, Thomas Petazzoni, linux-arm-kernel, linux-kernel,
linux-clk, Thomas Richard (TI.com)
In BOARDCFG_MANAGED mode, the low power mode configuration is done
statically for the DM via the boardcfg. Constraints are not supported, and
prepare_sleep() is not needed.
Signed-off-by: Thomas Richard (TI.com) <thomas.richard@bootlin.com>
---
drivers/firmware/ti_sci.c | 10 +++++++---
drivers/firmware/ti_sci.h | 2 ++
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index d1faa47576199..4afe1c4872ff8 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -3693,8 +3693,11 @@ static int ti_sci_prepare_system_suspend(struct ti_sci_info *info)
return ti_sci_cmd_prepare_sleep(&info->handle,
TISCI_MSG_VALUE_SLEEP_MODE_DM_MANAGED,
0, 0, 0);
+ } else if (info->fw_caps & MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED) {
+ /* Nothing to do in the BOARDCFG_MANAGED mode */
+ return 0;
} else {
- /* DM Managed is not supported by the firmware. */
+ /* DM Managed and BoardCfg Managed are not supported by the firmware. */
dev_err(info->dev, "Suspend to memory is not supported by the firmware\n");
return -EOPNOTSUPP;
}
@@ -3932,12 +3935,13 @@ static int ti_sci_probe(struct platform_device *pdev)
}
ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps);
- dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s\n",
+ dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s%s\n",
info->fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "",
info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "",
info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : "",
info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "",
- info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : ""
+ info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : "",
+ info->fw_caps & MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED ? " BoardConfig-Managed" : ""
);
ti_sci_setup_ops(info);
diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h
index 7559cde17b6cc..3638c68351705 100644
--- a/drivers/firmware/ti_sci.h
+++ b/drivers/firmware/ti_sci.h
@@ -150,6 +150,7 @@ struct ti_sci_msg_req_reboot {
* MSG_FLAG_CAPS_LPM_DM_MANAGED: LPM can be managed by DM
* MSG_FLAG_CAPS_LPM_ABORT: Abort entry to LPM
* MSG_FLAG_CAPS_IO_ISOLATION: IO Isolation support
+ * MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED: LPM config done statically for the DM via boardcfg
*
* Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS
* providing currently available SOC/firmware capabilities. SoC that don't
@@ -162,6 +163,7 @@ struct ti_sci_msg_resp_query_fw_caps {
#define MSG_FLAG_CAPS_LPM_DM_MANAGED TI_SCI_MSG_FLAG(5)
#define MSG_FLAG_CAPS_LPM_ABORT TI_SCI_MSG_FLAG(9)
#define MSG_FLAG_CAPS_IO_ISOLATION TI_SCI_MSG_FLAG(7)
+#define MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED TI_SCI_MSG_FLAG(10)
#define MSG_MASK_CAPS_LPM GENMASK_ULL(4, 1)
u64 fw_caps;
} __packed;
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH RFC v2 2/4] firmware: ti_sci: handle IRQ restore in BOARDCFG_MANAGED mode during resume
2025-11-27 8:38 [PATCH RFC v2 0/4] firmware: ti_sci: Introduce BOARDCFG_MANAGED mode for Jacinto family Thomas Richard (TI.com)
2025-11-27 8:38 ` [PATCH RFC v2 1/4] firmware: ti_sci: add BOARDCFG_MANAGED mode support Thomas Richard (TI.com)
@ 2025-11-27 8:38 ` Thomas Richard (TI.com)
2025-11-27 8:38 ` [PATCH RFC v2 3/4] clk: keystone: sci-clk: add restore_context() operation Thomas Richard (TI.com)
2025-11-27 8:38 ` [PATCH RFC v2 4/4] firmware: ti_sci: restore clock context during resume in BOARDCFG_MANAGED mode Thomas Richard (TI.com)
3 siblings, 0 replies; 7+ messages in thread
From: Thomas Richard (TI.com) @ 2025-11-27 8:38 UTC (permalink / raw)
To: Nishanth Menon, Tero Kristo, Santosh Shilimkar, Michael Turquette,
Stephen Boyd
Cc: Gregory CLEMENT, richard.genoud, Udit Kumar, Prasanth Mantena,
Abhash Kumar, Thomas Petazzoni, linux-arm-kernel, linux-kernel,
linux-clk, Thomas Richard (TI.com)
In BOARDCFG_MANAGED mode, the firmware cannot restore IRQs during
resume. This responsibility is delegated to the ti_sci driver,
which maintains an internal list of all requested IRQs. This list
is updated on each set/free operation, and all IRQs are restored
during the resume_noirq() phase.
Signed-off-by: Thomas Richard (TI.com) <thomas.richard@bootlin.com>
---
drivers/firmware/ti_sci.c | 147 +++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 138 insertions(+), 9 deletions(-)
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 4afe1c4872ff8..a4d28f37b58ae 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -12,6 +12,7 @@
#include <linux/cpu.h>
#include <linux/debugfs.h>
#include <linux/export.h>
+#include <linux/hashtable.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
@@ -87,6 +88,16 @@ struct ti_sci_desc {
int max_msg_size;
};
+/**
+ * struct ti_sci_irq - Description of allocated irqs
+ * @node: Link to hash table
+ * @desc: Description of the irq
+ */
+struct ti_sci_irq {
+ struct hlist_node node;
+ struct ti_sci_msg_req_manage_irq desc;
+};
+
/**
* struct ti_sci_info - Structure representing a TI SCI instance
* @dev: Device pointer
@@ -101,6 +112,7 @@ struct ti_sci_desc {
* @chan_rx: Receive mailbox channel
* @minfo: Message info
* @node: list head
+ * @irqs: List of allocated irqs
* @host_id: Host ID
* @fw_caps: FW/SoC low power capabilities
* @users: Number of users of this instance
@@ -117,6 +129,7 @@ struct ti_sci_info {
struct mbox_chan *chan_tx;
struct mbox_chan *chan_rx;
struct ti_sci_xfers_info minfo;
+ DECLARE_HASHTABLE(irqs, 8);
struct list_head node;
u8 host_id;
u64 fw_caps;
@@ -2294,6 +2307,32 @@ static int ti_sci_manage_irq(const struct ti_sci_handle *handle,
return ret;
}
+/**
+ * ti_sci_irq_hash() - Helper API to compute irq hash for the hash table.
+ * @irq: irq to hash
+ *
+ * Return: the computed hash value.
+ */
+static int ti_sci_irq_hash(struct ti_sci_msg_req_manage_irq *irq)
+{
+ return irq->src_id ^ irq->src_index;
+}
+
+/**
+ * ti_sci_irq_equal() - Helper API to compare two irqs (generic headers are not
+ * compared)
+ * @irq_a: irq_a to compare
+ * @irq_b: irq_b to compare
+ *
+ * Return: true if the two irqs are equal, else false.
+ */
+static bool ti_sci_irq_equal(struct ti_sci_msg_req_manage_irq *irq_a,
+ struct ti_sci_msg_req_manage_irq *irq_b)
+{
+ return !memcmp(&irq_a->valid_params, &irq_b->valid_params,
+ sizeof(*irq_a) - sizeof(irq_a->hdr));
+}
+
/**
* ti_sci_set_irq() - Helper api to configure the irq route between the
* requested source and destination
@@ -2317,15 +2356,43 @@ static int ti_sci_set_irq(const struct ti_sci_handle *handle, u32 valid_params,
u16 dst_host_irq, u16 ia_id, u16 vint,
u16 global_event, u8 vint_status_bit, u8 s_host)
{
+ struct ti_sci_info *info = handle_to_ti_sci_info(handle);
+ struct ti_sci_msg_req_manage_irq *desc;
+ struct ti_sci_irq *irq;
+ int ret;
+
pr_debug("%s: IRQ set with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
__func__, valid_params, src_id, src_index,
dst_id, dst_host_irq, ia_id, vint, global_event,
vint_status_bit);
- return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
- dst_id, dst_host_irq, ia_id, vint,
- global_event, vint_status_bit, s_host,
- TI_SCI_MSG_SET_IRQ);
+ ret = ti_sci_manage_irq(handle, valid_params, src_id, src_index,
+ dst_id, dst_host_irq, ia_id, vint,
+ global_event, vint_status_bit, s_host,
+ TI_SCI_MSG_SET_IRQ);
+
+ if (ret)
+ return ret;
+
+ irq = kzalloc(sizeof(*irq), GFP_KERNEL);
+ if (!irq)
+ return -ENOMEM;
+
+ desc = &irq->desc;
+ desc->valid_params = valid_params;
+ desc->src_id = src_id;
+ desc->src_index = src_index;
+ desc->dst_id = dst_id;
+ desc->dst_host_irq = dst_host_irq;
+ desc->ia_id = ia_id;
+ desc->vint = vint;
+ desc->global_event = global_event;
+ desc->vint_status_bit = vint_status_bit;
+ desc->secondary_host = s_host;
+
+ hash_add(info->irqs, &irq->node, ti_sci_irq_hash(desc));
+
+ return 0;
}
/**
@@ -2351,15 +2418,46 @@ static int ti_sci_free_irq(const struct ti_sci_handle *handle, u32 valid_params,
u16 dst_host_irq, u16 ia_id, u16 vint,
u16 global_event, u8 vint_status_bit, u8 s_host)
{
+ struct ti_sci_info *info = handle_to_ti_sci_info(handle);
+ struct ti_sci_msg_req_manage_irq irq_desc;
+ struct ti_sci_irq *this_irq;
+ struct hlist_node *tmp_node;
+ int ret;
+
pr_debug("%s: IRQ release with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
__func__, valid_params, src_id, src_index,
dst_id, dst_host_irq, ia_id, vint, global_event,
vint_status_bit);
- return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
- dst_id, dst_host_irq, ia_id, vint,
- global_event, vint_status_bit, s_host,
- TI_SCI_MSG_FREE_IRQ);
+ ret = ti_sci_manage_irq(handle, valid_params, src_id, src_index,
+ dst_id, dst_host_irq, ia_id, vint,
+ global_event, vint_status_bit, s_host,
+ TI_SCI_MSG_FREE_IRQ);
+
+ if (ret)
+ return ret;
+
+ irq_desc.valid_params = valid_params;
+ irq_desc.src_id = src_id;
+ irq_desc.src_index = src_index;
+ irq_desc.dst_id = dst_id;
+ irq_desc.dst_host_irq = dst_host_irq;
+ irq_desc.ia_id = ia_id;
+ irq_desc.vint = vint;
+ irq_desc.global_event = global_event;
+ irq_desc.vint_status_bit = vint_status_bit;
+ irq_desc.secondary_host = s_host;
+
+ hash_for_each_possible_safe(info->irqs, this_irq, tmp_node, node,
+ ti_sci_irq_hash(&irq_desc)) {
+ if (ti_sci_irq_equal(&irq_desc, &this_irq->desc)) {
+ hlist_del(&this_irq->node);
+ kfree(this_irq);
+ return 0;
+ }
+ }
+
+ return 0;
}
/**
@@ -3768,7 +3866,10 @@ static int ti_sci_suspend_noirq(struct device *dev)
static int ti_sci_resume_noirq(struct device *dev)
{
struct ti_sci_info *info = dev_get_drvdata(dev);
- int ret = 0;
+ struct ti_sci_msg_req_manage_irq *irq_desc;
+ struct ti_sci_irq *irq;
+ struct hlist_node *tmp_node;
+ int ret = 0, i;
u32 source;
u64 time;
u8 pin;
@@ -3780,6 +3881,32 @@ static int ti_sci_resume_noirq(struct device *dev)
return ret;
}
+ switch (pm_suspend_target_state) {
+ case PM_SUSPEND_MEM:
+ if (info->fw_caps & MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED) {
+ hash_for_each_safe(info->irqs, i, tmp_node, irq, node) {
+ irq_desc = &irq->desc;
+ ret = ti_sci_manage_irq(&info->handle,
+ irq_desc->valid_params,
+ irq_desc->src_id,
+ irq_desc->src_index,
+ irq_desc->dst_id,
+ irq_desc->dst_host_irq,
+ irq_desc->ia_id,
+ irq_desc->vint,
+ irq_desc->global_event,
+ irq_desc->vint_status_bit,
+ irq_desc->secondary_host,
+ TI_SCI_MSG_SET_IRQ);
+ if (ret)
+ return ret;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
ret = ti_sci_msg_cmd_lpm_wake_reason(&info->handle, &source, &time, &pin, &mode);
/* Do not fail to resume on error as the wake reason is not critical */
if (!ret)
@@ -3961,6 +4088,8 @@ static int ti_sci_probe(struct platform_device *pdev)
list_add_tail(&info->node, &ti_sci_list);
mutex_unlock(&ti_sci_list_mutex);
+ hash_init(info->irqs);
+
return of_platform_populate(dev->of_node, NULL, NULL, dev);
out:
if (!IS_ERR(info->chan_tx))
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH RFC v2 3/4] clk: keystone: sci-clk: add restore_context() operation
2025-11-27 8:38 [PATCH RFC v2 0/4] firmware: ti_sci: Introduce BOARDCFG_MANAGED mode for Jacinto family Thomas Richard (TI.com)
2025-11-27 8:38 ` [PATCH RFC v2 1/4] firmware: ti_sci: add BOARDCFG_MANAGED mode support Thomas Richard (TI.com)
2025-11-27 8:38 ` [PATCH RFC v2 2/4] firmware: ti_sci: handle IRQ restore in BOARDCFG_MANAGED mode during resume Thomas Richard (TI.com)
@ 2025-11-27 8:38 ` Thomas Richard (TI.com)
2025-12-03 7:50 ` Kumar, Udit
2025-11-27 8:38 ` [PATCH RFC v2 4/4] firmware: ti_sci: restore clock context during resume in BOARDCFG_MANAGED mode Thomas Richard (TI.com)
3 siblings, 1 reply; 7+ messages in thread
From: Thomas Richard (TI.com) @ 2025-11-27 8:38 UTC (permalink / raw)
To: Nishanth Menon, Tero Kristo, Santosh Shilimkar, Michael Turquette,
Stephen Boyd
Cc: Gregory CLEMENT, richard.genoud, Udit Kumar, Prasanth Mantena,
Abhash Kumar, Thomas Petazzoni, linux-arm-kernel, linux-kernel,
linux-clk, Thomas Richard (TI.com)
Implement the restore_context() operation to restore the clock parent
state. The parent index is saved in sci_clk struct during set_parent().
During clock registration, the core retrieves each clock’s parent using
get_parent() operation to ensure the internal clock tree reflects the
actual hardware state, including any configurations made by the
bootloader. So we also save the parent index in get_parent().
Signed-off-by: Thomas Richard (TI.com) <thomas.richard@bootlin.com>
---
drivers/clk/keystone/sci-clk.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index a4b42811de55d..1e5dd01484d1c 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -47,6 +47,7 @@ struct sci_clk_provider {
* @node: Link for handling clocks probed via DT
* @cached_req: Cached requested freq for determine rate calls
* @cached_res: Cached result freq for determine rate calls
+ * @parent_id: Parent index for this clock
*/
struct sci_clk {
struct clk_hw hw;
@@ -58,6 +59,7 @@ struct sci_clk {
struct list_head node;
unsigned long cached_req;
unsigned long cached_res;
+ u8 parent_id;
};
#define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw)
@@ -237,9 +239,9 @@ static u8 sci_clk_get_parent(struct clk_hw *hw)
return 0;
}
- parent_id = parent_id - clk->clk_id - 1;
+ clk->parent_id = (u8)(parent_id - clk->clk_id - 1);
- return (u8)parent_id;
+ return clk->parent_id;
}
/**
@@ -252,12 +254,24 @@ static u8 sci_clk_get_parent(struct clk_hw *hw)
static int sci_clk_set_parent(struct clk_hw *hw, u8 index)
{
struct sci_clk *clk = to_sci_clk(hw);
+ int ret;
clk->cached_req = 0;
- return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
- clk->clk_id,
- index + 1 + clk->clk_id);
+ ret = clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
+ clk->clk_id,
+ index + 1 + clk->clk_id);
+ if (!ret)
+ clk->parent_id = index;
+
+ return ret;
+}
+
+static void sci_clk_restore_context(struct clk_hw *hw)
+{
+ struct sci_clk *clk = to_sci_clk(hw);
+
+ sci_clk_set_parent(hw, clk->parent_id);
}
static const struct clk_ops sci_clk_ops = {
@@ -269,6 +283,7 @@ static const struct clk_ops sci_clk_ops = {
.set_rate = sci_clk_set_rate,
.get_parent = sci_clk_get_parent,
.set_parent = sci_clk_set_parent,
+ .restore_context = sci_clk_restore_context,
};
/**
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH RFC v2 4/4] firmware: ti_sci: restore clock context during resume in BOARDCFG_MANAGED mode
2025-11-27 8:38 [PATCH RFC v2 0/4] firmware: ti_sci: Introduce BOARDCFG_MANAGED mode for Jacinto family Thomas Richard (TI.com)
` (2 preceding siblings ...)
2025-11-27 8:38 ` [PATCH RFC v2 3/4] clk: keystone: sci-clk: add restore_context() operation Thomas Richard (TI.com)
@ 2025-11-27 8:38 ` Thomas Richard (TI.com)
3 siblings, 0 replies; 7+ messages in thread
From: Thomas Richard (TI.com) @ 2025-11-27 8:38 UTC (permalink / raw)
To: Nishanth Menon, Tero Kristo, Santosh Shilimkar, Michael Turquette,
Stephen Boyd
Cc: Gregory CLEMENT, richard.genoud, Udit Kumar, Prasanth Mantena,
Abhash Kumar, Thomas Petazzoni, linux-arm-kernel, linux-kernel,
linux-clk, Thomas Richard (TI.com)
In BOARDCFG_MANAGED mode, the firmware cannot restore the clock parents.
This responsibility is therefore delegated to the ti_sci driver, which uses
clk_restore_context() to trigger the context_restore() operation for all
registered clocks, including those managed by the sci-clk driver. The
sci-clk driver implements the context_restore() operation to ensure clock
parents are correctly restored.
Signed-off-by: Thomas Richard (TI.com) <thomas.richard@bootlin.com>
---
drivers/firmware/ti_sci.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index a4d28f37b58ae..1e3fe00ff9109 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -9,6 +9,7 @@
#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/bitmap.h>
+#include <linux/clk.h>
#include <linux/cpu.h>
#include <linux/debugfs.h>
#include <linux/export.h>
@@ -3901,6 +3902,8 @@ static int ti_sci_resume_noirq(struct device *dev)
if (ret)
return ret;
}
+
+ clk_restore_context();
}
break;
default:
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH RFC v2 3/4] clk: keystone: sci-clk: add restore_context() operation
2025-11-27 8:38 ` [PATCH RFC v2 3/4] clk: keystone: sci-clk: add restore_context() operation Thomas Richard (TI.com)
@ 2025-12-03 7:50 ` Kumar, Udit
2025-12-03 14:10 ` Thomas Richard
0 siblings, 1 reply; 7+ messages in thread
From: Kumar, Udit @ 2025-12-03 7:50 UTC (permalink / raw)
To: Thomas Richard (TI.com), Nishanth Menon, Tero Kristo,
Santosh Shilimkar, Michael Turquette, Stephen Boyd
Cc: Gregory CLEMENT, richard.genoud, Prasanth Mantena, Abhash Kumar,
Thomas Petazzoni, linux-arm-kernel, linux-kernel, linux-clk,
u-kumar1
On 11/27/2025 2:08 PM, Thomas Richard (TI.com) wrote:
> Implement the restore_context() operation to restore the clock parent
> state. The parent index is saved in sci_clk struct during set_parent().
> During clock registration, the core retrieves each clock’s parent using
> get_parent() operation to ensure the internal clock tree reflects the
> actual hardware state, including any configurations made by the
> bootloader. So we also save the parent index in get_parent().
>
> Signed-off-by: Thomas Richard (TI.com) <thomas.richard@bootlin.com>
> ---
> drivers/clk/keystone/sci-clk.c | 25 ++++++++++++++++++++-----
> 1 file changed, 20 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
> index a4b42811de55d..1e5dd01484d1c 100644
> --- a/drivers/clk/keystone/sci-clk.c
> +++ b/drivers/clk/keystone/sci-clk.c
> @@ -47,6 +47,7 @@ struct sci_clk_provider {
> * @node: Link for handling clocks probed via DT
> * @cached_req: Cached requested freq for determine rate calls
> * @cached_res: Cached result freq for determine rate calls
> + * @parent_id: Parent index for this clock
> */
> struct sci_clk {
> struct clk_hw hw;
> @@ -58,6 +59,7 @@ struct sci_clk {
> struct list_head node;
> unsigned long cached_req;
> unsigned long cached_res;
> + u8 parent_id;
you may need to restore rate as well
> };
>
> #define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw)
> @@ -237,9 +239,9 @@ static u8 sci_clk_get_parent(struct clk_hw *hw)
> return 0;
> }
>
> - parent_id = parent_id - clk->clk_id - 1;
> + clk->parent_id = (u8)(parent_id - clk->clk_id - 1);
>
> - return (u8)parent_id;
> + return clk->parent_id;
> }
>
> /**
> @@ -252,12 +254,24 @@ static u8 sci_clk_get_parent(struct clk_hw *hw)
> static int sci_clk_set_parent(struct clk_hw *hw, u8 index)
> {
> struct sci_clk *clk = to_sci_clk(hw);
> + int ret;
>
> clk->cached_req = 0;
>
> - return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
> - clk->clk_id,
> - index + 1 + clk->clk_id);
> + ret = clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
> + clk->clk_id,
> + index + 1 + clk->clk_id);
> + if (!ret)
> + clk->parent_id = index;
> +
> + return ret;
> +}
> +
> +static void sci_clk_restore_context(struct clk_hw *hw)
> +{
> + struct sci_clk *clk = to_sci_clk(hw);
> +
> + sci_clk_set_parent(hw, clk->parent_id);
You should restore, if this is BOARD_CFG managed
> }
>
> static const struct clk_ops sci_clk_ops = {
> @@ -269,6 +283,7 @@ static const struct clk_ops sci_clk_ops = {
> .set_rate = sci_clk_set_rate,
> .get_parent = sci_clk_get_parent,
> .set_parent = sci_clk_set_parent,
> + .restore_context = sci_clk_restore_context,
> };
>
> /**
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH RFC v2 3/4] clk: keystone: sci-clk: add restore_context() operation
2025-12-03 7:50 ` Kumar, Udit
@ 2025-12-03 14:10 ` Thomas Richard
0 siblings, 0 replies; 7+ messages in thread
From: Thomas Richard @ 2025-12-03 14:10 UTC (permalink / raw)
To: Kumar, Udit, Nishanth Menon, Tero Kristo, Santosh Shilimkar,
Michael Turquette, Stephen Boyd
Cc: Gregory CLEMENT, richard.genoud, Prasanth Mantena, Abhash Kumar,
Thomas Petazzoni, linux-arm-kernel, linux-kernel, linux-clk
Hi Udit,
On 12/3/25 8:50 AM, Kumar, Udit wrote:
>
> On 11/27/2025 2:08 PM, Thomas Richard (TI.com) wrote:
>> Implement the restore_context() operation to restore the clock parent
>> state. The parent index is saved in sci_clk struct during set_parent().
>> During clock registration, the core retrieves each clock’s parent using
>> get_parent() operation to ensure the internal clock tree reflects the
>> actual hardware state, including any configurations made by the
>> bootloader. So we also save the parent index in get_parent().
>>
>> Signed-off-by: Thomas Richard (TI.com) <thomas.richard@bootlin.com>
>> ---
>> drivers/clk/keystone/sci-clk.c | 25 ++++++++++++++++++++-----
>> 1 file changed, 20 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/
>> sci-clk.c
>> index a4b42811de55d..1e5dd01484d1c 100644
>> --- a/drivers/clk/keystone/sci-clk.c
>> +++ b/drivers/clk/keystone/sci-clk.c
>> @@ -47,6 +47,7 @@ struct sci_clk_provider {
>> * @node: Link for handling clocks probed via DT
>> * @cached_req: Cached requested freq for determine rate calls
>> * @cached_res: Cached result freq for determine rate calls
>> + * @parent_id: Parent index for this clock
>> */
>> struct sci_clk {
>> struct clk_hw hw;
>> @@ -58,6 +59,7 @@ struct sci_clk {
>> struct list_head node;
>> unsigned long cached_req;
>> unsigned long cached_res;
>> + u8 parent_id;
>
> you may need to restore rate as well
will do in v3.
>
>
>> };
>> #define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw)
>> @@ -237,9 +239,9 @@ static u8 sci_clk_get_parent(struct clk_hw *hw)
>> return 0;
>> }
>> - parent_id = parent_id - clk->clk_id - 1;
>> + clk->parent_id = (u8)(parent_id - clk->clk_id - 1);
>> - return (u8)parent_id;
>> + return clk->parent_id;
>> }
>> /**
>> @@ -252,12 +254,24 @@ static u8 sci_clk_get_parent(struct clk_hw *hw)
>> static int sci_clk_set_parent(struct clk_hw *hw, u8 index)
>> {
>> struct sci_clk *clk = to_sci_clk(hw);
>> + int ret;
>> clk->cached_req = 0;
>> - return clk->provider->ops->set_parent(clk->provider->sci, clk-
>> >dev_id,
>> - clk->clk_id,
>> - index + 1 + clk->clk_id);
>> + ret = clk->provider->ops->set_parent(clk->provider->sci, clk-
>> >dev_id,
>> + clk->clk_id,
>> + index + 1 + clk->clk_id);
>> + if (!ret)
>> + clk->parent_id = index;
>> +
>> + return ret;
>> +}
>> +
>> +static void sci_clk_restore_context(struct clk_hw *hw)
>> +{
>> + struct sci_clk *clk = to_sci_clk(hw);
>> +
>> + sci_clk_set_parent(hw, clk->parent_id);
>
> You should restore, if this is BOARD_CFG managed
restore_context() operation is called by clk_restore_context() for each
registered clock. And we call clk_restore_context() from ti_sci driver
only for BOARDCFG_MANAGED mode.
sci-clk driver cannot decide if clock context shall be restored or not.
Decision shall come from ti_sci as it knows the lpm mode.
Best Regards,
Thomas
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-12-03 14:10 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-27 8:38 [PATCH RFC v2 0/4] firmware: ti_sci: Introduce BOARDCFG_MANAGED mode for Jacinto family Thomas Richard (TI.com)
2025-11-27 8:38 ` [PATCH RFC v2 1/4] firmware: ti_sci: add BOARDCFG_MANAGED mode support Thomas Richard (TI.com)
2025-11-27 8:38 ` [PATCH RFC v2 2/4] firmware: ti_sci: handle IRQ restore in BOARDCFG_MANAGED mode during resume Thomas Richard (TI.com)
2025-11-27 8:38 ` [PATCH RFC v2 3/4] clk: keystone: sci-clk: add restore_context() operation Thomas Richard (TI.com)
2025-12-03 7:50 ` Kumar, Udit
2025-12-03 14:10 ` Thomas Richard
2025-11-27 8:38 ` [PATCH RFC v2 4/4] firmware: ti_sci: restore clock context during resume in BOARDCFG_MANAGED mode Thomas Richard (TI.com)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox