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