xref: /openbmc/linux/drivers/memory/tegra/tegra124.c (revision 479965a2)
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/device.h>
8 #include <linux/slab.h>
9 
10 #include <dt-bindings/memory/tegra124-mc.h>
11 
12 #include "mc.h"
13 
14 static const struct tegra_mc_client tegra124_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 = 0xc2,
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 = 0xc6,
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 = 0x50,
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 = 0x50,
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 = 0x50,
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 = 0x50,
121 			},
122 		},
123 	}, {
124 		.id = 0x0e,
125 		.name = "afir",
126 		.swgroup = TEGRA_SWGROUP_AFI,
127 		.regs = {
128 			.smmu = {
129 				.reg = 0x228,
130 				.bit = 14,
131 			},
132 			.la = {
133 				.reg = 0x2e0,
134 				.shift = 0,
135 				.mask = 0xff,
136 				.def = 0x13,
137 			},
138 		},
139 	}, {
140 		.id = 0x0f,
141 		.name = "avpcarm7r",
142 		.swgroup = TEGRA_SWGROUP_AVPC,
143 		.regs = {
144 			.smmu = {
145 				.reg = 0x228,
146 				.bit = 15,
147 			},
148 			.la = {
149 				.reg = 0x2e4,
150 				.shift = 0,
151 				.mask = 0xff,
152 				.def = 0x04,
153 			},
154 		},
155 	}, {
156 		.id = 0x10,
157 		.name = "displayhc",
158 		.swgroup = TEGRA_SWGROUP_DC,
159 		.regs = {
160 			.smmu = {
161 				.reg = 0x228,
162 				.bit = 16,
163 			},
164 			.la = {
165 				.reg = 0x2f0,
166 				.shift = 0,
167 				.mask = 0xff,
168 				.def = 0x50,
169 			},
170 		},
171 	}, {
172 		.id = 0x11,
173 		.name = "displayhcb",
174 		.swgroup = TEGRA_SWGROUP_DCB,
175 		.regs = {
176 			.smmu = {
177 				.reg = 0x228,
178 				.bit = 17,
179 			},
180 			.la = {
181 				.reg = 0x2fc,
182 				.shift = 0,
183 				.mask = 0xff,
184 				.def = 0x50,
185 			},
186 		},
187 	}, {
188 		.id = 0x15,
189 		.name = "hdar",
190 		.swgroup = TEGRA_SWGROUP_HDA,
191 		.regs = {
192 			.smmu = {
193 				.reg = 0x228,
194 				.bit = 21,
195 			},
196 			.la = {
197 				.reg = 0x318,
198 				.shift = 0,
199 				.mask = 0xff,
200 				.def = 0x24,
201 			},
202 		},
203 	}, {
204 		.id = 0x16,
205 		.name = "host1xdmar",
206 		.swgroup = TEGRA_SWGROUP_HC,
207 		.regs = {
208 			.smmu = {
209 				.reg = 0x228,
210 				.bit = 22,
211 			},
212 			.la = {
213 				.reg = 0x310,
214 				.shift = 0,
215 				.mask = 0xff,
216 				.def = 0x1e,
217 			},
218 		},
219 	}, {
220 		.id = 0x17,
221 		.name = "host1xr",
222 		.swgroup = TEGRA_SWGROUP_HC,
223 		.regs = {
224 			.smmu = {
225 				.reg = 0x228,
226 				.bit = 23,
227 			},
228 			.la = {
229 				.reg = 0x310,
230 				.shift = 16,
231 				.mask = 0xff,
232 				.def = 0x50,
233 			},
234 		},
235 	}, {
236 		.id = 0x1c,
237 		.name = "msencsrd",
238 		.swgroup = TEGRA_SWGROUP_MSENC,
239 		.regs = {
240 			.smmu = {
241 				.reg = 0x228,
242 				.bit = 28,
243 			},
244 			.la = {
245 				.reg = 0x328,
246 				.shift = 0,
247 				.mask = 0xff,
248 				.def = 0x23,
249 			},
250 		},
251 	}, {
252 		.id = 0x1d,
253 		.name = "ppcsahbdmar",
254 		.swgroup = TEGRA_SWGROUP_PPCS,
255 		.regs = {
256 			.smmu = {
257 				.reg = 0x228,
258 				.bit = 29,
259 			},
260 			.la = {
261 				.reg = 0x344,
262 				.shift = 0,
263 				.mask = 0xff,
264 				.def = 0x49,
265 			},
266 		},
267 	}, {
268 		.id = 0x1e,
269 		.name = "ppcsahbslvr",
270 		.swgroup = TEGRA_SWGROUP_PPCS,
271 		.regs = {
272 			.smmu = {
273 				.reg = 0x228,
274 				.bit = 30,
275 			},
276 			.la = {
277 				.reg = 0x344,
278 				.shift = 16,
279 				.mask = 0xff,
280 				.def = 0x1a,
281 			},
282 		},
283 	}, {
284 		.id = 0x1f,
285 		.name = "satar",
286 		.swgroup = TEGRA_SWGROUP_SATA,
287 		.regs = {
288 			.smmu = {
289 				.reg = 0x228,
290 				.bit = 31,
291 			},
292 			.la = {
293 				.reg = 0x350,
294 				.shift = 0,
295 				.mask = 0xff,
296 				.def = 0x65,
297 			},
298 		},
299 	}, {
300 		.id = 0x22,
301 		.name = "vdebsevr",
302 		.swgroup = TEGRA_SWGROUP_VDE,
303 		.regs = {
304 			.smmu = {
305 				.reg = 0x22c,
306 				.bit = 2,
307 			},
308 			.la = {
309 				.reg = 0x354,
310 				.shift = 0,
311 				.mask = 0xff,
312 				.def = 0x4f,
313 			},
314 		},
315 	}, {
316 		.id = 0x23,
317 		.name = "vdember",
318 		.swgroup = TEGRA_SWGROUP_VDE,
319 		.regs = {
320 			.smmu = {
321 				.reg = 0x22c,
322 				.bit = 3,
323 			},
324 			.la = {
325 				.reg = 0x354,
326 				.shift = 16,
327 				.mask = 0xff,
328 				.def = 0x3d,
329 			},
330 		},
331 	}, {
332 		.id = 0x24,
333 		.name = "vdemcer",
334 		.swgroup = TEGRA_SWGROUP_VDE,
335 		.regs = {
336 			.smmu = {
337 				.reg = 0x22c,
338 				.bit = 4,
339 			},
340 			.la = {
341 				.reg = 0x358,
342 				.shift = 0,
343 				.mask = 0xff,
344 				.def = 0x66,
345 			},
346 		},
347 	}, {
348 		.id = 0x25,
349 		.name = "vdetper",
350 		.swgroup = TEGRA_SWGROUP_VDE,
351 		.regs = {
352 			.smmu = {
353 				.reg = 0x22c,
354 				.bit = 5,
355 			},
356 			.la = {
357 				.reg = 0x358,
358 				.shift = 16,
359 				.mask = 0xff,
360 				.def = 0xa5,
361 			},
362 		},
363 	}, {
364 		.id = 0x26,
365 		.name = "mpcorelpr",
366 		.swgroup = TEGRA_SWGROUP_MPCORELP,
367 		.regs = {
368 			.la = {
369 				.reg = 0x324,
370 				.shift = 0,
371 				.mask = 0xff,
372 				.def = 0x04,
373 			},
374 		},
375 	}, {
376 		.id = 0x27,
377 		.name = "mpcorer",
378 		.swgroup = TEGRA_SWGROUP_MPCORE,
379 		.regs = {
380 			.la = {
381 				.reg = 0x320,
382 				.shift = 0,
383 				.mask = 0xff,
384 				.def = 0x04,
385 			},
386 		},
387 	}, {
388 		.id = 0x2b,
389 		.name = "msencswr",
390 		.swgroup = TEGRA_SWGROUP_MSENC,
391 		.regs = {
392 			.smmu = {
393 				.reg = 0x22c,
394 				.bit = 11,
395 			},
396 			.la = {
397 				.reg = 0x328,
398 				.shift = 16,
399 				.mask = 0xff,
400 				.def = 0x80,
401 			},
402 		},
403 	}, {
404 		.id = 0x31,
405 		.name = "afiw",
406 		.swgroup = TEGRA_SWGROUP_AFI,
407 		.regs = {
408 			.smmu = {
409 				.reg = 0x22c,
410 				.bit = 17,
411 			},
412 			.la = {
413 				.reg = 0x2e0,
414 				.shift = 16,
415 				.mask = 0xff,
416 				.def = 0x80,
417 			},
418 		},
419 	}, {
420 		.id = 0x32,
421 		.name = "avpcarm7w",
422 		.swgroup = TEGRA_SWGROUP_AVPC,
423 		.regs = {
424 			.smmu = {
425 				.reg = 0x22c,
426 				.bit = 18,
427 			},
428 			.la = {
429 				.reg = 0x2e4,
430 				.shift = 16,
431 				.mask = 0xff,
432 				.def = 0x80,
433 			},
434 		},
435 	}, {
436 		.id = 0x35,
437 		.name = "hdaw",
438 		.swgroup = TEGRA_SWGROUP_HDA,
439 		.regs = {
440 			.smmu = {
441 				.reg = 0x22c,
442 				.bit = 21,
443 			},
444 			.la = {
445 				.reg = 0x318,
446 				.shift = 16,
447 				.mask = 0xff,
448 				.def = 0x80,
449 			},
450 		},
451 	}, {
452 		.id = 0x36,
453 		.name = "host1xw",
454 		.swgroup = TEGRA_SWGROUP_HC,
455 		.regs = {
456 			.smmu = {
457 				.reg = 0x22c,
458 				.bit = 22,
459 			},
460 			.la = {
461 				.reg = 0x314,
462 				.shift = 0,
463 				.mask = 0xff,
464 				.def = 0x80,
465 			},
466 		},
467 	}, {
468 		.id = 0x38,
469 		.name = "mpcorelpw",
470 		.swgroup = TEGRA_SWGROUP_MPCORELP,
471 		.regs = {
472 			.la = {
473 				.reg = 0x324,
474 				.shift = 16,
475 				.mask = 0xff,
476 				.def = 0x80,
477 			},
478 		},
479 	}, {
480 		.id = 0x39,
481 		.name = "mpcorew",
482 		.swgroup = TEGRA_SWGROUP_MPCORE,
483 		.regs = {
484 			.la = {
485 				.reg = 0x320,
486 				.shift = 16,
487 				.mask = 0xff,
488 				.def = 0x80,
489 			},
490 		},
491 	}, {
492 		.id = 0x3b,
493 		.name = "ppcsahbdmaw",
494 		.swgroup = TEGRA_SWGROUP_PPCS,
495 		.regs = {
496 			.smmu = {
497 				.reg = 0x22c,
498 				.bit = 27,
499 			},
500 			.la = {
501 				.reg = 0x348,
502 				.shift = 0,
503 				.mask = 0xff,
504 				.def = 0x80,
505 			},
506 		},
507 	}, {
508 		.id = 0x3c,
509 		.name = "ppcsahbslvw",
510 		.swgroup = TEGRA_SWGROUP_PPCS,
511 		.regs = {
512 			.smmu = {
513 				.reg = 0x22c,
514 				.bit = 28,
515 			},
516 			.la = {
517 				.reg = 0x348,
518 				.shift = 16,
519 				.mask = 0xff,
520 				.def = 0x80,
521 			},
522 		},
523 	}, {
524 		.id = 0x3d,
525 		.name = "sataw",
526 		.swgroup = TEGRA_SWGROUP_SATA,
527 		.regs = {
528 			.smmu = {
529 				.reg = 0x22c,
530 				.bit = 29,
531 			},
532 			.la = {
533 				.reg = 0x350,
534 				.shift = 16,
535 				.mask = 0xff,
536 				.def = 0x65,
537 			},
538 		},
539 	}, {
540 		.id = 0x3e,
541 		.name = "vdebsevw",
542 		.swgroup = TEGRA_SWGROUP_VDE,
543 		.regs = {
544 			.smmu = {
545 				.reg = 0x22c,
546 				.bit = 30,
547 			},
548 			.la = {
549 				.reg = 0x35c,
550 				.shift = 0,
551 				.mask = 0xff,
552 				.def = 0x80,
553 			},
554 		},
555 	}, {
556 		.id = 0x3f,
557 		.name = "vdedbgw",
558 		.swgroup = TEGRA_SWGROUP_VDE,
559 		.regs = {
560 			.smmu = {
561 				.reg = 0x22c,
562 				.bit = 31,
563 			},
564 			.la = {
565 				.reg = 0x35c,
566 				.shift = 16,
567 				.mask = 0xff,
568 				.def = 0x80,
569 			},
570 		},
571 	}, {
572 		.id = 0x40,
573 		.name = "vdembew",
574 		.swgroup = TEGRA_SWGROUP_VDE,
575 		.regs = {
576 			.smmu = {
577 				.reg = 0x230,
578 				.bit = 0,
579 			},
580 			.la = {
581 				.reg = 0x360,
582 				.shift = 0,
583 				.mask = 0xff,
584 				.def = 0x80,
585 			},
586 		},
587 	}, {
588 		.id = 0x41,
589 		.name = "vdetpmw",
590 		.swgroup = TEGRA_SWGROUP_VDE,
591 		.regs = {
592 			.smmu = {
593 				.reg = 0x230,
594 				.bit = 1,
595 			},
596 			.la = {
597 				.reg = 0x360,
598 				.shift = 16,
599 				.mask = 0xff,
600 				.def = 0x80,
601 			},
602 		},
603 	}, {
604 		.id = 0x44,
605 		.name = "ispra",
606 		.swgroup = TEGRA_SWGROUP_ISP2,
607 		.regs = {
608 			.smmu = {
609 				.reg = 0x230,
610 				.bit = 4,
611 			},
612 			.la = {
613 				.reg = 0x370,
614 				.shift = 0,
615 				.mask = 0xff,
616 				.def = 0x18,
617 			},
618 		},
619 	}, {
620 		.id = 0x46,
621 		.name = "ispwa",
622 		.swgroup = TEGRA_SWGROUP_ISP2,
623 		.regs = {
624 			.smmu = {
625 				.reg = 0x230,
626 				.bit = 6,
627 			},
628 			.la = {
629 				.reg = 0x374,
630 				.shift = 0,
631 				.mask = 0xff,
632 				.def = 0x80,
633 			},
634 		},
635 	}, {
636 		.id = 0x47,
637 		.name = "ispwb",
638 		.swgroup = TEGRA_SWGROUP_ISP2,
639 		.regs = {
640 			.smmu = {
641 				.reg = 0x230,
642 				.bit = 7,
643 			},
644 			.la = {
645 				.reg = 0x374,
646 				.shift = 16,
647 				.mask = 0xff,
648 				.def = 0x80,
649 			},
650 		},
651 	}, {
652 		.id = 0x4a,
653 		.name = "xusb_hostr",
654 		.swgroup = TEGRA_SWGROUP_XUSB_HOST,
655 		.regs = {
656 			.smmu = {
657 				.reg = 0x230,
658 				.bit = 10,
659 			},
660 			.la = {
661 				.reg = 0x37c,
662 				.shift = 0,
663 				.mask = 0xff,
664 				.def = 0x39,
665 			},
666 		},
667 	}, {
668 		.id = 0x4b,
669 		.name = "xusb_hostw",
670 		.swgroup = TEGRA_SWGROUP_XUSB_HOST,
671 		.regs = {
672 			.smmu = {
673 				.reg = 0x230,
674 				.bit = 11,
675 			},
676 			.la = {
677 				.reg = 0x37c,
678 				.shift = 16,
679 				.mask = 0xff,
680 				.def = 0x80,
681 			},
682 		},
683 	}, {
684 		.id = 0x4c,
685 		.name = "xusb_devr",
686 		.swgroup = TEGRA_SWGROUP_XUSB_DEV,
687 		.regs = {
688 			.smmu = {
689 				.reg = 0x230,
690 				.bit = 12,
691 			},
692 			.la = {
693 				.reg = 0x380,
694 				.shift = 0,
695 				.mask = 0xff,
696 				.def = 0x39,
697 			},
698 		},
699 	}, {
700 		.id = 0x4d,
701 		.name = "xusb_devw",
702 		.swgroup = TEGRA_SWGROUP_XUSB_DEV,
703 		.regs = {
704 			.smmu = {
705 				.reg = 0x230,
706 				.bit = 13,
707 			},
708 			.la = {
709 				.reg = 0x380,
710 				.shift = 16,
711 				.mask = 0xff,
712 				.def = 0x80,
713 			},
714 		},
715 	}, {
716 		.id = 0x4e,
717 		.name = "isprab",
718 		.swgroup = TEGRA_SWGROUP_ISP2B,
719 		.regs = {
720 			.smmu = {
721 				.reg = 0x230,
722 				.bit = 14,
723 			},
724 			.la = {
725 				.reg = 0x384,
726 				.shift = 0,
727 				.mask = 0xff,
728 				.def = 0x18,
729 			},
730 		},
731 	}, {
732 		.id = 0x50,
733 		.name = "ispwab",
734 		.swgroup = TEGRA_SWGROUP_ISP2B,
735 		.regs = {
736 			.smmu = {
737 				.reg = 0x230,
738 				.bit = 16,
739 			},
740 			.la = {
741 				.reg = 0x388,
742 				.shift = 0,
743 				.mask = 0xff,
744 				.def = 0x80,
745 			},
746 		},
747 	}, {
748 		.id = 0x51,
749 		.name = "ispwbb",
750 		.swgroup = TEGRA_SWGROUP_ISP2B,
751 		.regs = {
752 			.smmu = {
753 				.reg = 0x230,
754 				.bit = 17,
755 			},
756 			.la = {
757 				.reg = 0x388,
758 				.shift = 16,
759 				.mask = 0xff,
760 				.def = 0x80,
761 			},
762 		},
763 	}, {
764 		.id = 0x54,
765 		.name = "tsecsrd",
766 		.swgroup = TEGRA_SWGROUP_TSEC,
767 		.regs = {
768 			.smmu = {
769 				.reg = 0x230,
770 				.bit = 20,
771 			},
772 			.la = {
773 				.reg = 0x390,
774 				.shift = 0,
775 				.mask = 0xff,
776 				.def = 0x9b,
777 			},
778 		},
779 	}, {
780 		.id = 0x55,
781 		.name = "tsecswr",
782 		.swgroup = TEGRA_SWGROUP_TSEC,
783 		.regs = {
784 			.smmu = {
785 				.reg = 0x230,
786 				.bit = 21,
787 			},
788 			.la = {
789 				.reg = 0x390,
790 				.shift = 16,
791 				.mask = 0xff,
792 				.def = 0x80,
793 			},
794 		},
795 	}, {
796 		.id = 0x56,
797 		.name = "a9avpscr",
798 		.swgroup = TEGRA_SWGROUP_A9AVP,
799 		.regs = {
800 			.smmu = {
801 				.reg = 0x230,
802 				.bit = 22,
803 			},
804 			.la = {
805 				.reg = 0x3a4,
806 				.shift = 0,
807 				.mask = 0xff,
808 				.def = 0x04,
809 			},
810 		},
811 	}, {
812 		.id = 0x57,
813 		.name = "a9avpscw",
814 		.swgroup = TEGRA_SWGROUP_A9AVP,
815 		.regs = {
816 			.smmu = {
817 				.reg = 0x230,
818 				.bit = 23,
819 			},
820 			.la = {
821 				.reg = 0x3a4,
822 				.shift = 16,
823 				.mask = 0xff,
824 				.def = 0x80,
825 			},
826 		},
827 	}, {
828 		.id = 0x58,
829 		.name = "gpusrd",
830 		.swgroup = TEGRA_SWGROUP_GPU,
831 		.regs = {
832 			.smmu = {
833 				/* read-only */
834 				.reg = 0x230,
835 				.bit = 24,
836 			},
837 			.la = {
838 				.reg = 0x3c8,
839 				.shift = 0,
840 				.mask = 0xff,
841 				.def = 0x1a,
842 			},
843 		},
844 	}, {
845 		.id = 0x59,
846 		.name = "gpuswr",
847 		.swgroup = TEGRA_SWGROUP_GPU,
848 		.regs = {
849 			.smmu = {
850 				/* read-only */
851 				.reg = 0x230,
852 				.bit = 25,
853 			},
854 			.la = {
855 				.reg = 0x3c8,
856 				.shift = 16,
857 				.mask = 0xff,
858 				.def = 0x80,
859 			},
860 		},
861 	}, {
862 		.id = 0x5a,
863 		.name = "displayt",
864 		.swgroup = TEGRA_SWGROUP_DC,
865 		.regs = {
866 			.smmu = {
867 				.reg = 0x230,
868 				.bit = 26,
869 			},
870 			.la = {
871 				.reg = 0x2f0,
872 				.shift = 16,
873 				.mask = 0xff,
874 				.def = 0x50,
875 			},
876 		},
877 	}, {
878 		.id = 0x60,
879 		.name = "sdmmcra",
880 		.swgroup = TEGRA_SWGROUP_SDMMC1A,
881 		.regs = {
882 			.smmu = {
883 				.reg = 0x234,
884 				.bit = 0,
885 			},
886 			.la = {
887 				.reg = 0x3b8,
888 				.shift = 0,
889 				.mask = 0xff,
890 				.def = 0x49,
891 			},
892 		},
893 	}, {
894 		.id = 0x61,
895 		.name = "sdmmcraa",
896 		.swgroup = TEGRA_SWGROUP_SDMMC2A,
897 		.regs = {
898 			.smmu = {
899 				.reg = 0x234,
900 				.bit = 1,
901 			},
902 			.la = {
903 				.reg = 0x3bc,
904 				.shift = 0,
905 				.mask = 0xff,
906 				.def = 0x49,
907 			},
908 		},
909 	}, {
910 		.id = 0x62,
911 		.name = "sdmmcr",
912 		.swgroup = TEGRA_SWGROUP_SDMMC3A,
913 		.regs = {
914 			.smmu = {
915 				.reg = 0x234,
916 				.bit = 2,
917 			},
918 			.la = {
919 				.reg = 0x3c0,
920 				.shift = 0,
921 				.mask = 0xff,
922 				.def = 0x49,
923 			},
924 		},
925 	}, {
926 		.id = 0x63,
927 		.swgroup = TEGRA_SWGROUP_SDMMC4A,
928 		.name = "sdmmcrab",
929 		.regs = {
930 			.smmu = {
931 				.reg = 0x234,
932 				.bit = 3,
933 			},
934 			.la = {
935 				.reg = 0x3c4,
936 				.shift = 0,
937 				.mask = 0xff,
938 				.def = 0x49,
939 			},
940 		},
941 	}, {
942 		.id = 0x64,
943 		.name = "sdmmcwa",
944 		.swgroup = TEGRA_SWGROUP_SDMMC1A,
945 		.regs = {
946 			.smmu = {
947 				.reg = 0x234,
948 				.bit = 4,
949 			},
950 			.la = {
951 				.reg = 0x3b8,
952 				.shift = 16,
953 				.mask = 0xff,
954 				.def = 0x80,
955 			},
956 		},
957 	}, {
958 		.id = 0x65,
959 		.name = "sdmmcwaa",
960 		.swgroup = TEGRA_SWGROUP_SDMMC2A,
961 		.regs = {
962 			.smmu = {
963 				.reg = 0x234,
964 				.bit = 5,
965 			},
966 			.la = {
967 				.reg = 0x3bc,
968 				.shift = 16,
969 				.mask = 0xff,
970 				.def = 0x80,
971 			},
972 		},
973 	}, {
974 		.id = 0x66,
975 		.name = "sdmmcw",
976 		.swgroup = TEGRA_SWGROUP_SDMMC3A,
977 		.regs = {
978 			.smmu = {
979 				.reg = 0x234,
980 				.bit = 6,
981 			},
982 			.la = {
983 				.reg = 0x3c0,
984 				.shift = 16,
985 				.mask = 0xff,
986 				.def = 0x80,
987 			},
988 		},
989 	}, {
990 		.id = 0x67,
991 		.name = "sdmmcwab",
992 		.swgroup = TEGRA_SWGROUP_SDMMC4A,
993 		.regs = {
994 			.smmu = {
995 				.reg = 0x234,
996 				.bit = 7,
997 			},
998 			.la = {
999 				.reg = 0x3c4,
1000 				.shift = 16,
1001 				.mask = 0xff,
1002 				.def = 0x80,
1003 			},
1004 		},
1005 	}, {
1006 		.id = 0x6c,
1007 		.name = "vicsrd",
1008 		.swgroup = TEGRA_SWGROUP_VIC,
1009 		.regs = {
1010 			.smmu = {
1011 				.reg = 0x234,
1012 				.bit = 12,
1013 			},
1014 			.la = {
1015 				.reg = 0x394,
1016 				.shift = 0,
1017 				.mask = 0xff,
1018 				.def = 0x1a,
1019 			},
1020 		},
1021 	}, {
1022 		.id = 0x6d,
1023 		.name = "vicswr",
1024 		.swgroup = TEGRA_SWGROUP_VIC,
1025 		.regs = {
1026 			.smmu = {
1027 				.reg = 0x234,
1028 				.bit = 13,
1029 			},
1030 			.la = {
1031 				.reg = 0x394,
1032 				.shift = 16,
1033 				.mask = 0xff,
1034 				.def = 0x80,
1035 			},
1036 		},
1037 	}, {
1038 		.id = 0x72,
1039 		.name = "viw",
1040 		.swgroup = TEGRA_SWGROUP_VI,
1041 		.regs = {
1042 			.smmu = {
1043 				.reg = 0x234,
1044 				.bit = 18,
1045 			},
1046 			.la = {
1047 				.reg = 0x398,
1048 				.shift = 0,
1049 				.mask = 0xff,
1050 				.def = 0x80,
1051 			},
1052 		},
1053 	}, {
1054 		.id = 0x73,
1055 		.name = "displayd",
1056 		.swgroup = TEGRA_SWGROUP_DC,
1057 		.regs = {
1058 			.smmu = {
1059 				.reg = 0x234,
1060 				.bit = 19,
1061 			},
1062 			.la = {
1063 				.reg = 0x3c8,
1064 				.shift = 0,
1065 				.mask = 0xff,
1066 				.def = 0x50,
1067 			},
1068 		},
1069 	},
1070 };
1071 
1072 static const struct tegra_smmu_swgroup tegra124_swgroups[] = {
1073 	{ .name = "dc",        .swgroup = TEGRA_SWGROUP_DC,        .reg = 0x240 },
1074 	{ .name = "dcb",       .swgroup = TEGRA_SWGROUP_DCB,       .reg = 0x244 },
1075 	{ .name = "afi",       .swgroup = TEGRA_SWGROUP_AFI,       .reg = 0x238 },
1076 	{ .name = "avpc",      .swgroup = TEGRA_SWGROUP_AVPC,      .reg = 0x23c },
1077 	{ .name = "hda",       .swgroup = TEGRA_SWGROUP_HDA,       .reg = 0x254 },
1078 	{ .name = "hc",        .swgroup = TEGRA_SWGROUP_HC,        .reg = 0x250 },
1079 	{ .name = "msenc",     .swgroup = TEGRA_SWGROUP_MSENC,     .reg = 0x264 },
1080 	{ .name = "ppcs",      .swgroup = TEGRA_SWGROUP_PPCS,      .reg = 0x270 },
1081 	{ .name = "sata",      .swgroup = TEGRA_SWGROUP_SATA,      .reg = 0x274 },
1082 	{ .name = "vde",       .swgroup = TEGRA_SWGROUP_VDE,       .reg = 0x27c },
1083 	{ .name = "isp2",      .swgroup = TEGRA_SWGROUP_ISP2,      .reg = 0x258 },
1084 	{ .name = "xusb_host", .swgroup = TEGRA_SWGROUP_XUSB_HOST, .reg = 0x288 },
1085 	{ .name = "xusb_dev",  .swgroup = TEGRA_SWGROUP_XUSB_DEV,  .reg = 0x28c },
1086 	{ .name = "isp2b",     .swgroup = TEGRA_SWGROUP_ISP2B,     .reg = 0xaa4 },
1087 	{ .name = "tsec",      .swgroup = TEGRA_SWGROUP_TSEC,      .reg = 0x294 },
1088 	{ .name = "a9avp",     .swgroup = TEGRA_SWGROUP_A9AVP,     .reg = 0x290 },
1089 	{ .name = "gpu",       .swgroup = TEGRA_SWGROUP_GPU,       .reg = 0xaac },
1090 	{ .name = "sdmmc1a",   .swgroup = TEGRA_SWGROUP_SDMMC1A,   .reg = 0xa94 },
1091 	{ .name = "sdmmc2a",   .swgroup = TEGRA_SWGROUP_SDMMC2A,   .reg = 0xa98 },
1092 	{ .name = "sdmmc3a",   .swgroup = TEGRA_SWGROUP_SDMMC3A,   .reg = 0xa9c },
1093 	{ .name = "sdmmc4a",   .swgroup = TEGRA_SWGROUP_SDMMC4A,   .reg = 0xaa0 },
1094 	{ .name = "vic",       .swgroup = TEGRA_SWGROUP_VIC,       .reg = 0x284 },
1095 	{ .name = "vi",        .swgroup = TEGRA_SWGROUP_VI,        .reg = 0x280 },
1096 };
1097 
1098 static const unsigned int tegra124_group_drm[] = {
1099 	TEGRA_SWGROUP_DC,
1100 	TEGRA_SWGROUP_DCB,
1101 	TEGRA_SWGROUP_VIC,
1102 };
1103 
1104 static const struct tegra_smmu_group_soc tegra124_groups[] = {
1105 	{
1106 		.name = "drm",
1107 		.swgroups = tegra124_group_drm,
1108 		.num_swgroups = ARRAY_SIZE(tegra124_group_drm),
1109 	},
1110 };
1111 
1112 #define TEGRA124_MC_RESET(_name, _control, _status, _bit)	\
1113 	{							\
1114 		.name = #_name,					\
1115 		.id = TEGRA124_MC_RESET_##_name,		\
1116 		.control = _control,				\
1117 		.status = _status,				\
1118 		.bit = _bit,					\
1119 	}
1120 
1121 static const struct tegra_mc_reset tegra124_mc_resets[] = {
1122 	TEGRA124_MC_RESET(AFI,       0x200, 0x204,  0),
1123 	TEGRA124_MC_RESET(AVPC,      0x200, 0x204,  1),
1124 	TEGRA124_MC_RESET(DC,        0x200, 0x204,  2),
1125 	TEGRA124_MC_RESET(DCB,       0x200, 0x204,  3),
1126 	TEGRA124_MC_RESET(HC,        0x200, 0x204,  6),
1127 	TEGRA124_MC_RESET(HDA,       0x200, 0x204,  7),
1128 	TEGRA124_MC_RESET(ISP2,      0x200, 0x204,  8),
1129 	TEGRA124_MC_RESET(MPCORE,    0x200, 0x204,  9),
1130 	TEGRA124_MC_RESET(MPCORELP,  0x200, 0x204, 10),
1131 	TEGRA124_MC_RESET(MSENC,     0x200, 0x204, 11),
1132 	TEGRA124_MC_RESET(PPCS,      0x200, 0x204, 14),
1133 	TEGRA124_MC_RESET(SATA,      0x200, 0x204, 15),
1134 	TEGRA124_MC_RESET(VDE,       0x200, 0x204, 16),
1135 	TEGRA124_MC_RESET(VI,        0x200, 0x204, 17),
1136 	TEGRA124_MC_RESET(VIC,       0x200, 0x204, 18),
1137 	TEGRA124_MC_RESET(XUSB_HOST, 0x200, 0x204, 19),
1138 	TEGRA124_MC_RESET(XUSB_DEV,  0x200, 0x204, 20),
1139 	TEGRA124_MC_RESET(TSEC,      0x200, 0x204, 21),
1140 	TEGRA124_MC_RESET(SDMMC1,    0x200, 0x204, 22),
1141 	TEGRA124_MC_RESET(SDMMC2,    0x200, 0x204, 23),
1142 	TEGRA124_MC_RESET(SDMMC3,    0x200, 0x204, 25),
1143 	TEGRA124_MC_RESET(SDMMC4,    0x970, 0x974,  0),
1144 	TEGRA124_MC_RESET(ISP2B,     0x970, 0x974,  1),
1145 	TEGRA124_MC_RESET(GPU,       0x970, 0x974,  2),
1146 };
1147 
1148 static int tegra124_mc_icc_set(struct icc_node *src, struct icc_node *dst)
1149 {
1150 	/* TODO: program PTSA */
1151 	return 0;
1152 }
1153 
1154 static int tegra124_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
1155 				    u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
1156 {
1157 	/*
1158 	 * ISO clients need to reserve extra bandwidth up-front because
1159 	 * there could be high bandwidth pressure during initial filling
1160 	 * of the client's FIFO buffers.  Secondly, we need to take into
1161 	 * account impurities of the memory subsystem.
1162 	 */
1163 	if (tag & TEGRA_MC_ICC_TAG_ISO)
1164 		peak_bw = tegra_mc_scale_percents(peak_bw, 400);
1165 
1166 	*agg_avg += avg_bw;
1167 	*agg_peak = max(*agg_peak, peak_bw);
1168 
1169 	return 0;
1170 }
1171 
1172 static struct icc_node_data *
1173 tegra124_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
1174 {
1175 	struct tegra_mc *mc = icc_provider_to_tegra_mc(data);
1176 	const struct tegra_mc_client *client;
1177 	unsigned int i, idx = spec->args[0];
1178 	struct icc_node_data *ndata;
1179 	struct icc_node *node;
1180 
1181 	list_for_each_entry(node, &mc->provider.nodes, node_list) {
1182 		if (node->id != idx)
1183 			continue;
1184 
1185 		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
1186 		if (!ndata)
1187 			return ERR_PTR(-ENOMEM);
1188 
1189 		client = &mc->soc->clients[idx];
1190 		ndata->node = node;
1191 
1192 		switch (client->swgroup) {
1193 		case TEGRA_SWGROUP_DC:
1194 		case TEGRA_SWGROUP_DCB:
1195 		case TEGRA_SWGROUP_PTC:
1196 		case TEGRA_SWGROUP_VI:
1197 			/* these clients are isochronous by default */
1198 			ndata->tag = TEGRA_MC_ICC_TAG_ISO;
1199 			break;
1200 
1201 		default:
1202 			ndata->tag = TEGRA_MC_ICC_TAG_DEFAULT;
1203 			break;
1204 		}
1205 
1206 		return ndata;
1207 	}
1208 
1209 	for (i = 0; i < mc->soc->num_clients; i++) {
1210 		if (mc->soc->clients[i].id == idx)
1211 			return ERR_PTR(-EPROBE_DEFER);
1212 	}
1213 
1214 	dev_err(mc->dev, "invalid ICC client ID %u\n", idx);
1215 
1216 	return ERR_PTR(-EINVAL);
1217 }
1218 
1219 static const struct tegra_mc_icc_ops tegra124_mc_icc_ops = {
1220 	.xlate_extended = tegra124_mc_of_icc_xlate_extended,
1221 	.aggregate = tegra124_mc_icc_aggreate,
1222 	.set = tegra124_mc_icc_set,
1223 };
1224 
1225 #ifdef CONFIG_ARCH_TEGRA_124_SOC
1226 static const unsigned long tegra124_mc_emem_regs[] = {
1227 	MC_EMEM_ARB_CFG,
1228 	MC_EMEM_ARB_OUTSTANDING_REQ,
1229 	MC_EMEM_ARB_TIMING_RCD,
1230 	MC_EMEM_ARB_TIMING_RP,
1231 	MC_EMEM_ARB_TIMING_RC,
1232 	MC_EMEM_ARB_TIMING_RAS,
1233 	MC_EMEM_ARB_TIMING_FAW,
1234 	MC_EMEM_ARB_TIMING_RRD,
1235 	MC_EMEM_ARB_TIMING_RAP2PRE,
1236 	MC_EMEM_ARB_TIMING_WAP2PRE,
1237 	MC_EMEM_ARB_TIMING_R2R,
1238 	MC_EMEM_ARB_TIMING_W2W,
1239 	MC_EMEM_ARB_TIMING_R2W,
1240 	MC_EMEM_ARB_TIMING_W2R,
1241 	MC_EMEM_ARB_DA_TURNS,
1242 	MC_EMEM_ARB_DA_COVERS,
1243 	MC_EMEM_ARB_MISC0,
1244 	MC_EMEM_ARB_MISC1,
1245 	MC_EMEM_ARB_RING1_THROTTLE
1246 };
1247 
1248 static const struct tegra_smmu_soc tegra124_smmu_soc = {
1249 	.clients = tegra124_mc_clients,
1250 	.num_clients = ARRAY_SIZE(tegra124_mc_clients),
1251 	.swgroups = tegra124_swgroups,
1252 	.num_swgroups = ARRAY_SIZE(tegra124_swgroups),
1253 	.groups = tegra124_groups,
1254 	.num_groups = ARRAY_SIZE(tegra124_groups),
1255 	.supports_round_robin_arbitration = true,
1256 	.supports_request_limit = true,
1257 	.num_tlb_lines = 32,
1258 	.num_asids = 128,
1259 };
1260 
1261 const struct tegra_mc_soc tegra124_mc_soc = {
1262 	.clients = tegra124_mc_clients,
1263 	.num_clients = ARRAY_SIZE(tegra124_mc_clients),
1264 	.num_address_bits = 34,
1265 	.atom_size = 32,
1266 	.client_id_mask = 0x7f,
1267 	.smmu = &tegra124_smmu_soc,
1268 	.emem_regs = tegra124_mc_emem_regs,
1269 	.num_emem_regs = ARRAY_SIZE(tegra124_mc_emem_regs),
1270 	.intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
1271 		   MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
1272 		   MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
1273 	.reset_ops = &tegra_mc_reset_ops_common,
1274 	.resets = tegra124_mc_resets,
1275 	.num_resets = ARRAY_SIZE(tegra124_mc_resets),
1276 	.icc_ops = &tegra124_mc_icc_ops,
1277 	.ops = &tegra30_mc_ops,
1278 };
1279 #endif /* CONFIG_ARCH_TEGRA_124_SOC */
1280 
1281 #ifdef CONFIG_ARCH_TEGRA_132_SOC
1282 static const struct tegra_smmu_soc tegra132_smmu_soc = {
1283 	.clients = tegra124_mc_clients,
1284 	.num_clients = ARRAY_SIZE(tegra124_mc_clients),
1285 	.swgroups = tegra124_swgroups,
1286 	.num_swgroups = ARRAY_SIZE(tegra124_swgroups),
1287 	.groups = tegra124_groups,
1288 	.num_groups = ARRAY_SIZE(tegra124_groups),
1289 	.supports_round_robin_arbitration = true,
1290 	.supports_request_limit = true,
1291 	.num_tlb_lines = 32,
1292 	.num_asids = 128,
1293 };
1294 
1295 const struct tegra_mc_soc tegra132_mc_soc = {
1296 	.clients = tegra124_mc_clients,
1297 	.num_clients = ARRAY_SIZE(tegra124_mc_clients),
1298 	.num_address_bits = 34,
1299 	.atom_size = 32,
1300 	.client_id_mask = 0x7f,
1301 	.smmu = &tegra132_smmu_soc,
1302 	.intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
1303 		   MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
1304 		   MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
1305 	.reset_ops = &tegra_mc_reset_ops_common,
1306 	.resets = tegra124_mc_resets,
1307 	.num_resets = ARRAY_SIZE(tegra124_mc_resets),
1308 	.icc_ops = &tegra124_mc_icc_ops,
1309 	.ops = &tegra30_mc_ops,
1310 };
1311 #endif /* CONFIG_ARCH_TEGRA_132_SOC */
1312