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