aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt21
-rw-r--r--drivers/iommu/Kconfig2
-rw-r--r--drivers/iommu/tegra-smmu.c149
3 files changed, 117 insertions, 55 deletions
diff --git a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
new file mode 100644
index 000000000000..89fb5434b730
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
@@ -0,0 +1,21 @@
1NVIDIA Tegra 30 IOMMU H/W, SMMU (System Memory Management Unit)
2
3Required properties:
4- compatible : "nvidia,tegra30-smmu"
5- reg : Should contain 3 register banks(address and length) for each
6 of the SMMU register blocks.
7- interrupts : Should contain MC General interrupt.
8- nvidia,#asids : # of ASIDs
9- dma-window : IOVA start address and length.
10- nvidia,ahb : phandle to the ahb bus connected to SMMU.
11
12Example:
13 smmu {
14 compatible = "nvidia,tegra30-smmu";
15 reg = <0x7000f010 0x02c
16 0x7000f1f0 0x010
17 0x7000f228 0x05c>;
18 nvidia,#asids = <4>; /* # of ASIDs */
19 dma-window = <0 0x40000000>; /* IOVA start & length */
20 nvidia,ahb = <&ahb>;
21 };
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 4826af62a9de..9f69b561f5db 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -158,7 +158,7 @@ config TEGRA_IOMMU_GART
158 158
159config TEGRA_IOMMU_SMMU 159config TEGRA_IOMMU_SMMU
160 bool "Tegra SMMU IOMMU Support" 160 bool "Tegra SMMU IOMMU Support"
161 depends on ARCH_TEGRA_3x_SOC 161 depends on ARCH_TEGRA_3x_SOC && TEGRA_AHB
162 select IOMMU_API 162 select IOMMU_API
163 help 163 help
164 Enables support for remapping discontiguous physical memory 164 Enables support for remapping discontiguous physical memory
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index ecd679043d77..2c92b8c3514e 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -30,12 +30,15 @@
30#include <linux/sched.h> 30#include <linux/sched.h>
31#include <linux/iommu.h> 31#include <linux/iommu.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/of.h>
34#include <linux/of_iommu.h>
33 35
34#include <asm/page.h> 36#include <asm/page.h>
35#include <asm/cacheflush.h> 37#include <asm/cacheflush.h>
36 38
37#include <mach/iomap.h> 39#include <mach/iomap.h>
38#include <mach/smmu.h> 40#include <mach/smmu.h>
41#include <mach/tegra-ahb.h>
39 42
40/* bitmap of the page sizes currently supported */ 43/* bitmap of the page sizes currently supported */
41#define SMMU_IOMMU_PGSIZES (SZ_4K) 44#define SMMU_IOMMU_PGSIZES (SZ_4K)
@@ -111,12 +114,6 @@
111 114
112#define SMMU_PDE_NEXT_SHIFT 28 115#define SMMU_PDE_NEXT_SHIFT 28
113 116
114/* AHB Arbiter Registers */
115#define AHB_XBAR_CTRL 0xe0
116#define AHB_XBAR_CTRL_SMMU_INIT_DONE_DONE 1
117#define AHB_XBAR_CTRL_SMMU_INIT_DONE_SHIFT 17
118
119#define SMMU_NUM_ASIDS 4
120#define SMMU_TLB_FLUSH_VA_SECTION__MASK 0xffc00000 117#define SMMU_TLB_FLUSH_VA_SECTION__MASK 0xffc00000
121#define SMMU_TLB_FLUSH_VA_SECTION__SHIFT 12 /* right shift */ 118#define SMMU_TLB_FLUSH_VA_SECTION__SHIFT 12 /* right shift */
122#define SMMU_TLB_FLUSH_VA_GROUP__MASK 0xffffc000 119#define SMMU_TLB_FLUSH_VA_GROUP__MASK 0xffffc000
@@ -136,6 +133,7 @@
136 133
137#define SMMU_PAGE_SHIFT 12 134#define SMMU_PAGE_SHIFT 12
138#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT) 135#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT)
136#define SMMU_PAGE_MASK ((1 << SMMU_PAGE_SHIFT) - 1)
139 137
140#define SMMU_PDIR_COUNT 1024 138#define SMMU_PDIR_COUNT 1024
141#define SMMU_PDIR_SIZE (sizeof(unsigned long) * SMMU_PDIR_COUNT) 139#define SMMU_PDIR_SIZE (sizeof(unsigned long) * SMMU_PDIR_COUNT)
@@ -177,6 +175,8 @@
177#define SMMU_ASID_DISABLE 0 175#define SMMU_ASID_DISABLE 0
178#define SMMU_ASID_ASID(n) ((n) & ~SMMU_ASID_ENABLE(0)) 176#define SMMU_ASID_ASID(n) ((n) & ~SMMU_ASID_ENABLE(0))
179 177
178#define NUM_SMMU_REG_BANKS 3
179
180#define smmu_client_enable_hwgrp(c, m) smmu_client_set_hwgrp(c, m, 1) 180#define smmu_client_enable_hwgrp(c, m) smmu_client_set_hwgrp(c, m, 1)
181#define smmu_client_disable_hwgrp(c) smmu_client_set_hwgrp(c, 0, 0) 181#define smmu_client_disable_hwgrp(c) smmu_client_set_hwgrp(c, 0, 0)
182#define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1) 182#define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1)
@@ -235,7 +235,7 @@ struct smmu_as {
235 * Per SMMU device - IOMMU device 235 * Per SMMU device - IOMMU device
236 */ 236 */
237struct smmu_device { 237struct smmu_device {
238 void __iomem *regs, *regs_ahbarb; 238 void __iomem *regs[NUM_SMMU_REG_BANKS];
239 unsigned long iovmm_base; /* remappable base address */ 239 unsigned long iovmm_base; /* remappable base address */
240 unsigned long page_count; /* total remappable size */ 240 unsigned long page_count; /* total remappable size */
241 spinlock_t lock; 241 spinlock_t lock;
@@ -252,29 +252,47 @@ struct smmu_device {
252 unsigned long translation_enable_1; 252 unsigned long translation_enable_1;
253 unsigned long translation_enable_2; 253 unsigned long translation_enable_2;
254 unsigned long asid_security; 254 unsigned long asid_security;
255
256 struct device_node *ahb;
255}; 257};
256 258
257static struct smmu_device *smmu_handle; /* unique for a system */ 259static struct smmu_device *smmu_handle; /* unique for a system */
258 260
259/* 261/*
260 * SMMU/AHB register accessors 262 * SMMU register accessors
261 */ 263 */
262static inline u32 smmu_read(struct smmu_device *smmu, size_t offs) 264static inline u32 smmu_read(struct smmu_device *smmu, size_t offs)
263{ 265{
264 return readl(smmu->regs + offs); 266 BUG_ON(offs < 0x10);
265} 267 if (offs < 0x3c)
266static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs) 268 return readl(smmu->regs[0] + offs - 0x10);
267{ 269 BUG_ON(offs < 0x1f0);
268 writel(val, smmu->regs + offs); 270 if (offs < 0x200)
271 return readl(smmu->regs[1] + offs - 0x1f0);
272 BUG_ON(offs < 0x228);
273 if (offs < 0x284)
274 return readl(smmu->regs[2] + offs - 0x228);
275 BUG();
269} 276}
270 277
271static inline u32 ahb_read(struct smmu_device *smmu, size_t offs) 278static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs)
272{
273 return readl(smmu->regs_ahbarb + offs);
274}
275static inline void ahb_write(struct smmu_device *smmu, u32 val, size_t offs)
276{ 279{
277 writel(val, smmu->regs_ahbarb + offs); 280 BUG_ON(offs < 0x10);
281 if (offs < 0x3c) {
282 writel(val, smmu->regs[0] + offs - 0x10);
283 return;
284 }
285 BUG_ON(offs < 0x1f0);
286 if (offs < 0x200) {
287 writel(val, smmu->regs[1] + offs - 0x1f0);
288 return;
289 }
290 BUG_ON(offs < 0x228);
291 if (offs < 0x284) {
292 writel(val, smmu->regs[2] + offs - 0x228);
293 return;
294 }
295 BUG();
278} 296}
279 297
280#define VA_PAGE_TO_PA(va, page) \ 298#define VA_PAGE_TO_PA(va, page) \
@@ -370,7 +388,7 @@ static void smmu_flush_regs(struct smmu_device *smmu, int enable)
370 FLUSH_SMMU_REGS(smmu); 388 FLUSH_SMMU_REGS(smmu);
371} 389}
372 390
373static void smmu_setup_regs(struct smmu_device *smmu) 391static int smmu_setup_regs(struct smmu_device *smmu)
374{ 392{
375 int i; 393 int i;
376 u32 val; 394 u32 val;
@@ -398,10 +416,7 @@ static void smmu_setup_regs(struct smmu_device *smmu)
398 416
399 smmu_flush_regs(smmu, 1); 417 smmu_flush_regs(smmu, 1);
400 418
401 val = ahb_read(smmu, AHB_XBAR_CTRL); 419 return tegra_ahb_enable_smmu(smmu->ahb);
402 val |= AHB_XBAR_CTRL_SMMU_INIT_DONE_DONE <<
403 AHB_XBAR_CTRL_SMMU_INIT_DONE_SHIFT;
404 ahb_write(smmu, val, AHB_XBAR_CTRL);
405} 420}
406 421
407static void flush_ptc_and_tlb(struct smmu_device *smmu, 422static void flush_ptc_and_tlb(struct smmu_device *smmu,
@@ -873,52 +888,72 @@ static int tegra_smmu_resume(struct device *dev)
873{ 888{
874 struct smmu_device *smmu = dev_get_drvdata(dev); 889 struct smmu_device *smmu = dev_get_drvdata(dev);
875 unsigned long flags; 890 unsigned long flags;
891 int err;
876 892
877 spin_lock_irqsave(&smmu->lock, flags); 893 spin_lock_irqsave(&smmu->lock, flags);
878 smmu_setup_regs(smmu); 894 err = smmu_setup_regs(smmu);
879 spin_unlock_irqrestore(&smmu->lock, flags); 895 spin_unlock_irqrestore(&smmu->lock, flags);
880 return 0; 896 return err;
881} 897}
882 898
883static int tegra_smmu_probe(struct platform_device *pdev) 899static int tegra_smmu_probe(struct platform_device *pdev)
884{ 900{
885 struct smmu_device *smmu; 901 struct smmu_device *smmu;
886 struct resource *regs, *regs2, *window;
887 struct device *dev = &pdev->dev; 902 struct device *dev = &pdev->dev;
888 int i, err = 0; 903 int i, asids, err = 0;
904 dma_addr_t base;
905 size_t size;
906 const void *prop;
889 907
890 if (smmu_handle) 908 if (smmu_handle)
891 return -EIO; 909 return -EIO;
892 910
893 BUILD_BUG_ON(PAGE_SHIFT != SMMU_PAGE_SHIFT); 911 BUILD_BUG_ON(PAGE_SHIFT != SMMU_PAGE_SHIFT);
894 912
895 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
896 regs2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
897 window = platform_get_resource(pdev, IORESOURCE_MEM, 2);
898 if (!regs || !regs2 || !window) {
899 dev_err(dev, "No SMMU resources\n");
900 return -ENODEV;
901 }
902
903 smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL); 913 smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
904 if (!smmu) { 914 if (!smmu) {
905 dev_err(dev, "failed to allocate smmu_device\n"); 915 dev_err(dev, "failed to allocate smmu_device\n");
906 return -ENOMEM; 916 return -ENOMEM;
907 } 917 }
908 918
909 smmu->dev = dev; 919 for (i = 0; i < ARRAY_SIZE(smmu->regs); i++) {
910 smmu->num_as = SMMU_NUM_ASIDS; 920 struct resource *res;
911 smmu->iovmm_base = (unsigned long)window->start; 921
912 smmu->page_count = resource_size(window) >> SMMU_PAGE_SHIFT; 922 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
913 smmu->regs = devm_ioremap(dev, regs->start, resource_size(regs)); 923 if (!res)
914 smmu->regs_ahbarb = devm_ioremap(dev, regs2->start, 924 return -ENODEV;
915 resource_size(regs2)); 925 smmu->regs[i] = devm_request_and_ioremap(&pdev->dev, res);
916 if (!smmu->regs || !smmu->regs_ahbarb) { 926 if (!smmu->regs[i])
917 dev_err(dev, "failed to remap SMMU registers\n"); 927 return -EBUSY;
918 err = -ENXIO;
919 goto fail;
920 } 928 }
921 929
930 err = of_get_dma_window(dev->of_node, NULL, 0, NULL, &base, &size);
931 if (err)
932 return -ENODEV;
933
934 if (size & SMMU_PAGE_MASK)
935 return -EINVAL;
936
937 size >>= SMMU_PAGE_SHIFT;
938 if (!size)
939 return -EINVAL;
940
941 prop = of_get_property(dev->of_node, "nvidia,#asids", NULL);
942 if (!prop)
943 return -ENODEV;
944 asids = be32_to_cpup(prop);
945 if (!asids)
946 return -ENODEV;
947
948 smmu->ahb = of_parse_phandle(dev->of_node, "nvidia,ahb", 0);
949 if (!smmu->ahb)
950 return -ENODEV;
951
952 smmu->dev = dev;
953 smmu->num_as = asids;
954 smmu->iovmm_base = base;
955 smmu->page_count = size;
956
922 smmu->translation_enable_0 = ~0; 957 smmu->translation_enable_0 = ~0;
923 smmu->translation_enable_1 = ~0; 958 smmu->translation_enable_1 = ~0;
924 smmu->translation_enable_2 = ~0; 959 smmu->translation_enable_2 = ~0;
@@ -945,7 +980,9 @@ static int tegra_smmu_probe(struct platform_device *pdev)
945 INIT_LIST_HEAD(&as->client); 980 INIT_LIST_HEAD(&as->client);
946 } 981 }
947 spin_lock_init(&smmu->lock); 982 spin_lock_init(&smmu->lock);
948 smmu_setup_regs(smmu); 983 err = smmu_setup_regs(smmu);
984 if (err)
985 goto fail;
949 platform_set_drvdata(pdev, smmu); 986 platform_set_drvdata(pdev, smmu);
950 987
951 smmu->avp_vector_page = alloc_page(GFP_KERNEL); 988 smmu->avp_vector_page = alloc_page(GFP_KERNEL);
@@ -958,10 +995,6 @@ static int tegra_smmu_probe(struct platform_device *pdev)
958fail: 995fail:
959 if (smmu->avp_vector_page) 996 if (smmu->avp_vector_page)
960 __free_page(smmu->avp_vector_page); 997 __free_page(smmu->avp_vector_page);
961 if (smmu->regs)
962 devm_iounmap(dev, smmu->regs);
963 if (smmu->regs_ahbarb)
964 devm_iounmap(dev, smmu->regs_ahbarb);
965 if (smmu && smmu->as) { 998 if (smmu && smmu->as) {
966 for (i = 0; i < smmu->num_as; i++) { 999 for (i = 0; i < smmu->num_as; i++) {
967 if (smmu->as[i].pdir_page) { 1000 if (smmu->as[i].pdir_page) {
@@ -993,8 +1026,6 @@ static int tegra_smmu_remove(struct platform_device *pdev)
993 __free_page(smmu->avp_vector_page); 1026 __free_page(smmu->avp_vector_page);
994 if (smmu->regs) 1027 if (smmu->regs)
995 devm_iounmap(dev, smmu->regs); 1028 devm_iounmap(dev, smmu->regs);
996 if (smmu->regs_ahbarb)
997 devm_iounmap(dev, smmu->regs_ahbarb);
998 devm_kfree(dev, smmu); 1029 devm_kfree(dev, smmu);
999 smmu_handle = NULL; 1030 smmu_handle = NULL;
1000 return 0; 1031 return 0;
@@ -1005,6 +1036,14 @@ const struct dev_pm_ops tegra_smmu_pm_ops = {
1005 .resume = tegra_smmu_resume, 1036 .resume = tegra_smmu_resume,
1006}; 1037};
1007 1038
1039#ifdef CONFIG_OF
1040static struct of_device_id tegra_smmu_of_match[] __devinitdata = {
1041 { .compatible = "nvidia,tegra30-smmu", },
1042 { },
1043};
1044MODULE_DEVICE_TABLE(of, tegra_smmu_of_match);
1045#endif
1046
1008static struct platform_driver tegra_smmu_driver = { 1047static struct platform_driver tegra_smmu_driver = {
1009 .probe = tegra_smmu_probe, 1048 .probe = tegra_smmu_probe,
1010 .remove = tegra_smmu_remove, 1049 .remove = tegra_smmu_remove,
@@ -1012,6 +1051,7 @@ static struct platform_driver tegra_smmu_driver = {
1012 .owner = THIS_MODULE, 1051 .owner = THIS_MODULE,
1013 .name = "tegra-smmu", 1052 .name = "tegra-smmu",
1014 .pm = &tegra_smmu_pm_ops, 1053 .pm = &tegra_smmu_pm_ops,
1054 .of_match_table = of_match_ptr(tegra_smmu_of_match),
1015 }, 1055 },
1016}; 1056};
1017 1057
@@ -1031,4 +1071,5 @@ module_exit(tegra_smmu_exit);
1031 1071
1032MODULE_DESCRIPTION("IOMMU API for SMMU in Tegra30"); 1072MODULE_DESCRIPTION("IOMMU API for SMMU in Tegra30");
1033MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>"); 1073MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
1074MODULE_ALIAS("platform:tegra-smmu");
1034MODULE_LICENSE("GPL v2"); 1075MODULE_LICENSE("GPL v2");