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