linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] exynos-acpm: add DVFS protocol and clock driver
@ 2025-08-19 11:45 Tudor Ambarus
  2025-08-19 11:45 ` [PATCH 1/3] dt-bindings: firmware: google,gs101-acpm-ipc: add clocks node Tudor Ambarus
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Tudor Ambarus @ 2025-08-19 11:45 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
	André Draszik, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Alim Akhtar, Sylwester Nawrocki,
	Chanwoo Choi
  Cc: linux-kernel, linux-samsung-soc, devicetree, linux-arm-kernel,
	linux-clk, willmcvicker, kernel-team, Tudor Ambarus

The APM firmware exposes clocks that are variable and index based.
These clocks don't provide an entire range of values between the limits
but only discrete points within the range. The firmware also manages
the voltage scaling appropriately with the clock scaling.

Add support for the ACPM DVFS protocol. It translates clock frequency
requests to messages that can be interpreted by the APM firmware.
Add an ACPM clock driver to model the clocks exposed by the APM firmware.

All patches can go through the samsung tree.

Thanks,
ta

Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
Tudor Ambarus (3):
      dt-bindings: firmware: google,gs101-acpm-ipc: add clocks node
      firmware: exynos-acpm: add DVFS protocol
      clk: samsung: add Exynos ACPM clock driver

 .../bindings/firmware/google,gs101-acpm-ipc.yaml   |  28 +++
 drivers/clk/samsung/Kconfig                        |  10 ++
 drivers/clk/samsung/Makefile                       |   1 +
 drivers/clk/samsung/clk-acpm.c                     | 192 +++++++++++++++++++++
 drivers/firmware/samsung/Makefile                  |   4 +-
 drivers/firmware/samsung/exynos-acpm-dvfs.c        |  85 +++++++++
 drivers/firmware/samsung/exynos-acpm-dvfs.h        |  21 +++
 drivers/firmware/samsung/exynos-acpm.c             |   5 +
 include/dt-bindings/clock/google,gs101.h           |  15 ++
 .../linux/firmware/samsung/exynos-acpm-protocol.h  |  10 ++
 10 files changed, 370 insertions(+), 1 deletion(-)
---
base-commit: c17b750b3ad9f45f2b6f7e6f7f4679844244f0b9
change-id: 20250819-acpm-clk-28d2a78e0307

Best regards,
-- 
Tudor Ambarus <tudor.ambarus@linaro.org>


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

* [PATCH 1/3] dt-bindings: firmware: google,gs101-acpm-ipc: add clocks node
  2025-08-19 11:45 [PATCH 0/3] exynos-acpm: add DVFS protocol and clock driver Tudor Ambarus
@ 2025-08-19 11:45 ` Tudor Ambarus
  2025-08-22 13:55   ` Rob Herring
  2025-08-19 11:45 ` [PATCH 2/3] firmware: exynos-acpm: add DVFS protocol Tudor Ambarus
  2025-08-19 11:45 ` [PATCH 3/3] clk: samsung: add Exynos ACPM clock driver Tudor Ambarus
  2 siblings, 1 reply; 16+ messages in thread
From: Tudor Ambarus @ 2025-08-19 11:45 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
	André Draszik, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Alim Akhtar, Sylwester Nawrocki,
	Chanwoo Choi
  Cc: linux-kernel, linux-samsung-soc, devicetree, linux-arm-kernel,
	linux-clk, willmcvicker, kernel-team, Tudor Ambarus

The firmware exposes clocks that can be controlled via the ACPM
interface. Describe the clocks exposed by the APM firmware.

Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
 .../bindings/firmware/google,gs101-acpm-ipc.yaml   | 28 ++++++++++++++++++++++
 include/dt-bindings/clock/google,gs101.h           | 15 ++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
index 9785aac3b5f34955bbfe2718eec48581d050954f..27cdf9c881ca680e78e77a0e14ffcffeba970871 100644
--- a/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
+++ b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
@@ -27,6 +27,29 @@ properties:
   mboxes:
     maxItems: 1
 
+  clocks:
+    description:
+      Clocks that are variable and index based. These clocks don't provide
+      an entire range of values between the limits but only discrete points
+      within the range. The firmware also manages the voltage scaling
+      appropriately with the clock scaling.
+    type: object
+    additionalProperties: false
+
+    properties:
+      compatible:
+        const: google,gs101-acpm-dvfs-clocks
+
+      "#clock-cells":
+        const: 1
+        description:
+          The argument is the ID of the clock contained by the firmware
+          messages.
+
+    required:
+      - compatible
+      - "#clock-cells"
+
   pmic:
     description: Child node describing the main PMIC.
     type: object
@@ -59,6 +82,11 @@ examples:
         mboxes = <&ap2apm_mailbox>;
         shmem = <&apm_sram>;
 
+        clocks {
+            compatible = "google,gs101-acpm-dvfs-clocks";
+            #clock-cells = <1>;
+        };
+
         pmic {
             compatible = "samsung,s2mpg10-pmic";
             interrupts-extended = <&gpa0 6 IRQ_TYPE_LEVEL_LOW>;
diff --git a/include/dt-bindings/clock/google,gs101.h b/include/dt-bindings/clock/google,gs101.h
index 442f9e9037dc33198a1cee20af62fc70bbd96605..f1d0df412fdd49b300db4ba88bc0b1674cf0cdf8 100644
--- a/include/dt-bindings/clock/google,gs101.h
+++ b/include/dt-bindings/clock/google,gs101.h
@@ -634,4 +634,19 @@
 #define CLK_GOUT_PERIC1_CLK_PERIC1_USI9_USI_CLK		45
 #define CLK_GOUT_PERIC1_SYSREG_PERIC1_PCLK		46
 
+#define CLK_ACPM_DVFS_MIF				0
+#define CLK_ACPM_DVFS_INT				1
+#define CLK_ACPM_DVFS_CPUCL0				2
+#define CLK_ACPM_DVFS_CPUCL1				3
+#define CLK_ACPM_DVFS_CPUCL2				4
+#define CLK_ACPM_DVFS_G3D				5
+#define CLK_ACPM_DVFS_G3DL2				6
+#define CLK_ACPM_DVFS_TPU				7
+#define CLK_ACPM_DVFS_INTCAM				8
+#define CLK_ACPM_DVFS_TNR				9
+#define CLK_ACPM_DVFS_CAM				10
+#define CLK_ACPM_DVFS_MFC				11
+#define CLK_ACPM_DVFS_DISP				12
+#define CLK_ACPM_DVFS_BO				13
+
 #endif /* _DT_BINDINGS_CLOCK_GOOGLE_GS101_H */

-- 
2.51.0.rc1.167.g924127e9c0-goog


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

* [PATCH 2/3] firmware: exynos-acpm: add DVFS protocol
  2025-08-19 11:45 [PATCH 0/3] exynos-acpm: add DVFS protocol and clock driver Tudor Ambarus
  2025-08-19 11:45 ` [PATCH 1/3] dt-bindings: firmware: google,gs101-acpm-ipc: add clocks node Tudor Ambarus
@ 2025-08-19 11:45 ` Tudor Ambarus
  2025-08-24 17:11   ` Krzysztof Kozlowski
  2025-08-19 11:45 ` [PATCH 3/3] clk: samsung: add Exynos ACPM clock driver Tudor Ambarus
  2 siblings, 1 reply; 16+ messages in thread
From: Tudor Ambarus @ 2025-08-19 11:45 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
	André Draszik, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Alim Akhtar, Sylwester Nawrocki,
	Chanwoo Choi
  Cc: linux-kernel, linux-samsung-soc, devicetree, linux-arm-kernel,
	linux-clk, willmcvicker, kernel-team, Tudor Ambarus

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        | 85 ++++++++++++++++++++++
 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, 124 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..ee457c1a3de2ff2e4395d9fc3ff4c13294473b2d
--- /dev/null
+++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c
@@ -0,0 +1,85 @@
+// 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)
+
+enum exynos_acpm_dvfs_func {
+	ACPM_DVFS_FREQ_REQ,
+	ACPM_DVFS_FREQ_GET,
+};
+
+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.rc1.167.g924127e9c0-goog


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

* [PATCH 3/3] clk: samsung: add Exynos ACPM clock driver
  2025-08-19 11:45 [PATCH 0/3] exynos-acpm: add DVFS protocol and clock driver Tudor Ambarus
  2025-08-19 11:45 ` [PATCH 1/3] dt-bindings: firmware: google,gs101-acpm-ipc: add clocks node Tudor Ambarus
  2025-08-19 11:45 ` [PATCH 2/3] firmware: exynos-acpm: add DVFS protocol Tudor Ambarus
@ 2025-08-19 11:45 ` Tudor Ambarus
  2025-08-21 18:34   ` Brian Masney
  2025-08-24 17:10   ` Krzysztof Kozlowski
  2 siblings, 2 replies; 16+ messages in thread
From: Tudor Ambarus @ 2025-08-19 11:45 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
	André Draszik, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Alim Akhtar, Sylwester Nawrocki,
	Chanwoo Choi
  Cc: linux-kernel, linux-samsung-soc, devicetree, linux-arm-kernel,
	linux-clk, willmcvicker, kernel-team, Tudor Ambarus

Add the Exynos ACPM clock driver. It provides support for clocks that
are controlled by firmware that implements the ACPM interface.

Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
 drivers/clk/samsung/Kconfig    |  10 +++
 drivers/clk/samsung/Makefile   |   1 +
 drivers/clk/samsung/clk-acpm.c | 192 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 203 insertions(+)

diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig
index 76a494e95027af26272e30876a87ac293bd56dfa..fe05212d7dd882adde9cd5c656cd0d58d501c42f 100644
--- a/drivers/clk/samsung/Kconfig
+++ b/drivers/clk/samsung/Kconfig
@@ -95,6 +95,16 @@ config EXYNOS_CLKOUT
 	  status of the certains clocks from SoC, but it could also be tied to
 	  other devices as an input clock.
 
+config EXYNOS_ACPM_CLK
+	tristate "Clock driver controlled via ACPM interface"
+	depends on EXYNOS_ACPM_PROTOCOL || COMPILE_TEST
+	help
+	  This driver provides support for clocks that are controlled by
+	  firmware that implements the ACPM interface.
+
+	  This driver uses the ACPM interface to interact with the firmware
+	  providing all the clock controlls.
+
 config TESLA_FSD_COMMON_CLK
 	bool "Tesla FSD clock controller support" if COMPILE_TEST
 	depends on COMMON_CLK_SAMSUNG
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index b77fe288e4bb484c68d1ff497acc0b83d132ea03..04b63436b12f6f5169575d74f54b105e97bbb052 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos990.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynosautov9.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynosautov920.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-gs101.o
+obj-$(CONFIG_EXYNOS_ACPM_CLK)		+= clk-acpm.o
 obj-$(CONFIG_S3C64XX_COMMON_CLK)	+= clk-s3c64xx.o
 obj-$(CONFIG_S5PV210_COMMON_CLK)	+= clk-s5pv210.o clk-s5pv210-audss.o
 obj-$(CONFIG_TESLA_FSD_COMMON_CLK)	+= clk-fsd.o
diff --git a/drivers/clk/samsung/clk-acpm.c b/drivers/clk/samsung/clk-acpm.c
new file mode 100644
index 0000000000000000000000000000000000000000..e3e648331ad54072876f52a63b11fe259a0b9be2
--- /dev/null
+++ b/drivers/clk/samsung/clk-acpm.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Samsung Exynos ACPM protocol based clock driver.
+ *
+ * Copyright 2025 Linaro Ltd.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/firmware/samsung/exynos-acpm-protocol.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include <dt-bindings/clock/google,gs101.h>
+
+struct acpm_clk {
+	u32 id;
+	struct clk_hw hw;
+	unsigned int acpm_chan_id;
+	const struct acpm_handle *handle;
+};
+
+#define to_acpm_clk(clk) container_of(clk, struct acpm_clk, hw)
+
+struct acpm_clk_variant {
+	unsigned int id;
+	const char *name;
+};
+
+struct acpm_clk_match_data {
+	const struct acpm_clk_variant *clks;
+	unsigned int nr_clks;
+	unsigned int acpm_chan_id;
+};
+
+static unsigned long acpm_clk_recalc_rate(struct clk_hw *hw,
+					  unsigned long parent_rate)
+{
+	struct acpm_clk *clk = to_acpm_clk(hw);
+
+	return clk->handle->ops.dvfs_ops.get_rate(clk->handle,
+					clk->acpm_chan_id, clk->id, 0);
+}
+
+static long acpm_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *parent_rate)
+{
+	/*
+	 * We can't figure out what rate it will be, so just return the
+	 * rate back to the caller. acpm_clk_recalc_rate() will be called
+	 * after the rate is set and we'll know what rate the clock is
+	 * running at then.
+	 */
+	return rate;
+}
+
+static int acpm_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+			     unsigned long parent_rate)
+{
+	struct acpm_clk *clk = to_acpm_clk(hw);
+
+	return clk->handle->ops.dvfs_ops.set_rate(clk->handle,
+					clk->acpm_chan_id, clk->id, rate);
+}
+
+static const struct clk_ops acpm_clk_ops = {
+	.recalc_rate = acpm_clk_recalc_rate,
+	.round_rate = acpm_clk_round_rate,
+	.set_rate = acpm_clk_set_rate,
+};
+
+static int __init acpm_clk_ops_init(struct device *dev, struct acpm_clk *aclk,
+				    const char *name)
+{
+	struct clk_init_data init = {};
+
+	init.name = name;
+	init.ops = &acpm_clk_ops;
+	aclk->hw.init = &init;
+
+	return devm_clk_hw_register(dev, &aclk->hw);
+}
+
+static int __init acpm_clk_probe(struct platform_device *pdev)
+{
+	const struct acpm_clk_match_data *match_data;
+	const struct acpm_handle *acpm_handle;
+	struct clk_hw_onecell_data *clk_data;
+	struct clk_hw **hws;
+	struct device *dev = &pdev->dev;
+	struct acpm_clk *aclks;
+	unsigned int acpm_chan_id;
+	int i, err, count;
+
+	acpm_handle = devm_acpm_get_by_node(dev, dev->parent->of_node);
+	if (IS_ERR(acpm_handle))
+		return dev_err_probe(dev, PTR_ERR(acpm_handle),
+				     "Failed to get acpm handle.\n");
+
+	match_data = of_device_get_match_data(dev);
+	if (!match_data)
+		return dev_err_probe(dev, -EINVAL,
+				     "Failed to get match data.\n");
+
+	count = match_data->nr_clks;
+	acpm_chan_id = match_data->acpm_chan_id;
+
+	clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count),
+				GFP_KERNEL);
+	if (!clk_data)
+		return -ENOMEM;
+
+	clk_data->num = count;
+	hws = clk_data->hws;
+
+	aclks = devm_kcalloc(dev, count, sizeof(*aclks), GFP_KERNEL);
+	if (!aclks)
+		return -ENOMEM;
+
+	for (i = 0; i < count; i++) {
+		const struct acpm_clk_variant *variant = &match_data->clks[i];
+		struct acpm_clk *aclk = &aclks[i];
+
+		hws[i] = &aclk->hw;
+
+		aclk->id = variant->id;
+		aclk->handle = acpm_handle;
+		aclk->acpm_chan_id = acpm_chan_id;
+
+		err = acpm_clk_ops_init(dev, aclk, variant->name);
+		if (err)
+			return dev_err_probe(dev, err,
+					     "Failed to register clock.\n");
+	}
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   clk_data);
+}
+
+#define ACPM_CLK(_id, cname)					\
+	{							\
+		.id		= _id,				\
+		.name		= cname,			\
+	}
+
+static const struct acpm_clk_variant gs101_acpm_clks[] __initconst = {
+	ACPM_CLK(CLK_ACPM_DVFS_MIF, "mif"),
+	ACPM_CLK(CLK_ACPM_DVFS_INT, "int"),
+	ACPM_CLK(CLK_ACPM_DVFS_CPUCL0, "cpucl0"),
+	ACPM_CLK(CLK_ACPM_DVFS_CPUCL1, "cpucl1"),
+	ACPM_CLK(CLK_ACPM_DVFS_CPUCL2, "cpucl2"),
+	ACPM_CLK(CLK_ACPM_DVFS_G3D, "g3d"),
+	ACPM_CLK(CLK_ACPM_DVFS_G3DL2, "g3dl2"),
+	ACPM_CLK(CLK_ACPM_DVFS_TPU, "tpu"),
+	ACPM_CLK(CLK_ACPM_DVFS_INTCAM, "intcam"),
+	ACPM_CLK(CLK_ACPM_DVFS_TNR, "tnr"),
+	ACPM_CLK(CLK_ACPM_DVFS_CAM, "cam"),
+	ACPM_CLK(CLK_ACPM_DVFS_MFC, "mfc"),
+	ACPM_CLK(CLK_ACPM_DVFS_DISP, "disp"),
+	ACPM_CLK(CLK_ACPM_DVFS_BO, "b0"),
+};
+
+static const struct acpm_clk_match_data acpm_clk_gs101 __initconst = {
+	.clks = gs101_acpm_clks,
+	.nr_clks = ARRAY_SIZE(gs101_acpm_clks),
+	.acpm_chan_id = 0,
+};
+
+static const struct of_device_id acpm_clk_ids[] __initconst = {
+	{
+		.compatible = "google,gs101-acpm-dvfs-clocks",
+		.data =  &acpm_clk_gs101,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, acpm_clk_ids);
+
+static struct platform_driver acpm_clk_driver __refdata = {
+	.driver	= {
+		.name = "acpm-clocks",
+		.of_match_table = acpm_clk_ids,
+	},
+	.probe = acpm_clk_probe,
+};
+module_platform_driver(acpm_clk_driver);
+
+MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus@linaro.org>");
+MODULE_DESCRIPTION("Samsung Exynos ACPM clock driver");
+MODULE_LICENSE("GPL");

-- 
2.51.0.rc1.167.g924127e9c0-goog


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

* Re: [PATCH 3/3] clk: samsung: add Exynos ACPM clock driver
  2025-08-19 11:45 ` [PATCH 3/3] clk: samsung: add Exynos ACPM clock driver Tudor Ambarus
@ 2025-08-21 18:34   ` Brian Masney
  2025-08-22  8:14     ` Tudor Ambarus
  2025-08-24 17:10   ` Krzysztof Kozlowski
  1 sibling, 1 reply; 16+ messages in thread
From: Brian Masney @ 2025-08-21 18:34 UTC (permalink / raw)
  To: Tudor Ambarus
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
	André Draszik, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Alim Akhtar, Sylwester Nawrocki,
	Chanwoo Choi, linux-kernel, linux-samsung-soc, devicetree,
	linux-arm-kernel, linux-clk, willmcvicker, kernel-team

Hi Tudor,

On Tue, Aug 19, 2025 at 11:45:38AM +0000, Tudor Ambarus wrote:
> +static long acpm_clk_round_rate(struct clk_hw *hw, unsigned long rate,
> +				unsigned long *parent_rate)
> +{
> +	/*
> +	 * We can't figure out what rate it will be, so just return the
> +	 * rate back to the caller. acpm_clk_recalc_rate() will be called
> +	 * after the rate is set and we'll know what rate the clock is
> +	 * running at then.
> +	 */
> +	return rate;
> +}

...

> +
> +static const struct clk_ops acpm_clk_ops = {
> +	.recalc_rate = acpm_clk_recalc_rate,
> +	.round_rate = acpm_clk_round_rate,
> +	.set_rate = acpm_clk_set_rate,
> +};

The round_rate clk op is deprecated. Please convert this over to use
determine_rate.

Brian


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

* Re: [PATCH 3/3] clk: samsung: add Exynos ACPM clock driver
  2025-08-21 18:34   ` Brian Masney
@ 2025-08-22  8:14     ` Tudor Ambarus
  2025-08-22 10:23       ` Brian Masney
  0 siblings, 1 reply; 16+ messages in thread
From: Tudor Ambarus @ 2025-08-22  8:14 UTC (permalink / raw)
  To: Brian Masney
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
	André Draszik, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Alim Akhtar, Sylwester Nawrocki,
	Chanwoo Choi, linux-kernel, linux-samsung-soc, devicetree,
	linux-arm-kernel, linux-clk, willmcvicker, kernel-team



On 8/21/25 7:34 PM, Brian Masney wrote:
> Hi Tudor,

Hi, Brian,

> 
> On Tue, Aug 19, 2025 at 11:45:38AM +0000, Tudor Ambarus wrote:
>> +static long acpm_clk_round_rate(struct clk_hw *hw, unsigned long rate,
>> +				unsigned long *parent_rate)
>> +{
>> +	/*
>> +	 * We can't figure out what rate it will be, so just return the
>> +	 * rate back to the caller. acpm_clk_recalc_rate() will be called
>> +	 * after the rate is set and we'll know what rate the clock is
>> +	 * running at then.
>> +	 */
>> +	return rate;
>> +}
> 
> ...
> 
>> +
>> +static const struct clk_ops acpm_clk_ops = {
>> +	.recalc_rate = acpm_clk_recalc_rate,
>> +	.round_rate = acpm_clk_round_rate,
>> +	.set_rate = acpm_clk_set_rate,
>> +};
> 
> The round_rate clk op is deprecated. Please convert this over to use
> determine_rate.

I can do that, sure. Shall I also update the kdoc for round_rate(), mark it
as deprecated and add your Suggested-by tag? It would help other newcomers.

Thanks,
ta

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

* Re: [PATCH 3/3] clk: samsung: add Exynos ACPM clock driver
  2025-08-22  8:14     ` Tudor Ambarus
@ 2025-08-22 10:23       ` Brian Masney
  2025-08-22 10:27         ` Tudor Ambarus
  0 siblings, 1 reply; 16+ messages in thread
From: Brian Masney @ 2025-08-22 10:23 UTC (permalink / raw)
  To: Tudor Ambarus
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
	André Draszik, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Alim Akhtar, Sylwester Nawrocki,
	Chanwoo Choi, linux-kernel, linux-samsung-soc, devicetree,
	linux-arm-kernel, linux-clk, willmcvicker, kernel-team

Hi Tudor,

On Fri, Aug 22, 2025 at 09:14:03AM +0100, Tudor Ambarus wrote:
> On 8/21/25 7:34 PM, Brian Masney wrote:
> > On Tue, Aug 19, 2025 at 11:45:38AM +0000, Tudor Ambarus wrote:
> >> +static long acpm_clk_round_rate(struct clk_hw *hw, unsigned long rate,
> >> +				unsigned long *parent_rate)
> >> +{
> >> +	/*
> >> +	 * We can't figure out what rate it will be, so just return the
> >> +	 * rate back to the caller. acpm_clk_recalc_rate() will be called
> >> +	 * after the rate is set and we'll know what rate the clock is
> >> +	 * running at then.
> >> +	 */
> >> +	return rate;
> >> +}
> > 
> > ...
> > 
> >> +
> >> +static const struct clk_ops acpm_clk_ops = {
> >> +	.recalc_rate = acpm_clk_recalc_rate,
> >> +	.round_rate = acpm_clk_round_rate,
> >> +	.set_rate = acpm_clk_set_rate,
> >> +};
> > 
> > The round_rate clk op is deprecated. Please convert this over to use
> > determine_rate.
> 
> I can do that, sure. Shall I also update the kdoc for round_rate(), mark it
> as deprecated and add your Suggested-by tag? It would help other newcomers.

I am working to remove round_rate from the clk core and the various
drivers. Your driver just needs to be updated similar to this:

https://lore.kernel.org/all/20250710-clk-imx-round-rate-v1-10-5726f98e6d8d@redhat.com/

Brian


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

* Re: [PATCH 3/3] clk: samsung: add Exynos ACPM clock driver
  2025-08-22 10:23       ` Brian Masney
@ 2025-08-22 10:27         ` Tudor Ambarus
  0 siblings, 0 replies; 16+ messages in thread
From: Tudor Ambarus @ 2025-08-22 10:27 UTC (permalink / raw)
  To: Brian Masney
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
	André Draszik, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Alim Akhtar, Sylwester Nawrocki,
	Chanwoo Choi, linux-kernel, linux-samsung-soc, devicetree,
	linux-arm-kernel, linux-clk, willmcvicker, kernel-team



On 8/22/25 11:23 AM, Brian Masney wrote:
> Hi Tudor,
> 
> On Fri, Aug 22, 2025 at 09:14:03AM +0100, Tudor Ambarus wrote:
>> On 8/21/25 7:34 PM, Brian Masney wrote:
>>> On Tue, Aug 19, 2025 at 11:45:38AM +0000, Tudor Ambarus wrote:
>>>> +static long acpm_clk_round_rate(struct clk_hw *hw, unsigned long rate,
>>>> +				unsigned long *parent_rate)
>>>> +{
>>>> +	/*
>>>> +	 * We can't figure out what rate it will be, so just return the
>>>> +	 * rate back to the caller. acpm_clk_recalc_rate() will be called
>>>> +	 * after the rate is set and we'll know what rate the clock is
>>>> +	 * running at then.
>>>> +	 */
>>>> +	return rate;
>>>> +}
>>>
>>> ...
>>>
>>>> +
>>>> +static const struct clk_ops acpm_clk_ops = {
>>>> +	.recalc_rate = acpm_clk_recalc_rate,
>>>> +	.round_rate = acpm_clk_round_rate,
>>>> +	.set_rate = acpm_clk_set_rate,
>>>> +};
>>>
>>> The round_rate clk op is deprecated. Please convert this over to use
>>> determine_rate.
>>
>> I can do that, sure. Shall I also update the kdoc for round_rate(), mark it
>> as deprecated and add your Suggested-by tag? It would help other newcomers.
> 
> I am working to remove round_rate from the clk core and the various

ah, great. Thanks for the pointer!

> drivers. Your driver just needs to be updated similar to this:
> 
> https://lore.kernel.org/all/20250710-clk-imx-round-rate-v1-10-5726f98e6d8d@redhat.com/
> 
> Brian
> 


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

* Re: [PATCH 1/3] dt-bindings: firmware: google,gs101-acpm-ipc: add clocks node
  2025-08-19 11:45 ` [PATCH 1/3] dt-bindings: firmware: google,gs101-acpm-ipc: add clocks node Tudor Ambarus
@ 2025-08-22 13:55   ` Rob Herring
  2025-08-22 15:03     ` Tudor Ambarus
  0 siblings, 1 reply; 16+ messages in thread
From: Rob Herring @ 2025-08-22 13:55 UTC (permalink / raw)
  To: Tudor Ambarus
  Cc: Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
	André Draszik, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Alim Akhtar, Sylwester Nawrocki,
	Chanwoo Choi, linux-kernel, linux-samsung-soc, devicetree,
	linux-arm-kernel, linux-clk, willmcvicker, kernel-team

On Tue, Aug 19, 2025 at 11:45:36AM +0000, Tudor Ambarus wrote:
> The firmware exposes clocks that can be controlled via the ACPM
> interface. Describe the clocks exposed by the APM firmware.

ACPM? APM is Advanced Power Management aka the predecessor to ACPI?


> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
> ---
>  .../bindings/firmware/google,gs101-acpm-ipc.yaml   | 28 ++++++++++++++++++++++
>  include/dt-bindings/clock/google,gs101.h           | 15 ++++++++++++
>  2 files changed, 43 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
> index 9785aac3b5f34955bbfe2718eec48581d050954f..27cdf9c881ca680e78e77a0e14ffcffeba970871 100644
> --- a/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
> +++ b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
> @@ -27,6 +27,29 @@ properties:
>    mboxes:
>      maxItems: 1
>  
> +  clocks:
> +    description:
> +      Clocks that are variable and index based. These clocks don't provide
> +      an entire range of values between the limits but only discrete points
> +      within the range. The firmware also manages the voltage scaling
> +      appropriately with the clock scaling.
> +    type: object
> +    additionalProperties: false

You don't need a child node. Just add #clock-cells to the parent.

> +
> +    properties:
> +      compatible:
> +        const: google,gs101-acpm-dvfs-clocks
> +
> +      "#clock-cells":
> +        const: 1
> +        description:
> +          The argument is the ID of the clock contained by the firmware
> +          messages.
> +
> +    required:
> +      - compatible
> +      - "#clock-cells"
> +
>    pmic:
>      description: Child node describing the main PMIC.
>      type: object
> @@ -59,6 +82,11 @@ examples:
>          mboxes = <&ap2apm_mailbox>;
>          shmem = <&apm_sram>;
>  
> +        clocks {
> +            compatible = "google,gs101-acpm-dvfs-clocks";
> +            #clock-cells = <1>;
> +        };
> +
>          pmic {
>              compatible = "samsung,s2mpg10-pmic";
>              interrupts-extended = <&gpa0 6 IRQ_TYPE_LEVEL_LOW>;
> diff --git a/include/dt-bindings/clock/google,gs101.h b/include/dt-bindings/clock/google,gs101.h
> index 442f9e9037dc33198a1cee20af62fc70bbd96605..f1d0df412fdd49b300db4ba88bc0b1674cf0cdf8 100644
> --- a/include/dt-bindings/clock/google,gs101.h
> +++ b/include/dt-bindings/clock/google,gs101.h
> @@ -634,4 +634,19 @@
>  #define CLK_GOUT_PERIC1_CLK_PERIC1_USI9_USI_CLK		45
>  #define CLK_GOUT_PERIC1_SYSREG_PERIC1_PCLK		46
>  
> +#define CLK_ACPM_DVFS_MIF				0
> +#define CLK_ACPM_DVFS_INT				1
> +#define CLK_ACPM_DVFS_CPUCL0				2
> +#define CLK_ACPM_DVFS_CPUCL1				3
> +#define CLK_ACPM_DVFS_CPUCL2				4
> +#define CLK_ACPM_DVFS_G3D				5
> +#define CLK_ACPM_DVFS_G3DL2				6
> +#define CLK_ACPM_DVFS_TPU				7
> +#define CLK_ACPM_DVFS_INTCAM				8
> +#define CLK_ACPM_DVFS_TNR				9
> +#define CLK_ACPM_DVFS_CAM				10
> +#define CLK_ACPM_DVFS_MFC				11
> +#define CLK_ACPM_DVFS_DISP				12
> +#define CLK_ACPM_DVFS_BO				13
> +
>  #endif /* _DT_BINDINGS_CLOCK_GOOGLE_GS101_H */
> 
> -- 
> 2.51.0.rc1.167.g924127e9c0-goog
> 

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

* Re: [PATCH 1/3] dt-bindings: firmware: google,gs101-acpm-ipc: add clocks node
  2025-08-22 13:55   ` Rob Herring
@ 2025-08-22 15:03     ` Tudor Ambarus
  2025-08-24 17:00       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 16+ messages in thread
From: Tudor Ambarus @ 2025-08-22 15:03 UTC (permalink / raw)
  To: Rob Herring
  Cc: Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
	André Draszik, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Alim Akhtar, Sylwester Nawrocki,
	Chanwoo Choi, linux-kernel, linux-samsung-soc, devicetree,
	linux-arm-kernel, linux-clk, willmcvicker, kernel-team

Hi, Rob,

On 8/22/25 2:55 PM, Rob Herring wrote:
> On Tue, Aug 19, 2025 at 11:45:36AM +0000, Tudor Ambarus wrote:
>> The firmware exposes clocks that can be controlled via the ACPM
>> interface. Describe the clocks exposed by the APM firmware.
> 
> ACPM? APM is Advanced Power Management aka the predecessor to ACPI?

ACPM (Alive Clock and Power Manager) is a firmware that operates on the                                 
APM (Active Power Management) module that handles overall power management                              
activities. APM is built around a GREBE processor.

In linux we have an ACPM protocol driver that communicates with the firmware
via mailbox channels. It's similar to arm,scmi if you want.

Cheers,
ta

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

* Re: [PATCH 1/3] dt-bindings: firmware: google,gs101-acpm-ipc: add clocks node
  2025-08-22 15:03     ` Tudor Ambarus
@ 2025-08-24 17:00       ` Krzysztof Kozlowski
  2025-08-25 12:01         ` Tudor Ambarus
  0 siblings, 1 reply; 16+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-24 17:00 UTC (permalink / raw)
  To: Tudor Ambarus, Rob Herring
  Cc: Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
	André Draszik, Michael Turquette, Stephen Boyd, Alim Akhtar,
	Sylwester Nawrocki, Chanwoo Choi, linux-kernel, linux-samsung-soc,
	devicetree, linux-arm-kernel, linux-clk, willmcvicker,
	kernel-team

On 22/08/2025 17:03, Tudor Ambarus wrote:
> Hi, Rob,
> 
> On 8/22/25 2:55 PM, Rob Herring wrote:
>> On Tue, Aug 19, 2025 at 11:45:36AM +0000, Tudor Ambarus wrote:
>>> The firmware exposes clocks that can be controlled via the ACPM
>>> interface. Describe the clocks exposed by the APM firmware.
>>
>> ACPM? APM is Advanced Power Management aka the predecessor to ACPI?
> 
> ACPM (Alive Clock and Power Manager) is a firmware that operates on the     

Please unwrap the acronym in one place of bindings commit msgs.

> APM (Active Power Management) module that handles overall power management                              
> activities. APM is built around a GREBE processor.
> 
> In linux we have an ACPM protocol driver that communicates with the firmware
> via mailbox channels. It's similar to arm,scmi if you want.

Rest of Rob's comment seems valid, so this also invalidates the DTS.


Best regards,
Krzysztof

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

* Re: [PATCH 3/3] clk: samsung: add Exynos ACPM clock driver
  2025-08-19 11:45 ` [PATCH 3/3] clk: samsung: add Exynos ACPM clock driver Tudor Ambarus
  2025-08-21 18:34   ` Brian Masney
@ 2025-08-24 17:10   ` Krzysztof Kozlowski
  2025-08-25 12:28     ` Tudor Ambarus
  1 sibling, 1 reply; 16+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-24 17:10 UTC (permalink / raw)
  To: Tudor Ambarus, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Peter Griffin, André Draszik, Michael Turquette,
	Stephen Boyd, Alim Akhtar, Sylwester Nawrocki, Chanwoo Choi
  Cc: linux-kernel, linux-samsung-soc, devicetree, linux-arm-kernel,
	linux-clk, willmcvicker, kernel-team

On 19/08/2025 13:45, Tudor Ambarus wrote:
> +
> +static int acpm_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> +			     unsigned long parent_rate)
> +{
> +	struct acpm_clk *clk = to_acpm_clk(hw);
> +
> +	return clk->handle->ops.dvfs_ops.set_rate(clk->handle,
> +					clk->acpm_chan_id, clk->id, rate);
> +}
> +
> +static const struct clk_ops acpm_clk_ops = {
> +	.recalc_rate = acpm_clk_recalc_rate,
> +	.round_rate = acpm_clk_round_rate,

This should be determine_rate. Check recent patchset from Brian Masney.
I applied the samsung bits from it to samsung soc tree.

...

> +
> +static int __init acpm_clk_probe(struct platform_device *pdev)

module probe for sure should not be __init.

> +{
> +	const struct acpm_clk_match_data *match_data;
> +	const struct acpm_handle *acpm_handle;
> +	struct clk_hw_onecell_data *clk_data;
> +	struct clk_hw **hws;
> +	struct device *dev = &pdev->dev;
> +	struct acpm_clk *aclks;
> +	unsigned int acpm_chan_id;
> +	int i, err, count;
> +
> +	acpm_handle = devm_acpm_get_by_node(dev, dev->parent->of_node);
> +	if (IS_ERR(acpm_handle))
> +		return dev_err_probe(dev, PTR_ERR(acpm_handle),
> +				     "Failed to get acpm handle.\n");
> +
> +	match_data = of_device_get_match_data(dev);
> +	if (!match_data)
> +		return dev_err_probe(dev, -EINVAL,
> +				     "Failed to get match data.\n");
> +
> +	count = match_data->nr_clks;
> +	acpm_chan_id = match_data->acpm_chan_id;
> +
> +	clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count),
> +				GFP_KERNEL);
> +	if (!clk_data)
> +		return -ENOMEM;
> +
> +	clk_data->num = count;
> +	hws = clk_data->hws;
> +
> +	aclks = devm_kcalloc(dev, count, sizeof(*aclks), GFP_KERNEL);
> +	if (!aclks)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < count; i++) {
> +		const struct acpm_clk_variant *variant = &match_data->clks[i];
> +		struct acpm_clk *aclk = &aclks[i];
> +
> +		hws[i] = &aclk->hw;
> +
> +		aclk->id = variant->id;
> +		aclk->handle = acpm_handle;
> +		aclk->acpm_chan_id = acpm_chan_id;
> +
> +		err = acpm_clk_ops_init(dev, aclk, variant->name);
> +		if (err)
> +			return dev_err_probe(dev, err,
> +					     "Failed to register clock.\n");
> +	}
> +
> +	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
> +					   clk_data);
> +}
> +
> +#define ACPM_CLK(_id, cname)					\
> +	{							\
> +		.id		= _id,				\
> +		.name		= cname,			\
> +	}
> +
> +static const struct acpm_clk_variant gs101_acpm_clks[] __initconst = {

This goes to top of the file, after struct declarations.

> +	ACPM_CLK(CLK_ACPM_DVFS_MIF, "mif"),
> +	ACPM_CLK(CLK_ACPM_DVFS_INT, "int"),
> +	ACPM_CLK(CLK_ACPM_DVFS_CPUCL0, "cpucl0"),
> +	ACPM_CLK(CLK_ACPM_DVFS_CPUCL1, "cpucl1"),
> +	ACPM_CLK(CLK_ACPM_DVFS_CPUCL2, "cpucl2"),
> +	ACPM_CLK(CLK_ACPM_DVFS_G3D, "g3d"),
> +	ACPM_CLK(CLK_ACPM_DVFS_G3DL2, "g3dl2"),
> +	ACPM_CLK(CLK_ACPM_DVFS_TPU, "tpu"),
> +	ACPM_CLK(CLK_ACPM_DVFS_INTCAM, "intcam"),
> +	ACPM_CLK(CLK_ACPM_DVFS_TNR, "tnr"),
> +	ACPM_CLK(CLK_ACPM_DVFS_CAM, "cam"),
> +	ACPM_CLK(CLK_ACPM_DVFS_MFC, "mfc"),
> +	ACPM_CLK(CLK_ACPM_DVFS_DISP, "disp"),
> +	ACPM_CLK(CLK_ACPM_DVFS_BO, "b0"),
> +};
> +
> +static const struct acpm_clk_match_data acpm_clk_gs101 __initconst = {

Are you going to have more of such clk_match_data? More variants?

> +	.clks = gs101_acpm_clks,
> +	.nr_clks = ARRAY_SIZE(gs101_acpm_clks),
> +	.acpm_chan_id = 0,
> +};
> +
> +static const struct of_device_id acpm_clk_ids[] __initconst = {
> +	{
> +		.compatible = "google,gs101-acpm-dvfs-clocks",
> +		.data =  &acpm_clk_gs101,
> +	},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, acpm_clk_ids);
> +
> +static struct platform_driver acpm_clk_driver __refdata = {

__refdata feels wrong here. There is a long standing issue with Samsung
clock drivers - I sent a patchset for that but it did failed testing.

But your code is even simpler - no CLK_OFDECLARE - so why is this refdata?


Best regards,
Krzysztof

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

* Re: [PATCH 2/3] firmware: exynos-acpm: add DVFS protocol
  2025-08-19 11:45 ` [PATCH 2/3] firmware: exynos-acpm: add DVFS protocol Tudor Ambarus
@ 2025-08-24 17:11   ` Krzysztof Kozlowski
  2025-08-25 12:02     ` Tudor Ambarus
  0 siblings, 1 reply; 16+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-24 17:11 UTC (permalink / raw)
  To: Tudor Ambarus, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Peter Griffin, André Draszik, Michael Turquette,
	Stephen Boyd, Alim Akhtar, Sylwester Nawrocki, Chanwoo Choi
  Cc: linux-kernel, linux-samsung-soc, devicetree, linux-arm-kernel,
	linux-clk, willmcvicker, kernel-team

On 19/08/2025 13:45, Tudor Ambarus wrote:
> 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        | 85 ++++++++++++++++++++++
>  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, 124 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..ee457c1a3de2ff2e4395d9fc3ff4c13294473b2d
> --- /dev/null
> +++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c
> @@ -0,0 +1,85 @@
> +// 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)
> +
> +enum exynos_acpm_dvfs_func {
> +	ACPM_DVFS_FREQ_REQ,
> +	ACPM_DVFS_FREQ_GET,
> +};

These are actual values for hardware/firmware? If so, please use rather
defines.

Rest looks good.

Best regards,
Krzysztof

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

* Re: [PATCH 1/3] dt-bindings: firmware: google,gs101-acpm-ipc: add clocks node
  2025-08-24 17:00       ` Krzysztof Kozlowski
@ 2025-08-25 12:01         ` Tudor Ambarus
  0 siblings, 0 replies; 16+ messages in thread
From: Tudor Ambarus @ 2025-08-25 12:01 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Rob Herring
  Cc: Krzysztof Kozlowski, Conor Dooley, Peter Griffin,
	André Draszik, Michael Turquette, Stephen Boyd, Alim Akhtar,
	Sylwester Nawrocki, Chanwoo Choi, linux-kernel, linux-samsung-soc,
	devicetree, linux-arm-kernel, linux-clk, willmcvicker,
	kernel-team



On 8/24/25 6:00 PM, Krzysztof Kozlowski wrote:
> On 22/08/2025 17:03, Tudor Ambarus wrote:
>> Hi, Rob,
>>
>> On 8/22/25 2:55 PM, Rob Herring wrote:
>>> On Tue, Aug 19, 2025 at 11:45:36AM +0000, Tudor Ambarus wrote:
>>>> The firmware exposes clocks that can be controlled via the ACPM
>>>> interface. Describe the clocks exposed by the APM firmware.
>>>
>>> ACPM? APM is Advanced Power Management aka the predecessor to ACPI?
>>
>> ACPM (Alive Clock and Power Manager) is a firmware that operates on the     
> 
> Please unwrap the acronym in one place of bindings commit msgs.

Okay.

> 
>> APM (Active Power Management) module that handles overall power management                              
>> activities. APM is built around a GREBE processor.
>>
>> In linux we have an ACPM protocol driver that communicates with the firmware
>> via mailbox channels. It's similar to arm,scmi if you want.
> 
> Rest of Rob's comment seems valid, so this also invalidates the DTS.
> 

I assume Rob and you are suggesting to drop the child node and add 
#clock-cells to the parent. Then define the specific clock data in
the parent and create a platform device by hand for the clocks with
platform_device_register_data().

I think this works well as what's used in the kernel is just the
clock mailbox channel id, clock IDs and clock names. And these
can be defined with parent's compatible data.

Please correct me if I understood it wrong. Cheers,
ta

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

* Re: [PATCH 2/3] firmware: exynos-acpm: add DVFS protocol
  2025-08-24 17:11   ` Krzysztof Kozlowski
@ 2025-08-25 12:02     ` Tudor Ambarus
  0 siblings, 0 replies; 16+ messages in thread
From: Tudor Ambarus @ 2025-08-25 12:02 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Peter Griffin, André Draszik,
	Michael Turquette, Stephen Boyd, Alim Akhtar, Sylwester Nawrocki,
	Chanwoo Choi
  Cc: linux-kernel, linux-samsung-soc, devicetree, linux-arm-kernel,
	linux-clk, willmcvicker, kernel-team



On 8/24/25 6:11 PM, Krzysztof Kozlowski wrote:
> On 19/08/2025 13:45, Tudor Ambarus wrote:
>> 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        | 85 ++++++++++++++++++++++
>>  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, 124 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..ee457c1a3de2ff2e4395d9fc3ff4c13294473b2d
>> --- /dev/null
>> +++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c
>> @@ -0,0 +1,85 @@
>> +// 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)
>> +
>> +enum exynos_acpm_dvfs_func {
>> +	ACPM_DVFS_FREQ_REQ,
>> +	ACPM_DVFS_FREQ_GET,
>> +};
> 
> These are actual values for hardware/firmware? If so, please use rather
> defines.

yes, they are. Will do, thanks!

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

* Re: [PATCH 3/3] clk: samsung: add Exynos ACPM clock driver
  2025-08-24 17:10   ` Krzysztof Kozlowski
@ 2025-08-25 12:28     ` Tudor Ambarus
  0 siblings, 0 replies; 16+ messages in thread
From: Tudor Ambarus @ 2025-08-25 12:28 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Peter Griffin, André Draszik,
	Michael Turquette, Stephen Boyd, Alim Akhtar, Sylwester Nawrocki,
	Chanwoo Choi
  Cc: linux-kernel, linux-samsung-soc, devicetree, linux-arm-kernel,
	linux-clk, willmcvicker, kernel-team



On 8/24/25 6:10 PM, Krzysztof Kozlowski wrote:
> On 19/08/2025 13:45, Tudor Ambarus wrote:
>> +
>> +static int acpm_clk_set_rate(struct clk_hw *hw, unsigned long rate,
>> +			     unsigned long parent_rate)
>> +{
>> +	struct acpm_clk *clk = to_acpm_clk(hw);
>> +
>> +	return clk->handle->ops.dvfs_ops.set_rate(clk->handle,
>> +					clk->acpm_chan_id, clk->id, rate);
>> +}
>> +
>> +static const struct clk_ops acpm_clk_ops = {
>> +	.recalc_rate = acpm_clk_recalc_rate,
>> +	.round_rate = acpm_clk_round_rate,
> 
> This should be determine_rate. Check recent patchset from Brian Masney.
> I applied the samsung bits from it to samsung soc tree.

Will do.

> 
> ...
> 
>> +
>> +static int __init acpm_clk_probe(struct platform_device *pdev)
> 
> module probe for sure should not be __init.

Ah, indeed, both __init and __refdata are wrong here, my appologies.
I assume they came from the time I considered the driver only needed
at boot time. Will drop them.
> 
>> +{
>> +	const struct acpm_clk_match_data *match_data;
>> +	const struct acpm_handle *acpm_handle;
>> +	struct clk_hw_onecell_data *clk_data;
>> +	struct clk_hw **hws;
>> +	struct device *dev = &pdev->dev;
>> +	struct acpm_clk *aclks;
>> +	unsigned int acpm_chan_id;
>> +	int i, err, count;
>> +
>> +	acpm_handle = devm_acpm_get_by_node(dev, dev->parent->of_node);
>> +	if (IS_ERR(acpm_handle))
>> +		return dev_err_probe(dev, PTR_ERR(acpm_handle),
>> +				     "Failed to get acpm handle.\n");
>> +
>> +	match_data = of_device_get_match_data(dev);
>> +	if (!match_data)
>> +		return dev_err_probe(dev, -EINVAL,
>> +				     "Failed to get match data.\n");
>> +
>> +	count = match_data->nr_clks;
>> +	acpm_chan_id = match_data->acpm_chan_id;
>> +
>> +	clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count),
>> +				GFP_KERNEL);
>> +	if (!clk_data)
>> +		return -ENOMEM;
>> +
>> +	clk_data->num = count;
>> +	hws = clk_data->hws;
>> +
>> +	aclks = devm_kcalloc(dev, count, sizeof(*aclks), GFP_KERNEL);
>> +	if (!aclks)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0; i < count; i++) {
>> +		const struct acpm_clk_variant *variant = &match_data->clks[i];
>> +		struct acpm_clk *aclk = &aclks[i];
>> +
>> +		hws[i] = &aclk->hw;
>> +
>> +		aclk->id = variant->id;
>> +		aclk->handle = acpm_handle;
>> +		aclk->acpm_chan_id = acpm_chan_id;
>> +
>> +		err = acpm_clk_ops_init(dev, aclk, variant->name);
>> +		if (err)
>> +			return dev_err_probe(dev, err,
>> +					     "Failed to register clock.\n");
>> +	}
>> +
>> +	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
>> +					   clk_data);
>> +}
>> +
>> +#define ACPM_CLK(_id, cname)					\
>> +	{							\
>> +		.id		= _id,				\
>> +		.name		= cname,			\
>> +	}
>> +
>> +static const struct acpm_clk_variant gs101_acpm_clks[] __initconst = {
> 
> This goes to top of the file, after struct declarations.

Okay, will do.
> 
>> +	ACPM_CLK(CLK_ACPM_DVFS_MIF, "mif"),
>> +	ACPM_CLK(CLK_ACPM_DVFS_INT, "int"),
>> +	ACPM_CLK(CLK_ACPM_DVFS_CPUCL0, "cpucl0"),
>> +	ACPM_CLK(CLK_ACPM_DVFS_CPUCL1, "cpucl1"),
>> +	ACPM_CLK(CLK_ACPM_DVFS_CPUCL2, "cpucl2"),
>> +	ACPM_CLK(CLK_ACPM_DVFS_G3D, "g3d"),
>> +	ACPM_CLK(CLK_ACPM_DVFS_G3DL2, "g3dl2"),
>> +	ACPM_CLK(CLK_ACPM_DVFS_TPU, "tpu"),
>> +	ACPM_CLK(CLK_ACPM_DVFS_INTCAM, "intcam"),
>> +	ACPM_CLK(CLK_ACPM_DVFS_TNR, "tnr"),
>> +	ACPM_CLK(CLK_ACPM_DVFS_CAM, "cam"),
>> +	ACPM_CLK(CLK_ACPM_DVFS_MFC, "mfc"),
>> +	ACPM_CLK(CLK_ACPM_DVFS_DISP, "disp"),
>> +	ACPM_CLK(CLK_ACPM_DVFS_BO, "b0"),
>> +};
>> +
>> +static const struct acpm_clk_match_data acpm_clk_gs101 __initconst = {
> 
> Are you going to have more of such clk_match_data? More variants?

I see downstream that gs101 and gs201 have the same clock IDs, clock names
and acpm_chan_id. But I can't tell about others. I assume it's safer to
assume there will be other variants.

Anyway, I'll pass this as platform data, if I understood correctly.

Thanks,
ta
> 
>> +	.clks = gs101_acpm_clks,
>> +	.nr_clks = ARRAY_SIZE(gs101_acpm_clks),
>> +	.acpm_chan_id = 0,
>> +};
>> +




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

end of thread, other threads:[~2025-08-25 12:28 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-19 11:45 [PATCH 0/3] exynos-acpm: add DVFS protocol and clock driver Tudor Ambarus
2025-08-19 11:45 ` [PATCH 1/3] dt-bindings: firmware: google,gs101-acpm-ipc: add clocks node Tudor Ambarus
2025-08-22 13:55   ` Rob Herring
2025-08-22 15:03     ` Tudor Ambarus
2025-08-24 17:00       ` Krzysztof Kozlowski
2025-08-25 12:01         ` Tudor Ambarus
2025-08-19 11:45 ` [PATCH 2/3] firmware: exynos-acpm: add DVFS protocol Tudor Ambarus
2025-08-24 17:11   ` Krzysztof Kozlowski
2025-08-25 12:02     ` Tudor Ambarus
2025-08-19 11:45 ` [PATCH 3/3] clk: samsung: add Exynos ACPM clock driver Tudor Ambarus
2025-08-21 18:34   ` Brian Masney
2025-08-22  8:14     ` Tudor Ambarus
2025-08-22 10:23       ` Brian Masney
2025-08-22 10:27         ` Tudor Ambarus
2025-08-24 17:10   ` Krzysztof Kozlowski
2025-08-25 12:28     ` Tudor Ambarus

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).