Merge tag 'mvebu-drivers-5.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / memory / tegra / tegra30.c
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
14 static 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
35 static 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
1141 static 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
1160 static 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
1168 static 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
1176 static 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
1198 static 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
1219 static 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
1291 static 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
1316 static 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
1334 static struct icc_node_data *
1335 tegra30_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
1381 static 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
1387 const 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 };