blob: 8611edfc52da0e6624989ee93b96bbc101bde0f5 [file] [log] [blame]
Davide Grohmann32660f92022-04-27 16:49:07 +02001/*
Kristofer Jonssonb42bc0b2023-01-04 17:09:28 +01002 * Copyright 2022-2023 Arm Limited and/or its affiliates
Davide Grohmann32660f92022-04-27 16:49:07 +02003 *
4 * This program is free software and is provided to you under the terms of the
5 * GNU General Public License version 2 as published by the Free Software
6 * Foundation, and any use by you of this program is subject to the terms
7 * of such GNU licence.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, you can access it online at
16 * http://www.gnu.org/licenses/gpl-2.0.html.
17 *
18 * SPDX-License-Identifier: GPL-2.0-only
19 */
20
21/****************************************************************************
22 * Includes
23 ****************************************************************************/
24
25#include "ethosu_capabilities.h"
26
Kristofer Jonssond779a082023-01-04 17:09:47 +010027#include "ethosu_core_rpmsg.h"
Davide Grohmann32660f92022-04-27 16:49:07 +020028#include "ethosu_device.h"
29
30#include <linux/delay.h>
31#include <linux/dma-mapping.h>
32#include <linux/errno.h>
33
34/****************************************************************************
35 * Defines
36 ****************************************************************************/
37
38#define CAPABILITIES_RESP_TIMEOUT_MS 2000
39
40/****************************************************************************
41 * Functions
42 ****************************************************************************/
43
Kristofer Jonssonec477042023-01-20 13:38:13 +010044static inline int ethosu_capabilities_send(struct ethosu_capabilities *cap,
45 struct ethosu_mailbox *mailbox)
Davide Grohmann32660f92022-04-27 16:49:07 +020046{
Kristofer Jonssonec477042023-01-20 13:38:13 +010047 return ethosu_mailbox_capabilities_request(mailbox,
Davide Grohmann32660f92022-04-27 16:49:07 +020048 &cap->msg);
49}
50
51static void ethosu_capabilities_fail(struct ethosu_mailbox_msg *msg)
52{
53 struct ethosu_capabilities *cap =
54 container_of(msg, typeof(*cap), msg);
55
56 if (completion_done(&cap->done))
57 return;
58
59 cap->errno = -EFAULT;
60 complete(&cap->done);
61}
62
Kristofer Jonssonec477042023-01-20 13:38:13 +010063void ethosu_capability_rsp(struct ethosu_mailbox *mailbox,
Kristofer Jonssond779a082023-01-04 17:09:47 +010064 int msg_id,
Davide Grohmann32660f92022-04-27 16:49:07 +020065 struct ethosu_core_msg_capabilities_rsp *rsp)
66{
Kristofer Jonssonec477042023-01-20 13:38:13 +010067 struct device *dev = mailbox->dev;
Davide Grohmann32660f92022-04-27 16:49:07 +020068 struct ethosu_mailbox_msg *msg;
69 struct ethosu_capabilities *cap;
70
Kristofer Jonssonec477042023-01-20 13:38:13 +010071 msg = ethosu_mailbox_find(mailbox, msg_id);
Davide Grohmann32660f92022-04-27 16:49:07 +020072 if (IS_ERR(msg)) {
Kristofer Jonssonec477042023-01-20 13:38:13 +010073 dev_warn(dev,
Davide Grohmann32660f92022-04-27 16:49:07 +020074 "Id for capabilities msg not found. id=%d\n",
Kristofer Jonssond779a082023-01-04 17:09:47 +010075 msg_id);
Davide Grohmann32660f92022-04-27 16:49:07 +020076
77 return;
78 }
79
80 cap = container_of(msg, typeof(*cap), msg);
81
82 if (completion_done(&cap->done))
83 return;
84
85 cap->uapi->hw_id.version_status = rsp->version_status;
86 cap->uapi->hw_id.version_minor = rsp->version_minor;
87 cap->uapi->hw_id.version_major = rsp->version_major;
88 cap->uapi->hw_id.product_major = rsp->product_major;
89 cap->uapi->hw_id.arch_patch_rev = rsp->arch_patch_rev;
90 cap->uapi->hw_id.arch_minor_rev = rsp->arch_minor_rev;
91 cap->uapi->hw_id.arch_major_rev = rsp->arch_major_rev;
92 cap->uapi->driver_patch_rev = rsp->driver_patch_rev;
93 cap->uapi->driver_minor_rev = rsp->driver_minor_rev;
94 cap->uapi->driver_major_rev = rsp->driver_major_rev;
95 cap->uapi->hw_cfg.macs_per_cc = rsp->macs_per_cc;
96 cap->uapi->hw_cfg.cmd_stream_version = rsp->cmd_stream_version;
97 cap->uapi->hw_cfg.custom_dma = rsp->custom_dma;
98
99 cap->errno = 0;
100 complete(&cap->done);
101}
102
Kristofer Jonssonec477042023-01-20 13:38:13 +0100103int ethosu_capabilities_request(struct device *dev,
104 struct ethosu_mailbox *mailbox,
Davide Grohmann32660f92022-04-27 16:49:07 +0200105 struct ethosu_uapi_device_capabilities *uapi)
106{
107 struct ethosu_capabilities *cap;
108 int ret;
109 int timeout;
110
Kristofer Jonssonec477042023-01-20 13:38:13 +0100111 cap = devm_kzalloc(dev, sizeof(struct ethosu_capabilities),
Davide Grohmann32660f92022-04-27 16:49:07 +0200112 GFP_KERNEL);
113 if (!cap)
114 return -ENOMEM;
115
Kristofer Jonssonec477042023-01-20 13:38:13 +0100116 cap->dev = dev;
Davide Grohmann32660f92022-04-27 16:49:07 +0200117 cap->uapi = uapi;
118 init_completion(&cap->done);
119 cap->msg.fail = ethosu_capabilities_fail;
Davide Grohmann32660f92022-04-27 16:49:07 +0200120
Kristofer Jonssonec477042023-01-20 13:38:13 +0100121 ret = ethosu_mailbox_register(mailbox, &cap->msg);
Davide Grohmann32660f92022-04-27 16:49:07 +0200122 if (ret < 0)
123 goto kfree;
124
Kristofer Jonssonec477042023-01-20 13:38:13 +0100125 dev_info(dev, "Capabilities create. Id=%d, handle=0x%p\n",
Davide Grohmann32660f92022-04-27 16:49:07 +0200126 cap->msg.id, cap);
127
Kristofer Jonssonec477042023-01-20 13:38:13 +0100128 ret = ethosu_capabilities_send(cap, mailbox);
Davide Grohmann32660f92022-04-27 16:49:07 +0200129 if (0 != ret)
130 goto deregister;
131
132 /* Unlock the mutex before going to block on the condition */
Kristofer Jonssonec477042023-01-20 13:38:13 +0100133 device_unlock(dev);
Davide Grohmann32660f92022-04-27 16:49:07 +0200134
135 /* wait for response to arrive back */
136 timeout = wait_for_completion_timeout(&cap->done,
137 msecs_to_jiffies(
138 CAPABILITIES_RESP_TIMEOUT_MS));
139
140 /* take back the mutex before resuming to do anything */
Kristofer Jonssonec477042023-01-20 13:38:13 +0100141 device_lock(dev);
Davide Grohmann32660f92022-04-27 16:49:07 +0200142
143 if (0 == timeout) {
Kristofer Jonssonec477042023-01-20 13:38:13 +0100144 dev_warn(dev, "Capabilities response timeout");
Davide Grohmann32660f92022-04-27 16:49:07 +0200145 ret = -ETIME;
146 goto deregister;
147 }
148
149 if (cap->errno) {
150 ret = cap->errno;
151 goto deregister;
152 }
153
154deregister:
Kristofer Jonssonec477042023-01-20 13:38:13 +0100155 ethosu_mailbox_deregister(mailbox, &cap->msg);
Davide Grohmann32660f92022-04-27 16:49:07 +0200156
157kfree:
Kristofer Jonssonec477042023-01-20 13:38:13 +0100158 dev_info(dev, "Capabilities destroy. Id=%d, handle=0x%p\n",
Davide Grohmann32660f92022-04-27 16:49:07 +0200159 cap->msg.id, cap);
Kristofer Jonssonec477042023-01-20 13:38:13 +0100160 devm_kfree(dev, cap);
Davide Grohmann32660f92022-04-27 16:49:07 +0200161
162 return ret;
163}