From: Tudor Ambarus <tudor.ambarus@linaro.org>
To: "Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Peter Griffin" <peter.griffin@linaro.org>,
"André Draszik" <andre.draszik@linaro.org>,
"Michael Turquette" <mturquette@baylibre.com>,
"Stephen Boyd" <sboyd@kernel.org>,
"Krzysztof Kozlowski" <krzk@kernel.org>,
"Alim Akhtar" <alim.akhtar@samsung.com>,
"Sylwester Nawrocki" <s.nawrocki@samsung.com>,
"Chanwoo Choi" <cw00.choi@samsung.com>,
"Catalin Marinas" <catalin.marinas@arm.com>,
"Will Deacon" <will@kernel.org>
Cc: linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org,
devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org,
willmcvicker@google.com, kernel-team@android.com,
Tudor Ambarus <tudor.ambarus@linaro.org>
Subject: [PATCH v2 2/5] firmware: exynos-acpm: add DVFS protocol
Date: Wed, 27 Aug 2025 12:42:12 +0000 [thread overview]
Message-ID: <20250827-acpm-clk-v2-2-de5c86b49b64@linaro.org> (raw)
In-Reply-To: <20250827-acpm-clk-v2-0-de5c86b49b64@linaro.org>
Add ACPM DVFS protocol handler. It constructs DVFS messages that
the APM firmware can understand.
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
drivers/firmware/samsung/Makefile | 4 +-
drivers/firmware/samsung/exynos-acpm-dvfs.c | 83 ++++++++++++++++++++++
drivers/firmware/samsung/exynos-acpm-dvfs.h | 21 ++++++
drivers/firmware/samsung/exynos-acpm.c | 5 ++
.../linux/firmware/samsung/exynos-acpm-protocol.h | 10 +++
5 files changed, 122 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/samsung/Makefile b/drivers/firmware/samsung/Makefile
index 7b4c9f6f34f54fd731886d97a615fe1aa97ba9a0..80d4f89b33a9558b68c9083da675c70ec3d05f19 100644
--- a/drivers/firmware/samsung/Makefile
+++ b/drivers/firmware/samsung/Makefile
@@ -1,4 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
-acpm-protocol-objs := exynos-acpm.o exynos-acpm-pmic.o
+acpm-protocol-objs := exynos-acpm.o
+acpm-protocol-objs += exynos-acpm-pmic.o
+acpm-protocol-objs += exynos-acpm-dvfs.o
obj-$(CONFIG_EXYNOS_ACPM_PROTOCOL) += acpm-protocol.o
diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.c b/drivers/firmware/samsung/exynos-acpm-dvfs.c
new file mode 100644
index 0000000000000000000000000000000000000000..a8763bf9374d41952a8d26124cc77baae0f1c723
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2025 Linaro Ltd.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/firmware/samsung/exynos-acpm-protocol.h>
+#include <linux/ktime.h>
+#include <linux/types.h>
+#include <linux/units.h>
+
+#include "exynos-acpm.h"
+#include "exynos-acpm-dvfs.h"
+
+#define ACPM_DVFS_ID GENMASK(11, 0)
+#define ACPM_DVFS_REQ_TYPE GENMASK(15, 0)
+
+#define ACPM_DVFS_FREQ_REQ 0
+#define ACPM_DVFS_FREQ_GET 1
+
+static void acpm_dvfs_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen,
+ unsigned int acpm_chan_id, bool response)
+{
+ xfer->acpm_chan_id = acpm_chan_id;
+ xfer->txd = cmd;
+ xfer->txlen = cmdlen;
+
+ if (response) {
+ xfer->rxd = cmd;
+ xfer->rxlen = cmdlen;
+ }
+}
+
+static void acpm_dvfs_init_set_rate_cmd(u32 cmd[4], unsigned int clk_id,
+ unsigned long rate)
+{
+ cmd[0] = FIELD_PREP(ACPM_DVFS_ID, clk_id);
+ cmd[1] = rate / HZ_PER_KHZ;
+ cmd[2] = FIELD_PREP(ACPM_DVFS_REQ_TYPE, ACPM_DVFS_FREQ_REQ);
+ cmd[3] = ktime_to_ms(ktime_get());
+}
+
+int acpm_dvfs_set_rate(const struct acpm_handle *handle,
+ unsigned int acpm_chan_id, unsigned int clk_id,
+ unsigned long rate)
+{
+ struct acpm_xfer xfer = {0};
+ u32 cmd[4];
+
+ acpm_dvfs_init_set_rate_cmd(cmd, clk_id, rate);
+ acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, false);
+
+ return acpm_do_xfer(handle, &xfer);
+}
+
+static void acpm_dvfs_init_get_rate_cmd(u32 cmd[4], unsigned int clk_id,
+ u32 dbg_val)
+{
+ cmd[0] = FIELD_PREP(ACPM_DVFS_ID, clk_id);
+ cmd[1] = dbg_val;
+ cmd[2] = FIELD_PREP(ACPM_DVFS_REQ_TYPE, ACPM_DVFS_FREQ_GET);
+ cmd[3] = ktime_to_ms(ktime_get());
+}
+
+unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle,
+ unsigned int acpm_chan_id, unsigned int clk_id,
+ u32 dbg_val)
+{
+ struct acpm_xfer xfer;
+ unsigned int cmd[4];
+ int ret;
+
+ acpm_dvfs_init_get_rate_cmd(cmd, clk_id, dbg_val);
+ acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, true);
+
+ ret = acpm_do_xfer(handle, &xfer);
+ if (ret)
+ return 0;
+
+ return xfer.rxd[1] * HZ_PER_KHZ;
+}
diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.h b/drivers/firmware/samsung/exynos-acpm-dvfs.h
new file mode 100644
index 0000000000000000000000000000000000000000..85a10bd535d118f2f36e9888e41b9b705b08ea59
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm-dvfs.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2020 Samsung Electronics Co., Ltd.
+ * Copyright 2020 Google LLC.
+ * Copyright 2025 Linaro Ltd.
+ */
+#ifndef __EXYNOS_ACPM_DVFS_H__
+#define __EXYNOS_ACPM_DVFS_H__
+
+#include <linux/types.h>
+
+struct acpm_handle;
+
+int acpm_dvfs_set_rate(const struct acpm_handle *handle,
+ unsigned int acpm_chan_id, unsigned int id,
+ unsigned long rate);
+unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle,
+ unsigned int acpm_chan_id, unsigned int clk_id,
+ u32 dbg_val);
+
+#endif /* __EXYNOS_ACPM_DVFS_H__ */
diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
index 3a69fe3234c75e0b5a93cbea6bb210dc6f69d2a6..9fa0335ccf5db32892fdf09e8d4b0a885a8f8fb5 100644
--- a/drivers/firmware/samsung/exynos-acpm.c
+++ b/drivers/firmware/samsung/exynos-acpm.c
@@ -29,6 +29,7 @@
#include <linux/types.h>
#include "exynos-acpm.h"
+#include "exynos-acpm-dvfs.h"
#include "exynos-acpm-pmic.h"
#define ACPM_PROTOCOL_SEQNUM GENMASK(21, 16)
@@ -590,8 +591,12 @@ static int acpm_channels_init(struct acpm_info *acpm)
*/
static void acpm_setup_ops(struct acpm_info *acpm)
{
+ struct acpm_dvfs_ops *dvfs_ops = &acpm->handle.ops.dvfs_ops;
struct acpm_pmic_ops *pmic_ops = &acpm->handle.ops.pmic_ops;
+ dvfs_ops->set_rate = acpm_dvfs_set_rate;
+ dvfs_ops->get_rate = acpm_dvfs_get_rate;
+
pmic_ops->read_reg = acpm_pmic_read_reg;
pmic_ops->bulk_read = acpm_pmic_bulk_read;
pmic_ops->write_reg = acpm_pmic_write_reg;
diff --git a/include/linux/firmware/samsung/exynos-acpm-protocol.h b/include/linux/firmware/samsung/exynos-acpm-protocol.h
index f628bf1862c25fa018a2fe5e7e123bf05c5254b9..e41055316bb578bb8250a1b1177f1059eeeb2611 100644
--- a/include/linux/firmware/samsung/exynos-acpm-protocol.h
+++ b/include/linux/firmware/samsung/exynos-acpm-protocol.h
@@ -13,6 +13,15 @@
struct acpm_handle;
struct device_node;
+struct acpm_dvfs_ops {
+ int (*set_rate)(const struct acpm_handle *handle,
+ unsigned int acpm_chan_id, unsigned int clk_id,
+ unsigned long rate);
+ unsigned long (*get_rate)(const struct acpm_handle *handle,
+ unsigned int acpm_chan_id,
+ unsigned int clk_id, u32 dbg_val);
+};
+
struct acpm_pmic_ops {
int (*read_reg)(const struct acpm_handle *handle,
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
@@ -32,6 +41,7 @@ struct acpm_pmic_ops {
};
struct acpm_ops {
+ struct acpm_dvfs_ops dvfs_ops;
struct acpm_pmic_ops pmic_ops;
};
--
2.51.0.261.g7ce5a0a67e-goog
next prev parent reply other threads:[~2025-08-27 12:42 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-27 12:42 [PATCH v2 0/5] exynos-acpm: add DVFS protocol and clock driver Tudor Ambarus
2025-08-27 12:42 ` [PATCH v2 1/5] dt-bindings: firmware: google,gs101-acpm-ipc: add #clock-cells Tudor Ambarus
2025-08-29 16:51 ` Rob Herring (Arm)
2025-08-31 10:40 ` Krzysztof Kozlowski
2025-09-01 6:25 ` Tudor Ambarus
2025-08-27 12:42 ` Tudor Ambarus [this message]
2025-08-27 12:42 ` [PATCH v2 3/5] clk: samsung: add Exynos ACPM clock driver Tudor Ambarus
2025-08-28 5:35 ` Tudor Ambarus
2025-08-27 12:42 ` [PATCH v2 4/5] firmware: exynos-acpm: register ACPM clocks dev Tudor Ambarus
2025-08-31 10:50 ` Krzysztof Kozlowski
2025-09-01 6:56 ` Tudor Ambarus
2025-09-01 7:48 ` Krzysztof Kozlowski
2025-09-01 8:43 ` Tudor Ambarus
2025-09-01 9:34 ` Krzysztof Kozlowski
2025-08-27 12:42 ` [PATCH v2 5/5] arm64: defconfig: enable Exynos ACPM clocks Tudor Ambarus
2025-08-31 10:42 ` [PATCH v2 0/5] exynos-acpm: add DVFS protocol and clock driver Krzysztof Kozlowski
2025-09-01 7:06 ` Tudor Ambarus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250827-acpm-clk-v2-2-de5c86b49b64@linaro.org \
--to=tudor.ambarus@linaro.org \
--cc=alim.akhtar@samsung.com \
--cc=andre.draszik@linaro.org \
--cc=catalin.marinas@arm.com \
--cc=conor+dt@kernel.org \
--cc=cw00.choi@samsung.com \
--cc=devicetree@vger.kernel.org \
--cc=kernel-team@android.com \
--cc=krzk+dt@kernel.org \
--cc=krzk@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=mturquette@baylibre.com \
--cc=peter.griffin@linaro.org \
--cc=robh@kernel.org \
--cc=s.nawrocki@samsung.com \
--cc=sboyd@kernel.org \
--cc=will@kernel.org \
--cc=willmcvicker@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).