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