aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c117
1 files changed, 40 insertions, 77 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index 369beb5041a2..448d69fe3756 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -64,16 +64,21 @@ int amdgpu_debugfs_add_files(struct amdgpu_device *adev,
64 64
65#if defined(CONFIG_DEBUG_FS) 65#if defined(CONFIG_DEBUG_FS)
66 66
67static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf, 67
68 size_t size, loff_t *pos) 68static int amdgpu_debugfs_process_reg_op(bool read, struct file *f,
69 char __user *buf, size_t size, loff_t *pos)
69{ 70{
70 struct amdgpu_device *adev = file_inode(f)->i_private; 71 struct amdgpu_device *adev = file_inode(f)->i_private;
71 ssize_t result = 0; 72 ssize_t result = 0;
72 int r; 73 int r;
73 bool pm_pg_lock, use_bank; 74 bool pm_pg_lock, use_bank, use_ring;
74 unsigned instance_bank, sh_bank, se_bank; 75 unsigned instance_bank, sh_bank, se_bank, me, pipe, queue;
75 76
76 if (size & 0x3 || *pos & 0x3) 77 pm_pg_lock = use_bank = use_ring = false;
78 instance_bank = sh_bank = se_bank = me = pipe = queue = 0;
79
80 if (size & 0x3 || *pos & 0x3 ||
81 ((*pos & (1ULL << 62)) && (*pos & (1ULL << 61))))
77 return -EINVAL; 82 return -EINVAL;
78 83
79 /* are we reading registers for which a PG lock is necessary? */ 84 /* are we reading registers for which a PG lock is necessary? */
@@ -91,8 +96,15 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
91 if (instance_bank == 0x3FF) 96 if (instance_bank == 0x3FF)
92 instance_bank = 0xFFFFFFFF; 97 instance_bank = 0xFFFFFFFF;
93 use_bank = 1; 98 use_bank = 1;
99 } else if (*pos & (1ULL << 61)) {
100
101 me = (*pos & GENMASK_ULL(33, 24)) >> 24;
102 pipe = (*pos & GENMASK_ULL(43, 34)) >> 34;
103 queue = (*pos & GENMASK_ULL(53, 44)) >> 44;
104
105 use_ring = 1;
94 } else { 106 } else {
95 use_bank = 0; 107 use_bank = use_ring = 0;
96 } 108 }
97 109
98 *pos &= (1UL << 22) - 1; 110 *pos &= (1UL << 22) - 1;
@@ -104,6 +116,9 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
104 mutex_lock(&adev->grbm_idx_mutex); 116 mutex_lock(&adev->grbm_idx_mutex);
105 amdgpu_gfx_select_se_sh(adev, se_bank, 117 amdgpu_gfx_select_se_sh(adev, se_bank,
106 sh_bank, instance_bank); 118 sh_bank, instance_bank);
119 } else if (use_ring) {
120 mutex_lock(&adev->srbm_mutex);
121 amdgpu_gfx_select_me_pipe_q(adev, me, pipe, queue);
107 } 122 }
108 123
109 if (pm_pg_lock) 124 if (pm_pg_lock)
@@ -115,8 +130,14 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
115 if (*pos > adev->rmmio_size) 130 if (*pos > adev->rmmio_size)
116 goto end; 131 goto end;
117 132
118 value = RREG32(*pos >> 2); 133 if (read) {
119 r = put_user(value, (uint32_t *)buf); 134 value = RREG32(*pos >> 2);
135 r = put_user(value, (uint32_t *)buf);
136 } else {
137 r = get_user(value, (uint32_t *)buf);
138 if (!r)
139 WREG32(*pos >> 2, value);
140 }
120 if (r) { 141 if (r) {
121 result = r; 142 result = r;
122 goto end; 143 goto end;
@@ -132,6 +153,9 @@ end:
132 if (use_bank) { 153 if (use_bank) {
133 amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); 154 amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
134 mutex_unlock(&adev->grbm_idx_mutex); 155 mutex_unlock(&adev->grbm_idx_mutex);
156 } else if (use_ring) {
157 amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0);
158 mutex_unlock(&adev->srbm_mutex);
135 } 159 }
136 160
137 if (pm_pg_lock) 161 if (pm_pg_lock)
@@ -140,78 +164,17 @@ end:
140 return result; 164 return result;
141} 165}
142 166
167
168static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
169 size_t size, loff_t *pos)
170{
171 return amdgpu_debugfs_process_reg_op(true, f, buf, size, pos);
172}
173
143static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf, 174static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,
144 size_t size, loff_t *pos) 175 size_t size, loff_t *pos)
145{ 176{
146 struct amdgpu_device *adev = file_inode(f)->i_private; 177 return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos);
147 ssize_t result = 0;
148 int r;
149 bool pm_pg_lock, use_bank;
150 unsigned instance_bank, sh_bank, se_bank;
151
152 if (size & 0x3 || *pos & 0x3)
153 return -EINVAL;
154
155 /* are we reading registers for which a PG lock is necessary? */
156 pm_pg_lock = (*pos >> 23) & 1;
157
158 if (*pos & (1ULL << 62)) {
159 se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24;
160 sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34;
161 instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44;
162
163 if (se_bank == 0x3FF)
164 se_bank = 0xFFFFFFFF;
165 if (sh_bank == 0x3FF)
166 sh_bank = 0xFFFFFFFF;
167 if (instance_bank == 0x3FF)
168 instance_bank = 0xFFFFFFFF;
169 use_bank = 1;
170 } else {
171 use_bank = 0;
172 }
173
174 *pos &= (1UL << 22) - 1;
175
176 if (use_bank) {
177 if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||
178 (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines))
179 return -EINVAL;
180 mutex_lock(&adev->grbm_idx_mutex);
181 amdgpu_gfx_select_se_sh(adev, se_bank,
182 sh_bank, instance_bank);
183 }
184
185 if (pm_pg_lock)
186 mutex_lock(&adev->pm.mutex);
187
188 while (size) {
189 uint32_t value;
190
191 if (*pos > adev->rmmio_size)
192 return result;
193
194 r = get_user(value, (uint32_t *)buf);
195 if (r)
196 return r;
197
198 WREG32(*pos >> 2, value);
199
200 result += 4;
201 buf += 4;
202 *pos += 4;
203 size -= 4;
204 }
205
206 if (use_bank) {
207 amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
208 mutex_unlock(&adev->grbm_idx_mutex);
209 }
210
211 if (pm_pg_lock)
212 mutex_unlock(&adev->pm.mutex);
213
214 return result;
215} 178}
216 179
217static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf, 180static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,