blob: eb841d692b3460d5eaabf003ff33ef56d97f1731 [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
34static int scmi_mbox_process_msg(struct udevice *dev, struct scmi_msg *msg)
35{
36 struct scmi_mbox_channel *chan = dev_get_priv(dev);
37 int ret;
38
39 ret = scmi_write_msg_to_smt(dev, &chan->smt, msg);
40 if (ret)
41 return ret;
42
43 /* Give shm addr to mbox in case it is meaningful */
44 ret = mbox_send(&chan->mbox, chan->smt.buf);
45 if (ret) {
46 dev_err(dev, "Message send failed: %d\n", ret);
47 goto out;
48 }
49
50 /* Receive the response */
51 ret = mbox_recv(&chan->mbox, chan->smt.buf, chan->timeout_us);
52 if (ret) {
53 dev_err(dev, "Response failed: %d, abort\n", ret);
54 goto out;
55 }
56
57 ret = scmi_read_resp_from_smt(dev, &chan->smt, msg);
58
59out:
60 scmi_clear_smt_channel(&chan->smt);
61
62 return ret;
63}
64
65int scmi_mbox_probe(struct udevice *dev)
66{
67 struct scmi_mbox_channel *chan = dev_get_priv(dev);
68 int ret;
69
70 chan->timeout_us = TIMEOUT_US_10MS;
71
72 ret = mbox_get_by_index(dev, 0, &chan->mbox);
73 if (ret) {
74 dev_err(dev, "Failed to find mailbox: %d\n", ret);
Etienne Carriereadbf0fc2021-11-08 08:56:08 +010075 return ret;
Etienne Carriere2b412082020-09-09 18:44:01 +020076 }
77
78 ret = scmi_dt_get_smt_buffer(dev, &chan->smt);
79 if (ret)
80 dev_err(dev, "Failed to get shm resources: %d\n", ret);
81
Etienne Carriere2b412082020-09-09 18:44:01 +020082 return ret;
83}
84
85static const struct udevice_id scmi_mbox_ids[] = {
86 { .compatible = "arm,scmi" },
87 { }
88};
89
90static const struct scmi_agent_ops scmi_mbox_ops = {
91 .process_msg = scmi_mbox_process_msg,
92};
93
94U_BOOT_DRIVER(scmi_mbox) = {
95 .name = "scmi-over-mailbox",
96 .id = UCLASS_SCMI_AGENT,
97 .of_match = scmi_mbox_ids,
Simon Glass8a2b47f2020-12-03 16:55:17 -070098 .priv_auto = sizeof(struct scmi_mbox_channel),
Etienne Carriere2b412082020-09-09 18:44:01 +020099 .probe = scmi_mbox_probe,
100 .ops = &scmi_mbox_ops,
101};