1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Texas Instruments System Control Interface Protocol Driver
4 *
5 * Copyright (C) 2015-2025 Texas Instruments Incorporated - https://www.ti.com/
6 * Nishanth Menon
7 */
8
9 #define pr_fmt(fmt) "%s: " fmt, __func__
10
11 #include <linux/bitmap.h>
12 #include <linux/clk.h>
13 #include <linux/cpu.h>
14 #include <linux/debugfs.h>
15 #include <linux/export.h>
16 #include <linux/hashtable.h>
17 #include <linux/io.h>
18 #include <linux/iopoll.h>
19 #include <linux/kernel.h>
20 #include <linux/mailbox_client.h>
21 #include <linux/module.h>
22 #include <linux/mutex.h>
23 #include <linux/of.h>
24 #include <linux/of_platform.h>
25 #include <linux/platform_device.h>
26 #include <linux/pm_qos.h>
27 #include <linux/property.h>
28 #include <linux/semaphore.h>
29 #include <linux/slab.h>
30 #include <linux/soc/ti/ti-msgmgr.h>
31 #include <linux/soc/ti/ti_sci_protocol.h>
32 #include <linux/suspend.h>
33 #include <linux/sys_soc.h>
34 #include <linux/reboot.h>
35
36 #include "ti_sci.h"
37
38 /* List of all TI SCI devices active in system */
39 static LIST_HEAD(ti_sci_list);
40 /* Protection for the entire list */
41 static DEFINE_MUTEX(ti_sci_list_mutex);
42
43 /**
44 * struct ti_sci_xfer - Structure representing a message flow
45 * @tx_message: Transmit message
46 * @rx_len: Receive message length
47 * @xfer_buf: Preallocated buffer to store receive message
48 * Since we work with request-ACK protocol, we can
49 * reuse the same buffer for the rx path as we
50 * use for the tx path.
51 * @done: completion event
52 */
53 struct ti_sci_xfer {
54 struct ti_msgmgr_message tx_message;
55 u8 rx_len;
56 u8 *xfer_buf;
57 struct completion done;
58 };
59
60 /**
61 * struct ti_sci_xfers_info - Structure to manage transfer information
62 * @sem_xfer_count: Counting Semaphore for managing max simultaneous
63 * Messages.
64 * @xfer_block: Preallocated Message array
65 * @xfer_alloc_table: Bitmap table for allocated messages.
66 * Index of this bitmap table is also used for message
67 * sequence identifier.
68 * @xfer_lock: Protection for message allocation
69 */
70 struct ti_sci_xfers_info {
71 struct semaphore sem_xfer_count;
72 struct ti_sci_xfer *xfer_block;
73 unsigned long *xfer_alloc_table;
74 /* protect transfer allocation */
75 spinlock_t xfer_lock;
76 };
77
78 /**
79 * struct ti_sci_desc - Description of SoC integration
80 * @default_host_id: Host identifier representing the compute entity
81 * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
82 * @max_msgs: Maximum number of messages that can be pending
83 * simultaneously in the system
84 * @max_msg_size: Maximum size of data per message that can be handled.
85 */
86 struct ti_sci_desc {
87 u8 default_host_id;
88 int max_rx_timeout_ms;
89 int max_msgs;
90 int max_msg_size;
91 };
92
93 /**
94 * struct ti_sci_irq - Description of allocated irqs
95 * @node: Link to hash table
96 * @desc: Description of the irq
97 */
98 struct ti_sci_irq {
99 struct hlist_node node;
100 struct ti_sci_msg_req_manage_irq desc;
101 };
102
103 /**
104 * struct ti_sci_info - Structure representing a TI SCI instance
105 * @dev: Device pointer
106 * @desc: SoC description for this instance
107 * @d: Debugfs file entry
108 * @debug_region: Memory region where the debug message are available
109 * @debug_region_size: Debug region size
110 * @debug_buffer: Buffer allocated to copy debug messages.
111 * @handle: Instance of TI SCI handle to send to clients.
112 * @cl: Mailbox Client
113 * @chan_tx: Transmit mailbox channel
114 * @chan_rx: Receive mailbox channel
115 * @minfo: Message info
116 * @node: list head
117 * @irqs: List of allocated irqs
118 * @irq_lock: Protection for irq hash list
119 * @host_id: Host ID
120 * @fw_caps: FW/SoC low power capabilities
121 * @users: Number of users of this instance
122 */
123 struct ti_sci_info {
124 struct device *dev;
125 const struct ti_sci_desc *desc;
126 struct dentry *d;
127 void __iomem *debug_region;
128 char *debug_buffer;
129 size_t debug_region_size;
130 struct ti_sci_handle handle;
131 struct mbox_client cl;
132 struct mbox_chan *chan_tx;
133 struct mbox_chan *chan_rx;
134 struct ti_sci_xfers_info minfo;
135 struct list_head node;
136 DECLARE_HASHTABLE(irqs, 8);
137 struct mutex irq_lock;
138 u8 host_id;
139 u64 fw_caps;
140 /* protected by ti_sci_list_mutex */
141 int users;
142 };
143
144 #define cl_to_ti_sci_info(c) container_of(c, struct ti_sci_info, cl)
145 #define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle)
146
147 #ifdef CONFIG_DEBUG_FS
148
149 /**
150 * ti_sci_debug_show() - Helper to dump the debug log
151 * @s: sequence file pointer
152 * @unused: unused.
153 *
154 * Return: 0
155 */
ti_sci_debug_show(struct seq_file * s,void * unused)156 static int ti_sci_debug_show(struct seq_file *s, void *unused)
157 {
158 struct ti_sci_info *info = s->private;
159
160 memcpy_fromio(info->debug_buffer, info->debug_region,
161 info->debug_region_size);
162 /*
163 * We don't trust firmware to leave NULL terminated last byte (hence
164 * we have allocated 1 extra 0 byte). Since we cannot guarantee any
165 * specific data format for debug messages, We just present the data
166 * in the buffer as is - we expect the messages to be self explanatory.
167 */
168 seq_puts(s, info->debug_buffer);
169 return 0;
170 }
171
172 /* Provide the log file operations interface*/
173 DEFINE_SHOW_ATTRIBUTE(ti_sci_debug);
174
175 /**
176 * ti_sci_debugfs_create() - Create log debug file
177 * @pdev: platform device pointer
178 * @info: Pointer to SCI entity information
179 *
180 * Return: 0 if all went fine, else corresponding error.
181 */
ti_sci_debugfs_create(struct platform_device * pdev,struct ti_sci_info * info)182 static int ti_sci_debugfs_create(struct platform_device *pdev,
183 struct ti_sci_info *info)
184 {
185 struct device *dev = &pdev->dev;
186 struct resource *res;
187 char debug_name[50];
188
189 /* Debug region is optional */
190 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
191 "debug_messages");
192 info->debug_region = devm_ioremap_resource(dev, res);
193 if (IS_ERR(info->debug_region))
194 return 0;
195 info->debug_region_size = resource_size(res);
196
197 info->debug_buffer = devm_kcalloc(dev, info->debug_region_size + 1,
198 sizeof(char), GFP_KERNEL);
199 if (!info->debug_buffer)
200 return -ENOMEM;
201 /* Setup NULL termination */
202 info->debug_buffer[info->debug_region_size] = 0;
203
204 snprintf(debug_name, sizeof(debug_name), "ti_sci_debug@%s",
205 dev_name(dev));
206 info->d = debugfs_create_file(debug_name, 0444, NULL, info,
207 &ti_sci_debug_fops);
208 if (IS_ERR(info->d))
209 return PTR_ERR(info->d);
210
211 dev_dbg(dev, "Debug region => %p, size = %zu bytes, resource: %pr\n",
212 info->debug_region, info->debug_region_size, res);
213 return 0;
214 }
215
216 #else /* CONFIG_DEBUG_FS */
ti_sci_debugfs_create(struct platform_device * dev,struct ti_sci_info * info)217 static inline int ti_sci_debugfs_create(struct platform_device *dev,
218 struct ti_sci_info *info)
219 {
220 return 0;
221 }
222
ti_sci_debugfs_destroy(struct platform_device * dev,struct ti_sci_info * info)223 static inline void ti_sci_debugfs_destroy(struct platform_device *dev,
224 struct ti_sci_info *info)
225 {
226 }
227 #endif /* CONFIG_DEBUG_FS */
228
229 /**
230 * ti_sci_dump_header_dbg() - Helper to dump a message header.
231 * @dev: Device pointer corresponding to the SCI entity
232 * @hdr: pointer to header.
233 */
ti_sci_dump_header_dbg(struct device * dev,struct ti_sci_msg_hdr * hdr)234 static inline void ti_sci_dump_header_dbg(struct device *dev,
235 struct ti_sci_msg_hdr *hdr)
236 {
237 dev_dbg(dev, "MSGHDR:type=0x%04x host=0x%02x seq=0x%02x flags=0x%08x\n",
238 hdr->type, hdr->host, hdr->seq, hdr->flags);
239 }
240
241 /**
242 * ti_sci_rx_callback() - mailbox client callback for receive messages
243 * @cl: client pointer
244 * @m: mailbox message
245 *
246 * Processes one received message to appropriate transfer information and
247 * signals completion of the transfer.
248 *
249 * NOTE: This function will be invoked in IRQ context, hence should be
250 * as optimal as possible.
251 */
ti_sci_rx_callback(struct mbox_client * cl,void * m)252 static void ti_sci_rx_callback(struct mbox_client *cl, void *m)
253 {
254 struct ti_sci_info *info = cl_to_ti_sci_info(cl);
255 struct device *dev = info->dev;
256 struct ti_sci_xfers_info *minfo = &info->minfo;
257 struct ti_msgmgr_message *mbox_msg = m;
258 struct ti_sci_msg_hdr *hdr = (struct ti_sci_msg_hdr *)mbox_msg->buf;
259 struct ti_sci_xfer *xfer;
260 u8 xfer_id;
261
262 xfer_id = hdr->seq;
263
264 /*
265 * Are we even expecting this?
266 * NOTE: barriers were implicit in locks used for modifying the bitmap
267 */
268 if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
269 dev_err(dev, "Message for %d is not expected!\n", xfer_id);
270 return;
271 }
272
273 xfer = &minfo->xfer_block[xfer_id];
274
275 /* Is the message of valid length? */
276 if (mbox_msg->len > info->desc->max_msg_size) {
277 dev_err(dev, "Unable to handle %zu xfer(max %d)\n",
278 mbox_msg->len, info->desc->max_msg_size);
279 ti_sci_dump_header_dbg(dev, hdr);
280 return;
281 }
282 if (mbox_msg->len < xfer->rx_len) {
283 dev_err(dev, "Recv xfer %zu < expected %d length\n",
284 mbox_msg->len, xfer->rx_len);
285 ti_sci_dump_header_dbg(dev, hdr);
286 return;
287 }
288
289 ti_sci_dump_header_dbg(dev, hdr);
290 /* Take a copy to the rx buffer.. */
291 memcpy(xfer->xfer_buf, mbox_msg->buf, xfer->rx_len);
292 complete(&xfer->done);
293 }
294
295 /**
296 * ti_sci_get_one_xfer() - Allocate one message
297 * @info: Pointer to SCI entity information
298 * @msg_type: Message type
299 * @msg_flags: Flag to set for the message
300 * @tx_message_size: transmit message size
301 * @rx_message_size: receive message size
302 *
303 * Helper function which is used by various command functions that are
304 * exposed to clients of this driver for allocating a message traffic event.
305 *
306 * This function can sleep depending on pending requests already in the system
307 * for the SCI entity. Further, this also holds a spinlock to maintain integrity
308 * of internal data structures.
309 *
310 * Return: 0 if all went fine, else corresponding error.
311 */
ti_sci_get_one_xfer(struct ti_sci_info * info,u16 msg_type,u32 msg_flags,size_t tx_message_size,size_t rx_message_size)312 static struct ti_sci_xfer *ti_sci_get_one_xfer(struct ti_sci_info *info,
313 u16 msg_type, u32 msg_flags,
314 size_t tx_message_size,
315 size_t rx_message_size)
316 {
317 struct ti_sci_xfers_info *minfo = &info->minfo;
318 struct ti_sci_xfer *xfer;
319 struct ti_sci_msg_hdr *hdr;
320 unsigned long flags;
321 unsigned long bit_pos;
322 u8 xfer_id;
323 int ret;
324 int timeout;
325
326 /* Ensure we have sane transfer sizes */
327 if (rx_message_size > info->desc->max_msg_size ||
328 tx_message_size > info->desc->max_msg_size ||
329 rx_message_size < sizeof(*hdr) || tx_message_size < sizeof(*hdr))
330 return ERR_PTR(-ERANGE);
331
332 /*
333 * Ensure we have only controlled number of pending messages.
334 * Ideally, we might just have to wait a single message, be
335 * conservative and wait 5 times that..
336 */
337 timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms) * 5;
338 ret = down_timeout(&minfo->sem_xfer_count, timeout);
339 if (ret < 0)
340 return ERR_PTR(ret);
341
342 /* Keep the locked section as small as possible */
343 spin_lock_irqsave(&minfo->xfer_lock, flags);
344 bit_pos = find_first_zero_bit(minfo->xfer_alloc_table,
345 info->desc->max_msgs);
346 set_bit(bit_pos, minfo->xfer_alloc_table);
347 spin_unlock_irqrestore(&minfo->xfer_lock, flags);
348
349 /*
350 * We already ensured in probe that we can have max messages that can
351 * fit in hdr.seq - NOTE: this improves access latencies
352 * to predictable O(1) access, BUT, it opens us to risk if
353 * remote misbehaves with corrupted message sequence responses.
354 * If that happens, we are going to be messed up anyways..
355 */
356 xfer_id = (u8)bit_pos;
357
358 xfer = &minfo->xfer_block[xfer_id];
359
360 hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
361 xfer->tx_message.len = tx_message_size;
362 xfer->tx_message.chan_rx = info->chan_rx;
363 xfer->tx_message.timeout_rx_ms = info->desc->max_rx_timeout_ms;
364 xfer->rx_len = (u8)rx_message_size;
365
366 reinit_completion(&xfer->done);
367
368 hdr->seq = xfer_id;
369 hdr->type = msg_type;
370 hdr->host = info->host_id;
371 hdr->flags = msg_flags;
372
373 return xfer;
374 }
375
376 /**
377 * ti_sci_put_one_xfer() - Release a message
378 * @minfo: transfer info pointer
379 * @xfer: message that was reserved by ti_sci_get_one_xfer
380 *
381 * This holds a spinlock to maintain integrity of internal data structures.
382 */
ti_sci_put_one_xfer(struct ti_sci_xfers_info * minfo,struct ti_sci_xfer * xfer)383 static void ti_sci_put_one_xfer(struct ti_sci_xfers_info *minfo,
384 struct ti_sci_xfer *xfer)
385 {
386 unsigned long flags;
387 struct ti_sci_msg_hdr *hdr;
388 u8 xfer_id;
389
390 hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
391 xfer_id = hdr->seq;
392
393 /*
394 * Keep the locked section as small as possible
395 * NOTE: we might escape with smp_mb and no lock here..
396 * but just be conservative and symmetric.
397 */
398 spin_lock_irqsave(&minfo->xfer_lock, flags);
399 clear_bit(xfer_id, minfo->xfer_alloc_table);
400 spin_unlock_irqrestore(&minfo->xfer_lock, flags);
401
402 /* Increment the count for the next user to get through */
403 up(&minfo->sem_xfer_count);
404 }
405
406 /**
407 * ti_sci_do_xfer() - Do one transfer
408 * @info: Pointer to SCI entity information
409 * @xfer: Transfer to initiate and wait for response
410 *
411 * Return: -ETIMEDOUT in case of no response, if transmit error,
412 * return corresponding error, else if all goes well,
413 * return 0.
414 */
ti_sci_do_xfer(struct ti_sci_info * info,struct ti_sci_xfer * xfer)415 static inline int ti_sci_do_xfer(struct ti_sci_info *info,
416 struct ti_sci_xfer *xfer)
417 {
418 struct ti_sci_msg_hdr *hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
419 bool response_expected = !!(hdr->flags & (TI_SCI_FLAG_REQ_ACK_ON_PROCESSED |
420 TI_SCI_FLAG_REQ_ACK_ON_RECEIVED));
421 int ret;
422 int timeout;
423 struct device *dev = info->dev;
424 bool done_state = true;
425
426 ret = mbox_send_message(info->chan_tx, &xfer->tx_message);
427 if (ret < 0)
428 return ret;
429
430 ret = 0;
431
432 if (response_expected && system_state <= SYSTEM_RUNNING) {
433 /* And we wait for the response. */
434 timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
435 if (!wait_for_completion_timeout(&xfer->done, timeout))
436 ret = -ETIMEDOUT;
437 } else if (response_expected) {
438 /*
439 * If we are !running, we cannot use wait_for_completion_timeout
440 * during noirq phase, so we must manually poll the completion.
441 */
442 ret = read_poll_timeout_atomic(try_wait_for_completion, done_state,
443 done_state, 1,
444 info->desc->max_rx_timeout_ms * 1000,
445 false, &xfer->done);
446 }
447
448 if (ret == -ETIMEDOUT)
449 dev_err(dev, "Mbox timedout in resp(caller: %pS)\n",
450 (void *)_RET_IP_);
451
452 /*
453 * NOTE: we might prefer not to need the mailbox ticker to manage the
454 * transfer queueing since the protocol layer queues things by itself.
455 * Unfortunately, we have to kick the mailbox framework after we have
456 * received our message.
457 */
458 mbox_client_txdone(info->chan_tx, ret);
459
460 return ret;
461 }
462
463 /**
464 * ti_sci_cmd_get_revision() - command to get the revision of the SCI entity
465 * @info: Pointer to SCI entity information
466 *
467 * Updates the SCI information in the internal data structure.
468 *
469 * Return: 0 if all went fine, else return appropriate error.
470 */
ti_sci_cmd_get_revision(struct ti_sci_info * info)471 static int ti_sci_cmd_get_revision(struct ti_sci_info *info)
472 {
473 struct device *dev = info->dev;
474 struct ti_sci_handle *handle = &info->handle;
475 struct ti_sci_version_info *ver = &handle->version;
476 struct ti_sci_msg_resp_version *rev_info;
477 struct ti_sci_xfer *xfer;
478 int ret;
479
480 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_VERSION,
481 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
482 sizeof(struct ti_sci_msg_hdr),
483 sizeof(*rev_info));
484 if (IS_ERR(xfer)) {
485 ret = PTR_ERR(xfer);
486 dev_err(dev, "Message alloc failed(%d)\n", ret);
487 return ret;
488 }
489
490 rev_info = (struct ti_sci_msg_resp_version *)xfer->xfer_buf;
491
492 ret = ti_sci_do_xfer(info, xfer);
493 if (ret) {
494 dev_err(dev, "Mbox send fail %d\n", ret);
495 goto fail;
496 }
497
498 ver->abi_major = rev_info->abi_major;
499 ver->abi_minor = rev_info->abi_minor;
500 ver->firmware_revision = rev_info->firmware_revision;
501 strscpy(ver->firmware_description, rev_info->firmware_description,
502 sizeof(ver->firmware_description));
503
504 fail:
505 ti_sci_put_one_xfer(&info->minfo, xfer);
506 return ret;
507 }
508
509 /**
510 * ti_sci_is_response_ack() - Generic ACK/NACK message checkup
511 * @r: pointer to response buffer
512 *
513 * Return: true if the response was an ACK, else returns false.
514 */
ti_sci_is_response_ack(void * r)515 static inline bool ti_sci_is_response_ack(void *r)
516 {
517 struct ti_sci_msg_hdr *hdr = r;
518
519 return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
520 }
521
522 /**
523 * ti_sci_set_device_state() - Set device state helper
524 * @handle: pointer to TI SCI handle
525 * @id: Device identifier
526 * @flags: flags to setup for the device
527 * @state: State to move the device to
528 *
529 * Return: 0 if all went well, else returns appropriate error value.
530 */
ti_sci_set_device_state(const struct ti_sci_handle * handle,u32 id,u32 flags,u8 state)531 static int ti_sci_set_device_state(const struct ti_sci_handle *handle,
532 u32 id, u32 flags, u8 state)
533 {
534 struct ti_sci_info *info;
535 struct ti_sci_msg_req_set_device_state *req;
536 struct ti_sci_msg_hdr *resp;
537 struct ti_sci_xfer *xfer;
538 struct device *dev;
539 int ret = 0;
540
541 if (IS_ERR(handle))
542 return PTR_ERR(handle);
543 if (!handle)
544 return -EINVAL;
545
546 info = handle_to_ti_sci_info(handle);
547 dev = info->dev;
548
549 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE,
550 flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
551 sizeof(*req), sizeof(*resp));
552 if (IS_ERR(xfer)) {
553 ret = PTR_ERR(xfer);
554 dev_err(dev, "Message alloc failed(%d)\n", ret);
555 return ret;
556 }
557 req = (struct ti_sci_msg_req_set_device_state *)xfer->xfer_buf;
558 req->id = id;
559 req->state = state;
560
561 ret = ti_sci_do_xfer(info, xfer);
562 if (ret) {
563 dev_err(dev, "Mbox send fail %d\n", ret);
564 goto fail;
565 }
566
567 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
568
569 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
570
571 fail:
572 ti_sci_put_one_xfer(&info->minfo, xfer);
573
574 return ret;
575 }
576
577 /**
578 * ti_sci_get_device_state() - Get device state helper
579 * @handle: Handle to the device
580 * @id: Device Identifier
581 * @clcnt: Pointer to Context Loss Count
582 * @resets: pointer to resets
583 * @p_state: pointer to p_state
584 * @c_state: pointer to c_state
585 *
586 * Return: 0 if all went fine, else return appropriate error.
587 */
ti_sci_get_device_state(const struct ti_sci_handle * handle,u32 id,u32 * clcnt,u32 * resets,u8 * p_state,u8 * c_state)588 static int ti_sci_get_device_state(const struct ti_sci_handle *handle,
589 u32 id, u32 *clcnt, u32 *resets,
590 u8 *p_state, u8 *c_state)
591 {
592 struct ti_sci_info *info;
593 struct ti_sci_msg_req_get_device_state *req;
594 struct ti_sci_msg_resp_get_device_state *resp;
595 struct ti_sci_xfer *xfer;
596 struct device *dev;
597 int ret = 0;
598
599 if (IS_ERR(handle))
600 return PTR_ERR(handle);
601 if (!handle)
602 return -EINVAL;
603
604 if (!clcnt && !resets && !p_state && !c_state)
605 return -EINVAL;
606
607 info = handle_to_ti_sci_info(handle);
608 dev = info->dev;
609
610 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE,
611 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
612 sizeof(*req), sizeof(*resp));
613 if (IS_ERR(xfer)) {
614 ret = PTR_ERR(xfer);
615 dev_err(dev, "Message alloc failed(%d)\n", ret);
616 return ret;
617 }
618 req = (struct ti_sci_msg_req_get_device_state *)xfer->xfer_buf;
619 req->id = id;
620
621 ret = ti_sci_do_xfer(info, xfer);
622 if (ret) {
623 dev_err(dev, "Mbox send fail %d\n", ret);
624 goto fail;
625 }
626
627 resp = (struct ti_sci_msg_resp_get_device_state *)xfer->xfer_buf;
628 if (!ti_sci_is_response_ack(resp)) {
629 ret = -ENODEV;
630 goto fail;
631 }
632
633 if (clcnt)
634 *clcnt = resp->context_loss_count;
635 if (resets)
636 *resets = resp->resets;
637 if (p_state)
638 *p_state = resp->programmed_state;
639 if (c_state)
640 *c_state = resp->current_state;
641 fail:
642 ti_sci_put_one_xfer(&info->minfo, xfer);
643
644 return ret;
645 }
646
647 /**
648 * ti_sci_cmd_get_device() - command to request for device managed by TISCI
649 * that can be shared with other hosts.
650 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
651 * @id: Device Identifier
652 *
653 * Request for the device - NOTE: the client MUST maintain integrity of
654 * usage count by balancing get_device with put_device. No refcounting is
655 * managed by driver for that purpose.
656 *
657 * Return: 0 if all went fine, else return appropriate error.
658 */
ti_sci_cmd_get_device(const struct ti_sci_handle * handle,u32 id)659 static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id)
660 {
661 return ti_sci_set_device_state(handle, id, 0,
662 MSG_DEVICE_SW_STATE_ON);
663 }
664
665 /**
666 * ti_sci_cmd_get_device_exclusive() - command to request for device managed by
667 * TISCI that is exclusively owned by the
668 * requesting host.
669 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
670 * @id: Device Identifier
671 *
672 * Request for the device - NOTE: the client MUST maintain integrity of
673 * usage count by balancing get_device with put_device. No refcounting is
674 * managed by driver for that purpose.
675 *
676 * Return: 0 if all went fine, else return appropriate error.
677 */
ti_sci_cmd_get_device_exclusive(const struct ti_sci_handle * handle,u32 id)678 static int ti_sci_cmd_get_device_exclusive(const struct ti_sci_handle *handle,
679 u32 id)
680 {
681 return ti_sci_set_device_state(handle, id,
682 MSG_FLAG_DEVICE_EXCLUSIVE,
683 MSG_DEVICE_SW_STATE_ON);
684 }
685
686 /**
687 * ti_sci_cmd_idle_device() - Command to idle a device managed by TISCI
688 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
689 * @id: Device Identifier
690 *
691 * Request for the device - NOTE: the client MUST maintain integrity of
692 * usage count by balancing get_device with put_device. No refcounting is
693 * managed by driver for that purpose.
694 *
695 * Return: 0 if all went fine, else return appropriate error.
696 */
ti_sci_cmd_idle_device(const struct ti_sci_handle * handle,u32 id)697 static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id)
698 {
699 return ti_sci_set_device_state(handle, id, 0,
700 MSG_DEVICE_SW_STATE_RETENTION);
701 }
702
703 /**
704 * ti_sci_cmd_idle_device_exclusive() - Command to idle a device managed by
705 * TISCI that is exclusively owned by
706 * requesting host.
707 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
708 * @id: Device Identifier
709 *
710 * Request for the device - NOTE: the client MUST maintain integrity of
711 * usage count by balancing get_device with put_device. No refcounting is
712 * managed by driver for that purpose.
713 *
714 * Return: 0 if all went fine, else return appropriate error.
715 */
ti_sci_cmd_idle_device_exclusive(const struct ti_sci_handle * handle,u32 id)716 static int ti_sci_cmd_idle_device_exclusive(const struct ti_sci_handle *handle,
717 u32 id)
718 {
719 return ti_sci_set_device_state(handle, id,
720 MSG_FLAG_DEVICE_EXCLUSIVE,
721 MSG_DEVICE_SW_STATE_RETENTION);
722 }
723
724 /**
725 * ti_sci_cmd_put_device() - command to release a device managed by TISCI
726 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
727 * @id: Device Identifier
728 *
729 * Request for the device - NOTE: the client MUST maintain integrity of
730 * usage count by balancing get_device with put_device. No refcounting is
731 * managed by driver for that purpose.
732 *
733 * Return: 0 if all went fine, else return appropriate error.
734 */
ti_sci_cmd_put_device(const struct ti_sci_handle * handle,u32 id)735 static int ti_sci_cmd_put_device(const struct ti_sci_handle *handle, u32 id)
736 {
737 return ti_sci_set_device_state(handle, id,
738 0, MSG_DEVICE_SW_STATE_AUTO_OFF);
739 }
740
741 /**
742 * ti_sci_cmd_dev_is_valid() - Is the device valid
743 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
744 * @id: Device Identifier
745 *
746 * Return: 0 if all went fine and the device ID is valid, else return
747 * appropriate error.
748 */
ti_sci_cmd_dev_is_valid(const struct ti_sci_handle * handle,u32 id)749 static int ti_sci_cmd_dev_is_valid(const struct ti_sci_handle *handle, u32 id)
750 {
751 u8 unused;
752
753 /* check the device state which will also tell us if the ID is valid */
754 return ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &unused);
755 }
756
757 /**
758 * ti_sci_cmd_dev_get_clcnt() - Get context loss counter
759 * @handle: Pointer to TISCI handle
760 * @id: Device Identifier
761 * @count: Pointer to Context Loss counter to populate
762 *
763 * Return: 0 if all went fine, else return appropriate error.
764 */
ti_sci_cmd_dev_get_clcnt(const struct ti_sci_handle * handle,u32 id,u32 * count)765 static int ti_sci_cmd_dev_get_clcnt(const struct ti_sci_handle *handle, u32 id,
766 u32 *count)
767 {
768 return ti_sci_get_device_state(handle, id, count, NULL, NULL, NULL);
769 }
770
771 /**
772 * ti_sci_cmd_dev_is_idle() - Check if the device is requested to be idle
773 * @handle: Pointer to TISCI handle
774 * @id: Device Identifier
775 * @r_state: true if requested to be idle
776 *
777 * Return: 0 if all went fine, else return appropriate error.
778 */
ti_sci_cmd_dev_is_idle(const struct ti_sci_handle * handle,u32 id,bool * r_state)779 static int ti_sci_cmd_dev_is_idle(const struct ti_sci_handle *handle, u32 id,
780 bool *r_state)
781 {
782 int ret;
783 u8 state;
784
785 if (!r_state)
786 return -EINVAL;
787
788 ret = ti_sci_get_device_state(handle, id, NULL, NULL, &state, NULL);
789 if (ret)
790 return ret;
791
792 *r_state = (state == MSG_DEVICE_SW_STATE_RETENTION);
793
794 return 0;
795 }
796
797 /**
798 * ti_sci_cmd_dev_is_stop() - Check if the device is requested to be stopped
799 * @handle: Pointer to TISCI handle
800 * @id: Device Identifier
801 * @r_state: true if requested to be stopped
802 * @curr_state: true if currently stopped.
803 *
804 * Return: 0 if all went fine, else return appropriate error.
805 */
ti_sci_cmd_dev_is_stop(const struct ti_sci_handle * handle,u32 id,bool * r_state,bool * curr_state)806 static int ti_sci_cmd_dev_is_stop(const struct ti_sci_handle *handle, u32 id,
807 bool *r_state, bool *curr_state)
808 {
809 int ret;
810 u8 p_state, c_state;
811
812 if (!r_state && !curr_state)
813 return -EINVAL;
814
815 ret =
816 ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
817 if (ret)
818 return ret;
819
820 if (r_state)
821 *r_state = (p_state == MSG_DEVICE_SW_STATE_AUTO_OFF);
822 if (curr_state)
823 *curr_state = (c_state == MSG_DEVICE_HW_STATE_OFF);
824
825 return 0;
826 }
827
828 /**
829 * ti_sci_cmd_dev_is_on() - Check if the device is requested to be ON
830 * @handle: Pointer to TISCI handle
831 * @id: Device Identifier
832 * @r_state: true if requested to be ON
833 * @curr_state: true if currently ON and active
834 *
835 * Return: 0 if all went fine, else return appropriate error.
836 */
ti_sci_cmd_dev_is_on(const struct ti_sci_handle * handle,u32 id,bool * r_state,bool * curr_state)837 static int ti_sci_cmd_dev_is_on(const struct ti_sci_handle *handle, u32 id,
838 bool *r_state, bool *curr_state)
839 {
840 int ret;
841 u8 p_state, c_state;
842
843 if (!r_state && !curr_state)
844 return -EINVAL;
845
846 ret =
847 ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
848 if (ret)
849 return ret;
850
851 if (r_state)
852 *r_state = (p_state == MSG_DEVICE_SW_STATE_ON);
853 if (curr_state)
854 *curr_state = (c_state == MSG_DEVICE_HW_STATE_ON);
855
856 return 0;
857 }
858
859 /**
860 * ti_sci_cmd_dev_is_trans() - Check if the device is currently transitioning
861 * @handle: Pointer to TISCI handle
862 * @id: Device Identifier
863 * @curr_state: true if currently transitioning.
864 *
865 * Return: 0 if all went fine, else return appropriate error.
866 */
ti_sci_cmd_dev_is_trans(const struct ti_sci_handle * handle,u32 id,bool * curr_state)867 static int ti_sci_cmd_dev_is_trans(const struct ti_sci_handle *handle, u32 id,
868 bool *curr_state)
869 {
870 int ret;
871 u8 state;
872
873 if (!curr_state)
874 return -EINVAL;
875
876 ret = ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &state);
877 if (ret)
878 return ret;
879
880 *curr_state = (state == MSG_DEVICE_HW_STATE_TRANS);
881
882 return 0;
883 }
884
885 /**
886 * ti_sci_cmd_set_device_resets() - command to set resets for device managed
887 * by TISCI
888 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle
889 * @id: Device Identifier
890 * @reset_state: Device specific reset bit field
891 *
892 * Return: 0 if all went fine, else return appropriate error.
893 */
ti_sci_cmd_set_device_resets(const struct ti_sci_handle * handle,u32 id,u32 reset_state)894 static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle,
895 u32 id, u32 reset_state)
896 {
897 struct ti_sci_info *info;
898 struct ti_sci_msg_req_set_device_resets *req;
899 struct ti_sci_msg_hdr *resp;
900 struct ti_sci_xfer *xfer;
901 struct device *dev;
902 int ret = 0;
903
904 if (IS_ERR(handle))
905 return PTR_ERR(handle);
906 if (!handle)
907 return -EINVAL;
908
909 info = handle_to_ti_sci_info(handle);
910 dev = info->dev;
911
912 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_RESETS,
913 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
914 sizeof(*req), sizeof(*resp));
915 if (IS_ERR(xfer)) {
916 ret = PTR_ERR(xfer);
917 dev_err(dev, "Message alloc failed(%d)\n", ret);
918 return ret;
919 }
920 req = (struct ti_sci_msg_req_set_device_resets *)xfer->xfer_buf;
921 req->id = id;
922 req->resets = reset_state;
923
924 ret = ti_sci_do_xfer(info, xfer);
925 if (ret) {
926 dev_err(dev, "Mbox send fail %d\n", ret);
927 goto fail;
928 }
929
930 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
931
932 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
933
934 fail:
935 ti_sci_put_one_xfer(&info->minfo, xfer);
936
937 return ret;
938 }
939
940 /**
941 * ti_sci_cmd_get_device_resets() - Get reset state for device managed
942 * by TISCI
943 * @handle: Pointer to TISCI handle
944 * @id: Device Identifier
945 * @reset_state: Pointer to reset state to populate
946 *
947 * Return: 0 if all went fine, else return appropriate error.
948 */
ti_sci_cmd_get_device_resets(const struct ti_sci_handle * handle,u32 id,u32 * reset_state)949 static int ti_sci_cmd_get_device_resets(const struct ti_sci_handle *handle,
950 u32 id, u32 *reset_state)
951 {
952 return ti_sci_get_device_state(handle, id, NULL, reset_state, NULL,
953 NULL);
954 }
955
956 /**
957 * ti_sci_set_clock_state() - Set clock state helper
958 * @handle: pointer to TI SCI handle
959 * @dev_id: Device identifier this request is for
960 * @clk_id: Clock identifier for the device for this request.
961 * Each device has it's own set of clock inputs. This indexes
962 * which clock input to modify.
963 * @flags: Header flags as needed
964 * @state: State to request for the clock.
965 *
966 * Return: 0 if all went well, else returns appropriate error value.
967 */
ti_sci_set_clock_state(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id,u32 flags,u8 state)968 static int ti_sci_set_clock_state(const struct ti_sci_handle *handle,
969 u32 dev_id, u32 clk_id,
970 u32 flags, u8 state)
971 {
972 struct ti_sci_info *info;
973 struct ti_sci_msg_req_set_clock_state *req;
974 struct ti_sci_msg_hdr *resp;
975 struct ti_sci_xfer *xfer;
976 struct device *dev;
977 int ret = 0;
978
979 if (IS_ERR(handle))
980 return PTR_ERR(handle);
981 if (!handle)
982 return -EINVAL;
983
984 info = handle_to_ti_sci_info(handle);
985 dev = info->dev;
986
987 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_STATE,
988 flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
989 sizeof(*req), sizeof(*resp));
990 if (IS_ERR(xfer)) {
991 ret = PTR_ERR(xfer);
992 dev_err(dev, "Message alloc failed(%d)\n", ret);
993 return ret;
994 }
995 req = (struct ti_sci_msg_req_set_clock_state *)xfer->xfer_buf;
996 req->dev_id = dev_id;
997 if (clk_id < 255) {
998 req->clk_id = clk_id;
999 } else {
1000 req->clk_id = 255;
1001 req->clk_id_32 = clk_id;
1002 }
1003 req->request_state = state;
1004
1005 ret = ti_sci_do_xfer(info, xfer);
1006 if (ret) {
1007 dev_err(dev, "Mbox send fail %d\n", ret);
1008 goto fail;
1009 }
1010
1011 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
1012
1013 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
1014
1015 fail:
1016 ti_sci_put_one_xfer(&info->minfo, xfer);
1017
1018 return ret;
1019 }
1020
1021 /**
1022 * ti_sci_cmd_get_clock_state() - Get clock state helper
1023 * @handle: pointer to TI SCI handle
1024 * @dev_id: Device identifier this request is for
1025 * @clk_id: Clock identifier for the device for this request.
1026 * Each device has it's own set of clock inputs. This indexes
1027 * which clock input to modify.
1028 * @programmed_state: State requested for clock to move to
1029 * @current_state: State that the clock is currently in
1030 *
1031 * Return: 0 if all went well, else returns appropriate error value.
1032 */
ti_sci_cmd_get_clock_state(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id,u8 * programmed_state,u8 * current_state)1033 static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle,
1034 u32 dev_id, u32 clk_id,
1035 u8 *programmed_state, u8 *current_state)
1036 {
1037 struct ti_sci_info *info;
1038 struct ti_sci_msg_req_get_clock_state *req;
1039 struct ti_sci_msg_resp_get_clock_state *resp;
1040 struct ti_sci_xfer *xfer;
1041 struct device *dev;
1042 int ret = 0;
1043
1044 if (IS_ERR(handle))
1045 return PTR_ERR(handle);
1046 if (!handle)
1047 return -EINVAL;
1048
1049 if (!programmed_state && !current_state)
1050 return -EINVAL;
1051
1052 info = handle_to_ti_sci_info(handle);
1053 dev = info->dev;
1054
1055 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_STATE,
1056 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1057 sizeof(*req), sizeof(*resp));
1058 if (IS_ERR(xfer)) {
1059 ret = PTR_ERR(xfer);
1060 dev_err(dev, "Message alloc failed(%d)\n", ret);
1061 return ret;
1062 }
1063 req = (struct ti_sci_msg_req_get_clock_state *)xfer->xfer_buf;
1064 req->dev_id = dev_id;
1065 if (clk_id < 255) {
1066 req->clk_id = clk_id;
1067 } else {
1068 req->clk_id = 255;
1069 req->clk_id_32 = clk_id;
1070 }
1071
1072 ret = ti_sci_do_xfer(info, xfer);
1073 if (ret) {
1074 dev_err(dev, "Mbox send fail %d\n", ret);
1075 goto fail;
1076 }
1077
1078 resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->xfer_buf;
1079
1080 if (!ti_sci_is_response_ack(resp)) {
1081 ret = -ENODEV;
1082 goto fail;
1083 }
1084
1085 if (programmed_state)
1086 *programmed_state = resp->programmed_state;
1087 if (current_state)
1088 *current_state = resp->current_state;
1089
1090 fail:
1091 ti_sci_put_one_xfer(&info->minfo, xfer);
1092
1093 return ret;
1094 }
1095
1096 /**
1097 * ti_sci_cmd_get_clock() - Get control of a clock from TI SCI
1098 * @handle: pointer to TI SCI handle
1099 * @dev_id: Device identifier this request is for
1100 * @clk_id: Clock identifier for the device for this request.
1101 * Each device has it's own set of clock inputs. This indexes
1102 * which clock input to modify.
1103 * @needs_ssc: 'true' if Spread Spectrum clock is desired, else 'false'
1104 * @can_change_freq: 'true' if frequency change is desired, else 'false'
1105 * @enable_input_term: 'true' if input termination is desired, else 'false'
1106 *
1107 * Return: 0 if all went well, else returns appropriate error value.
1108 */
ti_sci_cmd_get_clock(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id,bool needs_ssc,bool can_change_freq,bool enable_input_term)1109 static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id,
1110 u32 clk_id, bool needs_ssc,
1111 bool can_change_freq, bool enable_input_term)
1112 {
1113 u32 flags = 0;
1114
1115 flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0;
1116 flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0;
1117 flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0;
1118
1119 return ti_sci_set_clock_state(handle, dev_id, clk_id, flags,
1120 MSG_CLOCK_SW_STATE_REQ);
1121 }
1122
1123 /**
1124 * ti_sci_cmd_idle_clock() - Idle a clock which is in our control
1125 * @handle: pointer to TI SCI handle
1126 * @dev_id: Device identifier this request is for
1127 * @clk_id: Clock identifier for the device for this request.
1128 * Each device has it's own set of clock inputs. This indexes
1129 * which clock input to modify.
1130 *
1131 * NOTE: This clock must have been requested by get_clock previously.
1132 *
1133 * Return: 0 if all went well, else returns appropriate error value.
1134 */
ti_sci_cmd_idle_clock(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id)1135 static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle,
1136 u32 dev_id, u32 clk_id)
1137 {
1138 return ti_sci_set_clock_state(handle, dev_id, clk_id,
1139 MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,
1140 MSG_CLOCK_SW_STATE_UNREQ);
1141 }
1142
1143 /**
1144 * ti_sci_cmd_put_clock() - Release a clock from our control back to TISCI
1145 * @handle: pointer to TI SCI handle
1146 * @dev_id: Device identifier this request is for
1147 * @clk_id: Clock identifier for the device for this request.
1148 * Each device has it's own set of clock inputs. This indexes
1149 * which clock input to modify.
1150 *
1151 * NOTE: This clock must have been requested by get_clock previously.
1152 *
1153 * Return: 0 if all went well, else returns appropriate error value.
1154 */
ti_sci_cmd_put_clock(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id)1155 static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle,
1156 u32 dev_id, u32 clk_id)
1157 {
1158 return ti_sci_set_clock_state(handle, dev_id, clk_id,
1159 MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,
1160 MSG_CLOCK_SW_STATE_AUTO);
1161 }
1162
1163 /**
1164 * ti_sci_cmd_clk_is_auto() - Is the clock being auto managed
1165 * @handle: pointer to TI SCI handle
1166 * @dev_id: Device identifier this request is for
1167 * @clk_id: Clock identifier for the device for this request.
1168 * Each device has it's own set of clock inputs. This indexes
1169 * which clock input to modify.
1170 * @req_state: state indicating if the clock is auto managed
1171 *
1172 * Return: 0 if all went well, else returns appropriate error value.
1173 */
ti_sci_cmd_clk_is_auto(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id,bool * req_state)1174 static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle,
1175 u32 dev_id, u32 clk_id, bool *req_state)
1176 {
1177 u8 state = 0;
1178 int ret;
1179
1180 if (!req_state)
1181 return -EINVAL;
1182
1183 ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, &state, NULL);
1184 if (ret)
1185 return ret;
1186
1187 *req_state = (state == MSG_CLOCK_SW_STATE_AUTO);
1188 return 0;
1189 }
1190
1191 /**
1192 * ti_sci_cmd_clk_is_on() - Is the clock ON
1193 * @handle: pointer to TI SCI handle
1194 * @dev_id: Device identifier this request is for
1195 * @clk_id: Clock identifier for the device for this request.
1196 * Each device has it's own set of clock inputs. This indexes
1197 * which clock input to modify.
1198 * @req_state: state indicating if the clock is managed by us and enabled
1199 * @curr_state: state indicating if the clock is ready for operation
1200 *
1201 * Return: 0 if all went well, else returns appropriate error value.
1202 */
ti_sci_cmd_clk_is_on(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id,bool * req_state,bool * curr_state)1203 static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id,
1204 u32 clk_id, bool *req_state, bool *curr_state)
1205 {
1206 u8 c_state = 0, r_state = 0;
1207 int ret;
1208
1209 if (!req_state && !curr_state)
1210 return -EINVAL;
1211
1212 ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
1213 &r_state, &c_state);
1214 if (ret)
1215 return ret;
1216
1217 if (req_state)
1218 *req_state = (r_state == MSG_CLOCK_SW_STATE_REQ);
1219 if (curr_state)
1220 *curr_state = (c_state == MSG_CLOCK_HW_STATE_READY);
1221 return 0;
1222 }
1223
1224 /**
1225 * ti_sci_cmd_clk_is_off() - Is the clock OFF
1226 * @handle: pointer to TI SCI handle
1227 * @dev_id: Device identifier this request is for
1228 * @clk_id: Clock identifier for the device for this request.
1229 * Each device has it's own set of clock inputs. This indexes
1230 * which clock input to modify.
1231 * @req_state: state indicating if the clock is managed by us and disabled
1232 * @curr_state: state indicating if the clock is NOT ready for operation
1233 *
1234 * Return: 0 if all went well, else returns appropriate error value.
1235 */
ti_sci_cmd_clk_is_off(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id,bool * req_state,bool * curr_state)1236 static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id,
1237 u32 clk_id, bool *req_state, bool *curr_state)
1238 {
1239 u8 c_state = 0, r_state = 0;
1240 int ret;
1241
1242 if (!req_state && !curr_state)
1243 return -EINVAL;
1244
1245 ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
1246 &r_state, &c_state);
1247 if (ret)
1248 return ret;
1249
1250 if (req_state)
1251 *req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ);
1252 if (curr_state)
1253 *curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY);
1254 return 0;
1255 }
1256
1257 /**
1258 * ti_sci_cmd_clk_set_parent() - Set the clock source of a specific device clock
1259 * @handle: pointer to TI SCI handle
1260 * @dev_id: Device identifier this request is for
1261 * @clk_id: Clock identifier for the device for this request.
1262 * Each device has it's own set of clock inputs. This indexes
1263 * which clock input to modify.
1264 * @parent_id: Parent clock identifier to set
1265 *
1266 * Return: 0 if all went well, else returns appropriate error value.
1267 */
ti_sci_cmd_clk_set_parent(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id,u32 parent_id)1268 static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle,
1269 u32 dev_id, u32 clk_id, u32 parent_id)
1270 {
1271 struct ti_sci_info *info;
1272 struct ti_sci_msg_req_set_clock_parent *req;
1273 struct ti_sci_msg_hdr *resp;
1274 struct ti_sci_xfer *xfer;
1275 struct device *dev;
1276 int ret = 0;
1277
1278 if (IS_ERR(handle))
1279 return PTR_ERR(handle);
1280 if (!handle)
1281 return -EINVAL;
1282
1283 info = handle_to_ti_sci_info(handle);
1284 dev = info->dev;
1285
1286 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_PARENT,
1287 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1288 sizeof(*req), sizeof(*resp));
1289 if (IS_ERR(xfer)) {
1290 ret = PTR_ERR(xfer);
1291 dev_err(dev, "Message alloc failed(%d)\n", ret);
1292 return ret;
1293 }
1294 req = (struct ti_sci_msg_req_set_clock_parent *)xfer->xfer_buf;
1295 req->dev_id = dev_id;
1296 if (clk_id < 255) {
1297 req->clk_id = clk_id;
1298 } else {
1299 req->clk_id = 255;
1300 req->clk_id_32 = clk_id;
1301 }
1302 if (parent_id < 255) {
1303 req->parent_id = parent_id;
1304 } else {
1305 req->parent_id = 255;
1306 req->parent_id_32 = parent_id;
1307 }
1308
1309 ret = ti_sci_do_xfer(info, xfer);
1310 if (ret) {
1311 dev_err(dev, "Mbox send fail %d\n", ret);
1312 goto fail;
1313 }
1314
1315 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
1316
1317 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
1318
1319 fail:
1320 ti_sci_put_one_xfer(&info->minfo, xfer);
1321
1322 return ret;
1323 }
1324
1325 /**
1326 * ti_sci_cmd_clk_get_parent() - Get current parent clock source
1327 * @handle: pointer to TI SCI handle
1328 * @dev_id: Device identifier this request is for
1329 * @clk_id: Clock identifier for the device for this request.
1330 * Each device has it's own set of clock inputs. This indexes
1331 * which clock input to modify.
1332 * @parent_id: Current clock parent
1333 *
1334 * Return: 0 if all went well, else returns appropriate error value.
1335 */
ti_sci_cmd_clk_get_parent(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id,u32 * parent_id)1336 static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle,
1337 u32 dev_id, u32 clk_id, u32 *parent_id)
1338 {
1339 struct ti_sci_info *info;
1340 struct ti_sci_msg_req_get_clock_parent *req;
1341 struct ti_sci_msg_resp_get_clock_parent *resp;
1342 struct ti_sci_xfer *xfer;
1343 struct device *dev;
1344 int ret = 0;
1345
1346 if (IS_ERR(handle))
1347 return PTR_ERR(handle);
1348 if (!handle || !parent_id)
1349 return -EINVAL;
1350
1351 info = handle_to_ti_sci_info(handle);
1352 dev = info->dev;
1353
1354 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_PARENT,
1355 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1356 sizeof(*req), sizeof(*resp));
1357 if (IS_ERR(xfer)) {
1358 ret = PTR_ERR(xfer);
1359 dev_err(dev, "Message alloc failed(%d)\n", ret);
1360 return ret;
1361 }
1362 req = (struct ti_sci_msg_req_get_clock_parent *)xfer->xfer_buf;
1363 req->dev_id = dev_id;
1364 if (clk_id < 255) {
1365 req->clk_id = clk_id;
1366 } else {
1367 req->clk_id = 255;
1368 req->clk_id_32 = clk_id;
1369 }
1370
1371 ret = ti_sci_do_xfer(info, xfer);
1372 if (ret) {
1373 dev_err(dev, "Mbox send fail %d\n", ret);
1374 goto fail;
1375 }
1376
1377 resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->xfer_buf;
1378
1379 if (!ti_sci_is_response_ack(resp)) {
1380 ret = -ENODEV;
1381 } else {
1382 if (resp->parent_id < 255)
1383 *parent_id = resp->parent_id;
1384 else
1385 *parent_id = resp->parent_id_32;
1386 }
1387
1388 fail:
1389 ti_sci_put_one_xfer(&info->minfo, xfer);
1390
1391 return ret;
1392 }
1393
1394 /**
1395 * ti_sci_cmd_clk_get_num_parents() - Get num parents of the current clk source
1396 * @handle: pointer to TI SCI handle
1397 * @dev_id: Device identifier this request is for
1398 * @clk_id: Clock identifier for the device for this request.
1399 * Each device has it's own set of clock inputs. This indexes
1400 * which clock input to modify.
1401 * @num_parents: Returns he number of parents to the current clock.
1402 *
1403 * Return: 0 if all went well, else returns appropriate error value.
1404 */
ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id,u32 * num_parents)1405 static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle,
1406 u32 dev_id, u32 clk_id,
1407 u32 *num_parents)
1408 {
1409 struct ti_sci_info *info;
1410 struct ti_sci_msg_req_get_clock_num_parents *req;
1411 struct ti_sci_msg_resp_get_clock_num_parents *resp;
1412 struct ti_sci_xfer *xfer;
1413 struct device *dev;
1414 int ret = 0;
1415
1416 if (IS_ERR(handle))
1417 return PTR_ERR(handle);
1418 if (!handle || !num_parents)
1419 return -EINVAL;
1420
1421 info = handle_to_ti_sci_info(handle);
1422 dev = info->dev;
1423
1424 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_NUM_CLOCK_PARENTS,
1425 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1426 sizeof(*req), sizeof(*resp));
1427 if (IS_ERR(xfer)) {
1428 ret = PTR_ERR(xfer);
1429 dev_err(dev, "Message alloc failed(%d)\n", ret);
1430 return ret;
1431 }
1432 req = (struct ti_sci_msg_req_get_clock_num_parents *)xfer->xfer_buf;
1433 req->dev_id = dev_id;
1434 if (clk_id < 255) {
1435 req->clk_id = clk_id;
1436 } else {
1437 req->clk_id = 255;
1438 req->clk_id_32 = clk_id;
1439 }
1440
1441 ret = ti_sci_do_xfer(info, xfer);
1442 if (ret) {
1443 dev_err(dev, "Mbox send fail %d\n", ret);
1444 goto fail;
1445 }
1446
1447 resp = (struct ti_sci_msg_resp_get_clock_num_parents *)xfer->xfer_buf;
1448
1449 if (!ti_sci_is_response_ack(resp)) {
1450 ret = -ENODEV;
1451 } else {
1452 if (resp->num_parents < 255)
1453 *num_parents = resp->num_parents;
1454 else
1455 *num_parents = resp->num_parents_32;
1456 }
1457
1458 fail:
1459 ti_sci_put_one_xfer(&info->minfo, xfer);
1460
1461 return ret;
1462 }
1463
1464 /**
1465 * ti_sci_cmd_clk_get_match_freq() - Find a good match for frequency
1466 * @handle: pointer to TI SCI handle
1467 * @dev_id: Device identifier this request is for
1468 * @clk_id: Clock identifier for the device for this request.
1469 * Each device has it's own set of clock inputs. This indexes
1470 * which clock input to modify.
1471 * @min_freq: The minimum allowable frequency in Hz. This is the minimum
1472 * allowable programmed frequency and does not account for clock
1473 * tolerances and jitter.
1474 * @target_freq: The target clock frequency in Hz. A frequency will be
1475 * processed as close to this target frequency as possible.
1476 * @max_freq: The maximum allowable frequency in Hz. This is the maximum
1477 * allowable programmed frequency and does not account for clock
1478 * tolerances and jitter.
1479 * @match_freq: Frequency match in Hz response.
1480 *
1481 * Return: 0 if all went well, else returns appropriate error value.
1482 */
ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id,u64 min_freq,u64 target_freq,u64 max_freq,u64 * match_freq)1483 static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle,
1484 u32 dev_id, u32 clk_id, u64 min_freq,
1485 u64 target_freq, u64 max_freq,
1486 u64 *match_freq)
1487 {
1488 struct ti_sci_info *info;
1489 struct ti_sci_msg_req_query_clock_freq *req;
1490 struct ti_sci_msg_resp_query_clock_freq *resp;
1491 struct ti_sci_xfer *xfer;
1492 struct device *dev;
1493 int ret = 0;
1494
1495 if (IS_ERR(handle))
1496 return PTR_ERR(handle);
1497 if (!handle || !match_freq)
1498 return -EINVAL;
1499
1500 info = handle_to_ti_sci_info(handle);
1501 dev = info->dev;
1502
1503 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_QUERY_CLOCK_FREQ,
1504 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1505 sizeof(*req), sizeof(*resp));
1506 if (IS_ERR(xfer)) {
1507 ret = PTR_ERR(xfer);
1508 dev_err(dev, "Message alloc failed(%d)\n", ret);
1509 return ret;
1510 }
1511 req = (struct ti_sci_msg_req_query_clock_freq *)xfer->xfer_buf;
1512 req->dev_id = dev_id;
1513 if (clk_id < 255) {
1514 req->clk_id = clk_id;
1515 } else {
1516 req->clk_id = 255;
1517 req->clk_id_32 = clk_id;
1518 }
1519 req->min_freq_hz = min_freq;
1520 req->target_freq_hz = target_freq;
1521 req->max_freq_hz = max_freq;
1522
1523 ret = ti_sci_do_xfer(info, xfer);
1524 if (ret) {
1525 dev_err(dev, "Mbox send fail %d\n", ret);
1526 goto fail;
1527 }
1528
1529 resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->xfer_buf;
1530
1531 if (!ti_sci_is_response_ack(resp))
1532 ret = -ENODEV;
1533 else
1534 *match_freq = resp->freq_hz;
1535
1536 fail:
1537 ti_sci_put_one_xfer(&info->minfo, xfer);
1538
1539 return ret;
1540 }
1541
1542 /**
1543 * ti_sci_cmd_clk_set_freq() - Set a frequency for clock
1544 * @handle: pointer to TI SCI handle
1545 * @dev_id: Device identifier this request is for
1546 * @clk_id: Clock identifier for the device for this request.
1547 * Each device has it's own set of clock inputs. This indexes
1548 * which clock input to modify.
1549 * @min_freq: The minimum allowable frequency in Hz. This is the minimum
1550 * allowable programmed frequency and does not account for clock
1551 * tolerances and jitter.
1552 * @target_freq: The target clock frequency in Hz. A frequency will be
1553 * processed as close to this target frequency as possible.
1554 * @max_freq: The maximum allowable frequency in Hz. This is the maximum
1555 * allowable programmed frequency and does not account for clock
1556 * tolerances and jitter.
1557 *
1558 * Return: 0 if all went well, else returns appropriate error value.
1559 */
ti_sci_cmd_clk_set_freq(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id,u64 min_freq,u64 target_freq,u64 max_freq)1560 static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle,
1561 u32 dev_id, u32 clk_id, u64 min_freq,
1562 u64 target_freq, u64 max_freq)
1563 {
1564 struct ti_sci_info *info;
1565 struct ti_sci_msg_req_set_clock_freq *req;
1566 struct ti_sci_msg_hdr *resp;
1567 struct ti_sci_xfer *xfer;
1568 struct device *dev;
1569 int ret = 0;
1570
1571 if (IS_ERR(handle))
1572 return PTR_ERR(handle);
1573 if (!handle)
1574 return -EINVAL;
1575
1576 info = handle_to_ti_sci_info(handle);
1577 dev = info->dev;
1578
1579 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_FREQ,
1580 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1581 sizeof(*req), sizeof(*resp));
1582 if (IS_ERR(xfer)) {
1583 ret = PTR_ERR(xfer);
1584 dev_err(dev, "Message alloc failed(%d)\n", ret);
1585 return ret;
1586 }
1587 req = (struct ti_sci_msg_req_set_clock_freq *)xfer->xfer_buf;
1588 req->dev_id = dev_id;
1589 if (clk_id < 255) {
1590 req->clk_id = clk_id;
1591 } else {
1592 req->clk_id = 255;
1593 req->clk_id_32 = clk_id;
1594 }
1595 req->min_freq_hz = min_freq;
1596 req->target_freq_hz = target_freq;
1597 req->max_freq_hz = max_freq;
1598
1599 ret = ti_sci_do_xfer(info, xfer);
1600 if (ret) {
1601 dev_err(dev, "Mbox send fail %d\n", ret);
1602 goto fail;
1603 }
1604
1605 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
1606
1607 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
1608
1609 fail:
1610 ti_sci_put_one_xfer(&info->minfo, xfer);
1611
1612 return ret;
1613 }
1614
1615 /**
1616 * ti_sci_cmd_clk_get_freq() - Get current frequency
1617 * @handle: pointer to TI SCI handle
1618 * @dev_id: Device identifier this request is for
1619 * @clk_id: Clock identifier for the device for this request.
1620 * Each device has it's own set of clock inputs. This indexes
1621 * which clock input to modify.
1622 * @freq: Currently frequency in Hz
1623 *
1624 * Return: 0 if all went well, else returns appropriate error value.
1625 */
ti_sci_cmd_clk_get_freq(const struct ti_sci_handle * handle,u32 dev_id,u32 clk_id,u64 * freq)1626 static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle,
1627 u32 dev_id, u32 clk_id, u64 *freq)
1628 {
1629 struct ti_sci_info *info;
1630 struct ti_sci_msg_req_get_clock_freq *req;
1631 struct ti_sci_msg_resp_get_clock_freq *resp;
1632 struct ti_sci_xfer *xfer;
1633 struct device *dev;
1634 int ret = 0;
1635
1636 if (IS_ERR(handle))
1637 return PTR_ERR(handle);
1638 if (!handle || !freq)
1639 return -EINVAL;
1640
1641 info = handle_to_ti_sci_info(handle);
1642 dev = info->dev;
1643
1644 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_FREQ,
1645 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1646 sizeof(*req), sizeof(*resp));
1647 if (IS_ERR(xfer)) {
1648 ret = PTR_ERR(xfer);
1649 dev_err(dev, "Message alloc failed(%d)\n", ret);
1650 return ret;
1651 }
1652 req = (struct ti_sci_msg_req_get_clock_freq *)xfer->xfer_buf;
1653 req->dev_id = dev_id;
1654 if (clk_id < 255) {
1655 req->clk_id = clk_id;
1656 } else {
1657 req->clk_id = 255;
1658 req->clk_id_32 = clk_id;
1659 }
1660
1661 ret = ti_sci_do_xfer(info, xfer);
1662 if (ret) {
1663 dev_err(dev, "Mbox send fail %d\n", ret);
1664 goto fail;
1665 }
1666
1667 resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->xfer_buf;
1668
1669 if (!ti_sci_is_response_ack(resp))
1670 ret = -ENODEV;
1671 else
1672 *freq = resp->freq_hz;
1673
1674 fail:
1675 ti_sci_put_one_xfer(&info->minfo, xfer);
1676
1677 return ret;
1678 }
1679
1680 /**
1681 * ti_sci_cmd_prepare_sleep() - Prepare system for system suspend
1682 * @handle: pointer to TI SCI handle
1683 * @mode: Device identifier
1684 * @ctx_lo: Low part of address for context save
1685 * @ctx_hi: High part of address for context save
1686 * @debug_flags: Debug flags to pass to firmware
1687 *
1688 * Return: 0 if all went well, else returns appropriate error value.
1689 */
ti_sci_cmd_prepare_sleep(const struct ti_sci_handle * handle,u8 mode,u32 ctx_lo,u32 ctx_hi,u32 debug_flags)1690 static int ti_sci_cmd_prepare_sleep(const struct ti_sci_handle *handle, u8 mode,
1691 u32 ctx_lo, u32 ctx_hi, u32 debug_flags)
1692 {
1693 u32 msg_flags = mode == TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO ?
1694 TI_SCI_FLAG_REQ_GENERIC_NORESPONSE :
1695 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED;
1696 struct ti_sci_info *info;
1697 struct ti_sci_msg_req_prepare_sleep *req;
1698 struct ti_sci_msg_hdr *resp;
1699 struct ti_sci_xfer *xfer;
1700 struct device *dev;
1701 int ret = 0;
1702
1703 if (IS_ERR(handle))
1704 return PTR_ERR(handle);
1705 if (!handle)
1706 return -EINVAL;
1707
1708 info = handle_to_ti_sci_info(handle);
1709 dev = info->dev;
1710
1711 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PREPARE_SLEEP,
1712 msg_flags,
1713 sizeof(*req), sizeof(*resp));
1714 if (IS_ERR(xfer)) {
1715 ret = PTR_ERR(xfer);
1716 dev_err(dev, "Message alloc failed(%d)\n", ret);
1717 return ret;
1718 }
1719
1720 req = (struct ti_sci_msg_req_prepare_sleep *)xfer->xfer_buf;
1721 req->mode = mode;
1722 req->ctx_lo = ctx_lo;
1723 req->ctx_hi = ctx_hi;
1724 req->debug_flags = debug_flags;
1725
1726 ret = ti_sci_do_xfer(info, xfer);
1727 if (ret) {
1728 dev_err(dev, "Mbox send fail %d\n", ret);
1729 goto fail;
1730 }
1731
1732 if (msg_flags == TI_SCI_FLAG_REQ_ACK_ON_PROCESSED) {
1733 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
1734 if (!ti_sci_is_response_ack(resp)) {
1735 dev_err(dev, "Failed to prepare sleep\n");
1736 ret = -ENODEV;
1737 }
1738 }
1739
1740 fail:
1741 ti_sci_put_one_xfer(&info->minfo, xfer);
1742
1743 return ret;
1744 }
1745
1746 /**
1747 * ti_sci_msg_cmd_query_fw_caps() - Get the FW/SoC capabilities
1748 * @handle: Pointer to TI SCI handle
1749 * @fw_caps: Each bit in fw_caps indicating one FW/SOC capability
1750 *
1751 * Check if the firmware supports any optional low power modes.
1752 * Old revisions of TIFS (< 08.04) will NACK the request which results in
1753 * -ENODEV being returned.
1754 *
1755 * Return: 0 if all went well, else returns appropriate error value.
1756 */
ti_sci_msg_cmd_query_fw_caps(const struct ti_sci_handle * handle,u64 * fw_caps)1757 static int ti_sci_msg_cmd_query_fw_caps(const struct ti_sci_handle *handle,
1758 u64 *fw_caps)
1759 {
1760 struct ti_sci_info *info;
1761 struct ti_sci_xfer *xfer;
1762 struct ti_sci_msg_resp_query_fw_caps *resp;
1763 struct device *dev;
1764 int ret = 0;
1765
1766 if (IS_ERR(handle))
1767 return PTR_ERR(handle);
1768 if (!handle)
1769 return -EINVAL;
1770
1771 info = handle_to_ti_sci_info(handle);
1772 dev = info->dev;
1773
1774 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_QUERY_FW_CAPS,
1775 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1776 sizeof(struct ti_sci_msg_hdr),
1777 sizeof(*resp));
1778 if (IS_ERR(xfer)) {
1779 ret = PTR_ERR(xfer);
1780 dev_err(dev, "Message alloc failed(%d)\n", ret);
1781 return ret;
1782 }
1783
1784 ret = ti_sci_do_xfer(info, xfer);
1785 if (ret) {
1786 dev_err(dev, "Mbox send fail %d\n", ret);
1787 goto fail;
1788 }
1789
1790 resp = (struct ti_sci_msg_resp_query_fw_caps *)xfer->xfer_buf;
1791
1792 if (!ti_sci_is_response_ack(resp)) {
1793 dev_err(dev, "Failed to get capabilities\n");
1794 ret = -ENODEV;
1795 goto fail;
1796 }
1797
1798 if (fw_caps)
1799 *fw_caps = resp->fw_caps;
1800
1801 fail:
1802 ti_sci_put_one_xfer(&info->minfo, xfer);
1803
1804 return ret;
1805 }
1806
1807 /**
1808 * ti_sci_cmd_set_io_isolation() - Enable IO isolation in LPM
1809 * @handle: Pointer to TI SCI handle
1810 * @state: The desired state of the IO isolation
1811 *
1812 * Return: 0 if all went well, else returns appropriate error value.
1813 */
ti_sci_cmd_set_io_isolation(const struct ti_sci_handle * handle,u8 state)1814 static int ti_sci_cmd_set_io_isolation(const struct ti_sci_handle *handle,
1815 u8 state)
1816 {
1817 struct ti_sci_info *info;
1818 struct ti_sci_msg_req_set_io_isolation *req;
1819 struct ti_sci_msg_hdr *resp;
1820 struct ti_sci_xfer *xfer;
1821 struct device *dev;
1822 int ret = 0;
1823
1824 if (IS_ERR(handle))
1825 return PTR_ERR(handle);
1826 if (!handle)
1827 return -EINVAL;
1828
1829 info = handle_to_ti_sci_info(handle);
1830 dev = info->dev;
1831
1832 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_IO_ISOLATION,
1833 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1834 sizeof(*req), sizeof(*resp));
1835 if (IS_ERR(xfer)) {
1836 ret = PTR_ERR(xfer);
1837 dev_err(dev, "Message alloc failed(%d)\n", ret);
1838 return ret;
1839 }
1840 req = (struct ti_sci_msg_req_set_io_isolation *)xfer->xfer_buf;
1841 req->state = state;
1842
1843 ret = ti_sci_do_xfer(info, xfer);
1844 if (ret) {
1845 dev_err(dev, "Mbox send fail %d\n", ret);
1846 goto fail;
1847 }
1848
1849 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
1850
1851 if (!ti_sci_is_response_ack(resp)) {
1852 dev_err(dev, "Failed to set IO isolation\n");
1853 ret = -ENODEV;
1854 }
1855
1856 fail:
1857 ti_sci_put_one_xfer(&info->minfo, xfer);
1858
1859 return ret;
1860 }
1861
1862 /**
1863 * ti_sci_msg_cmd_lpm_wake_reason() - Get the wakeup source from LPM
1864 * @handle: Pointer to TI SCI handle
1865 * @source: The wakeup source that woke the SoC from LPM
1866 * @timestamp: Timestamp of the wakeup event
1867 * @pin: The pin that has triggered wake up
1868 * @mode: The last entered low power mode
1869 *
1870 * Return: 0 if all went well, else returns appropriate error value.
1871 */
ti_sci_msg_cmd_lpm_wake_reason(const struct ti_sci_handle * handle,u32 * source,u64 * timestamp,u8 * pin,u8 * mode)1872 static int ti_sci_msg_cmd_lpm_wake_reason(const struct ti_sci_handle *handle,
1873 u32 *source, u64 *timestamp, u8 *pin, u8 *mode)
1874 {
1875 struct ti_sci_info *info;
1876 struct ti_sci_xfer *xfer;
1877 struct ti_sci_msg_resp_lpm_wake_reason *resp;
1878 struct device *dev;
1879 int ret = 0;
1880
1881 if (IS_ERR(handle))
1882 return PTR_ERR(handle);
1883 if (!handle)
1884 return -EINVAL;
1885
1886 info = handle_to_ti_sci_info(handle);
1887 dev = info->dev;
1888
1889 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_WAKE_REASON,
1890 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1891 sizeof(struct ti_sci_msg_hdr),
1892 sizeof(*resp));
1893 if (IS_ERR(xfer)) {
1894 ret = PTR_ERR(xfer);
1895 dev_err(dev, "Message alloc failed(%d)\n", ret);
1896 return ret;
1897 }
1898
1899 ret = ti_sci_do_xfer(info, xfer);
1900 if (ret) {
1901 dev_err(dev, "Mbox send fail %d\n", ret);
1902 goto fail;
1903 }
1904
1905 resp = (struct ti_sci_msg_resp_lpm_wake_reason *)xfer->xfer_buf;
1906
1907 if (!ti_sci_is_response_ack(resp)) {
1908 dev_err(dev, "Failed to get wake reason\n");
1909 ret = -ENODEV;
1910 goto fail;
1911 }
1912
1913 if (source)
1914 *source = resp->wake_source;
1915 if (timestamp)
1916 *timestamp = resp->wake_timestamp;
1917 if (pin)
1918 *pin = resp->wake_pin;
1919 if (mode)
1920 *mode = resp->mode;
1921
1922 fail:
1923 ti_sci_put_one_xfer(&info->minfo, xfer);
1924
1925 return ret;
1926 }
1927
1928 /**
1929 * ti_sci_cmd_set_device_constraint() - Set LPM constraint on behalf of a device
1930 * @handle: pointer to TI SCI handle
1931 * @id: Device identifier
1932 * @state: The desired state of device constraint: set or clear
1933 *
1934 * Return: 0 if all went well, else returns appropriate error value.
1935 */
ti_sci_cmd_set_device_constraint(const struct ti_sci_handle * handle,u32 id,u8 state)1936 static int ti_sci_cmd_set_device_constraint(const struct ti_sci_handle *handle,
1937 u32 id, u8 state)
1938 {
1939 struct ti_sci_info *info;
1940 struct ti_sci_msg_req_lpm_set_device_constraint *req;
1941 struct ti_sci_msg_hdr *resp;
1942 struct ti_sci_xfer *xfer;
1943 struct device *dev;
1944 int ret = 0;
1945
1946 if (IS_ERR(handle))
1947 return PTR_ERR(handle);
1948 if (!handle)
1949 return -EINVAL;
1950
1951 info = handle_to_ti_sci_info(handle);
1952 dev = info->dev;
1953
1954 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_SET_DEVICE_CONSTRAINT,
1955 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1956 sizeof(*req), sizeof(*resp));
1957 if (IS_ERR(xfer)) {
1958 ret = PTR_ERR(xfer);
1959 dev_err(dev, "Message alloc failed(%d)\n", ret);
1960 return ret;
1961 }
1962 req = (struct ti_sci_msg_req_lpm_set_device_constraint *)xfer->xfer_buf;
1963 req->id = id;
1964 req->state = state;
1965
1966 ret = ti_sci_do_xfer(info, xfer);
1967 if (ret) {
1968 dev_err(dev, "Mbox send fail %d\n", ret);
1969 goto fail;
1970 }
1971
1972 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
1973
1974 if (!ti_sci_is_response_ack(resp)) {
1975 dev_err(dev, "Failed to set device constraint\n");
1976 ret = -ENODEV;
1977 }
1978
1979 fail:
1980 ti_sci_put_one_xfer(&info->minfo, xfer);
1981
1982 return ret;
1983 }
1984
1985 /**
1986 * ti_sci_cmd_set_latency_constraint() - Set LPM resume latency constraint
1987 * @handle: pointer to TI SCI handle
1988 * @latency: maximum acceptable latency (in ms) to wake up from LPM
1989 * @state: The desired state of latency constraint: set or clear
1990 *
1991 * Return: 0 if all went well, else returns appropriate error value.
1992 */
ti_sci_cmd_set_latency_constraint(const struct ti_sci_handle * handle,u16 latency,u8 state)1993 static int ti_sci_cmd_set_latency_constraint(const struct ti_sci_handle *handle,
1994 u16 latency, u8 state)
1995 {
1996 struct ti_sci_info *info;
1997 struct ti_sci_msg_req_lpm_set_latency_constraint *req;
1998 struct ti_sci_msg_hdr *resp;
1999 struct ti_sci_xfer *xfer;
2000 struct device *dev;
2001 int ret = 0;
2002
2003 if (IS_ERR(handle))
2004 return PTR_ERR(handle);
2005 if (!handle)
2006 return -EINVAL;
2007
2008 info = handle_to_ti_sci_info(handle);
2009 dev = info->dev;
2010
2011 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_SET_LATENCY_CONSTRAINT,
2012 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2013 sizeof(*req), sizeof(*resp));
2014 if (IS_ERR(xfer)) {
2015 ret = PTR_ERR(xfer);
2016 dev_err(dev, "Message alloc failed(%d)\n", ret);
2017 return ret;
2018 }
2019 req = (struct ti_sci_msg_req_lpm_set_latency_constraint *)xfer->xfer_buf;
2020 req->latency = latency;
2021 req->state = state;
2022
2023 ret = ti_sci_do_xfer(info, xfer);
2024 if (ret) {
2025 dev_err(dev, "Mbox send fail %d\n", ret);
2026 goto fail;
2027 }
2028
2029 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2030
2031 if (!ti_sci_is_response_ack(resp)) {
2032 dev_err(dev, "Failed to set device constraint\n");
2033 ret = -ENODEV;
2034 }
2035
2036 fail:
2037 ti_sci_put_one_xfer(&info->minfo, xfer);
2038
2039 return ret;
2040 }
2041
2042 /**
2043 * ti_sci_cmd_lpm_abort() - Abort entry to LPM by clearing selection of LPM to enter
2044 * @dev: Device pointer corresponding to the SCI entity
2045 *
2046 * Return: 0 if all went well, else returns appropriate error value.
2047 */
ti_sci_cmd_lpm_abort(struct device * dev)2048 static int ti_sci_cmd_lpm_abort(struct device *dev)
2049 {
2050 struct ti_sci_info *info = dev_get_drvdata(dev);
2051 struct ti_sci_msg_hdr *req;
2052 struct ti_sci_msg_hdr *resp;
2053 struct ti_sci_xfer *xfer;
2054 int ret = 0;
2055
2056 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_ABORT,
2057 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2058 sizeof(*req), sizeof(*resp));
2059 if (IS_ERR(xfer)) {
2060 ret = PTR_ERR(xfer);
2061 dev_err(dev, "Message alloc failed(%d)\n", ret);
2062 return ret;
2063 }
2064 req = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2065
2066 ret = ti_sci_do_xfer(info, xfer);
2067 if (ret) {
2068 dev_err(dev, "Mbox send fail %d\n", ret);
2069 goto fail;
2070 }
2071
2072 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2073
2074 if (!ti_sci_is_response_ack(resp))
2075 ret = -ENODEV;
2076
2077 fail:
2078 ti_sci_put_one_xfer(&info->minfo, xfer);
2079
2080 return ret;
2081 }
2082
ti_sci_cmd_core_reboot(const struct ti_sci_handle * handle)2083 static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle)
2084 {
2085 struct ti_sci_info *info;
2086 struct ti_sci_msg_req_reboot *req;
2087 struct ti_sci_msg_hdr *resp;
2088 struct ti_sci_xfer *xfer;
2089 struct device *dev;
2090 int ret = 0;
2091
2092 if (IS_ERR(handle))
2093 return PTR_ERR(handle);
2094 if (!handle)
2095 return -EINVAL;
2096
2097 info = handle_to_ti_sci_info(handle);
2098 dev = info->dev;
2099
2100 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SYS_RESET,
2101 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2102 sizeof(*req), sizeof(*resp));
2103 if (IS_ERR(xfer)) {
2104 ret = PTR_ERR(xfer);
2105 dev_err(dev, "Message alloc failed(%d)\n", ret);
2106 return ret;
2107 }
2108 req = (struct ti_sci_msg_req_reboot *)xfer->xfer_buf;
2109
2110 ret = ti_sci_do_xfer(info, xfer);
2111 if (ret) {
2112 dev_err(dev, "Mbox send fail %d\n", ret);
2113 goto fail;
2114 }
2115
2116 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2117
2118 if (!ti_sci_is_response_ack(resp))
2119 ret = -ENODEV;
2120 else
2121 ret = 0;
2122
2123 fail:
2124 ti_sci_put_one_xfer(&info->minfo, xfer);
2125
2126 return ret;
2127 }
2128
2129 /**
2130 * ti_sci_get_resource_range - Helper to get a range of resources assigned
2131 * to a host. Resource is uniquely identified by
2132 * type and subtype.
2133 * @handle: Pointer to TISCI handle.
2134 * @dev_id: TISCI device ID.
2135 * @subtype: Resource assignment subtype that is being requested
2136 * from the given device.
2137 * @s_host: Host processor ID to which the resources are allocated
2138 * @desc: Pointer to ti_sci_resource_desc to be updated with the
2139 * resource range start index and number of resources
2140 *
2141 * Return: 0 if all went fine, else return appropriate error.
2142 */
ti_sci_get_resource_range(const struct ti_sci_handle * handle,u32 dev_id,u8 subtype,u8 s_host,struct ti_sci_resource_desc * desc)2143 static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
2144 u32 dev_id, u8 subtype, u8 s_host,
2145 struct ti_sci_resource_desc *desc)
2146 {
2147 struct ti_sci_msg_resp_get_resource_range *resp;
2148 struct ti_sci_msg_req_get_resource_range *req;
2149 struct ti_sci_xfer *xfer;
2150 struct ti_sci_info *info;
2151 struct device *dev;
2152 int ret = 0;
2153
2154 if (IS_ERR(handle))
2155 return PTR_ERR(handle);
2156 if (!handle || !desc)
2157 return -EINVAL;
2158
2159 info = handle_to_ti_sci_info(handle);
2160 dev = info->dev;
2161
2162 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_RESOURCE_RANGE,
2163 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2164 sizeof(*req), sizeof(*resp));
2165 if (IS_ERR(xfer)) {
2166 ret = PTR_ERR(xfer);
2167 dev_err(dev, "Message alloc failed(%d)\n", ret);
2168 return ret;
2169 }
2170
2171 req = (struct ti_sci_msg_req_get_resource_range *)xfer->xfer_buf;
2172 req->secondary_host = s_host;
2173 req->type = dev_id & MSG_RM_RESOURCE_TYPE_MASK;
2174 req->subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK;
2175
2176 ret = ti_sci_do_xfer(info, xfer);
2177 if (ret) {
2178 dev_err(dev, "Mbox send fail %d\n", ret);
2179 goto fail;
2180 }
2181
2182 resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->xfer_buf;
2183
2184 if (!ti_sci_is_response_ack(resp)) {
2185 ret = -ENODEV;
2186 } else if (!resp->range_num && !resp->range_num_sec) {
2187 /* Neither of the two resource range is valid */
2188 ret = -ENODEV;
2189 } else {
2190 desc->start = resp->range_start;
2191 desc->num = resp->range_num;
2192 desc->start_sec = resp->range_start_sec;
2193 desc->num_sec = resp->range_num_sec;
2194 }
2195
2196 fail:
2197 ti_sci_put_one_xfer(&info->minfo, xfer);
2198
2199 return ret;
2200 }
2201
2202 /**
2203 * ti_sci_cmd_get_resource_range - Get a range of resources assigned to host
2204 * that is same as ti sci interface host.
2205 * @handle: Pointer to TISCI handle.
2206 * @dev_id: TISCI device ID.
2207 * @subtype: Resource assignment subtype that is being requested
2208 * from the given device.
2209 * @desc: Pointer to ti_sci_resource_desc to be updated with the
2210 * resource range start index and number of resources
2211 *
2212 * Return: 0 if all went fine, else return appropriate error.
2213 */
ti_sci_cmd_get_resource_range(const struct ti_sci_handle * handle,u32 dev_id,u8 subtype,struct ti_sci_resource_desc * desc)2214 static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle,
2215 u32 dev_id, u8 subtype,
2216 struct ti_sci_resource_desc *desc)
2217 {
2218 return ti_sci_get_resource_range(handle, dev_id, subtype,
2219 TI_SCI_IRQ_SECONDARY_HOST_INVALID,
2220 desc);
2221 }
2222
2223 /**
2224 * ti_sci_cmd_get_resource_range_from_shost - Get a range of resources
2225 * assigned to a specified host.
2226 * @handle: Pointer to TISCI handle.
2227 * @dev_id: TISCI device ID.
2228 * @subtype: Resource assignment subtype that is being requested
2229 * from the given device.
2230 * @s_host: Host processor ID to which the resources are allocated
2231 * @desc: Pointer to ti_sci_resource_desc to be updated with the
2232 * resource range start index and number of resources
2233 *
2234 * Return: 0 if all went fine, else return appropriate error.
2235 */
2236 static
ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle * handle,u32 dev_id,u8 subtype,u8 s_host,struct ti_sci_resource_desc * desc)2237 int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle,
2238 u32 dev_id, u8 subtype, u8 s_host,
2239 struct ti_sci_resource_desc *desc)
2240 {
2241 return ti_sci_get_resource_range(handle, dev_id, subtype, s_host, desc);
2242 }
2243
2244 /**
2245 * ti_sci_manage_irq() - Helper api to configure/release the irq route between
2246 * the requested source and destination
2247 * @handle: Pointer to TISCI handle.
2248 * @valid_params: Bit fields defining the validity of certain params
2249 * @src_id: Device ID of the IRQ source
2250 * @src_index: IRQ source index within the source device
2251 * @dst_id: Device ID of the IRQ destination
2252 * @dst_host_irq: IRQ number of the destination device
2253 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
2254 * @vint: Virtual interrupt to be used within the IA
2255 * @global_event: Global event number to be used for the requesting event
2256 * @vint_status_bit: Virtual interrupt status bit to be used for the event
2257 * @s_host: Secondary host ID to which the irq/event is being
2258 * requested for.
2259 * @type: Request type irq set or release.
2260 *
2261 * Return: 0 if all went fine, else return appropriate error.
2262 */
ti_sci_manage_irq(const struct ti_sci_handle * handle,u32 valid_params,u16 src_id,u16 src_index,u16 dst_id,u16 dst_host_irq,u16 ia_id,u16 vint,u16 global_event,u8 vint_status_bit,u8 s_host,u16 type)2263 static int ti_sci_manage_irq(const struct ti_sci_handle *handle,
2264 u32 valid_params, u16 src_id, u16 src_index,
2265 u16 dst_id, u16 dst_host_irq, u16 ia_id, u16 vint,
2266 u16 global_event, u8 vint_status_bit, u8 s_host,
2267 u16 type)
2268 {
2269 struct ti_sci_msg_req_manage_irq *req;
2270 struct ti_sci_msg_hdr *resp;
2271 struct ti_sci_xfer *xfer;
2272 struct ti_sci_info *info;
2273 struct device *dev;
2274 int ret = 0;
2275
2276 if (IS_ERR(handle))
2277 return PTR_ERR(handle);
2278 if (!handle)
2279 return -EINVAL;
2280
2281 info = handle_to_ti_sci_info(handle);
2282 dev = info->dev;
2283
2284 xfer = ti_sci_get_one_xfer(info, type, TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2285 sizeof(*req), sizeof(*resp));
2286 if (IS_ERR(xfer)) {
2287 ret = PTR_ERR(xfer);
2288 dev_err(dev, "Message alloc failed(%d)\n", ret);
2289 return ret;
2290 }
2291 req = (struct ti_sci_msg_req_manage_irq *)xfer->xfer_buf;
2292 req->valid_params = valid_params;
2293 req->src_id = src_id;
2294 req->src_index = src_index;
2295 req->dst_id = dst_id;
2296 req->dst_host_irq = dst_host_irq;
2297 req->ia_id = ia_id;
2298 req->vint = vint;
2299 req->global_event = global_event;
2300 req->vint_status_bit = vint_status_bit;
2301 req->secondary_host = s_host;
2302
2303 ret = ti_sci_do_xfer(info, xfer);
2304 if (ret) {
2305 dev_err(dev, "Mbox send fail %d\n", ret);
2306 goto fail;
2307 }
2308
2309 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2310
2311 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
2312
2313 fail:
2314 ti_sci_put_one_xfer(&info->minfo, xfer);
2315
2316 return ret;
2317 }
2318
2319 /**
2320 * ti_sci_irq_hash() - Helper API to compute irq hash for the hash table.
2321 * @irq: irq to hash
2322 *
2323 * Return: the computed hash value.
2324 */
ti_sci_irq_hash(struct ti_sci_msg_req_manage_irq * irq)2325 static int ti_sci_irq_hash(struct ti_sci_msg_req_manage_irq *irq)
2326 {
2327 return irq->src_id ^ irq->src_index;
2328 }
2329
2330 /**
2331 * ti_sci_irq_equal() - Helper API to compare two irqs (generic headers are not
2332 * compared)
2333 * @irq_a: irq_a to compare
2334 * @irq_b: irq_b to compare
2335 *
2336 * Return: true if the two irqs are equal, else false.
2337 */
ti_sci_irq_equal(struct ti_sci_msg_req_manage_irq * irq_a,struct ti_sci_msg_req_manage_irq * irq_b)2338 static bool ti_sci_irq_equal(struct ti_sci_msg_req_manage_irq *irq_a,
2339 struct ti_sci_msg_req_manage_irq *irq_b)
2340 {
2341 return !memcmp(&irq_a->valid_params, &irq_b->valid_params,
2342 sizeof(*irq_a) - sizeof(irq_a->hdr));
2343 }
2344
2345 /**
2346 * ti_sci_set_irq() - Helper api to configure the irq route between the
2347 * requested source and destination
2348 * @handle: Pointer to TISCI handle.
2349 * @valid_params: Bit fields defining the validity of certain params
2350 * @src_id: Device ID of the IRQ source
2351 * @src_index: IRQ source index within the source device
2352 * @dst_id: Device ID of the IRQ destination
2353 * @dst_host_irq: IRQ number of the destination device
2354 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
2355 * @vint: Virtual interrupt to be used within the IA
2356 * @global_event: Global event number to be used for the requesting event
2357 * @vint_status_bit: Virtual interrupt status bit to be used for the event
2358 * @s_host: Secondary host ID to which the irq/event is being
2359 * requested for.
2360 *
2361 * Return: 0 if all went fine, else return appropriate error.
2362 */
ti_sci_set_irq(const struct ti_sci_handle * handle,u32 valid_params,u16 src_id,u16 src_index,u16 dst_id,u16 dst_host_irq,u16 ia_id,u16 vint,u16 global_event,u8 vint_status_bit,u8 s_host)2363 static int ti_sci_set_irq(const struct ti_sci_handle *handle, u32 valid_params,
2364 u16 src_id, u16 src_index, u16 dst_id,
2365 u16 dst_host_irq, u16 ia_id, u16 vint,
2366 u16 global_event, u8 vint_status_bit, u8 s_host)
2367 {
2368 struct ti_sci_info *info = handle_to_ti_sci_info(handle);
2369 struct ti_sci_msg_req_manage_irq *desc;
2370 struct ti_sci_irq *irq;
2371 int ret;
2372
2373 /* Lock for set_irq() and free_irq() to keep the IRQ hash list consistent */
2374 guard(mutex)(&info->irq_lock);
2375
2376 pr_debug("%s: IRQ set with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
2377 __func__, valid_params, src_id, src_index,
2378 dst_id, dst_host_irq, ia_id, vint, global_event,
2379 vint_status_bit);
2380
2381 ret = ti_sci_manage_irq(handle, valid_params, src_id, src_index,
2382 dst_id, dst_host_irq, ia_id, vint,
2383 global_event, vint_status_bit, s_host,
2384 TI_SCI_MSG_SET_IRQ);
2385
2386 if (ret || !(info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST))
2387 goto end;
2388
2389 irq = kzalloc_obj(*irq);
2390 if (!irq) {
2391 ti_sci_manage_irq(handle, valid_params, src_id, src_index,
2392 dst_id, dst_host_irq, ia_id, vint,
2393 global_event, vint_status_bit, s_host,
2394 TI_SCI_MSG_FREE_IRQ);
2395 ret = -ENOMEM;
2396 goto end;
2397 }
2398
2399 desc = &irq->desc;
2400 desc->valid_params = valid_params;
2401 desc->src_id = src_id;
2402 desc->src_index = src_index;
2403 desc->dst_id = dst_id;
2404 desc->dst_host_irq = dst_host_irq;
2405 desc->ia_id = ia_id;
2406 desc->vint = vint;
2407 desc->global_event = global_event;
2408 desc->vint_status_bit = vint_status_bit;
2409 desc->secondary_host = s_host;
2410
2411 hash_add(info->irqs, &irq->node, ti_sci_irq_hash(desc));
2412
2413 end:
2414 return ret;
2415 }
2416
2417 /**
2418 * ti_sci_free_irq() - Helper api to free the irq route between the
2419 * requested source and destination
2420 * @handle: Pointer to TISCI handle.
2421 * @valid_params: Bit fields defining the validity of certain params
2422 * @src_id: Device ID of the IRQ source
2423 * @src_index: IRQ source index within the source device
2424 * @dst_id: Device ID of the IRQ destination
2425 * @dst_host_irq: IRQ number of the destination device
2426 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
2427 * @vint: Virtual interrupt to be used within the IA
2428 * @global_event: Global event number to be used for the requesting event
2429 * @vint_status_bit: Virtual interrupt status bit to be used for the event
2430 * @s_host: Secondary host ID to which the irq/event is being
2431 * requested for.
2432 *
2433 * Return: 0 if all went fine, else return appropriate error.
2434 */
ti_sci_free_irq(const struct ti_sci_handle * handle,u32 valid_params,u16 src_id,u16 src_index,u16 dst_id,u16 dst_host_irq,u16 ia_id,u16 vint,u16 global_event,u8 vint_status_bit,u8 s_host)2435 static int ti_sci_free_irq(const struct ti_sci_handle *handle, u32 valid_params,
2436 u16 src_id, u16 src_index, u16 dst_id,
2437 u16 dst_host_irq, u16 ia_id, u16 vint,
2438 u16 global_event, u8 vint_status_bit, u8 s_host)
2439 {
2440 struct ti_sci_info *info = handle_to_ti_sci_info(handle);
2441 struct ti_sci_msg_req_manage_irq irq_desc;
2442 struct device *dev = info->dev;
2443 struct ti_sci_irq *this_irq;
2444 struct hlist_node *tmp_node;
2445 int ret;
2446
2447 guard(mutex)(&info->irq_lock);
2448
2449 pr_debug("%s: IRQ release with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
2450 __func__, valid_params, src_id, src_index,
2451 dst_id, dst_host_irq, ia_id, vint, global_event,
2452 vint_status_bit);
2453
2454 ret = ti_sci_manage_irq(handle, valid_params, src_id, src_index,
2455 dst_id, dst_host_irq, ia_id, vint,
2456 global_event, vint_status_bit, s_host,
2457 TI_SCI_MSG_FREE_IRQ);
2458
2459 if (ret || !(info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST))
2460 goto end;
2461
2462 irq_desc.valid_params = valid_params;
2463 irq_desc.src_id = src_id;
2464 irq_desc.src_index = src_index;
2465 irq_desc.dst_id = dst_id;
2466 irq_desc.dst_host_irq = dst_host_irq;
2467 irq_desc.ia_id = ia_id;
2468 irq_desc.vint = vint;
2469 irq_desc.global_event = global_event;
2470 irq_desc.vint_status_bit = vint_status_bit;
2471 irq_desc.secondary_host = s_host;
2472
2473 hash_for_each_possible_safe(info->irqs, this_irq, tmp_node, node,
2474 ti_sci_irq_hash(&irq_desc)) {
2475 if (ti_sci_irq_equal(&irq_desc, &this_irq->desc)) {
2476 hlist_del(&this_irq->node);
2477 kfree(this_irq);
2478 goto end;
2479 }
2480 }
2481
2482 dev_warn(dev, "%s: should not be here, IRQ was not found in hash list\n",
2483 __func__);
2484
2485 end:
2486 return ret;
2487 }
2488
2489 /**
2490 * ti_sci_cmd_set_irq() - Configure a host irq route between the requested
2491 * source and destination.
2492 * @handle: Pointer to TISCI handle.
2493 * @src_id: Device ID of the IRQ source
2494 * @src_index: IRQ source index within the source device
2495 * @dst_id: Device ID of the IRQ destination
2496 * @dst_host_irq: IRQ number of the destination device
2497 *
2498 * Return: 0 if all went fine, else return appropriate error.
2499 */
ti_sci_cmd_set_irq(const struct ti_sci_handle * handle,u16 src_id,u16 src_index,u16 dst_id,u16 dst_host_irq)2500 static int ti_sci_cmd_set_irq(const struct ti_sci_handle *handle, u16 src_id,
2501 u16 src_index, u16 dst_id, u16 dst_host_irq)
2502 {
2503 u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
2504
2505 return ti_sci_set_irq(handle, valid_params, src_id, src_index, dst_id,
2506 dst_host_irq, 0, 0, 0, 0, 0);
2507 }
2508
2509 /**
2510 * ti_sci_cmd_set_event_map() - Configure an event based irq route between the
2511 * requested source and Interrupt Aggregator.
2512 * @handle: Pointer to TISCI handle.
2513 * @src_id: Device ID of the IRQ source
2514 * @src_index: IRQ source index within the source device
2515 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
2516 * @vint: Virtual interrupt to be used within the IA
2517 * @global_event: Global event number to be used for the requesting event
2518 * @vint_status_bit: Virtual interrupt status bit to be used for the event
2519 *
2520 * Return: 0 if all went fine, else return appropriate error.
2521 */
ti_sci_cmd_set_event_map(const struct ti_sci_handle * handle,u16 src_id,u16 src_index,u16 ia_id,u16 vint,u16 global_event,u8 vint_status_bit)2522 static int ti_sci_cmd_set_event_map(const struct ti_sci_handle *handle,
2523 u16 src_id, u16 src_index, u16 ia_id,
2524 u16 vint, u16 global_event,
2525 u8 vint_status_bit)
2526 {
2527 u32 valid_params = MSG_FLAG_IA_ID_VALID | MSG_FLAG_VINT_VALID |
2528 MSG_FLAG_GLB_EVNT_VALID |
2529 MSG_FLAG_VINT_STS_BIT_VALID;
2530
2531 return ti_sci_set_irq(handle, valid_params, src_id, src_index, 0, 0,
2532 ia_id, vint, global_event, vint_status_bit, 0);
2533 }
2534
2535 /**
2536 * ti_sci_cmd_free_irq() - Free a host irq route between the between the
2537 * requested source and destination.
2538 * @handle: Pointer to TISCI handle.
2539 * @src_id: Device ID of the IRQ source
2540 * @src_index: IRQ source index within the source device
2541 * @dst_id: Device ID of the IRQ destination
2542 * @dst_host_irq: IRQ number of the destination device
2543 *
2544 * Return: 0 if all went fine, else return appropriate error.
2545 */
ti_sci_cmd_free_irq(const struct ti_sci_handle * handle,u16 src_id,u16 src_index,u16 dst_id,u16 dst_host_irq)2546 static int ti_sci_cmd_free_irq(const struct ti_sci_handle *handle, u16 src_id,
2547 u16 src_index, u16 dst_id, u16 dst_host_irq)
2548 {
2549 u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
2550
2551 return ti_sci_free_irq(handle, valid_params, src_id, src_index, dst_id,
2552 dst_host_irq, 0, 0, 0, 0, 0);
2553 }
2554
2555 /**
2556 * ti_sci_cmd_free_event_map() - Free an event map between the requested source
2557 * and Interrupt Aggregator.
2558 * @handle: Pointer to TISCI handle.
2559 * @src_id: Device ID of the IRQ source
2560 * @src_index: IRQ source index within the source device
2561 * @ia_id: Device ID of the IA, if the IRQ flows through this IA
2562 * @vint: Virtual interrupt to be used within the IA
2563 * @global_event: Global event number to be used for the requesting event
2564 * @vint_status_bit: Virtual interrupt status bit to be used for the event
2565 *
2566 * Return: 0 if all went fine, else return appropriate error.
2567 */
ti_sci_cmd_free_event_map(const struct ti_sci_handle * handle,u16 src_id,u16 src_index,u16 ia_id,u16 vint,u16 global_event,u8 vint_status_bit)2568 static int ti_sci_cmd_free_event_map(const struct ti_sci_handle *handle,
2569 u16 src_id, u16 src_index, u16 ia_id,
2570 u16 vint, u16 global_event,
2571 u8 vint_status_bit)
2572 {
2573 u32 valid_params = MSG_FLAG_IA_ID_VALID |
2574 MSG_FLAG_VINT_VALID | MSG_FLAG_GLB_EVNT_VALID |
2575 MSG_FLAG_VINT_STS_BIT_VALID;
2576
2577 return ti_sci_free_irq(handle, valid_params, src_id, src_index, 0, 0,
2578 ia_id, vint, global_event, vint_status_bit, 0);
2579 }
2580
2581 /**
2582 * ti_sci_cmd_rm_ring_cfg() - Configure a NAVSS ring
2583 * @handle: Pointer to TI SCI handle.
2584 * @params: Pointer to ti_sci_msg_rm_ring_cfg ring config structure
2585 *
2586 * Return: 0 if all went well, else returns appropriate error value.
2587 *
2588 * See @ti_sci_msg_rm_ring_cfg and @ti_sci_msg_rm_ring_cfg_req for
2589 * more info.
2590 */
ti_sci_cmd_rm_ring_cfg(const struct ti_sci_handle * handle,const struct ti_sci_msg_rm_ring_cfg * params)2591 static int ti_sci_cmd_rm_ring_cfg(const struct ti_sci_handle *handle,
2592 const struct ti_sci_msg_rm_ring_cfg *params)
2593 {
2594 struct ti_sci_msg_rm_ring_cfg_req *req;
2595 struct ti_sci_msg_hdr *resp;
2596 struct ti_sci_xfer *xfer;
2597 struct ti_sci_info *info;
2598 struct device *dev;
2599 int ret = 0;
2600
2601 if (IS_ERR_OR_NULL(handle))
2602 return -EINVAL;
2603
2604 info = handle_to_ti_sci_info(handle);
2605 dev = info->dev;
2606
2607 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_RING_CFG,
2608 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2609 sizeof(*req), sizeof(*resp));
2610 if (IS_ERR(xfer)) {
2611 ret = PTR_ERR(xfer);
2612 dev_err(dev, "RM_RA:Message config failed(%d)\n", ret);
2613 return ret;
2614 }
2615 req = (struct ti_sci_msg_rm_ring_cfg_req *)xfer->xfer_buf;
2616 req->valid_params = params->valid_params;
2617 req->nav_id = params->nav_id;
2618 req->index = params->index;
2619 req->addr_lo = params->addr_lo;
2620 req->addr_hi = params->addr_hi;
2621 req->count = params->count;
2622 req->mode = params->mode;
2623 req->size = params->size;
2624 req->order_id = params->order_id;
2625 req->virtid = params->virtid;
2626 req->asel = params->asel;
2627
2628 ret = ti_sci_do_xfer(info, xfer);
2629 if (ret) {
2630 dev_err(dev, "RM_RA:Mbox config send fail %d\n", ret);
2631 goto fail;
2632 }
2633
2634 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2635 ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2636
2637 fail:
2638 ti_sci_put_one_xfer(&info->minfo, xfer);
2639 dev_dbg(dev, "RM_RA:config ring %u ret:%d\n", params->index, ret);
2640 return ret;
2641 }
2642
2643 /**
2644 * ti_sci_cmd_rm_psil_pair() - Pair PSI-L source to destination thread
2645 * @handle: Pointer to TI SCI handle.
2646 * @nav_id: Device ID of Navigator Subsystem which should be used for
2647 * pairing
2648 * @src_thread: Source PSI-L thread ID
2649 * @dst_thread: Destination PSI-L thread ID
2650 *
2651 * Return: 0 if all went well, else returns appropriate error value.
2652 */
ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle * handle,u32 nav_id,u32 src_thread,u32 dst_thread)2653 static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle,
2654 u32 nav_id, u32 src_thread, u32 dst_thread)
2655 {
2656 struct ti_sci_msg_psil_pair *req;
2657 struct ti_sci_msg_hdr *resp;
2658 struct ti_sci_xfer *xfer;
2659 struct ti_sci_info *info;
2660 struct device *dev;
2661 int ret = 0;
2662
2663 if (IS_ERR(handle))
2664 return PTR_ERR(handle);
2665 if (!handle)
2666 return -EINVAL;
2667
2668 info = handle_to_ti_sci_info(handle);
2669 dev = info->dev;
2670
2671 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_PSIL_PAIR,
2672 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2673 sizeof(*req), sizeof(*resp));
2674 if (IS_ERR(xfer)) {
2675 ret = PTR_ERR(xfer);
2676 dev_err(dev, "RM_PSIL:Message reconfig failed(%d)\n", ret);
2677 return ret;
2678 }
2679 req = (struct ti_sci_msg_psil_pair *)xfer->xfer_buf;
2680 req->nav_id = nav_id;
2681 req->src_thread = src_thread;
2682 req->dst_thread = dst_thread;
2683
2684 ret = ti_sci_do_xfer(info, xfer);
2685 if (ret) {
2686 dev_err(dev, "RM_PSIL:Mbox send fail %d\n", ret);
2687 goto fail;
2688 }
2689
2690 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2691 ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2692
2693 fail:
2694 ti_sci_put_one_xfer(&info->minfo, xfer);
2695
2696 return ret;
2697 }
2698
2699 /**
2700 * ti_sci_cmd_rm_psil_unpair() - Unpair PSI-L source from destination thread
2701 * @handle: Pointer to TI SCI handle.
2702 * @nav_id: Device ID of Navigator Subsystem which should be used for
2703 * unpairing
2704 * @src_thread: Source PSI-L thread ID
2705 * @dst_thread: Destination PSI-L thread ID
2706 *
2707 * Return: 0 if all went well, else returns appropriate error value.
2708 */
ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle * handle,u32 nav_id,u32 src_thread,u32 dst_thread)2709 static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle,
2710 u32 nav_id, u32 src_thread, u32 dst_thread)
2711 {
2712 struct ti_sci_msg_psil_unpair *req;
2713 struct ti_sci_msg_hdr *resp;
2714 struct ti_sci_xfer *xfer;
2715 struct ti_sci_info *info;
2716 struct device *dev;
2717 int ret = 0;
2718
2719 if (IS_ERR(handle))
2720 return PTR_ERR(handle);
2721 if (!handle)
2722 return -EINVAL;
2723
2724 info = handle_to_ti_sci_info(handle);
2725 dev = info->dev;
2726
2727 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_PSIL_UNPAIR,
2728 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2729 sizeof(*req), sizeof(*resp));
2730 if (IS_ERR(xfer)) {
2731 ret = PTR_ERR(xfer);
2732 dev_err(dev, "RM_PSIL:Message reconfig failed(%d)\n", ret);
2733 return ret;
2734 }
2735 req = (struct ti_sci_msg_psil_unpair *)xfer->xfer_buf;
2736 req->nav_id = nav_id;
2737 req->src_thread = src_thread;
2738 req->dst_thread = dst_thread;
2739
2740 ret = ti_sci_do_xfer(info, xfer);
2741 if (ret) {
2742 dev_err(dev, "RM_PSIL:Mbox send fail %d\n", ret);
2743 goto fail;
2744 }
2745
2746 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2747 ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2748
2749 fail:
2750 ti_sci_put_one_xfer(&info->minfo, xfer);
2751
2752 return ret;
2753 }
2754
2755 /**
2756 * ti_sci_cmd_rm_udmap_tx_ch_cfg() - Configure a UDMAP TX channel
2757 * @handle: Pointer to TI SCI handle.
2758 * @params: Pointer to ti_sci_msg_rm_udmap_tx_ch_cfg TX channel config
2759 * structure
2760 *
2761 * Return: 0 if all went well, else returns appropriate error value.
2762 *
2763 * See @ti_sci_msg_rm_udmap_tx_ch_cfg and @ti_sci_msg_rm_udmap_tx_ch_cfg_req for
2764 * more info.
2765 */
ti_sci_cmd_rm_udmap_tx_ch_cfg(const struct ti_sci_handle * handle,const struct ti_sci_msg_rm_udmap_tx_ch_cfg * params)2766 static int ti_sci_cmd_rm_udmap_tx_ch_cfg(const struct ti_sci_handle *handle,
2767 const struct ti_sci_msg_rm_udmap_tx_ch_cfg *params)
2768 {
2769 struct ti_sci_msg_rm_udmap_tx_ch_cfg_req *req;
2770 struct ti_sci_msg_hdr *resp;
2771 struct ti_sci_xfer *xfer;
2772 struct ti_sci_info *info;
2773 struct device *dev;
2774 int ret = 0;
2775
2776 if (IS_ERR_OR_NULL(handle))
2777 return -EINVAL;
2778
2779 info = handle_to_ti_sci_info(handle);
2780 dev = info->dev;
2781
2782 xfer = ti_sci_get_one_xfer(info, TISCI_MSG_RM_UDMAP_TX_CH_CFG,
2783 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2784 sizeof(*req), sizeof(*resp));
2785 if (IS_ERR(xfer)) {
2786 ret = PTR_ERR(xfer);
2787 dev_err(dev, "Message TX_CH_CFG alloc failed(%d)\n", ret);
2788 return ret;
2789 }
2790 req = (struct ti_sci_msg_rm_udmap_tx_ch_cfg_req *)xfer->xfer_buf;
2791 req->valid_params = params->valid_params;
2792 req->nav_id = params->nav_id;
2793 req->index = params->index;
2794 req->tx_pause_on_err = params->tx_pause_on_err;
2795 req->tx_filt_einfo = params->tx_filt_einfo;
2796 req->tx_filt_pswords = params->tx_filt_pswords;
2797 req->tx_atype = params->tx_atype;
2798 req->tx_chan_type = params->tx_chan_type;
2799 req->tx_supr_tdpkt = params->tx_supr_tdpkt;
2800 req->tx_fetch_size = params->tx_fetch_size;
2801 req->tx_credit_count = params->tx_credit_count;
2802 req->txcq_qnum = params->txcq_qnum;
2803 req->tx_priority = params->tx_priority;
2804 req->tx_qos = params->tx_qos;
2805 req->tx_orderid = params->tx_orderid;
2806 req->fdepth = params->fdepth;
2807 req->tx_sched_priority = params->tx_sched_priority;
2808 req->tx_burst_size = params->tx_burst_size;
2809 req->tx_tdtype = params->tx_tdtype;
2810 req->extended_ch_type = params->extended_ch_type;
2811
2812 ret = ti_sci_do_xfer(info, xfer);
2813 if (ret) {
2814 dev_err(dev, "Mbox send TX_CH_CFG fail %d\n", ret);
2815 goto fail;
2816 }
2817
2818 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2819 ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2820
2821 fail:
2822 ti_sci_put_one_xfer(&info->minfo, xfer);
2823 dev_dbg(dev, "TX_CH_CFG: chn %u ret:%u\n", params->index, ret);
2824 return ret;
2825 }
2826
2827 /**
2828 * ti_sci_cmd_rm_udmap_rx_ch_cfg() - Configure a UDMAP RX channel
2829 * @handle: Pointer to TI SCI handle.
2830 * @params: Pointer to ti_sci_msg_rm_udmap_rx_ch_cfg RX channel config
2831 * structure
2832 *
2833 * Return: 0 if all went well, else returns appropriate error value.
2834 *
2835 * See @ti_sci_msg_rm_udmap_rx_ch_cfg and @ti_sci_msg_rm_udmap_rx_ch_cfg_req for
2836 * more info.
2837 */
ti_sci_cmd_rm_udmap_rx_ch_cfg(const struct ti_sci_handle * handle,const struct ti_sci_msg_rm_udmap_rx_ch_cfg * params)2838 static int ti_sci_cmd_rm_udmap_rx_ch_cfg(const struct ti_sci_handle *handle,
2839 const struct ti_sci_msg_rm_udmap_rx_ch_cfg *params)
2840 {
2841 struct ti_sci_msg_rm_udmap_rx_ch_cfg_req *req;
2842 struct ti_sci_msg_hdr *resp;
2843 struct ti_sci_xfer *xfer;
2844 struct ti_sci_info *info;
2845 struct device *dev;
2846 int ret = 0;
2847
2848 if (IS_ERR_OR_NULL(handle))
2849 return -EINVAL;
2850
2851 info = handle_to_ti_sci_info(handle);
2852 dev = info->dev;
2853
2854 xfer = ti_sci_get_one_xfer(info, TISCI_MSG_RM_UDMAP_RX_CH_CFG,
2855 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2856 sizeof(*req), sizeof(*resp));
2857 if (IS_ERR(xfer)) {
2858 ret = PTR_ERR(xfer);
2859 dev_err(dev, "Message RX_CH_CFG alloc failed(%d)\n", ret);
2860 return ret;
2861 }
2862 req = (struct ti_sci_msg_rm_udmap_rx_ch_cfg_req *)xfer->xfer_buf;
2863 req->valid_params = params->valid_params;
2864 req->nav_id = params->nav_id;
2865 req->index = params->index;
2866 req->rx_fetch_size = params->rx_fetch_size;
2867 req->rxcq_qnum = params->rxcq_qnum;
2868 req->rx_priority = params->rx_priority;
2869 req->rx_qos = params->rx_qos;
2870 req->rx_orderid = params->rx_orderid;
2871 req->rx_sched_priority = params->rx_sched_priority;
2872 req->flowid_start = params->flowid_start;
2873 req->flowid_cnt = params->flowid_cnt;
2874 req->rx_pause_on_err = params->rx_pause_on_err;
2875 req->rx_atype = params->rx_atype;
2876 req->rx_chan_type = params->rx_chan_type;
2877 req->rx_ignore_short = params->rx_ignore_short;
2878 req->rx_ignore_long = params->rx_ignore_long;
2879 req->rx_burst_size = params->rx_burst_size;
2880
2881 ret = ti_sci_do_xfer(info, xfer);
2882 if (ret) {
2883 dev_err(dev, "Mbox send RX_CH_CFG fail %d\n", ret);
2884 goto fail;
2885 }
2886
2887 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2888 ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2889
2890 fail:
2891 ti_sci_put_one_xfer(&info->minfo, xfer);
2892 dev_dbg(dev, "RX_CH_CFG: chn %u ret:%d\n", params->index, ret);
2893 return ret;
2894 }
2895
2896 /**
2897 * ti_sci_cmd_rm_udmap_rx_flow_cfg() - Configure UDMAP RX FLOW
2898 * @handle: Pointer to TI SCI handle.
2899 * @params: Pointer to ti_sci_msg_rm_udmap_flow_cfg RX FLOW config
2900 * structure
2901 *
2902 * Return: 0 if all went well, else returns appropriate error value.
2903 *
2904 * See @ti_sci_msg_rm_udmap_flow_cfg and @ti_sci_msg_rm_udmap_flow_cfg_req for
2905 * more info.
2906 */
ti_sci_cmd_rm_udmap_rx_flow_cfg(const struct ti_sci_handle * handle,const struct ti_sci_msg_rm_udmap_flow_cfg * params)2907 static int ti_sci_cmd_rm_udmap_rx_flow_cfg(const struct ti_sci_handle *handle,
2908 const struct ti_sci_msg_rm_udmap_flow_cfg *params)
2909 {
2910 struct ti_sci_msg_rm_udmap_flow_cfg_req *req;
2911 struct ti_sci_msg_hdr *resp;
2912 struct ti_sci_xfer *xfer;
2913 struct ti_sci_info *info;
2914 struct device *dev;
2915 int ret = 0;
2916
2917 if (IS_ERR_OR_NULL(handle))
2918 return -EINVAL;
2919
2920 info = handle_to_ti_sci_info(handle);
2921 dev = info->dev;
2922
2923 xfer = ti_sci_get_one_xfer(info, TISCI_MSG_RM_UDMAP_FLOW_CFG,
2924 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2925 sizeof(*req), sizeof(*resp));
2926 if (IS_ERR(xfer)) {
2927 ret = PTR_ERR(xfer);
2928 dev_err(dev, "RX_FL_CFG: Message alloc failed(%d)\n", ret);
2929 return ret;
2930 }
2931 req = (struct ti_sci_msg_rm_udmap_flow_cfg_req *)xfer->xfer_buf;
2932 req->valid_params = params->valid_params;
2933 req->nav_id = params->nav_id;
2934 req->flow_index = params->flow_index;
2935 req->rx_einfo_present = params->rx_einfo_present;
2936 req->rx_psinfo_present = params->rx_psinfo_present;
2937 req->rx_error_handling = params->rx_error_handling;
2938 req->rx_desc_type = params->rx_desc_type;
2939 req->rx_sop_offset = params->rx_sop_offset;
2940 req->rx_dest_qnum = params->rx_dest_qnum;
2941 req->rx_src_tag_hi = params->rx_src_tag_hi;
2942 req->rx_src_tag_lo = params->rx_src_tag_lo;
2943 req->rx_dest_tag_hi = params->rx_dest_tag_hi;
2944 req->rx_dest_tag_lo = params->rx_dest_tag_lo;
2945 req->rx_src_tag_hi_sel = params->rx_src_tag_hi_sel;
2946 req->rx_src_tag_lo_sel = params->rx_src_tag_lo_sel;
2947 req->rx_dest_tag_hi_sel = params->rx_dest_tag_hi_sel;
2948 req->rx_dest_tag_lo_sel = params->rx_dest_tag_lo_sel;
2949 req->rx_fdq0_sz0_qnum = params->rx_fdq0_sz0_qnum;
2950 req->rx_fdq1_qnum = params->rx_fdq1_qnum;
2951 req->rx_fdq2_qnum = params->rx_fdq2_qnum;
2952 req->rx_fdq3_qnum = params->rx_fdq3_qnum;
2953 req->rx_ps_location = params->rx_ps_location;
2954
2955 ret = ti_sci_do_xfer(info, xfer);
2956 if (ret) {
2957 dev_err(dev, "RX_FL_CFG: Mbox send fail %d\n", ret);
2958 goto fail;
2959 }
2960
2961 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2962 ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2963
2964 fail:
2965 ti_sci_put_one_xfer(&info->minfo, xfer);
2966 dev_dbg(info->dev, "RX_FL_CFG: %u ret:%d\n", params->flow_index, ret);
2967 return ret;
2968 }
2969
2970 /**
2971 * ti_sci_cmd_proc_request() - Command to request a physical processor control
2972 * @handle: Pointer to TI SCI handle
2973 * @proc_id: Processor ID this request is for
2974 *
2975 * Return: 0 if all went well, else returns appropriate error value.
2976 */
ti_sci_cmd_proc_request(const struct ti_sci_handle * handle,u8 proc_id)2977 static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle,
2978 u8 proc_id)
2979 {
2980 struct ti_sci_msg_req_proc_request *req;
2981 struct ti_sci_msg_hdr *resp;
2982 struct ti_sci_info *info;
2983 struct ti_sci_xfer *xfer;
2984 struct device *dev;
2985 int ret = 0;
2986
2987 if (!handle)
2988 return -EINVAL;
2989 if (IS_ERR(handle))
2990 return PTR_ERR(handle);
2991
2992 info = handle_to_ti_sci_info(handle);
2993 dev = info->dev;
2994
2995 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_REQUEST,
2996 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2997 sizeof(*req), sizeof(*resp));
2998 if (IS_ERR(xfer)) {
2999 ret = PTR_ERR(xfer);
3000 dev_err(dev, "Message alloc failed(%d)\n", ret);
3001 return ret;
3002 }
3003 req = (struct ti_sci_msg_req_proc_request *)xfer->xfer_buf;
3004 req->processor_id = proc_id;
3005
3006 ret = ti_sci_do_xfer(info, xfer);
3007 if (ret) {
3008 dev_err(dev, "Mbox send fail %d\n", ret);
3009 goto fail;
3010 }
3011
3012 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
3013
3014 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
3015
3016 fail:
3017 ti_sci_put_one_xfer(&info->minfo, xfer);
3018
3019 return ret;
3020 }
3021
3022 /**
3023 * ti_sci_cmd_proc_release() - Command to release a physical processor control
3024 * @handle: Pointer to TI SCI handle
3025 * @proc_id: Processor ID this request is for
3026 *
3027 * Return: 0 if all went well, else returns appropriate error value.
3028 */
ti_sci_cmd_proc_release(const struct ti_sci_handle * handle,u8 proc_id)3029 static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle,
3030 u8 proc_id)
3031 {
3032 struct ti_sci_msg_req_proc_release *req;
3033 struct ti_sci_msg_hdr *resp;
3034 struct ti_sci_info *info;
3035 struct ti_sci_xfer *xfer;
3036 struct device *dev;
3037 int ret = 0;
3038
3039 if (!handle)
3040 return -EINVAL;
3041 if (IS_ERR(handle))
3042 return PTR_ERR(handle);
3043
3044 info = handle_to_ti_sci_info(handle);
3045 dev = info->dev;
3046
3047 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_RELEASE,
3048 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
3049 sizeof(*req), sizeof(*resp));
3050 if (IS_ERR(xfer)) {
3051 ret = PTR_ERR(xfer);
3052 dev_err(dev, "Message alloc failed(%d)\n", ret);
3053 return ret;
3054 }
3055 req = (struct ti_sci_msg_req_proc_release *)xfer->xfer_buf;
3056 req->processor_id = proc_id;
3057
3058 ret = ti_sci_do_xfer(info, xfer);
3059 if (ret) {
3060 dev_err(dev, "Mbox send fail %d\n", ret);
3061 goto fail;
3062 }
3063
3064 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
3065
3066 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
3067
3068 fail:
3069 ti_sci_put_one_xfer(&info->minfo, xfer);
3070
3071 return ret;
3072 }
3073
3074 /**
3075 * ti_sci_cmd_proc_handover() - Command to handover a physical processor
3076 * control to a host in the processor's access
3077 * control list.
3078 * @handle: Pointer to TI SCI handle
3079 * @proc_id: Processor ID this request is for
3080 * @host_id: Host ID to get the control of the processor
3081 *
3082 * Return: 0 if all went well, else returns appropriate error value.
3083 */
ti_sci_cmd_proc_handover(const struct ti_sci_handle * handle,u8 proc_id,u8 host_id)3084 static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle,
3085 u8 proc_id, u8 host_id)
3086 {
3087 struct ti_sci_msg_req_proc_handover *req;
3088 struct ti_sci_msg_hdr *resp;
3089 struct ti_sci_info *info;
3090 struct ti_sci_xfer *xfer;
3091 struct device *dev;
3092 int ret = 0;
3093
3094 if (!handle)
3095 return -EINVAL;
3096 if (IS_ERR(handle))
3097 return PTR_ERR(handle);
3098
3099 info = handle_to_ti_sci_info(handle);
3100 dev = info->dev;
3101
3102 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_HANDOVER,
3103 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
3104 sizeof(*req), sizeof(*resp));
3105 if (IS_ERR(xfer)) {
3106 ret = PTR_ERR(xfer);
3107 dev_err(dev, "Message alloc failed(%d)\n", ret);
3108 return ret;
3109 }
3110 req = (struct ti_sci_msg_req_proc_handover *)xfer->xfer_buf;
3111 req->processor_id = proc_id;
3112 req->host_id = host_id;
3113
3114 ret = ti_sci_do_xfer(info, xfer);
3115 if (ret) {
3116 dev_err(dev, "Mbox send fail %d\n", ret);
3117 goto fail;
3118 }
3119
3120 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
3121
3122 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
3123
3124 fail:
3125 ti_sci_put_one_xfer(&info->minfo, xfer);
3126
3127 return ret;
3128 }
3129
3130 /**
3131 * ti_sci_cmd_proc_set_config() - Command to set the processor boot
3132 * configuration flags
3133 * @handle: Pointer to TI SCI handle
3134 * @proc_id: Processor ID this request is for
3135 * @bootvector: Processor Boot vector (start address)
3136 * @config_flags_set: Configuration flags to be set
3137 * @config_flags_clear: Configuration flags to be cleared.
3138 *
3139 * Return: 0 if all went well, else returns appropriate error value.
3140 */
ti_sci_cmd_proc_set_config(const struct ti_sci_handle * handle,u8 proc_id,u64 bootvector,u32 config_flags_set,u32 config_flags_clear)3141 static int ti_sci_cmd_proc_set_config(const struct ti_sci_handle *handle,
3142 u8 proc_id, u64 bootvector,
3143 u32 config_flags_set,
3144 u32 config_flags_clear)
3145 {
3146 struct ti_sci_msg_req_set_config *req;
3147 struct ti_sci_msg_hdr *resp;
3148 struct ti_sci_info *info;
3149 struct ti_sci_xfer *xfer;
3150 struct device *dev;
3151 int ret = 0;
3152
3153 if (!handle)
3154 return -EINVAL;
3155 if (IS_ERR(handle))
3156 return PTR_ERR(handle);
3157
3158 info = handle_to_ti_sci_info(handle);
3159 dev = info->dev;
3160
3161 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CONFIG,
3162 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
3163 sizeof(*req), sizeof(*resp));
3164 if (IS_ERR(xfer)) {
3165 ret = PTR_ERR(xfer);
3166 dev_err(dev, "Message alloc failed(%d)\n", ret);
3167 return ret;
3168 }
3169 req = (struct ti_sci_msg_req_set_config *)xfer->xfer_buf;
3170 req->processor_id = proc_id;
3171 req->bootvector_low = bootvector & TI_SCI_ADDR_LOW_MASK;
3172 req->bootvector_high = (bootvector & TI_SCI_ADDR_HIGH_MASK) >>
3173 TI_SCI_ADDR_HIGH_SHIFT;
3174 req->config_flags_set = config_flags_set;
3175 req->config_flags_clear = config_flags_clear;
3176
3177 ret = ti_sci_do_xfer(info, xfer);
3178 if (ret) {
3179 dev_err(dev, "Mbox send fail %d\n", ret);
3180 goto fail;
3181 }
3182
3183 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
3184
3185 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
3186
3187 fail:
3188 ti_sci_put_one_xfer(&info->minfo, xfer);
3189
3190 return ret;
3191 }
3192
3193 /**
3194 * ti_sci_cmd_proc_set_control() - Command to set the processor boot
3195 * control flags
3196 * @handle: Pointer to TI SCI handle
3197 * @proc_id: Processor ID this request is for
3198 * @control_flags_set: Control flags to be set
3199 * @control_flags_clear: Control flags to be cleared
3200 *
3201 * Return: 0 if all went well, else returns appropriate error value.
3202 */
ti_sci_cmd_proc_set_control(const struct ti_sci_handle * handle,u8 proc_id,u32 control_flags_set,u32 control_flags_clear)3203 static int ti_sci_cmd_proc_set_control(const struct ti_sci_handle *handle,
3204 u8 proc_id, u32 control_flags_set,
3205 u32 control_flags_clear)
3206 {
3207 struct ti_sci_msg_req_set_ctrl *req;
3208 struct ti_sci_msg_hdr *resp;
3209 struct ti_sci_info *info;
3210 struct ti_sci_xfer *xfer;
3211 struct device *dev;
3212 int ret = 0;
3213
3214 if (!handle)
3215 return -EINVAL;
3216 if (IS_ERR(handle))
3217 return PTR_ERR(handle);
3218
3219 info = handle_to_ti_sci_info(handle);
3220 dev = info->dev;
3221
3222 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CTRL,
3223 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
3224 sizeof(*req), sizeof(*resp));
3225 if (IS_ERR(xfer)) {
3226 ret = PTR_ERR(xfer);
3227 dev_err(dev, "Message alloc failed(%d)\n", ret);
3228 return ret;
3229 }
3230 req = (struct ti_sci_msg_req_set_ctrl *)xfer->xfer_buf;
3231 req->processor_id = proc_id;
3232 req->control_flags_set = control_flags_set;
3233 req->control_flags_clear = control_flags_clear;
3234
3235 ret = ti_sci_do_xfer(info, xfer);
3236 if (ret) {
3237 dev_err(dev, "Mbox send fail %d\n", ret);
3238 goto fail;
3239 }
3240
3241 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
3242
3243 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
3244
3245 fail:
3246 ti_sci_put_one_xfer(&info->minfo, xfer);
3247
3248 return ret;
3249 }
3250
3251 /**
3252 * ti_sci_cmd_proc_get_status() - Command to get the processor boot status
3253 * @handle: Pointer to TI SCI handle
3254 * @proc_id: Processor ID this request is for
3255 * @bv: Processor Boot vector (start address)
3256 * @cfg_flags: Processor specific configuration flags
3257 * @ctrl_flags: Processor specific control flags
3258 * @sts_flags: Processor specific status flags
3259 *
3260 * Return: 0 if all went well, else returns appropriate error value.
3261 */
ti_sci_cmd_proc_get_status(const struct ti_sci_handle * handle,u8 proc_id,u64 * bv,u32 * cfg_flags,u32 * ctrl_flags,u32 * sts_flags)3262 static int ti_sci_cmd_proc_get_status(const struct ti_sci_handle *handle,
3263 u8 proc_id, u64 *bv, u32 *cfg_flags,
3264 u32 *ctrl_flags, u32 *sts_flags)
3265 {
3266 struct ti_sci_msg_resp_get_status *resp;
3267 struct ti_sci_msg_req_get_status *req;
3268 struct ti_sci_info *info;
3269 struct ti_sci_xfer *xfer;
3270 struct device *dev;
3271 int ret = 0;
3272
3273 if (!handle)
3274 return -EINVAL;
3275 if (IS_ERR(handle))
3276 return PTR_ERR(handle);
3277
3278 info = handle_to_ti_sci_info(handle);
3279 dev = info->dev;
3280
3281 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_STATUS,
3282 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
3283 sizeof(*req), sizeof(*resp));
3284 if (IS_ERR(xfer)) {
3285 ret = PTR_ERR(xfer);
3286 dev_err(dev, "Message alloc failed(%d)\n", ret);
3287 return ret;
3288 }
3289 req = (struct ti_sci_msg_req_get_status *)xfer->xfer_buf;
3290 req->processor_id = proc_id;
3291
3292 ret = ti_sci_do_xfer(info, xfer);
3293 if (ret) {
3294 dev_err(dev, "Mbox send fail %d\n", ret);
3295 goto fail;
3296 }
3297
3298 resp = (struct ti_sci_msg_resp_get_status *)xfer->tx_message.buf;
3299
3300 if (!ti_sci_is_response_ack(resp)) {
3301 ret = -ENODEV;
3302 } else {
3303 *bv = (resp->bootvector_low & TI_SCI_ADDR_LOW_MASK) |
3304 (((u64)resp->bootvector_high << TI_SCI_ADDR_HIGH_SHIFT) &
3305 TI_SCI_ADDR_HIGH_MASK);
3306 *cfg_flags = resp->config_flags;
3307 *ctrl_flags = resp->control_flags;
3308 *sts_flags = resp->status_flags;
3309 }
3310
3311 fail:
3312 ti_sci_put_one_xfer(&info->minfo, xfer);
3313
3314 return ret;
3315 }
3316
3317 /*
3318 * ti_sci_setup_ops() - Setup the operations structures
3319 * @info: pointer to TISCI pointer
3320 */
ti_sci_setup_ops(struct ti_sci_info * info)3321 static void ti_sci_setup_ops(struct ti_sci_info *info)
3322 {
3323 struct ti_sci_ops *ops = &info->handle.ops;
3324 struct ti_sci_core_ops *core_ops = &ops->core_ops;
3325 struct ti_sci_dev_ops *dops = &ops->dev_ops;
3326 struct ti_sci_clk_ops *cops = &ops->clk_ops;
3327 struct ti_sci_pm_ops *pmops = &ops->pm_ops;
3328 struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;
3329 struct ti_sci_rm_irq_ops *iops = &ops->rm_irq_ops;
3330 struct ti_sci_rm_ringacc_ops *rops = &ops->rm_ring_ops;
3331 struct ti_sci_rm_psil_ops *psilops = &ops->rm_psil_ops;
3332 struct ti_sci_rm_udmap_ops *udmap_ops = &ops->rm_udmap_ops;
3333 struct ti_sci_proc_ops *pops = &ops->proc_ops;
3334
3335 core_ops->reboot_device = ti_sci_cmd_core_reboot;
3336
3337 dops->get_device = ti_sci_cmd_get_device;
3338 dops->get_device_exclusive = ti_sci_cmd_get_device_exclusive;
3339 dops->idle_device = ti_sci_cmd_idle_device;
3340 dops->idle_device_exclusive = ti_sci_cmd_idle_device_exclusive;
3341 dops->put_device = ti_sci_cmd_put_device;
3342
3343 dops->is_valid = ti_sci_cmd_dev_is_valid;
3344 dops->get_context_loss_count = ti_sci_cmd_dev_get_clcnt;
3345 dops->is_idle = ti_sci_cmd_dev_is_idle;
3346 dops->is_stop = ti_sci_cmd_dev_is_stop;
3347 dops->is_on = ti_sci_cmd_dev_is_on;
3348 dops->is_transitioning = ti_sci_cmd_dev_is_trans;
3349 dops->set_device_resets = ti_sci_cmd_set_device_resets;
3350 dops->get_device_resets = ti_sci_cmd_get_device_resets;
3351
3352 cops->get_clock = ti_sci_cmd_get_clock;
3353 cops->idle_clock = ti_sci_cmd_idle_clock;
3354 cops->put_clock = ti_sci_cmd_put_clock;
3355 cops->is_auto = ti_sci_cmd_clk_is_auto;
3356 cops->is_on = ti_sci_cmd_clk_is_on;
3357 cops->is_off = ti_sci_cmd_clk_is_off;
3358
3359 cops->set_parent = ti_sci_cmd_clk_set_parent;
3360 cops->get_parent = ti_sci_cmd_clk_get_parent;
3361 cops->get_num_parents = ti_sci_cmd_clk_get_num_parents;
3362
3363 cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq;
3364 cops->set_freq = ti_sci_cmd_clk_set_freq;
3365 cops->get_freq = ti_sci_cmd_clk_get_freq;
3366
3367 if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
3368 pr_debug("detected DM managed LPM in fw_caps\n");
3369 pmops->lpm_wake_reason = ti_sci_msg_cmd_lpm_wake_reason;
3370 pmops->set_device_constraint = ti_sci_cmd_set_device_constraint;
3371 pmops->set_latency_constraint = ti_sci_cmd_set_latency_constraint;
3372 }
3373
3374 rm_core_ops->get_range = ti_sci_cmd_get_resource_range;
3375 rm_core_ops->get_range_from_shost =
3376 ti_sci_cmd_get_resource_range_from_shost;
3377
3378 iops->set_irq = ti_sci_cmd_set_irq;
3379 iops->set_event_map = ti_sci_cmd_set_event_map;
3380 iops->free_irq = ti_sci_cmd_free_irq;
3381 iops->free_event_map = ti_sci_cmd_free_event_map;
3382
3383 rops->set_cfg = ti_sci_cmd_rm_ring_cfg;
3384
3385 psilops->pair = ti_sci_cmd_rm_psil_pair;
3386 psilops->unpair = ti_sci_cmd_rm_psil_unpair;
3387
3388 udmap_ops->tx_ch_cfg = ti_sci_cmd_rm_udmap_tx_ch_cfg;
3389 udmap_ops->rx_ch_cfg = ti_sci_cmd_rm_udmap_rx_ch_cfg;
3390 udmap_ops->rx_flow_cfg = ti_sci_cmd_rm_udmap_rx_flow_cfg;
3391
3392 pops->request = ti_sci_cmd_proc_request;
3393 pops->release = ti_sci_cmd_proc_release;
3394 pops->handover = ti_sci_cmd_proc_handover;
3395 pops->set_config = ti_sci_cmd_proc_set_config;
3396 pops->set_control = ti_sci_cmd_proc_set_control;
3397 pops->get_status = ti_sci_cmd_proc_get_status;
3398 }
3399
3400 /**
3401 * ti_sci_get_handle() - Get the TI SCI handle for a device
3402 * @dev: Pointer to device for which we want SCI handle
3403 *
3404 * NOTE: The function does not track individual clients of the framework
3405 * and is expected to be maintained by caller of TI SCI protocol library.
3406 * ti_sci_put_handle must be balanced with successful ti_sci_get_handle
3407 * Return: pointer to handle if successful, else:
3408 * -EPROBE_DEFER if the instance is not ready
3409 * -ENODEV if the required node handler is missing
3410 * -EINVAL if invalid conditions are encountered.
3411 */
ti_sci_get_handle(struct device * dev)3412 const struct ti_sci_handle *ti_sci_get_handle(struct device *dev)
3413 {
3414 struct device_node *ti_sci_np;
3415 struct ti_sci_handle *handle = NULL;
3416 struct ti_sci_info *info;
3417
3418 if (!dev) {
3419 pr_err("I need a device pointer\n");
3420 return ERR_PTR(-EINVAL);
3421 }
3422 ti_sci_np = of_get_parent(dev->of_node);
3423 if (!ti_sci_np) {
3424 dev_err(dev, "No OF information\n");
3425 return ERR_PTR(-EINVAL);
3426 }
3427
3428 mutex_lock(&ti_sci_list_mutex);
3429 list_for_each_entry(info, &ti_sci_list, node) {
3430 if (ti_sci_np == info->dev->of_node) {
3431 handle = &info->handle;
3432 info->users++;
3433 break;
3434 }
3435 }
3436 mutex_unlock(&ti_sci_list_mutex);
3437 of_node_put(ti_sci_np);
3438
3439 if (!handle)
3440 return ERR_PTR(-EPROBE_DEFER);
3441
3442 return handle;
3443 }
3444 EXPORT_SYMBOL_GPL(ti_sci_get_handle);
3445
3446 /**
3447 * ti_sci_put_handle() - Release the handle acquired by ti_sci_get_handle
3448 * @handle: Handle acquired by ti_sci_get_handle
3449 *
3450 * NOTE: The function does not track individual clients of the framework
3451 * and is expected to be maintained by caller of TI SCI protocol library.
3452 * ti_sci_put_handle must be balanced with successful ti_sci_get_handle
3453 *
3454 * Return: 0 is successfully released
3455 * if an error pointer was passed, it returns the error value back,
3456 * if null was passed, it returns -EINVAL;
3457 */
ti_sci_put_handle(const struct ti_sci_handle * handle)3458 int ti_sci_put_handle(const struct ti_sci_handle *handle)
3459 {
3460 struct ti_sci_info *info;
3461
3462 if (IS_ERR(handle))
3463 return PTR_ERR(handle);
3464 if (!handle)
3465 return -EINVAL;
3466
3467 info = handle_to_ti_sci_info(handle);
3468 mutex_lock(&ti_sci_list_mutex);
3469 if (!WARN_ON(!info->users))
3470 info->users--;
3471 mutex_unlock(&ti_sci_list_mutex);
3472
3473 return 0;
3474 }
3475 EXPORT_SYMBOL_GPL(ti_sci_put_handle);
3476
devm_ti_sci_release(struct device * dev,void * res)3477 static void devm_ti_sci_release(struct device *dev, void *res)
3478 {
3479 const struct ti_sci_handle **ptr = res;
3480 const struct ti_sci_handle *handle = *ptr;
3481 int ret;
3482
3483 ret = ti_sci_put_handle(handle);
3484 if (ret)
3485 dev_err(dev, "failed to put handle %d\n", ret);
3486 }
3487
3488 /**
3489 * devm_ti_sci_get_handle() - Managed get handle
3490 * @dev: device for which we want SCI handle for.
3491 *
3492 * NOTE: This releases the handle once the device resources are
3493 * no longer needed. MUST NOT BE released with ti_sci_put_handle.
3494 * The function does not track individual clients of the framework
3495 * and is expected to be maintained by caller of TI SCI protocol library.
3496 *
3497 * Return: 0 if all went fine, else corresponding error.
3498 */
devm_ti_sci_get_handle(struct device * dev)3499 const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev)
3500 {
3501 const struct ti_sci_handle **ptr;
3502 const struct ti_sci_handle *handle;
3503
3504 ptr = devres_alloc(devm_ti_sci_release, sizeof(*ptr), GFP_KERNEL);
3505 if (!ptr)
3506 return ERR_PTR(-ENOMEM);
3507 handle = ti_sci_get_handle(dev);
3508
3509 if (!IS_ERR(handle)) {
3510 *ptr = handle;
3511 devres_add(dev, ptr);
3512 } else {
3513 devres_free(ptr);
3514 }
3515
3516 return handle;
3517 }
3518 EXPORT_SYMBOL_GPL(devm_ti_sci_get_handle);
3519
3520 /**
3521 * ti_sci_get_by_phandle() - Get the TI SCI handle using DT phandle
3522 * @np: device node
3523 * @property: property name containing phandle on TISCI node
3524 *
3525 * NOTE: The function does not track individual clients of the framework
3526 * and is expected to be maintained by caller of TI SCI protocol library.
3527 * ti_sci_put_handle must be balanced with successful ti_sci_get_by_phandle
3528 * Return: pointer to handle if successful, else:
3529 * -EPROBE_DEFER if the instance is not ready
3530 * -ENODEV if the required node handler is missing
3531 * -EINVAL if invalid conditions are encountered.
3532 */
ti_sci_get_by_phandle(struct device_node * np,const char * property)3533 const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np,
3534 const char *property)
3535 {
3536 struct ti_sci_handle *handle = NULL;
3537 struct device_node *ti_sci_np;
3538 struct ti_sci_info *info;
3539
3540 if (!np) {
3541 pr_err("I need a device pointer\n");
3542 return ERR_PTR(-EINVAL);
3543 }
3544
3545 ti_sci_np = of_parse_phandle(np, property, 0);
3546 if (!ti_sci_np)
3547 return ERR_PTR(-ENODEV);
3548
3549 mutex_lock(&ti_sci_list_mutex);
3550 list_for_each_entry(info, &ti_sci_list, node) {
3551 if (ti_sci_np == info->dev->of_node) {
3552 handle = &info->handle;
3553 info->users++;
3554 break;
3555 }
3556 }
3557 mutex_unlock(&ti_sci_list_mutex);
3558 of_node_put(ti_sci_np);
3559
3560 if (!handle)
3561 return ERR_PTR(-EPROBE_DEFER);
3562
3563 return handle;
3564 }
3565 EXPORT_SYMBOL_GPL(ti_sci_get_by_phandle);
3566
3567 /**
3568 * devm_ti_sci_get_by_phandle() - Managed get handle using phandle
3569 * @dev: Device pointer requesting TISCI handle
3570 * @property: property name containing phandle on TISCI node
3571 *
3572 * NOTE: This releases the handle once the device resources are
3573 * no longer needed. MUST NOT BE released with ti_sci_put_handle.
3574 * The function does not track individual clients of the framework
3575 * and is expected to be maintained by caller of TI SCI protocol library.
3576 *
3577 * Return: 0 if all went fine, else corresponding error.
3578 */
devm_ti_sci_get_by_phandle(struct device * dev,const char * property)3579 const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev,
3580 const char *property)
3581 {
3582 const struct ti_sci_handle *handle;
3583 const struct ti_sci_handle **ptr;
3584
3585 ptr = devres_alloc(devm_ti_sci_release, sizeof(*ptr), GFP_KERNEL);
3586 if (!ptr)
3587 return ERR_PTR(-ENOMEM);
3588 handle = ti_sci_get_by_phandle(dev_of_node(dev), property);
3589
3590 if (!IS_ERR(handle)) {
3591 *ptr = handle;
3592 devres_add(dev, ptr);
3593 } else {
3594 devres_free(ptr);
3595 }
3596
3597 return handle;
3598 }
3599 EXPORT_SYMBOL_GPL(devm_ti_sci_get_by_phandle);
3600
3601 /**
3602 * ti_sci_get_free_resource() - Get a free resource from TISCI resource.
3603 * @res: Pointer to the TISCI resource
3604 *
3605 * Return: resource num if all went ok else TI_SCI_RESOURCE_NULL.
3606 */
ti_sci_get_free_resource(struct ti_sci_resource * res)3607 u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
3608 {
3609 unsigned long flags;
3610 u16 set, free_bit;
3611
3612 raw_spin_lock_irqsave(&res->lock, flags);
3613 for (set = 0; set < res->sets; set++) {
3614 struct ti_sci_resource_desc *desc = &res->desc[set];
3615 int res_count = desc->num + desc->num_sec;
3616
3617 free_bit = find_first_zero_bit(desc->res_map, res_count);
3618 if (free_bit != res_count) {
3619 __set_bit(free_bit, desc->res_map);
3620 raw_spin_unlock_irqrestore(&res->lock, flags);
3621
3622 if (desc->num && free_bit < desc->num)
3623 return desc->start + free_bit;
3624 else
3625 return desc->start_sec + free_bit;
3626 }
3627 }
3628 raw_spin_unlock_irqrestore(&res->lock, flags);
3629
3630 return TI_SCI_RESOURCE_NULL;
3631 }
3632 EXPORT_SYMBOL_GPL(ti_sci_get_free_resource);
3633
3634 /**
3635 * ti_sci_release_resource() - Release a resource from TISCI resource.
3636 * @res: Pointer to the TISCI resource
3637 * @id: Resource id to be released.
3638 */
ti_sci_release_resource(struct ti_sci_resource * res,u16 id)3639 void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
3640 {
3641 unsigned long flags;
3642 u16 set;
3643
3644 raw_spin_lock_irqsave(&res->lock, flags);
3645 for (set = 0; set < res->sets; set++) {
3646 struct ti_sci_resource_desc *desc = &res->desc[set];
3647
3648 if (desc->num && desc->start <= id &&
3649 (desc->start + desc->num) > id)
3650 __clear_bit(id - desc->start, desc->res_map);
3651 else if (desc->num_sec && desc->start_sec <= id &&
3652 (desc->start_sec + desc->num_sec) > id)
3653 __clear_bit(id - desc->start_sec, desc->res_map);
3654 }
3655 raw_spin_unlock_irqrestore(&res->lock, flags);
3656 }
3657 EXPORT_SYMBOL_GPL(ti_sci_release_resource);
3658
3659 /**
3660 * ti_sci_get_num_resources() - Get the number of resources in TISCI resource
3661 * @res: Pointer to the TISCI resource
3662 *
3663 * Return: Total number of available resources.
3664 */
ti_sci_get_num_resources(struct ti_sci_resource * res)3665 u32 ti_sci_get_num_resources(struct ti_sci_resource *res)
3666 {
3667 u32 set, count = 0;
3668
3669 for (set = 0; set < res->sets; set++)
3670 count += res->desc[set].num + res->desc[set].num_sec;
3671
3672 return count;
3673 }
3674 EXPORT_SYMBOL_GPL(ti_sci_get_num_resources);
3675
3676 /**
3677 * devm_ti_sci_get_resource_sets() - Get a TISCI resources assigned to a device
3678 * @handle: TISCI handle
3679 * @dev: Device pointer to which the resource is assigned
3680 * @dev_id: TISCI device id to which the resource is assigned
3681 * @sub_types: Array of sub_types assigned corresponding to device
3682 * @sets: Number of sub_types
3683 *
3684 * Return: Pointer to ti_sci_resource if all went well else appropriate
3685 * error pointer.
3686 */
3687 static struct ti_sci_resource *
devm_ti_sci_get_resource_sets(const struct ti_sci_handle * handle,struct device * dev,u32 dev_id,u32 * sub_types,u32 sets)3688 devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle,
3689 struct device *dev, u32 dev_id, u32 *sub_types,
3690 u32 sets)
3691 {
3692 struct ti_sci_resource *res;
3693 bool valid_set = false;
3694 int i, ret, res_count;
3695
3696 res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
3697 if (!res)
3698 return ERR_PTR(-ENOMEM);
3699
3700 res->sets = sets;
3701 res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc),
3702 GFP_KERNEL);
3703 if (!res->desc)
3704 return ERR_PTR(-ENOMEM);
3705
3706 for (i = 0; i < res->sets; i++) {
3707 ret = handle->ops.rm_core_ops.get_range(handle, dev_id,
3708 sub_types[i],
3709 &res->desc[i]);
3710 if (ret) {
3711 dev_dbg(dev, "dev = %d subtype %d not allocated for this host\n",
3712 dev_id, sub_types[i]);
3713 memset(&res->desc[i], 0, sizeof(res->desc[i]));
3714 continue;
3715 }
3716
3717 dev_dbg(dev, "dev/sub_type: %d/%d, start/num: %d/%d | %d/%d\n",
3718 dev_id, sub_types[i], res->desc[i].start,
3719 res->desc[i].num, res->desc[i].start_sec,
3720 res->desc[i].num_sec);
3721
3722 valid_set = true;
3723 res_count = res->desc[i].num + res->desc[i].num_sec;
3724 res->desc[i].res_map = devm_bitmap_zalloc(dev, res_count,
3725 GFP_KERNEL);
3726 if (!res->desc[i].res_map)
3727 return ERR_PTR(-ENOMEM);
3728 }
3729 raw_spin_lock_init(&res->lock);
3730
3731 if (valid_set)
3732 return res;
3733
3734 return ERR_PTR(-EINVAL);
3735 }
3736
3737 /**
3738 * devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to a device
3739 * @handle: TISCI handle
3740 * @dev: Device pointer to which the resource is assigned
3741 * @dev_id: TISCI device id to which the resource is assigned
3742 * @of_prop: property name by which the resource are represented
3743 *
3744 * Return: Pointer to ti_sci_resource if all went well else appropriate
3745 * error pointer.
3746 */
3747 struct ti_sci_resource *
devm_ti_sci_get_of_resource(const struct ti_sci_handle * handle,struct device * dev,u32 dev_id,char * of_prop)3748 devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
3749 struct device *dev, u32 dev_id, char *of_prop)
3750 {
3751 struct ti_sci_resource *res;
3752 u32 *sub_types;
3753 int sets;
3754
3755 sets = of_property_count_elems_of_size(dev_of_node(dev), of_prop,
3756 sizeof(u32));
3757 if (sets < 0) {
3758 dev_err(dev, "%s resource type ids not available\n", of_prop);
3759 return ERR_PTR(sets);
3760 }
3761
3762 sub_types = kcalloc(sets, sizeof(*sub_types), GFP_KERNEL);
3763 if (!sub_types)
3764 return ERR_PTR(-ENOMEM);
3765
3766 of_property_read_u32_array(dev_of_node(dev), of_prop, sub_types, sets);
3767 res = devm_ti_sci_get_resource_sets(handle, dev, dev_id, sub_types,
3768 sets);
3769
3770 kfree(sub_types);
3771 return res;
3772 }
3773 EXPORT_SYMBOL_GPL(devm_ti_sci_get_of_resource);
3774
3775 /**
3776 * devm_ti_sci_get_resource() - Get a resource range assigned to the device
3777 * @handle: TISCI handle
3778 * @dev: Device pointer to which the resource is assigned
3779 * @dev_id: TISCI device id to which the resource is assigned
3780 * @sub_type: TISCI resource subytpe representing the resource.
3781 *
3782 * Return: Pointer to ti_sci_resource if all went well else appropriate
3783 * error pointer.
3784 */
3785 struct ti_sci_resource *
devm_ti_sci_get_resource(const struct ti_sci_handle * handle,struct device * dev,u32 dev_id,u32 sub_type)3786 devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev,
3787 u32 dev_id, u32 sub_type)
3788 {
3789 return devm_ti_sci_get_resource_sets(handle, dev, dev_id, &sub_type, 1);
3790 }
3791 EXPORT_SYMBOL_GPL(devm_ti_sci_get_resource);
3792
3793 /*
3794 * Iterate all device nodes that have a wakeup-source property and check if one
3795 * of the possible phandles points to a Partial-IO system state. If it
3796 * does resolve the device node to an actual device and check if wakeup is
3797 * enabled.
3798 */
ti_sci_partial_io_wakeup_enabled(struct ti_sci_info * info)3799 static bool ti_sci_partial_io_wakeup_enabled(struct ti_sci_info *info)
3800 {
3801 struct device_node *wakeup_node = NULL;
3802
3803 for_each_node_with_property(wakeup_node, "wakeup-source") {
3804 struct of_phandle_iterator it;
3805 int err;
3806
3807 of_for_each_phandle(&it, err, wakeup_node, "wakeup-source", NULL, 0) {
3808 struct platform_device *pdev;
3809 bool may_wakeup;
3810
3811 /*
3812 * Continue if idle-state-name is not off-wake. Return
3813 * value is the index of the string which should be 0 if
3814 * off-wake is present.
3815 */
3816 if (of_property_match_string(it.node, "idle-state-name", "off-wake"))
3817 continue;
3818
3819 pdev = of_find_device_by_node(wakeup_node);
3820 if (!pdev)
3821 continue;
3822
3823 may_wakeup = device_may_wakeup(&pdev->dev);
3824 put_device(&pdev->dev);
3825
3826 if (may_wakeup) {
3827 dev_dbg(info->dev, "%pOF identified as wakeup source for Partial-IO\n",
3828 wakeup_node);
3829 of_node_put(it.node);
3830 of_node_put(wakeup_node);
3831 return true;
3832 }
3833 }
3834 }
3835
3836 return false;
3837 }
3838
ti_sci_sys_off_handler(struct sys_off_data * data)3839 static int ti_sci_sys_off_handler(struct sys_off_data *data)
3840 {
3841 struct ti_sci_info *info = data->cb_data;
3842 const struct ti_sci_handle *handle = &info->handle;
3843 bool enter_partial_io = ti_sci_partial_io_wakeup_enabled(info);
3844 int ret;
3845
3846 if (!enter_partial_io)
3847 return NOTIFY_DONE;
3848
3849 dev_info(info->dev, "Entering Partial-IO because a powered wakeup-enabled device was found.\n");
3850
3851 ret = ti_sci_cmd_prepare_sleep(handle, TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO, 0, 0, 0);
3852 if (ret) {
3853 dev_err(info->dev,
3854 "Failed to enter Partial-IO %pe, trying to do an emergency restart\n",
3855 ERR_PTR(ret));
3856 emergency_restart();
3857 }
3858
3859 mdelay(5000);
3860 emergency_restart();
3861
3862 return NOTIFY_DONE;
3863 }
3864
tisci_reboot_handler(struct sys_off_data * data)3865 static int tisci_reboot_handler(struct sys_off_data *data)
3866 {
3867 struct ti_sci_info *info = data->cb_data;
3868 const struct ti_sci_handle *handle = &info->handle;
3869
3870 ti_sci_cmd_core_reboot(handle);
3871
3872 /* call fail OR pass, we should not be here in the first place */
3873 return NOTIFY_BAD;
3874 }
3875
ti_sci_prepare_system_suspend(struct ti_sci_info * info)3876 static int ti_sci_prepare_system_suspend(struct ti_sci_info *info)
3877 {
3878 /*
3879 * Map and validate the target Linux suspend state to TISCI LPM.
3880 * Default is to let Device Manager select the low power mode.
3881 */
3882 switch (pm_suspend_target_state) {
3883 case PM_SUSPEND_MEM:
3884 if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
3885 /*
3886 * For the DM_MANAGED mode the context is reserved for
3887 * internal use and can be 0
3888 */
3889 return ti_sci_cmd_prepare_sleep(&info->handle,
3890 TISCI_MSG_VALUE_SLEEP_MODE_DM_MANAGED,
3891 0, 0, 0);
3892 } else if (info->fw_caps & MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED) {
3893 /* Nothing to do in the BOARDCFG_MANAGED mode */
3894 return 0;
3895 } else {
3896 /* DM Managed and BoardCfg Managed are not supported by the firmware. */
3897 dev_err(info->dev, "Suspend to memory is not supported by the firmware\n");
3898 return -EOPNOTSUPP;
3899 }
3900 break;
3901 default:
3902 /*
3903 * Do not fail if we don't have action to take for a
3904 * specific suspend mode.
3905 */
3906 return 0;
3907 }
3908 }
3909
ti_sci_suspend(struct device * dev)3910 static int ti_sci_suspend(struct device *dev)
3911 {
3912 struct ti_sci_info *info = dev_get_drvdata(dev);
3913 struct device *cpu_dev, *cpu_dev_max = NULL;
3914 s32 val, cpu_lat = 0;
3915 u16 cpu_lat_ms;
3916 int i, ret;
3917
3918 if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
3919 for_each_possible_cpu(i) {
3920 cpu_dev = get_cpu_device(i);
3921 val = dev_pm_qos_read_value(cpu_dev, DEV_PM_QOS_RESUME_LATENCY);
3922 if (val != PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) {
3923 cpu_lat = max(cpu_lat, val);
3924 cpu_dev_max = cpu_dev;
3925 }
3926 }
3927 if (cpu_dev_max) {
3928 /*
3929 * PM QoS latency unit is usecs, device manager uses msecs.
3930 * Convert to msecs and round down for device manager.
3931 */
3932 cpu_lat_ms = cpu_lat / USEC_PER_MSEC;
3933 dev_dbg(cpu_dev_max, "%s: sending max CPU latency=%u ms\n", __func__,
3934 cpu_lat_ms);
3935 ret = ti_sci_cmd_set_latency_constraint(&info->handle,
3936 cpu_lat_ms,
3937 TISCI_MSG_CONSTRAINT_SET);
3938 if (ret)
3939 return ret;
3940 }
3941 }
3942
3943 ret = ti_sci_prepare_system_suspend(info);
3944 if (ret)
3945 return ret;
3946
3947 return 0;
3948 }
3949
ti_sci_suspend_noirq(struct device * dev)3950 static int ti_sci_suspend_noirq(struct device *dev)
3951 {
3952 struct ti_sci_info *info = dev_get_drvdata(dev);
3953 int ret = 0;
3954
3955 if (info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION) {
3956 ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_ENABLE);
3957 if (ret)
3958 return ret;
3959 }
3960
3961 return 0;
3962 }
3963
ti_sci_resume_noirq(struct device * dev)3964 static int ti_sci_resume_noirq(struct device *dev)
3965 {
3966 struct ti_sci_info *info = dev_get_drvdata(dev);
3967 struct ti_sci_msg_req_manage_irq *irq_desc;
3968 struct ti_sci_irq *irq;
3969 struct hlist_node *tmp_node;
3970 int ret = 0, err = 0, i;
3971 u32 source;
3972 u64 time;
3973 u8 pin;
3974 u8 mode;
3975
3976 if (info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION) {
3977 ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_DISABLE);
3978 if (ret)
3979 return ret;
3980 }
3981
3982 switch (pm_suspend_target_state) {
3983 case PM_SUSPEND_MEM:
3984 if (info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST) {
3985 hash_for_each_safe(info->irqs, i, tmp_node, irq, node) {
3986 irq_desc = &irq->desc;
3987 ret = ti_sci_manage_irq(&info->handle,
3988 irq_desc->valid_params,
3989 irq_desc->src_id,
3990 irq_desc->src_index,
3991 irq_desc->dst_id,
3992 irq_desc->dst_host_irq,
3993 irq_desc->ia_id,
3994 irq_desc->vint,
3995 irq_desc->global_event,
3996 irq_desc->vint_status_bit,
3997 irq_desc->secondary_host,
3998 TI_SCI_MSG_SET_IRQ);
3999 if (ret) {
4000 dev_err(dev, "failed to restore IRQ with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d, via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
4001 irq_desc->valid_params,
4002 irq_desc->src_id,
4003 irq_desc->src_index,
4004 irq_desc->dst_id,
4005 irq_desc->dst_host_irq,
4006 irq_desc->ia_id,
4007 irq_desc->vint,
4008 irq_desc->global_event,
4009 irq_desc->vint_status_bit);
4010 err = ret;
4011 }
4012 }
4013 }
4014
4015 if (info->fw_caps & MSG_FLAG_CAPS_LPM_CLK_CONTEXT_LOST)
4016 clk_restore_context();
4017 break;
4018 default:
4019 break;
4020 }
4021
4022 ret = ti_sci_msg_cmd_lpm_wake_reason(&info->handle, &source, &time, &pin, &mode);
4023 /* Do not fail to resume on error as the wake reason is not critical */
4024 if (!ret)
4025 dev_info(dev, "ti_sci: wakeup source:0x%x, pin:0x%x, mode:0x%x\n",
4026 source, pin, mode);
4027
4028 return err;
4029 }
4030
ti_sci_pm_complete(struct device * dev)4031 static void ti_sci_pm_complete(struct device *dev)
4032 {
4033 struct ti_sci_info *info = dev_get_drvdata(dev);
4034
4035 if (info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT) {
4036 if (ti_sci_cmd_lpm_abort(dev))
4037 dev_err(dev, "LPM clear selection failed.\n");
4038 }
4039 }
4040
4041 static const struct dev_pm_ops ti_sci_pm_ops = {
4042 .suspend = pm_sleep_ptr(ti_sci_suspend),
4043 .suspend_noirq = pm_sleep_ptr(ti_sci_suspend_noirq),
4044 .resume_noirq = pm_sleep_ptr(ti_sci_resume_noirq),
4045 .complete = pm_sleep_ptr(ti_sci_pm_complete),
4046 };
4047
4048 /* Description for K2G */
4049 static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
4050 .default_host_id = 2,
4051 /* Conservative duration */
4052 .max_rx_timeout_ms = 1000,
4053 /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
4054 .max_msgs = 20,
4055 .max_msg_size = 64,
4056 };
4057
4058 /* Description for AM654 */
4059 static const struct ti_sci_desc ti_sci_pmmc_am654_desc = {
4060 .default_host_id = 12,
4061 /* Conservative duration */
4062 .max_rx_timeout_ms = 10000,
4063 /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
4064 .max_msgs = 20,
4065 .max_msg_size = 60,
4066 };
4067
4068 static const struct of_device_id ti_sci_of_match[] = {
4069 {.compatible = "ti,k2g-sci", .data = &ti_sci_pmmc_k2g_desc},
4070 {.compatible = "ti,am654-sci", .data = &ti_sci_pmmc_am654_desc},
4071 { /* Sentinel */ },
4072 };
4073 MODULE_DEVICE_TABLE(of, ti_sci_of_match);
4074
ti_sci_probe(struct platform_device * pdev)4075 static int ti_sci_probe(struct platform_device *pdev)
4076 {
4077 struct device *dev = &pdev->dev;
4078 const struct ti_sci_desc *desc;
4079 struct ti_sci_xfer *xfer;
4080 struct ti_sci_info *info = NULL;
4081 struct ti_sci_xfers_info *minfo;
4082 struct mbox_client *cl;
4083 int ret = -EINVAL;
4084 int i;
4085 u32 h_id;
4086
4087 desc = device_get_match_data(dev);
4088
4089 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
4090 if (!info)
4091 return -ENOMEM;
4092
4093 info->dev = dev;
4094 info->desc = desc;
4095 ret = of_property_read_u32(dev->of_node, "ti,host-id", &h_id);
4096 /* if the property is not present in DT, use a default from desc */
4097 if (ret < 0) {
4098 info->host_id = info->desc->default_host_id;
4099 } else {
4100 if (!h_id) {
4101 dev_warn(dev, "Host ID 0 is reserved for firmware\n");
4102 info->host_id = info->desc->default_host_id;
4103 } else {
4104 info->host_id = h_id;
4105 }
4106 }
4107
4108 INIT_LIST_HEAD(&info->node);
4109 minfo = &info->minfo;
4110
4111 /*
4112 * Pre-allocate messages
4113 * NEVER allocate more than what we can indicate in hdr.seq
4114 * if we have data description bug, force a fix..
4115 */
4116 if (WARN_ON(desc->max_msgs >=
4117 1 << 8 * sizeof(((struct ti_sci_msg_hdr *)0)->seq)))
4118 return -EINVAL;
4119
4120 minfo->xfer_block = devm_kcalloc(dev,
4121 desc->max_msgs,
4122 sizeof(*minfo->xfer_block),
4123 GFP_KERNEL);
4124 if (!minfo->xfer_block)
4125 return -ENOMEM;
4126
4127 minfo->xfer_alloc_table = devm_bitmap_zalloc(dev,
4128 desc->max_msgs,
4129 GFP_KERNEL);
4130 if (!minfo->xfer_alloc_table)
4131 return -ENOMEM;
4132
4133 /* Pre-initialize the buffer pointer to pre-allocated buffers */
4134 for (i = 0, xfer = minfo->xfer_block; i < desc->max_msgs; i++, xfer++) {
4135 xfer->xfer_buf = devm_kcalloc(dev, 1, desc->max_msg_size,
4136 GFP_KERNEL);
4137 if (!xfer->xfer_buf)
4138 return -ENOMEM;
4139
4140 xfer->tx_message.buf = xfer->xfer_buf;
4141 init_completion(&xfer->done);
4142 }
4143
4144 ret = ti_sci_debugfs_create(pdev, info);
4145 if (ret)
4146 dev_warn(dev, "Failed to create debug file\n");
4147
4148 platform_set_drvdata(pdev, info);
4149
4150 cl = &info->cl;
4151 cl->dev = dev;
4152 cl->tx_block = false;
4153 cl->rx_callback = ti_sci_rx_callback;
4154 cl->knows_txdone = true;
4155
4156 spin_lock_init(&minfo->xfer_lock);
4157 sema_init(&minfo->sem_xfer_count, desc->max_msgs);
4158
4159 info->chan_rx = mbox_request_channel_byname(cl, "rx");
4160 if (IS_ERR(info->chan_rx)) {
4161 ret = PTR_ERR(info->chan_rx);
4162 goto out;
4163 }
4164
4165 info->chan_tx = mbox_request_channel_byname(cl, "tx");
4166 if (IS_ERR(info->chan_tx)) {
4167 ret = PTR_ERR(info->chan_tx);
4168 goto out;
4169 }
4170 ret = ti_sci_cmd_get_revision(info);
4171 if (ret) {
4172 dev_err(dev, "Unable to communicate with TISCI(%d)\n", ret);
4173 goto out;
4174 }
4175
4176 ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps);
4177 dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s%s%s%s\n",
4178 info->fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "",
4179 info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "",
4180 info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : "",
4181 info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "",
4182 info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : "",
4183 info->fw_caps & MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED ? " BoardConfig-Managed" : "",
4184 info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST ? " IRQ-Context-Lost" : "",
4185 info->fw_caps & MSG_FLAG_CAPS_LPM_CLK_CONTEXT_LOST ? " Clk-Context-Lost" : ""
4186 );
4187
4188 ti_sci_setup_ops(info);
4189
4190 ret = devm_register_restart_handler(dev, tisci_reboot_handler, info);
4191 if (ret) {
4192 dev_err(dev, "reboot registration fail(%d)\n", ret);
4193 goto out;
4194 }
4195
4196 if (info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO) {
4197 ret = devm_register_sys_off_handler(dev,
4198 SYS_OFF_MODE_POWER_OFF,
4199 SYS_OFF_PRIO_FIRMWARE,
4200 ti_sci_sys_off_handler,
4201 info);
4202 if (ret) {
4203 dev_err(dev, "Failed to register sys_off_handler %pe\n",
4204 ERR_PTR(ret));
4205 goto out;
4206 }
4207 }
4208
4209 dev_info(dev, "ABI: %d.%d (firmware rev 0x%04x '%s')\n",
4210 info->handle.version.abi_major, info->handle.version.abi_minor,
4211 info->handle.version.firmware_revision,
4212 info->handle.version.firmware_description);
4213
4214 mutex_lock(&ti_sci_list_mutex);
4215 list_add_tail(&info->node, &ti_sci_list);
4216 mutex_unlock(&ti_sci_list_mutex);
4217
4218 ret = devm_mutex_init(dev, &info->irq_lock);
4219 if (ret)
4220 goto out;
4221
4222 if (info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST)
4223 hash_init(info->irqs);
4224
4225 ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
4226 if (ret) {
4227 dev_err(dev, "platform_populate failed %pe\n", ERR_PTR(ret));
4228 of_platform_depopulate(dev);
4229 mutex_lock(&ti_sci_list_mutex);
4230 list_del(&info->node);
4231 mutex_unlock(&ti_sci_list_mutex);
4232 goto out;
4233 }
4234 return 0;
4235
4236 out:
4237 if (!IS_ERR(info->chan_tx))
4238 mbox_free_channel(info->chan_tx);
4239 if (!IS_ERR(info->chan_rx))
4240 mbox_free_channel(info->chan_rx);
4241 debugfs_remove(info->d);
4242 return ret;
4243 }
4244
4245 static struct platform_driver ti_sci_driver = {
4246 .probe = ti_sci_probe,
4247 .driver = {
4248 .name = "ti-sci",
4249 .of_match_table = ti_sci_of_match,
4250 .suppress_bind_attrs = true,
4251 .pm = &ti_sci_pm_ops,
4252 },
4253 };
4254 module_platform_driver(ti_sci_driver);
4255
4256 MODULE_LICENSE("GPL v2");
4257 MODULE_DESCRIPTION("TI System Control Interface(SCI) driver");
4258 MODULE_AUTHOR("Nishanth Menon");
4259 MODULE_ALIAS("platform:ti-sci");
4260