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