All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] clk: scmi: register all scmi clock by name with CCF
@ 2021-05-12 14:54 Etienne Carriere
  2021-05-12 14:54 ` [PATCH 2/2] firmware: scmi: fix sandbox and related test since clock discovery Etienne Carriere
  2021-05-15 15:20 ` [PATCH 1/2] clk: scmi: register all scmi clock by name with CCF Simon Glass
  0 siblings, 2 replies; 4+ messages in thread
From: Etienne Carriere @ 2021-05-12 14:54 UTC (permalink / raw)
  To: u-boot

From: Patrick Delaunay <patrick.delaunay@st.com>

This patch implements SCMI APIs to retrieve the number and the name of
SCMI clocks using SCMI_PROTOCOL_ATTRIBUTES messages.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
---
 drivers/clk/clk_scmi.c   | 101 +++++++++++++++++++++++++++++++++++++++
 include/scmi_protocols.h |  43 +++++++++++++++++
 2 files changed, 144 insertions(+)

diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
index 93a4819501..2a4c10a427 100644
--- a/drivers/clk/clk_scmi.c
+++ b/drivers/clk/clk_scmi.c
@@ -8,6 +8,50 @@
 #include <scmi_agent.h>
 #include <scmi_protocols.h>
 #include <asm/types.h>
+#include <linux/clk-provider.h>
+
+static u16 scmi_clk_get_num_clock(struct udevice *dev)
+{
+	struct scmi_clk_protocol_attr_out out;
+	struct scmi_msg msg = {
+		.protocol_id = SCMI_PROTOCOL_ID_CLOCK,
+		.message_id = SCMI_PROTOCOL_ATTRIBUTES,
+		.out_msg = (u8 *)&out,
+		.out_msg_sz = sizeof(out),
+	};
+	int ret;
+
+	ret = devm_scmi_process_msg(dev->parent, &msg);
+	if (ret)
+		return ret;
+
+	return out.attributes & SCMI_CLK_PROTO_ATTR_COUNT_MASK;
+}
+
+static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name)
+{
+	struct scmi_clk_attribute_in in = {
+		.clock_id = clkid,
+	};
+	struct scmi_clk_attribute_out out;
+	struct scmi_msg msg = {
+		.protocol_id = SCMI_PROTOCOL_ID_CLOCK,
+		.message_id = SCMI_CLOCK_ATTRIBUTES,
+		.in_msg = (u8 *)&in,
+		.in_msg_sz = sizeof(in),
+		.out_msg = (u8 *)&out,
+		.out_msg_sz = sizeof(out),
+	};
+	int ret;
+
+	ret = devm_scmi_process_msg(dev->parent, &msg);
+	if (ret)
+		return ret;
+
+	*name = out.clock_name;
+
+	return 0;
+}
 
 static int scmi_clk_gate(struct clk *clk, int enable)
 {
@@ -85,6 +129,62 @@ static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
 	return scmi_clk_get_rate(clk);
 }
 
+static struct clk *scmi_clk_register(struct udevice *dev, const char *name)
+{
+	struct clk *clk;
+	int ret;
+
+	clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+	if (!clk)
+		return ERR_PTR(-ENOMEM);
+
+	ret = clk_register(clk, dev->driver->name, name, dev->name);
+	if (ret) {
+		kfree(clk);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
+
+static int scmi_clk_probe(struct udevice *dev)
+{
+	struct clk *clk;
+	int num_clocks;
+	int i;
+
+	if (!CONFIG_IS_ENABLED(CLK_CCF))
+		return 0;
+
+	/* register CCF children: CLK UCLASS, no probed again */
+	if (device_get_uclass_id(dev->parent) == UCLASS_CLK)
+		return 0;
+
+	num_clocks = scmi_clk_get_num_clock(dev);
+	if (!num_clocks)
+		return 0;
+
+	for (i = 0; i < num_clocks; i++) {
+		char *name;
+
+		if (!scmi_clk_get_attibute(dev, i, &name)) {
+			char *clock_name = strdup(name);
+
+			clk = scmi_clk_register(dev, clock_name);
+			if (!IS_ERR(clk)) {
+				clk->id = i;
+				clk_request(dev, clk);
+			} else {
+				free(clock_name);
+
+				return PTR_ERR(clk);
+			}
+		}
+	}
+
+	return 0;
+}
+
 static const struct clk_ops scmi_clk_ops = {
 	.enable = scmi_clk_enable,
 	.disable = scmi_clk_disable,
@@ -96,4 +196,5 @@ U_BOOT_DRIVER(scmi_clock) = {
 	.name = "scmi_clk",
 	.id = UCLASS_CLK,
 	.ops = &scmi_clk_ops,
+	.probe = &scmi_clk_probe,
 };
diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
index 2db71697e8..3fc8ec95ef 100644
--- a/include/scmi_protocols.h
+++ b/include/scmi_protocols.h
@@ -40,22 +40,65 @@ enum scmi_status_code {
 	SCMI_PROTOCOL_ERROR = -10,
 };
 
+/*
+ * Generic message IDs
+ */
+enum scmi_discovery_id {
+	SCMI_PROTOCOL_VERSION = 0x0,
+	SCMI_PROTOCOL_ATTRIBUTES = 0x1,
+	SCMI_PROTOCOL_MESSAGE_ATTRIBUTES = 0x2,
+};
+
 /*
  * SCMI Clock Protocol
  */
 
 enum scmi_clock_message_id {
+	SCMI_CLOCK_ATTRIBUTES = 0x3,
 	SCMI_CLOCK_RATE_SET = 0x5,
 	SCMI_CLOCK_RATE_GET = 0x6,
 	SCMI_CLOCK_CONFIG_SET = 0x7,
 };
 
+#define SCMI_CLK_PROTO_ATTR_COUNT_MASK	GENMASK(15, 0)
 #define SCMI_CLK_RATE_ASYNC_NOTIFY	BIT(0)
 #define SCMI_CLK_RATE_ASYNC_NORESP	(BIT(0) | BIT(1))
 #define SCMI_CLK_RATE_ROUND_DOWN	0
 #define SCMI_CLK_RATE_ROUND_UP		BIT(2)
 #define SCMI_CLK_RATE_ROUND_CLOSEST	BIT(3)
 
+#define SCMI_CLOCK_NAME_LENGTH_MAX 16
+
+/**
+ * struct scmi_clk_get_nb_out - Response for SCMI_PROTOCOL_ATTRIBUTES command
+ * @status:	SCMI command status
+ * @attributes:	Attributes of the clock protocol, mainly number of clocks exposed
+ */
+struct scmi_clk_protocol_attr_out {
+	s32 status;
+	u32 attributes;
+};
+
+/**
+ * struct scmi_clk_attribute_in - Message payload for SCMI_CLOCK_ATTRIBUTES command
+ * @clock_id:	SCMI clock ID
+ */
+struct scmi_clk_attribute_in {
+	u32 clock_id;
+};
+
+/**
+ * struct scmi_clk_get_nb_out - Response payload for SCMI_CLOCK_ATTRIBUTES command
+ * @status:	SCMI command status
+ * @attributes:	clock attributes
+ * @clock_name:	name of the clock
+ */
+struct scmi_clk_attribute_out {
+	s32 status;
+	u32 attributes;
+	char clock_name[SCMI_CLOCK_NAME_LENGTH_MAX];
+};
+
 /**
  * struct scmi_clk_state_in - Message payload for CLOCK_CONFIG_SET command
  * @clock_id:	SCMI clock ID
-- 
2.17.1

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

end of thread, other threads:[~2021-05-15 15:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-12 14:54 [PATCH 1/2] clk: scmi: register all scmi clock by name with CCF Etienne Carriere
2021-05-12 14:54 ` [PATCH 2/2] firmware: scmi: fix sandbox and related test since clock discovery Etienne Carriere
2021-05-15 15:20   ` Simon Glass
2021-05-15 15:20 ` [PATCH 1/2] clk: scmi: register all scmi clock by name with CCF Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.