diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 51a9708290dc..c5aa465231c4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | |||
@@ -145,3 +145,106 @@ void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev) | |||
145 | if (WARN_ON(adev->gfx.num_compute_rings > AMDGPU_MAX_COMPUTE_RINGS)) | 145 | if (WARN_ON(adev->gfx.num_compute_rings > AMDGPU_MAX_COMPUTE_RINGS)) |
146 | adev->gfx.num_compute_rings = AMDGPU_MAX_COMPUTE_RINGS; | 146 | adev->gfx.num_compute_rings = AMDGPU_MAX_COMPUTE_RINGS; |
147 | } | 147 | } |
148 | |||
149 | static int amdgpu_gfx_kiq_acquire(struct amdgpu_device *adev, | ||
150 | struct amdgpu_ring *ring) | ||
151 | { | ||
152 | int queue_bit; | ||
153 | int mec, pipe, queue; | ||
154 | |||
155 | queue_bit = adev->gfx.mec.num_mec | ||
156 | * adev->gfx.mec.num_pipe_per_mec | ||
157 | * adev->gfx.mec.num_queue_per_pipe; | ||
158 | |||
159 | while (queue_bit-- >= 0) { | ||
160 | if (test_bit(queue_bit, adev->gfx.mec.queue_bitmap)) | ||
161 | continue; | ||
162 | |||
163 | amdgpu_gfx_bit_to_queue(adev, queue_bit, &mec, &pipe, &queue); | ||
164 | |||
165 | /* Using pipes 2/3 from MEC 2 seems cause problems */ | ||
166 | if (mec == 1 && pipe > 1) | ||
167 | continue; | ||
168 | |||
169 | ring->me = mec + 1; | ||
170 | ring->pipe = pipe; | ||
171 | ring->queue = queue; | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | dev_err(adev->dev, "Failed to find a queue for KIQ\n"); | ||
177 | return -EINVAL; | ||
178 | } | ||
179 | |||
180 | int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev, | ||
181 | struct amdgpu_ring *ring, | ||
182 | struct amdgpu_irq_src *irq) | ||
183 | { | ||
184 | struct amdgpu_kiq *kiq = &adev->gfx.kiq; | ||
185 | int r = 0; | ||
186 | |||
187 | mutex_init(&kiq->ring_mutex); | ||
188 | |||
189 | r = amdgpu_wb_get(adev, &adev->virt.reg_val_offs); | ||
190 | if (r) | ||
191 | return r; | ||
192 | |||
193 | ring->adev = NULL; | ||
194 | ring->ring_obj = NULL; | ||
195 | ring->use_doorbell = true; | ||
196 | ring->doorbell_index = AMDGPU_DOORBELL_KIQ; | ||
197 | |||
198 | r = amdgpu_gfx_kiq_acquire(adev, ring); | ||
199 | if (r) | ||
200 | return r; | ||
201 | |||
202 | ring->eop_gpu_addr = kiq->eop_gpu_addr; | ||
203 | sprintf(ring->name, "kiq %d.%d.%d", ring->me, ring->pipe, ring->queue); | ||
204 | r = amdgpu_ring_init(adev, ring, 1024, | ||
205 | irq, AMDGPU_CP_KIQ_IRQ_DRIVER0); | ||
206 | if (r) | ||
207 | dev_warn(adev->dev, "(%d) failed to init kiq ring\n", r); | ||
208 | |||
209 | return r; | ||
210 | } | ||
211 | |||
212 | void amdgpu_gfx_kiq_free_ring(struct amdgpu_ring *ring, | ||
213 | struct amdgpu_irq_src *irq) | ||
214 | { | ||
215 | amdgpu_wb_free(ring->adev, ring->adev->virt.reg_val_offs); | ||
216 | amdgpu_ring_fini(ring); | ||
217 | } | ||
218 | |||
219 | void amdgpu_gfx_kiq_fini(struct amdgpu_device *adev) | ||
220 | { | ||
221 | struct amdgpu_kiq *kiq = &adev->gfx.kiq; | ||
222 | |||
223 | amdgpu_bo_free_kernel(&kiq->eop_obj, &kiq->eop_gpu_addr, NULL); | ||
224 | } | ||
225 | |||
226 | int amdgpu_gfx_kiq_init(struct amdgpu_device *adev, | ||
227 | unsigned hpd_size) | ||
228 | { | ||
229 | int r; | ||
230 | u32 *hpd; | ||
231 | struct amdgpu_kiq *kiq = &adev->gfx.kiq; | ||
232 | |||
233 | r = amdgpu_bo_create_kernel(adev, hpd_size, PAGE_SIZE, | ||
234 | AMDGPU_GEM_DOMAIN_GTT, &kiq->eop_obj, | ||
235 | &kiq->eop_gpu_addr, (void **)&hpd); | ||
236 | if (r) { | ||
237 | dev_warn(adev->dev, "failed to create KIQ bo (%d).\n", r); | ||
238 | return r; | ||
239 | } | ||
240 | |||
241 | memset(hpd, 0, hpd_size); | ||
242 | |||
243 | r = amdgpu_bo_reserve(kiq->eop_obj, true); | ||
244 | if (unlikely(r != 0)) | ||
245 | dev_warn(adev->dev, "(%d) reserve kiq eop bo failed\n", r); | ||
246 | amdgpu_bo_kunmap(kiq->eop_obj); | ||
247 | amdgpu_bo_unreserve(kiq->eop_obj); | ||
248 | |||
249 | return 0; | ||
250 | } | ||