blob: aa4929aafaed7de3db260f56e9c39b7fe8c14e91 [file] [log] [blame]
Etienne Carriere2b412082020-09-09 18:44:01 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2020 Linaro Limited.
4 */
5
Patrick Delaunay5dd84d42021-02-24 11:19:44 +01006#define LOG_CATEGORY UCLASS_SCMI_AGENT
7
Etienne Carriere2b412082020-09-09 18:44:01 +02008#include <common.h>
9#include <dm.h>
Etienne Carriere2b412082020-09-09 18:44:01 +020010#include <errno.h>
11#include <mailbox.h>
12#include <scmi_agent.h>
13#include <scmi_agent-uclass.h>
Patrick Delaunayd4c9f682021-02-24 11:19:45 +010014#include <dm/device_compat.h>
Etienne Carriere2b412082020-09-09 18:44:01 +020015#include <dm/devres.h>
16#include <linux/compat.h>
17
18#include "smt.h"
19
20#define TIMEOUT_US_10MS 10000
21
22/**
23 * struct scmi_mbox_channel - Description of an SCMI mailbox transport
24 * @smt: Shared memory buffer
25 * @mbox: Mailbox channel description
26 * @timeout_us: Timeout in microseconds for the mailbox transfer
27 */
28struct scmi_mbox_channel {
29 struct scmi_smt smt;
30 struct mbox_chan mbox;
31 ulong timeout_us;
32};
33
Etienne Carriere05440292022-05-31 18:09:19 +020034static int scmi_mbox_process_msg(struct udevice *dev,
35 struct scmi_channel *channel,
36 struct scmi_msg *msg)
Etienne Carriere2b412082020-09-09 18:44:01 +020037{
Etienne Carriere3119e272021-11-08 08:56:09 +010038 struct scmi_mbox_channel *chan = dev_get_plat(dev);
Etienne Carriere2b412082020-09-09 18:44:01 +020039 int ret;
40
41 ret = scmi_write_msg_to_smt(dev, &chan->smt, msg);
42 if (ret)
43 return ret;
44
45 /* Give shm addr to mbox in case it is meaningful */
46 ret = mbox_send(&chan->mbox, chan->smt.buf);
47 if (ret) {
48 dev_err(dev, "Message send failed: %d\n", ret);
49 goto out;
50 }
51
52 /* Receive the response */
53 ret = mbox_recv(&chan->mbox, chan->smt.buf, chan->timeout_us);
54 if (ret) {
55 dev_err(dev, "Response failed: %d, abort\n", ret);
56 goto out;
57 }
58
59 ret = scmi_read_resp_from_smt(dev, &chan->smt, msg);
60
61out:
62 scmi_clear_smt_channel(&chan->smt);
63
64 return ret;
65}
66
Etienne Carriere3119e272021-11-08 08:56:09 +010067int scmi_mbox_of_to_plat(struct udevice *dev)
Etienne Carriere2b412082020-09-09 18:44:01 +020068{
Etienne Carriere3119e272021-11-08 08:56:09 +010069 struct scmi_mbox_channel *chan = dev_get_plat(dev);
Etienne Carriere2b412082020-09-09 18:44:01 +020070 int ret;
71
72 chan->timeout_us = TIMEOUT_US_10MS;
73
74 ret = mbox_get_by_index(dev, 0, &chan->mbox);
75 if (ret) {
76 dev_err(dev, "Failed to find mailbox: %d\n", ret);
Etienne Carriereadbf0fc2021-11-08 08:56:08 +010077 return ret;
Etienne Carriere2b412082020-09-09 18:44:01 +020078 }
79
80 ret = scmi_dt_get_smt_buffer(dev, &chan->smt);
81 if (ret)
82 dev_err(dev, "Failed to get shm resources: %d\n", ret);
83
Etienne Carriere2b412082020-09-09 18:44:01 +020084 return ret;
85}
86
87static const struct udevice_id scmi_mbox_ids[] = {
88 { .compatible = "arm,scmi" },
89 { }
90};
91
92static const struct scmi_agent_ops scmi_mbox_ops = {
93 .process_msg = scmi_mbox_process_msg,
94};
95
96U_BOOT_DRIVER(scmi_mbox) = {
97 .name = "scmi-over-mailbox",
98 .id = UCLASS_SCMI_AGENT,
99 .of_match = scmi_mbox_ids,
Etienne Carriere3119e272021-11-08 08:56:09 +0100100 .plat_auto = sizeof(struct scmi_mbox_channel),
101 .of_to_plat = scmi_mbox_of_to_plat,
Etienne Carriere2b412082020-09-09 18:44:01 +0200102 .ops = &scmi_mbox_ops,
103};