1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2020 Linaro Limited.
4  */
5 
6 #define LOG_CATEGORY UCLASS_SCMI_AGENT
7 
8 #include <dm.h>
9 #include <errno.h>
10 #include <scmi_agent.h>
11 #include <scmi_agent-uclass.h>
12 #include <scmi_protocols.h>
13 #include <dm/device_compat.h>
14 #include <dm/device-internal.h>
15 #include <linux/compat.h>
16 
17 /**
18  * struct error_code - Helper structure for SCMI error code conversion
19  * @scmi:	SCMI error code
20  * @errno:	Related standard error number
21  */
22 struct error_code {
23 	int scmi;
24 	int errno;
25 };
26 
27 static const struct error_code scmi_linux_errmap[] = {
28 	{ .scmi = SCMI_NOT_SUPPORTED, .errno = -EOPNOTSUPP, },
29 	{ .scmi = SCMI_INVALID_PARAMETERS, .errno = -EINVAL, },
30 	{ .scmi = SCMI_DENIED, .errno = -EACCES, },
31 	{ .scmi = SCMI_NOT_FOUND, .errno = -ENOENT, },
32 	{ .scmi = SCMI_OUT_OF_RANGE, .errno = -ERANGE, },
33 	{ .scmi = SCMI_BUSY, .errno = -EBUSY, },
34 	{ .scmi = SCMI_COMMS_ERROR, .errno = -ECOMM, },
35 	{ .scmi = SCMI_GENERIC_ERROR, .errno = -EIO, },
36 	{ .scmi = SCMI_HARDWARE_ERROR, .errno = -EREMOTEIO, },
37 	{ .scmi = SCMI_PROTOCOL_ERROR, .errno = -EPROTO, },
38 };
39 
40 /**
41  * scmi_protocol_is_supported - check availability of protocol
42  * @dev:	SCMI agent device
43  * @proto_id:	Identifier of protocol
44  *
45  * check if the protocol, @proto_id, is provided by the SCMI agent,
46  * @dev.
47  *
48  * Return:	0 on success, error code otherwise
49  */
scmi_protocol_is_supported(struct udevice * dev,enum scmi_std_protocol proto_id)50 static bool scmi_protocol_is_supported(struct udevice *dev,
51 				       enum scmi_std_protocol proto_id)
52 {
53 	struct scmi_agent_priv *priv;
54 	int i;
55 
56 	if (proto_id == SCMI_PROTOCOL_ID_BASE)
57 		return true;
58 
59 	priv = dev_get_uclass_plat(dev);
60 	if (!priv) {
61 		dev_err(dev, "No priv data found\n");
62 		return false;
63 	}
64 
65 	for (i = 0; i < priv->num_protocols; i++)
66 		if (priv->protocols[i] == proto_id)
67 			return true;
68 
69 	return false;
70 }
71 
scmi_get_protocol(struct udevice * dev,enum scmi_std_protocol id)72 struct udevice *scmi_get_protocol(struct udevice *dev,
73 				  enum scmi_std_protocol id)
74 {
75 	struct scmi_agent_priv *priv;
76 	struct udevice *proto;
77 
78 	priv = dev_get_uclass_plat(dev);
79 	if (!priv) {
80 		dev_err(dev, "No priv data found\n");
81 		return NULL;
82 	}
83 
84 	switch (id) {
85 	case SCMI_PROTOCOL_ID_BASE:
86 		proto = priv->base_dev;
87 		break;
88 	case SCMI_PROTOCOL_ID_POWER_DOMAIN:
89 		proto = priv->pwdom_dev;
90 		break;
91 	case SCMI_PROTOCOL_ID_CLOCK:
92 		proto = priv->clock_dev;
93 		break;
94 	case SCMI_PROTOCOL_ID_RESET_DOMAIN:
95 		proto = priv->resetdom_dev;
96 		break;
97 	case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
98 		proto = priv->voltagedom_dev;
99 		break;
100 	case SCMI_PROTOCOL_ID_PINCTRL:
101 		proto = priv->pinctrl_dev;
102 		break;
103 	default:
104 		dev_err(dev, "Protocol not supported\n");
105 		proto = NULL;
106 		break;
107 	}
108 	if (proto && device_probe(proto))
109 		dev_err(dev, "Probe failed\n");
110 
111 	return proto;
112 }
113 
114 /**
115  * scmi_add_protocol - add protocol to agent
116  * @dev:	SCMI agent device
117  * @proto_id:	SCMI protocol ID
118  * @proto:	SCMI protocol device
119  *
120  * Associate the protocol instance, @proto, to the agent, @dev,
121  * for later use.
122  *
123  * Return:	0 on success, error code on failure
124  */
scmi_add_protocol(struct udevice * dev,enum scmi_std_protocol proto_id,struct udevice * proto)125 static int scmi_add_protocol(struct udevice *dev,
126 			     enum scmi_std_protocol proto_id,
127 			     struct udevice *proto)
128 {
129 	struct scmi_agent_priv *priv;
130 
131 	priv = dev_get_uclass_plat(dev);
132 	if (!priv) {
133 		dev_err(dev, "No priv data found\n");
134 		return -ENODEV;
135 	}
136 
137 	switch (proto_id) {
138 	case SCMI_PROTOCOL_ID_BASE:
139 		priv->base_dev = proto;
140 		break;
141 	case SCMI_PROTOCOL_ID_POWER_DOMAIN:
142 		priv->pwdom_dev = proto;
143 		break;
144 	case SCMI_PROTOCOL_ID_CLOCK:
145 		priv->clock_dev = proto;
146 		break;
147 	case SCMI_PROTOCOL_ID_RESET_DOMAIN:
148 		priv->resetdom_dev = proto;
149 		break;
150 	case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
151 		priv->voltagedom_dev = proto;
152 		break;
153 	case SCMI_PROTOCOL_ID_PINCTRL:
154 		priv->pinctrl_dev = proto;
155 		break;
156 	default:
157 		dev_err(dev, "Protocol not supported\n");
158 		return -EPROTO;
159 	}
160 
161 	return 0;
162 }
163 
scmi_to_linux_errno(s32 scmi_code)164 int scmi_to_linux_errno(s32 scmi_code)
165 {
166 	int n;
167 
168 	if (!scmi_code)
169 		return 0;
170 
171 	for (n = 0; n < ARRAY_SIZE(scmi_linux_errmap); n++)
172 		if (scmi_code == scmi_linux_errmap[n].scmi)
173 			return scmi_linux_errmap[n].errno;
174 
175 	return -EPROTO;
176 }
177 
find_scmi_protocol_device(struct udevice * dev)178 static struct udevice *find_scmi_protocol_device(struct udevice *dev)
179 {
180 	struct udevice *parent = NULL, *protocol;
181 
182 	for (protocol = dev; protocol; protocol = parent) {
183 		parent = dev_get_parent(protocol);
184 		if (!parent ||
185 		    device_get_uclass_id(parent) == UCLASS_SCMI_AGENT)
186 			break;
187 	}
188 
189 	if (!parent) {
190 		dev_err(dev, "Invalid SCMI device, agent not found\n");
191 		return NULL;
192 	}
193 
194 	return protocol;
195 }
196 
transport_dev_ops(struct udevice * dev)197 static const struct scmi_agent_ops *transport_dev_ops(struct udevice *dev)
198 {
199 	return (const struct scmi_agent_ops *)dev->driver->ops;
200 }
201 
202 /**
203  * scmi_of_get_channel() - Get SCMI channel handle
204  *
205  * @dev:	SCMI agent device
206  * @channel:	Output reference to the SCMI channel upon success
207  *
208  * On return, @channel will be set.
209  * Return	0 on success and a negative errno on failure
210  */
scmi_of_get_channel(struct udevice * dev,struct udevice * protocol,struct scmi_channel ** channel)211 static int scmi_of_get_channel(struct udevice *dev, struct udevice *protocol,
212 			       struct scmi_channel **channel)
213 {
214 	const struct scmi_agent_ops *ops;
215 
216 	ops = transport_dev_ops(dev);
217 	if (ops->of_get_channel)
218 		return ops->of_get_channel(dev, protocol, channel);
219 	else
220 		return -EPROTONOSUPPORT;
221 }
222 
devm_scmi_of_get_channel(struct udevice * dev)223 int devm_scmi_of_get_channel(struct udevice *dev)
224 {
225 	struct udevice *protocol;
226 	struct scmi_agent_proto_priv *priv;
227 	int ret;
228 
229 	protocol = find_scmi_protocol_device(dev);
230 	if (!protocol)
231 		return -ENODEV;
232 
233 	priv = dev_get_parent_priv(protocol);
234 	ret = scmi_of_get_channel(protocol->parent, protocol, &priv->channel);
235 	if (ret == -EPROTONOSUPPORT) {
236 		/* Drivers without a get_channel operator don't need a channel ref */
237 		priv->channel = NULL;
238 
239 		return 0;
240 	}
241 
242 	return ret;
243 }
244 
245 /**
246  * scmi_process_msg() - Send and process an SCMI message
247  *
248  * Send a message to an SCMI server.
249  * Caller sets scmi_msg::out_msg_sz to the output message buffer size.
250  *
251  * @dev:	SCMI agent device
252  * @channel:	Communication channel for the device
253  * @msg:	Message structure reference
254  *
255  * On return, scmi_msg::out_msg_sz stores the response payload size.
256  * Return:	0 on success and a negative errno on failure
257  */
scmi_process_msg(struct udevice * dev,struct scmi_channel * channel,struct scmi_msg * msg)258 static int scmi_process_msg(struct udevice *dev, struct scmi_channel *channel,
259 			    struct scmi_msg *msg)
260 {
261 	const struct scmi_agent_ops *ops;
262 
263 	ops = transport_dev_ops(dev);
264 	if (ops->process_msg)
265 		return ops->process_msg(dev, channel, msg);
266 	else
267 		return -EPROTONOSUPPORT;
268 }
269 
devm_scmi_process_msg(struct udevice * dev,struct scmi_msg * msg)270 int devm_scmi_process_msg(struct udevice *dev, struct scmi_msg *msg)
271 {
272 	struct udevice *protocol;
273 	struct scmi_agent_proto_priv *priv;
274 
275 	protocol = find_scmi_protocol_device(dev);
276 	if (!protocol)
277 		return -ENODEV;
278 
279 	priv = dev_get_parent_priv(protocol);
280 
281 	return scmi_process_msg(protocol->parent, priv->channel, msg);
282 }
283 
284 /**
285  * scmi_fill_base_info - get base information about SCMI server
286  * @agent:	SCMI agent device
287  * @dev:	SCMI protocol device
288  *
289  * By using Base protocol commands, collect the base information
290  * about SCMI server.
291  *
292  * Return: 0 on success, error code on failure
293  */
scmi_fill_base_info(struct udevice * agent,struct udevice * dev)294 static int scmi_fill_base_info(struct udevice *agent, struct udevice *dev)
295 {
296 	struct scmi_agent_priv *priv = dev_get_uclass_plat(agent);
297 	int ret;
298 
299 	ret = scmi_base_protocol_version(dev, &priv->version);
300 	if (ret) {
301 		dev_err(dev, "protocol_version() failed (%d)\n", ret);
302 		return ret;
303 	}
304 	/* check for required version */
305 	if (priv->version < SCMI_BASE_PROTOCOL_VERSION) {
306 		dev_err(dev, "base protocol version (%d) lower than expected\n",
307 			priv->version);
308 		return -EPROTO;
309 	}
310 
311 	ret = scmi_base_protocol_attrs(dev, &priv->num_agents,
312 				       &priv->num_protocols);
313 	if (ret) {
314 		dev_err(dev, "protocol_attrs() failed (%d)\n", ret);
315 		return ret;
316 	}
317 	ret = scmi_base_discover_vendor(dev, &priv->vendor);
318 	if (ret) {
319 		dev_err(dev, "base_discover_vendor() failed (%d)\n", ret);
320 		return ret;
321 	}
322 	ret = scmi_base_discover_sub_vendor(dev, &priv->sub_vendor);
323 	if (ret) {
324 		if (ret != -EOPNOTSUPP) {
325 			dev_err(dev, "base_discover_sub_vendor() failed (%d)\n",
326 				ret);
327 			return ret;
328 		}
329 		priv->sub_vendor = "NA";
330 	}
331 	ret = scmi_base_discover_impl_version(dev, &priv->impl_version);
332 	if (ret) {
333 		dev_err(dev, "base_discover_impl_version() failed (%d)\n",
334 			ret);
335 		return ret;
336 	}
337 
338 	ret = scmi_base_discover_agent(dev, 0xffffffff,
339 				       &priv->agent_id, &priv->agent_name);
340 	if (ret) {
341 		if (ret != -EOPNOTSUPP) {
342 			dev_err(dev,
343 				"base_discover_agent() failed for myself (%d)\n",
344 				ret);
345 			return ret;
346 		}
347 		priv->agent_id = 0xffffffff;
348 		priv->agent_name = "NA";
349 	}
350 
351 	ret = scmi_base_discover_list_protocols(dev, &priv->protocols);
352 	if (ret != priv->num_protocols) {
353 		dev_err(dev, "base_discover_list_protocols() failed (%d)\n",
354 			ret);
355 		return -EPROTO;
356 	}
357 
358 	return 0;
359 }
360 
scmi_proto_driver_get(unsigned int proto_id)361 static struct driver *scmi_proto_driver_get(unsigned int proto_id)
362 {
363 	struct scmi_proto_driver *start, *entry;
364 	int n_ents;
365 
366 	start = ll_entry_start(struct scmi_proto_driver, scmi_proto_driver);
367 	n_ents = ll_entry_count(struct scmi_proto_driver, scmi_proto_driver);
368 
369 	for (entry = start; entry != start + n_ents; entry++) {
370 		if (entry->match->proto_id == proto_id)
371 			return entry->driver;
372 	}
373 
374 	return NULL;
375 }
376 
377 /*
378  * SCMI agent devices binds devices of various uclasses depending on
379  * the FDT description. scmi_bind_protocol() is a generic bind sequence
380  * called by the uclass at bind stage, that is uclass post_bind.
381  */
scmi_bind_protocols(struct udevice * dev)382 static int scmi_bind_protocols(struct udevice *dev)
383 {
384 	int ret = 0;
385 	ofnode node;
386 	const char *name;
387 	struct driver *drv;
388 	struct udevice *agent, *proto;
389 
390 	if (!uclass_get_device(UCLASS_SCMI_AGENT, 1, &agent)) {
391 		/* This is a second SCMI agent */
392 		dev_err(dev, "Cannot have more than one SCMI agent\n");
393 		return -EEXIST;
394 	}
395 
396 	/* initialize the device from device tree */
397 	drv = DM_DRIVER_GET(scmi_base_drv);
398 	name = "scmi-base.0";
399 	ret = device_bind(dev, drv, name, NULL, ofnode_null(), &proto);
400 	if (ret) {
401 		dev_err(dev, "failed to bind base protocol\n");
402 		return ret;
403 	}
404 	ret = scmi_add_protocol(dev, SCMI_PROTOCOL_ID_BASE, proto);
405 	if (ret) {
406 		dev_err(dev, "failed to add protocol: %s, ret: %d\n",
407 			proto->name, ret);
408 		return ret;
409 	}
410 
411 	ret = device_probe(proto);
412 	if (ret) {
413 		dev_err(dev, "failed to probe base protocol\n");
414 		return ret;
415 	}
416 
417 	ret = scmi_fill_base_info(dev, proto);
418 	if (ret) {
419 		dev_err(dev, "failed to get base information\n");
420 		return ret;
421 	}
422 
423 	dev_for_each_subnode(node, dev) {
424 		u32 protocol_id;
425 
426 		if (!ofnode_is_enabled(node))
427 			continue;
428 
429 		if (ofnode_read_u32(node, "reg", &protocol_id))
430 			continue;
431 
432 		drv = NULL;
433 		name = ofnode_get_name(node);
434 
435 		if (!scmi_protocol_is_supported(dev, protocol_id))
436 			continue;
437 
438 		drv = scmi_proto_driver_get(protocol_id);
439 		if (!drv) {
440 			dev_dbg(dev, "Ignore unsupported SCMI protocol %#x\n",
441 				protocol_id);
442 			continue;
443 		}
444 
445 		ret = device_bind(dev, drv, name, NULL, node, &proto);
446 		if (ret) {
447 			dev_err(dev, "failed to bind %s protocol\n", drv->name);
448 			break;
449 		}
450 		ret = scmi_add_protocol(dev, protocol_id, proto);
451 		if (ret) {
452 			dev_err(dev, "failed to add protocol: %s, ret: %d\n",
453 				proto->name, ret);
454 			break;
455 		}
456 	}
457 
458 	return ret;
459 }
460 
461 UCLASS_DRIVER(scmi_agent) = {
462 	.id		= UCLASS_SCMI_AGENT,
463 	.name		= "scmi_agent",
464 	.post_bind	= scmi_bind_protocols,
465 	.per_device_plat_auto = sizeof(struct scmi_agent_priv),
466 	.per_child_auto	= sizeof(struct scmi_agent_proto_priv),
467 };
468