1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Texas Instruments System Control Interface Protocol Driver
4  * Based on drivers/firmware/ti_sci.c from Linux.
5  *
6  * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
7  *	Lokesh Vutla <lokeshvutla@ti.com>
8  */
9 
10 #include <common.h>
11 #include <dm.h>
12 #include <errno.h>
13 #include <log.h>
14 #include <mailbox.h>
15 #include <malloc.h>
16 #include <dm/device.h>
17 #include <dm/device_compat.h>
18 #include <dm/devres.h>
19 #include <linux/bitops.h>
20 #include <linux/compat.h>
21 #include <linux/err.h>
22 #include <linux/soc/ti/k3-sec-proxy.h>
23 #include <linux/soc/ti/ti_sci_protocol.h>
24 
25 #include "ti_sci.h"
26 
27 /* List of all TI SCI devices active in system */
28 static LIST_HEAD(ti_sci_list);
29 
30 /**
31  * struct ti_sci_xfer - Structure representing a message flow
32  * @tx_message:	Transmit message
33  * @rx_len:	Receive message length
34  */
35 struct ti_sci_xfer {
36 	struct k3_sec_proxy_msg tx_message;
37 	u8 rx_len;
38 };
39 
40 /**
41  * struct ti_sci_rm_type_map - Structure representing TISCI Resource
42  *				management representation of dev_ids.
43  * @dev_id:	TISCI device ID
44  * @type:	Corresponding id as identified by TISCI RM.
45  *
46  * Note: This is used only as a work around for using RM range apis
47  *	for AM654 SoC. For future SoCs dev_id will be used as type
48  *	for RM range APIs. In order to maintain ABI backward compatibility
49  *	type is not being changed for AM654 SoC.
50  */
51 struct ti_sci_rm_type_map {
52 	u32 dev_id;
53 	u16 type;
54 };
55 
56 /**
57  * struct ti_sci_desc - Description of SoC integration
58  * @default_host_id:	Host identifier representing the compute entity
59  * @max_rx_timeout_ms:	Timeout for communication with SoC (in Milliseconds)
60  * @max_msgs: Maximum number of messages that can be pending
61  *		  simultaneously in the system
62  * @max_msg_size: Maximum size of data per message that can be handled.
63  * @rm_type_map: RM resource type mapping structure.
64  */
65 struct ti_sci_desc {
66 	u8 default_host_id;
67 	int max_rx_timeout_ms;
68 	int max_msgs;
69 	int max_msg_size;
70 	struct ti_sci_rm_type_map *rm_type_map;
71 };
72 
73 /**
74  * struct ti_sci_info - Structure representing a TI SCI instance
75  * @dev:	Device pointer
76  * @desc:	SoC description for this instance
77  * @handle:	Instance of TI SCI handle to send to clients.
78  * @chan_tx:	Transmit mailbox channel
79  * @chan_rx:	Receive mailbox channel
80  * @xfer:	xfer info
81  * @list:	list head
82  * @is_secure:	Determines if the communication is through secure threads.
83  * @host_id:	Host identifier representing the compute entity
84  * @seq:	Seq id used for verification for tx and rx message.
85  */
86 struct ti_sci_info {
87 	struct udevice *dev;
88 	const struct ti_sci_desc *desc;
89 	struct ti_sci_handle handle;
90 	struct mbox_chan chan_tx;
91 	struct mbox_chan chan_rx;
92 	struct mbox_chan chan_notify;
93 	struct ti_sci_xfer xfer;
94 	struct list_head list;
95 	struct list_head dev_list;
96 	bool is_secure;
97 	u8 host_id;
98 	u8 seq;
99 };
100 
101 struct ti_sci_exclusive_dev {
102 	u32 id;
103 	u32 count;
104 	struct list_head list;
105 };
106 
107 #define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle)
108 
109 /**
110  * ti_sci_setup_one_xfer() - Setup one message type
111  * @info:	Pointer to SCI entity information
112  * @msg_type:	Message type
113  * @msg_flags:	Flag to set for the message
114  * @buf:	Buffer to be send to mailbox channel
115  * @tx_message_size: transmit message size
116  * @rx_message_size: receive message size. may be set to zero for send-only
117  *		     transactions.
118  *
119  * Helper function which is used by various command functions that are
120  * exposed to clients of this driver for allocating a message traffic event.
121  *
122  * Return: Corresponding ti_sci_xfer pointer if all went fine,
123  *	   else appropriate error pointer.
124  */
ti_sci_setup_one_xfer(struct ti_sci_info * info,u16 msg_type,u32 msg_flags,u32 * buf,size_t tx_message_size,size_t rx_message_size)125 static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info,
126 						 u16 msg_type, u32 msg_flags,
127 						 u32 *buf,
128 						 size_t tx_message_size,
129 						 size_t rx_message_size)
130 {
131 	struct ti_sci_xfer *xfer = &info->xfer;
132 	struct ti_sci_msg_hdr *hdr;
133 
134 	/* Ensure we have sane transfer sizes */
135 	if (rx_message_size > info->desc->max_msg_size ||
136 	    tx_message_size > info->desc->max_msg_size ||
137 	    (rx_message_size > 0 && rx_message_size < sizeof(*hdr)) ||
138 	    tx_message_size < sizeof(*hdr))
139 		return ERR_PTR(-ERANGE);
140 
141 	info->seq = ~info->seq;
142 	xfer->tx_message.buf = buf;
143 	xfer->tx_message.len = tx_message_size;
144 	xfer->rx_len = (u8)rx_message_size;
145 
146 	hdr = (struct ti_sci_msg_hdr *)buf;
147 	hdr->seq = info->seq;
148 	hdr->type = msg_type;
149 	hdr->host = info->host_id;
150 	hdr->flags = msg_flags;
151 
152 	return xfer;
153 }
154 
155 /**
156  * ti_sci_get_response() - Receive response from mailbox channel
157  * @info:	Pointer to SCI entity information
158  * @xfer:	Transfer to initiate and wait for response
159  * @chan:	Channel to receive the response
160  *
161  * Return: -ETIMEDOUT in case of no response, if transmit error,
162  *	   return corresponding error, else if all goes well,
163  *	   return 0.
164  */
ti_sci_get_response(struct ti_sci_info * info,struct ti_sci_xfer * xfer,struct mbox_chan * chan)165 static inline int ti_sci_get_response(struct ti_sci_info *info,
166 				      struct ti_sci_xfer *xfer,
167 				      struct mbox_chan *chan)
168 {
169 	struct k3_sec_proxy_msg *msg = &xfer->tx_message;
170 	struct ti_sci_secure_msg_hdr *secure_hdr;
171 	struct ti_sci_msg_hdr *hdr;
172 	int ret;
173 
174 	/* Receive the response */
175 	ret = mbox_recv(chan, msg, info->desc->max_rx_timeout_ms * 1000);
176 	if (ret) {
177 		dev_err(info->dev, "%s: Message receive failed. ret = %d\n",
178 			__func__, ret);
179 		return ret;
180 	}
181 
182 	/* ToDo: Verify checksum */
183 	if (info->is_secure) {
184 		secure_hdr = (struct ti_sci_secure_msg_hdr *)msg->buf;
185 		msg->buf = (u32 *)((void *)msg->buf + sizeof(*secure_hdr));
186 	}
187 
188 	/* msg is updated by mailbox driver */
189 	hdr = (struct ti_sci_msg_hdr *)msg->buf;
190 
191 	/* Sanity check for message response */
192 	if (hdr->seq != info->seq) {
193 		dev_dbg(info->dev, "%s: Message for %d is not expected\n",
194 			__func__, hdr->seq);
195 		return ret;
196 	}
197 
198 	if (msg->len > info->desc->max_msg_size) {
199 		dev_err(info->dev, "%s: Unable to handle %zu xfer (max %d)\n",
200 			__func__, msg->len, info->desc->max_msg_size);
201 		return -EINVAL;
202 	}
203 
204 	if (msg->len < xfer->rx_len) {
205 		dev_err(info->dev, "%s: Recv xfer %zu < expected %d length\n",
206 			__func__, msg->len, xfer->rx_len);
207 	}
208 
209 	return ret;
210 }
211 
212 /**
213  * ti_sci_do_xfer() - Do one transfer
214  * @info:	Pointer to SCI entity information
215  * @xfer:	Transfer to initiate and wait for response
216  *
217  * Return: 0 if all went fine, else return appropriate error.
218  */
ti_sci_do_xfer(struct ti_sci_info * info,struct ti_sci_xfer * xfer)219 static inline int ti_sci_do_xfer(struct ti_sci_info *info,
220 				 struct ti_sci_xfer *xfer)
221 {
222 	struct k3_sec_proxy_msg *msg = &xfer->tx_message;
223 	u8 secure_buf[info->desc->max_msg_size];
224 	struct ti_sci_secure_msg_hdr secure_hdr;
225 	int ret;
226 
227 	if (info->is_secure) {
228 		/* ToDo: get checksum of the entire message */
229 		secure_hdr.checksum = 0;
230 		secure_hdr.reserved = 0;
231 		memcpy(&secure_buf[sizeof(secure_hdr)], xfer->tx_message.buf,
232 		       xfer->tx_message.len);
233 
234 		xfer->tx_message.buf = (u32 *)secure_buf;
235 		xfer->tx_message.len += sizeof(secure_hdr);
236 
237 		if (xfer->rx_len)
238 			xfer->rx_len += sizeof(secure_hdr);
239 	}
240 
241 	/* Send the message */
242 	ret = mbox_send(&info->chan_tx, msg);
243 	if (ret) {
244 		dev_err(info->dev, "%s: Message sending failed. ret = %d\n",
245 			__func__, ret);
246 		return ret;
247 	}
248 
249 	/* Get response if requested */
250 	if (xfer->rx_len)
251 		ret = ti_sci_get_response(info, xfer, &info->chan_rx);
252 
253 	return ret;
254 }
255 
256 /**
257  * ti_sci_cmd_get_revision() - command to get the revision of the SCI entity
258  * @handle:	pointer to TI SCI handle
259  *
260  * Updates the SCI information in the internal data structure.
261  *
262  * Return: 0 if all went fine, else return appropriate error.
263  */
ti_sci_cmd_get_revision(struct ti_sci_handle * handle)264 static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle)
265 {
266 	struct ti_sci_msg_resp_version *rev_info;
267 	struct ti_sci_version_info *ver;
268 	struct ti_sci_msg_hdr hdr;
269 	struct ti_sci_info *info;
270 	struct ti_sci_xfer *xfer;
271 	int ret;
272 
273 	if (IS_ERR(handle))
274 		return PTR_ERR(handle);
275 	if (!handle)
276 		return -EINVAL;
277 
278 	info = handle_to_ti_sci_info(handle);
279 
280 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_VERSION,
281 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
282 				     (u32 *)&hdr, sizeof(struct ti_sci_msg_hdr),
283 				     sizeof(*rev_info));
284 	if (IS_ERR(xfer)) {
285 		ret = PTR_ERR(xfer);
286 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
287 		return ret;
288 	}
289 
290 	ret = ti_sci_do_xfer(info, xfer);
291 	if (ret) {
292 		dev_err(info->dev, "Mbox communication fail %d\n", ret);
293 		return ret;
294 	}
295 
296 	rev_info = (struct ti_sci_msg_resp_version *)xfer->tx_message.buf;
297 
298 	ver = &handle->version;
299 	ver->abi_major = rev_info->abi_major;
300 	ver->abi_minor = rev_info->abi_minor;
301 	ver->firmware_revision = rev_info->firmware_revision;
302 	strncpy(ver->firmware_description, rev_info->firmware_description,
303 		sizeof(ver->firmware_description));
304 
305 	return 0;
306 }
307 
308 /**
309  * ti_sci_is_response_ack() - Generic ACK/NACK message checkup
310  * @r:	pointer to response buffer
311  *
312  * Return: true if the response was an ACK, else returns false.
313  */
ti_sci_is_response_ack(void * r)314 static inline bool ti_sci_is_response_ack(void *r)
315 {
316 	struct ti_sci_msg_hdr *hdr = r;
317 
318 	return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
319 }
320 
321 /**
322  * cmd_set_board_config_using_msg() - Common command to send board configuration
323  *                                    message
324  * @handle:	pointer to TI SCI handle
325  * @msg_type:	One of the TISCI message types to set board configuration
326  * @addr:	Address where the board config structure is located
327  * @size:	Size of the board config structure
328  *
329  * Return: 0 if all went well, else returns appropriate error value.
330  */
cmd_set_board_config_using_msg(const struct ti_sci_handle * handle,u16 msg_type,u64 addr,u32 size)331 static int cmd_set_board_config_using_msg(const struct ti_sci_handle *handle,
332 					  u16 msg_type, u64 addr, u32 size)
333 {
334 	struct ti_sci_msg_board_config req;
335 	struct ti_sci_msg_hdr *resp;
336 	struct ti_sci_info *info;
337 	struct ti_sci_xfer *xfer;
338 	int ret = 0;
339 
340 	if (IS_ERR(handle))
341 		return PTR_ERR(handle);
342 	if (!handle)
343 		return -EINVAL;
344 
345 	info = handle_to_ti_sci_info(handle);
346 
347 	xfer = ti_sci_setup_one_xfer(info, msg_type,
348 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
349 				     (u32 *)&req, sizeof(req), sizeof(*resp));
350 	if (IS_ERR(xfer)) {
351 		ret = PTR_ERR(xfer);
352 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
353 		return ret;
354 	}
355 	req.boardcfgp_high = (addr >> 32) & 0xffffffff;
356 	req.boardcfgp_low = addr & 0xffffffff;
357 	req.boardcfg_size = size;
358 
359 	ret = ti_sci_do_xfer(info, xfer);
360 	if (ret) {
361 		dev_err(info->dev, "Mbox send fail %d\n", ret);
362 		return ret;
363 	}
364 
365 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
366 
367 	if (!ti_sci_is_response_ack(resp))
368 		return -ENODEV;
369 
370 	return ret;
371 }
372 
373 /**
374  * ti_sci_cmd_set_board_config() - Command to send board configuration message
375  * @handle:	pointer to TI SCI handle
376  * @addr:	Address where the board config structure is located
377  * @size:	Size of the board config structure
378  *
379  * Return: 0 if all went well, else returns appropriate error value.
380  */
ti_sci_cmd_set_board_config(const struct ti_sci_handle * handle,u64 addr,u32 size)381 static int ti_sci_cmd_set_board_config(const struct ti_sci_handle *handle,
382 				       u64 addr, u32 size)
383 {
384 	return cmd_set_board_config_using_msg(handle,
385 					      TI_SCI_MSG_BOARD_CONFIG,
386 					      addr, size);
387 }
388 
389 /**
390  * ti_sci_cmd_set_board_config_rm() - Command to send board resource
391  *				      management configuration
392  * @handle:	pointer to TI SCI handle
393  * @addr:	Address where the board RM config structure is located
394  * @size:	Size of the RM config structure
395  *
396  * Return: 0 if all went well, else returns appropriate error value.
397  */
398 static
ti_sci_cmd_set_board_config_rm(const struct ti_sci_handle * handle,u64 addr,u32 size)399 int ti_sci_cmd_set_board_config_rm(const struct ti_sci_handle *handle,
400 				   u64 addr, u32 size)
401 {
402 	return cmd_set_board_config_using_msg(handle,
403 					      TI_SCI_MSG_BOARD_CONFIG_RM,
404 					      addr, size);
405 }
406 
407 /**
408  * ti_sci_cmd_set_board_config_security() - Command to send board security
409  *					    configuration message
410  * @handle:	pointer to TI SCI handle
411  * @addr:	Address where the board security config structure is located
412  * @size:	Size of the security config structure
413  *
414  * Return: 0 if all went well, else returns appropriate error value.
415  */
416 static
ti_sci_cmd_set_board_config_security(const struct ti_sci_handle * handle,u64 addr,u32 size)417 int ti_sci_cmd_set_board_config_security(const struct ti_sci_handle *handle,
418 					 u64 addr, u32 size)
419 {
420 	return cmd_set_board_config_using_msg(handle,
421 					      TI_SCI_MSG_BOARD_CONFIG_SECURITY,
422 					      addr, size);
423 }
424 
425 /**
426  * ti_sci_cmd_set_board_config_pm() - Command to send board power and clock
427  *				      configuration message
428  * @handle:	pointer to TI SCI handle
429  * @addr:	Address where the board PM config structure is located
430  * @size:	Size of the PM config structure
431  *
432  * Return: 0 if all went well, else returns appropriate error value.
433  */
ti_sci_cmd_set_board_config_pm(const struct ti_sci_handle * handle,u64 addr,u32 size)434 static int ti_sci_cmd_set_board_config_pm(const struct ti_sci_handle *handle,
435 					  u64 addr, u32 size)
436 {
437 	return cmd_set_board_config_using_msg(handle,
438 					      TI_SCI_MSG_BOARD_CONFIG_PM,
439 					      addr, size);
440 }
441 
442 static struct ti_sci_exclusive_dev
ti_sci_get_exclusive_dev(struct list_head * dev_list,u32 id)443 *ti_sci_get_exclusive_dev(struct list_head *dev_list, u32 id)
444 {
445 	struct ti_sci_exclusive_dev *dev;
446 
447 	list_for_each_entry(dev, dev_list, list)
448 		if (dev->id == id)
449 			return dev;
450 
451 	return NULL;
452 }
453 
ti_sci_add_exclusive_dev(struct ti_sci_info * info,u32 id)454 static void ti_sci_add_exclusive_dev(struct ti_sci_info *info, u32 id)
455 {
456 	struct ti_sci_exclusive_dev *dev;
457 
458 	dev = ti_sci_get_exclusive_dev(&info->dev_list, id);
459 	if (dev) {
460 		dev->count++;
461 		return;
462 	}
463 
464 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
465 	dev->id = id;
466 	dev->count = 1;
467 	INIT_LIST_HEAD(&dev->list);
468 	list_add_tail(&dev->list, &info->dev_list);
469 }
470 
ti_sci_delete_exclusive_dev(struct ti_sci_info * info,u32 id)471 static void ti_sci_delete_exclusive_dev(struct ti_sci_info *info, u32 id)
472 {
473 	struct ti_sci_exclusive_dev *dev;
474 
475 	dev = ti_sci_get_exclusive_dev(&info->dev_list, id);
476 	if (!dev)
477 		return;
478 
479 	if (dev->count > 0)
480 		dev->count--;
481 }
482 
483 /**
484  * ti_sci_set_device_state() - Set device state helper
485  * @handle:	pointer to TI SCI handle
486  * @id:		Device identifier
487  * @flags:	flags to setup for the device
488  * @state:	State to move the device to
489  *
490  * Return: 0 if all went well, else returns appropriate error value.
491  */
ti_sci_set_device_state(const struct ti_sci_handle * handle,u32 id,u32 flags,u8 state)492 static int ti_sci_set_device_state(const struct ti_sci_handle *handle,
493 				   u32 id, u32 flags, u8 state)
494 {
495 	struct ti_sci_msg_req_set_device_state req;
496 	struct ti_sci_msg_hdr *resp;
497 	struct ti_sci_info *info;
498 	struct ti_sci_xfer *xfer;
499 	int ret = 0;
500 
501 	if (IS_ERR(handle))
502 		return PTR_ERR(handle);
503 	if (!handle)
504 		return -EINVAL;
505 
506 	info = handle_to_ti_sci_info(handle);
507 
508 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE,
509 				     flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
510 				     (u32 *)&req, sizeof(req), sizeof(*resp));
511 	if (IS_ERR(xfer)) {
512 		ret = PTR_ERR(xfer);
513 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
514 		return ret;
515 	}
516 	req.id = id;
517 	req.state = state;
518 
519 	ret = ti_sci_do_xfer(info, xfer);
520 	if (ret) {
521 		dev_err(info->dev, "Mbox send fail %d\n", ret);
522 		return ret;
523 	}
524 
525 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
526 
527 	if (!ti_sci_is_response_ack(resp))
528 		return -ENODEV;
529 
530 	if (state == MSG_DEVICE_SW_STATE_AUTO_OFF)
531 		ti_sci_delete_exclusive_dev(info, id);
532 	else if (flags & MSG_FLAG_DEVICE_EXCLUSIVE)
533 		ti_sci_add_exclusive_dev(info, id);
534 
535 	return ret;
536 }
537 
538 /**
539  * ti_sci_set_device_state_no_wait() - Set device state helper without
540  *				       requesting or waiting for a response.
541  * @handle:	pointer to TI SCI handle
542  * @id:		Device identifier
543  * @flags:	flags to setup for the device
544  * @state:	State to move the device to
545  *
546  * Return: 0 if all went well, else returns appropriate error value.
547  */
ti_sci_set_device_state_no_wait(const struct ti_sci_handle * handle,u32 id,u32 flags,u8 state)548 static int ti_sci_set_device_state_no_wait(const struct ti_sci_handle *handle,
549 					   u32 id, u32 flags, u8 state)
550 {
551 	struct ti_sci_msg_req_set_device_state req;
552 	struct ti_sci_info *info;
553 	struct ti_sci_xfer *xfer;
554 	int ret = 0;
555 
556 	if (IS_ERR(handle))
557 		return PTR_ERR(handle);
558 	if (!handle)
559 		return -EINVAL;
560 
561 	info = handle_to_ti_sci_info(handle);
562 
563 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE,
564 				     flags | TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
565 				     (u32 *)&req, sizeof(req), 0);
566 	if (IS_ERR(xfer)) {
567 		ret = PTR_ERR(xfer);
568 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
569 		return ret;
570 	}
571 	req.id = id;
572 	req.state = state;
573 
574 	ret = ti_sci_do_xfer(info, xfer);
575 	if (ret)
576 		dev_err(info->dev, "Mbox send fail %d\n", ret);
577 
578 	return ret;
579 }
580 
581 /**
582  * ti_sci_get_device_state() - Get device state helper
583  * @handle:	Handle to the device
584  * @id:		Device Identifier
585  * @clcnt:	Pointer to Context Loss Count
586  * @resets:	pointer to resets
587  * @p_state:	pointer to p_state
588  * @c_state:	pointer to c_state
589  *
590  * Return: 0 if all went fine, else return appropriate error.
591  */
ti_sci_get_device_state(const struct ti_sci_handle * handle,u32 id,u32 * clcnt,u32 * resets,u8 * p_state,u8 * c_state)592 static int ti_sci_get_device_state(const struct ti_sci_handle *handle,
593 				   u32 id,  u32 *clcnt,  u32 *resets,
594 				   u8 *p_state,  u8 *c_state)
595 {
596 	struct ti_sci_msg_resp_get_device_state *resp;
597 	struct ti_sci_msg_req_get_device_state req;
598 	struct ti_sci_info *info;
599 	struct ti_sci_xfer *xfer;
600 	int ret = 0;
601 
602 	if (IS_ERR(handle))
603 		return PTR_ERR(handle);
604 	if (!handle)
605 		return -EINVAL;
606 
607 	if (!clcnt && !resets && !p_state && !c_state)
608 		return -EINVAL;
609 
610 	info = handle_to_ti_sci_info(handle);
611 
612 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE,
613 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
614 				     (u32 *)&req, sizeof(req), sizeof(*resp));
615 	if (IS_ERR(xfer)) {
616 		ret = PTR_ERR(xfer);
617 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
618 		return ret;
619 	}
620 	req.id = id;
621 
622 	ret = ti_sci_do_xfer(info, xfer);
623 	if (ret) {
624 		dev_err(dev, "Mbox send fail %d\n", ret);
625 		return ret;
626 	}
627 
628 	resp = (struct ti_sci_msg_resp_get_device_state *)xfer->tx_message.buf;
629 	if (!ti_sci_is_response_ack(resp))
630 		return -ENODEV;
631 
632 	if (clcnt)
633 		*clcnt = resp->context_loss_count;
634 	if (resets)
635 		*resets = resp->resets;
636 	if (p_state)
637 		*p_state = resp->programmed_state;
638 	if (c_state)
639 		*c_state = resp->current_state;
640 
641 	return ret;
642 }
643 
644 /**
645  * ti_sci_cmd_get_device() - command to request for device managed by TISCI
646  * @handle:	Pointer to TISCI handle as retrieved by *ti_sci_get_handle
647  * @id:		Device Identifier
648  *
649  * Request for the device - NOTE: the client MUST maintain integrity of
650  * usage count by balancing get_device with put_device. No refcounting is
651  * managed by driver for that purpose.
652  *
653  * NOTE: The request is for exclusive access for the processor.
654  *
655  * Return: 0 if all went fine, else return appropriate error.
656  */
ti_sci_cmd_get_device(const struct ti_sci_handle * handle,u32 id)657 static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id)
658 {
659 	return ti_sci_set_device_state(handle, id, 0,
660 				       MSG_DEVICE_SW_STATE_ON);
661 }
662 
ti_sci_cmd_get_device_exclusive(const struct ti_sci_handle * handle,u32 id)663 static int ti_sci_cmd_get_device_exclusive(const struct ti_sci_handle *handle,
664 					   u32 id)
665 {
666 	return ti_sci_set_device_state(handle, id, MSG_FLAG_DEVICE_EXCLUSIVE,
667 				       MSG_DEVICE_SW_STATE_ON);
668 }
669 
670 /**
671  * ti_sci_cmd_idle_device() - Command to idle a device managed by TISCI
672  * @handle:	Pointer to TISCI handle as retrieved by *ti_sci_get_handle
673  * @id:		Device Identifier
674  *
675  * Request for the device - NOTE: the client MUST maintain integrity of
676  * usage count by balancing get_device with put_device. No refcounting is
677  * managed by driver for that purpose.
678  *
679  * Return: 0 if all went fine, else return appropriate error.
680  */
ti_sci_cmd_idle_device(const struct ti_sci_handle * handle,u32 id)681 static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id)
682 {
683 	return ti_sci_set_device_state(handle, id,
684 				       0,
685 				       MSG_DEVICE_SW_STATE_RETENTION);
686 }
687 
ti_sci_cmd_idle_device_exclusive(const struct ti_sci_handle * handle,u32 id)688 static int ti_sci_cmd_idle_device_exclusive(const struct ti_sci_handle *handle,
689 					    u32 id)
690 {
691 	return ti_sci_set_device_state(handle, id, MSG_FLAG_DEVICE_EXCLUSIVE,
692 				       MSG_DEVICE_SW_STATE_RETENTION);
693 }
694 
695 /**
696  * ti_sci_cmd_put_device() - command to release a device managed by TISCI
697  * @handle:	Pointer to TISCI handle as retrieved by *ti_sci_get_handle
698  * @id:		Device Identifier
699  *
700  * Request for the device - NOTE: the client MUST maintain integrity of
701  * usage count by balancing get_device with put_device. No refcounting is
702  * managed by driver for that purpose.
703  *
704  * Return: 0 if all went fine, else return appropriate error.
705  */
ti_sci_cmd_put_device(const struct ti_sci_handle * handle,u32 id)706 static int ti_sci_cmd_put_device(const struct ti_sci_handle *handle, u32 id)
707 {
708 	return ti_sci_set_device_state(handle, id, 0,
709 				       MSG_DEVICE_SW_STATE_AUTO_OFF);
710 }
711 
712 static
ti_sci_cmd_release_exclusive_devices(const struct ti_sci_handle * handle)713 int ti_sci_cmd_release_exclusive_devices(const struct ti_sci_handle *handle)
714 {
715 	struct ti_sci_exclusive_dev *dev, *tmp;
716 	struct ti_sci_info *info;
717 	int i, cnt;
718 
719 	info = handle_to_ti_sci_info(handle);
720 
721 	list_for_each_entry_safe(dev, tmp, &info->dev_list, list) {
722 		cnt = dev->count;
723 		debug("%s: id = %d, cnt = %d\n", __func__, dev->id, cnt);
724 		for (i = 0; i < cnt; i++)
725 			ti_sci_cmd_put_device(handle, dev->id);
726 	}
727 
728 	return 0;
729 }
730 
731 /**
732  * ti_sci_cmd_dev_is_valid() - Is the device valid
733  * @handle:	Pointer to TISCI handle as retrieved by *ti_sci_get_handle
734  * @id:		Device Identifier
735  *
736  * Return: 0 if all went fine and the device ID is valid, else return
737  * appropriate error.
738  */
ti_sci_cmd_dev_is_valid(const struct ti_sci_handle * handle,u32 id)739 static int ti_sci_cmd_dev_is_valid(const struct ti_sci_handle *handle, u32 id)
740 {
741 	u8 unused;
742 
743 	/* check the device state which will also tell us if the ID is valid */
744 	return ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &unused);
745 }
746 
747 /**
748  * ti_sci_cmd_dev_get_clcnt() - Get context loss counter
749  * @handle:	Pointer to TISCI handle
750  * @id:		Device Identifier
751  * @count:	Pointer to Context Loss counter to populate
752  *
753  * Return: 0 if all went fine, else return appropriate error.
754  */
ti_sci_cmd_dev_get_clcnt(const struct ti_sci_handle * handle,u32 id,u32 * count)755 static int ti_sci_cmd_dev_get_clcnt(const struct ti_sci_handle *handle, u32 id,
756 				    u32 *count)
757 {
758 	return ti_sci_get_device_state(handle, id, count, NULL, NULL, NULL);
759 }
760 
761 /**
762  * ti_sci_cmd_dev_is_idle() - Check if the device is requested to be idle
763  * @handle:	Pointer to TISCI handle
764  * @id:		Device Identifier
765  * @r_state:	true if requested to be idle
766  *
767  * Return: 0 if all went fine, else return appropriate error.
768  */
ti_sci_cmd_dev_is_idle(const struct ti_sci_handle * handle,u32 id,bool * r_state)769 static int ti_sci_cmd_dev_is_idle(const struct ti_sci_handle *handle, u32 id,
770 				  bool *r_state)
771 {
772 	int ret;
773 	u8 state;
774 
775 	if (!r_state)
776 		return -EINVAL;
777 
778 	ret = ti_sci_get_device_state(handle, id, NULL, NULL, &state, NULL);
779 	if (ret)
780 		return ret;
781 
782 	*r_state = (state == MSG_DEVICE_SW_STATE_RETENTION);
783 
784 	return 0;
785 }
786 
787 /**
788  * ti_sci_cmd_dev_is_stop() - Check if the device is requested to be stopped
789  * @handle:	Pointer to TISCI handle
790  * @id:		Device Identifier
791  * @r_state:	true if requested to be stopped
792  * @curr_state:	true if currently stopped.
793  *
794  * Return: 0 if all went fine, else return appropriate error.
795  */
ti_sci_cmd_dev_is_stop(const struct ti_sci_handle * handle,u32 id,bool * r_state,bool * curr_state)796 static int ti_sci_cmd_dev_is_stop(const struct ti_sci_handle *handle, u32 id,
797 				  bool *r_state,  bool *curr_state)
798 {
799 	int ret;
800 	u8 p_state, c_state;
801 
802 	if (!r_state && !curr_state)
803 		return -EINVAL;
804 
805 	ret =
806 	    ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
807 	if (ret)
808 		return ret;
809 
810 	if (r_state)
811 		*r_state = (p_state == MSG_DEVICE_SW_STATE_AUTO_OFF);
812 	if (curr_state)
813 		*curr_state = (c_state == MSG_DEVICE_HW_STATE_OFF);
814 
815 	return 0;
816 }
817 
818 /**
819  * ti_sci_cmd_dev_is_on() - Check if the device is requested to be ON
820  * @handle:	Pointer to TISCI handle
821  * @id:		Device Identifier
822  * @r_state:	true if requested to be ON
823  * @curr_state:	true if currently ON and active
824  *
825  * Return: 0 if all went fine, else return appropriate error.
826  */
ti_sci_cmd_dev_is_on(const struct ti_sci_handle * handle,u32 id,bool * r_state,bool * curr_state)827 static int ti_sci_cmd_dev_is_on(const struct ti_sci_handle *handle, u32 id,
828 				bool *r_state,  bool *curr_state)
829 {
830 	int ret;
831 	u8 p_state, c_state;
832 
833 	if (!r_state && !curr_state)
834 		return -EINVAL;
835 
836 	ret =
837 	    ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
838 	if (ret)
839 		return ret;
840 
841 	if (r_state)
842 		*r_state = (p_state == MSG_DEVICE_SW_STATE_ON);
843 	if (curr_state)
844 		*curr_state = (c_state == MSG_DEVICE_HW_STATE_ON);
845 
846 	return 0;
847 }
848 
849 /**
850  * ti_sci_cmd_dev_is_trans() - Check if the device is currently transitioning
851  * @handle:	Pointer to TISCI handle
852  * @id:		Device Identifier
853  * @curr_state:	true if currently transitioning.
854  *
855  * Return: 0 if all went fine, else return appropriate error.
856  */
ti_sci_cmd_dev_is_trans(const struct ti_sci_handle * handle,u32 id,bool * curr_state)857 static int ti_sci_cmd_dev_is_trans(const struct ti_sci_handle *handle, u32 id,
858 				   bool *curr_state)
859 {
860 	int ret;
861 	u8 state;
862 
863 	if (!curr_state)
864 		return -EINVAL;
865 
866 	ret = ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &state);
867 	if (ret)
868 		return ret;
869 
870 	*curr_state = (state == MSG_DEVICE_HW_STATE_TRANS);
871 
872 	return 0;
873 }
874 
875 /**
876  * ti_sci_cmd_set_device_resets() - command to set resets for device managed
877  *				    by TISCI
878  * @handle:	Pointer to TISCI handle as retrieved by *ti_sci_get_handle
879  * @id:		Device Identifier
880  * @reset_state: Device specific reset bit field
881  *
882  * Return: 0 if all went fine, else return appropriate error.
883  */
ti_sci_cmd_set_device_resets(const struct ti_sci_handle * handle,u32 id,u32 reset_state)884 static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle,
885 					u32 id, u32 reset_state)
886 {
887 	struct ti_sci_msg_req_set_device_resets req;
888 	struct ti_sci_msg_hdr *resp;
889 	struct ti_sci_info *info;
890 	struct ti_sci_xfer *xfer;
891 	int ret = 0;
892 
893 	if (IS_ERR(handle))
894 		return PTR_ERR(handle);
895 	if (!handle)
896 		return -EINVAL;
897 
898 	info = handle_to_ti_sci_info(handle);
899 
900 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_DEVICE_RESETS,
901 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
902 				     (u32 *)&req, sizeof(req), sizeof(*resp));
903 	if (IS_ERR(xfer)) {
904 		ret = PTR_ERR(xfer);
905 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
906 		return ret;
907 	}
908 	req.id = id;
909 	req.resets = reset_state;
910 
911 	ret = ti_sci_do_xfer(info, xfer);
912 	if (ret) {
913 		dev_err(info->dev, "Mbox send fail %d\n", ret);
914 		return ret;
915 	}
916 
917 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
918 
919 	if (!ti_sci_is_response_ack(resp))
920 		return -ENODEV;
921 
922 	return ret;
923 }
924 
925 /**
926  * ti_sci_cmd_get_device_resets() - Get reset state for device managed
927  *				    by TISCI
928  * @handle:		Pointer to TISCI handle
929  * @id:			Device Identifier
930  * @reset_state:	Pointer to reset state to populate
931  *
932  * Return: 0 if all went fine, else return appropriate error.
933  */
ti_sci_cmd_get_device_resets(const struct ti_sci_handle * handle,u32 id,u32 * reset_state)934 static int ti_sci_cmd_get_device_resets(const struct ti_sci_handle *handle,
935 					u32 id, u32 *reset_state)
936 {
937 	return ti_sci_get_device_state(handle, id, NULL, reset_state, NULL,
938 				       NULL);
939 }
940 
941 /**
942  * ti_sci_set_clock_state() - Set clock state helper
943  * @handle:	pointer to TI SCI handle
944  * @dev_id:	Device identifier this request is for
945  * @clk_id:	Clock identifier for the device for this request.
946  *		Each device has it's own set of clock inputs. This indexes
947  *		which clock input to modify.
948  * @flags:	Header flags as needed
949  * @state:	State to request for the clock.
950  *
951  * Return: 0 if all went well, else returns appropriate error value.
952  */
ti_sci_set_clock_state(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id,u32 flags,u8 state)953 static int ti_sci_set_clock_state(const struct ti_sci_handle *handle,
954 				  u32 dev_id, u8 clk_id,
955 				  u32 flags, u8 state)
956 {
957 	struct ti_sci_msg_req_set_clock_state req;
958 	struct ti_sci_msg_hdr *resp;
959 	struct ti_sci_info *info;
960 	struct ti_sci_xfer *xfer;
961 	int ret = 0;
962 
963 	if (IS_ERR(handle))
964 		return PTR_ERR(handle);
965 	if (!handle)
966 		return -EINVAL;
967 
968 	info = handle_to_ti_sci_info(handle);
969 
970 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_CLOCK_STATE,
971 				     flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
972 				     (u32 *)&req, sizeof(req), sizeof(*resp));
973 	if (IS_ERR(xfer)) {
974 		ret = PTR_ERR(xfer);
975 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
976 		return ret;
977 	}
978 	req.dev_id = dev_id;
979 	req.clk_id = clk_id;
980 	req.request_state = state;
981 
982 	ret = ti_sci_do_xfer(info, xfer);
983 	if (ret) {
984 		dev_err(info->dev, "Mbox send fail %d\n", ret);
985 		return ret;
986 	}
987 
988 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
989 
990 	if (!ti_sci_is_response_ack(resp))
991 		return -ENODEV;
992 
993 	return ret;
994 }
995 
996 /**
997  * ti_sci_cmd_get_clock_state() - Get clock state helper
998  * @handle:	pointer to TI SCI handle
999  * @dev_id:	Device identifier this request is for
1000  * @clk_id:	Clock identifier for the device for this request.
1001  *		Each device has it's own set of clock inputs. This indexes
1002  *		which clock input to modify.
1003  * @programmed_state:	State requested for clock to move to
1004  * @current_state:	State that the clock is currently in
1005  *
1006  * Return: 0 if all went well, else returns appropriate error value.
1007  */
ti_sci_cmd_get_clock_state(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id,u8 * programmed_state,u8 * current_state)1008 static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle,
1009 				      u32 dev_id, u8 clk_id,
1010 				      u8 *programmed_state, u8 *current_state)
1011 {
1012 	struct ti_sci_msg_resp_get_clock_state *resp;
1013 	struct ti_sci_msg_req_get_clock_state req;
1014 	struct ti_sci_info *info;
1015 	struct ti_sci_xfer *xfer;
1016 	int ret = 0;
1017 
1018 	if (IS_ERR(handle))
1019 		return PTR_ERR(handle);
1020 	if (!handle)
1021 		return -EINVAL;
1022 
1023 	if (!programmed_state && !current_state)
1024 		return -EINVAL;
1025 
1026 	info = handle_to_ti_sci_info(handle);
1027 
1028 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_CLOCK_STATE,
1029 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1030 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1031 	if (IS_ERR(xfer)) {
1032 		ret = PTR_ERR(xfer);
1033 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
1034 		return ret;
1035 	}
1036 	req.dev_id = dev_id;
1037 	req.clk_id = clk_id;
1038 
1039 	ret = ti_sci_do_xfer(info, xfer);
1040 	if (ret) {
1041 		dev_err(info->dev, "Mbox send fail %d\n", ret);
1042 		return ret;
1043 	}
1044 
1045 	resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->tx_message.buf;
1046 
1047 	if (!ti_sci_is_response_ack(resp))
1048 		return -ENODEV;
1049 
1050 	if (programmed_state)
1051 		*programmed_state = resp->programmed_state;
1052 	if (current_state)
1053 		*current_state = resp->current_state;
1054 
1055 	return ret;
1056 }
1057 
1058 /**
1059  * ti_sci_cmd_get_clock() - Get control of a clock from TI SCI
1060  * @handle:	pointer to TI SCI handle
1061  * @dev_id:	Device identifier this request is for
1062  * @clk_id:	Clock identifier for the device for this request.
1063  *		Each device has it's own set of clock inputs. This indexes
1064  *		which clock input to modify.
1065  * @needs_ssc: 'true' if Spread Spectrum clock is desired, else 'false'
1066  * @can_change_freq: 'true' if frequency change is desired, else 'false'
1067  * @enable_input_term: 'true' if input termination is desired, else 'false'
1068  *
1069  * Return: 0 if all went well, else returns appropriate error value.
1070  */
ti_sci_cmd_get_clock(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id,bool needs_ssc,bool can_change_freq,bool enable_input_term)1071 static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id,
1072 				u8 clk_id, bool needs_ssc, bool can_change_freq,
1073 				bool enable_input_term)
1074 {
1075 	u32 flags = 0;
1076 
1077 	flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0;
1078 	flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0;
1079 	flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0;
1080 
1081 	return ti_sci_set_clock_state(handle, dev_id, clk_id, flags,
1082 				      MSG_CLOCK_SW_STATE_REQ);
1083 }
1084 
1085 /**
1086  * ti_sci_cmd_idle_clock() - Idle a clock which is in our control
1087  * @handle:	pointer to TI SCI handle
1088  * @dev_id:	Device identifier this request is for
1089  * @clk_id:	Clock identifier for the device for this request.
1090  *		Each device has it's own set of clock inputs. This indexes
1091  *		which clock input to modify.
1092  *
1093  * NOTE: This clock must have been requested by get_clock previously.
1094  *
1095  * Return: 0 if all went well, else returns appropriate error value.
1096  */
ti_sci_cmd_idle_clock(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id)1097 static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle,
1098 				 u32 dev_id, u8 clk_id)
1099 {
1100 	return ti_sci_set_clock_state(handle, dev_id, clk_id, 0,
1101 				      MSG_CLOCK_SW_STATE_UNREQ);
1102 }
1103 
1104 /**
1105  * ti_sci_cmd_put_clock() - Release a clock from our control back to TISCI
1106  * @handle:	pointer to TI SCI handle
1107  * @dev_id:	Device identifier this request is for
1108  * @clk_id:	Clock identifier for the device for this request.
1109  *		Each device has it's own set of clock inputs. This indexes
1110  *		which clock input to modify.
1111  *
1112  * NOTE: This clock must have been requested by get_clock previously.
1113  *
1114  * Return: 0 if all went well, else returns appropriate error value.
1115  */
ti_sci_cmd_put_clock(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id)1116 static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle,
1117 				u32 dev_id, u8 clk_id)
1118 {
1119 	return ti_sci_set_clock_state(handle, dev_id, clk_id, 0,
1120 				      MSG_CLOCK_SW_STATE_AUTO);
1121 }
1122 
1123 /**
1124  * ti_sci_cmd_clk_is_auto() - Is the clock being auto managed
1125  * @handle:	pointer to TI SCI handle
1126  * @dev_id:	Device identifier this request is for
1127  * @clk_id:	Clock identifier for the device for this request.
1128  *		Each device has it's own set of clock inputs. This indexes
1129  *		which clock input to modify.
1130  * @req_state: state indicating if the clock is auto managed
1131  *
1132  * Return: 0 if all went well, else returns appropriate error value.
1133  */
ti_sci_cmd_clk_is_auto(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id,bool * req_state)1134 static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle,
1135 				  u32 dev_id, u8 clk_id, bool *req_state)
1136 {
1137 	u8 state = 0;
1138 	int ret;
1139 
1140 	if (!req_state)
1141 		return -EINVAL;
1142 
1143 	ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, &state, NULL);
1144 	if (ret)
1145 		return ret;
1146 
1147 	*req_state = (state == MSG_CLOCK_SW_STATE_AUTO);
1148 	return 0;
1149 }
1150 
1151 /**
1152  * ti_sci_cmd_clk_is_on() - Is the clock ON
1153  * @handle:	pointer to TI SCI handle
1154  * @dev_id:	Device identifier this request is for
1155  * @clk_id:	Clock identifier for the device for this request.
1156  *		Each device has it's own set of clock inputs. This indexes
1157  *		which clock input to modify.
1158  * @req_state: state indicating if the clock is managed by us and enabled
1159  * @curr_state: state indicating if the clock is ready for operation
1160  *
1161  * Return: 0 if all went well, else returns appropriate error value.
1162  */
ti_sci_cmd_clk_is_on(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id,bool * req_state,bool * curr_state)1163 static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id,
1164 				u8 clk_id, bool *req_state, bool *curr_state)
1165 {
1166 	u8 c_state = 0, r_state = 0;
1167 	int ret;
1168 
1169 	if (!req_state && !curr_state)
1170 		return -EINVAL;
1171 
1172 	ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
1173 					 &r_state, &c_state);
1174 	if (ret)
1175 		return ret;
1176 
1177 	if (req_state)
1178 		*req_state = (r_state == MSG_CLOCK_SW_STATE_REQ);
1179 	if (curr_state)
1180 		*curr_state = (c_state == MSG_CLOCK_HW_STATE_READY);
1181 	return 0;
1182 }
1183 
1184 /**
1185  * ti_sci_cmd_clk_is_off() - Is the clock OFF
1186  * @handle:	pointer to TI SCI handle
1187  * @dev_id:	Device identifier this request is for
1188  * @clk_id:	Clock identifier for the device for this request.
1189  *		Each device has it's own set of clock inputs. This indexes
1190  *		which clock input to modify.
1191  * @req_state: state indicating if the clock is managed by us and disabled
1192  * @curr_state: state indicating if the clock is NOT ready for operation
1193  *
1194  * Return: 0 if all went well, else returns appropriate error value.
1195  */
ti_sci_cmd_clk_is_off(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id,bool * req_state,bool * curr_state)1196 static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id,
1197 				 u8 clk_id, bool *req_state, bool *curr_state)
1198 {
1199 	u8 c_state = 0, r_state = 0;
1200 	int ret;
1201 
1202 	if (!req_state && !curr_state)
1203 		return -EINVAL;
1204 
1205 	ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
1206 					 &r_state, &c_state);
1207 	if (ret)
1208 		return ret;
1209 
1210 	if (req_state)
1211 		*req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ);
1212 	if (curr_state)
1213 		*curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY);
1214 	return 0;
1215 }
1216 
1217 /**
1218  * ti_sci_cmd_clk_set_parent() - Set the clock source of a specific device clock
1219  * @handle:	pointer to TI SCI handle
1220  * @dev_id:	Device identifier this request is for
1221  * @clk_id:	Clock identifier for the device for this request.
1222  *		Each device has it's own set of clock inputs. This indexes
1223  *		which clock input to modify.
1224  * @parent_id:	Parent clock identifier to set
1225  *
1226  * Return: 0 if all went well, else returns appropriate error value.
1227  */
ti_sci_cmd_clk_set_parent(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id,u8 parent_id)1228 static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle,
1229 				     u32 dev_id, u8 clk_id, u8 parent_id)
1230 {
1231 	struct ti_sci_msg_req_set_clock_parent req;
1232 	struct ti_sci_msg_hdr *resp;
1233 	struct ti_sci_info *info;
1234 	struct ti_sci_xfer *xfer;
1235 	int ret = 0;
1236 
1237 	if (IS_ERR(handle))
1238 		return PTR_ERR(handle);
1239 	if (!handle)
1240 		return -EINVAL;
1241 
1242 	info = handle_to_ti_sci_info(handle);
1243 
1244 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_CLOCK_PARENT,
1245 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1246 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1247 	if (IS_ERR(xfer)) {
1248 		ret = PTR_ERR(xfer);
1249 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
1250 		return ret;
1251 	}
1252 	req.dev_id = dev_id;
1253 	req.clk_id = clk_id;
1254 	req.parent_id = parent_id;
1255 
1256 	ret = ti_sci_do_xfer(info, xfer);
1257 	if (ret) {
1258 		dev_err(info->dev, "Mbox send fail %d\n", ret);
1259 		return ret;
1260 	}
1261 
1262 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
1263 
1264 	if (!ti_sci_is_response_ack(resp))
1265 		return -ENODEV;
1266 
1267 	return ret;
1268 }
1269 
1270 /**
1271  * ti_sci_cmd_clk_get_parent() - Get current parent clock source
1272  * @handle:	pointer to TI SCI handle
1273  * @dev_id:	Device identifier this request is for
1274  * @clk_id:	Clock identifier for the device for this request.
1275  *		Each device has it's own set of clock inputs. This indexes
1276  *		which clock input to modify.
1277  * @parent_id:	Current clock parent
1278  *
1279  * Return: 0 if all went well, else returns appropriate error value.
1280  */
ti_sci_cmd_clk_get_parent(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id,u8 * parent_id)1281 static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle,
1282 				     u32 dev_id, u8 clk_id, u8 *parent_id)
1283 {
1284 	struct ti_sci_msg_resp_get_clock_parent *resp;
1285 	struct ti_sci_msg_req_get_clock_parent req;
1286 	struct ti_sci_info *info;
1287 	struct ti_sci_xfer *xfer;
1288 	int ret = 0;
1289 
1290 	if (IS_ERR(handle))
1291 		return PTR_ERR(handle);
1292 	if (!handle || !parent_id)
1293 		return -EINVAL;
1294 
1295 	info = handle_to_ti_sci_info(handle);
1296 
1297 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_CLOCK_PARENT,
1298 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1299 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1300 	if (IS_ERR(xfer)) {
1301 		ret = PTR_ERR(xfer);
1302 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
1303 		return ret;
1304 	}
1305 	req.dev_id = dev_id;
1306 	req.clk_id = clk_id;
1307 
1308 	ret = ti_sci_do_xfer(info, xfer);
1309 	if (ret) {
1310 		dev_err(info->dev, "Mbox send fail %d\n", ret);
1311 		return ret;
1312 	}
1313 
1314 	resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->tx_message.buf;
1315 
1316 	if (!ti_sci_is_response_ack(resp))
1317 		ret = -ENODEV;
1318 	else
1319 		*parent_id = resp->parent_id;
1320 
1321 	return ret;
1322 }
1323 
1324 /**
1325  * ti_sci_cmd_clk_get_num_parents() - Get num parents of the current clk source
1326  * @handle:	pointer to TI SCI handle
1327  * @dev_id:	Device identifier this request is for
1328  * @clk_id:	Clock identifier for the device for this request.
1329  *		Each device has it's own set of clock inputs. This indexes
1330  *		which clock input to modify.
1331  * @num_parents: Returns he number of parents to the current clock.
1332  *
1333  * Return: 0 if all went well, else returns appropriate error value.
1334  */
ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id,u8 * num_parents)1335 static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle,
1336 					  u32 dev_id, u8 clk_id,
1337 					  u8 *num_parents)
1338 {
1339 	struct ti_sci_msg_resp_get_clock_num_parents *resp;
1340 	struct ti_sci_msg_req_get_clock_num_parents req;
1341 	struct ti_sci_info *info;
1342 	struct ti_sci_xfer *xfer;
1343 	int ret = 0;
1344 
1345 	if (IS_ERR(handle))
1346 		return PTR_ERR(handle);
1347 	if (!handle || !num_parents)
1348 		return -EINVAL;
1349 
1350 	info = handle_to_ti_sci_info(handle);
1351 
1352 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_NUM_CLOCK_PARENTS,
1353 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1354 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1355 	if (IS_ERR(xfer)) {
1356 		ret = PTR_ERR(xfer);
1357 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
1358 		return ret;
1359 	}
1360 	req.dev_id = dev_id;
1361 	req.clk_id = clk_id;
1362 
1363 	ret = ti_sci_do_xfer(info, xfer);
1364 	if (ret) {
1365 		dev_err(info->dev, "Mbox send fail %d\n", ret);
1366 		return ret;
1367 	}
1368 
1369 	resp = (struct ti_sci_msg_resp_get_clock_num_parents *)
1370 							xfer->tx_message.buf;
1371 
1372 	if (!ti_sci_is_response_ack(resp))
1373 		ret = -ENODEV;
1374 	else
1375 		*num_parents = resp->num_parents;
1376 
1377 	return ret;
1378 }
1379 
1380 /**
1381  * ti_sci_cmd_clk_get_match_freq() - Find a good match for frequency
1382  * @handle:	pointer to TI SCI handle
1383  * @dev_id:	Device identifier this request is for
1384  * @clk_id:	Clock identifier for the device for this request.
1385  *		Each device has it's own set of clock inputs. This indexes
1386  *		which clock input to modify.
1387  * @min_freq:	The minimum allowable frequency in Hz. This is the minimum
1388  *		allowable programmed frequency and does not account for clock
1389  *		tolerances and jitter.
1390  * @target_freq: The target clock frequency in Hz. A frequency will be
1391  *		processed as close to this target frequency as possible.
1392  * @max_freq:	The maximum allowable frequency in Hz. This is the maximum
1393  *		allowable programmed frequency and does not account for clock
1394  *		tolerances and jitter.
1395  * @match_freq:	Frequency match in Hz response.
1396  *
1397  * Return: 0 if all went well, else returns appropriate error value.
1398  */
ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id,u64 min_freq,u64 target_freq,u64 max_freq,u64 * match_freq)1399 static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle,
1400 					 u32 dev_id, u8 clk_id, u64 min_freq,
1401 					 u64 target_freq, u64 max_freq,
1402 					 u64 *match_freq)
1403 {
1404 	struct ti_sci_msg_resp_query_clock_freq *resp;
1405 	struct ti_sci_msg_req_query_clock_freq req;
1406 	struct ti_sci_info *info;
1407 	struct ti_sci_xfer *xfer;
1408 	int ret = 0;
1409 
1410 	if (IS_ERR(handle))
1411 		return PTR_ERR(handle);
1412 	if (!handle || !match_freq)
1413 		return -EINVAL;
1414 
1415 	info = handle_to_ti_sci_info(handle);
1416 
1417 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_QUERY_CLOCK_FREQ,
1418 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1419 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1420 	if (IS_ERR(xfer)) {
1421 		ret = PTR_ERR(xfer);
1422 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
1423 		return ret;
1424 	}
1425 	req.dev_id = dev_id;
1426 	req.clk_id = clk_id;
1427 	req.min_freq_hz = min_freq;
1428 	req.target_freq_hz = target_freq;
1429 	req.max_freq_hz = max_freq;
1430 
1431 	ret = ti_sci_do_xfer(info, xfer);
1432 	if (ret) {
1433 		dev_err(info->dev, "Mbox send fail %d\n", ret);
1434 		return ret;
1435 	}
1436 
1437 	resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->tx_message.buf;
1438 
1439 	if (!ti_sci_is_response_ack(resp))
1440 		ret = -ENODEV;
1441 	else
1442 		*match_freq = resp->freq_hz;
1443 
1444 	return ret;
1445 }
1446 
1447 /**
1448  * ti_sci_cmd_clk_set_freq() - Set a frequency for clock
1449  * @handle:	pointer to TI SCI handle
1450  * @dev_id:	Device identifier this request is for
1451  * @clk_id:	Clock identifier for the device for this request.
1452  *		Each device has it's own set of clock inputs. This indexes
1453  *		which clock input to modify.
1454  * @min_freq:	The minimum allowable frequency in Hz. This is the minimum
1455  *		allowable programmed frequency and does not account for clock
1456  *		tolerances and jitter.
1457  * @target_freq: The target clock frequency in Hz. A frequency will be
1458  *		processed as close to this target frequency as possible.
1459  * @max_freq:	The maximum allowable frequency in Hz. This is the maximum
1460  *		allowable programmed frequency and does not account for clock
1461  *		tolerances and jitter.
1462  *
1463  * Return: 0 if all went well, else returns appropriate error value.
1464  */
ti_sci_cmd_clk_set_freq(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id,u64 min_freq,u64 target_freq,u64 max_freq)1465 static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle,
1466 				   u32 dev_id, u8 clk_id, u64 min_freq,
1467 				   u64 target_freq, u64 max_freq)
1468 {
1469 	struct ti_sci_msg_req_set_clock_freq req;
1470 	struct ti_sci_msg_hdr *resp;
1471 	struct ti_sci_info *info;
1472 	struct ti_sci_xfer *xfer;
1473 	int ret = 0;
1474 
1475 	if (IS_ERR(handle))
1476 		return PTR_ERR(handle);
1477 	if (!handle)
1478 		return -EINVAL;
1479 
1480 	info = handle_to_ti_sci_info(handle);
1481 
1482 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_CLOCK_FREQ,
1483 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1484 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1485 	if (IS_ERR(xfer)) {
1486 		ret = PTR_ERR(xfer);
1487 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
1488 		return ret;
1489 	}
1490 	req.dev_id = dev_id;
1491 	req.clk_id = clk_id;
1492 	req.min_freq_hz = min_freq;
1493 	req.target_freq_hz = target_freq;
1494 	req.max_freq_hz = max_freq;
1495 
1496 	ret = ti_sci_do_xfer(info, xfer);
1497 	if (ret) {
1498 		dev_err(info->dev, "Mbox send fail %d\n", ret);
1499 		return ret;
1500 	}
1501 
1502 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
1503 
1504 	if (!ti_sci_is_response_ack(resp))
1505 		return -ENODEV;
1506 
1507 	return ret;
1508 }
1509 
1510 /**
1511  * ti_sci_cmd_clk_get_freq() - Get current frequency
1512  * @handle:	pointer to TI SCI handle
1513  * @dev_id:	Device identifier this request is for
1514  * @clk_id:	Clock identifier for the device for this request.
1515  *		Each device has it's own set of clock inputs. This indexes
1516  *		which clock input to modify.
1517  * @freq:	Currently frequency in Hz
1518  *
1519  * Return: 0 if all went well, else returns appropriate error value.
1520  */
ti_sci_cmd_clk_get_freq(const struct ti_sci_handle * handle,u32 dev_id,u8 clk_id,u64 * freq)1521 static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle,
1522 				   u32 dev_id, u8 clk_id, u64 *freq)
1523 {
1524 	struct ti_sci_msg_resp_get_clock_freq *resp;
1525 	struct ti_sci_msg_req_get_clock_freq req;
1526 	struct ti_sci_info *info;
1527 	struct ti_sci_xfer *xfer;
1528 	int ret = 0;
1529 
1530 	if (IS_ERR(handle))
1531 		return PTR_ERR(handle);
1532 	if (!handle || !freq)
1533 		return -EINVAL;
1534 
1535 	info = handle_to_ti_sci_info(handle);
1536 
1537 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_CLOCK_FREQ,
1538 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1539 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1540 	if (IS_ERR(xfer)) {
1541 		ret = PTR_ERR(xfer);
1542 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
1543 		return ret;
1544 	}
1545 	req.dev_id = dev_id;
1546 	req.clk_id = clk_id;
1547 
1548 	ret = ti_sci_do_xfer(info, xfer);
1549 	if (ret) {
1550 		dev_err(info->dev, "Mbox send fail %d\n", ret);
1551 		return ret;
1552 	}
1553 
1554 	resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->tx_message.buf;
1555 
1556 	if (!ti_sci_is_response_ack(resp))
1557 		ret = -ENODEV;
1558 	else
1559 		*freq = resp->freq_hz;
1560 
1561 	return ret;
1562 }
1563 
1564 /**
1565  * ti_sci_cmd_core_reboot() - Command to request system reset
1566  * @handle:	pointer to TI SCI handle
1567  *
1568  * Return: 0 if all went well, else returns appropriate error value.
1569  */
ti_sci_cmd_core_reboot(const struct ti_sci_handle * handle)1570 static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle)
1571 {
1572 	struct ti_sci_msg_req_reboot req;
1573 	struct ti_sci_msg_hdr *resp;
1574 	struct ti_sci_info *info;
1575 	struct ti_sci_xfer *xfer;
1576 	int ret = 0;
1577 
1578 	if (IS_ERR(handle))
1579 		return PTR_ERR(handle);
1580 	if (!handle)
1581 		return -EINVAL;
1582 
1583 	info = handle_to_ti_sci_info(handle);
1584 
1585 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SYS_RESET,
1586 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1587 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1588 	if (IS_ERR(xfer)) {
1589 		ret = PTR_ERR(xfer);
1590 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
1591 		return ret;
1592 	}
1593 
1594 	ret = ti_sci_do_xfer(info, xfer);
1595 	if (ret) {
1596 		dev_err(dev, "Mbox send fail %d\n", ret);
1597 		return ret;
1598 	}
1599 
1600 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
1601 
1602 	if (!ti_sci_is_response_ack(resp))
1603 		return -ENODEV;
1604 
1605 	return ret;
1606 }
1607 
ti_sci_get_resource_type(struct ti_sci_info * info,u16 dev_id,u16 * type)1608 static int ti_sci_get_resource_type(struct ti_sci_info *info, u16 dev_id,
1609 				    u16 *type)
1610 {
1611 	struct ti_sci_rm_type_map *rm_type_map = info->desc->rm_type_map;
1612 	bool found = false;
1613 	int i;
1614 
1615 	/* If map is not provided then assume dev_id is used as type */
1616 	if (!rm_type_map) {
1617 		*type = dev_id;
1618 		return 0;
1619 	}
1620 
1621 	for (i = 0; rm_type_map[i].dev_id; i++) {
1622 		if (rm_type_map[i].dev_id == dev_id) {
1623 			*type = rm_type_map[i].type;
1624 			found = true;
1625 			break;
1626 		}
1627 	}
1628 
1629 	if (!found)
1630 		return -EINVAL;
1631 
1632 	return 0;
1633 }
1634 
1635 /**
1636  * ti_sci_get_resource_range - Helper to get a range of resources assigned
1637  *			       to a host. Resource is uniquely identified by
1638  *			       type and subtype.
1639  * @handle:		Pointer to TISCI handle.
1640  * @dev_id:		TISCI device ID.
1641  * @subtype:		Resource assignment subtype that is being requested
1642  *			from the given device.
1643  * @s_host:		Host processor ID to which the resources are allocated
1644  * @range_start:	Start index of the resource range
1645  * @range_num:		Number of resources in the range
1646  *
1647  * Return: 0 if all went fine, else return appropriate error.
1648  */
ti_sci_get_resource_range(const struct ti_sci_handle * handle,u32 dev_id,u8 subtype,u8 s_host,u16 * range_start,u16 * range_num)1649 static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
1650 				     u32 dev_id, u8 subtype, u8 s_host,
1651 				     u16 *range_start, u16 *range_num)
1652 {
1653 	struct ti_sci_msg_resp_get_resource_range *resp;
1654 	struct ti_sci_msg_req_get_resource_range req;
1655 	struct ti_sci_xfer *xfer;
1656 	struct ti_sci_info *info;
1657 	u16 type;
1658 	int ret = 0;
1659 
1660 	if (IS_ERR(handle))
1661 		return PTR_ERR(handle);
1662 	if (!handle)
1663 		return -EINVAL;
1664 
1665 	info = handle_to_ti_sci_info(handle);
1666 
1667 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_RESOURCE_RANGE,
1668 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1669 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1670 	if (IS_ERR(xfer)) {
1671 		ret = PTR_ERR(xfer);
1672 		dev_err(dev, "Message alloc failed(%d)\n", ret);
1673 		return ret;
1674 	}
1675 
1676 	ret = ti_sci_get_resource_type(info, dev_id, &type);
1677 	if (ret) {
1678 		dev_err(dev, "rm type lookup failed for %u\n", dev_id);
1679 		goto fail;
1680 	}
1681 
1682 	req.secondary_host = s_host;
1683 	req.type = type & MSG_RM_RESOURCE_TYPE_MASK;
1684 	req.subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK;
1685 
1686 	ret = ti_sci_do_xfer(info, xfer);
1687 	if (ret) {
1688 		dev_err(dev, "Mbox send fail %d\n", ret);
1689 		goto fail;
1690 	}
1691 
1692 	resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->tx_message.buf;
1693 	if (!ti_sci_is_response_ack(resp)) {
1694 		ret = -ENODEV;
1695 	} else if (!resp->range_start && !resp->range_num) {
1696 		ret = -ENODEV;
1697 	} else {
1698 		*range_start = resp->range_start;
1699 		*range_num = resp->range_num;
1700 	};
1701 
1702 fail:
1703 	return ret;
1704 }
1705 
1706 /**
1707  * ti_sci_cmd_get_resource_range - Get a range of resources assigned to host
1708  *				   that is same as ti sci interface host.
1709  * @handle:		Pointer to TISCI handle.
1710  * @dev_id:		TISCI device ID.
1711  * @subtype:		Resource assignment subtype that is being requested
1712  *			from the given device.
1713  * @range_start:	Start index of the resource range
1714  * @range_num:		Number of resources in the range
1715  *
1716  * Return: 0 if all went fine, else return appropriate error.
1717  */
ti_sci_cmd_get_resource_range(const struct ti_sci_handle * handle,u32 dev_id,u8 subtype,u16 * range_start,u16 * range_num)1718 static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle,
1719 					 u32 dev_id, u8 subtype,
1720 					 u16 *range_start, u16 *range_num)
1721 {
1722 	return ti_sci_get_resource_range(handle, dev_id, subtype,
1723 					 TI_SCI_IRQ_SECONDARY_HOST_INVALID,
1724 					 range_start, range_num);
1725 }
1726 
1727 /**
1728  * ti_sci_cmd_get_resource_range_from_shost - Get a range of resources
1729  *					      assigned to a specified host.
1730  * @handle:		Pointer to TISCI handle.
1731  * @dev_id:		TISCI device ID.
1732  * @subtype:		Resource assignment subtype that is being requested
1733  *			from the given device.
1734  * @s_host:		Host processor ID to which the resources are allocated
1735  * @range_start:	Start index of the resource range
1736  * @range_num:		Number of resources in the range
1737  *
1738  * Return: 0 if all went fine, else return appropriate error.
1739  */
1740 static
ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle * handle,u32 dev_id,u8 subtype,u8 s_host,u16 * range_start,u16 * range_num)1741 int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle,
1742 					     u32 dev_id, u8 subtype, u8 s_host,
1743 					     u16 *range_start, u16 *range_num)
1744 {
1745 	return ti_sci_get_resource_range(handle, dev_id, subtype, s_host,
1746 					 range_start, range_num);
1747 }
1748 
1749 /**
1750  * ti_sci_cmd_query_msmc() - Command to query currently available msmc memory
1751  * @handle:		pointer to TI SCI handle
1752  * @msms_start:		MSMC start as returned by tisci
1753  * @msmc_end:		MSMC end as returned by tisci
1754  *
1755  * Return: 0 if all went well, else returns appropriate error value.
1756  */
ti_sci_cmd_query_msmc(const struct ti_sci_handle * handle,u64 * msmc_start,u64 * msmc_end)1757 static int ti_sci_cmd_query_msmc(const struct ti_sci_handle *handle,
1758 				 u64 *msmc_start, u64 *msmc_end)
1759 {
1760 	struct ti_sci_msg_resp_query_msmc *resp;
1761 	struct ti_sci_msg_hdr req;
1762 	struct ti_sci_info *info;
1763 	struct ti_sci_xfer *xfer;
1764 	int ret = 0;
1765 
1766 	if (IS_ERR(handle))
1767 		return PTR_ERR(handle);
1768 	if (!handle)
1769 		return -EINVAL;
1770 
1771 	info = handle_to_ti_sci_info(handle);
1772 
1773 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_QUERY_MSMC,
1774 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1775 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1776 	if (IS_ERR(xfer)) {
1777 		ret = PTR_ERR(xfer);
1778 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
1779 		return ret;
1780 	}
1781 
1782 	ret = ti_sci_do_xfer(info, xfer);
1783 	if (ret) {
1784 		dev_err(dev, "Mbox send fail %d\n", ret);
1785 		return ret;
1786 	}
1787 
1788 	resp = (struct ti_sci_msg_resp_query_msmc *)xfer->tx_message.buf;
1789 
1790 	if (!ti_sci_is_response_ack(resp))
1791 		return -ENODEV;
1792 
1793 	*msmc_start = ((u64)resp->msmc_start_high << TISCI_ADDR_HIGH_SHIFT) |
1794 			resp->msmc_start_low;
1795 	*msmc_end = ((u64)resp->msmc_end_high << TISCI_ADDR_HIGH_SHIFT) |
1796 			resp->msmc_end_low;
1797 
1798 	return ret;
1799 }
1800 
1801 /**
1802  * ti_sci_cmd_proc_request() - Command to request a physical processor control
1803  * @handle:	Pointer to TI SCI handle
1804  * @proc_id:	Processor ID this request is for
1805  *
1806  * Return: 0 if all went well, else returns appropriate error value.
1807  */
ti_sci_cmd_proc_request(const struct ti_sci_handle * handle,u8 proc_id)1808 static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle,
1809 				   u8 proc_id)
1810 {
1811 	struct ti_sci_msg_req_proc_request req;
1812 	struct ti_sci_msg_hdr *resp;
1813 	struct ti_sci_info *info;
1814 	struct ti_sci_xfer *xfer;
1815 	int ret = 0;
1816 
1817 	if (IS_ERR(handle))
1818 		return PTR_ERR(handle);
1819 	if (!handle)
1820 		return -EINVAL;
1821 
1822 	info = handle_to_ti_sci_info(handle);
1823 
1824 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_REQUEST,
1825 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1826 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1827 	if (IS_ERR(xfer)) {
1828 		ret = PTR_ERR(xfer);
1829 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
1830 		return ret;
1831 	}
1832 	req.processor_id = proc_id;
1833 
1834 	ret = ti_sci_do_xfer(info, xfer);
1835 	if (ret) {
1836 		dev_err(info->dev, "Mbox send fail %d\n", ret);
1837 		return ret;
1838 	}
1839 
1840 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
1841 
1842 	if (!ti_sci_is_response_ack(resp))
1843 		ret = -ENODEV;
1844 
1845 	return ret;
1846 }
1847 
1848 /**
1849  * ti_sci_cmd_proc_release() - Command to release a physical processor control
1850  * @handle:	Pointer to TI SCI handle
1851  * @proc_id:	Processor ID this request is for
1852  *
1853  * Return: 0 if all went well, else returns appropriate error value.
1854  */
ti_sci_cmd_proc_release(const struct ti_sci_handle * handle,u8 proc_id)1855 static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle,
1856 				   u8 proc_id)
1857 {
1858 	struct ti_sci_msg_req_proc_release req;
1859 	struct ti_sci_msg_hdr *resp;
1860 	struct ti_sci_info *info;
1861 	struct ti_sci_xfer *xfer;
1862 	int ret = 0;
1863 
1864 	if (IS_ERR(handle))
1865 		return PTR_ERR(handle);
1866 	if (!handle)
1867 		return -EINVAL;
1868 
1869 	info = handle_to_ti_sci_info(handle);
1870 
1871 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_RELEASE,
1872 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1873 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1874 	if (IS_ERR(xfer)) {
1875 		ret = PTR_ERR(xfer);
1876 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
1877 		return ret;
1878 	}
1879 	req.processor_id = proc_id;
1880 
1881 	ret = ti_sci_do_xfer(info, xfer);
1882 	if (ret) {
1883 		dev_err(info->dev, "Mbox send fail %d\n", ret);
1884 		return ret;
1885 	}
1886 
1887 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
1888 
1889 	if (!ti_sci_is_response_ack(resp))
1890 		ret = -ENODEV;
1891 
1892 	return ret;
1893 }
1894 
1895 /**
1896  * ti_sci_cmd_proc_handover() - Command to handover a physical processor
1897  *				control to a host in the processor's access
1898  *				control list.
1899  * @handle:	Pointer to TI SCI handle
1900  * @proc_id:	Processor ID this request is for
1901  * @host_id:	Host ID to get the control of the processor
1902  *
1903  * Return: 0 if all went well, else returns appropriate error value.
1904  */
ti_sci_cmd_proc_handover(const struct ti_sci_handle * handle,u8 proc_id,u8 host_id)1905 static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle,
1906 				    u8 proc_id, u8 host_id)
1907 {
1908 	struct ti_sci_msg_req_proc_handover req;
1909 	struct ti_sci_msg_hdr *resp;
1910 	struct ti_sci_info *info;
1911 	struct ti_sci_xfer *xfer;
1912 	int ret = 0;
1913 
1914 	if (IS_ERR(handle))
1915 		return PTR_ERR(handle);
1916 	if (!handle)
1917 		return -EINVAL;
1918 
1919 	info = handle_to_ti_sci_info(handle);
1920 
1921 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_HANDOVER,
1922 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1923 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1924 	if (IS_ERR(xfer)) {
1925 		ret = PTR_ERR(xfer);
1926 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
1927 		return ret;
1928 	}
1929 	req.processor_id = proc_id;
1930 	req.host_id = host_id;
1931 
1932 	ret = ti_sci_do_xfer(info, xfer);
1933 	if (ret) {
1934 		dev_err(info->dev, "Mbox send fail %d\n", ret);
1935 		return ret;
1936 	}
1937 
1938 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
1939 
1940 	if (!ti_sci_is_response_ack(resp))
1941 		ret = -ENODEV;
1942 
1943 	return ret;
1944 }
1945 
1946 /**
1947  * ti_sci_cmd_set_proc_boot_cfg() - Command to set the processor boot
1948  *				    configuration flags
1949  * @handle:		Pointer to TI SCI handle
1950  * @proc_id:		Processor ID this request is for
1951  * @config_flags_set:	Configuration flags to be set
1952  * @config_flags_clear:	Configuration flags to be cleared.
1953  *
1954  * Return: 0 if all went well, else returns appropriate error value.
1955  */
ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle * handle,u8 proc_id,u64 bootvector,u32 config_flags_set,u32 config_flags_clear)1956 static int ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle *handle,
1957 					u8 proc_id, u64 bootvector,
1958 					u32 config_flags_set,
1959 					u32 config_flags_clear)
1960 {
1961 	struct ti_sci_msg_req_set_proc_boot_config req;
1962 	struct ti_sci_msg_hdr *resp;
1963 	struct ti_sci_info *info;
1964 	struct ti_sci_xfer *xfer;
1965 	int ret = 0;
1966 
1967 	if (IS_ERR(handle))
1968 		return PTR_ERR(handle);
1969 	if (!handle)
1970 		return -EINVAL;
1971 
1972 	info = handle_to_ti_sci_info(handle);
1973 
1974 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_SET_PROC_BOOT_CONFIG,
1975 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1976 				     (u32 *)&req, sizeof(req), sizeof(*resp));
1977 	if (IS_ERR(xfer)) {
1978 		ret = PTR_ERR(xfer);
1979 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
1980 		return ret;
1981 	}
1982 	req.processor_id = proc_id;
1983 	req.bootvector_low = bootvector & TISCI_ADDR_LOW_MASK;
1984 	req.bootvector_high = (bootvector & TISCI_ADDR_HIGH_MASK) >>
1985 				TISCI_ADDR_HIGH_SHIFT;
1986 	req.config_flags_set = config_flags_set;
1987 	req.config_flags_clear = config_flags_clear;
1988 
1989 	ret = ti_sci_do_xfer(info, xfer);
1990 	if (ret) {
1991 		dev_err(info->dev, "Mbox send fail %d\n", ret);
1992 		return ret;
1993 	}
1994 
1995 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
1996 
1997 	if (!ti_sci_is_response_ack(resp))
1998 		ret = -ENODEV;
1999 
2000 	return ret;
2001 }
2002 
2003 /**
2004  * ti_sci_cmd_set_proc_boot_ctrl() - Command to set the processor boot
2005  *				     control flags
2006  * @handle:			Pointer to TI SCI handle
2007  * @proc_id:			Processor ID this request is for
2008  * @control_flags_set:		Control flags to be set
2009  * @control_flags_clear:	Control flags to be cleared
2010  *
2011  * Return: 0 if all went well, else returns appropriate error value.
2012  */
ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle * handle,u8 proc_id,u32 control_flags_set,u32 control_flags_clear)2013 static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle,
2014 					 u8 proc_id, u32 control_flags_set,
2015 					 u32 control_flags_clear)
2016 {
2017 	struct ti_sci_msg_req_set_proc_boot_ctrl req;
2018 	struct ti_sci_msg_hdr *resp;
2019 	struct ti_sci_info *info;
2020 	struct ti_sci_xfer *xfer;
2021 	int ret = 0;
2022 
2023 	if (IS_ERR(handle))
2024 		return PTR_ERR(handle);
2025 	if (!handle)
2026 		return -EINVAL;
2027 
2028 	info = handle_to_ti_sci_info(handle);
2029 
2030 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_SET_PROC_BOOT_CTRL,
2031 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2032 				     (u32 *)&req, sizeof(req), sizeof(*resp));
2033 	if (IS_ERR(xfer)) {
2034 		ret = PTR_ERR(xfer);
2035 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
2036 		return ret;
2037 	}
2038 	req.processor_id = proc_id;
2039 	req.control_flags_set = control_flags_set;
2040 	req.control_flags_clear = control_flags_clear;
2041 
2042 	ret = ti_sci_do_xfer(info, xfer);
2043 	if (ret) {
2044 		dev_err(info->dev, "Mbox send fail %d\n", ret);
2045 		return ret;
2046 	}
2047 
2048 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
2049 
2050 	if (!ti_sci_is_response_ack(resp))
2051 		ret = -ENODEV;
2052 
2053 	return ret;
2054 }
2055 
2056 /**
2057  * ti_sci_cmd_proc_auth_boot_image() - Command to authenticate and load the
2058  *			image and then set the processor configuration flags.
2059  * @handle:	Pointer to TI SCI handle
2060  * @image_addr:	Memory address at which payload image and certificate is
2061  *		located in memory, this is updated if the image data is
2062  *		moved during authentication.
2063  * @image_size: This is updated with the final size of the image after
2064  *		authentication.
2065  *
2066  * Return: 0 if all went well, else returns appropriate error value.
2067  */
ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle * handle,u64 * image_addr,u32 * image_size)2068 static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle,
2069 					   u64 *image_addr, u32 *image_size)
2070 {
2071 	struct ti_sci_msg_req_proc_auth_boot_image req;
2072 	struct ti_sci_msg_resp_proc_auth_boot_image *resp;
2073 	struct ti_sci_info *info;
2074 	struct ti_sci_xfer *xfer;
2075 	int ret = 0;
2076 
2077 	if (IS_ERR(handle))
2078 		return PTR_ERR(handle);
2079 	if (!handle)
2080 		return -EINVAL;
2081 
2082 	info = handle_to_ti_sci_info(handle);
2083 
2084 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_AUTH_BOOT_IMIAGE,
2085 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2086 				     (u32 *)&req, sizeof(req), sizeof(*resp));
2087 	if (IS_ERR(xfer)) {
2088 		ret = PTR_ERR(xfer);
2089 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
2090 		return ret;
2091 	}
2092 	req.cert_addr_low = *image_addr & TISCI_ADDR_LOW_MASK;
2093 	req.cert_addr_high = (*image_addr & TISCI_ADDR_HIGH_MASK) >>
2094 				TISCI_ADDR_HIGH_SHIFT;
2095 
2096 	ret = ti_sci_do_xfer(info, xfer);
2097 	if (ret) {
2098 		dev_err(info->dev, "Mbox send fail %d\n", ret);
2099 		return ret;
2100 	}
2101 
2102 	resp = (struct ti_sci_msg_resp_proc_auth_boot_image *)xfer->tx_message.buf;
2103 
2104 	if (!ti_sci_is_response_ack(resp))
2105 		return -ENODEV;
2106 
2107 	*image_addr = (resp->image_addr_low & TISCI_ADDR_LOW_MASK) |
2108 			(((u64)resp->image_addr_high <<
2109 			  TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK);
2110 	*image_size = resp->image_size;
2111 
2112 	return ret;
2113 }
2114 
2115 /**
2116  * ti_sci_cmd_get_proc_boot_status() - Command to get the processor boot status
2117  * @handle:	Pointer to TI SCI handle
2118  * @proc_id:	Processor ID this request is for
2119  *
2120  * Return: 0 if all went well, else returns appropriate error value.
2121  */
ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle * handle,u8 proc_id,u64 * bv,u32 * cfg_flags,u32 * ctrl_flags,u32 * sts_flags)2122 static int ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle *handle,
2123 					   u8 proc_id, u64 *bv, u32 *cfg_flags,
2124 					   u32 *ctrl_flags, u32 *sts_flags)
2125 {
2126 	struct ti_sci_msg_resp_get_proc_boot_status *resp;
2127 	struct ti_sci_msg_req_get_proc_boot_status req;
2128 	struct ti_sci_info *info;
2129 	struct ti_sci_xfer *xfer;
2130 	int ret = 0;
2131 
2132 	if (IS_ERR(handle))
2133 		return PTR_ERR(handle);
2134 	if (!handle)
2135 		return -EINVAL;
2136 
2137 	info = handle_to_ti_sci_info(handle);
2138 
2139 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_GET_PROC_BOOT_STATUS,
2140 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2141 				     (u32 *)&req, sizeof(req), sizeof(*resp));
2142 	if (IS_ERR(xfer)) {
2143 		ret = PTR_ERR(xfer);
2144 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
2145 		return ret;
2146 	}
2147 	req.processor_id = proc_id;
2148 
2149 	ret = ti_sci_do_xfer(info, xfer);
2150 	if (ret) {
2151 		dev_err(info->dev, "Mbox send fail %d\n", ret);
2152 		return ret;
2153 	}
2154 
2155 	resp = (struct ti_sci_msg_resp_get_proc_boot_status *)
2156 							xfer->tx_message.buf;
2157 
2158 	if (!ti_sci_is_response_ack(resp))
2159 		return -ENODEV;
2160 	*bv = (resp->bootvector_low & TISCI_ADDR_LOW_MASK) |
2161 			(((u64)resp->bootvector_high  <<
2162 			  TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK);
2163 	*cfg_flags = resp->config_flags;
2164 	*ctrl_flags = resp->control_flags;
2165 	*sts_flags = resp->status_flags;
2166 
2167 	return ret;
2168 }
2169 
2170 /**
2171  * ti_sci_proc_wait_boot_status_no_wait() - Helper function to wait for a
2172  *				processor boot status without requesting or
2173  *				waiting for a response.
2174  * @proc_id:			Processor ID this request is for
2175  * @num_wait_iterations:	Total number of iterations we will check before
2176  *				we will timeout and give up
2177  * @num_match_iterations:	How many iterations should we have continued
2178  *				status to account for status bits glitching.
2179  *				This is to make sure that match occurs for
2180  *				consecutive checks. This implies that the
2181  *				worst case should consider that the stable
2182  *				time should at the worst be num_wait_iterations
2183  *				num_match_iterations to prevent timeout.
2184  * @delay_per_iteration_us:	Specifies how long to wait (in micro seconds)
2185  *				between each status checks. This is the minimum
2186  *				duration, and overhead of register reads and
2187  *				checks are on top of this and can vary based on
2188  *				varied conditions.
2189  * @delay_before_iterations_us:	Specifies how long to wait (in micro seconds)
2190  *				before the very first check in the first
2191  *				iteration of status check loop. This is the
2192  *				minimum duration, and overhead of register
2193  *				reads and checks are.
2194  * @status_flags_1_set_all_wait:If non-zero, Specifies that all bits of the
2195  *				status matching this field requested MUST be 1.
2196  * @status_flags_1_set_any_wait:If non-zero, Specifies that at least one of the
2197  *				bits matching this field requested MUST be 1.
2198  * @status_flags_1_clr_all_wait:If non-zero, Specifies that all bits of the
2199  *				status matching this field requested MUST be 0.
2200  * @status_flags_1_clr_any_wait:If non-zero, Specifies that at least one of the
2201  *				bits matching this field requested MUST be 0.
2202  *
2203  * Return: 0 if all goes well, else appropriate error message
2204  */
2205 static int
ti_sci_proc_wait_boot_status_no_wait(const struct ti_sci_handle * handle,u8 proc_id,u8 num_wait_iterations,u8 num_match_iterations,u8 delay_per_iteration_us,u8 delay_before_iterations_us,u32 status_flags_1_set_all_wait,u32 status_flags_1_set_any_wait,u32 status_flags_1_clr_all_wait,u32 status_flags_1_clr_any_wait)2206 ti_sci_proc_wait_boot_status_no_wait(const struct ti_sci_handle *handle,
2207 				     u8 proc_id,
2208 				     u8 num_wait_iterations,
2209 				     u8 num_match_iterations,
2210 				     u8 delay_per_iteration_us,
2211 				     u8 delay_before_iterations_us,
2212 				     u32 status_flags_1_set_all_wait,
2213 				     u32 status_flags_1_set_any_wait,
2214 				     u32 status_flags_1_clr_all_wait,
2215 				     u32 status_flags_1_clr_any_wait)
2216 {
2217 	struct ti_sci_msg_req_wait_proc_boot_status req;
2218 	struct ti_sci_info *info;
2219 	struct ti_sci_xfer *xfer;
2220 	int ret = 0;
2221 
2222 	if (IS_ERR(handle))
2223 		return PTR_ERR(handle);
2224 	if (!handle)
2225 		return -EINVAL;
2226 
2227 	info = handle_to_ti_sci_info(handle);
2228 
2229 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_WAIT_PROC_BOOT_STATUS,
2230 				     TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
2231 				     (u32 *)&req, sizeof(req), 0);
2232 	if (IS_ERR(xfer)) {
2233 		ret = PTR_ERR(xfer);
2234 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
2235 		return ret;
2236 	}
2237 	req.processor_id = proc_id;
2238 	req.num_wait_iterations = num_wait_iterations;
2239 	req.num_match_iterations = num_match_iterations;
2240 	req.delay_per_iteration_us = delay_per_iteration_us;
2241 	req.delay_before_iterations_us = delay_before_iterations_us;
2242 	req.status_flags_1_set_all_wait = status_flags_1_set_all_wait;
2243 	req.status_flags_1_set_any_wait = status_flags_1_set_any_wait;
2244 	req.status_flags_1_clr_all_wait = status_flags_1_clr_all_wait;
2245 	req.status_flags_1_clr_any_wait = status_flags_1_clr_any_wait;
2246 
2247 	ret = ti_sci_do_xfer(info, xfer);
2248 	if (ret)
2249 		dev_err(info->dev, "Mbox send fail %d\n", ret);
2250 
2251 	return ret;
2252 }
2253 
2254 /**
2255  * ti_sci_cmd_proc_shutdown_no_wait() - Command to shutdown a core without
2256  *		requesting or waiting for a response. Note that this API call
2257  *		should be followed by placing the respective processor into
2258  *		either WFE or WFI mode.
2259  * @handle:	Pointer to TI SCI handle
2260  * @proc_id:	Processor ID this request is for
2261  *
2262  * Return: 0 if all went well, else returns appropriate error value.
2263  */
ti_sci_cmd_proc_shutdown_no_wait(const struct ti_sci_handle * handle,u8 proc_id)2264 static int ti_sci_cmd_proc_shutdown_no_wait(const struct ti_sci_handle *handle,
2265 					    u8 proc_id)
2266 {
2267 	int ret;
2268 
2269 	/*
2270 	 * Send the core boot status wait message waiting for either WFE or
2271 	 * WFI without requesting or waiting for a TISCI response with the
2272 	 * maximum wait time to give us the best chance to get to the WFE/WFI
2273 	 * command that should follow the invocation of this API before the
2274 	 * DMSC-internal processing of this command times out. Note that
2275 	 * waiting for the R5 WFE/WFI flags will also work on an ARMV8 type
2276 	 * core as the related flag bit positions are the same.
2277 	 */
2278 	ret = ti_sci_proc_wait_boot_status_no_wait(handle, proc_id,
2279 		U8_MAX, 100, U8_MAX, U8_MAX,
2280 		0, PROC_BOOT_STATUS_FLAG_R5_WFE | PROC_BOOT_STATUS_FLAG_R5_WFI,
2281 		0, 0);
2282 	if (ret) {
2283 		dev_err(info->dev, "Sending core %u wait message fail %d\n",
2284 			proc_id, ret);
2285 		return ret;
2286 	}
2287 
2288 	/*
2289 	 * Release a processor managed by TISCI without requesting or waiting
2290 	 * for a response.
2291 	 */
2292 	ret = ti_sci_set_device_state_no_wait(handle, proc_id, 0,
2293 					      MSG_DEVICE_SW_STATE_AUTO_OFF);
2294 	if (ret)
2295 		dev_err(info->dev, "Sending core %u shutdown message fail %d\n",
2296 			proc_id, ret);
2297 
2298 	return ret;
2299 }
2300 
2301 /**
2302  * ti_sci_cmd_ring_config() - configure RA ring
2303  * @handle:	pointer to TI SCI handle
2304  * @valid_params: Bitfield defining validity of ring configuration parameters.
2305  * @nav_id: Device ID of Navigator Subsystem from which the ring is allocated
2306  * @index: Ring index.
2307  * @addr_lo: The ring base address lo 32 bits
2308  * @addr_hi: The ring base address hi 32 bits
2309  * @count: Number of ring elements.
2310  * @mode: The mode of the ring
2311  * @size: The ring element size.
2312  * @order_id: Specifies the ring's bus order ID.
2313  *
2314  * Return: 0 if all went well, else returns appropriate error value.
2315  *
2316  * See @ti_sci_msg_rm_ring_cfg_req for more info.
2317  */
ti_sci_cmd_ring_config(const struct ti_sci_handle * handle,u32 valid_params,u16 nav_id,u16 index,u32 addr_lo,u32 addr_hi,u32 count,u8 mode,u8 size,u8 order_id)2318 static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle,
2319 				  u32 valid_params, u16 nav_id, u16 index,
2320 				  u32 addr_lo, u32 addr_hi, u32 count,
2321 				  u8 mode, u8 size, u8 order_id)
2322 {
2323 	struct ti_sci_msg_rm_ring_cfg_resp *resp;
2324 	struct ti_sci_msg_rm_ring_cfg_req req;
2325 	struct ti_sci_xfer *xfer;
2326 	struct ti_sci_info *info;
2327 	int ret = 0;
2328 
2329 	if (IS_ERR(handle))
2330 		return PTR_ERR(handle);
2331 	if (!handle)
2332 		return -EINVAL;
2333 
2334 	info = handle_to_ti_sci_info(handle);
2335 
2336 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_RM_RING_CFG,
2337 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2338 				     (u32 *)&req, sizeof(req), sizeof(*resp));
2339 	if (IS_ERR(xfer)) {
2340 		ret = PTR_ERR(xfer);
2341 		dev_err(info->dev, "RM_RA:Message config failed(%d)\n", ret);
2342 		return ret;
2343 	}
2344 	req.valid_params = valid_params;
2345 	req.nav_id = nav_id;
2346 	req.index = index;
2347 	req.addr_lo = addr_lo;
2348 	req.addr_hi = addr_hi;
2349 	req.count = count;
2350 	req.mode = mode;
2351 	req.size = size;
2352 	req.order_id = order_id;
2353 
2354 	ret = ti_sci_do_xfer(info, xfer);
2355 	if (ret) {
2356 		dev_err(info->dev, "RM_RA:Mbox config send fail %d\n", ret);
2357 		goto fail;
2358 	}
2359 
2360 	resp = (struct ti_sci_msg_rm_ring_cfg_resp *)xfer->tx_message.buf;
2361 
2362 	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
2363 
2364 fail:
2365 	dev_dbg(info->dev, "RM_RA:config ring %u ret:%d\n", index, ret);
2366 	return ret;
2367 }
2368 
ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle * handle,u32 nav_id,u32 src_thread,u32 dst_thread)2369 static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle,
2370 				   u32 nav_id, u32 src_thread, u32 dst_thread)
2371 {
2372 	struct ti_sci_msg_hdr *resp;
2373 	struct ti_sci_msg_psil_pair req;
2374 	struct ti_sci_xfer *xfer;
2375 	struct ti_sci_info *info;
2376 	int ret = 0;
2377 
2378 	if (IS_ERR(handle))
2379 		return PTR_ERR(handle);
2380 	if (!handle)
2381 		return -EINVAL;
2382 
2383 	info = handle_to_ti_sci_info(handle);
2384 
2385 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_RM_PSIL_PAIR,
2386 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2387 				     (u32 *)&req, sizeof(req), sizeof(*resp));
2388 	if (IS_ERR(xfer)) {
2389 		ret = PTR_ERR(xfer);
2390 		dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret);
2391 		return ret;
2392 	}
2393 	req.nav_id = nav_id;
2394 	req.src_thread = src_thread;
2395 	req.dst_thread = dst_thread;
2396 
2397 	ret = ti_sci_do_xfer(info, xfer);
2398 	if (ret) {
2399 		dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret);
2400 		goto fail;
2401 	}
2402 
2403 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
2404 	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
2405 
2406 fail:
2407 	dev_dbg(info->dev, "RM_PSIL: nav: %u link pair %u->%u ret:%u\n",
2408 		nav_id, src_thread, dst_thread, ret);
2409 	return ret;
2410 }
2411 
ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle * handle,u32 nav_id,u32 src_thread,u32 dst_thread)2412 static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle,
2413 				     u32 nav_id, u32 src_thread, u32 dst_thread)
2414 {
2415 	struct ti_sci_msg_hdr *resp;
2416 	struct ti_sci_msg_psil_unpair req;
2417 	struct ti_sci_xfer *xfer;
2418 	struct ti_sci_info *info;
2419 	int ret = 0;
2420 
2421 	if (IS_ERR(handle))
2422 		return PTR_ERR(handle);
2423 	if (!handle)
2424 		return -EINVAL;
2425 
2426 	info = handle_to_ti_sci_info(handle);
2427 
2428 	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_RM_PSIL_UNPAIR,
2429 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2430 				     (u32 *)&req, sizeof(req), sizeof(*resp));
2431 	if (IS_ERR(xfer)) {
2432 		ret = PTR_ERR(xfer);
2433 		dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret);
2434 		return ret;
2435 	}
2436 	req.nav_id = nav_id;
2437 	req.src_thread = src_thread;
2438 	req.dst_thread = dst_thread;
2439 
2440 	ret = ti_sci_do_xfer(info, xfer);
2441 	if (ret) {
2442 		dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret);
2443 		goto fail;
2444 	}
2445 
2446 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
2447 	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
2448 
2449 fail:
2450 	dev_dbg(info->dev, "RM_PSIL: link unpair %u->%u ret:%u\n",
2451 		src_thread, dst_thread, ret);
2452 	return ret;
2453 }
2454 
ti_sci_cmd_rm_udmap_tx_ch_cfg(const struct ti_sci_handle * handle,const struct ti_sci_msg_rm_udmap_tx_ch_cfg * params)2455 static int ti_sci_cmd_rm_udmap_tx_ch_cfg(
2456 			const struct ti_sci_handle *handle,
2457 			const struct ti_sci_msg_rm_udmap_tx_ch_cfg *params)
2458 {
2459 	struct ti_sci_msg_rm_udmap_tx_ch_cfg_resp *resp;
2460 	struct ti_sci_msg_rm_udmap_tx_ch_cfg_req req;
2461 	struct ti_sci_xfer *xfer;
2462 	struct ti_sci_info *info;
2463 	int ret = 0;
2464 
2465 	if (IS_ERR(handle))
2466 		return PTR_ERR(handle);
2467 	if (!handle)
2468 		return -EINVAL;
2469 
2470 	info = handle_to_ti_sci_info(handle);
2471 
2472 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_RM_UDMAP_TX_CH_CFG,
2473 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2474 				     (u32 *)&req, sizeof(req), sizeof(*resp));
2475 	if (IS_ERR(xfer)) {
2476 		ret = PTR_ERR(xfer);
2477 		dev_err(info->dev, "Message TX_CH_CFG alloc failed(%d)\n", ret);
2478 		return ret;
2479 	}
2480 	req.valid_params = params->valid_params;
2481 	req.nav_id = params->nav_id;
2482 	req.index = params->index;
2483 	req.tx_pause_on_err = params->tx_pause_on_err;
2484 	req.tx_filt_einfo = params->tx_filt_einfo;
2485 	req.tx_filt_pswords = params->tx_filt_pswords;
2486 	req.tx_atype = params->tx_atype;
2487 	req.tx_chan_type = params->tx_chan_type;
2488 	req.tx_supr_tdpkt = params->tx_supr_tdpkt;
2489 	req.tx_fetch_size = params->tx_fetch_size;
2490 	req.tx_credit_count = params->tx_credit_count;
2491 	req.txcq_qnum = params->txcq_qnum;
2492 	req.tx_priority = params->tx_priority;
2493 	req.tx_qos = params->tx_qos;
2494 	req.tx_orderid = params->tx_orderid;
2495 	req.fdepth = params->fdepth;
2496 	req.tx_sched_priority = params->tx_sched_priority;
2497 
2498 	ret = ti_sci_do_xfer(info, xfer);
2499 	if (ret) {
2500 		dev_err(info->dev, "Mbox send TX_CH_CFG fail %d\n", ret);
2501 		goto fail;
2502 	}
2503 
2504 	resp =
2505 	      (struct ti_sci_msg_rm_udmap_tx_ch_cfg_resp *)xfer->tx_message.buf;
2506 	ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2507 
2508 fail:
2509 	dev_dbg(info->dev, "TX_CH_CFG: chn %u ret:%u\n", params->index, ret);
2510 	return ret;
2511 }
2512 
ti_sci_cmd_rm_udmap_rx_ch_cfg(const struct ti_sci_handle * handle,const struct ti_sci_msg_rm_udmap_rx_ch_cfg * params)2513 static int ti_sci_cmd_rm_udmap_rx_ch_cfg(
2514 			const struct ti_sci_handle *handle,
2515 			const struct ti_sci_msg_rm_udmap_rx_ch_cfg *params)
2516 {
2517 	struct ti_sci_msg_rm_udmap_rx_ch_cfg_resp *resp;
2518 	struct ti_sci_msg_rm_udmap_rx_ch_cfg_req req;
2519 	struct ti_sci_xfer *xfer;
2520 	struct ti_sci_info *info;
2521 	int ret = 0;
2522 
2523 	if (IS_ERR(handle))
2524 		return PTR_ERR(handle);
2525 	if (!handle)
2526 		return -EINVAL;
2527 
2528 	info = handle_to_ti_sci_info(handle);
2529 
2530 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_RM_UDMAP_RX_CH_CFG,
2531 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2532 				     (u32 *)&req, sizeof(req), sizeof(*resp));
2533 	if (IS_ERR(xfer)) {
2534 		ret = PTR_ERR(xfer);
2535 		dev_err(info->dev, "Message RX_CH_CFG alloc failed(%d)\n", ret);
2536 		return ret;
2537 	}
2538 
2539 	req.valid_params = params->valid_params;
2540 	req.nav_id = params->nav_id;
2541 	req.index = params->index;
2542 	req.rx_fetch_size = params->rx_fetch_size;
2543 	req.rxcq_qnum = params->rxcq_qnum;
2544 	req.rx_priority = params->rx_priority;
2545 	req.rx_qos = params->rx_qos;
2546 	req.rx_orderid = params->rx_orderid;
2547 	req.rx_sched_priority = params->rx_sched_priority;
2548 	req.flowid_start = params->flowid_start;
2549 	req.flowid_cnt = params->flowid_cnt;
2550 	req.rx_pause_on_err = params->rx_pause_on_err;
2551 	req.rx_atype = params->rx_atype;
2552 	req.rx_chan_type = params->rx_chan_type;
2553 	req.rx_ignore_short = params->rx_ignore_short;
2554 	req.rx_ignore_long = params->rx_ignore_long;
2555 
2556 	ret = ti_sci_do_xfer(info, xfer);
2557 	if (ret) {
2558 		dev_err(info->dev, "Mbox send RX_CH_CFG fail %d\n", ret);
2559 		goto fail;
2560 	}
2561 
2562 	resp =
2563 	      (struct ti_sci_msg_rm_udmap_rx_ch_cfg_resp *)xfer->tx_message.buf;
2564 	ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2565 
2566 fail:
2567 	dev_dbg(info->dev, "RX_CH_CFG: chn %u ret:%d\n", params->index, ret);
2568 	return ret;
2569 }
2570 
ti_sci_cmd_rm_udmap_rx_flow_cfg(const struct ti_sci_handle * handle,const struct ti_sci_msg_rm_udmap_flow_cfg * params)2571 static int ti_sci_cmd_rm_udmap_rx_flow_cfg(
2572 			const struct ti_sci_handle *handle,
2573 			const struct ti_sci_msg_rm_udmap_flow_cfg *params)
2574 {
2575 	struct ti_sci_msg_rm_udmap_flow_cfg_resp *resp;
2576 	struct ti_sci_msg_rm_udmap_flow_cfg_req req;
2577 	struct ti_sci_xfer *xfer;
2578 	struct ti_sci_info *info;
2579 	int ret = 0;
2580 
2581 	if (IS_ERR(handle))
2582 		return PTR_ERR(handle);
2583 	if (!handle)
2584 		return -EINVAL;
2585 
2586 	info = handle_to_ti_sci_info(handle);
2587 
2588 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_RM_UDMAP_FLOW_CFG,
2589 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2590 				     (u32 *)&req, sizeof(req), sizeof(*resp));
2591 	if (IS_ERR(xfer)) {
2592 		ret = PTR_ERR(xfer);
2593 		dev_err(dev, "RX_FL_CFG: Message alloc failed(%d)\n", ret);
2594 		return ret;
2595 	}
2596 
2597 	req.valid_params = params->valid_params;
2598 	req.nav_id = params->nav_id;
2599 	req.flow_index = params->flow_index;
2600 	req.rx_einfo_present = params->rx_einfo_present;
2601 	req.rx_psinfo_present = params->rx_psinfo_present;
2602 	req.rx_error_handling = params->rx_error_handling;
2603 	req.rx_desc_type = params->rx_desc_type;
2604 	req.rx_sop_offset = params->rx_sop_offset;
2605 	req.rx_dest_qnum = params->rx_dest_qnum;
2606 	req.rx_src_tag_hi = params->rx_src_tag_hi;
2607 	req.rx_src_tag_lo = params->rx_src_tag_lo;
2608 	req.rx_dest_tag_hi = params->rx_dest_tag_hi;
2609 	req.rx_dest_tag_lo = params->rx_dest_tag_lo;
2610 	req.rx_src_tag_hi_sel = params->rx_src_tag_hi_sel;
2611 	req.rx_src_tag_lo_sel = params->rx_src_tag_lo_sel;
2612 	req.rx_dest_tag_hi_sel = params->rx_dest_tag_hi_sel;
2613 	req.rx_dest_tag_lo_sel = params->rx_dest_tag_lo_sel;
2614 	req.rx_fdq0_sz0_qnum = params->rx_fdq0_sz0_qnum;
2615 	req.rx_fdq1_qnum = params->rx_fdq1_qnum;
2616 	req.rx_fdq2_qnum = params->rx_fdq2_qnum;
2617 	req.rx_fdq3_qnum = params->rx_fdq3_qnum;
2618 	req.rx_ps_location = params->rx_ps_location;
2619 
2620 	ret = ti_sci_do_xfer(info, xfer);
2621 	if (ret) {
2622 		dev_err(dev, "RX_FL_CFG: Mbox send fail %d\n", ret);
2623 		goto fail;
2624 	}
2625 
2626 	resp =
2627 	       (struct ti_sci_msg_rm_udmap_flow_cfg_resp *)xfer->tx_message.buf;
2628 	ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2629 
2630 fail:
2631 	dev_dbg(info->dev, "RX_FL_CFG: %u ret:%d\n", params->flow_index, ret);
2632 	return ret;
2633 }
2634 
2635 /**
2636  * ti_sci_cmd_set_fwl_region() - Request for configuring a firewall region
2637  * @handle:    pointer to TI SCI handle
2638  * @region:    region configuration parameters
2639  *
2640  * Return: 0 if all went well, else returns appropriate error value.
2641  */
ti_sci_cmd_set_fwl_region(const struct ti_sci_handle * handle,const struct ti_sci_msg_fwl_region * region)2642 static int ti_sci_cmd_set_fwl_region(const struct ti_sci_handle *handle,
2643 				     const struct ti_sci_msg_fwl_region *region)
2644 {
2645 	struct ti_sci_msg_fwl_set_firewall_region_req req;
2646 	struct ti_sci_msg_hdr *resp;
2647 	struct ti_sci_info *info;
2648 	struct ti_sci_xfer *xfer;
2649 	int ret = 0;
2650 
2651 	if (IS_ERR(handle))
2652 		return PTR_ERR(handle);
2653 	if (!handle)
2654 		return -EINVAL;
2655 
2656 	info = handle_to_ti_sci_info(handle);
2657 
2658 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_SET,
2659 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2660 				     (u32 *)&req, sizeof(req), sizeof(*resp));
2661 	if (IS_ERR(xfer)) {
2662 		ret = PTR_ERR(xfer);
2663 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
2664 		return ret;
2665 	}
2666 
2667 	req.fwl_id = region->fwl_id;
2668 	req.region = region->region;
2669 	req.n_permission_regs = region->n_permission_regs;
2670 	req.control = region->control;
2671 	req.permissions[0] = region->permissions[0];
2672 	req.permissions[1] = region->permissions[1];
2673 	req.permissions[2] = region->permissions[2];
2674 	req.start_address = region->start_address;
2675 	req.end_address = region->end_address;
2676 
2677 	ret = ti_sci_do_xfer(info, xfer);
2678 	if (ret) {
2679 		dev_err(info->dev, "Mbox send fail %d\n", ret);
2680 		return ret;
2681 	}
2682 
2683 	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
2684 
2685 	if (!ti_sci_is_response_ack(resp))
2686 		return -ENODEV;
2687 
2688 	return 0;
2689 }
2690 
2691 /**
2692  * ti_sci_cmd_get_fwl_region() - Request for getting a firewall region
2693  * @handle:    pointer to TI SCI handle
2694  * @region:    region configuration parameters
2695  *
2696  * Return: 0 if all went well, else returns appropriate error value.
2697  */
ti_sci_cmd_get_fwl_region(const struct ti_sci_handle * handle,struct ti_sci_msg_fwl_region * region)2698 static int ti_sci_cmd_get_fwl_region(const struct ti_sci_handle *handle,
2699 				     struct ti_sci_msg_fwl_region *region)
2700 {
2701 	struct ti_sci_msg_fwl_get_firewall_region_req req;
2702 	struct ti_sci_msg_fwl_get_firewall_region_resp *resp;
2703 	struct ti_sci_info *info;
2704 	struct ti_sci_xfer *xfer;
2705 	int ret = 0;
2706 
2707 	if (IS_ERR(handle))
2708 		return PTR_ERR(handle);
2709 	if (!handle)
2710 		return -EINVAL;
2711 
2712 	info = handle_to_ti_sci_info(handle);
2713 
2714 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_GET,
2715 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2716 				     (u32 *)&req, sizeof(req), sizeof(*resp));
2717 	if (IS_ERR(xfer)) {
2718 		ret = PTR_ERR(xfer);
2719 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
2720 		return ret;
2721 	}
2722 
2723 	req.fwl_id = region->fwl_id;
2724 	req.region = region->region;
2725 	req.n_permission_regs = region->n_permission_regs;
2726 
2727 	ret = ti_sci_do_xfer(info, xfer);
2728 	if (ret) {
2729 		dev_err(info->dev, "Mbox send fail %d\n", ret);
2730 		return ret;
2731 	}
2732 
2733 	resp = (struct ti_sci_msg_fwl_get_firewall_region_resp *)xfer->tx_message.buf;
2734 
2735 	if (!ti_sci_is_response_ack(resp))
2736 		return -ENODEV;
2737 
2738 	region->fwl_id = resp->fwl_id;
2739 	region->region = resp->region;
2740 	region->n_permission_regs = resp->n_permission_regs;
2741 	region->control = resp->control;
2742 	region->permissions[0] = resp->permissions[0];
2743 	region->permissions[1] = resp->permissions[1];
2744 	region->permissions[2] = resp->permissions[2];
2745 	region->start_address = resp->start_address;
2746 	region->end_address = resp->end_address;
2747 
2748 	return 0;
2749 }
2750 
2751 /**
2752  * ti_sci_cmd_change_fwl_owner() - Request for changing a firewall owner
2753  * @handle:    pointer to TI SCI handle
2754  * @region:    region configuration parameters
2755  *
2756  * Return: 0 if all went well, else returns appropriate error value.
2757  */
ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle * handle,struct ti_sci_msg_fwl_owner * owner)2758 static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle,
2759 				       struct ti_sci_msg_fwl_owner *owner)
2760 {
2761 	struct ti_sci_msg_fwl_change_owner_info_req req;
2762 	struct ti_sci_msg_fwl_change_owner_info_resp *resp;
2763 	struct ti_sci_info *info;
2764 	struct ti_sci_xfer *xfer;
2765 	int ret = 0;
2766 
2767 	if (IS_ERR(handle))
2768 		return PTR_ERR(handle);
2769 	if (!handle)
2770 		return -EINVAL;
2771 
2772 	info = handle_to_ti_sci_info(handle);
2773 
2774 	xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_CHANGE_OWNER,
2775 				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2776 				     (u32 *)&req, sizeof(req), sizeof(*resp));
2777 	if (IS_ERR(xfer)) {
2778 		ret = PTR_ERR(xfer);
2779 		dev_err(info->dev, "Message alloc failed(%d)\n", ret);
2780 		return ret;
2781 	}
2782 
2783 	req.fwl_id = owner->fwl_id;
2784 	req.region = owner->region;
2785 	req.owner_index = owner->owner_index;
2786 
2787 	ret = ti_sci_do_xfer(info, xfer);
2788 	if (ret) {
2789 		dev_err(info->dev, "Mbox send fail %d\n", ret);
2790 		return ret;
2791 	}
2792 
2793 	resp = (struct ti_sci_msg_fwl_change_owner_info_resp *)xfer->tx_message.buf;
2794 
2795 	if (!ti_sci_is_response_ack(resp))
2796 		return -ENODEV;
2797 
2798 	owner->fwl_id = resp->fwl_id;
2799 	owner->region = resp->region;
2800 	owner->owner_index = resp->owner_index;
2801 	owner->owner_privid = resp->owner_privid;
2802 	owner->owner_permission_bits = resp->owner_permission_bits;
2803 
2804 	return ret;
2805 }
2806 
2807 /*
2808  * ti_sci_setup_ops() - Setup the operations structures
2809  * @info:	pointer to TISCI pointer
2810  */
ti_sci_setup_ops(struct ti_sci_info * info)2811 static void ti_sci_setup_ops(struct ti_sci_info *info)
2812 {
2813 	struct ti_sci_ops *ops = &info->handle.ops;
2814 	struct ti_sci_board_ops *bops = &ops->board_ops;
2815 	struct ti_sci_dev_ops *dops = &ops->dev_ops;
2816 	struct ti_sci_clk_ops *cops = &ops->clk_ops;
2817 	struct ti_sci_core_ops *core_ops = &ops->core_ops;
2818 	struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;
2819 	struct ti_sci_proc_ops *pops = &ops->proc_ops;
2820 	struct ti_sci_rm_ringacc_ops *rops = &ops->rm_ring_ops;
2821 	struct ti_sci_rm_psil_ops *psilops = &ops->rm_psil_ops;
2822 	struct ti_sci_rm_udmap_ops *udmap_ops = &ops->rm_udmap_ops;
2823 	struct ti_sci_fwl_ops *fwl_ops = &ops->fwl_ops;
2824 
2825 	bops->board_config = ti_sci_cmd_set_board_config;
2826 	bops->board_config_rm = ti_sci_cmd_set_board_config_rm;
2827 	bops->board_config_security = ti_sci_cmd_set_board_config_security;
2828 	bops->board_config_pm = ti_sci_cmd_set_board_config_pm;
2829 
2830 	dops->get_device = ti_sci_cmd_get_device;
2831 	dops->get_device_exclusive = ti_sci_cmd_get_device_exclusive;
2832 	dops->idle_device = ti_sci_cmd_idle_device;
2833 	dops->idle_device_exclusive = ti_sci_cmd_idle_device_exclusive;
2834 	dops->put_device = ti_sci_cmd_put_device;
2835 	dops->is_valid = ti_sci_cmd_dev_is_valid;
2836 	dops->get_context_loss_count = ti_sci_cmd_dev_get_clcnt;
2837 	dops->is_idle = ti_sci_cmd_dev_is_idle;
2838 	dops->is_stop = ti_sci_cmd_dev_is_stop;
2839 	dops->is_on = ti_sci_cmd_dev_is_on;
2840 	dops->is_transitioning = ti_sci_cmd_dev_is_trans;
2841 	dops->set_device_resets = ti_sci_cmd_set_device_resets;
2842 	dops->get_device_resets = ti_sci_cmd_get_device_resets;
2843 	dops->release_exclusive_devices = ti_sci_cmd_release_exclusive_devices;
2844 
2845 	cops->get_clock = ti_sci_cmd_get_clock;
2846 	cops->idle_clock = ti_sci_cmd_idle_clock;
2847 	cops->put_clock = ti_sci_cmd_put_clock;
2848 	cops->is_auto = ti_sci_cmd_clk_is_auto;
2849 	cops->is_on = ti_sci_cmd_clk_is_on;
2850 	cops->is_off = ti_sci_cmd_clk_is_off;
2851 
2852 	cops->set_parent = ti_sci_cmd_clk_set_parent;
2853 	cops->get_parent = ti_sci_cmd_clk_get_parent;
2854 	cops->get_num_parents = ti_sci_cmd_clk_get_num_parents;
2855 
2856 	cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq;
2857 	cops->set_freq = ti_sci_cmd_clk_set_freq;
2858 	cops->get_freq = ti_sci_cmd_clk_get_freq;
2859 
2860 	core_ops->reboot_device = ti_sci_cmd_core_reboot;
2861 	core_ops->query_msmc = ti_sci_cmd_query_msmc;
2862 
2863 	rm_core_ops->get_range = ti_sci_cmd_get_resource_range;
2864 	rm_core_ops->get_range_from_shost =
2865 		ti_sci_cmd_get_resource_range_from_shost;
2866 
2867 	pops->proc_request = ti_sci_cmd_proc_request;
2868 	pops->proc_release = ti_sci_cmd_proc_release;
2869 	pops->proc_handover = ti_sci_cmd_proc_handover;
2870 	pops->set_proc_boot_cfg = ti_sci_cmd_set_proc_boot_cfg;
2871 	pops->set_proc_boot_ctrl = ti_sci_cmd_set_proc_boot_ctrl;
2872 	pops->proc_auth_boot_image = ti_sci_cmd_proc_auth_boot_image;
2873 	pops->get_proc_boot_status = ti_sci_cmd_get_proc_boot_status;
2874 	pops->proc_shutdown_no_wait = ti_sci_cmd_proc_shutdown_no_wait;
2875 
2876 	rops->config = ti_sci_cmd_ring_config;
2877 
2878 	psilops->pair = ti_sci_cmd_rm_psil_pair;
2879 	psilops->unpair = ti_sci_cmd_rm_psil_unpair;
2880 
2881 	udmap_ops->tx_ch_cfg = ti_sci_cmd_rm_udmap_tx_ch_cfg;
2882 	udmap_ops->rx_ch_cfg = ti_sci_cmd_rm_udmap_rx_ch_cfg;
2883 	udmap_ops->rx_flow_cfg = ti_sci_cmd_rm_udmap_rx_flow_cfg;
2884 
2885 	fwl_ops->set_fwl_region = ti_sci_cmd_set_fwl_region;
2886 	fwl_ops->get_fwl_region = ti_sci_cmd_get_fwl_region;
2887 	fwl_ops->change_fwl_owner = ti_sci_cmd_change_fwl_owner;
2888 }
2889 
2890 /**
2891  * ti_sci_get_handle_from_sysfw() - Get the TI SCI handle of the SYSFW
2892  * @dev:	Pointer to the SYSFW device
2893  *
2894  * Return: pointer to handle if successful, else EINVAL if invalid conditions
2895  *         are encountered.
2896  */
2897 const
ti_sci_get_handle_from_sysfw(struct udevice * sci_dev)2898 struct ti_sci_handle *ti_sci_get_handle_from_sysfw(struct udevice *sci_dev)
2899 {
2900 	if (!sci_dev)
2901 		return ERR_PTR(-EINVAL);
2902 
2903 	struct ti_sci_info *info = dev_get_priv(sci_dev);
2904 
2905 	if (!info)
2906 		return ERR_PTR(-EINVAL);
2907 
2908 	struct ti_sci_handle *handle = &info->handle;
2909 
2910 	if (!handle)
2911 		return ERR_PTR(-EINVAL);
2912 
2913 	return handle;
2914 }
2915 
2916 /**
2917  * ti_sci_get_handle() - Get the TI SCI handle for a device
2918  * @dev:	Pointer to device for which we want SCI handle
2919  *
2920  * Return: pointer to handle if successful, else EINVAL if invalid conditions
2921  *         are encountered.
2922  */
ti_sci_get_handle(struct udevice * dev)2923 const struct ti_sci_handle *ti_sci_get_handle(struct udevice *dev)
2924 {
2925 	if (!dev)
2926 		return ERR_PTR(-EINVAL);
2927 
2928 	struct udevice *sci_dev = dev_get_parent(dev);
2929 
2930 	return ti_sci_get_handle_from_sysfw(sci_dev);
2931 }
2932 
2933 /**
2934  * ti_sci_get_by_phandle() - Get the TI SCI handle using DT phandle
2935  * @dev:	device node
2936  * @propname:	property name containing phandle on TISCI node
2937  *
2938  * Return: pointer to handle if successful, else appropriate error value.
2939  */
ti_sci_get_by_phandle(struct udevice * dev,const char * property)2940 const struct ti_sci_handle *ti_sci_get_by_phandle(struct udevice *dev,
2941 						  const char *property)
2942 {
2943 	struct ti_sci_info *entry, *info = NULL;
2944 	u32 phandle, err;
2945 	ofnode node;
2946 
2947 	err = ofnode_read_u32(dev_ofnode(dev), property, &phandle);
2948 	if (err)
2949 		return ERR_PTR(err);
2950 
2951 	node = ofnode_get_by_phandle(phandle);
2952 	if (!ofnode_valid(node))
2953 		return ERR_PTR(-EINVAL);
2954 
2955 	list_for_each_entry(entry, &ti_sci_list, list)
2956 		if (ofnode_equal(dev_ofnode(entry->dev), node)) {
2957 			info = entry;
2958 			break;
2959 		}
2960 
2961 	if (!info)
2962 		return ERR_PTR(-ENODEV);
2963 
2964 	return &info->handle;
2965 }
2966 
2967 /**
2968  * ti_sci_of_to_info() - generate private data from device tree
2969  * @dev:	corresponding system controller interface device
2970  * @info:	pointer to driver specific private data
2971  *
2972  * Return: 0 if all goes good, else appropriate error message.
2973  */
ti_sci_of_to_info(struct udevice * dev,struct ti_sci_info * info)2974 static int ti_sci_of_to_info(struct udevice *dev, struct ti_sci_info *info)
2975 {
2976 	int ret;
2977 
2978 	ret = mbox_get_by_name(dev, "tx", &info->chan_tx);
2979 	if (ret) {
2980 		dev_err(dev, "%s: Acquiring Tx channel failed. ret = %d\n",
2981 			__func__, ret);
2982 		return ret;
2983 	}
2984 
2985 	ret = mbox_get_by_name(dev, "rx", &info->chan_rx);
2986 	if (ret) {
2987 		dev_err(dev, "%s: Acquiring Rx channel failed. ret = %d\n",
2988 			__func__, ret);
2989 		return ret;
2990 	}
2991 
2992 	/* Notify channel is optional. Enable only if populated */
2993 	ret = mbox_get_by_name(dev, "notify", &info->chan_notify);
2994 	if (ret) {
2995 		dev_dbg(dev, "%s: Acquiring notify channel failed. ret = %d\n",
2996 			__func__, ret);
2997 	}
2998 
2999 	info->host_id = dev_read_u32_default(dev, "ti,host-id",
3000 					     info->desc->default_host_id);
3001 
3002 	info->is_secure = dev_read_bool(dev, "ti,secure-host");
3003 
3004 	return 0;
3005 }
3006 
3007 /**
3008  * ti_sci_probe() - Basic probe
3009  * @dev:	corresponding system controller interface device
3010  *
3011  * Return: 0 if all goes good, else appropriate error message.
3012  */
ti_sci_probe(struct udevice * dev)3013 static int ti_sci_probe(struct udevice *dev)
3014 {
3015 	struct ti_sci_info *info;
3016 	int ret;
3017 
3018 	debug("%s(dev=%p)\n", __func__, dev);
3019 
3020 	info = dev_get_priv(dev);
3021 	info->desc = (void *)dev_get_driver_data(dev);
3022 
3023 	ret = ti_sci_of_to_info(dev, info);
3024 	if (ret) {
3025 		dev_err(dev, "%s: Probe failed with error %d\n", __func__, ret);
3026 		return ret;
3027 	}
3028 
3029 	info->dev = dev;
3030 	info->seq = 0xA;
3031 
3032 	list_add_tail(&info->list, &ti_sci_list);
3033 	ti_sci_setup_ops(info);
3034 
3035 	ret = ti_sci_cmd_get_revision(&info->handle);
3036 
3037 	INIT_LIST_HEAD(&info->dev_list);
3038 
3039 	return ret;
3040 }
3041 
3042 /*
3043  * ti_sci_get_free_resource() - Get a free resource from TISCI resource.
3044  * @res:	Pointer to the TISCI resource
3045  *
3046  * Return: resource num if all went ok else TI_SCI_RESOURCE_NULL.
3047  */
ti_sci_get_free_resource(struct ti_sci_resource * res)3048 u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
3049 {
3050 	u16 set, free_bit;
3051 
3052 	for (set = 0; set < res->sets; set++) {
3053 		free_bit = find_first_zero_bit(res->desc[set].res_map,
3054 					       res->desc[set].num);
3055 		if (free_bit != res->desc[set].num) {
3056 			set_bit(free_bit, res->desc[set].res_map);
3057 			return res->desc[set].start + free_bit;
3058 		}
3059 	}
3060 
3061 	return TI_SCI_RESOURCE_NULL;
3062 }
3063 
3064 /**
3065  * ti_sci_release_resource() - Release a resource from TISCI resource.
3066  * @res:	Pointer to the TISCI resource
3067  */
ti_sci_release_resource(struct ti_sci_resource * res,u16 id)3068 void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
3069 {
3070 	u16 set;
3071 
3072 	for (set = 0; set < res->sets; set++) {
3073 		if (res->desc[set].start <= id &&
3074 		    (res->desc[set].num + res->desc[set].start) > id)
3075 			clear_bit(id - res->desc[set].start,
3076 				  res->desc[set].res_map);
3077 	}
3078 }
3079 
3080 /**
3081  * devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to a device
3082  * @handle:	TISCI handle
3083  * @dev:	Device pointer to which the resource is assigned
3084  * @of_prop:	property name by which the resource are represented
3085  *
3086  * Note: This function expects of_prop to be in the form of tuples
3087  *	<type, subtype>. Allocates and initializes ti_sci_resource structure
3088  *	for each of_prop. Client driver can directly call
3089  *	ti_sci_(get_free, release)_resource apis for handling the resource.
3090  *
3091  * Return: Pointer to ti_sci_resource if all went well else appropriate
3092  *	   error pointer.
3093  */
3094 struct ti_sci_resource *
devm_ti_sci_get_of_resource(const struct ti_sci_handle * handle,struct udevice * dev,u32 dev_id,char * of_prop)3095 devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
3096 			    struct udevice *dev, u32 dev_id, char *of_prop)
3097 {
3098 	u32 resource_subtype;
3099 	u16 resource_type;
3100 	struct ti_sci_resource *res;
3101 	bool valid_set = false;
3102 	int sets, i, ret;
3103 	u32 *temp;
3104 
3105 	res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
3106 	if (!res)
3107 		return ERR_PTR(-ENOMEM);
3108 
3109 	sets = dev_read_size(dev, of_prop);
3110 	if (sets < 0) {
3111 		dev_err(dev, "%s resource type ids not available\n", of_prop);
3112 		return ERR_PTR(sets);
3113 	}
3114 	temp = malloc(sets);
3115 	sets /= sizeof(u32);
3116 	res->sets = sets;
3117 
3118 	res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc),
3119 				 GFP_KERNEL);
3120 	if (!res->desc)
3121 		return ERR_PTR(-ENOMEM);
3122 
3123 	ret = ti_sci_get_resource_type(handle_to_ti_sci_info(handle), dev_id,
3124 				       &resource_type);
3125 	if (ret) {
3126 		dev_err(dev, "No valid resource type for %u\n", dev_id);
3127 		return ERR_PTR(-EINVAL);
3128 	}
3129 
3130 	ret = dev_read_u32_array(dev, of_prop, temp, res->sets);
3131 	if (ret)
3132 		return ERR_PTR(-EINVAL);
3133 
3134 	for (i = 0; i < res->sets; i++) {
3135 		resource_subtype = temp[i];
3136 		ret = handle->ops.rm_core_ops.get_range(handle, dev_id,
3137 							resource_subtype,
3138 							&res->desc[i].start,
3139 							&res->desc[i].num);
3140 		if (ret) {
3141 			dev_dbg(dev, "type %d subtype %d not allocated for host %d\n",
3142 				resource_type, resource_subtype,
3143 				handle_to_ti_sci_info(handle)->host_id);
3144 			res->desc[i].start = 0;
3145 			res->desc[i].num = 0;
3146 			continue;
3147 		}
3148 
3149 		valid_set = true;
3150 		dev_dbg(dev, "res type = %d, subtype = %d, start = %d, num = %d\n",
3151 			resource_type, resource_subtype, res->desc[i].start,
3152 			res->desc[i].num);
3153 
3154 		res->desc[i].res_map =
3155 			devm_kzalloc(dev, BITS_TO_LONGS(res->desc[i].num) *
3156 				     sizeof(*res->desc[i].res_map), GFP_KERNEL);
3157 		if (!res->desc[i].res_map)
3158 			return ERR_PTR(-ENOMEM);
3159 	}
3160 
3161 	if (valid_set)
3162 		return res;
3163 
3164 	return ERR_PTR(-EINVAL);
3165 }
3166 
3167 /* Description for K2G */
3168 static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
3169 	.default_host_id = 2,
3170 	/* Conservative duration */
3171 	.max_rx_timeout_ms = 10000,
3172 	/* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
3173 	.max_msgs = 20,
3174 	.max_msg_size = 64,
3175 	.rm_type_map = NULL,
3176 };
3177 
3178 static struct ti_sci_rm_type_map ti_sci_am654_rm_type_map[] = {
3179 	{.dev_id = 56, .type = 0x00b}, /* GIC_IRQ */
3180 	{.dev_id = 179, .type = 0x000}, /* MAIN_NAV_UDMASS_IA0 */
3181 	{.dev_id = 187, .type = 0x009}, /* MAIN_NAV_RA */
3182 	{.dev_id = 188, .type = 0x006}, /* MAIN_NAV_UDMAP */
3183 	{.dev_id = 194, .type = 0x007}, /* MCU_NAV_UDMAP */
3184 	{.dev_id = 195, .type = 0x00a}, /* MCU_NAV_RA */
3185 	{.dev_id = 0, .type = 0x000}, /* end of table */
3186 };
3187 
3188 /* Description for AM654 */
3189 static const struct ti_sci_desc ti_sci_pmmc_am654_desc = {
3190 	.default_host_id = 12,
3191 	/* Conservative duration */
3192 	.max_rx_timeout_ms = 10000,
3193 	/* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
3194 	.max_msgs = 20,
3195 	.max_msg_size = 60,
3196 	.rm_type_map = ti_sci_am654_rm_type_map,
3197 };
3198 
3199 static const struct udevice_id ti_sci_ids[] = {
3200 	{
3201 		.compatible = "ti,k2g-sci",
3202 		.data = (ulong)&ti_sci_pmmc_k2g_desc
3203 	},
3204 	{
3205 		.compatible = "ti,am654-sci",
3206 		.data = (ulong)&ti_sci_pmmc_am654_desc
3207 	},
3208 	{ /* Sentinel */ },
3209 };
3210 
3211 U_BOOT_DRIVER(ti_sci) = {
3212 	.name = "ti_sci",
3213 	.id = UCLASS_FIRMWARE,
3214 	.of_match = ti_sci_ids,
3215 	.probe = ti_sci_probe,
3216 	.priv_auto_alloc_size = sizeof(struct ti_sci_info),
3217 };
3218