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