projects/linux·blob master · refs

1322 lines · 23.4 KiB

1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2014-2026 NVIDIA CORPORATION. All rights reserved.
4 */
5
6#include <linux/device.h>
7#include <linux/of.h>
8#include <linux/mm.h>
9
10#include <dt-bindings/memory/tegra114-mc.h>
11
12#include "mc.h"
13
14static const struct tegra_mc_client tegra114_mc_clients[] = {
15 {
16 .id = 0x00,
17 .name = "ptcr",
18 .swgroup = TEGRA_SWGROUP_PTC,
19 .regs = {
20 .la = {
21 .reg = 0x34c,
22 .shift = 0,
23 .mask = 0xff,
24 .def = 0x0,
25 },
26 },
27 }, {
28 .id = 0x01,
29 .name = "display0a",
30 .swgroup = TEGRA_SWGROUP_DC,
31 .regs = {
32 .smmu = {
33 .reg = 0x228,
34 .bit = 1,
35 },
36 .la = {
37 .reg = 0x2e8,
38 .shift = 0,
39 .mask = 0xff,
40 .def = 0x4e,
41 },
42 },
43 }, {
44 .id = 0x02,
45 .name = "display0ab",
46 .swgroup = TEGRA_SWGROUP_DCB,
47 .regs = {
48 .smmu = {
49 .reg = 0x228,
50 .bit = 2,
51 },
52 .la = {
53 .reg = 0x2f4,
54 .shift = 0,
55 .mask = 0xff,
56 .def = 0x4e,
57 },
58 },
59 }, {
60 .id = 0x03,
61 .name = "display0b",
62 .swgroup = TEGRA_SWGROUP_DC,
63 .regs = {
64 .smmu = {
65 .reg = 0x228,
66 .bit = 3,
67 },
68 .la = {
69 .reg = 0x2e8,
70 .shift = 16,
71 .mask = 0xff,
72 .def = 0x4e,
73 },
74 },
75 }, {
76 .id = 0x04,
77 .name = "display0bb",
78 .swgroup = TEGRA_SWGROUP_DCB,
79 .regs = {
80 .smmu = {
81 .reg = 0x228,
82 .bit = 4,
83 },
84 .la = {
85 .reg = 0x2f4,
86 .shift = 16,
87 .mask = 0xff,
88 .def = 0x4e,
89 },
90 },
91 }, {
92 .id = 0x05,
93 .name = "display0c",
94 .swgroup = TEGRA_SWGROUP_DC,
95 .regs = {
96 .smmu = {
97 .reg = 0x228,
98 .bit = 5,
99 },
100 .la = {
101 .reg = 0x2ec,
102 .shift = 0,
103 .mask = 0xff,
104 .def = 0x4e,
105 },
106 },
107 }, {
108 .id = 0x06,
109 .name = "display0cb",
110 .swgroup = TEGRA_SWGROUP_DCB,
111 .regs = {
112 .smmu = {
113 .reg = 0x228,
114 .bit = 6,
115 },
116 .la = {
117 .reg = 0x2f8,
118 .shift = 0,
119 .mask = 0xff,
120 .def = 0x4e,
121 },
122 },
123 }, {
124 .id = 0x09,
125 .name = "eppup",
126 .swgroup = TEGRA_SWGROUP_EPP,
127 .regs = {
128 .smmu = {
129 .reg = 0x228,
130 .bit = 9,
131 },
132 .la = {
133 .reg = 0x300,
134 .shift = 0,
135 .mask = 0xff,
136 .def = 0x33,
137 },
138 },
139 }, {
140 .id = 0x0a,
141 .name = "g2pr",
142 .swgroup = TEGRA_SWGROUP_G2,
143 .regs = {
144 .smmu = {
145 .reg = 0x228,
146 .bit = 10,
147 },
148 .la = {
149 .reg = 0x308,
150 .shift = 0,
151 .mask = 0xff,
152 .def = 0x09,
153 },
154 },
155 }, {
156 .id = 0x0b,
157 .name = "g2sr",
158 .swgroup = TEGRA_SWGROUP_G2,
159 .regs = {
160 .smmu = {
161 .reg = 0x228,
162 .bit = 11,
163 },
164 .la = {
165 .reg = 0x308,
166 .shift = 16,
167 .mask = 0xff,
168 .def = 0x09,
169 },
170 },
171 }, {
172 .id = 0x0f,
173 .name = "avpcarm7r",
174 .swgroup = TEGRA_SWGROUP_AVPC,
175 .regs = {
176 .smmu = {
177 .reg = 0x228,
178 .bit = 15,
179 },
180 .la = {
181 .reg = 0x2e4,
182 .shift = 0,
183 .mask = 0xff,
184 .def = 0x04,
185 },
186 },
187 }, {
188 .id = 0x10,
189 .name = "displayhc",
190 .swgroup = TEGRA_SWGROUP_DC,
191 .regs = {
192 .smmu = {
193 .reg = 0x228,
194 .bit = 16,
195 },
196 .la = {
197 .reg = 0x2f0,
198 .shift = 0,
199 .mask = 0xff,
200 .def = 0x68,
201 },
202 },
203 }, {
204 .id = 0x11,
205 .name = "displayhcb",
206 .swgroup = TEGRA_SWGROUP_DCB,
207 .regs = {
208 .smmu = {
209 .reg = 0x228,
210 .bit = 17,
211 },
212 .la = {
213 .reg = 0x2fc,
214 .shift = 0,
215 .mask = 0xff,
216 .def = 0x68,
217 },
218 },
219 }, {
220 .id = 0x12,
221 .name = "fdcdrd",
222 .swgroup = TEGRA_SWGROUP_NV,
223 .regs = {
224 .smmu = {
225 .reg = 0x228,
226 .bit = 18,
227 },
228 .la = {
229 .reg = 0x334,
230 .shift = 0,
231 .mask = 0xff,
232 .def = 0x0c,
233 },
234 },
235 }, {
236 .id = 0x13,
237 .name = "fdcdrd2",
238 .swgroup = TEGRA_SWGROUP_NV,
239 .regs = {
240 .smmu = {
241 .reg = 0x228,
242 .bit = 19,
243 },
244 .la = {
245 .reg = 0x33c,
246 .shift = 0,
247 .mask = 0xff,
248 .def = 0x0c,
249 },
250 },
251 }, {
252 .id = 0x14,
253 .name = "g2dr",
254 .swgroup = TEGRA_SWGROUP_G2,
255 .regs = {
256 .smmu = {
257 .reg = 0x228,
258 .bit = 20,
259 },
260 .la = {
261 .reg = 0x30c,
262 .shift = 0,
263 .mask = 0xff,
264 .def = 0x0a,
265 },
266 },
267 }, {
268 .id = 0x15,
269 .name = "hdar",
270 .swgroup = TEGRA_SWGROUP_HDA,
271 .regs = {
272 .smmu = {
273 .reg = 0x228,
274 .bit = 21,
275 },
276 .la = {
277 .reg = 0x318,
278 .shift = 0,
279 .mask = 0xff,
280 .def = 0xff,
281 },
282 },
283 }, {
284 .id = 0x16,
285 .name = "host1xdmar",
286 .swgroup = TEGRA_SWGROUP_HC,
287 .regs = {
288 .smmu = {
289 .reg = 0x228,
290 .bit = 22,
291 },
292 .la = {
293 .reg = 0x310,
294 .shift = 0,
295 .mask = 0xff,
296 .def = 0x10,
297 },
298 },
299 }, {
300 .id = 0x17,
301 .name = "host1xr",
302 .swgroup = TEGRA_SWGROUP_HC,
303 .regs = {
304 .smmu = {
305 .reg = 0x228,
306 .bit = 23,
307 },
308 .la = {
309 .reg = 0x310,
310 .shift = 16,
311 .mask = 0xff,
312 .def = 0xa5,
313 },
314 },
315 }, {
316 .id = 0x18,
317 .name = "idxsrd",
318 .swgroup = TEGRA_SWGROUP_NV,
319 .regs = {
320 .smmu = {
321 .reg = 0x228,
322 .bit = 24,
323 },
324 .la = {
325 .reg = 0x334,
326 .shift = 16,
327 .mask = 0xff,
328 .def = 0x0b,
329 },
330 },
331 }, {
332 .id = 0x1c,
333 .name = "msencsrd",
334 .swgroup = TEGRA_SWGROUP_MSENC,
335 .regs = {
336 .smmu = {
337 .reg = 0x228,
338 .bit = 28,
339 },
340 .la = {
341 .reg = 0x328,
342 .shift = 0,
343 .mask = 0xff,
344 .def = 0x80,
345 },
346 },
347 }, {
348 .id = 0x1d,
349 .name = "ppcsahbdmar",
350 .swgroup = TEGRA_SWGROUP_PPCS,
351 .regs = {
352 .smmu = {
353 .reg = 0x228,
354 .bit = 29,
355 },
356 .la = {
357 .reg = 0x344,
358 .shift = 0,
359 .mask = 0xff,
360 .def = 0x50,
361 },
362 },
363 }, {
364 .id = 0x1e,
365 .name = "ppcsahbslvr",
366 .swgroup = TEGRA_SWGROUP_PPCS,
367 .regs = {
368 .smmu = {
369 .reg = 0x228,
370 .bit = 30,
371 },
372 .la = {
373 .reg = 0x344,
374 .shift = 16,
375 .mask = 0xff,
376 .def = 0xe8,
377 },
378 },
379 }, {
380 .id = 0x20,
381 .name = "texl2srd",
382 .swgroup = TEGRA_SWGROUP_NV,
383 .regs = {
384 .smmu = {
385 .reg = 0x22c,
386 .bit = 0,
387 },
388 .la = {
389 .reg = 0x338,
390 .shift = 0,
391 .mask = 0xff,
392 .def = 0x0c,
393 },
394 },
395 }, {
396 .id = 0x22,
397 .name = "vdebsevr",
398 .swgroup = TEGRA_SWGROUP_VDE,
399 .regs = {
400 .smmu = {
401 .reg = 0x22c,
402 .bit = 2,
403 },
404 .la = {
405 .reg = 0x354,
406 .shift = 0,
407 .mask = 0xff,
408 .def = 0xff,
409 },
410 },
411 }, {
412 .id = 0x23,
413 .name = "vdember",
414 .swgroup = TEGRA_SWGROUP_VDE,
415 .regs = {
416 .smmu = {
417 .reg = 0x22c,
418 .bit = 3,
419 },
420 .la = {
421 .reg = 0x354,
422 .shift = 16,
423 .mask = 0xff,
424 .def = 0xff,
425 },
426 },
427 }, {
428 .id = 0x24,
429 .name = "vdemcer",
430 .swgroup = TEGRA_SWGROUP_VDE,
431 .regs = {
432 .smmu = {
433 .reg = 0x22c,
434 .bit = 4,
435 },
436 .la = {
437 .reg = 0x358,
438 .shift = 0,
439 .mask = 0xff,
440 .def = 0xb8,
441 },
442 },
443 }, {
444 .id = 0x25,
445 .name = "vdetper",
446 .swgroup = TEGRA_SWGROUP_VDE,
447 .regs = {
448 .smmu = {
449 .reg = 0x22c,
450 .bit = 5,
451 },
452 .la = {
453 .reg = 0x358,
454 .shift = 16,
455 .mask = 0xff,
456 .def = 0xee,
457 },
458 },
459 }, {
460 .id = 0x26,
461 .name = "mpcorelpr",
462 .swgroup = TEGRA_SWGROUP_MPCORELP,
463 .regs = {
464 .la = {
465 .reg = 0x324,
466 .shift = 0,
467 .mask = 0xff,
468 .def = 0x04,
469 },
470 },
471 }, {
472 .id = 0x27,
473 .name = "mpcorer",
474 .swgroup = TEGRA_SWGROUP_MPCORE,
475 .regs = {
476 .la = {
477 .reg = 0x320,
478 .shift = 0,
479 .mask = 0xff,
480 .def = 0x04,
481 },
482 },
483 }, {
484 .id = 0x28,
485 .name = "eppu",
486 .swgroup = TEGRA_SWGROUP_EPP,
487 .regs = {
488 .smmu = {
489 .reg = 0x22c,
490 .bit = 8,
491 },
492 .la = {
493 .reg = 0x300,
494 .shift = 16,
495 .mask = 0xff,
496 .def = 0x33,
497 },
498 },
499 }, {
500 .id = 0x29,
501 .name = "eppv",
502 .swgroup = TEGRA_SWGROUP_EPP,
503 .regs = {
504 .smmu = {
505 .reg = 0x22c,
506 .bit = 9,
507 },
508 .la = {
509 .reg = 0x304,
510 .shift = 0,
511 .mask = 0xff,
512 .def = 0x6c,
513 },
514 },
515 }, {
516 .id = 0x2a,
517 .name = "eppy",
518 .swgroup = TEGRA_SWGROUP_EPP,
519 .regs = {
520 .smmu = {
521 .reg = 0x22c,
522 .bit = 10,
523 },
524 .la = {
525 .reg = 0x304,
526 .shift = 16,
527 .mask = 0xff,
528 .def = 0x6c,
529 },
530 },
531 }, {
532 .id = 0x2b,
533 .name = "msencswr",
534 .swgroup = TEGRA_SWGROUP_MSENC,
535 .regs = {
536 .smmu = {
537 .reg = 0x22c,
538 .bit = 11,
539 },
540 .la = {
541 .reg = 0x328,
542 .shift = 16,
543 .mask = 0xff,
544 .def = 0x80,
545 },
546 },
547 }, {
548 .id = 0x2c,
549 .name = "viwsb",
550 .swgroup = TEGRA_SWGROUP_VI,
551 .regs = {
552 .smmu = {
553 .reg = 0x22c,
554 .bit = 12,
555 },
556 .la = {
557 .reg = 0x364,
558 .shift = 0,
559 .mask = 0xff,
560 .def = 0x47,
561 },
562 },
563 }, {
564 .id = 0x2d,
565 .name = "viwu",
566 .swgroup = TEGRA_SWGROUP_VI,
567 .regs = {
568 .smmu = {
569 .reg = 0x22c,
570 .bit = 13,
571 },
572 .la = {
573 .reg = 0x368,
574 .shift = 0,
575 .mask = 0xff,
576 .def = 0xff,
577 },
578 },
579 }, {
580 .id = 0x2e,
581 .name = "viwv",
582 .swgroup = TEGRA_SWGROUP_VI,
583 .regs = {
584 .smmu = {
585 .reg = 0x22c,
586 .bit = 14,
587 },
588 .la = {
589 .reg = 0x368,
590 .shift = 16,
591 .mask = 0xff,
592 .def = 0xff,
593 },
594 },
595 }, {
596 .id = 0x2f,
597 .name = "viwy",
598 .swgroup = TEGRA_SWGROUP_VI,
599 .regs = {
600 .smmu = {
601 .reg = 0x22c,
602 .bit = 15,
603 },
604 .la = {
605 .reg = 0x36c,
606 .shift = 0,
607 .mask = 0xff,
608 .def = 0x47,
609 },
610 },
611 }, {
612 .id = 0x30,
613 .name = "g2dw",
614 .swgroup = TEGRA_SWGROUP_G2,
615 .regs = {
616 .smmu = {
617 .reg = 0x22c,
618 .bit = 16,
619 },
620 .la = {
621 .reg = 0x30c,
622 .shift = 16,
623 .mask = 0xff,
624 .def = 0x9,
625 },
626 },
627 }, {
628 .id = 0x32,
629 .name = "avpcarm7w",
630 .swgroup = TEGRA_SWGROUP_AVPC,
631 .regs = {
632 .smmu = {
633 .reg = 0x22c,
634 .bit = 18,
635 },
636 .la = {
637 .reg = 0x2e4,
638 .shift = 16,
639 .mask = 0xff,
640 .def = 0x0e,
641 },
642 },
643 }, {
644 .id = 0x33,
645 .name = "fdcdwr",
646 .swgroup = TEGRA_SWGROUP_NV,
647 .regs = {
648 .smmu = {
649 .reg = 0x22c,
650 .bit = 19,
651 },
652 .la = {
653 .reg = 0x338,
654 .shift = 16,
655 .mask = 0xff,
656 .def = 0x10,
657 },
658 },
659 }, {
660 .id = 0x34,
661 .name = "fdcdwr2",
662 .swgroup = TEGRA_SWGROUP_NV,
663 .regs = {
664 .smmu = {
665 .reg = 0x22c,
666 .bit = 20,
667 },
668 .la = {
669 .reg = 0x340,
670 .shift = 0,
671 .mask = 0xff,
672 .def = 0x10,
673 },
674 },
675 }, {
676 .id = 0x35,
677 .name = "hdaw",
678 .swgroup = TEGRA_SWGROUP_HDA,
679 .regs = {
680 .smmu = {
681 .reg = 0x22c,
682 .bit = 21,
683 },
684 .la = {
685 .reg = 0x318,
686 .shift = 16,
687 .mask = 0xff,
688 .def = 0xff,
689 },
690 },
691 }, {
692 .id = 0x36,
693 .name = "host1xw",
694 .swgroup = TEGRA_SWGROUP_HC,
695 .regs = {
696 .smmu = {
697 .reg = 0x22c,
698 .bit = 22,
699 },
700 .la = {
701 .reg = 0x314,
702 .shift = 0,
703 .mask = 0xff,
704 .def = 0x25,
705 },
706 },
707 }, {
708 .id = 0x37,
709 .name = "ispw",
710 .swgroup = TEGRA_SWGROUP_ISP,
711 .regs = {
712 .smmu = {
713 .reg = 0x22c,
714 .bit = 23,
715 },
716 .la = {
717 .reg = 0x31c,
718 .shift = 0,
719 .mask = 0xff,
720 .def = 0xff,
721 },
722 },
723 }, {
724 .id = 0x38,
725 .name = "mpcorelpw",
726 .swgroup = TEGRA_SWGROUP_MPCORELP,
727 .regs = {
728 .la = {
729 .reg = 0x324,
730 .shift = 16,
731 .mask = 0xff,
732 .def = 0x80,
733 },
734 },
735 }, {
736 .id = 0x39,
737 .name = "mpcorew",
738 .swgroup = TEGRA_SWGROUP_MPCORE,
739 .regs = {
740 .la = {
741 .reg = 0x320,
742 .shift = 16,
743 .mask = 0xff,
744 .def = 0x0e,
745 },
746 },
747 }, {
748 .id = 0x3b,
749 .name = "ppcsahbdmaw",
750 .swgroup = TEGRA_SWGROUP_PPCS,
751 .regs = {
752 .smmu = {
753 .reg = 0x22c,
754 .bit = 27,
755 },
756 .la = {
757 .reg = 0x348,
758 .shift = 0,
759 .mask = 0xff,
760 .def = 0xa5,
761 },
762 },
763 }, {
764 .id = 0x3c,
765 .name = "ppcsahbslvw",
766 .swgroup = TEGRA_SWGROUP_PPCS,
767 .regs = {
768 .smmu = {
769 .reg = 0x22c,
770 .bit = 28,
771 },
772 .la = {
773 .reg = 0x348,
774 .shift = 16,
775 .mask = 0xff,
776 .def = 0xe8,
777 },
778 },
779 }, {
780 .id = 0x3e,
781 .name = "vdebsevw",
782 .swgroup = TEGRA_SWGROUP_VDE,
783 .regs = {
784 .smmu = {
785 .reg = 0x22c,
786 .bit = 30,
787 },
788 .la = {
789 .reg = 0x35c,
790 .shift = 0,
791 .mask = 0xff,
792 .def = 0xff,
793 },
794 },
795 }, {
796 .id = 0x3f,
797 .name = "vdedbgw",
798 .swgroup = TEGRA_SWGROUP_VDE,
799 .regs = {
800 .smmu = {
801 .reg = 0x22c,
802 .bit = 31,
803 },
804 .la = {
805 .reg = 0x35c,
806 .shift = 16,
807 .mask = 0xff,
808 .def = 0xff,
809 },
810 },
811 }, {
812 .id = 0x40,
813 .name = "vdembew",
814 .swgroup = TEGRA_SWGROUP_VDE,
815 .regs = {
816 .smmu = {
817 .reg = 0x230,
818 .bit = 0,
819 },
820 .la = {
821 .reg = 0x360,
822 .shift = 0,
823 .mask = 0xff,
824 .def = 0x89,
825 },
826 },
827 }, {
828 .id = 0x41,
829 .name = "vdetpmw",
830 .swgroup = TEGRA_SWGROUP_VDE,
831 .regs = {
832 .smmu = {
833 .reg = 0x230,
834 .bit = 1,
835 },
836 .la = {
837 .reg = 0x360,
838 .shift = 16,
839 .mask = 0xff,
840 .def = 0x59,
841 },
842 },
843 }, {
844 .id = 0x4a,
845 .name = "xusb_hostr",
846 .swgroup = TEGRA_SWGROUP_XUSB_HOST,
847 .regs = {
848 .smmu = {
849 .reg = 0x230,
850 .bit = 10,
851 },
852 .la = {
853 .reg = 0x37c,
854 .shift = 0,
855 .mask = 0xff,
856 .def = 0xa5,
857 },
858 },
859 }, {
860 .id = 0x4b,
861 .name = "xusb_hostw",
862 .swgroup = TEGRA_SWGROUP_XUSB_HOST,
863 .regs = {
864 .smmu = {
865 .reg = 0x230,
866 .bit = 11,
867 },
868 .la = {
869 .reg = 0x37c,
870 .shift = 16,
871 .mask = 0xff,
872 .def = 0xa5,
873 },
874 },
875 }, {
876 .id = 0x4c,
877 .name = "xusb_devr",
878 .swgroup = TEGRA_SWGROUP_XUSB_DEV,
879 .regs = {
880 .smmu = {
881 .reg = 0x230,
882 .bit = 12,
883 },
884 .la = {
885 .reg = 0x380,
886 .shift = 0,
887 .mask = 0xff,
888 .def = 0xa5,
889 },
890 },
891 }, {
892 .id = 0x4d,
893 .name = "xusb_devw",
894 .swgroup = TEGRA_SWGROUP_XUSB_DEV,
895 .regs = {
896 .smmu = {
897 .reg = 0x230,
898 .bit = 13,
899 },
900 .la = {
901 .reg = 0x380,
902 .shift = 16,
903 .mask = 0xff,
904 .def = 0xa5,
905 },
906 },
907 }, {
908 .id = 0x4e,
909 .name = "fdcdwr3",
910 .swgroup = TEGRA_SWGROUP_NV,
911 .regs = {
912 .smmu = {
913 .reg = 0x230,
914 .bit = 14,
915 },
916 .la = {
917 .reg = 0x388,
918 .shift = 0,
919 .mask = 0xff,
920 .def = 0x10,
921 },
922 },
923 }, {
924 .id = 0x4f,
925 .name = "fdcdrd3",
926 .swgroup = TEGRA_SWGROUP_NV,
927 .regs = {
928 .smmu = {
929 .reg = 0x230,
930 .bit = 15,
931 },
932 .la = {
933 .reg = 0x384,
934 .shift = 0,
935 .mask = 0xff,
936 .def = 0x0c,
937 },
938 },
939 }, {
940 .id = 0x50,
941 .name = "fdcwr4",
942 .swgroup = TEGRA_SWGROUP_NV,
943 .regs = {
944 .smmu = {
945 .reg = 0x230,
946 .bit = 16,
947 },
948 .la = {
949 .reg = 0x388,
950 .shift = 16,
951 .mask = 0xff,
952 .def = 0x10,
953 },
954 },
955 }, {
956 .id = 0x51,
957 .name = "fdcrd4",
958 .swgroup = TEGRA_SWGROUP_NV,
959 .regs = {
960 .smmu = {
961 .reg = 0x230,
962 .bit = 17,
963 },
964 .la = {
965 .reg = 0x384,
966 .shift = 16,
967 .mask = 0xff,
968 .def = 0x0c,
969 },
970 },
971 }, {
972 .id = 0x52,
973 .name = "emucifr",
974 .swgroup = TEGRA_SWGROUP_EMUCIF,
975 .regs = {
976 .la = {
977 .reg = 0x38c,
978 .shift = 0,
979 .mask = 0xff,
980 .def = 0x04,
981 },
982 },
983 }, {
984 .id = 0x53,
985 .name = "emucifw",
986 .swgroup = TEGRA_SWGROUP_EMUCIF,
987 .regs = {
988 .la = {
989 .reg = 0x38c,
990 .shift = 16,
991 .mask = 0xff,
992 .def = 0x0e,
993 },
994 },
995 }, {
996 .id = 0x54,
997 .name = "tsecsrd",
998 .swgroup = TEGRA_SWGROUP_TSEC,
999 .regs = {
1000 .smmu = {
1001 .reg = 0x230,
1002 .bit = 20,
1003 },
1004 .la = {
1005 .reg = 0x390,
1006 .shift = 0,
1007 .mask = 0xff,
1008 .def = 0x50,
1009 },
1010 },
1011 }, {
1012 .id = 0x55,
1013 .name = "tsecswr",
1014 .swgroup = TEGRA_SWGROUP_TSEC,
1015 .regs = {
1016 .smmu = {
1017 .reg = 0x230,
1018 .bit = 21,
1019 },
1020 .la = {
1021 .reg = 0x390,
1022 .shift = 16,
1023 .mask = 0xff,
1024 .def = 0x50,
1025 },
1026 },
1027 },
1028};
1029
1030static const struct tegra_smmu_swgroup tegra114_swgroups[] = {
1031 { .name = "dc", .swgroup = TEGRA_SWGROUP_DC, .reg = 0x240 },
1032 { .name = "dcb", .swgroup = TEGRA_SWGROUP_DCB, .reg = 0x244 },
1033 { .name = "epp", .swgroup = TEGRA_SWGROUP_EPP, .reg = 0x248 },
1034 { .name = "g2", .swgroup = TEGRA_SWGROUP_G2, .reg = 0x24c },
1035 { .name = "avpc", .swgroup = TEGRA_SWGROUP_AVPC, .reg = 0x23c },
1036 { .name = "nv", .swgroup = TEGRA_SWGROUP_NV, .reg = 0x268 },
1037 { .name = "hda", .swgroup = TEGRA_SWGROUP_HDA, .reg = 0x254 },
1038 { .name = "hc", .swgroup = TEGRA_SWGROUP_HC, .reg = 0x250 },
1039 { .name = "msenc", .swgroup = TEGRA_SWGROUP_MSENC, .reg = 0x264 },
1040 { .name = "ppcs", .swgroup = TEGRA_SWGROUP_PPCS, .reg = 0x270 },
1041 { .name = "vde", .swgroup = TEGRA_SWGROUP_VDE, .reg = 0x27c },
1042 { .name = "vi", .swgroup = TEGRA_SWGROUP_VI, .reg = 0x280 },
1043 { .name = "isp", .swgroup = TEGRA_SWGROUP_ISP, .reg = 0x258 },
1044 { .name = "xusb_host", .swgroup = TEGRA_SWGROUP_XUSB_HOST, .reg = 0x288 },
1045 { .name = "xusb_dev", .swgroup = TEGRA_SWGROUP_XUSB_DEV, .reg = 0x28c },
1046 { .name = "tsec", .swgroup = TEGRA_SWGROUP_TSEC, .reg = 0x294 },
1047};
1048
1049static const unsigned int tegra114_group_drm[] = {
1050 TEGRA_SWGROUP_DC,
1051 TEGRA_SWGROUP_DCB,
1052 TEGRA_SWGROUP_G2,
1053 TEGRA_SWGROUP_NV,
1054};
1055
1056static const struct tegra_smmu_group_soc tegra114_groups[] = {
1057 {
1058 .name = "drm",
1059 .swgroups = tegra114_group_drm,
1060 .num_swgroups = ARRAY_SIZE(tegra114_group_drm),
1061 },
1062};
1063
1064static const struct tegra_smmu_soc tegra114_smmu_soc = {
1065 .clients = tegra114_mc_clients,
1066 .num_clients = ARRAY_SIZE(tegra114_mc_clients),
1067 .swgroups = tegra114_swgroups,
1068 .num_swgroups = ARRAY_SIZE(tegra114_swgroups),
1069 .groups = tegra114_groups,
1070 .num_groups = ARRAY_SIZE(tegra114_groups),
1071 .supports_round_robin_arbitration = false,
1072 .supports_request_limit = false,
1073 .num_tlb_lines = 32,
1074 .num_asids = 4,
1075};
1076
1077#define TEGRA114_MC_RESET(_name, _control, _status, _bit) \
1078 { \
1079 .name = #_name, \
1080 .id = TEGRA114_MC_RESET_##_name, \
1081 .control = _control, \
1082 .status = _status, \
1083 .bit = _bit, \
1084 }
1085
1086static const struct tegra_mc_reset tegra114_mc_resets[] = {
1087 TEGRA114_MC_RESET(AVPC, 0x200, 0x204, 1),
1088 TEGRA114_MC_RESET(DC, 0x200, 0x204, 2),
1089 TEGRA114_MC_RESET(DCB, 0x200, 0x204, 3),
1090 TEGRA114_MC_RESET(EPP, 0x200, 0x204, 4),
1091 TEGRA114_MC_RESET(2D, 0x200, 0x204, 5),
1092 TEGRA114_MC_RESET(HC, 0x200, 0x204, 6),
1093 TEGRA114_MC_RESET(HDA, 0x200, 0x204, 7),
1094 TEGRA114_MC_RESET(ISP, 0x200, 0x204, 8),
1095 TEGRA114_MC_RESET(MPCORE, 0x200, 0x204, 9),
1096 TEGRA114_MC_RESET(MPCORELP, 0x200, 0x204, 10),
1097 TEGRA114_MC_RESET(MPE, 0x200, 0x204, 11),
1098 TEGRA114_MC_RESET(3D, 0x200, 0x204, 12),
1099 TEGRA114_MC_RESET(3D2, 0x200, 0x204, 13),
1100 TEGRA114_MC_RESET(PPCS, 0x200, 0x204, 14),
1101 TEGRA114_MC_RESET(VDE, 0x200, 0x204, 16),
1102 TEGRA114_MC_RESET(VI, 0x200, 0x204, 17),
1103};
1104
1105static void tegra114_mc_tune_client_latency(struct tegra_mc *mc,
1106 const struct tegra_mc_client *client,
1107 unsigned int bandwidth_mbytes_sec)
1108{
1109 u32 arb_tolerance_compensation_nsec, arb_tolerance_compensation_div;
1110 unsigned int fifo_size = client->fifo_size;
1111 u32 arb_nsec, la_ticks, value;
1112
1113 /* see 20.3.1.1 Client Configuration in Tegra4 TRM v01p */
1114 if (bandwidth_mbytes_sec)
1115 arb_nsec = fifo_size * NSEC_PER_USEC / bandwidth_mbytes_sec;
1116 else
1117 arb_nsec = U32_MAX;
1118
1119 /*
1120 * Latency allowness should be set with consideration for the module's
1121 * latency tolerance and internal buffering capabilities.
1122 *
1123 * Display memory clients use isochronous transfers and have very low
1124 * tolerance to a belated transfers. Hence we need to compensate the
1125 * memory arbitration imperfection for them in order to prevent FIFO
1126 * underflow condition when memory bus is busy.
1127 *
1128 * VI clients also need a stronger compensation.
1129 */
1130 switch (client->swgroup) {
1131 case TEGRA_SWGROUP_MPCORE:
1132 case TEGRA_SWGROUP_PTC:
1133 /*
1134 * We always want lower latency for these clients, hence
1135 * don't touch them.
1136 */
1137 return;
1138
1139 case TEGRA_SWGROUP_DC:
1140 case TEGRA_SWGROUP_DCB:
1141 arb_tolerance_compensation_nsec = 1050;
1142 arb_tolerance_compensation_div = 2;
1143 break;
1144
1145 case TEGRA_SWGROUP_VI:
1146 arb_tolerance_compensation_nsec = 1050;
1147 arb_tolerance_compensation_div = 1;
1148 break;
1149
1150 default:
1151 arb_tolerance_compensation_nsec = 150;
1152 arb_tolerance_compensation_div = 1;
1153 break;
1154 }
1155
1156 if (arb_nsec > arb_tolerance_compensation_nsec)
1157 arb_nsec -= arb_tolerance_compensation_nsec;
1158 else
1159 arb_nsec = 0;
1160
1161 arb_nsec /= arb_tolerance_compensation_div;
1162
1163 /*
1164 * Latency allowance is a number of ticks a request from a particular
1165 * client may wait in the EMEM arbiter before it becomes a high-priority
1166 * request.
1167 */
1168 la_ticks = arb_nsec / mc->tick;
1169 la_ticks = min(la_ticks, client->regs.la.mask);
1170
1171 value = mc_readl(mc, client->regs.la.reg);
1172 value &= ~(client->regs.la.mask << client->regs.la.shift);
1173 value |= la_ticks << client->regs.la.shift;
1174 mc_writel(mc, value, client->regs.la.reg);
1175}
1176
1177static int tegra114_mc_icc_set(struct icc_node *src, struct icc_node *dst)
1178{
1179 struct tegra_mc *mc = icc_provider_to_tegra_mc(src->provider);
1180 const struct tegra_mc_client *client = &mc->soc->clients[src->id];
1181 u64 peak_bandwidth = icc_units_to_bps(src->peak_bw);
1182
1183 /*
1184 * Skip pre-initialization that is done by icc_node_add(), which sets
1185 * bandwidth to maximum for all clients before drivers are loaded.
1186 *
1187 * This doesn't make sense for us because we don't have drivers for all
1188 * clients and it's okay to keep configuration left from bootloader
1189 * during boot, at least for today.
1190 */
1191 if (src == dst)
1192 return 0;
1193
1194 /* convert bytes/sec to megabytes/sec */
1195 do_div(peak_bandwidth, 1000000);
1196
1197 tegra114_mc_tune_client_latency(mc, client, peak_bandwidth);
1198
1199 return 0;
1200}
1201
1202static int tegra114_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
1203 u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
1204{
1205 /*
1206 * ISO clients need to reserve extra bandwidth up-front because
1207 * there could be high bandwidth pressure during initial filling
1208 * of the client's FIFO buffers. Secondly, we need to take into
1209 * account impurities of the memory subsystem.
1210 */
1211 if (tag & TEGRA_MC_ICC_TAG_ISO)
1212 peak_bw = tegra_mc_scale_percents(peak_bw, 400);
1213
1214 *agg_avg += avg_bw;
1215 *agg_peak = max(*agg_peak, peak_bw);
1216
1217 return 0;
1218}
1219
1220static struct icc_node_data *
1221tegra114_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
1222{
1223 struct tegra_mc *mc = icc_provider_to_tegra_mc(data);
1224 const struct tegra_mc_client *client;
1225 unsigned int i, idx = spec->args[0];
1226 struct icc_node_data *ndata;
1227 struct icc_node *node;
1228
1229 list_for_each_entry(node, &mc->provider.nodes, node_list) {
1230 if (node->id != idx)
1231 continue;
1232
1233 ndata = kzalloc_obj(*ndata);
1234 if (!ndata)
1235 return ERR_PTR(-ENOMEM);
1236
1237 client = &mc->soc->clients[idx];
1238 ndata->node = node;
1239
1240 switch (client->swgroup) {
1241 case TEGRA_SWGROUP_DC:
1242 case TEGRA_SWGROUP_DCB:
1243 case TEGRA_SWGROUP_PTC:
1244 case TEGRA_SWGROUP_VI:
1245 /* these clients are isochronous by default */
1246 ndata->tag = TEGRA_MC_ICC_TAG_ISO;
1247 break;
1248
1249 default:
1250 ndata->tag = TEGRA_MC_ICC_TAG_DEFAULT;
1251 break;
1252 }
1253
1254 return ndata;
1255 }
1256
1257 for (i = 0; i < mc->soc->num_clients; i++) {
1258 if (mc->soc->clients[i].id == idx)
1259 return ERR_PTR(-EPROBE_DEFER);
1260 }
1261
1262 dev_err(mc->dev, "invalid ICC client ID %u\n", idx);
1263
1264 return ERR_PTR(-EINVAL);
1265}
1266
1267static const struct tegra_mc_icc_ops tegra114_mc_icc_ops = {
1268 .xlate_extended = tegra114_mc_of_icc_xlate_extended,
1269 .aggregate = tegra114_mc_icc_aggreate,
1270 .set = tegra114_mc_icc_set,
1271};
1272
1273static const unsigned long tegra114_mc_emem_regs[] = {
1274 MC_EMEM_ARB_CFG,
1275 MC_EMEM_ARB_OUTSTANDING_REQ,
1276 MC_EMEM_ARB_TIMING_RCD,
1277 MC_EMEM_ARB_TIMING_RP,
1278 MC_EMEM_ARB_TIMING_RC,
1279 MC_EMEM_ARB_TIMING_RAS,
1280 MC_EMEM_ARB_TIMING_FAW,
1281 MC_EMEM_ARB_TIMING_RRD,
1282 MC_EMEM_ARB_TIMING_RAP2PRE,
1283 MC_EMEM_ARB_TIMING_WAP2PRE,
1284 MC_EMEM_ARB_TIMING_R2R,
1285 MC_EMEM_ARB_TIMING_W2W,
1286 MC_EMEM_ARB_TIMING_R2W,
1287 MC_EMEM_ARB_TIMING_W2R,
1288 MC_EMEM_ARB_DA_TURNS,
1289 MC_EMEM_ARB_DA_COVERS,
1290 MC_EMEM_ARB_MISC0,
1291 MC_EMEM_ARB_RING1_THROTTLE,
1292};
1293
1294static const struct tegra_mc_intmask tegra114_mc_intmasks[] = {
1295 {
1296 .reg = MC_INTMASK,
1297 .mask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
1298 MC_INT_DECERR_EMEM,
1299 },
1300};
1301
1302const struct tegra_mc_soc tegra114_mc_soc = {
1303 .clients = tegra114_mc_clients,
1304 .num_clients = ARRAY_SIZE(tegra114_mc_clients),
1305 .num_address_bits = 32,
1306 .atom_size = 32,
1307 .client_id_mask = 0x7f,
1308 .smmu = &tegra114_smmu_soc,
1309 .emem_regs = tegra114_mc_emem_regs,
1310 .num_emem_regs = ARRAY_SIZE(tegra114_mc_emem_regs),
1311 .intmasks = tegra114_mc_intmasks,
1312 .num_intmasks = ARRAY_SIZE(tegra114_mc_intmasks),
1313 .reset_ops = &tegra_mc_reset_ops_common,
1314 .resets = tegra114_mc_resets,
1315 .num_resets = ARRAY_SIZE(tegra114_mc_resets),
1316 .icc_ops = &tegra114_mc_icc_ops,
1317 .ops = &tegra30_mc_ops,
1318 .regs = &tegra20_mc_regs,
1319 .handle_irq = tegra30_mc_irq_handlers,
1320 .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers),
1321 .mc_err_status_type_mask = (0x7 << 28),
1322};