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