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