aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1835-drm-amd-amdgpu-add-support-for-iova_to_phys-to-repla.patch
blob: ca0403f37e83731c289484ea87b643218dcc122b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
From 299368dc0e31366db1aa9d317fccbf3272ed10c9 Mon Sep 17 00:00:00 2001
From: Tom St Denis <tom.stdenis@amd.com>
Date: Mon, 18 Sep 2017 07:28:14 -0400
Subject: [PATCH 1835/4131] drm/amd/amdgpu: add support for iova_to_phys to
 replace TTM trace (v5)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Tom St Denis <tom.stdenis@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>

(v2): Add domain to iova debugfs
(v3): Add true read/write methods to access system memory of pages
      mapped to the device
(v4): Move get_domain call out of loop and return on error
(v5): Just use kmap/kunmap
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 99 +++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 8681ce6..4daaacd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -43,6 +43,7 @@
 #include <linux/swap.h>
 #include <linux/pagemap.h>
 #include <linux/debugfs.h>
+#include <linux/iommu.h>
 #include "amdgpu.h"
 #include "amdgpu_trace.h"
 #include "bif/bif_4_1_d.h"
@@ -2101,7 +2102,104 @@ static const struct file_operations amdgpu_ttm_gtt_fops = {
 
 #endif
 
+static ssize_t amdgpu_iova_to_phys_read(struct file *f, char __user *buf,
+				   size_t size, loff_t *pos)
+{
+	struct amdgpu_device *adev = file_inode(f)->i_private;
+	ssize_t result, n;
+	int r;
+	uint64_t phys;
+	void *ptr;
+	struct iommu_domain *dom;
+
+	dom = iommu_get_domain_for_dev(adev->dev);
+	if (!dom)
+		return -EFAULT;
+
+	result = 0;
+	while (size) {
+		// get physical address and map
+		phys = iommu_iova_to_phys(dom, *pos);
+
+		// copy upto one page
+		if (size > PAGE_SIZE)
+			n = PAGE_SIZE;
+		else
+			n = size;
+
+		// to end of the page
+		if (((*pos & (PAGE_SIZE - 1)) + n) >= PAGE_SIZE)
+			n = PAGE_SIZE - (*pos & (PAGE_SIZE - 1));
+
+		ptr = kmap(pfn_to_page(PFN_DOWN(phys)));
+		if (!ptr)
+			return -EFAULT;
+
+		r = copy_to_user(buf, ptr, n);
+		kunmap(pfn_to_page(PFN_DOWN(phys)));
+		if (r)
+			return -EFAULT;
+
+		*pos += n;
+		size -= n;
+		result += n;
+	}
+
+	return result;
+}
+
+static ssize_t amdgpu_iova_to_phys_write(struct file *f, const char __user *buf,
+				   size_t size, loff_t *pos)
+{
+	struct amdgpu_device *adev = file_inode(f)->i_private;
+	ssize_t result, n;
+	int r;
+	uint64_t phys;
+	void *ptr;
+	struct iommu_domain *dom;
+
+	dom = iommu_get_domain_for_dev(adev->dev);
+	if (!dom)
+		return -EFAULT;
+
+	result = 0;
+	while (size) {
+		// get physical address and map
+		phys = iommu_iova_to_phys(dom, *pos);
 
+		// copy upto one page
+		if (size > PAGE_SIZE)
+			n = PAGE_SIZE;
+		else
+			n = size;
+
+		// to end of the page
+		if (((*pos & (PAGE_SIZE - 1)) + n) >= PAGE_SIZE)
+			n = PAGE_SIZE - (*pos & (PAGE_SIZE - 1));
+
+		ptr = kmap(pfn_to_page(PFN_DOWN(phys)));
+		if (!ptr)
+			return -EFAULT;
+
+		r = copy_from_user(ptr, buf, n);
+		kunmap(pfn_to_page(PFN_DOWN(phys)));
+		if (r)
+			return -EFAULT;
+
+		*pos += n;
+		size -= n;
+		result += n;
+	}
+
+	return result;
+}
+
+static const struct file_operations amdgpu_ttm_iova_fops = {
+	.owner = THIS_MODULE,
+	.read = amdgpu_iova_to_phys_read,
+	.write = amdgpu_iova_to_phys_write,
+	.llseek = default_llseek
+};
 
 static const struct {
 	char *name;
@@ -2112,6 +2210,7 @@ static const struct {
 #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
 	{ "amdgpu_gtt", &amdgpu_ttm_gtt_fops, TTM_PL_TT },
 #endif
+	{ "amdgpu_iova", &amdgpu_ttm_iova_fops, TTM_PL_SYSTEM },
 };
 
 #endif
-- 
2.7.4