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>
11 #include <linux/of_platform.h>
12 #include <linux/platform_device.h>
14 #include <soc/tegra/mc.h>
16 #if defined(CONFIG_ARCH_TEGRA_186_SOC)
17 #include <dt-bindings/memory/tegra186-mc.h>
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)
26 static int tegra186_mc_probe(struct tegra_mc *mc)
28 struct platform_device *pdev = to_platform_device(mc->dev);
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) {
37 "Broadcast channel is missing, please update your device-tree\n");
38 mc->bcast_ch_regs = NULL;
42 return PTR_ERR(mc->bcast_ch_regs);
45 mc->ch_regs = devm_kcalloc(mc->dev, mc->soc->num_channels, sizeof(*mc->ch_regs),
50 for (i = 0; i < mc->soc->num_channels; i++) {
51 snprintf(name, sizeof(name), "ch%u", i);
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]);
59 err = of_platform_populate(mc->dev->of_node, NULL, NULL, mc->dev);
66 static void tegra186_mc_remove(struct tegra_mc *mc)
68 of_platform_depopulate(mc->dev);
71 #if IS_ENABLED(CONFIG_IOMMU_API)
72 static void tegra186_mc_client_sid_override(struct tegra_mc *mc,
73 const struct tegra_mc_client *client,
78 if (client->regs.sid.security == 0 && client->regs.sid.override == 0)
81 value = readl(mc->regs + client->regs.sid.security);
82 if ((value & MC_SID_STREAMID_SECURITY_OVERRIDE) == 0) {
84 * If the secure firmware has locked this down the override
85 * for this memory client, there's nothing we can do here.
87 if (value & MC_SID_STREAMID_SECURITY_WRITE_ACCESS_DISABLED)
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
97 WARN_ON((value & MC_SID_STREAMID_SECURITY_OVERRIDE) == 0);
99 value |= MC_SID_STREAMID_SECURITY_OVERRIDE;
100 writel(value, mc->regs + client->regs.sid.security);
103 value = readl(mc->regs + client->regs.sid.override);
104 old = value & MC_SID_STREAMID_OVERRIDE_MASK;
107 dev_dbg(mc->dev, "overriding SID %x for %s with %x\n", old,
109 writel(sid, mc->regs + client->regs.sid.override);
114 static int tegra186_mc_probe_device(struct tegra_mc *mc, struct device *dev)
116 #if IS_ENABLED(CONFIG_IOMMU_API)
117 struct of_phandle_args args;
118 unsigned int i, index = 0;
121 if (!tegra_dev_iommu_get_stream_id(dev, &sid))
124 while (!of_parse_phandle_with_args(dev->of_node, "interconnects", "#interconnect-cells",
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];
130 if (client->id == args.args[0])
131 tegra186_mc_client_sid_override(
133 sid & MC_SID_STREAMID_OVERRIDE_MASK);
144 static int tegra186_mc_resume(struct tegra_mc *mc)
146 #if IS_ENABLED(CONFIG_IOMMU_API)
149 for (i = 0; i < mc->soc->num_clients; i++) {
150 const struct tegra_mc_client *client = &mc->soc->clients[i];
152 tegra186_mc_client_sid_override(mc, client, client->sid);
159 const 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,
167 #if defined(CONFIG_ARCH_TEGRA_186_SOC)
168 static const struct tegra_mc_client tegra186_mc_clients[] = {
170 .id = TEGRA186_MEMORY_CLIENT_PTCR,
172 .sid = TEGRA186_SID_PASSTHROUGH,
180 .id = TEGRA186_MEMORY_CLIENT_AFIR,
182 .sid = TEGRA186_SID_AFI,
190 .id = TEGRA186_MEMORY_CLIENT_HDAR,
192 .sid = TEGRA186_SID_HDA,
200 .id = TEGRA186_MEMORY_CLIENT_HOST1XDMAR,
201 .name = "host1xdmar",
202 .sid = TEGRA186_SID_HOST1X,
210 .id = TEGRA186_MEMORY_CLIENT_NVENCSRD,
212 .sid = TEGRA186_SID_NVENC,
220 .id = TEGRA186_MEMORY_CLIENT_SATAR,
222 .sid = TEGRA186_SID_SATA,
230 .id = TEGRA186_MEMORY_CLIENT_MPCORER,
232 .sid = TEGRA186_SID_PASSTHROUGH,
240 .id = TEGRA186_MEMORY_CLIENT_NVENCSWR,
242 .sid = TEGRA186_SID_NVENC,
250 .id = TEGRA186_MEMORY_CLIENT_AFIW,
252 .sid = TEGRA186_SID_AFI,
260 .id = TEGRA186_MEMORY_CLIENT_HDAW,
262 .sid = TEGRA186_SID_HDA,
270 .id = TEGRA186_MEMORY_CLIENT_MPCOREW,
272 .sid = TEGRA186_SID_PASSTHROUGH,
280 .id = TEGRA186_MEMORY_CLIENT_SATAW,
282 .sid = TEGRA186_SID_SATA,
290 .id = TEGRA186_MEMORY_CLIENT_ISPRA,
292 .sid = TEGRA186_SID_ISP,
300 .id = TEGRA186_MEMORY_CLIENT_ISPWA,
302 .sid = TEGRA186_SID_ISP,
310 .id = TEGRA186_MEMORY_CLIENT_ISPWB,
312 .sid = TEGRA186_SID_ISP,
320 .id = TEGRA186_MEMORY_CLIENT_XUSB_HOSTR,
321 .name = "xusb_hostr",
322 .sid = TEGRA186_SID_XUSB_HOST,
330 .id = TEGRA186_MEMORY_CLIENT_XUSB_HOSTW,
331 .name = "xusb_hostw",
332 .sid = TEGRA186_SID_XUSB_HOST,
340 .id = TEGRA186_MEMORY_CLIENT_XUSB_DEVR,
342 .sid = TEGRA186_SID_XUSB_DEV,
350 .id = TEGRA186_MEMORY_CLIENT_XUSB_DEVW,
352 .sid = TEGRA186_SID_XUSB_DEV,
360 .id = TEGRA186_MEMORY_CLIENT_TSECSRD,
362 .sid = TEGRA186_SID_TSEC,
370 .id = TEGRA186_MEMORY_CLIENT_TSECSWR,
372 .sid = TEGRA186_SID_TSEC,
380 .id = TEGRA186_MEMORY_CLIENT_GPUSRD,
382 .sid = TEGRA186_SID_GPU,
390 .id = TEGRA186_MEMORY_CLIENT_GPUSWR,
392 .sid = TEGRA186_SID_GPU,
400 .id = TEGRA186_MEMORY_CLIENT_SDMMCRA,
402 .sid = TEGRA186_SID_SDMMC1,
410 .id = TEGRA186_MEMORY_CLIENT_SDMMCRAA,
412 .sid = TEGRA186_SID_SDMMC2,
420 .id = TEGRA186_MEMORY_CLIENT_SDMMCR,
422 .sid = TEGRA186_SID_SDMMC3,
430 .id = TEGRA186_MEMORY_CLIENT_SDMMCRAB,
432 .sid = TEGRA186_SID_SDMMC4,
440 .id = TEGRA186_MEMORY_CLIENT_SDMMCWA,
442 .sid = TEGRA186_SID_SDMMC1,
450 .id = TEGRA186_MEMORY_CLIENT_SDMMCWAA,
452 .sid = TEGRA186_SID_SDMMC2,
460 .id = TEGRA186_MEMORY_CLIENT_SDMMCW,
462 .sid = TEGRA186_SID_SDMMC3,
470 .id = TEGRA186_MEMORY_CLIENT_SDMMCWAB,
472 .sid = TEGRA186_SID_SDMMC4,
480 .id = TEGRA186_MEMORY_CLIENT_VICSRD,
482 .sid = TEGRA186_SID_VIC,
490 .id = TEGRA186_MEMORY_CLIENT_VICSWR,
492 .sid = TEGRA186_SID_VIC,
500 .id = TEGRA186_MEMORY_CLIENT_VIW,
502 .sid = TEGRA186_SID_VI,
510 .id = TEGRA186_MEMORY_CLIENT_NVDECSRD,
512 .sid = TEGRA186_SID_NVDEC,
520 .id = TEGRA186_MEMORY_CLIENT_NVDECSWR,
522 .sid = TEGRA186_SID_NVDEC,
530 .id = TEGRA186_MEMORY_CLIENT_APER,
532 .sid = TEGRA186_SID_APE,
540 .id = TEGRA186_MEMORY_CLIENT_APEW,
542 .sid = TEGRA186_SID_APE,
550 .id = TEGRA186_MEMORY_CLIENT_NVJPGSRD,
552 .sid = TEGRA186_SID_NVJPG,
560 .id = TEGRA186_MEMORY_CLIENT_NVJPGSWR,
562 .sid = TEGRA186_SID_NVJPG,
570 .id = TEGRA186_MEMORY_CLIENT_SESRD,
572 .sid = TEGRA186_SID_SE,
580 .id = TEGRA186_MEMORY_CLIENT_SESWR,
582 .sid = TEGRA186_SID_SE,
590 .id = TEGRA186_MEMORY_CLIENT_ETRR,
592 .sid = TEGRA186_SID_ETR,
600 .id = TEGRA186_MEMORY_CLIENT_ETRW,
602 .sid = TEGRA186_SID_ETR,
610 .id = TEGRA186_MEMORY_CLIENT_TSECSRDB,
612 .sid = TEGRA186_SID_TSECB,
620 .id = TEGRA186_MEMORY_CLIENT_TSECSWRB,
622 .sid = TEGRA186_SID_TSECB,
630 .id = TEGRA186_MEMORY_CLIENT_GPUSRD2,
632 .sid = TEGRA186_SID_GPU,
640 .id = TEGRA186_MEMORY_CLIENT_GPUSWR2,
642 .sid = TEGRA186_SID_GPU,
650 .id = TEGRA186_MEMORY_CLIENT_AXISR,
652 .sid = TEGRA186_SID_GPCDMA_0,
660 .id = TEGRA186_MEMORY_CLIENT_AXISW,
662 .sid = TEGRA186_SID_GPCDMA_0,
670 .id = TEGRA186_MEMORY_CLIENT_EQOSR,
672 .sid = TEGRA186_SID_EQOS,
680 .id = TEGRA186_MEMORY_CLIENT_EQOSW,
682 .sid = TEGRA186_SID_EQOS,
690 .id = TEGRA186_MEMORY_CLIENT_UFSHCR,
692 .sid = TEGRA186_SID_UFSHC,
700 .id = TEGRA186_MEMORY_CLIENT_UFSHCW,
702 .sid = TEGRA186_SID_UFSHC,
710 .id = TEGRA186_MEMORY_CLIENT_NVDISPLAYR,
711 .name = "nvdisplayr",
712 .sid = TEGRA186_SID_NVDISPLAY,
720 .id = TEGRA186_MEMORY_CLIENT_BPMPR,
722 .sid = TEGRA186_SID_BPMP,
730 .id = TEGRA186_MEMORY_CLIENT_BPMPW,
732 .sid = TEGRA186_SID_BPMP,
740 .id = TEGRA186_MEMORY_CLIENT_BPMPDMAR,
742 .sid = TEGRA186_SID_BPMP,
750 .id = TEGRA186_MEMORY_CLIENT_BPMPDMAW,
752 .sid = TEGRA186_SID_BPMP,
760 .id = TEGRA186_MEMORY_CLIENT_AONR,
762 .sid = TEGRA186_SID_AON,
770 .id = TEGRA186_MEMORY_CLIENT_AONW,
772 .sid = TEGRA186_SID_AON,
780 .id = TEGRA186_MEMORY_CLIENT_AONDMAR,
782 .sid = TEGRA186_SID_AON,
790 .id = TEGRA186_MEMORY_CLIENT_AONDMAW,
792 .sid = TEGRA186_SID_AON,
800 .id = TEGRA186_MEMORY_CLIENT_SCER,
802 .sid = TEGRA186_SID_SCE,
810 .id = TEGRA186_MEMORY_CLIENT_SCEW,
812 .sid = TEGRA186_SID_SCE,
820 .id = TEGRA186_MEMORY_CLIENT_SCEDMAR,
822 .sid = TEGRA186_SID_SCE,
830 .id = TEGRA186_MEMORY_CLIENT_SCEDMAW,
832 .sid = TEGRA186_SID_SCE,
840 .id = TEGRA186_MEMORY_CLIENT_APEDMAR,
842 .sid = TEGRA186_SID_APE,
850 .id = TEGRA186_MEMORY_CLIENT_APEDMAW,
852 .sid = TEGRA186_SID_APE,
860 .id = TEGRA186_MEMORY_CLIENT_NVDISPLAYR1,
861 .name = "nvdisplayr1",
862 .sid = TEGRA186_SID_NVDISPLAY,
870 .id = TEGRA186_MEMORY_CLIENT_VICSRD1,
872 .sid = TEGRA186_SID_VIC,
880 .id = TEGRA186_MEMORY_CLIENT_NVDECSRD1,
882 .sid = TEGRA186_SID_NVDEC,
892 const 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,
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,