1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2017-2021 NVIDIA CORPORATION. All rights reserved.
7 #include <linux/iommu.h>
8 #include <linux/module.h>
9 #include <linux/mod_devicetable.h>
10 #include <linux/of_device.h>
11 #include <linux/platform_device.h>
13 #include <soc/tegra/mc.h>
15 #if defined(CONFIG_ARCH_TEGRA_186_SOC)
16 #include <dt-bindings/memory/tegra186-mc.h>
19 #define MC_SID_STREAMID_OVERRIDE_MASK GENMASK(7, 0)
20 #define MC_SID_STREAMID_SECURITY_WRITE_ACCESS_DISABLED BIT(16)
21 #define MC_SID_STREAMID_SECURITY_OVERRIDE BIT(8)
23 static void tegra186_mc_program_sid(struct tegra_mc *mc)
27 for (i = 0; i < mc->soc->num_clients; i++) {
28 const struct tegra_mc_client *client = &mc->soc->clients[i];
29 u32 override, security;
31 override = readl(mc->regs + client->regs.sid.override);
32 security = readl(mc->regs + client->regs.sid.security);
34 dev_dbg(mc->dev, "client %s: override: %x security: %x\n",
35 client->name, override, security);
37 dev_dbg(mc->dev, "setting SID %u for %s\n", client->sid,
39 writel(client->sid, mc->regs + client->regs.sid.override);
41 override = readl(mc->regs + client->regs.sid.override);
42 security = readl(mc->regs + client->regs.sid.security);
44 dev_dbg(mc->dev, "client %s: override: %x security: %x\n",
45 client->name, override, security);
49 static int tegra186_mc_probe(struct tegra_mc *mc)
53 err = of_platform_populate(mc->dev->of_node, NULL, NULL, mc->dev);
57 tegra186_mc_program_sid(mc);
62 static void tegra186_mc_remove(struct tegra_mc *mc)
64 of_platform_depopulate(mc->dev);
67 static int tegra186_mc_resume(struct tegra_mc *mc)
69 tegra186_mc_program_sid(mc);
74 static void tegra186_mc_client_sid_override(struct tegra_mc *mc,
75 const struct tegra_mc_client *client,
80 value = readl(mc->regs + client->regs.sid.security);
81 if ((value & MC_SID_STREAMID_SECURITY_OVERRIDE) == 0) {
83 * If the secure firmware has locked this down the override
84 * for this memory client, there's nothing we can do here.
86 if (value & MC_SID_STREAMID_SECURITY_WRITE_ACCESS_DISABLED)
90 * Otherwise, try to set the override itself. Typically the
91 * secure firmware will never have set this configuration.
92 * Instead, it will either have disabled write access to
93 * this field, or it will already have set an explicit
96 WARN_ON((value & MC_SID_STREAMID_SECURITY_OVERRIDE) == 0);
98 value |= MC_SID_STREAMID_SECURITY_OVERRIDE;
99 writel(value, mc->regs + client->regs.sid.security);
102 value = readl(mc->regs + client->regs.sid.override);
103 old = value & MC_SID_STREAMID_OVERRIDE_MASK;
106 dev_dbg(mc->dev, "overriding SID %x for %s with %x\n", old,
108 writel(sid, mc->regs + client->regs.sid.override);
112 static int tegra186_mc_probe_device(struct tegra_mc *mc, struct device *dev)
114 #if IS_ENABLED(CONFIG_IOMMU_API)
115 struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
116 struct of_phandle_args args;
117 unsigned int i, index = 0;
119 while (!of_parse_phandle_with_args(dev->of_node, "interconnects", "#interconnect-cells",
121 if (args.np == mc->dev->of_node && args.args_count != 0) {
122 for (i = 0; i < mc->soc->num_clients; i++) {
123 const struct tegra_mc_client *client = &mc->soc->clients[i];
125 if (client->id == args.args[0]) {
126 u32 sid = fwspec->ids[0] & MC_SID_STREAMID_OVERRIDE_MASK;
128 tegra186_mc_client_sid_override(mc, client, sid);
140 const struct tegra_mc_ops tegra186_mc_ops = {
141 .probe = tegra186_mc_probe,
142 .remove = tegra186_mc_remove,
143 .resume = tegra186_mc_resume,
144 .probe_device = tegra186_mc_probe_device,
147 #if defined(CONFIG_ARCH_TEGRA_186_SOC)
148 static const struct tegra_mc_client tegra186_mc_clients[] = {
150 .id = TEGRA186_MEMORY_CLIENT_PTCR,
152 .sid = TEGRA186_SID_PASSTHROUGH,
160 .id = TEGRA186_MEMORY_CLIENT_AFIR,
162 .sid = TEGRA186_SID_AFI,
170 .id = TEGRA186_MEMORY_CLIENT_HDAR,
172 .sid = TEGRA186_SID_HDA,
180 .id = TEGRA186_MEMORY_CLIENT_HOST1XDMAR,
181 .name = "host1xdmar",
182 .sid = TEGRA186_SID_HOST1X,
190 .id = TEGRA186_MEMORY_CLIENT_NVENCSRD,
192 .sid = TEGRA186_SID_NVENC,
200 .id = TEGRA186_MEMORY_CLIENT_SATAR,
202 .sid = TEGRA186_SID_SATA,
210 .id = TEGRA186_MEMORY_CLIENT_MPCORER,
212 .sid = TEGRA186_SID_PASSTHROUGH,
220 .id = TEGRA186_MEMORY_CLIENT_NVENCSWR,
222 .sid = TEGRA186_SID_NVENC,
230 .id = TEGRA186_MEMORY_CLIENT_AFIW,
232 .sid = TEGRA186_SID_AFI,
240 .id = TEGRA186_MEMORY_CLIENT_HDAW,
242 .sid = TEGRA186_SID_HDA,
250 .id = TEGRA186_MEMORY_CLIENT_MPCOREW,
252 .sid = TEGRA186_SID_PASSTHROUGH,
260 .id = TEGRA186_MEMORY_CLIENT_SATAW,
262 .sid = TEGRA186_SID_SATA,
270 .id = TEGRA186_MEMORY_CLIENT_ISPRA,
272 .sid = TEGRA186_SID_ISP,
280 .id = TEGRA186_MEMORY_CLIENT_ISPWA,
282 .sid = TEGRA186_SID_ISP,
290 .id = TEGRA186_MEMORY_CLIENT_ISPWB,
292 .sid = TEGRA186_SID_ISP,
300 .id = TEGRA186_MEMORY_CLIENT_XUSB_HOSTR,
301 .name = "xusb_hostr",
302 .sid = TEGRA186_SID_XUSB_HOST,
310 .id = TEGRA186_MEMORY_CLIENT_XUSB_HOSTW,
311 .name = "xusb_hostw",
312 .sid = TEGRA186_SID_XUSB_HOST,
320 .id = TEGRA186_MEMORY_CLIENT_XUSB_DEVR,
322 .sid = TEGRA186_SID_XUSB_DEV,
330 .id = TEGRA186_MEMORY_CLIENT_XUSB_DEVW,
332 .sid = TEGRA186_SID_XUSB_DEV,
340 .id = TEGRA186_MEMORY_CLIENT_TSECSRD,
342 .sid = TEGRA186_SID_TSEC,
350 .id = TEGRA186_MEMORY_CLIENT_TSECSWR,
352 .sid = TEGRA186_SID_TSEC,
360 .id = TEGRA186_MEMORY_CLIENT_GPUSRD,
362 .sid = TEGRA186_SID_GPU,
370 .id = TEGRA186_MEMORY_CLIENT_GPUSWR,
372 .sid = TEGRA186_SID_GPU,
380 .id = TEGRA186_MEMORY_CLIENT_SDMMCRA,
382 .sid = TEGRA186_SID_SDMMC1,
390 .id = TEGRA186_MEMORY_CLIENT_SDMMCRAA,
392 .sid = TEGRA186_SID_SDMMC2,
400 .id = TEGRA186_MEMORY_CLIENT_SDMMCR,
402 .sid = TEGRA186_SID_SDMMC3,
410 .id = TEGRA186_MEMORY_CLIENT_SDMMCRAB,
412 .sid = TEGRA186_SID_SDMMC4,
420 .id = TEGRA186_MEMORY_CLIENT_SDMMCWA,
422 .sid = TEGRA186_SID_SDMMC1,
430 .id = TEGRA186_MEMORY_CLIENT_SDMMCWAA,
432 .sid = TEGRA186_SID_SDMMC2,
440 .id = TEGRA186_MEMORY_CLIENT_SDMMCW,
442 .sid = TEGRA186_SID_SDMMC3,
450 .id = TEGRA186_MEMORY_CLIENT_SDMMCWAB,
452 .sid = TEGRA186_SID_SDMMC4,
460 .id = TEGRA186_MEMORY_CLIENT_VICSRD,
462 .sid = TEGRA186_SID_VIC,
470 .id = TEGRA186_MEMORY_CLIENT_VICSWR,
472 .sid = TEGRA186_SID_VIC,
480 .id = TEGRA186_MEMORY_CLIENT_VIW,
482 .sid = TEGRA186_SID_VI,
490 .id = TEGRA186_MEMORY_CLIENT_NVDECSRD,
492 .sid = TEGRA186_SID_NVDEC,
500 .id = TEGRA186_MEMORY_CLIENT_NVDECSWR,
502 .sid = TEGRA186_SID_NVDEC,
510 .id = TEGRA186_MEMORY_CLIENT_APER,
512 .sid = TEGRA186_SID_APE,
520 .id = TEGRA186_MEMORY_CLIENT_APEW,
522 .sid = TEGRA186_SID_APE,
530 .id = TEGRA186_MEMORY_CLIENT_NVJPGSRD,
532 .sid = TEGRA186_SID_NVJPG,
540 .id = TEGRA186_MEMORY_CLIENT_NVJPGSWR,
542 .sid = TEGRA186_SID_NVJPG,
550 .id = TEGRA186_MEMORY_CLIENT_SESRD,
552 .sid = TEGRA186_SID_SE,
560 .id = TEGRA186_MEMORY_CLIENT_SESWR,
562 .sid = TEGRA186_SID_SE,
570 .id = TEGRA186_MEMORY_CLIENT_ETRR,
572 .sid = TEGRA186_SID_ETR,
580 .id = TEGRA186_MEMORY_CLIENT_ETRW,
582 .sid = TEGRA186_SID_ETR,
590 .id = TEGRA186_MEMORY_CLIENT_TSECSRDB,
592 .sid = TEGRA186_SID_TSECB,
600 .id = TEGRA186_MEMORY_CLIENT_TSECSWRB,
602 .sid = TEGRA186_SID_TSECB,
610 .id = TEGRA186_MEMORY_CLIENT_GPUSRD2,
612 .sid = TEGRA186_SID_GPU,
620 .id = TEGRA186_MEMORY_CLIENT_GPUSWR2,
622 .sid = TEGRA186_SID_GPU,
630 .id = TEGRA186_MEMORY_CLIENT_AXISR,
632 .sid = TEGRA186_SID_GPCDMA_0,
640 .id = TEGRA186_MEMORY_CLIENT_AXISW,
642 .sid = TEGRA186_SID_GPCDMA_0,
650 .id = TEGRA186_MEMORY_CLIENT_EQOSR,
652 .sid = TEGRA186_SID_EQOS,
660 .id = TEGRA186_MEMORY_CLIENT_EQOSW,
662 .sid = TEGRA186_SID_EQOS,
670 .id = TEGRA186_MEMORY_CLIENT_UFSHCR,
672 .sid = TEGRA186_SID_UFSHC,
680 .id = TEGRA186_MEMORY_CLIENT_UFSHCW,
682 .sid = TEGRA186_SID_UFSHC,
690 .id = TEGRA186_MEMORY_CLIENT_NVDISPLAYR,
691 .name = "nvdisplayr",
692 .sid = TEGRA186_SID_NVDISPLAY,
700 .id = TEGRA186_MEMORY_CLIENT_BPMPR,
702 .sid = TEGRA186_SID_BPMP,
710 .id = TEGRA186_MEMORY_CLIENT_BPMPW,
712 .sid = TEGRA186_SID_BPMP,
720 .id = TEGRA186_MEMORY_CLIENT_BPMPDMAR,
722 .sid = TEGRA186_SID_BPMP,
730 .id = TEGRA186_MEMORY_CLIENT_BPMPDMAW,
732 .sid = TEGRA186_SID_BPMP,
740 .id = TEGRA186_MEMORY_CLIENT_AONR,
742 .sid = TEGRA186_SID_AON,
750 .id = TEGRA186_MEMORY_CLIENT_AONW,
752 .sid = TEGRA186_SID_AON,
760 .id = TEGRA186_MEMORY_CLIENT_AONDMAR,
762 .sid = TEGRA186_SID_AON,
770 .id = TEGRA186_MEMORY_CLIENT_AONDMAW,
772 .sid = TEGRA186_SID_AON,
780 .id = TEGRA186_MEMORY_CLIENT_SCER,
782 .sid = TEGRA186_SID_SCE,
790 .id = TEGRA186_MEMORY_CLIENT_SCEW,
792 .sid = TEGRA186_SID_SCE,
800 .id = TEGRA186_MEMORY_CLIENT_SCEDMAR,
802 .sid = TEGRA186_SID_SCE,
810 .id = TEGRA186_MEMORY_CLIENT_SCEDMAW,
812 .sid = TEGRA186_SID_SCE,
820 .id = TEGRA186_MEMORY_CLIENT_APEDMAR,
822 .sid = TEGRA186_SID_APE,
830 .id = TEGRA186_MEMORY_CLIENT_APEDMAW,
832 .sid = TEGRA186_SID_APE,
840 .id = TEGRA186_MEMORY_CLIENT_NVDISPLAYR1,
841 .name = "nvdisplayr1",
842 .sid = TEGRA186_SID_NVDISPLAY,
850 .id = TEGRA186_MEMORY_CLIENT_VICSRD1,
852 .sid = TEGRA186_SID_VIC,
860 .id = TEGRA186_MEMORY_CLIENT_NVDECSRD1,
862 .sid = TEGRA186_SID_NVDEC,
872 const struct tegra_mc_soc tegra186_mc_soc = {
873 .num_clients = ARRAY_SIZE(tegra186_mc_clients),
874 .clients = tegra186_mc_clients,
875 .num_address_bits = 40,
876 .ops = &tegra186_mc_ops,