Loading...
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2017-2021 NVIDIA CORPORATION. All rights reserved.
4 */
5
6#include <linux/io.h>
7#include <linux/iommu.h>
8#include <linux/module.h>
9#include <linux/mod_devicetable.h>
10#include <linux/of.h>
11#include <linux/of_platform.h>
12#include <linux/platform_device.h>
13
14#include <soc/tegra/mc.h>
15
16#if defined(CONFIG_ARCH_TEGRA_186_SOC)
17#include <dt-bindings/memory/tegra186-mc.h>
18#endif
19
20#include "mc.h"
21
22#define MC_SID_STREAMID_OVERRIDE_MASK GENMASK(7, 0)
23#define MC_SID_STREAMID_SECURITY_WRITE_ACCESS_DISABLED BIT(16)
24#define MC_SID_STREAMID_SECURITY_OVERRIDE BIT(8)
25
26static int tegra186_mc_probe(struct tegra_mc *mc)
27{
28 struct platform_device *pdev = to_platform_device(mc->dev);
29 unsigned int i;
30 char name[8];
31 int err;
32
33 mc->bcast_ch_regs = devm_platform_ioremap_resource_byname(pdev, "broadcast");
34 if (IS_ERR(mc->bcast_ch_regs)) {
35 if (PTR_ERR(mc->bcast_ch_regs) == -EINVAL) {
36 dev_warn(&pdev->dev,
37 "Broadcast channel is missing, please update your device-tree\n");
38 mc->bcast_ch_regs = NULL;
39 goto populate;
40 }
41
42 return PTR_ERR(mc->bcast_ch_regs);
43 }
44
45 mc->ch_regs = devm_kcalloc(mc->dev, mc->soc->num_channels, sizeof(*mc->ch_regs),
46 GFP_KERNEL);
47 if (!mc->ch_regs)
48 return -ENOMEM;
49
50 for (i = 0; i < mc->soc->num_channels; i++) {
51 snprintf(name, sizeof(name), "ch%u", i);
52
53 mc->ch_regs[i] = devm_platform_ioremap_resource_byname(pdev, name);
54 if (IS_ERR(mc->ch_regs[i]))
55 return PTR_ERR(mc->ch_regs[i]);
56 }
57
58populate:
59 err = of_platform_populate(mc->dev->of_node, NULL, NULL, mc->dev);
60 if (err < 0)
61 return err;
62
63 return 0;
64}
65
66static void tegra186_mc_remove(struct tegra_mc *mc)
67{
68 of_platform_depopulate(mc->dev);
69}
70
71#if IS_ENABLED(CONFIG_IOMMU_API)
72static void tegra186_mc_client_sid_override(struct tegra_mc *mc,
73 const struct tegra_mc_client *client,
74 unsigned int sid)
75{
76 u32 value, old;
77
78 if (client->regs.sid.security == 0 && client->regs.sid.override == 0)
79 return;
80
81 value = readl(mc->regs + client->regs.sid.security);
82 if ((value & MC_SID_STREAMID_SECURITY_OVERRIDE) == 0) {
83 /*
84 * If the secure firmware has locked this down the override
85 * for this memory client, there's nothing we can do here.
86 */
87 if (value & MC_SID_STREAMID_SECURITY_WRITE_ACCESS_DISABLED)
88 return;
89
90 /*
91 * Otherwise, try to set the override itself. Typically the
92 * secure firmware will never have set this configuration.
93 * Instead, it will either have disabled write access to
94 * this field, or it will already have set an explicit
95 * override itself.
96 */
97 WARN_ON((value & MC_SID_STREAMID_SECURITY_OVERRIDE) == 0);
98
99 value |= MC_SID_STREAMID_SECURITY_OVERRIDE;
100 writel(value, mc->regs + client->regs.sid.security);
101 }
102
103 value = readl(mc->regs + client->regs.sid.override);
104 old = value & MC_SID_STREAMID_OVERRIDE_MASK;
105
106 if (old != sid) {
107 dev_dbg(mc->dev, "overriding SID %x for %s with %x\n", old,
108 client->name, sid);
109 writel(sid, mc->regs + client->regs.sid.override);
110 }
111}
112#endif
113
114static int tegra186_mc_probe_device(struct tegra_mc *mc, struct device *dev)
115{
116#if IS_ENABLED(CONFIG_IOMMU_API)
117 struct of_phandle_args args;
118 unsigned int i, index = 0;
119 u32 sid;
120
121 if (!tegra_dev_iommu_get_stream_id(dev, &sid))
122 return 0;
123
124 while (!of_parse_phandle_with_args(dev->of_node, "interconnects", "#interconnect-cells",
125 index, &args)) {
126 if (args.np == mc->dev->of_node && args.args_count != 0) {
127 for (i = 0; i < mc->soc->num_clients; i++) {
128 const struct tegra_mc_client *client = &mc->soc->clients[i];
129
130 if (client->id == args.args[0])
131 tegra186_mc_client_sid_override(
132 mc, client,
133 sid & MC_SID_STREAMID_OVERRIDE_MASK);
134 }
135 }
136
137 index++;
138 }
139#endif
140
141 return 0;
142}
143
144static int tegra186_mc_resume(struct tegra_mc *mc)
145{
146#if IS_ENABLED(CONFIG_IOMMU_API)
147 unsigned int i;
148
149 for (i = 0; i < mc->soc->num_clients; i++) {
150 const struct tegra_mc_client *client = &mc->soc->clients[i];
151
152 tegra186_mc_client_sid_override(mc, client, client->sid);
153 }
154#endif
155
156 return 0;
157}
158
159const struct tegra_mc_ops tegra186_mc_ops = {
160 .probe = tegra186_mc_probe,
161 .remove = tegra186_mc_remove,
162 .resume = tegra186_mc_resume,
163 .probe_device = tegra186_mc_probe_device,
164 .handle_irq = tegra30_mc_handle_irq,
165};
166
167#if defined(CONFIG_ARCH_TEGRA_186_SOC)
168static const struct tegra_mc_client tegra186_mc_clients[] = {
169 {
170 .id = TEGRA186_MEMORY_CLIENT_PTCR,
171 .name = "ptcr",
172 .sid = TEGRA186_SID_PASSTHROUGH,
173 .regs = {
174 .sid = {
175 .override = 0x000,
176 .security = 0x004,
177 },
178 },
179 }, {
180 .id = TEGRA186_MEMORY_CLIENT_AFIR,
181 .name = "afir",
182 .sid = TEGRA186_SID_AFI,
183 .regs = {
184 .sid = {
185 .override = 0x070,
186 .security = 0x074,
187 },
188 },
189 }, {
190 .id = TEGRA186_MEMORY_CLIENT_HDAR,
191 .name = "hdar",
192 .sid = TEGRA186_SID_HDA,
193 .regs = {
194 .sid = {
195 .override = 0x0a8,
196 .security = 0x0ac,
197 },
198 },
199 }, {
200 .id = TEGRA186_MEMORY_CLIENT_HOST1XDMAR,
201 .name = "host1xdmar",
202 .sid = TEGRA186_SID_HOST1X,
203 .regs = {
204 .sid = {
205 .override = 0x0b0,
206 .security = 0x0b4,
207 },
208 },
209 }, {
210 .id = TEGRA186_MEMORY_CLIENT_NVENCSRD,
211 .name = "nvencsrd",
212 .sid = TEGRA186_SID_NVENC,
213 .regs = {
214 .sid = {
215 .override = 0x0e0,
216 .security = 0x0e4,
217 },
218 },
219 }, {
220 .id = TEGRA186_MEMORY_CLIENT_SATAR,
221 .name = "satar",
222 .sid = TEGRA186_SID_SATA,
223 .regs = {
224 .sid = {
225 .override = 0x0f8,
226 .security = 0x0fc,
227 },
228 },
229 }, {
230 .id = TEGRA186_MEMORY_CLIENT_MPCORER,
231 .name = "mpcorer",
232 .sid = TEGRA186_SID_PASSTHROUGH,
233 .regs = {
234 .sid = {
235 .override = 0x138,
236 .security = 0x13c,
237 },
238 },
239 }, {
240 .id = TEGRA186_MEMORY_CLIENT_NVENCSWR,
241 .name = "nvencswr",
242 .sid = TEGRA186_SID_NVENC,
243 .regs = {
244 .sid = {
245 .override = 0x158,
246 .security = 0x15c,
247 },
248 },
249 }, {
250 .id = TEGRA186_MEMORY_CLIENT_AFIW,
251 .name = "afiw",
252 .sid = TEGRA186_SID_AFI,
253 .regs = {
254 .sid = {
255 .override = 0x188,
256 .security = 0x18c,
257 },
258 },
259 }, {
260 .id = TEGRA186_MEMORY_CLIENT_HDAW,
261 .name = "hdaw",
262 .sid = TEGRA186_SID_HDA,
263 .regs = {
264 .sid = {
265 .override = 0x1a8,
266 .security = 0x1ac,
267 },
268 },
269 }, {
270 .id = TEGRA186_MEMORY_CLIENT_MPCOREW,
271 .name = "mpcorew",
272 .sid = TEGRA186_SID_PASSTHROUGH,
273 .regs = {
274 .sid = {
275 .override = 0x1c8,
276 .security = 0x1cc,
277 },
278 },
279 }, {
280 .id = TEGRA186_MEMORY_CLIENT_SATAW,
281 .name = "sataw",
282 .sid = TEGRA186_SID_SATA,
283 .regs = {
284 .sid = {
285 .override = 0x1e8,
286 .security = 0x1ec,
287 },
288 },
289 }, {
290 .id = TEGRA186_MEMORY_CLIENT_ISPRA,
291 .name = "ispra",
292 .sid = TEGRA186_SID_ISP,
293 .regs = {
294 .sid = {
295 .override = 0x220,
296 .security = 0x224,
297 },
298 },
299 }, {
300 .id = TEGRA186_MEMORY_CLIENT_ISPWA,
301 .name = "ispwa",
302 .sid = TEGRA186_SID_ISP,
303 .regs = {
304 .sid = {
305 .override = 0x230,
306 .security = 0x234,
307 },
308 },
309 }, {
310 .id = TEGRA186_MEMORY_CLIENT_ISPWB,
311 .name = "ispwb",
312 .sid = TEGRA186_SID_ISP,
313 .regs = {
314 .sid = {
315 .override = 0x238,
316 .security = 0x23c,
317 },
318 },
319 }, {
320 .id = TEGRA186_MEMORY_CLIENT_XUSB_HOSTR,
321 .name = "xusb_hostr",
322 .sid = TEGRA186_SID_XUSB_HOST,
323 .regs = {
324 .sid = {
325 .override = 0x250,
326 .security = 0x254,
327 },
328 },
329 }, {
330 .id = TEGRA186_MEMORY_CLIENT_XUSB_HOSTW,
331 .name = "xusb_hostw",
332 .sid = TEGRA186_SID_XUSB_HOST,
333 .regs = {
334 .sid = {
335 .override = 0x258,
336 .security = 0x25c,
337 },
338 },
339 }, {
340 .id = TEGRA186_MEMORY_CLIENT_XUSB_DEVR,
341 .name = "xusb_devr",
342 .sid = TEGRA186_SID_XUSB_DEV,
343 .regs = {
344 .sid = {
345 .override = 0x260,
346 .security = 0x264,
347 },
348 },
349 }, {
350 .id = TEGRA186_MEMORY_CLIENT_XUSB_DEVW,
351 .name = "xusb_devw",
352 .sid = TEGRA186_SID_XUSB_DEV,
353 .regs = {
354 .sid = {
355 .override = 0x268,
356 .security = 0x26c,
357 },
358 },
359 }, {
360 .id = TEGRA186_MEMORY_CLIENT_TSECSRD,
361 .name = "tsecsrd",
362 .sid = TEGRA186_SID_TSEC,
363 .regs = {
364 .sid = {
365 .override = 0x2a0,
366 .security = 0x2a4,
367 },
368 },
369 }, {
370 .id = TEGRA186_MEMORY_CLIENT_TSECSWR,
371 .name = "tsecswr",
372 .sid = TEGRA186_SID_TSEC,
373 .regs = {
374 .sid = {
375 .override = 0x2a8,
376 .security = 0x2ac,
377 },
378 },
379 }, {
380 .id = TEGRA186_MEMORY_CLIENT_GPUSRD,
381 .name = "gpusrd",
382 .sid = TEGRA186_SID_GPU,
383 .regs = {
384 .sid = {
385 .override = 0x2c0,
386 .security = 0x2c4,
387 },
388 },
389 }, {
390 .id = TEGRA186_MEMORY_CLIENT_GPUSWR,
391 .name = "gpuswr",
392 .sid = TEGRA186_SID_GPU,
393 .regs = {
394 .sid = {
395 .override = 0x2c8,
396 .security = 0x2cc,
397 },
398 },
399 }, {
400 .id = TEGRA186_MEMORY_CLIENT_SDMMCRA,
401 .name = "sdmmcra",
402 .sid = TEGRA186_SID_SDMMC1,
403 .regs = {
404 .sid = {
405 .override = 0x300,
406 .security = 0x304,
407 },
408 },
409 }, {
410 .id = TEGRA186_MEMORY_CLIENT_SDMMCRAA,
411 .name = "sdmmcraa",
412 .sid = TEGRA186_SID_SDMMC2,
413 .regs = {
414 .sid = {
415 .override = 0x308,
416 .security = 0x30c,
417 },
418 },
419 }, {
420 .id = TEGRA186_MEMORY_CLIENT_SDMMCR,
421 .name = "sdmmcr",
422 .sid = TEGRA186_SID_SDMMC3,
423 .regs = {
424 .sid = {
425 .override = 0x310,
426 .security = 0x314,
427 },
428 },
429 }, {
430 .id = TEGRA186_MEMORY_CLIENT_SDMMCRAB,
431 .name = "sdmmcrab",
432 .sid = TEGRA186_SID_SDMMC4,
433 .regs = {
434 .sid = {
435 .override = 0x318,
436 .security = 0x31c,
437 },
438 },
439 }, {
440 .id = TEGRA186_MEMORY_CLIENT_SDMMCWA,
441 .name = "sdmmcwa",
442 .sid = TEGRA186_SID_SDMMC1,
443 .regs = {
444 .sid = {
445 .override = 0x320,
446 .security = 0x324,
447 },
448 },
449 }, {
450 .id = TEGRA186_MEMORY_CLIENT_SDMMCWAA,
451 .name = "sdmmcwaa",
452 .sid = TEGRA186_SID_SDMMC2,
453 .regs = {
454 .sid = {
455 .override = 0x328,
456 .security = 0x32c,
457 },
458 },
459 }, {
460 .id = TEGRA186_MEMORY_CLIENT_SDMMCW,
461 .name = "sdmmcw",
462 .sid = TEGRA186_SID_SDMMC3,
463 .regs = {
464 .sid = {
465 .override = 0x330,
466 .security = 0x334,
467 },
468 },
469 }, {
470 .id = TEGRA186_MEMORY_CLIENT_SDMMCWAB,
471 .name = "sdmmcwab",
472 .sid = TEGRA186_SID_SDMMC4,
473 .regs = {
474 .sid = {
475 .override = 0x338,
476 .security = 0x33c,
477 },
478 },
479 }, {
480 .id = TEGRA186_MEMORY_CLIENT_VICSRD,
481 .name = "vicsrd",
482 .sid = TEGRA186_SID_VIC,
483 .regs = {
484 .sid = {
485 .override = 0x360,
486 .security = 0x364,
487 },
488 },
489 }, {
490 .id = TEGRA186_MEMORY_CLIENT_VICSWR,
491 .name = "vicswr",
492 .sid = TEGRA186_SID_VIC,
493 .regs = {
494 .sid = {
495 .override = 0x368,
496 .security = 0x36c,
497 },
498 },
499 }, {
500 .id = TEGRA186_MEMORY_CLIENT_VIW,
501 .name = "viw",
502 .sid = TEGRA186_SID_VI,
503 .regs = {
504 .sid = {
505 .override = 0x390,
506 .security = 0x394,
507 },
508 },
509 }, {
510 .id = TEGRA186_MEMORY_CLIENT_NVDECSRD,
511 .name = "nvdecsrd",
512 .sid = TEGRA186_SID_NVDEC,
513 .regs = {
514 .sid = {
515 .override = 0x3c0,
516 .security = 0x3c4,
517 },
518 },
519 }, {
520 .id = TEGRA186_MEMORY_CLIENT_NVDECSWR,
521 .name = "nvdecswr",
522 .sid = TEGRA186_SID_NVDEC,
523 .regs = {
524 .sid = {
525 .override = 0x3c8,
526 .security = 0x3cc,
527 },
528 },
529 }, {
530 .id = TEGRA186_MEMORY_CLIENT_APER,
531 .name = "aper",
532 .sid = TEGRA186_SID_APE,
533 .regs = {
534 .sid = {
535 .override = 0x3d0,
536 .security = 0x3d4,
537 },
538 },
539 }, {
540 .id = TEGRA186_MEMORY_CLIENT_APEW,
541 .name = "apew",
542 .sid = TEGRA186_SID_APE,
543 .regs = {
544 .sid = {
545 .override = 0x3d8,
546 .security = 0x3dc,
547 },
548 },
549 }, {
550 .id = TEGRA186_MEMORY_CLIENT_NVJPGSRD,
551 .name = "nvjpgsrd",
552 .sid = TEGRA186_SID_NVJPG,
553 .regs = {
554 .sid = {
555 .override = 0x3f0,
556 .security = 0x3f4,
557 },
558 },
559 }, {
560 .id = TEGRA186_MEMORY_CLIENT_NVJPGSWR,
561 .name = "nvjpgswr",
562 .sid = TEGRA186_SID_NVJPG,
563 .regs = {
564 .sid = {
565 .override = 0x3f8,
566 .security = 0x3fc,
567 },
568 },
569 }, {
570 .id = TEGRA186_MEMORY_CLIENT_SESRD,
571 .name = "sesrd",
572 .sid = TEGRA186_SID_SE,
573 .regs = {
574 .sid = {
575 .override = 0x400,
576 .security = 0x404,
577 },
578 },
579 }, {
580 .id = TEGRA186_MEMORY_CLIENT_SESWR,
581 .name = "seswr",
582 .sid = TEGRA186_SID_SE,
583 .regs = {
584 .sid = {
585 .override = 0x408,
586 .security = 0x40c,
587 },
588 },
589 }, {
590 .id = TEGRA186_MEMORY_CLIENT_ETRR,
591 .name = "etrr",
592 .sid = TEGRA186_SID_ETR,
593 .regs = {
594 .sid = {
595 .override = 0x420,
596 .security = 0x424,
597 },
598 },
599 }, {
600 .id = TEGRA186_MEMORY_CLIENT_ETRW,
601 .name = "etrw",
602 .sid = TEGRA186_SID_ETR,
603 .regs = {
604 .sid = {
605 .override = 0x428,
606 .security = 0x42c,
607 },
608 },
609 }, {
610 .id = TEGRA186_MEMORY_CLIENT_TSECSRDB,
611 .name = "tsecsrdb",
612 .sid = TEGRA186_SID_TSECB,
613 .regs = {
614 .sid = {
615 .override = 0x430,
616 .security = 0x434,
617 },
618 },
619 }, {
620 .id = TEGRA186_MEMORY_CLIENT_TSECSWRB,
621 .name = "tsecswrb",
622 .sid = TEGRA186_SID_TSECB,
623 .regs = {
624 .sid = {
625 .override = 0x438,
626 .security = 0x43c,
627 },
628 },
629 }, {
630 .id = TEGRA186_MEMORY_CLIENT_GPUSRD2,
631 .name = "gpusrd2",
632 .sid = TEGRA186_SID_GPU,
633 .regs = {
634 .sid = {
635 .override = 0x440,
636 .security = 0x444,
637 },
638 },
639 }, {
640 .id = TEGRA186_MEMORY_CLIENT_GPUSWR2,
641 .name = "gpuswr2",
642 .sid = TEGRA186_SID_GPU,
643 .regs = {
644 .sid = {
645 .override = 0x448,
646 .security = 0x44c,
647 },
648 },
649 }, {
650 .id = TEGRA186_MEMORY_CLIENT_AXISR,
651 .name = "axisr",
652 .sid = TEGRA186_SID_GPCDMA_0,
653 .regs = {
654 .sid = {
655 .override = 0x460,
656 .security = 0x464,
657 },
658 },
659 }, {
660 .id = TEGRA186_MEMORY_CLIENT_AXISW,
661 .name = "axisw",
662 .sid = TEGRA186_SID_GPCDMA_0,
663 .regs = {
664 .sid = {
665 .override = 0x468,
666 .security = 0x46c,
667 },
668 },
669 }, {
670 .id = TEGRA186_MEMORY_CLIENT_EQOSR,
671 .name = "eqosr",
672 .sid = TEGRA186_SID_EQOS,
673 .regs = {
674 .sid = {
675 .override = 0x470,
676 .security = 0x474,
677 },
678 },
679 }, {
680 .id = TEGRA186_MEMORY_CLIENT_EQOSW,
681 .name = "eqosw",
682 .sid = TEGRA186_SID_EQOS,
683 .regs = {
684 .sid = {
685 .override = 0x478,
686 .security = 0x47c,
687 },
688 },
689 }, {
690 .id = TEGRA186_MEMORY_CLIENT_UFSHCR,
691 .name = "ufshcr",
692 .sid = TEGRA186_SID_UFSHC,
693 .regs = {
694 .sid = {
695 .override = 0x480,
696 .security = 0x484,
697 },
698 },
699 }, {
700 .id = TEGRA186_MEMORY_CLIENT_UFSHCW,
701 .name = "ufshcw",
702 .sid = TEGRA186_SID_UFSHC,
703 .regs = {
704 .sid = {
705 .override = 0x488,
706 .security = 0x48c,
707 },
708 },
709 }, {
710 .id = TEGRA186_MEMORY_CLIENT_NVDISPLAYR,
711 .name = "nvdisplayr",
712 .sid = TEGRA186_SID_NVDISPLAY,
713 .regs = {
714 .sid = {
715 .override = 0x490,
716 .security = 0x494,
717 },
718 },
719 }, {
720 .id = TEGRA186_MEMORY_CLIENT_BPMPR,
721 .name = "bpmpr",
722 .sid = TEGRA186_SID_BPMP,
723 .regs = {
724 .sid = {
725 .override = 0x498,
726 .security = 0x49c,
727 },
728 },
729 }, {
730 .id = TEGRA186_MEMORY_CLIENT_BPMPW,
731 .name = "bpmpw",
732 .sid = TEGRA186_SID_BPMP,
733 .regs = {
734 .sid = {
735 .override = 0x4a0,
736 .security = 0x4a4,
737 },
738 },
739 }, {
740 .id = TEGRA186_MEMORY_CLIENT_BPMPDMAR,
741 .name = "bpmpdmar",
742 .sid = TEGRA186_SID_BPMP,
743 .regs = {
744 .sid = {
745 .override = 0x4a8,
746 .security = 0x4ac,
747 },
748 },
749 }, {
750 .id = TEGRA186_MEMORY_CLIENT_BPMPDMAW,
751 .name = "bpmpdmaw",
752 .sid = TEGRA186_SID_BPMP,
753 .regs = {
754 .sid = {
755 .override = 0x4b0,
756 .security = 0x4b4,
757 },
758 },
759 }, {
760 .id = TEGRA186_MEMORY_CLIENT_AONR,
761 .name = "aonr",
762 .sid = TEGRA186_SID_AON,
763 .regs = {
764 .sid = {
765 .override = 0x4b8,
766 .security = 0x4bc,
767 },
768 },
769 }, {
770 .id = TEGRA186_MEMORY_CLIENT_AONW,
771 .name = "aonw",
772 .sid = TEGRA186_SID_AON,
773 .regs = {
774 .sid = {
775 .override = 0x4c0,
776 .security = 0x4c4,
777 },
778 },
779 }, {
780 .id = TEGRA186_MEMORY_CLIENT_AONDMAR,
781 .name = "aondmar",
782 .sid = TEGRA186_SID_AON,
783 .regs = {
784 .sid = {
785 .override = 0x4c8,
786 .security = 0x4cc,
787 },
788 },
789 }, {
790 .id = TEGRA186_MEMORY_CLIENT_AONDMAW,
791 .name = "aondmaw",
792 .sid = TEGRA186_SID_AON,
793 .regs = {
794 .sid = {
795 .override = 0x4d0,
796 .security = 0x4d4,
797 },
798 },
799 }, {
800 .id = TEGRA186_MEMORY_CLIENT_SCER,
801 .name = "scer",
802 .sid = TEGRA186_SID_SCE,
803 .regs = {
804 .sid = {
805 .override = 0x4d8,
806 .security = 0x4dc,
807 },
808 },
809 }, {
810 .id = TEGRA186_MEMORY_CLIENT_SCEW,
811 .name = "scew",
812 .sid = TEGRA186_SID_SCE,
813 .regs = {
814 .sid = {
815 .override = 0x4e0,
816 .security = 0x4e4,
817 },
818 },
819 }, {
820 .id = TEGRA186_MEMORY_CLIENT_SCEDMAR,
821 .name = "scedmar",
822 .sid = TEGRA186_SID_SCE,
823 .regs = {
824 .sid = {
825 .override = 0x4e8,
826 .security = 0x4ec,
827 },
828 },
829 }, {
830 .id = TEGRA186_MEMORY_CLIENT_SCEDMAW,
831 .name = "scedmaw",
832 .sid = TEGRA186_SID_SCE,
833 .regs = {
834 .sid = {
835 .override = 0x4f0,
836 .security = 0x4f4,
837 },
838 },
839 }, {
840 .id = TEGRA186_MEMORY_CLIENT_APEDMAR,
841 .name = "apedmar",
842 .sid = TEGRA186_SID_APE,
843 .regs = {
844 .sid = {
845 .override = 0x4f8,
846 .security = 0x4fc,
847 },
848 },
849 }, {
850 .id = TEGRA186_MEMORY_CLIENT_APEDMAW,
851 .name = "apedmaw",
852 .sid = TEGRA186_SID_APE,
853 .regs = {
854 .sid = {
855 .override = 0x500,
856 .security = 0x504,
857 },
858 },
859 }, {
860 .id = TEGRA186_MEMORY_CLIENT_NVDISPLAYR1,
861 .name = "nvdisplayr1",
862 .sid = TEGRA186_SID_NVDISPLAY,
863 .regs = {
864 .sid = {
865 .override = 0x508,
866 .security = 0x50c,
867 },
868 },
869 }, {
870 .id = TEGRA186_MEMORY_CLIENT_VICSRD1,
871 .name = "vicsrd1",
872 .sid = TEGRA186_SID_VIC,
873 .regs = {
874 .sid = {
875 .override = 0x510,
876 .security = 0x514,
877 },
878 },
879 }, {
880 .id = TEGRA186_MEMORY_CLIENT_NVDECSRD1,
881 .name = "nvdecsrd1",
882 .sid = TEGRA186_SID_NVDEC,
883 .regs = {
884 .sid = {
885 .override = 0x518,
886 .security = 0x51c,
887 },
888 },
889 },
890};
891
892const struct tegra_mc_soc tegra186_mc_soc = {
893 .num_clients = ARRAY_SIZE(tegra186_mc_clients),
894 .clients = tegra186_mc_clients,
895 .num_address_bits = 40,
896 .num_channels = 4,
897 .client_id_mask = 0xff,
898 .intmask = MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS |
899 MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
900 MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
901 .ops = &tegra186_mc_ops,
902 .ch_intmask = 0x0000000f,
903 .global_intstatus_channel_shift = 0,
904};
905#endif
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved.
4 */
5
6#include <linux/io.h>
7#include <linux/module.h>
8#include <linux/mod_devicetable.h>
9#include <linux/platform_device.h>
10
11#include <dt-bindings/memory/tegra186-mc.h>
12
13struct tegra_mc {
14 struct device *dev;
15 void __iomem *regs;
16};
17
18struct tegra_mc_client {
19 const char *name;
20 unsigned int sid;
21 struct {
22 unsigned int override;
23 unsigned int security;
24 } regs;
25};
26
27static const struct tegra_mc_client tegra186_mc_clients[] = {
28 {
29 .name = "ptcr",
30 .sid = TEGRA186_SID_PASSTHROUGH,
31 .regs = {
32 .override = 0x000,
33 .security = 0x004,
34 },
35 }, {
36 .name = "afir",
37 .sid = TEGRA186_SID_AFI,
38 .regs = {
39 .override = 0x070,
40 .security = 0x074,
41 },
42 }, {
43 .name = "hdar",
44 .sid = TEGRA186_SID_HDA,
45 .regs = {
46 .override = 0x0a8,
47 .security = 0x0ac,
48 },
49 }, {
50 .name = "host1xdmar",
51 .sid = TEGRA186_SID_HOST1X,
52 .regs = {
53 .override = 0x0b0,
54 .security = 0x0b4,
55 },
56 }, {
57 .name = "nvencsrd",
58 .sid = TEGRA186_SID_NVENC,
59 .regs = {
60 .override = 0x0e0,
61 .security = 0x0e4,
62 },
63 }, {
64 .name = "satar",
65 .sid = TEGRA186_SID_SATA,
66 .regs = {
67 .override = 0x0f8,
68 .security = 0x0fc,
69 },
70 }, {
71 .name = "mpcorer",
72 .sid = TEGRA186_SID_PASSTHROUGH,
73 .regs = {
74 .override = 0x138,
75 .security = 0x13c,
76 },
77 }, {
78 .name = "nvencswr",
79 .sid = TEGRA186_SID_NVENC,
80 .regs = {
81 .override = 0x158,
82 .security = 0x15c,
83 },
84 }, {
85 .name = "afiw",
86 .sid = TEGRA186_SID_AFI,
87 .regs = {
88 .override = 0x188,
89 .security = 0x18c,
90 },
91 }, {
92 .name = "hdaw",
93 .sid = TEGRA186_SID_HDA,
94 .regs = {
95 .override = 0x1a8,
96 .security = 0x1ac,
97 },
98 }, {
99 .name = "mpcorew",
100 .sid = TEGRA186_SID_PASSTHROUGH,
101 .regs = {
102 .override = 0x1c8,
103 .security = 0x1cc,
104 },
105 }, {
106 .name = "sataw",
107 .sid = TEGRA186_SID_SATA,
108 .regs = {
109 .override = 0x1e8,
110 .security = 0x1ec,
111 },
112 }, {
113 .name = "ispra",
114 .sid = TEGRA186_SID_ISP,
115 .regs = {
116 .override = 0x220,
117 .security = 0x224,
118 },
119 }, {
120 .name = "ispwa",
121 .sid = TEGRA186_SID_ISP,
122 .regs = {
123 .override = 0x230,
124 .security = 0x234,
125 },
126 }, {
127 .name = "ispwb",
128 .sid = TEGRA186_SID_ISP,
129 .regs = {
130 .override = 0x238,
131 .security = 0x23c,
132 },
133 }, {
134 .name = "xusb_hostr",
135 .sid = TEGRA186_SID_XUSB_HOST,
136 .regs = {
137 .override = 0x250,
138 .security = 0x254,
139 },
140 }, {
141 .name = "xusb_hostw",
142 .sid = TEGRA186_SID_XUSB_HOST,
143 .regs = {
144 .override = 0x258,
145 .security = 0x25c,
146 },
147 }, {
148 .name = "xusb_devr",
149 .sid = TEGRA186_SID_XUSB_DEV,
150 .regs = {
151 .override = 0x260,
152 .security = 0x264,
153 },
154 }, {
155 .name = "xusb_devw",
156 .sid = TEGRA186_SID_XUSB_DEV,
157 .regs = {
158 .override = 0x268,
159 .security = 0x26c,
160 },
161 }, {
162 .name = "tsecsrd",
163 .sid = TEGRA186_SID_TSEC,
164 .regs = {
165 .override = 0x2a0,
166 .security = 0x2a4,
167 },
168 }, {
169 .name = "tsecswr",
170 .sid = TEGRA186_SID_TSEC,
171 .regs = {
172 .override = 0x2a8,
173 .security = 0x2ac,
174 },
175 }, {
176 .name = "gpusrd",
177 .sid = TEGRA186_SID_GPU,
178 .regs = {
179 .override = 0x2c0,
180 .security = 0x2c4,
181 },
182 }, {
183 .name = "gpuswr",
184 .sid = TEGRA186_SID_GPU,
185 .regs = {
186 .override = 0x2c8,
187 .security = 0x2cc,
188 },
189 }, {
190 .name = "sdmmcra",
191 .sid = TEGRA186_SID_SDMMC1,
192 .regs = {
193 .override = 0x300,
194 .security = 0x304,
195 },
196 }, {
197 .name = "sdmmcraa",
198 .sid = TEGRA186_SID_SDMMC2,
199 .regs = {
200 .override = 0x308,
201 .security = 0x30c,
202 },
203 }, {
204 .name = "sdmmcr",
205 .sid = TEGRA186_SID_SDMMC3,
206 .regs = {
207 .override = 0x310,
208 .security = 0x314,
209 },
210 }, {
211 .name = "sdmmcrab",
212 .sid = TEGRA186_SID_SDMMC4,
213 .regs = {
214 .override = 0x318,
215 .security = 0x31c,
216 },
217 }, {
218 .name = "sdmmcwa",
219 .sid = TEGRA186_SID_SDMMC1,
220 .regs = {
221 .override = 0x320,
222 .security = 0x324,
223 },
224 }, {
225 .name = "sdmmcwaa",
226 .sid = TEGRA186_SID_SDMMC2,
227 .regs = {
228 .override = 0x328,
229 .security = 0x32c,
230 },
231 }, {
232 .name = "sdmmcw",
233 .sid = TEGRA186_SID_SDMMC3,
234 .regs = {
235 .override = 0x330,
236 .security = 0x334,
237 },
238 }, {
239 .name = "sdmmcwab",
240 .sid = TEGRA186_SID_SDMMC4,
241 .regs = {
242 .override = 0x338,
243 .security = 0x33c,
244 },
245 }, {
246 .name = "vicsrd",
247 .sid = TEGRA186_SID_VIC,
248 .regs = {
249 .override = 0x360,
250 .security = 0x364,
251 },
252 }, {
253 .name = "vicswr",
254 .sid = TEGRA186_SID_VIC,
255 .regs = {
256 .override = 0x368,
257 .security = 0x36c,
258 },
259 }, {
260 .name = "viw",
261 .sid = TEGRA186_SID_VI,
262 .regs = {
263 .override = 0x390,
264 .security = 0x394,
265 },
266 }, {
267 .name = "nvdecsrd",
268 .sid = TEGRA186_SID_NVDEC,
269 .regs = {
270 .override = 0x3c0,
271 .security = 0x3c4,
272 },
273 }, {
274 .name = "nvdecswr",
275 .sid = TEGRA186_SID_NVDEC,
276 .regs = {
277 .override = 0x3c8,
278 .security = 0x3cc,
279 },
280 }, {
281 .name = "aper",
282 .sid = TEGRA186_SID_APE,
283 .regs = {
284 .override = 0x3d0,
285 .security = 0x3d4,
286 },
287 }, {
288 .name = "apew",
289 .sid = TEGRA186_SID_APE,
290 .regs = {
291 .override = 0x3d8,
292 .security = 0x3dc,
293 },
294 }, {
295 .name = "nvjpgsrd",
296 .sid = TEGRA186_SID_NVJPG,
297 .regs = {
298 .override = 0x3f0,
299 .security = 0x3f4,
300 },
301 }, {
302 .name = "nvjpgswr",
303 .sid = TEGRA186_SID_NVJPG,
304 .regs = {
305 .override = 0x3f8,
306 .security = 0x3fc,
307 },
308 }, {
309 .name = "sesrd",
310 .sid = TEGRA186_SID_SE,
311 .regs = {
312 .override = 0x400,
313 .security = 0x404,
314 },
315 }, {
316 .name = "seswr",
317 .sid = TEGRA186_SID_SE,
318 .regs = {
319 .override = 0x408,
320 .security = 0x40c,
321 },
322 }, {
323 .name = "etrr",
324 .sid = TEGRA186_SID_ETR,
325 .regs = {
326 .override = 0x420,
327 .security = 0x424,
328 },
329 }, {
330 .name = "etrw",
331 .sid = TEGRA186_SID_ETR,
332 .regs = {
333 .override = 0x428,
334 .security = 0x42c,
335 },
336 }, {
337 .name = "tsecsrdb",
338 .sid = TEGRA186_SID_TSECB,
339 .regs = {
340 .override = 0x430,
341 .security = 0x434,
342 },
343 }, {
344 .name = "tsecswrb",
345 .sid = TEGRA186_SID_TSECB,
346 .regs = {
347 .override = 0x438,
348 .security = 0x43c,
349 },
350 }, {
351 .name = "gpusrd2",
352 .sid = TEGRA186_SID_GPU,
353 .regs = {
354 .override = 0x440,
355 .security = 0x444,
356 },
357 }, {
358 .name = "gpuswr2",
359 .sid = TEGRA186_SID_GPU,
360 .regs = {
361 .override = 0x448,
362 .security = 0x44c,
363 },
364 }, {
365 .name = "axisr",
366 .sid = TEGRA186_SID_GPCDMA_0,
367 .regs = {
368 .override = 0x460,
369 .security = 0x464,
370 },
371 }, {
372 .name = "axisw",
373 .sid = TEGRA186_SID_GPCDMA_0,
374 .regs = {
375 .override = 0x468,
376 .security = 0x46c,
377 },
378 }, {
379 .name = "eqosr",
380 .sid = TEGRA186_SID_EQOS,
381 .regs = {
382 .override = 0x470,
383 .security = 0x474,
384 },
385 }, {
386 .name = "eqosw",
387 .sid = TEGRA186_SID_EQOS,
388 .regs = {
389 .override = 0x478,
390 .security = 0x47c,
391 },
392 }, {
393 .name = "ufshcr",
394 .sid = TEGRA186_SID_UFSHC,
395 .regs = {
396 .override = 0x480,
397 .security = 0x484,
398 },
399 }, {
400 .name = "ufshcw",
401 .sid = TEGRA186_SID_UFSHC,
402 .regs = {
403 .override = 0x488,
404 .security = 0x48c,
405 },
406 }, {
407 .name = "nvdisplayr",
408 .sid = TEGRA186_SID_NVDISPLAY,
409 .regs = {
410 .override = 0x490,
411 .security = 0x494,
412 },
413 }, {
414 .name = "bpmpr",
415 .sid = TEGRA186_SID_BPMP,
416 .regs = {
417 .override = 0x498,
418 .security = 0x49c,
419 },
420 }, {
421 .name = "bpmpw",
422 .sid = TEGRA186_SID_BPMP,
423 .regs = {
424 .override = 0x4a0,
425 .security = 0x4a4,
426 },
427 }, {
428 .name = "bpmpdmar",
429 .sid = TEGRA186_SID_BPMP,
430 .regs = {
431 .override = 0x4a8,
432 .security = 0x4ac,
433 },
434 }, {
435 .name = "bpmpdmaw",
436 .sid = TEGRA186_SID_BPMP,
437 .regs = {
438 .override = 0x4b0,
439 .security = 0x4b4,
440 },
441 }, {
442 .name = "aonr",
443 .sid = TEGRA186_SID_AON,
444 .regs = {
445 .override = 0x4b8,
446 .security = 0x4bc,
447 },
448 }, {
449 .name = "aonw",
450 .sid = TEGRA186_SID_AON,
451 .regs = {
452 .override = 0x4c0,
453 .security = 0x4c4,
454 },
455 }, {
456 .name = "aondmar",
457 .sid = TEGRA186_SID_AON,
458 .regs = {
459 .override = 0x4c8,
460 .security = 0x4cc,
461 },
462 }, {
463 .name = "aondmaw",
464 .sid = TEGRA186_SID_AON,
465 .regs = {
466 .override = 0x4d0,
467 .security = 0x4d4,
468 },
469 }, {
470 .name = "scer",
471 .sid = TEGRA186_SID_SCE,
472 .regs = {
473 .override = 0x4d8,
474 .security = 0x4dc,
475 },
476 }, {
477 .name = "scew",
478 .sid = TEGRA186_SID_SCE,
479 .regs = {
480 .override = 0x4e0,
481 .security = 0x4e4,
482 },
483 }, {
484 .name = "scedmar",
485 .sid = TEGRA186_SID_SCE,
486 .regs = {
487 .override = 0x4e8,
488 .security = 0x4ec,
489 },
490 }, {
491 .name = "scedmaw",
492 .sid = TEGRA186_SID_SCE,
493 .regs = {
494 .override = 0x4f0,
495 .security = 0x4f4,
496 },
497 }, {
498 .name = "apedmar",
499 .sid = TEGRA186_SID_APE,
500 .regs = {
501 .override = 0x4f8,
502 .security = 0x4fc,
503 },
504 }, {
505 .name = "apedmaw",
506 .sid = TEGRA186_SID_APE,
507 .regs = {
508 .override = 0x500,
509 .security = 0x504,
510 },
511 }, {
512 .name = "nvdisplayr1",
513 .sid = TEGRA186_SID_NVDISPLAY,
514 .regs = {
515 .override = 0x508,
516 .security = 0x50c,
517 },
518 }, {
519 .name = "vicsrd1",
520 .sid = TEGRA186_SID_VIC,
521 .regs = {
522 .override = 0x510,
523 .security = 0x514,
524 },
525 }, {
526 .name = "nvdecsrd1",
527 .sid = TEGRA186_SID_NVDEC,
528 .regs = {
529 .override = 0x518,
530 .security = 0x51c,
531 },
532 },
533};
534
535static int tegra186_mc_probe(struct platform_device *pdev)
536{
537 struct resource *res;
538 struct tegra_mc *mc;
539 unsigned int i;
540 int err = 0;
541
542 mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
543 if (!mc)
544 return -ENOMEM;
545
546 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
547 mc->regs = devm_ioremap_resource(&pdev->dev, res);
548 if (IS_ERR(mc->regs))
549 return PTR_ERR(mc->regs);
550
551 mc->dev = &pdev->dev;
552
553 for (i = 0; i < ARRAY_SIZE(tegra186_mc_clients); i++) {
554 const struct tegra_mc_client *client = &tegra186_mc_clients[i];
555 u32 override, security;
556
557 override = readl(mc->regs + client->regs.override);
558 security = readl(mc->regs + client->regs.security);
559
560 dev_dbg(&pdev->dev, "client %s: override: %x security: %x\n",
561 client->name, override, security);
562
563 dev_dbg(&pdev->dev, "setting SID %u for %s\n", client->sid,
564 client->name);
565 writel(client->sid, mc->regs + client->regs.override);
566
567 override = readl(mc->regs + client->regs.override);
568 security = readl(mc->regs + client->regs.security);
569
570 dev_dbg(&pdev->dev, "client %s: override: %x security: %x\n",
571 client->name, override, security);
572 }
573
574 platform_set_drvdata(pdev, mc);
575
576 return err;
577}
578
579static const struct of_device_id tegra186_mc_of_match[] = {
580 { .compatible = "nvidia,tegra186-mc", },
581 { /* sentinel */ }
582};
583MODULE_DEVICE_TABLE(of, tegra186_mc_of_match);
584
585static struct platform_driver tegra186_mc_driver = {
586 .driver = {
587 .name = "tegra186-mc",
588 .of_match_table = tegra186_mc_of_match,
589 .suppress_bind_attrs = true,
590 },
591 .prevent_deferred_probe = true,
592 .probe = tegra186_mc_probe,
593};
594module_platform_driver(tegra186_mc_driver);
595
596MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
597MODULE_DESCRIPTION("NVIDIA Tegra186 Memory Controller driver");
598MODULE_LICENSE("GPL v2");