blob: 6dc1fcb336533e69c508d2fefae49c582504c455 [file] [log] [blame]
Etienne Carrierec6e9af32020-09-09 18:44:06 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
Etienne Carriere5f35e282022-05-31 18:09:26 +02003 * Copyright (C) 2019-2022 Linaro Limited
Etienne Carrierec6e9af32020-09-09 18:44:06 +02004 */
Patrick Delaunay1b585062021-10-28 19:13:12 +02005
6#define LOG_CATEGORY UCLASS_RESET
7
Etienne Carrierec6e9af32020-09-09 18:44:06 +02008#include <dm.h>
9#include <errno.h>
10#include <reset-uclass.h>
11#include <scmi_agent.h>
12#include <scmi_protocols.h>
13#include <asm/types.h>
14
15static int scmi_reset_set_level(struct reset_ctl *rst, bool assert_not_deassert)
16{
17 struct scmi_rd_reset_in in = {
18 .domain_id = rst->id,
19 .flags = assert_not_deassert ? SCMI_RD_RESET_FLAG_ASSERT : 0,
20 .reset_state = 0,
21 };
22 struct scmi_rd_reset_out out;
23 struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_RESET_DOMAIN,
24 SCMI_RESET_DOMAIN_RESET,
25 in, out);
26 int ret;
27
AKASHI Takahiro7b3aa372023-10-11 19:06:54 +090028 ret = devm_scmi_process_msg(rst->dev, &msg);
Etienne Carrierec6e9af32020-09-09 18:44:06 +020029 if (ret)
30 return ret;
31
32 return scmi_to_linux_errno(out.status);
33}
34
35static int scmi_reset_assert(struct reset_ctl *rst)
36{
37 return scmi_reset_set_level(rst, true);
38}
39
40static int scmi_reset_deassert(struct reset_ctl *rst)
41{
42 return scmi_reset_set_level(rst, false);
43}
44
45static int scmi_reset_request(struct reset_ctl *rst)
46{
47 struct scmi_rd_attr_in in = {
48 .domain_id = rst->id,
49 };
50 struct scmi_rd_attr_out out;
51 struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_RESET_DOMAIN,
52 SCMI_RESET_DOMAIN_ATTRIBUTES,
53 in, out);
54 int ret;
55
56 /*
57 * We don't really care about the attribute, just check
58 * the reset domain exists.
59 */
AKASHI Takahiro7b3aa372023-10-11 19:06:54 +090060 ret = devm_scmi_process_msg(rst->dev, &msg);
Etienne Carrierec6e9af32020-09-09 18:44:06 +020061 if (ret)
62 return ret;
63
64 return scmi_to_linux_errno(out.status);
65}
66
Etienne Carrierec6e9af32020-09-09 18:44:06 +020067static const struct reset_ops scmi_reset_domain_ops = {
68 .request = scmi_reset_request,
Etienne Carrierec6e9af32020-09-09 18:44:06 +020069 .rst_assert = scmi_reset_assert,
70 .rst_deassert = scmi_reset_deassert,
71};
72
Etienne Carriere5f35e282022-05-31 18:09:26 +020073static int scmi_reset_probe(struct udevice *dev)
74{
AKASHI Takahiro7b3aa372023-10-11 19:06:54 +090075 return devm_scmi_of_get_channel(dev);
Etienne Carriere5f35e282022-05-31 18:09:26 +020076}
77
Etienne Carrierec6e9af32020-09-09 18:44:06 +020078U_BOOT_DRIVER(scmi_reset_domain) = {
79 .name = "scmi_reset_domain",
80 .id = UCLASS_RESET,
81 .ops = &scmi_reset_domain_ops,
Etienne Carriere5f35e282022-05-31 18:09:26 +020082 .probe = scmi_reset_probe,
Etienne Carrierec6e9af32020-09-09 18:44:06 +020083};