123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * Copyright (C) 2019-2020 Linaro Limited
- */
- #include <common.h>
- #include <clk-uclass.h>
- #include <dm.h>
- #include <scmi_agent.h>
- #include <scmi_protocols.h>
- #include <asm/types.h>
- static int scmi_clk_gate(struct clk *clk, int enable)
- {
- struct scmi_clk_state_in in = {
- .clock_id = clk->id,
- .attributes = enable,
- };
- struct scmi_clk_state_out out;
- struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
- SCMI_CLOCK_CONFIG_SET,
- in, out);
- int ret;
- ret = devm_scmi_process_msg(clk->dev->parent, &msg);
- if (ret)
- return ret;
- return scmi_to_linux_errno(out.status);
- }
- static int scmi_clk_enable(struct clk *clk)
- {
- return scmi_clk_gate(clk, 1);
- }
- static int scmi_clk_disable(struct clk *clk)
- {
- return scmi_clk_gate(clk, 0);
- }
- static ulong scmi_clk_get_rate(struct clk *clk)
- {
- struct scmi_clk_rate_get_in in = {
- .clock_id = clk->id,
- };
- struct scmi_clk_rate_get_out out;
- struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
- SCMI_CLOCK_RATE_GET,
- in, out);
- int ret;
- ret = devm_scmi_process_msg(clk->dev->parent, &msg);
- if (ret < 0)
- return ret;
- ret = scmi_to_linux_errno(out.status);
- if (ret < 0)
- return ret;
- return (ulong)(((u64)out.rate_msb << 32) | out.rate_lsb);
- }
- static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
- {
- struct scmi_clk_rate_set_in in = {
- .clock_id = clk->id,
- .flags = SCMI_CLK_RATE_ROUND_CLOSEST,
- .rate_lsb = (u32)rate,
- .rate_msb = (u32)((u64)rate >> 32),
- };
- struct scmi_clk_rate_set_out out;
- struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
- SCMI_CLOCK_RATE_SET,
- in, out);
- int ret;
- ret = devm_scmi_process_msg(clk->dev->parent, &msg);
- if (ret < 0)
- return ret;
- ret = scmi_to_linux_errno(out.status);
- if (ret < 0)
- return ret;
- return scmi_clk_get_rate(clk);
- }
- static const struct clk_ops scmi_clk_ops = {
- .enable = scmi_clk_enable,
- .disable = scmi_clk_disable,
- .get_rate = scmi_clk_get_rate,
- .set_rate = scmi_clk_set_rate,
- };
- U_BOOT_DRIVER(scmi_clock) = {
- .name = "scmi_clk",
- .id = UCLASS_CLK,
- .ops = &scmi_clk_ops,
- };
|