Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'tegra-for-4.16-memory' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers

Pull "memory: tegra: Changes for v4.16-rc1" from Thierry Reding:

The Tegra memory controller driver will now instruct the SMMU driver to
create groups, which will make it easier for device drivers to share an
IOMMU domain between multiple devices.

Initial Tegra186 support is also added in a separate driver.

* tag 'tegra-for-4.16-memory' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
iommu/tegra-smmu: Fix return value check in tegra_smmu_group_get()
iommu/tegra: Allow devices to be grouped
memory: tegra: Create SMMU display groups
memory: tegra: Add Tegra186 support
dt-bindings: memory: Add Tegra186 support
dt-bindings: misc: Add Tegra186 MISC registers bindings

+917 -4
+2
Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.txt
··· 12 12 - clock-names: Must include the following entries: 13 13 - mc: the module's clock input 14 14 - interrupts: The interrupt outputs from the controller. 15 + 16 + Required properties for Tegra30, Tegra114, Tegra124, Tegra132 and Tegra210: 15 17 - #iommu-cells: Should be 1. The single cell of the IOMMU specifier defines 16 18 the SWGROUP of the master. 17 19
+12
Documentation/devicetree/bindings/misc/nvidia,tegra186-misc.txt
··· 1 + NVIDIA Tegra186 MISC register block 2 + 3 + The MISC register block found on Tegra186 SoCs contains registers that can be 4 + used to identify a given chip and various strapping options. 5 + 6 + Required properties: 7 + - compatible: Must be: 8 + - Tegra186: "nvidia,tegra186-misc" 9 + - reg: Should contain 2 entries: The first entry gives the physical address 10 + and length of the register region which contains revision and debug 11 + features. The second entry specifies the physical address and length 12 + of the register region indicating the strapping options.
+120 -4
drivers/iommu/tegra-smmu.c
··· 20 20 #include <soc/tegra/ahb.h> 21 21 #include <soc/tegra/mc.h> 22 22 23 + struct tegra_smmu_group { 24 + struct list_head list; 25 + const struct tegra_smmu_group_soc *soc; 26 + struct iommu_group *group; 27 + }; 28 + 23 29 struct tegra_smmu { 24 30 void __iomem *regs; 25 31 struct device *dev; 26 32 27 33 struct tegra_mc *mc; 28 34 const struct tegra_smmu_soc *soc; 35 + 36 + struct list_head groups; 29 37 30 38 unsigned long pfn_mask; 31 39 unsigned long tlb_mask; ··· 711 703 return mc->smmu; 712 704 } 713 705 706 + static int tegra_smmu_configure(struct tegra_smmu *smmu, struct device *dev, 707 + struct of_phandle_args *args) 708 + { 709 + const struct iommu_ops *ops = smmu->iommu.ops; 710 + int err; 711 + 712 + err = iommu_fwspec_init(dev, &dev->of_node->fwnode, ops); 713 + if (err < 0) { 714 + dev_err(dev, "failed to initialize fwspec: %d\n", err); 715 + return err; 716 + } 717 + 718 + err = ops->of_xlate(dev, args); 719 + if (err < 0) { 720 + dev_err(dev, "failed to parse SW group ID: %d\n", err); 721 + iommu_fwspec_free(dev); 722 + return err; 723 + } 724 + 725 + return 0; 726 + } 727 + 714 728 static int tegra_smmu_add_device(struct device *dev) 715 729 { 716 730 struct device_node *np = dev->of_node; 731 + struct tegra_smmu *smmu = NULL; 717 732 struct iommu_group *group; 718 733 struct of_phandle_args args; 719 734 unsigned int index = 0; 735 + int err; 720 736 721 737 while (of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index, 722 738 &args) == 0) { 723 - struct tegra_smmu *smmu; 724 - 725 739 smmu = tegra_smmu_find(args.np); 726 740 if (smmu) { 741 + err = tegra_smmu_configure(smmu, dev, &args); 742 + of_node_put(args.np); 743 + 744 + if (err < 0) 745 + return err; 746 + 727 747 /* 728 748 * Only a single IOMMU master interface is currently 729 749 * supported by the Linux kernel, so abort after the ··· 764 728 break; 765 729 } 766 730 731 + of_node_put(args.np); 767 732 index++; 768 733 } 734 + 735 + if (!smmu) 736 + return -ENODEV; 769 737 770 738 group = iommu_group_get_for_dev(dev); 771 739 if (IS_ERR(group)) ··· 791 751 iommu_group_remove_device(dev); 792 752 } 793 753 754 + static const struct tegra_smmu_group_soc * 755 + tegra_smmu_find_group(struct tegra_smmu *smmu, unsigned int swgroup) 756 + { 757 + unsigned int i, j; 758 + 759 + for (i = 0; i < smmu->soc->num_groups; i++) 760 + for (j = 0; j < smmu->soc->groups[i].num_swgroups; j++) 761 + if (smmu->soc->groups[i].swgroups[j] == swgroup) 762 + return &smmu->soc->groups[i]; 763 + 764 + return NULL; 765 + } 766 + 767 + static struct iommu_group *tegra_smmu_group_get(struct tegra_smmu *smmu, 768 + unsigned int swgroup) 769 + { 770 + const struct tegra_smmu_group_soc *soc; 771 + struct tegra_smmu_group *group; 772 + 773 + soc = tegra_smmu_find_group(smmu, swgroup); 774 + if (!soc) 775 + return NULL; 776 + 777 + mutex_lock(&smmu->lock); 778 + 779 + list_for_each_entry(group, &smmu->groups, list) 780 + if (group->soc == soc) { 781 + mutex_unlock(&smmu->lock); 782 + return group->group; 783 + } 784 + 785 + group = devm_kzalloc(smmu->dev, sizeof(*group), GFP_KERNEL); 786 + if (!group) { 787 + mutex_unlock(&smmu->lock); 788 + return NULL; 789 + } 790 + 791 + INIT_LIST_HEAD(&group->list); 792 + group->soc = soc; 793 + 794 + group->group = iommu_group_alloc(); 795 + if (IS_ERR(group->group)) { 796 + devm_kfree(smmu->dev, group); 797 + mutex_unlock(&smmu->lock); 798 + return NULL; 799 + } 800 + 801 + list_add_tail(&group->list, &smmu->groups); 802 + mutex_unlock(&smmu->lock); 803 + 804 + return group->group; 805 + } 806 + 807 + static struct iommu_group *tegra_smmu_device_group(struct device *dev) 808 + { 809 + struct iommu_fwspec *fwspec = dev->iommu_fwspec; 810 + struct tegra_smmu *smmu = dev->archdata.iommu; 811 + struct iommu_group *group; 812 + 813 + group = tegra_smmu_group_get(smmu, fwspec->ids[0]); 814 + if (!group) 815 + group = generic_device_group(dev); 816 + 817 + return group; 818 + } 819 + 820 + static int tegra_smmu_of_xlate(struct device *dev, 821 + struct of_phandle_args *args) 822 + { 823 + u32 id = args->args[0]; 824 + 825 + return iommu_fwspec_add_ids(dev, &id, 1); 826 + } 827 + 794 828 static const struct iommu_ops tegra_smmu_ops = { 795 829 .capable = tegra_smmu_capable, 796 830 .domain_alloc = tegra_smmu_domain_alloc, ··· 873 759 .detach_dev = tegra_smmu_detach_dev, 874 760 .add_device = tegra_smmu_add_device, 875 761 .remove_device = tegra_smmu_remove_device, 876 - .device_group = generic_device_group, 762 + .device_group = tegra_smmu_device_group, 877 763 .map = tegra_smmu_map, 878 764 .unmap = tegra_smmu_unmap, 879 765 .map_sg = default_iommu_map_sg, 880 766 .iova_to_phys = tegra_smmu_iova_to_phys, 881 - 767 + .of_xlate = tegra_smmu_of_xlate, 882 768 .pgsize_bitmap = SZ_4K, 883 769 }; 884 770 ··· 1027 913 if (!smmu->asids) 1028 914 return ERR_PTR(-ENOMEM); 1029 915 916 + INIT_LIST_HEAD(&smmu->groups); 1030 917 mutex_init(&smmu->lock); 1031 918 1032 919 smmu->regs = mc->regs; ··· 1069 954 return ERR_PTR(err); 1070 955 1071 956 iommu_device_set_ops(&smmu->iommu, &tegra_smmu_ops); 957 + iommu_device_set_fwnode(&smmu->iommu, dev->fwnode); 1072 958 1073 959 err = iommu_device_register(&smmu->iommu); 1074 960 if (err) {
+1
drivers/memory/tegra/Makefile
··· 10 10 obj-$(CONFIG_TEGRA_MC) += tegra-mc.o 11 11 12 12 obj-$(CONFIG_TEGRA124_EMC) += tegra124-emc.o 13 + obj-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186.o
+15
drivers/memory/tegra/tegra114.c
··· 912 912 { .name = "tsec", .swgroup = TEGRA_SWGROUP_TSEC, .reg = 0x294 }, 913 913 }; 914 914 915 + static const unsigned int tegra114_group_display[] = { 916 + TEGRA_SWGROUP_DC, 917 + TEGRA_SWGROUP_DCB, 918 + }; 919 + 920 + static const struct tegra_smmu_group_soc tegra114_groups[] = { 921 + { 922 + .name = "display", 923 + .swgroups = tegra114_group_display, 924 + .num_swgroups = ARRAY_SIZE(tegra114_group_display), 925 + }, 926 + }; 927 + 915 928 static const struct tegra_smmu_soc tegra114_smmu_soc = { 916 929 .clients = tegra114_mc_clients, 917 930 .num_clients = ARRAY_SIZE(tegra114_mc_clients), 918 931 .swgroups = tegra114_swgroups, 919 932 .num_swgroups = ARRAY_SIZE(tegra114_swgroups), 933 + .groups = tegra114_groups, 934 + .num_groups = ARRAY_SIZE(tegra114_groups), 920 935 .supports_round_robin_arbitration = false, 921 936 .supports_request_limit = false, 922 937 .num_tlb_lines = 32,
+17
drivers/memory/tegra/tegra124.c
··· 999 999 { .name = "vi", .swgroup = TEGRA_SWGROUP_VI, .reg = 0x280 }, 1000 1000 }; 1001 1001 1002 + static const unsigned int tegra124_group_display[] = { 1003 + TEGRA_SWGROUP_DC, 1004 + TEGRA_SWGROUP_DCB, 1005 + }; 1006 + 1007 + static const struct tegra_smmu_group_soc tegra124_groups[] = { 1008 + { 1009 + .name = "display", 1010 + .swgroups = tegra124_group_display, 1011 + .num_swgroups = ARRAY_SIZE(tegra124_group_display), 1012 + }, 1013 + }; 1014 + 1002 1015 #ifdef CONFIG_ARCH_TEGRA_124_SOC 1003 1016 static const struct tegra_smmu_soc tegra124_smmu_soc = { 1004 1017 .clients = tegra124_mc_clients, 1005 1018 .num_clients = ARRAY_SIZE(tegra124_mc_clients), 1006 1019 .swgroups = tegra124_swgroups, 1007 1020 .num_swgroups = ARRAY_SIZE(tegra124_swgroups), 1021 + .groups = tegra124_groups, 1022 + .num_groups = ARRAY_SIZE(tegra124_groups), 1008 1023 .supports_round_robin_arbitration = true, 1009 1024 .supports_request_limit = true, 1010 1025 .num_tlb_lines = 32, ··· 1044 1029 .num_clients = ARRAY_SIZE(tegra124_mc_clients), 1045 1030 .swgroups = tegra124_swgroups, 1046 1031 .num_swgroups = ARRAY_SIZE(tegra124_swgroups), 1032 + .groups = tegra124_groups, 1033 + .num_groups = ARRAY_SIZE(tegra124_groups), 1047 1034 .supports_round_robin_arbitration = true, 1048 1035 .supports_request_limit = true, 1049 1036 .num_tlb_lines = 32,
+600
drivers/memory/tegra/tegra186.c
··· 1 + /* 2 + * Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #include <linux/io.h> 10 + #include <linux/module.h> 11 + #include <linux/platform_device.h> 12 + 13 + #include <dt-bindings/memory/tegra186-mc.h> 14 + 15 + struct tegra_mc { 16 + struct device *dev; 17 + void __iomem *regs; 18 + }; 19 + 20 + struct tegra_mc_client { 21 + const char *name; 22 + unsigned int sid; 23 + struct { 24 + unsigned int override; 25 + unsigned int security; 26 + } regs; 27 + }; 28 + 29 + static const struct tegra_mc_client tegra186_mc_clients[] = { 30 + { 31 + .name = "ptcr", 32 + .sid = TEGRA186_SID_PASSTHROUGH, 33 + .regs = { 34 + .override = 0x000, 35 + .security = 0x004, 36 + }, 37 + }, { 38 + .name = "afir", 39 + .sid = TEGRA186_SID_AFI, 40 + .regs = { 41 + .override = 0x070, 42 + .security = 0x074, 43 + }, 44 + }, { 45 + .name = "hdar", 46 + .sid = TEGRA186_SID_HDA, 47 + .regs = { 48 + .override = 0x0a8, 49 + .security = 0x0ac, 50 + }, 51 + }, { 52 + .name = "host1xdmar", 53 + .sid = TEGRA186_SID_HOST1X, 54 + .regs = { 55 + .override = 0x0b0, 56 + .security = 0x0b4, 57 + }, 58 + }, { 59 + .name = "nvencsrd", 60 + .sid = TEGRA186_SID_NVENC, 61 + .regs = { 62 + .override = 0x0e0, 63 + .security = 0x0e4, 64 + }, 65 + }, { 66 + .name = "satar", 67 + .sid = TEGRA186_SID_SATA, 68 + .regs = { 69 + .override = 0x0f8, 70 + .security = 0x0fc, 71 + }, 72 + }, { 73 + .name = "mpcorer", 74 + .sid = TEGRA186_SID_PASSTHROUGH, 75 + .regs = { 76 + .override = 0x138, 77 + .security = 0x13c, 78 + }, 79 + }, { 80 + .name = "nvencswr", 81 + .sid = TEGRA186_SID_NVENC, 82 + .regs = { 83 + .override = 0x158, 84 + .security = 0x15c, 85 + }, 86 + }, { 87 + .name = "afiw", 88 + .sid = TEGRA186_SID_AFI, 89 + .regs = { 90 + .override = 0x188, 91 + .security = 0x18c, 92 + }, 93 + }, { 94 + .name = "hdaw", 95 + .sid = TEGRA186_SID_HDA, 96 + .regs = { 97 + .override = 0x1a8, 98 + .security = 0x1ac, 99 + }, 100 + }, { 101 + .name = "mpcorew", 102 + .sid = TEGRA186_SID_PASSTHROUGH, 103 + .regs = { 104 + .override = 0x1c8, 105 + .security = 0x1cc, 106 + }, 107 + }, { 108 + .name = "sataw", 109 + .sid = TEGRA186_SID_SATA, 110 + .regs = { 111 + .override = 0x1e8, 112 + .security = 0x1ec, 113 + }, 114 + }, { 115 + .name = "ispra", 116 + .sid = TEGRA186_SID_ISP, 117 + .regs = { 118 + .override = 0x220, 119 + .security = 0x224, 120 + }, 121 + }, { 122 + .name = "ispwa", 123 + .sid = TEGRA186_SID_ISP, 124 + .regs = { 125 + .override = 0x230, 126 + .security = 0x234, 127 + }, 128 + }, { 129 + .name = "ispwb", 130 + .sid = TEGRA186_SID_ISP, 131 + .regs = { 132 + .override = 0x238, 133 + .security = 0x23c, 134 + }, 135 + }, { 136 + .name = "xusb_hostr", 137 + .sid = TEGRA186_SID_XUSB_HOST, 138 + .regs = { 139 + .override = 0x250, 140 + .security = 0x254, 141 + }, 142 + }, { 143 + .name = "xusb_hostw", 144 + .sid = TEGRA186_SID_XUSB_HOST, 145 + .regs = { 146 + .override = 0x258, 147 + .security = 0x25c, 148 + }, 149 + }, { 150 + .name = "xusb_devr", 151 + .sid = TEGRA186_SID_XUSB_DEV, 152 + .regs = { 153 + .override = 0x260, 154 + .security = 0x264, 155 + }, 156 + }, { 157 + .name = "xusb_devw", 158 + .sid = TEGRA186_SID_XUSB_DEV, 159 + .regs = { 160 + .override = 0x268, 161 + .security = 0x26c, 162 + }, 163 + }, { 164 + .name = "tsecsrd", 165 + .sid = TEGRA186_SID_TSEC, 166 + .regs = { 167 + .override = 0x2a0, 168 + .security = 0x2a4, 169 + }, 170 + }, { 171 + .name = "tsecswr", 172 + .sid = TEGRA186_SID_TSEC, 173 + .regs = { 174 + .override = 0x2a8, 175 + .security = 0x2ac, 176 + }, 177 + }, { 178 + .name = "gpusrd", 179 + .sid = TEGRA186_SID_GPU, 180 + .regs = { 181 + .override = 0x2c0, 182 + .security = 0x2c4, 183 + }, 184 + }, { 185 + .name = "gpuswr", 186 + .sid = TEGRA186_SID_GPU, 187 + .regs = { 188 + .override = 0x2c8, 189 + .security = 0x2cc, 190 + }, 191 + }, { 192 + .name = "sdmmcra", 193 + .sid = TEGRA186_SID_SDMMC1, 194 + .regs = { 195 + .override = 0x300, 196 + .security = 0x304, 197 + }, 198 + }, { 199 + .name = "sdmmcraa", 200 + .sid = TEGRA186_SID_SDMMC2, 201 + .regs = { 202 + .override = 0x308, 203 + .security = 0x30c, 204 + }, 205 + }, { 206 + .name = "sdmmcr", 207 + .sid = TEGRA186_SID_SDMMC3, 208 + .regs = { 209 + .override = 0x310, 210 + .security = 0x314, 211 + }, 212 + }, { 213 + .name = "sdmmcrab", 214 + .sid = TEGRA186_SID_SDMMC4, 215 + .regs = { 216 + .override = 0x318, 217 + .security = 0x31c, 218 + }, 219 + }, { 220 + .name = "sdmmcwa", 221 + .sid = TEGRA186_SID_SDMMC1, 222 + .regs = { 223 + .override = 0x320, 224 + .security = 0x324, 225 + }, 226 + }, { 227 + .name = "sdmmcwaa", 228 + .sid = TEGRA186_SID_SDMMC2, 229 + .regs = { 230 + .override = 0x328, 231 + .security = 0x32c, 232 + }, 233 + }, { 234 + .name = "sdmmcw", 235 + .sid = TEGRA186_SID_SDMMC3, 236 + .regs = { 237 + .override = 0x330, 238 + .security = 0x334, 239 + }, 240 + }, { 241 + .name = "sdmmcwab", 242 + .sid = TEGRA186_SID_SDMMC4, 243 + .regs = { 244 + .override = 0x338, 245 + .security = 0x33c, 246 + }, 247 + }, { 248 + .name = "vicsrd", 249 + .sid = TEGRA186_SID_VIC, 250 + .regs = { 251 + .override = 0x360, 252 + .security = 0x364, 253 + }, 254 + }, { 255 + .name = "vicswr", 256 + .sid = TEGRA186_SID_VIC, 257 + .regs = { 258 + .override = 0x368, 259 + .security = 0x36c, 260 + }, 261 + }, { 262 + .name = "viw", 263 + .sid = TEGRA186_SID_VI, 264 + .regs = { 265 + .override = 0x390, 266 + .security = 0x394, 267 + }, 268 + }, { 269 + .name = "nvdecsrd", 270 + .sid = TEGRA186_SID_NVDEC, 271 + .regs = { 272 + .override = 0x3c0, 273 + .security = 0x3c4, 274 + }, 275 + }, { 276 + .name = "nvdecswr", 277 + .sid = TEGRA186_SID_NVDEC, 278 + .regs = { 279 + .override = 0x3c8, 280 + .security = 0x3cc, 281 + }, 282 + }, { 283 + .name = "aper", 284 + .sid = TEGRA186_SID_APE, 285 + .regs = { 286 + .override = 0x3d0, 287 + .security = 0x3d4, 288 + }, 289 + }, { 290 + .name = "apew", 291 + .sid = TEGRA186_SID_APE, 292 + .regs = { 293 + .override = 0x3d8, 294 + .security = 0x3dc, 295 + }, 296 + }, { 297 + .name = "nvjpgsrd", 298 + .sid = TEGRA186_SID_NVJPG, 299 + .regs = { 300 + .override = 0x3f0, 301 + .security = 0x3f4, 302 + }, 303 + }, { 304 + .name = "nvjpgswr", 305 + .sid = TEGRA186_SID_NVJPG, 306 + .regs = { 307 + .override = 0x3f8, 308 + .security = 0x3fc, 309 + }, 310 + }, { 311 + .name = "sesrd", 312 + .sid = TEGRA186_SID_SE, 313 + .regs = { 314 + .override = 0x400, 315 + .security = 0x404, 316 + }, 317 + }, { 318 + .name = "seswr", 319 + .sid = TEGRA186_SID_SE, 320 + .regs = { 321 + .override = 0x408, 322 + .security = 0x40c, 323 + }, 324 + }, { 325 + .name = "etrr", 326 + .sid = TEGRA186_SID_ETR, 327 + .regs = { 328 + .override = 0x420, 329 + .security = 0x424, 330 + }, 331 + }, { 332 + .name = "etrw", 333 + .sid = TEGRA186_SID_ETR, 334 + .regs = { 335 + .override = 0x428, 336 + .security = 0x42c, 337 + }, 338 + }, { 339 + .name = "tsecsrdb", 340 + .sid = TEGRA186_SID_TSECB, 341 + .regs = { 342 + .override = 0x430, 343 + .security = 0x434, 344 + }, 345 + }, { 346 + .name = "tsecswrb", 347 + .sid = TEGRA186_SID_TSECB, 348 + .regs = { 349 + .override = 0x438, 350 + .security = 0x43c, 351 + }, 352 + }, { 353 + .name = "gpusrd2", 354 + .sid = TEGRA186_SID_GPU, 355 + .regs = { 356 + .override = 0x440, 357 + .security = 0x444, 358 + }, 359 + }, { 360 + .name = "gpuswr2", 361 + .sid = TEGRA186_SID_GPU, 362 + .regs = { 363 + .override = 0x448, 364 + .security = 0x44c, 365 + }, 366 + }, { 367 + .name = "axisr", 368 + .sid = TEGRA186_SID_GPCDMA_0, 369 + .regs = { 370 + .override = 0x460, 371 + .security = 0x464, 372 + }, 373 + }, { 374 + .name = "axisw", 375 + .sid = TEGRA186_SID_GPCDMA_0, 376 + .regs = { 377 + .override = 0x468, 378 + .security = 0x46c, 379 + }, 380 + }, { 381 + .name = "eqosr", 382 + .sid = TEGRA186_SID_EQOS, 383 + .regs = { 384 + .override = 0x470, 385 + .security = 0x474, 386 + }, 387 + }, { 388 + .name = "eqosw", 389 + .sid = TEGRA186_SID_EQOS, 390 + .regs = { 391 + .override = 0x478, 392 + .security = 0x47c, 393 + }, 394 + }, { 395 + .name = "ufshcr", 396 + .sid = TEGRA186_SID_UFSHC, 397 + .regs = { 398 + .override = 0x480, 399 + .security = 0x484, 400 + }, 401 + }, { 402 + .name = "ufshcw", 403 + .sid = TEGRA186_SID_UFSHC, 404 + .regs = { 405 + .override = 0x488, 406 + .security = 0x48c, 407 + }, 408 + }, { 409 + .name = "nvdisplayr", 410 + .sid = TEGRA186_SID_NVDISPLAY, 411 + .regs = { 412 + .override = 0x490, 413 + .security = 0x494, 414 + }, 415 + }, { 416 + .name = "bpmpr", 417 + .sid = TEGRA186_SID_BPMP, 418 + .regs = { 419 + .override = 0x498, 420 + .security = 0x49c, 421 + }, 422 + }, { 423 + .name = "bpmpw", 424 + .sid = TEGRA186_SID_BPMP, 425 + .regs = { 426 + .override = 0x4a0, 427 + .security = 0x4a4, 428 + }, 429 + }, { 430 + .name = "bpmpdmar", 431 + .sid = TEGRA186_SID_BPMP, 432 + .regs = { 433 + .override = 0x4a8, 434 + .security = 0x4ac, 435 + }, 436 + }, { 437 + .name = "bpmpdmaw", 438 + .sid = TEGRA186_SID_BPMP, 439 + .regs = { 440 + .override = 0x4b0, 441 + .security = 0x4b4, 442 + }, 443 + }, { 444 + .name = "aonr", 445 + .sid = TEGRA186_SID_AON, 446 + .regs = { 447 + .override = 0x4b8, 448 + .security = 0x4bc, 449 + }, 450 + }, { 451 + .name = "aonw", 452 + .sid = TEGRA186_SID_AON, 453 + .regs = { 454 + .override = 0x4c0, 455 + .security = 0x4c4, 456 + }, 457 + }, { 458 + .name = "aondmar", 459 + .sid = TEGRA186_SID_AON, 460 + .regs = { 461 + .override = 0x4c8, 462 + .security = 0x4cc, 463 + }, 464 + }, { 465 + .name = "aondmaw", 466 + .sid = TEGRA186_SID_AON, 467 + .regs = { 468 + .override = 0x4d0, 469 + .security = 0x4d4, 470 + }, 471 + }, { 472 + .name = "scer", 473 + .sid = TEGRA186_SID_SCE, 474 + .regs = { 475 + .override = 0x4d8, 476 + .security = 0x4dc, 477 + }, 478 + }, { 479 + .name = "scew", 480 + .sid = TEGRA186_SID_SCE, 481 + .regs = { 482 + .override = 0x4e0, 483 + .security = 0x4e4, 484 + }, 485 + }, { 486 + .name = "scedmar", 487 + .sid = TEGRA186_SID_SCE, 488 + .regs = { 489 + .override = 0x4e8, 490 + .security = 0x4ec, 491 + }, 492 + }, { 493 + .name = "scedmaw", 494 + .sid = TEGRA186_SID_SCE, 495 + .regs = { 496 + .override = 0x4f0, 497 + .security = 0x4f4, 498 + }, 499 + }, { 500 + .name = "apedmar", 501 + .sid = TEGRA186_SID_APE, 502 + .regs = { 503 + .override = 0x4f8, 504 + .security = 0x4fc, 505 + }, 506 + }, { 507 + .name = "apedmaw", 508 + .sid = TEGRA186_SID_APE, 509 + .regs = { 510 + .override = 0x500, 511 + .security = 0x504, 512 + }, 513 + }, { 514 + .name = "nvdisplayr1", 515 + .sid = TEGRA186_SID_NVDISPLAY, 516 + .regs = { 517 + .override = 0x508, 518 + .security = 0x50c, 519 + }, 520 + }, { 521 + .name = "vicsrd1", 522 + .sid = TEGRA186_SID_VIC, 523 + .regs = { 524 + .override = 0x510, 525 + .security = 0x514, 526 + }, 527 + }, { 528 + .name = "nvdecsrd1", 529 + .sid = TEGRA186_SID_NVDEC, 530 + .regs = { 531 + .override = 0x518, 532 + .security = 0x51c, 533 + }, 534 + }, 535 + }; 536 + 537 + static int tegra186_mc_probe(struct platform_device *pdev) 538 + { 539 + struct resource *res; 540 + struct tegra_mc *mc; 541 + unsigned int i; 542 + int err = 0; 543 + 544 + mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL); 545 + if (!mc) 546 + return -ENOMEM; 547 + 548 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 549 + mc->regs = devm_ioremap_resource(&pdev->dev, res); 550 + if (IS_ERR(mc->regs)) 551 + return PTR_ERR(mc->regs); 552 + 553 + mc->dev = &pdev->dev; 554 + 555 + for (i = 0; i < ARRAY_SIZE(tegra186_mc_clients); i++) { 556 + const struct tegra_mc_client *client = &tegra186_mc_clients[i]; 557 + u32 override, security; 558 + 559 + override = readl(mc->regs + client->regs.override); 560 + security = readl(mc->regs + client->regs.security); 561 + 562 + dev_dbg(&pdev->dev, "client %s: override: %x security: %x\n", 563 + client->name, override, security); 564 + 565 + dev_dbg(&pdev->dev, "setting SID %u for %s\n", client->sid, 566 + client->name); 567 + writel(client->sid, mc->regs + client->regs.override); 568 + 569 + override = readl(mc->regs + client->regs.override); 570 + security = readl(mc->regs + client->regs.security); 571 + 572 + dev_dbg(&pdev->dev, "client %s: override: %x security: %x\n", 573 + client->name, override, security); 574 + } 575 + 576 + platform_set_drvdata(pdev, mc); 577 + 578 + return err; 579 + } 580 + 581 + static const struct of_device_id tegra186_mc_of_match[] = { 582 + { .compatible = "nvidia,tegra186-mc", }, 583 + { /* sentinel */ } 584 + }; 585 + MODULE_DEVICE_TABLE(of, tegra186_mc_of_match); 586 + 587 + static struct platform_driver tegra186_mc_driver = { 588 + .driver = { 589 + .name = "tegra186-mc", 590 + .of_match_table = tegra186_mc_of_match, 591 + .suppress_bind_attrs = true, 592 + }, 593 + .prevent_deferred_probe = true, 594 + .probe = tegra186_mc_probe, 595 + }; 596 + module_platform_driver(tegra186_mc_driver); 597 + 598 + MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); 599 + MODULE_DESCRIPTION("NVIDIA Tegra186 Memory Controller driver"); 600 + MODULE_LICENSE("GPL v2");
+15
drivers/memory/tegra/tegra210.c
··· 1059 1059 { .name = "tsecb", .swgroup = TEGRA_SWGROUP_TSECB, .reg = 0xad4 }, 1060 1060 }; 1061 1061 1062 + static const unsigned int tegra210_group_display[] = { 1063 + TEGRA_SWGROUP_DC, 1064 + TEGRA_SWGROUP_DCB, 1065 + }; 1066 + 1067 + static const struct tegra_smmu_group_soc tegra210_groups[] = { 1068 + { 1069 + .name = "display", 1070 + .swgroups = tegra210_group_display, 1071 + .num_swgroups = ARRAY_SIZE(tegra210_group_display), 1072 + }, 1073 + }; 1074 + 1062 1075 static const struct tegra_smmu_soc tegra210_smmu_soc = { 1063 1076 .clients = tegra210_mc_clients, 1064 1077 .num_clients = ARRAY_SIZE(tegra210_mc_clients), 1065 1078 .swgroups = tegra210_swgroups, 1066 1079 .num_swgroups = ARRAY_SIZE(tegra210_swgroups), 1080 + .groups = tegra210_groups, 1081 + .num_groups = ARRAY_SIZE(tegra210_groups), 1067 1082 .supports_round_robin_arbitration = true, 1068 1083 .supports_request_limit = true, 1069 1084 .num_tlb_lines = 32,
+15
drivers/memory/tegra/tegra30.c
··· 934 934 { .name = "isp", .swgroup = TEGRA_SWGROUP_ISP, .reg = 0x258 }, 935 935 }; 936 936 937 + static const unsigned int tegra30_group_display[] = { 938 + TEGRA_SWGROUP_DC, 939 + TEGRA_SWGROUP_DCB, 940 + }; 941 + 942 + static const struct tegra_smmu_group_soc tegra30_groups[] = { 943 + { 944 + .name = "display", 945 + .swgroups = tegra30_group_display, 946 + .num_swgroups = ARRAY_SIZE(tegra30_group_display), 947 + }, 948 + }; 949 + 937 950 static const struct tegra_smmu_soc tegra30_smmu_soc = { 938 951 .clients = tegra30_mc_clients, 939 952 .num_clients = ARRAY_SIZE(tegra30_mc_clients), 940 953 .swgroups = tegra30_swgroups, 941 954 .num_swgroups = ARRAY_SIZE(tegra30_swgroups), 955 + .groups = tegra30_groups, 956 + .num_groups = ARRAY_SIZE(tegra30_groups), 942 957 .supports_round_robin_arbitration = false, 943 958 .supports_request_limit = false, 944 959 .num_tlb_lines = 16,
+111
include/dt-bindings/memory/tegra186-mc.h
··· 1 + #ifndef DT_BINDINGS_MEMORY_TEGRA186_MC_H 2 + #define DT_BINDINGS_MEMORY_TEGRA186_MC_H 3 + 4 + /* special clients */ 5 + #define TEGRA186_SID_INVALID 0x00 6 + #define TEGRA186_SID_PASSTHROUGH 0x7f 7 + 8 + /* host1x clients */ 9 + #define TEGRA186_SID_HOST1X 0x01 10 + #define TEGRA186_SID_CSI 0x02 11 + #define TEGRA186_SID_VIC 0x03 12 + #define TEGRA186_SID_VI 0x04 13 + #define TEGRA186_SID_ISP 0x05 14 + #define TEGRA186_SID_NVDEC 0x06 15 + #define TEGRA186_SID_NVENC 0x07 16 + #define TEGRA186_SID_NVJPG 0x08 17 + #define TEGRA186_SID_NVDISPLAY 0x09 18 + #define TEGRA186_SID_TSEC 0x0a 19 + #define TEGRA186_SID_TSECB 0x0b 20 + #define TEGRA186_SID_SE 0x0c 21 + #define TEGRA186_SID_SE1 0x0d 22 + #define TEGRA186_SID_SE2 0x0e 23 + #define TEGRA186_SID_SE3 0x0f 24 + 25 + /* GPU clients */ 26 + #define TEGRA186_SID_GPU 0x10 27 + 28 + /* other SoC clients */ 29 + #define TEGRA186_SID_AFI 0x11 30 + #define TEGRA186_SID_HDA 0x12 31 + #define TEGRA186_SID_ETR 0x13 32 + #define TEGRA186_SID_EQOS 0x14 33 + #define TEGRA186_SID_UFSHC 0x15 34 + #define TEGRA186_SID_AON 0x16 35 + #define TEGRA186_SID_SDMMC4 0x17 36 + #define TEGRA186_SID_SDMMC3 0x18 37 + #define TEGRA186_SID_SDMMC2 0x19 38 + #define TEGRA186_SID_SDMMC1 0x1a 39 + #define TEGRA186_SID_XUSB_HOST 0x1b 40 + #define TEGRA186_SID_XUSB_DEV 0x1c 41 + #define TEGRA186_SID_SATA 0x1d 42 + #define TEGRA186_SID_APE 0x1e 43 + #define TEGRA186_SID_SCE 0x1f 44 + 45 + /* GPC DMA clients */ 46 + #define TEGRA186_SID_GPCDMA_0 0x20 47 + #define TEGRA186_SID_GPCDMA_1 0x21 48 + #define TEGRA186_SID_GPCDMA_2 0x22 49 + #define TEGRA186_SID_GPCDMA_3 0x23 50 + #define TEGRA186_SID_GPCDMA_4 0x24 51 + #define TEGRA186_SID_GPCDMA_5 0x25 52 + #define TEGRA186_SID_GPCDMA_6 0x26 53 + #define TEGRA186_SID_GPCDMA_7 0x27 54 + 55 + /* APE DMA clients */ 56 + #define TEGRA186_SID_APE_1 0x28 57 + #define TEGRA186_SID_APE_2 0x29 58 + 59 + /* camera RTCPU */ 60 + #define TEGRA186_SID_RCE 0x2a 61 + 62 + /* camera RTCPU on host1x address space */ 63 + #define TEGRA186_SID_RCE_1X 0x2b 64 + 65 + /* APE DMA clients */ 66 + #define TEGRA186_SID_APE_3 0x2c 67 + 68 + /* camera RTCPU running on APE */ 69 + #define TEGRA186_SID_APE_CAM 0x2d 70 + #define TEGRA186_SID_APE_CAM_1X 0x2e 71 + 72 + /* 73 + * The BPMP has its SID value hardcoded in the firmware. Changing it requires 74 + * considerable effort. 75 + */ 76 + #define TEGRA186_SID_BPMP 0x32 77 + 78 + /* for SMMU tests */ 79 + #define TEGRA186_SID_SMMU_TEST 0x33 80 + 81 + /* host1x virtualization channels */ 82 + #define TEGRA186_SID_HOST1X_CTX0 0x38 83 + #define TEGRA186_SID_HOST1X_CTX1 0x39 84 + #define TEGRA186_SID_HOST1X_CTX2 0x3a 85 + #define TEGRA186_SID_HOST1X_CTX3 0x3b 86 + #define TEGRA186_SID_HOST1X_CTX4 0x3c 87 + #define TEGRA186_SID_HOST1X_CTX5 0x3d 88 + #define TEGRA186_SID_HOST1X_CTX6 0x3e 89 + #define TEGRA186_SID_HOST1X_CTX7 0x3f 90 + 91 + /* host1x command buffers */ 92 + #define TEGRA186_SID_HOST1X_VM0 0x40 93 + #define TEGRA186_SID_HOST1X_VM1 0x41 94 + #define TEGRA186_SID_HOST1X_VM2 0x42 95 + #define TEGRA186_SID_HOST1X_VM3 0x43 96 + #define TEGRA186_SID_HOST1X_VM4 0x44 97 + #define TEGRA186_SID_HOST1X_VM5 0x45 98 + #define TEGRA186_SID_HOST1X_VM6 0x46 99 + #define TEGRA186_SID_HOST1X_VM7 0x47 100 + 101 + /* SE data buffers */ 102 + #define TEGRA186_SID_SE_VM0 0x48 103 + #define TEGRA186_SID_SE_VM1 0x49 104 + #define TEGRA186_SID_SE_VM2 0x4a 105 + #define TEGRA186_SID_SE_VM3 0x4b 106 + #define TEGRA186_SID_SE_VM4 0x4c 107 + #define TEGRA186_SID_SE_VM5 0x4d 108 + #define TEGRA186_SID_SE_VM6 0x4e 109 + #define TEGRA186_SID_SE_VM7 0x4f 110 + 111 + #endif
+9
include/soc/tegra/mc.h
··· 51 51 unsigned int reg; 52 52 }; 53 53 54 + struct tegra_smmu_group_soc { 55 + const char *name; 56 + const unsigned int *swgroups; 57 + unsigned int num_swgroups; 58 + }; 59 + 54 60 struct tegra_smmu_soc { 55 61 const struct tegra_mc_client *clients; 56 62 unsigned int num_clients; 57 63 58 64 const struct tegra_smmu_swgroup *swgroups; 59 65 unsigned int num_swgroups; 66 + 67 + const struct tegra_smmu_group_soc *groups; 68 + unsigned int num_groups; 60 69 61 70 bool supports_round_robin_arbitration; 62 71 bool supports_request_limit;