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