1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2019-2020 Linaro Limited
6 #define LOG_CATEGORY UCLASS_CLK
9 #include <clk-uclass.h>
11 #include <scmi_agent.h>
12 #include <scmi_protocols.h>
13 #include <asm/types.h>
15 static int scmi_clk_gate(struct clk *clk, int enable)
17 struct scmi_clk_state_in in = {
21 struct scmi_clk_state_out out;
22 struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
23 SCMI_CLOCK_CONFIG_SET,
27 ret = devm_scmi_process_msg(clk->dev->parent, &msg);
31 return scmi_to_linux_errno(out.status);
34 static int scmi_clk_enable(struct clk *clk)
36 return scmi_clk_gate(clk, 1);
39 static int scmi_clk_disable(struct clk *clk)
41 return scmi_clk_gate(clk, 0);
44 static ulong scmi_clk_get_rate(struct clk *clk)
46 struct scmi_clk_rate_get_in in = {
49 struct scmi_clk_rate_get_out out;
50 struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
55 ret = devm_scmi_process_msg(clk->dev->parent, &msg);
59 ret = scmi_to_linux_errno(out.status);
63 return (ulong)(((u64)out.rate_msb << 32) | out.rate_lsb);
66 static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
68 struct scmi_clk_rate_set_in in = {
70 .flags = SCMI_CLK_RATE_ROUND_CLOSEST,
71 .rate_lsb = (u32)rate,
72 .rate_msb = (u32)((u64)rate >> 32),
74 struct scmi_clk_rate_set_out out;
75 struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
80 ret = devm_scmi_process_msg(clk->dev->parent, &msg);
84 ret = scmi_to_linux_errno(out.status);
88 return scmi_clk_get_rate(clk);
91 static const struct clk_ops scmi_clk_ops = {
92 .enable = scmi_clk_enable,
93 .disable = scmi_clk_disable,
94 .get_rate = scmi_clk_get_rate,
95 .set_rate = scmi_clk_set_rate,
98 U_BOOT_DRIVER(scmi_clock) = {
101 .ops = &scmi_clk_ops,