diff options
author | James Zhu <James.Zhu@amd.com> | 2018-05-15 15:31:24 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-05-18 17:08:12 -0400 |
commit | 10dd74eac4dba963bfa97f5092040aa75ff742d6 (patch) | |
tree | b93a33adbbe061247ae98fb024b6100ad86407d9 | |
parent | 2bb795f5ba9cd676536858a978b9df06f473af88 (diff) |
drm/amdgpu/vg20:Restruct uvd.inst to support multiple instances
Vega20 has dual-UVD. Need add multiple instances support for uvd.
Restruct uvd.inst, using uvd.inst[0] to replace uvd.inst->.
Repurpose amdgpu_ring::me for instance index, and initialize to 0.
There are no any logical changes here.
Signed-off-by: James Zhu <James.Zhu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 229 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 1002 |
5 files changed, 660 insertions, 590 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 1070f4042cbb..39ec6b8890a1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | |||
@@ -376,14 +376,14 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring, | |||
376 | struct amdgpu_device *adev = ring->adev; | 376 | struct amdgpu_device *adev = ring->adev; |
377 | uint64_t index; | 377 | uint64_t index; |
378 | 378 | ||
379 | if (ring != &adev->uvd.inst->ring) { | 379 | if (ring != &adev->uvd.inst[ring->me].ring) { |
380 | ring->fence_drv.cpu_addr = &adev->wb.wb[ring->fence_offs]; | 380 | ring->fence_drv.cpu_addr = &adev->wb.wb[ring->fence_offs]; |
381 | ring->fence_drv.gpu_addr = adev->wb.gpu_addr + (ring->fence_offs * 4); | 381 | ring->fence_drv.gpu_addr = adev->wb.gpu_addr + (ring->fence_offs * 4); |
382 | } else { | 382 | } else { |
383 | /* put fence directly behind firmware */ | 383 | /* put fence directly behind firmware */ |
384 | index = ALIGN(adev->uvd.fw->size, 8); | 384 | index = ALIGN(adev->uvd.fw->size, 8); |
385 | ring->fence_drv.cpu_addr = adev->uvd.inst->cpu_addr + index; | 385 | ring->fence_drv.cpu_addr = adev->uvd.inst[ring->me].cpu_addr + index; |
386 | ring->fence_drv.gpu_addr = adev->uvd.inst->gpu_addr + index; | 386 | ring->fence_drv.gpu_addr = adev->uvd.inst[ring->me].gpu_addr + index; |
387 | } | 387 | } |
388 | amdgpu_fence_write(ring, atomic_read(&ring->fence_drv.last_seq)); | 388 | amdgpu_fence_write(ring, atomic_read(&ring->fence_drv.last_seq)); |
389 | amdgpu_irq_get(adev, irq_src, irq_type); | 389 | amdgpu_irq_get(adev, irq_src, irq_type); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 5620ed291107..91517b166a3b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
@@ -286,7 +286,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
286 | struct drm_crtc *crtc; | 286 | struct drm_crtc *crtc; |
287 | uint32_t ui32 = 0; | 287 | uint32_t ui32 = 0; |
288 | uint64_t ui64 = 0; | 288 | uint64_t ui64 = 0; |
289 | int i, found; | 289 | int i, j, found; |
290 | int ui32_size = sizeof(ui32); | 290 | int ui32_size = sizeof(ui32); |
291 | 291 | ||
292 | if (!info->return_size || !info->return_pointer) | 292 | if (!info->return_size || !info->return_pointer) |
@@ -348,7 +348,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
348 | break; | 348 | break; |
349 | case AMDGPU_HW_IP_UVD: | 349 | case AMDGPU_HW_IP_UVD: |
350 | type = AMD_IP_BLOCK_TYPE_UVD; | 350 | type = AMD_IP_BLOCK_TYPE_UVD; |
351 | ring_mask = adev->uvd.inst->ring.ready ? 1 : 0; | 351 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) |
352 | ring_mask |= ((adev->uvd.inst[i].ring.ready ? 1 : 0) << i); | ||
352 | ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; | 353 | ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; |
353 | ib_size_alignment = 16; | 354 | ib_size_alignment = 16; |
354 | break; | 355 | break; |
@@ -361,8 +362,11 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file | |||
361 | break; | 362 | break; |
362 | case AMDGPU_HW_IP_UVD_ENC: | 363 | case AMDGPU_HW_IP_UVD_ENC: |
363 | type = AMD_IP_BLOCK_TYPE_UVD; | 364 | type = AMD_IP_BLOCK_TYPE_UVD; |
364 | for (i = 0; i < adev->uvd.num_enc_rings; i++) | 365 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) |
365 | ring_mask |= ((adev->uvd.inst->ring_enc[i].ready ? 1 : 0) << i); | 366 | for (j = 0; j < adev->uvd.num_enc_rings; j++) |
367 | ring_mask |= | ||
368 | ((adev->uvd.inst[i].ring_enc[j].ready ? 1 : 0) << | ||
369 | (j + i * adev->uvd.num_enc_rings)); | ||
366 | ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; | 370 | ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; |
367 | ib_size_alignment = 1; | 371 | ib_size_alignment = 1; |
368 | break; | 372 | break; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 49cad08b5c16..c6850b629d0e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | |||
@@ -362,6 +362,7 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) | |||
362 | 362 | ||
363 | dma_fence_put(ring->vmid_wait); | 363 | dma_fence_put(ring->vmid_wait); |
364 | ring->vmid_wait = NULL; | 364 | ring->vmid_wait = NULL; |
365 | ring->me = 0; | ||
365 | 366 | ||
366 | ring->adev->rings[ring->idx] = NULL; | 367 | ring->adev->rings[ring->idx] = NULL; |
367 | } | 368 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 02683a039a98..e961492d357a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | |||
@@ -127,7 +127,7 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) | |||
127 | const char *fw_name; | 127 | const char *fw_name; |
128 | const struct common_firmware_header *hdr; | 128 | const struct common_firmware_header *hdr; |
129 | unsigned version_major, version_minor, family_id; | 129 | unsigned version_major, version_minor, family_id; |
130 | int i, r; | 130 | int i, j, r; |
131 | 131 | ||
132 | INIT_DELAYED_WORK(&adev->uvd.inst->idle_work, amdgpu_uvd_idle_work_handler); | 132 | INIT_DELAYED_WORK(&adev->uvd.inst->idle_work, amdgpu_uvd_idle_work_handler); |
133 | 133 | ||
@@ -236,28 +236,30 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) | |||
236 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) | 236 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) |
237 | bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); | 237 | bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); |
238 | 238 | ||
239 | r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE, | 239 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
240 | AMDGPU_GEM_DOMAIN_VRAM, &adev->uvd.inst->vcpu_bo, | ||
241 | &adev->uvd.inst->gpu_addr, &adev->uvd.inst->cpu_addr); | ||
242 | if (r) { | ||
243 | dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r); | ||
244 | return r; | ||
245 | } | ||
246 | 240 | ||
247 | ring = &adev->uvd.inst->ring; | 241 | r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE, |
248 | rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; | 242 | AMDGPU_GEM_DOMAIN_VRAM, &adev->uvd.inst[j].vcpu_bo, |
249 | r = drm_sched_entity_init(&ring->sched, &adev->uvd.inst->entity, | 243 | &adev->uvd.inst[j].gpu_addr, &adev->uvd.inst[j].cpu_addr); |
250 | rq, NULL); | 244 | if (r) { |
251 | if (r != 0) { | 245 | dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r); |
252 | DRM_ERROR("Failed setting up UVD run queue.\n"); | 246 | return r; |
253 | return r; | 247 | } |
254 | } | ||
255 | 248 | ||
256 | for (i = 0; i < adev->uvd.max_handles; ++i) { | 249 | ring = &adev->uvd.inst[j].ring; |
257 | atomic_set(&adev->uvd.inst->handles[i], 0); | 250 | rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; |
258 | adev->uvd.inst->filp[i] = NULL; | 251 | r = drm_sched_entity_init(&ring->sched, &adev->uvd.inst[j].entity, |
259 | } | 252 | rq, NULL); |
253 | if (r != 0) { | ||
254 | DRM_ERROR("Failed setting up UVD(%d) run queue.\n", j); | ||
255 | return r; | ||
256 | } | ||
260 | 257 | ||
258 | for (i = 0; i < adev->uvd.max_handles; ++i) { | ||
259 | atomic_set(&adev->uvd.inst[j].handles[i], 0); | ||
260 | adev->uvd.inst[j].filp[i] = NULL; | ||
261 | } | ||
262 | } | ||
261 | /* from uvd v5.0 HW addressing capacity increased to 64 bits */ | 263 | /* from uvd v5.0 HW addressing capacity increased to 64 bits */ |
262 | if (!amdgpu_device_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0)) | 264 | if (!amdgpu_device_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0)) |
263 | adev->uvd.address_64_bit = true; | 265 | adev->uvd.address_64_bit = true; |
@@ -284,20 +286,22 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) | |||
284 | 286 | ||
285 | int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) | 287 | int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) |
286 | { | 288 | { |
287 | int i; | 289 | int i, j; |
288 | kfree(adev->uvd.inst->saved_bo); | ||
289 | 290 | ||
290 | drm_sched_entity_fini(&adev->uvd.inst->ring.sched, &adev->uvd.inst->entity); | 291 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { |
292 | kfree(adev->uvd.inst[j].saved_bo); | ||
291 | 293 | ||
292 | amdgpu_bo_free_kernel(&adev->uvd.inst->vcpu_bo, | 294 | drm_sched_entity_fini(&adev->uvd.inst[j].ring.sched, &adev->uvd.inst[j].entity); |
293 | &adev->uvd.inst->gpu_addr, | ||
294 | (void **)&adev->uvd.inst->cpu_addr); | ||
295 | 295 | ||
296 | amdgpu_ring_fini(&adev->uvd.inst->ring); | 296 | amdgpu_bo_free_kernel(&adev->uvd.inst[j].vcpu_bo, |
297 | &adev->uvd.inst[j].gpu_addr, | ||
298 | (void **)&adev->uvd.inst[j].cpu_addr); | ||
297 | 299 | ||
298 | for (i = 0; i < AMDGPU_MAX_UVD_ENC_RINGS; ++i) | 300 | amdgpu_ring_fini(&adev->uvd.inst[j].ring); |
299 | amdgpu_ring_fini(&adev->uvd.inst->ring_enc[i]); | ||
300 | 301 | ||
302 | for (i = 0; i < AMDGPU_MAX_UVD_ENC_RINGS; ++i) | ||
303 | amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]); | ||
304 | } | ||
301 | release_firmware(adev->uvd.fw); | 305 | release_firmware(adev->uvd.fw); |
302 | 306 | ||
303 | return 0; | 307 | return 0; |
@@ -307,32 +311,33 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) | |||
307 | { | 311 | { |
308 | unsigned size; | 312 | unsigned size; |
309 | void *ptr; | 313 | void *ptr; |
310 | int i; | 314 | int i, j; |
311 | 315 | ||
312 | if (adev->uvd.inst->vcpu_bo == NULL) | 316 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { |
313 | return 0; | 317 | if (adev->uvd.inst[j].vcpu_bo == NULL) |
318 | continue; | ||
314 | 319 | ||
315 | cancel_delayed_work_sync(&adev->uvd.inst->idle_work); | 320 | cancel_delayed_work_sync(&adev->uvd.inst[j].idle_work); |
316 | 321 | ||
317 | /* only valid for physical mode */ | 322 | /* only valid for physical mode */ |
318 | if (adev->asic_type < CHIP_POLARIS10) { | 323 | if (adev->asic_type < CHIP_POLARIS10) { |
319 | for (i = 0; i < adev->uvd.max_handles; ++i) | 324 | for (i = 0; i < adev->uvd.max_handles; ++i) |
320 | if (atomic_read(&adev->uvd.inst->handles[i])) | 325 | if (atomic_read(&adev->uvd.inst[j].handles[i])) |
321 | break; | 326 | break; |
322 | 327 | ||
323 | if (i == adev->uvd.max_handles) | 328 | if (i == adev->uvd.max_handles) |
324 | return 0; | 329 | continue; |
325 | } | 330 | } |
326 | |||
327 | size = amdgpu_bo_size(adev->uvd.inst->vcpu_bo); | ||
328 | ptr = adev->uvd.inst->cpu_addr; | ||
329 | 331 | ||
330 | adev->uvd.inst->saved_bo = kmalloc(size, GFP_KERNEL); | 332 | size = amdgpu_bo_size(adev->uvd.inst[j].vcpu_bo); |
331 | if (!adev->uvd.inst->saved_bo) | 333 | ptr = adev->uvd.inst[j].cpu_addr; |
332 | return -ENOMEM; | ||
333 | 334 | ||
334 | memcpy_fromio(adev->uvd.inst->saved_bo, ptr, size); | 335 | adev->uvd.inst[j].saved_bo = kmalloc(size, GFP_KERNEL); |
336 | if (!adev->uvd.inst[j].saved_bo) | ||
337 | return -ENOMEM; | ||
335 | 338 | ||
339 | memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size); | ||
340 | } | ||
336 | return 0; | 341 | return 0; |
337 | } | 342 | } |
338 | 343 | ||
@@ -340,59 +345,65 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) | |||
340 | { | 345 | { |
341 | unsigned size; | 346 | unsigned size; |
342 | void *ptr; | 347 | void *ptr; |
348 | int i; | ||
343 | 349 | ||
344 | if (adev->uvd.inst->vcpu_bo == NULL) | 350 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { |
345 | return -EINVAL; | 351 | if (adev->uvd.inst[i].vcpu_bo == NULL) |
352 | return -EINVAL; | ||
346 | 353 | ||
347 | size = amdgpu_bo_size(adev->uvd.inst->vcpu_bo); | 354 | size = amdgpu_bo_size(adev->uvd.inst[i].vcpu_bo); |
348 | ptr = adev->uvd.inst->cpu_addr; | 355 | ptr = adev->uvd.inst[i].cpu_addr; |
349 | 356 | ||
350 | if (adev->uvd.inst->saved_bo != NULL) { | 357 | if (adev->uvd.inst[i].saved_bo != NULL) { |
351 | memcpy_toio(ptr, adev->uvd.inst->saved_bo, size); | 358 | memcpy_toio(ptr, adev->uvd.inst[i].saved_bo, size); |
352 | kfree(adev->uvd.inst->saved_bo); | 359 | kfree(adev->uvd.inst[i].saved_bo); |
353 | adev->uvd.inst->saved_bo = NULL; | 360 | adev->uvd.inst[i].saved_bo = NULL; |
354 | } else { | 361 | } else { |
355 | const struct common_firmware_header *hdr; | 362 | const struct common_firmware_header *hdr; |
356 | unsigned offset; | 363 | unsigned offset; |
357 | 364 | ||
358 | hdr = (const struct common_firmware_header *)adev->uvd.fw->data; | 365 | hdr = (const struct common_firmware_header *)adev->uvd.fw->data; |
359 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { | 366 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { |
360 | offset = le32_to_cpu(hdr->ucode_array_offset_bytes); | 367 | offset = le32_to_cpu(hdr->ucode_array_offset_bytes); |
361 | memcpy_toio(adev->uvd.inst->cpu_addr, adev->uvd.fw->data + offset, | 368 | memcpy_toio(adev->uvd.inst[i].cpu_addr, adev->uvd.fw->data + offset, |
362 | le32_to_cpu(hdr->ucode_size_bytes)); | 369 | le32_to_cpu(hdr->ucode_size_bytes)); |
363 | size -= le32_to_cpu(hdr->ucode_size_bytes); | 370 | size -= le32_to_cpu(hdr->ucode_size_bytes); |
364 | ptr += le32_to_cpu(hdr->ucode_size_bytes); | 371 | ptr += le32_to_cpu(hdr->ucode_size_bytes); |
372 | } | ||
373 | memset_io(ptr, 0, size); | ||
374 | /* to restore uvd fence seq */ | ||
375 | amdgpu_fence_driver_force_completion(&adev->uvd.inst[i].ring); | ||
365 | } | 376 | } |
366 | memset_io(ptr, 0, size); | ||
367 | /* to restore uvd fence seq */ | ||
368 | amdgpu_fence_driver_force_completion(&adev->uvd.inst->ring); | ||
369 | } | 377 | } |
370 | |||
371 | return 0; | 378 | return 0; |
372 | } | 379 | } |
373 | 380 | ||
374 | void amdgpu_uvd_free_handles(struct amdgpu_device *adev, struct drm_file *filp) | 381 | void amdgpu_uvd_free_handles(struct amdgpu_device *adev, struct drm_file *filp) |
375 | { | 382 | { |
376 | struct amdgpu_ring *ring = &adev->uvd.inst->ring; | 383 | struct amdgpu_ring *ring; |
377 | int i, r; | 384 | int i, j, r; |
378 | 385 | ||
379 | for (i = 0; i < adev->uvd.max_handles; ++i) { | 386 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
380 | uint32_t handle = atomic_read(&adev->uvd.inst->handles[i]); | 387 | ring = &adev->uvd.inst[j].ring; |
381 | if (handle != 0 && adev->uvd.inst->filp[i] == filp) { | ||
382 | struct dma_fence *fence; | ||
383 | |||
384 | r = amdgpu_uvd_get_destroy_msg(ring, handle, | ||
385 | false, &fence); | ||
386 | if (r) { | ||
387 | DRM_ERROR("Error destroying UVD (%d)!\n", r); | ||
388 | continue; | ||
389 | } | ||
390 | 388 | ||
391 | dma_fence_wait(fence, false); | 389 | for (i = 0; i < adev->uvd.max_handles; ++i) { |
392 | dma_fence_put(fence); | 390 | uint32_t handle = atomic_read(&adev->uvd.inst[j].handles[i]); |
391 | if (handle != 0 && adev->uvd.inst[j].filp[i] == filp) { | ||
392 | struct dma_fence *fence; | ||
393 | |||
394 | r = amdgpu_uvd_get_destroy_msg(ring, handle, | ||
395 | false, &fence); | ||
396 | if (r) { | ||
397 | DRM_ERROR("Error destroying UVD(%d) %d!\n", j, r); | ||
398 | continue; | ||
399 | } | ||
393 | 400 | ||
394 | adev->uvd.inst->filp[i] = NULL; | 401 | dma_fence_wait(fence, false); |
395 | atomic_set(&adev->uvd.inst->handles[i], 0); | 402 | dma_fence_put(fence); |
403 | |||
404 | adev->uvd.inst[j].filp[i] = NULL; | ||
405 | atomic_set(&adev->uvd.inst[j].handles[i], 0); | ||
406 | } | ||
396 | } | 407 | } |
397 | } | 408 | } |
398 | } | 409 | } |
@@ -667,15 +678,16 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, | |||
667 | void *ptr; | 678 | void *ptr; |
668 | long r; | 679 | long r; |
669 | int i; | 680 | int i; |
681 | uint32_t ip_instance = ctx->parser->job->ring->me; | ||
670 | 682 | ||
671 | if (offset & 0x3F) { | 683 | if (offset & 0x3F) { |
672 | DRM_ERROR("UVD messages must be 64 byte aligned!\n"); | 684 | DRM_ERROR("UVD(%d) messages must be 64 byte aligned!\n", ip_instance); |
673 | return -EINVAL; | 685 | return -EINVAL; |
674 | } | 686 | } |
675 | 687 | ||
676 | r = amdgpu_bo_kmap(bo, &ptr); | 688 | r = amdgpu_bo_kmap(bo, &ptr); |
677 | if (r) { | 689 | if (r) { |
678 | DRM_ERROR("Failed mapping the UVD message (%ld)!\n", r); | 690 | DRM_ERROR("Failed mapping the UVD(%d) message (%ld)!\n", ip_instance, r); |
679 | return r; | 691 | return r; |
680 | } | 692 | } |
681 | 693 | ||
@@ -685,7 +697,7 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, | |||
685 | handle = msg[2]; | 697 | handle = msg[2]; |
686 | 698 | ||
687 | if (handle == 0) { | 699 | if (handle == 0) { |
688 | DRM_ERROR("Invalid UVD handle!\n"); | 700 | DRM_ERROR("Invalid UVD(%d) handle!\n", ip_instance); |
689 | return -EINVAL; | 701 | return -EINVAL; |
690 | } | 702 | } |
691 | 703 | ||
@@ -696,18 +708,18 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, | |||
696 | 708 | ||
697 | /* try to alloc a new handle */ | 709 | /* try to alloc a new handle */ |
698 | for (i = 0; i < adev->uvd.max_handles; ++i) { | 710 | for (i = 0; i < adev->uvd.max_handles; ++i) { |
699 | if (atomic_read(&adev->uvd.inst->handles[i]) == handle) { | 711 | if (atomic_read(&adev->uvd.inst[ip_instance].handles[i]) == handle) { |
700 | DRM_ERROR("Handle 0x%x already in use!\n", handle); | 712 | DRM_ERROR("(%d)Handle 0x%x already in use!\n", ip_instance, handle); |
701 | return -EINVAL; | 713 | return -EINVAL; |
702 | } | 714 | } |
703 | 715 | ||
704 | if (!atomic_cmpxchg(&adev->uvd.inst->handles[i], 0, handle)) { | 716 | if (!atomic_cmpxchg(&adev->uvd.inst[ip_instance].handles[i], 0, handle)) { |
705 | adev->uvd.inst->filp[i] = ctx->parser->filp; | 717 | adev->uvd.inst[ip_instance].filp[i] = ctx->parser->filp; |
706 | return 0; | 718 | return 0; |
707 | } | 719 | } |
708 | } | 720 | } |
709 | 721 | ||
710 | DRM_ERROR("No more free UVD handles!\n"); | 722 | DRM_ERROR("No more free UVD(%d) handles!\n", ip_instance); |
711 | return -ENOSPC; | 723 | return -ENOSPC; |
712 | 724 | ||
713 | case 1: | 725 | case 1: |
@@ -719,27 +731,27 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, | |||
719 | 731 | ||
720 | /* validate the handle */ | 732 | /* validate the handle */ |
721 | for (i = 0; i < adev->uvd.max_handles; ++i) { | 733 | for (i = 0; i < adev->uvd.max_handles; ++i) { |
722 | if (atomic_read(&adev->uvd.inst->handles[i]) == handle) { | 734 | if (atomic_read(&adev->uvd.inst[ip_instance].handles[i]) == handle) { |
723 | if (adev->uvd.inst->filp[i] != ctx->parser->filp) { | 735 | if (adev->uvd.inst[ip_instance].filp[i] != ctx->parser->filp) { |
724 | DRM_ERROR("UVD handle collision detected!\n"); | 736 | DRM_ERROR("UVD(%d) handle collision detected!\n", ip_instance); |
725 | return -EINVAL; | 737 | return -EINVAL; |
726 | } | 738 | } |
727 | return 0; | 739 | return 0; |
728 | } | 740 | } |
729 | } | 741 | } |
730 | 742 | ||
731 | DRM_ERROR("Invalid UVD handle 0x%x!\n", handle); | 743 | DRM_ERROR("Invalid UVD(%d) handle 0x%x!\n", ip_instance, handle); |
732 | return -ENOENT; | 744 | return -ENOENT; |
733 | 745 | ||
734 | case 2: | 746 | case 2: |
735 | /* it's a destroy msg, free the handle */ | 747 | /* it's a destroy msg, free the handle */ |
736 | for (i = 0; i < adev->uvd.max_handles; ++i) | 748 | for (i = 0; i < adev->uvd.max_handles; ++i) |
737 | atomic_cmpxchg(&adev->uvd.inst->handles[i], handle, 0); | 749 | atomic_cmpxchg(&adev->uvd.inst[ip_instance].handles[i], handle, 0); |
738 | amdgpu_bo_kunmap(bo); | 750 | amdgpu_bo_kunmap(bo); |
739 | return 0; | 751 | return 0; |
740 | 752 | ||
741 | default: | 753 | default: |
742 | DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); | 754 | DRM_ERROR("Illegal UVD(%d) message type (%d)!\n", ip_instance, msg_type); |
743 | return -EINVAL; | 755 | return -EINVAL; |
744 | } | 756 | } |
745 | BUG(); | 757 | BUG(); |
@@ -1043,7 +1055,7 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo, | |||
1043 | if (r) | 1055 | if (r) |
1044 | goto err_free; | 1056 | goto err_free; |
1045 | 1057 | ||
1046 | r = amdgpu_job_submit(job, ring, &adev->uvd.inst->entity, | 1058 | r = amdgpu_job_submit(job, ring, &adev->uvd.inst[ring->me].entity, |
1047 | AMDGPU_FENCE_OWNER_UNDEFINED, &f); | 1059 | AMDGPU_FENCE_OWNER_UNDEFINED, &f); |
1048 | if (r) | 1060 | if (r) |
1049 | goto err_free; | 1061 | goto err_free; |
@@ -1189,27 +1201,28 @@ int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
1189 | { | 1201 | { |
1190 | struct dma_fence *fence; | 1202 | struct dma_fence *fence; |
1191 | long r; | 1203 | long r; |
1204 | uint32_t ip_instance = ring->me; | ||
1192 | 1205 | ||
1193 | r = amdgpu_uvd_get_create_msg(ring, 1, NULL); | 1206 | r = amdgpu_uvd_get_create_msg(ring, 1, NULL); |
1194 | if (r) { | 1207 | if (r) { |
1195 | DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r); | 1208 | DRM_ERROR("amdgpu: (%d)failed to get create msg (%ld).\n", ip_instance, r); |
1196 | goto error; | 1209 | goto error; |
1197 | } | 1210 | } |
1198 | 1211 | ||
1199 | r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence); | 1212 | r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence); |
1200 | if (r) { | 1213 | if (r) { |
1201 | DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r); | 1214 | DRM_ERROR("amdgpu: (%d)failed to get destroy ib (%ld).\n", ip_instance, r); |
1202 | goto error; | 1215 | goto error; |
1203 | } | 1216 | } |
1204 | 1217 | ||
1205 | r = dma_fence_wait_timeout(fence, false, timeout); | 1218 | r = dma_fence_wait_timeout(fence, false, timeout); |
1206 | if (r == 0) { | 1219 | if (r == 0) { |
1207 | DRM_ERROR("amdgpu: IB test timed out.\n"); | 1220 | DRM_ERROR("amdgpu: (%d)IB test timed out.\n", ip_instance); |
1208 | r = -ETIMEDOUT; | 1221 | r = -ETIMEDOUT; |
1209 | } else if (r < 0) { | 1222 | } else if (r < 0) { |
1210 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | 1223 | DRM_ERROR("amdgpu: (%d)fence wait failed (%ld).\n", ip_instance, r); |
1211 | } else { | 1224 | } else { |
1212 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | 1225 | DRM_DEBUG("ib test on (%d)ring %d succeeded\n", ip_instance, ring->idx); |
1213 | r = 0; | 1226 | r = 0; |
1214 | } | 1227 | } |
1215 | 1228 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index 66d4bea5fb2c..08f3b6c84bea 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | |||
@@ -58,7 +58,7 @@ static uint64_t uvd_v7_0_ring_get_rptr(struct amdgpu_ring *ring) | |||
58 | { | 58 | { |
59 | struct amdgpu_device *adev = ring->adev; | 59 | struct amdgpu_device *adev = ring->adev; |
60 | 60 | ||
61 | return RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR); | 61 | return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_RPTR); |
62 | } | 62 | } |
63 | 63 | ||
64 | /** | 64 | /** |
@@ -72,10 +72,10 @@ static uint64_t uvd_v7_0_enc_ring_get_rptr(struct amdgpu_ring *ring) | |||
72 | { | 72 | { |
73 | struct amdgpu_device *adev = ring->adev; | 73 | struct amdgpu_device *adev = ring->adev; |
74 | 74 | ||
75 | if (ring == &adev->uvd.inst->ring_enc[0]) | 75 | if (ring == &adev->uvd.inst[ring->me].ring_enc[0]) |
76 | return RREG32_SOC15(UVD, 0, mmUVD_RB_RPTR); | 76 | return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR); |
77 | else | 77 | else |
78 | return RREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2); | 78 | return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR2); |
79 | } | 79 | } |
80 | 80 | ||
81 | /** | 81 | /** |
@@ -89,7 +89,7 @@ static uint64_t uvd_v7_0_ring_get_wptr(struct amdgpu_ring *ring) | |||
89 | { | 89 | { |
90 | struct amdgpu_device *adev = ring->adev; | 90 | struct amdgpu_device *adev = ring->adev; |
91 | 91 | ||
92 | return RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR); | 92 | return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR); |
93 | } | 93 | } |
94 | 94 | ||
95 | /** | 95 | /** |
@@ -106,10 +106,10 @@ static uint64_t uvd_v7_0_enc_ring_get_wptr(struct amdgpu_ring *ring) | |||
106 | if (ring->use_doorbell) | 106 | if (ring->use_doorbell) |
107 | return adev->wb.wb[ring->wptr_offs]; | 107 | return adev->wb.wb[ring->wptr_offs]; |
108 | 108 | ||
109 | if (ring == &adev->uvd.inst->ring_enc[0]) | 109 | if (ring == &adev->uvd.inst[ring->me].ring_enc[0]) |
110 | return RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR); | 110 | return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR); |
111 | else | 111 | else |
112 | return RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2); | 112 | return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2); |
113 | } | 113 | } |
114 | 114 | ||
115 | /** | 115 | /** |
@@ -123,7 +123,7 @@ static void uvd_v7_0_ring_set_wptr(struct amdgpu_ring *ring) | |||
123 | { | 123 | { |
124 | struct amdgpu_device *adev = ring->adev; | 124 | struct amdgpu_device *adev = ring->adev; |
125 | 125 | ||
126 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr)); | 126 | WREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr)); |
127 | } | 127 | } |
128 | 128 | ||
129 | /** | 129 | /** |
@@ -144,11 +144,11 @@ static void uvd_v7_0_enc_ring_set_wptr(struct amdgpu_ring *ring) | |||
144 | return; | 144 | return; |
145 | } | 145 | } |
146 | 146 | ||
147 | if (ring == &adev->uvd.inst->ring_enc[0]) | 147 | if (ring == &adev->uvd.inst[ring->me].ring_enc[0]) |
148 | WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, | 148 | WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR, |
149 | lower_32_bits(ring->wptr)); | 149 | lower_32_bits(ring->wptr)); |
150 | else | 150 | else |
151 | WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, | 151 | WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2, |
152 | lower_32_bits(ring->wptr)); | 152 | lower_32_bits(ring->wptr)); |
153 | } | 153 | } |
154 | 154 | ||
@@ -387,19 +387,21 @@ static int uvd_v7_0_sw_init(void *handle) | |||
387 | { | 387 | { |
388 | struct amdgpu_ring *ring; | 388 | struct amdgpu_ring *ring; |
389 | struct drm_sched_rq *rq; | 389 | struct drm_sched_rq *rq; |
390 | int i, r; | 390 | int i, j, r; |
391 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 391 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
392 | 392 | ||
393 | /* UVD TRAP */ | 393 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
394 | r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UVD, 124, &adev->uvd.inst->irq); | 394 | /* UVD TRAP */ |
395 | if (r) | 395 | r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UVD, 124, &adev->uvd.inst[j].irq); |
396 | return r; | ||
397 | |||
398 | /* UVD ENC TRAP */ | ||
399 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | ||
400 | r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UVD, i + 119, &adev->uvd.inst->irq); | ||
401 | if (r) | 396 | if (r) |
402 | return r; | 397 | return r; |
398 | |||
399 | /* UVD ENC TRAP */ | ||
400 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | ||
401 | r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UVD, i + 119, &adev->uvd.inst[j].irq); | ||
402 | if (r) | ||
403 | return r; | ||
404 | } | ||
403 | } | 405 | } |
404 | 406 | ||
405 | r = amdgpu_uvd_sw_init(adev); | 407 | r = amdgpu_uvd_sw_init(adev); |
@@ -416,43 +418,48 @@ static int uvd_v7_0_sw_init(void *handle) | |||
416 | DRM_INFO("PSP loading UVD firmware\n"); | 418 | DRM_INFO("PSP loading UVD firmware\n"); |
417 | } | 419 | } |
418 | 420 | ||
419 | ring = &adev->uvd.inst->ring_enc[0]; | 421 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
420 | rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; | 422 | ring = &adev->uvd.inst[j].ring_enc[0]; |
421 | r = drm_sched_entity_init(&ring->sched, &adev->uvd.inst->entity_enc, | 423 | rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; |
422 | rq, NULL); | 424 | r = drm_sched_entity_init(&ring->sched, &adev->uvd.inst[j].entity_enc, |
423 | if (r) { | 425 | rq, NULL); |
424 | DRM_ERROR("Failed setting up UVD ENC run queue.\n"); | 426 | if (r) { |
425 | return r; | 427 | DRM_ERROR("(%d)Failed setting up UVD ENC run queue.\n", j); |
428 | return r; | ||
429 | } | ||
426 | } | 430 | } |
427 | 431 | ||
428 | r = amdgpu_uvd_resume(adev); | 432 | r = amdgpu_uvd_resume(adev); |
429 | if (r) | 433 | if (r) |
430 | return r; | 434 | return r; |
431 | if (!amdgpu_sriov_vf(adev)) { | ||
432 | ring = &adev->uvd.inst->ring; | ||
433 | sprintf(ring->name, "uvd"); | ||
434 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0); | ||
435 | if (r) | ||
436 | return r; | ||
437 | } | ||
438 | 435 | ||
439 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | 436 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
440 | ring = &adev->uvd.inst->ring_enc[i]; | 437 | if (!amdgpu_sriov_vf(adev)) { |
441 | sprintf(ring->name, "uvd_enc%d", i); | 438 | ring = &adev->uvd.inst[j].ring; |
442 | if (amdgpu_sriov_vf(adev)) { | 439 | sprintf(ring->name, "uvd<%d>", j); |
443 | ring->use_doorbell = true; | 440 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0); |
444 | 441 | if (r) | |
445 | /* currently only use the first enconding ring for | 442 | return r; |
446 | * sriov, so set unused location for other unused rings. | 443 | } |
447 | */ | 444 | |
448 | if (i == 0) | 445 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { |
449 | ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING0_1 * 2; | 446 | ring = &adev->uvd.inst[j].ring_enc[i]; |
450 | else | 447 | sprintf(ring->name, "uvd_enc%d<%d>", i, j); |
451 | ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING2_3 * 2 + 1; | 448 | if (amdgpu_sriov_vf(adev)) { |
449 | ring->use_doorbell = true; | ||
450 | |||
451 | /* currently only use the first enconding ring for | ||
452 | * sriov, so set unused location for other unused rings. | ||
453 | */ | ||
454 | if (i == 0) | ||
455 | ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING0_1 * 2; | ||
456 | else | ||
457 | ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING2_3 * 2 + 1; | ||
458 | } | ||
459 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0); | ||
460 | if (r) | ||
461 | return r; | ||
452 | } | 462 | } |
453 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0); | ||
454 | if (r) | ||
455 | return r; | ||
456 | } | 463 | } |
457 | 464 | ||
458 | r = amdgpu_virt_alloc_mm_table(adev); | 465 | r = amdgpu_virt_alloc_mm_table(adev); |
@@ -464,7 +471,7 @@ static int uvd_v7_0_sw_init(void *handle) | |||
464 | 471 | ||
465 | static int uvd_v7_0_sw_fini(void *handle) | 472 | static int uvd_v7_0_sw_fini(void *handle) |
466 | { | 473 | { |
467 | int i, r; | 474 | int i, j, r; |
468 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 475 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
469 | 476 | ||
470 | amdgpu_virt_free_mm_table(adev); | 477 | amdgpu_virt_free_mm_table(adev); |
@@ -473,11 +480,12 @@ static int uvd_v7_0_sw_fini(void *handle) | |||
473 | if (r) | 480 | if (r) |
474 | return r; | 481 | return r; |
475 | 482 | ||
476 | drm_sched_entity_fini(&adev->uvd.inst->ring_enc[0].sched, &adev->uvd.inst->entity_enc); | 483 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { |
477 | 484 | drm_sched_entity_fini(&adev->uvd.inst[j].ring_enc[0].sched, &adev->uvd.inst[j].entity_enc); | |
478 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) | ||
479 | amdgpu_ring_fini(&adev->uvd.inst->ring_enc[i]); | ||
480 | 485 | ||
486 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) | ||
487 | amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]); | ||
488 | } | ||
481 | return amdgpu_uvd_sw_fini(adev); | 489 | return amdgpu_uvd_sw_fini(adev); |
482 | } | 490 | } |
483 | 491 | ||
@@ -491,9 +499,9 @@ static int uvd_v7_0_sw_fini(void *handle) | |||
491 | static int uvd_v7_0_hw_init(void *handle) | 499 | static int uvd_v7_0_hw_init(void *handle) |
492 | { | 500 | { |
493 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 501 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
494 | struct amdgpu_ring *ring = &adev->uvd.inst->ring; | 502 | struct amdgpu_ring *ring; |
495 | uint32_t tmp; | 503 | uint32_t tmp; |
496 | int i, r; | 504 | int i, j, r; |
497 | 505 | ||
498 | if (amdgpu_sriov_vf(adev)) | 506 | if (amdgpu_sriov_vf(adev)) |
499 | r = uvd_v7_0_sriov_start(adev); | 507 | r = uvd_v7_0_sriov_start(adev); |
@@ -502,57 +510,60 @@ static int uvd_v7_0_hw_init(void *handle) | |||
502 | if (r) | 510 | if (r) |
503 | goto done; | 511 | goto done; |
504 | 512 | ||
505 | if (!amdgpu_sriov_vf(adev)) { | 513 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { |
506 | ring->ready = true; | 514 | ring = &adev->uvd.inst[j].ring; |
507 | r = amdgpu_ring_test_ring(ring); | 515 | |
508 | if (r) { | 516 | if (!amdgpu_sriov_vf(adev)) { |
509 | ring->ready = false; | 517 | ring->ready = true; |
510 | goto done; | 518 | r = amdgpu_ring_test_ring(ring); |
519 | if (r) { | ||
520 | ring->ready = false; | ||
521 | goto done; | ||
522 | } | ||
523 | |||
524 | r = amdgpu_ring_alloc(ring, 10); | ||
525 | if (r) { | ||
526 | DRM_ERROR("amdgpu: (%d)ring failed to lock UVD ring (%d).\n", j, r); | ||
527 | goto done; | ||
528 | } | ||
529 | |||
530 | tmp = PACKET0(SOC15_REG_OFFSET(UVD, j, | ||
531 | mmUVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL), 0); | ||
532 | amdgpu_ring_write(ring, tmp); | ||
533 | amdgpu_ring_write(ring, 0xFFFFF); | ||
534 | |||
535 | tmp = PACKET0(SOC15_REG_OFFSET(UVD, j, | ||
536 | mmUVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL), 0); | ||
537 | amdgpu_ring_write(ring, tmp); | ||
538 | amdgpu_ring_write(ring, 0xFFFFF); | ||
539 | |||
540 | tmp = PACKET0(SOC15_REG_OFFSET(UVD, j, | ||
541 | mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL), 0); | ||
542 | amdgpu_ring_write(ring, tmp); | ||
543 | amdgpu_ring_write(ring, 0xFFFFF); | ||
544 | |||
545 | /* Clear timeout status bits */ | ||
546 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, j, | ||
547 | mmUVD_SEMA_TIMEOUT_STATUS), 0)); | ||
548 | amdgpu_ring_write(ring, 0x8); | ||
549 | |||
550 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, j, | ||
551 | mmUVD_SEMA_CNTL), 0)); | ||
552 | amdgpu_ring_write(ring, 3); | ||
553 | |||
554 | amdgpu_ring_commit(ring); | ||
511 | } | 555 | } |
512 | 556 | ||
513 | r = amdgpu_ring_alloc(ring, 10); | 557 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { |
514 | if (r) { | 558 | ring = &adev->uvd.inst[j].ring_enc[i]; |
515 | DRM_ERROR("amdgpu: ring failed to lock UVD ring (%d).\n", r); | 559 | ring->ready = true; |
516 | goto done; | 560 | r = amdgpu_ring_test_ring(ring); |
561 | if (r) { | ||
562 | ring->ready = false; | ||
563 | goto done; | ||
564 | } | ||
517 | } | 565 | } |
518 | |||
519 | tmp = PACKET0(SOC15_REG_OFFSET(UVD, 0, | ||
520 | mmUVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL), 0); | ||
521 | amdgpu_ring_write(ring, tmp); | ||
522 | amdgpu_ring_write(ring, 0xFFFFF); | ||
523 | |||
524 | tmp = PACKET0(SOC15_REG_OFFSET(UVD, 0, | ||
525 | mmUVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL), 0); | ||
526 | amdgpu_ring_write(ring, tmp); | ||
527 | amdgpu_ring_write(ring, 0xFFFFF); | ||
528 | |||
529 | tmp = PACKET0(SOC15_REG_OFFSET(UVD, 0, | ||
530 | mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL), 0); | ||
531 | amdgpu_ring_write(ring, tmp); | ||
532 | amdgpu_ring_write(ring, 0xFFFFF); | ||
533 | |||
534 | /* Clear timeout status bits */ | ||
535 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0, | ||
536 | mmUVD_SEMA_TIMEOUT_STATUS), 0)); | ||
537 | amdgpu_ring_write(ring, 0x8); | ||
538 | |||
539 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0, | ||
540 | mmUVD_SEMA_CNTL), 0)); | ||
541 | amdgpu_ring_write(ring, 3); | ||
542 | |||
543 | amdgpu_ring_commit(ring); | ||
544 | } | 566 | } |
545 | |||
546 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | ||
547 | ring = &adev->uvd.inst->ring_enc[i]; | ||
548 | ring->ready = true; | ||
549 | r = amdgpu_ring_test_ring(ring); | ||
550 | if (r) { | ||
551 | ring->ready = false; | ||
552 | goto done; | ||
553 | } | ||
554 | } | ||
555 | |||
556 | done: | 567 | done: |
557 | if (!r) | 568 | if (!r) |
558 | DRM_INFO("UVD and UVD ENC initialized successfully.\n"); | 569 | DRM_INFO("UVD and UVD ENC initialized successfully.\n"); |
@@ -570,7 +581,7 @@ done: | |||
570 | static int uvd_v7_0_hw_fini(void *handle) | 581 | static int uvd_v7_0_hw_fini(void *handle) |
571 | { | 582 | { |
572 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 583 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
573 | struct amdgpu_ring *ring = &adev->uvd.inst->ring; | 584 | int i; |
574 | 585 | ||
575 | if (!amdgpu_sriov_vf(adev)) | 586 | if (!amdgpu_sriov_vf(adev)) |
576 | uvd_v7_0_stop(adev); | 587 | uvd_v7_0_stop(adev); |
@@ -579,7 +590,8 @@ static int uvd_v7_0_hw_fini(void *handle) | |||
579 | DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); | 590 | DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); |
580 | } | 591 | } |
581 | 592 | ||
582 | ring->ready = false; | 593 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) |
594 | adev->uvd.inst[i].ring.ready = false; | ||
583 | 595 | ||
584 | return 0; | 596 | return 0; |
585 | } | 597 | } |
@@ -619,48 +631,51 @@ static void uvd_v7_0_mc_resume(struct amdgpu_device *adev) | |||
619 | { | 631 | { |
620 | uint32_t size = AMDGPU_UVD_FIRMWARE_SIZE(adev); | 632 | uint32_t size = AMDGPU_UVD_FIRMWARE_SIZE(adev); |
621 | uint32_t offset; | 633 | uint32_t offset; |
634 | int i; | ||
622 | 635 | ||
623 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { | 636 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
624 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, | 637 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { |
625 | lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); | 638 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, |
626 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, | 639 | lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); |
627 | upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); | 640 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, |
628 | offset = 0; | 641 | upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); |
629 | } else { | 642 | offset = 0; |
630 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, | 643 | } else { |
631 | lower_32_bits(adev->uvd.inst->gpu_addr)); | 644 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, |
632 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, | 645 | lower_32_bits(adev->uvd.inst[i].gpu_addr)); |
633 | upper_32_bits(adev->uvd.inst->gpu_addr)); | 646 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, |
634 | offset = size; | 647 | upper_32_bits(adev->uvd.inst[i].gpu_addr)); |
635 | } | 648 | offset = size; |
649 | } | ||
636 | 650 | ||
637 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0, | 651 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET0, |
638 | AMDGPU_UVD_FIRMWARE_OFFSET >> 3); | 652 | AMDGPU_UVD_FIRMWARE_OFFSET >> 3); |
639 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE0, size); | 653 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE0, size); |
640 | 654 | ||
641 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW, | 655 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW, |
642 | lower_32_bits(adev->uvd.inst->gpu_addr + offset)); | 656 | lower_32_bits(adev->uvd.inst[i].gpu_addr + offset)); |
643 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH, | 657 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH, |
644 | upper_32_bits(adev->uvd.inst->gpu_addr + offset)); | 658 | upper_32_bits(adev->uvd.inst[i].gpu_addr + offset)); |
645 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1, (1 << 21)); | 659 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET1, (1 << 21)); |
646 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_UVD_HEAP_SIZE); | 660 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_UVD_HEAP_SIZE); |
647 | 661 | ||
648 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW, | 662 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW, |
649 | lower_32_bits(adev->uvd.inst->gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); | 663 | lower_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); |
650 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH, | 664 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH, |
651 | upper_32_bits(adev->uvd.inst->gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); | 665 | upper_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); |
652 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2, (2 << 21)); | 666 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET2, (2 << 21)); |
653 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, | 667 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE2, |
654 | AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40)); | 668 | AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40)); |
655 | 669 | ||
656 | WREG32_SOC15(UVD, 0, mmUVD_UDEC_ADDR_CONFIG, | 670 | WREG32_SOC15(UVD, i, mmUVD_UDEC_ADDR_CONFIG, |
657 | adev->gfx.config.gb_addr_config); | 671 | adev->gfx.config.gb_addr_config); |
658 | WREG32_SOC15(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG, | 672 | WREG32_SOC15(UVD, i, mmUVD_UDEC_DB_ADDR_CONFIG, |
659 | adev->gfx.config.gb_addr_config); | 673 | adev->gfx.config.gb_addr_config); |
660 | WREG32_SOC15(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG, | 674 | WREG32_SOC15(UVD, i, mmUVD_UDEC_DBW_ADDR_CONFIG, |
661 | adev->gfx.config.gb_addr_config); | 675 | adev->gfx.config.gb_addr_config); |
662 | 676 | ||
663 | WREG32_SOC15(UVD, 0, mmUVD_GP_SCRATCH4, adev->uvd.max_handles); | 677 | WREG32_SOC15(UVD, i, mmUVD_GP_SCRATCH4, adev->uvd.max_handles); |
678 | } | ||
664 | } | 679 | } |
665 | 680 | ||
666 | static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev, | 681 | static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev, |
@@ -670,6 +685,7 @@ static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev, | |||
670 | uint64_t addr = table->gpu_addr; | 685 | uint64_t addr = table->gpu_addr; |
671 | struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)table->cpu_addr; | 686 | struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)table->cpu_addr; |
672 | uint32_t size; | 687 | uint32_t size; |
688 | int i; | ||
673 | 689 | ||
674 | size = header->header_size + header->vce_table_size + header->uvd_table_size; | 690 | size = header->header_size + header->vce_table_size + header->uvd_table_size; |
675 | 691 | ||
@@ -689,11 +705,12 @@ static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev, | |||
689 | /* 4, set resp to zero */ | 705 | /* 4, set resp to zero */ |
690 | WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP, 0); | 706 | WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP, 0); |
691 | 707 | ||
692 | WDOORBELL32(adev->uvd.inst->ring_enc[0].doorbell_index, 0); | 708 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
693 | adev->wb.wb[adev->uvd.inst->ring_enc[0].wptr_offs] = 0; | 709 | WDOORBELL32(adev->uvd.inst[i].ring_enc[0].doorbell_index, 0); |
694 | adev->uvd.inst->ring_enc[0].wptr = 0; | 710 | adev->wb.wb[adev->uvd.inst[i].ring_enc[0].wptr_offs] = 0; |
695 | adev->uvd.inst->ring_enc[0].wptr_old = 0; | 711 | adev->uvd.inst[i].ring_enc[0].wptr = 0; |
696 | 712 | adev->uvd.inst[i].ring_enc[0].wptr_old = 0; | |
713 | } | ||
697 | /* 5, kick off the initialization and wait until VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero */ | 714 | /* 5, kick off the initialization and wait until VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero */ |
698 | WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_HOST, 0x10000001); | 715 | WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_HOST, 0x10000001); |
699 | 716 | ||
@@ -726,6 +743,7 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev) | |||
726 | struct mmsch_v1_0_cmd_end end = { {0} }; | 743 | struct mmsch_v1_0_cmd_end end = { {0} }; |
727 | uint32_t *init_table = adev->virt.mm_table.cpu_addr; | 744 | uint32_t *init_table = adev->virt.mm_table.cpu_addr; |
728 | struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)init_table; | 745 | struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)init_table; |
746 | uint8_t i = 0; | ||
729 | 747 | ||
730 | direct_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_WRITE; | 748 | direct_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_WRITE; |
731 | direct_rd_mod_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE; | 749 | direct_rd_mod_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE; |
@@ -743,120 +761,121 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev) | |||
743 | 761 | ||
744 | init_table += header->uvd_table_offset; | 762 | init_table += header->uvd_table_offset; |
745 | 763 | ||
746 | ring = &adev->uvd.inst->ring; | 764 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
747 | ring->wptr = 0; | 765 | ring = &adev->uvd.inst[i].ring; |
748 | size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4); | 766 | ring->wptr = 0; |
749 | 767 | size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4); | |
750 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), | 768 | |
751 | 0xFFFFFFFF, 0x00000004); | 769 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS), |
752 | /* mc resume*/ | 770 | 0xFFFFFFFF, 0x00000004); |
753 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { | 771 | /* mc resume*/ |
754 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), | 772 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { |
755 | lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); | 773 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), |
756 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), | 774 | lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); |
757 | upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); | 775 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), |
758 | offset = 0; | 776 | upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); |
759 | } else { | 777 | offset = 0; |
760 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), | 778 | } else { |
761 | lower_32_bits(adev->uvd.inst->gpu_addr)); | 779 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), |
762 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), | 780 | lower_32_bits(adev->uvd.inst[i].gpu_addr)); |
763 | upper_32_bits(adev->uvd.inst->gpu_addr)); | 781 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), |
764 | offset = size; | 782 | upper_32_bits(adev->uvd.inst[i].gpu_addr)); |
783 | offset = size; | ||
784 | } | ||
785 | |||
786 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_OFFSET0), | ||
787 | AMDGPU_UVD_FIRMWARE_OFFSET >> 3); | ||
788 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE0), size); | ||
789 | |||
790 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), | ||
791 | lower_32_bits(adev->uvd.inst[i].gpu_addr + offset)); | ||
792 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), | ||
793 | upper_32_bits(adev->uvd.inst[i].gpu_addr + offset)); | ||
794 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_OFFSET1), (1 << 21)); | ||
795 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_UVD_HEAP_SIZE); | ||
796 | |||
797 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), | ||
798 | lower_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); | ||
799 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), | ||
800 | upper_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); | ||
801 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_OFFSET2), (2 << 21)); | ||
802 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE2), | ||
803 | AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40)); | ||
804 | |||
805 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_GP_SCRATCH4), adev->uvd.max_handles); | ||
806 | /* mc resume end*/ | ||
807 | |||
808 | /* disable clock gating */ | ||
809 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_CGC_CTRL), | ||
810 | ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK, 0); | ||
811 | |||
812 | /* disable interupt */ | ||
813 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN), | ||
814 | ~UVD_MASTINT_EN__VCPU_EN_MASK, 0); | ||
815 | |||
816 | /* stall UMC and register bus before resetting VCPU */ | ||
817 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2), | ||
818 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, | ||
819 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
820 | |||
821 | /* put LMI, VCPU, RBC etc... into reset */ | ||
822 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_SOFT_RESET), | ||
823 | (uint32_t)(UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | | ||
824 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | | ||
825 | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | | ||
826 | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | | ||
827 | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | | ||
828 | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | | ||
829 | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | | ||
830 | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK)); | ||
831 | |||
832 | /* initialize UVD memory controller */ | ||
833 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL), | ||
834 | (uint32_t)((0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | | ||
835 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | | ||
836 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | | ||
837 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | | ||
838 | UVD_LMI_CTRL__REQ_MODE_MASK | | ||
839 | 0x00100000L)); | ||
840 | |||
841 | /* take all subblocks out of reset, except VCPU */ | ||
842 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_SOFT_RESET), | ||
843 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
844 | |||
845 | /* enable VCPU clock */ | ||
846 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL), | ||
847 | UVD_VCPU_CNTL__CLK_EN_MASK); | ||
848 | |||
849 | /* enable master interrupt */ | ||
850 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN), | ||
851 | ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK), | ||
852 | (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK)); | ||
853 | |||
854 | /* clear the bit 4 of UVD_STATUS */ | ||
855 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS), | ||
856 | ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT), 0); | ||
857 | |||
858 | /* force RBC into idle state */ | ||
859 | size = order_base_2(ring->ring_size); | ||
860 | tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, size); | ||
861 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); | ||
862 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RBC_RB_CNTL), tmp); | ||
863 | |||
864 | ring = &adev->uvd.inst[i].ring_enc[0]; | ||
865 | ring->wptr = 0; | ||
866 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_BASE_LO), ring->gpu_addr); | ||
867 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_BASE_HI), upper_32_bits(ring->gpu_addr)); | ||
868 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_SIZE), ring->ring_size / 4); | ||
869 | |||
870 | /* boot up the VCPU */ | ||
871 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_SOFT_RESET), 0); | ||
872 | |||
873 | /* enable UMC */ | ||
874 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2), | ||
875 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, 0); | ||
876 | |||
877 | MMSCH_V1_0_INSERT_DIRECT_POLL(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS), 0x02, 0x02); | ||
765 | } | 878 | } |
766 | |||
767 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0), | ||
768 | AMDGPU_UVD_FIRMWARE_OFFSET >> 3); | ||
769 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE0), size); | ||
770 | |||
771 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), | ||
772 | lower_32_bits(adev->uvd.inst->gpu_addr + offset)); | ||
773 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), | ||
774 | upper_32_bits(adev->uvd.inst->gpu_addr + offset)); | ||
775 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1), (1 << 21)); | ||
776 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_UVD_HEAP_SIZE); | ||
777 | |||
778 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), | ||
779 | lower_32_bits(adev->uvd.inst->gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); | ||
780 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), | ||
781 | upper_32_bits(adev->uvd.inst->gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); | ||
782 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2), (2 << 21)); | ||
783 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE2), | ||
784 | AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40)); | ||
785 | |||
786 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_GP_SCRATCH4), adev->uvd.max_handles); | ||
787 | /* mc resume end*/ | ||
788 | |||
789 | /* disable clock gating */ | ||
790 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_CGC_CTRL), | ||
791 | ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK, 0); | ||
792 | |||
793 | /* disable interupt */ | ||
794 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), | ||
795 | ~UVD_MASTINT_EN__VCPU_EN_MASK, 0); | ||
796 | |||
797 | /* stall UMC and register bus before resetting VCPU */ | ||
798 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), | ||
799 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, | ||
800 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
801 | |||
802 | /* put LMI, VCPU, RBC etc... into reset */ | ||
803 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), | ||
804 | (uint32_t)(UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | | ||
805 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | | ||
806 | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | | ||
807 | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | | ||
808 | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | | ||
809 | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | | ||
810 | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | | ||
811 | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK)); | ||
812 | |||
813 | /* initialize UVD memory controller */ | ||
814 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL), | ||
815 | (uint32_t)((0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | | ||
816 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | | ||
817 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | | ||
818 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | | ||
819 | UVD_LMI_CTRL__REQ_MODE_MASK | | ||
820 | 0x00100000L)); | ||
821 | |||
822 | /* take all subblocks out of reset, except VCPU */ | ||
823 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), | ||
824 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
825 | |||
826 | /* enable VCPU clock */ | ||
827 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CNTL), | ||
828 | UVD_VCPU_CNTL__CLK_EN_MASK); | ||
829 | |||
830 | /* enable master interrupt */ | ||
831 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), | ||
832 | ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK), | ||
833 | (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK)); | ||
834 | |||
835 | /* clear the bit 4 of UVD_STATUS */ | ||
836 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), | ||
837 | ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT), 0); | ||
838 | |||
839 | /* force RBC into idle state */ | ||
840 | size = order_base_2(ring->ring_size); | ||
841 | tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, size); | ||
842 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); | ||
843 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), tmp); | ||
844 | |||
845 | ring = &adev->uvd.inst->ring_enc[0]; | ||
846 | ring->wptr = 0; | ||
847 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_LO), ring->gpu_addr); | ||
848 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_HI), upper_32_bits(ring->gpu_addr)); | ||
849 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_SIZE), ring->ring_size / 4); | ||
850 | |||
851 | /* boot up the VCPU */ | ||
852 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0); | ||
853 | |||
854 | /* enable UMC */ | ||
855 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), | ||
856 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, 0); | ||
857 | |||
858 | MMSCH_V1_0_INSERT_DIRECT_POLL(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0x02, 0x02); | ||
859 | |||
860 | /* add end packet */ | 879 | /* add end packet */ |
861 | memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end)); | 880 | memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end)); |
862 | table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4; | 881 | table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4; |
@@ -875,15 +894,17 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev) | |||
875 | */ | 894 | */ |
876 | static int uvd_v7_0_start(struct amdgpu_device *adev) | 895 | static int uvd_v7_0_start(struct amdgpu_device *adev) |
877 | { | 896 | { |
878 | struct amdgpu_ring *ring = &adev->uvd.inst->ring; | 897 | struct amdgpu_ring *ring; |
879 | uint32_t rb_bufsz, tmp; | 898 | uint32_t rb_bufsz, tmp; |
880 | uint32_t lmi_swap_cntl; | 899 | uint32_t lmi_swap_cntl; |
881 | uint32_t mp_swap_cntl; | 900 | uint32_t mp_swap_cntl; |
882 | int i, j, r; | 901 | int i, j, k, r; |
883 | 902 | ||
884 | /* disable DPG */ | 903 | for (k = 0; k < adev->uvd.num_uvd_inst; ++k) { |
885 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), 0, | 904 | /* disable DPG */ |
886 | ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); | 905 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_POWER_STATUS), 0, |
906 | ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); | ||
907 | } | ||
887 | 908 | ||
888 | /* disable byte swapping */ | 909 | /* disable byte swapping */ |
889 | lmi_swap_cntl = 0; | 910 | lmi_swap_cntl = 0; |
@@ -891,157 +912,159 @@ static int uvd_v7_0_start(struct amdgpu_device *adev) | |||
891 | 912 | ||
892 | uvd_v7_0_mc_resume(adev); | 913 | uvd_v7_0_mc_resume(adev); |
893 | 914 | ||
894 | /* disable clock gating */ | 915 | for (k = 0; k < adev->uvd.num_uvd_inst; ++k) { |
895 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_CGC_CTRL), 0, | 916 | ring = &adev->uvd.inst[k].ring; |
896 | ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK); | 917 | /* disable clock gating */ |
897 | 918 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_CGC_CTRL), 0, | |
898 | /* disable interupt */ | 919 | ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK); |
899 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0, | ||
900 | ~UVD_MASTINT_EN__VCPU_EN_MASK); | ||
901 | |||
902 | /* stall UMC and register bus before resetting VCPU */ | ||
903 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), | ||
904 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, | ||
905 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
906 | mdelay(1); | ||
907 | |||
908 | /* put LMI, VCPU, RBC etc... into reset */ | ||
909 | WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, | ||
910 | UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | | ||
911 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | | ||
912 | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | | ||
913 | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | | ||
914 | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | | ||
915 | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | | ||
916 | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | | ||
917 | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK); | ||
918 | mdelay(5); | ||
919 | 920 | ||
920 | /* initialize UVD memory controller */ | 921 | /* disable interupt */ |
921 | WREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL, | 922 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_MASTINT_EN), 0, |
922 | (0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | | 923 | ~UVD_MASTINT_EN__VCPU_EN_MASK); |
923 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | | 924 | |
924 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | | 925 | /* stall UMC and register bus before resetting VCPU */ |
925 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | | 926 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_LMI_CTRL2), |
926 | UVD_LMI_CTRL__REQ_MODE_MASK | | 927 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, |
927 | 0x00100000L); | 928 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); |
929 | mdelay(1); | ||
930 | |||
931 | /* put LMI, VCPU, RBC etc... into reset */ | ||
932 | WREG32_SOC15(UVD, k, mmUVD_SOFT_RESET, | ||
933 | UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | | ||
934 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | | ||
935 | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | | ||
936 | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | | ||
937 | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | | ||
938 | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | | ||
939 | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | | ||
940 | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK); | ||
941 | mdelay(5); | ||
942 | |||
943 | /* initialize UVD memory controller */ | ||
944 | WREG32_SOC15(UVD, k, mmUVD_LMI_CTRL, | ||
945 | (0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | | ||
946 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | | ||
947 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | | ||
948 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | | ||
949 | UVD_LMI_CTRL__REQ_MODE_MASK | | ||
950 | 0x00100000L); | ||
928 | 951 | ||
929 | #ifdef __BIG_ENDIAN | 952 | #ifdef __BIG_ENDIAN |
930 | /* swap (8 in 32) RB and IB */ | 953 | /* swap (8 in 32) RB and IB */ |
931 | lmi_swap_cntl = 0xa; | 954 | lmi_swap_cntl = 0xa; |
932 | mp_swap_cntl = 0; | 955 | mp_swap_cntl = 0; |
933 | #endif | 956 | #endif |
934 | WREG32_SOC15(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl); | 957 | WREG32_SOC15(UVD, k, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl); |
935 | WREG32_SOC15(UVD, 0, mmUVD_MP_SWAP_CNTL, mp_swap_cntl); | 958 | WREG32_SOC15(UVD, k, mmUVD_MP_SWAP_CNTL, mp_swap_cntl); |
936 | |||
937 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA0, 0x40c2040); | ||
938 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA1, 0x0); | ||
939 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB0, 0x40c2040); | ||
940 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB1, 0x0); | ||
941 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_ALU, 0); | ||
942 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUX, 0x88); | ||
943 | |||
944 | /* take all subblocks out of reset, except VCPU */ | ||
945 | WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, | ||
946 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
947 | mdelay(5); | ||
948 | 959 | ||
949 | /* enable VCPU clock */ | 960 | WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXA0, 0x40c2040); |
950 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, | 961 | WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXA1, 0x0); |
951 | UVD_VCPU_CNTL__CLK_EN_MASK); | 962 | WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXB0, 0x40c2040); |
963 | WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXB1, 0x0); | ||
964 | WREG32_SOC15(UVD, k, mmUVD_MPC_SET_ALU, 0); | ||
965 | WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUX, 0x88); | ||
952 | 966 | ||
953 | /* enable UMC */ | 967 | /* take all subblocks out of reset, except VCPU */ |
954 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0, | 968 | WREG32_SOC15(UVD, k, mmUVD_SOFT_RESET, |
955 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | 969 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); |
970 | mdelay(5); | ||
956 | 971 | ||
957 | /* boot up the VCPU */ | 972 | /* enable VCPU clock */ |
958 | WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, 0); | 973 | WREG32_SOC15(UVD, k, mmUVD_VCPU_CNTL, |
959 | mdelay(10); | 974 | UVD_VCPU_CNTL__CLK_EN_MASK); |
960 | 975 | ||
961 | for (i = 0; i < 10; ++i) { | 976 | /* enable UMC */ |
962 | uint32_t status; | 977 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_LMI_CTRL2), 0, |
978 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
963 | 979 | ||
964 | for (j = 0; j < 100; ++j) { | 980 | /* boot up the VCPU */ |
965 | status = RREG32_SOC15(UVD, 0, mmUVD_STATUS); | 981 | WREG32_SOC15(UVD, k, mmUVD_SOFT_RESET, 0); |
982 | mdelay(10); | ||
983 | |||
984 | for (i = 0; i < 10; ++i) { | ||
985 | uint32_t status; | ||
986 | |||
987 | for (j = 0; j < 100; ++j) { | ||
988 | status = RREG32_SOC15(UVD, k, mmUVD_STATUS); | ||
989 | if (status & 2) | ||
990 | break; | ||
991 | mdelay(10); | ||
992 | } | ||
993 | r = 0; | ||
966 | if (status & 2) | 994 | if (status & 2) |
967 | break; | 995 | break; |
996 | |||
997 | DRM_ERROR("UVD(%d) not responding, trying to reset the VCPU!!!\n", k); | ||
998 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_SOFT_RESET), | ||
999 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK, | ||
1000 | ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
1001 | mdelay(10); | ||
1002 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_SOFT_RESET), 0, | ||
1003 | ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
968 | mdelay(10); | 1004 | mdelay(10); |
1005 | r = -1; | ||
969 | } | 1006 | } |
970 | r = 0; | ||
971 | if (status & 2) | ||
972 | break; | ||
973 | 1007 | ||
974 | DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n"); | 1008 | if (r) { |
975 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), | 1009 | DRM_ERROR("UVD(%d) not responding, giving up!!!\n", k); |
976 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK, | 1010 | return r; |
977 | ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | 1011 | } |
978 | mdelay(10); | 1012 | /* enable master interrupt */ |
979 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0, | 1013 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_MASTINT_EN), |
980 | ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | 1014 | (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK), |
981 | mdelay(10); | 1015 | ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK)); |
982 | r = -1; | ||
983 | } | ||
984 | |||
985 | if (r) { | ||
986 | DRM_ERROR("UVD not responding, giving up!!!\n"); | ||
987 | return r; | ||
988 | } | ||
989 | /* enable master interrupt */ | ||
990 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), | ||
991 | (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK), | ||
992 | ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK)); | ||
993 | |||
994 | /* clear the bit 4 of UVD_STATUS */ | ||
995 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0, | ||
996 | ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); | ||
997 | |||
998 | /* force RBC into idle state */ | ||
999 | rb_bufsz = order_base_2(ring->ring_size); | ||
1000 | tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz); | ||
1001 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); | ||
1002 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); | ||
1003 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0); | ||
1004 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); | ||
1005 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); | ||
1006 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp); | ||
1007 | |||
1008 | /* set the write pointer delay */ | ||
1009 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR_CNTL, 0); | ||
1010 | |||
1011 | /* set the wb address */ | ||
1012 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR_ADDR, | ||
1013 | (upper_32_bits(ring->gpu_addr) >> 2)); | ||
1014 | |||
1015 | /* programm the RB_BASE for ring buffer */ | ||
1016 | WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW, | ||
1017 | lower_32_bits(ring->gpu_addr)); | ||
1018 | WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH, | ||
1019 | upper_32_bits(ring->gpu_addr)); | ||
1020 | |||
1021 | /* Initialize the ring buffer's read and write pointers */ | ||
1022 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR, 0); | ||
1023 | |||
1024 | ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR); | ||
1025 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, | ||
1026 | lower_32_bits(ring->wptr)); | ||
1027 | |||
1028 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0, | ||
1029 | ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK); | ||
1030 | |||
1031 | ring = &adev->uvd.inst->ring_enc[0]; | ||
1032 | WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); | ||
1033 | WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); | ||
1034 | WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr); | ||
1035 | WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); | ||
1036 | WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4); | ||
1037 | 1016 | ||
1038 | ring = &adev->uvd.inst->ring_enc[1]; | 1017 | /* clear the bit 4 of UVD_STATUS */ |
1039 | WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); | 1018 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_STATUS), 0, |
1040 | WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); | 1019 | ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); |
1041 | WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr); | ||
1042 | WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); | ||
1043 | WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4); | ||
1044 | 1020 | ||
1021 | /* force RBC into idle state */ | ||
1022 | rb_bufsz = order_base_2(ring->ring_size); | ||
1023 | tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz); | ||
1024 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); | ||
1025 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); | ||
1026 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0); | ||
1027 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); | ||
1028 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); | ||
1029 | WREG32_SOC15(UVD, k, mmUVD_RBC_RB_CNTL, tmp); | ||
1030 | |||
1031 | /* set the write pointer delay */ | ||
1032 | WREG32_SOC15(UVD, k, mmUVD_RBC_RB_WPTR_CNTL, 0); | ||
1033 | |||
1034 | /* set the wb address */ | ||
1035 | WREG32_SOC15(UVD, k, mmUVD_RBC_RB_RPTR_ADDR, | ||
1036 | (upper_32_bits(ring->gpu_addr) >> 2)); | ||
1037 | |||
1038 | /* programm the RB_BASE for ring buffer */ | ||
1039 | WREG32_SOC15(UVD, k, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW, | ||
1040 | lower_32_bits(ring->gpu_addr)); | ||
1041 | WREG32_SOC15(UVD, k, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH, | ||
1042 | upper_32_bits(ring->gpu_addr)); | ||
1043 | |||
1044 | /* Initialize the ring buffer's read and write pointers */ | ||
1045 | WREG32_SOC15(UVD, k, mmUVD_RBC_RB_RPTR, 0); | ||
1046 | |||
1047 | ring->wptr = RREG32_SOC15(UVD, k, mmUVD_RBC_RB_RPTR); | ||
1048 | WREG32_SOC15(UVD, k, mmUVD_RBC_RB_WPTR, | ||
1049 | lower_32_bits(ring->wptr)); | ||
1050 | |||
1051 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_RBC_RB_CNTL), 0, | ||
1052 | ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK); | ||
1053 | |||
1054 | ring = &adev->uvd.inst[k].ring_enc[0]; | ||
1055 | WREG32_SOC15(UVD, k, mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); | ||
1056 | WREG32_SOC15(UVD, k, mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); | ||
1057 | WREG32_SOC15(UVD, k, mmUVD_RB_BASE_LO, ring->gpu_addr); | ||
1058 | WREG32_SOC15(UVD, k, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); | ||
1059 | WREG32_SOC15(UVD, k, mmUVD_RB_SIZE, ring->ring_size / 4); | ||
1060 | |||
1061 | ring = &adev->uvd.inst[k].ring_enc[1]; | ||
1062 | WREG32_SOC15(UVD, k, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); | ||
1063 | WREG32_SOC15(UVD, k, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); | ||
1064 | WREG32_SOC15(UVD, k, mmUVD_RB_BASE_LO2, ring->gpu_addr); | ||
1065 | WREG32_SOC15(UVD, k, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); | ||
1066 | WREG32_SOC15(UVD, k, mmUVD_RB_SIZE2, ring->ring_size / 4); | ||
1067 | } | ||
1045 | return 0; | 1068 | return 0; |
1046 | } | 1069 | } |
1047 | 1070 | ||
@@ -1054,26 +1077,30 @@ static int uvd_v7_0_start(struct amdgpu_device *adev) | |||
1054 | */ | 1077 | */ |
1055 | static void uvd_v7_0_stop(struct amdgpu_device *adev) | 1078 | static void uvd_v7_0_stop(struct amdgpu_device *adev) |
1056 | { | 1079 | { |
1057 | /* force RBC into idle state */ | 1080 | uint8_t i = 0; |
1058 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, 0x11010101); | 1081 | |
1059 | 1082 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { | |
1060 | /* Stall UMC and register bus before resetting VCPU */ | 1083 | /* force RBC into idle state */ |
1061 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), | 1084 | WREG32_SOC15(UVD, i, mmUVD_RBC_RB_CNTL, 0x11010101); |
1062 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, | ||
1063 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
1064 | mdelay(1); | ||
1065 | |||
1066 | /* put VCPU into reset */ | ||
1067 | WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, | ||
1068 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
1069 | mdelay(5); | ||
1070 | 1085 | ||
1071 | /* disable VCPU clock */ | 1086 | /* Stall UMC and register bus before resetting VCPU */ |
1072 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, 0x0); | 1087 | WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2), |
1088 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, | ||
1089 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
1090 | mdelay(1); | ||
1073 | 1091 | ||
1074 | /* Unstall UMC and register bus */ | 1092 | /* put VCPU into reset */ |
1075 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0, | 1093 | WREG32_SOC15(UVD, i, mmUVD_SOFT_RESET, |
1076 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | 1094 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); |
1095 | mdelay(5); | ||
1096 | |||
1097 | /* disable VCPU clock */ | ||
1098 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CNTL, 0x0); | ||
1099 | |||
1100 | /* Unstall UMC and register bus */ | ||
1101 | WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2), 0, | ||
1102 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
1103 | } | ||
1077 | } | 1104 | } |
1078 | 1105 | ||
1079 | /** | 1106 | /** |
@@ -1092,26 +1119,26 @@ static void uvd_v7_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq | |||
1092 | WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); | 1119 | WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); |
1093 | 1120 | ||
1094 | amdgpu_ring_write(ring, | 1121 | amdgpu_ring_write(ring, |
1095 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0)); | 1122 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_CONTEXT_ID), 0)); |
1096 | amdgpu_ring_write(ring, seq); | 1123 | amdgpu_ring_write(ring, seq); |
1097 | amdgpu_ring_write(ring, | 1124 | amdgpu_ring_write(ring, |
1098 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); | 1125 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0)); |
1099 | amdgpu_ring_write(ring, addr & 0xffffffff); | 1126 | amdgpu_ring_write(ring, addr & 0xffffffff); |
1100 | amdgpu_ring_write(ring, | 1127 | amdgpu_ring_write(ring, |
1101 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); | 1128 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0)); |
1102 | amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff); | 1129 | amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff); |
1103 | amdgpu_ring_write(ring, | 1130 | amdgpu_ring_write(ring, |
1104 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); | 1131 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0)); |
1105 | amdgpu_ring_write(ring, 0); | 1132 | amdgpu_ring_write(ring, 0); |
1106 | 1133 | ||
1107 | amdgpu_ring_write(ring, | 1134 | amdgpu_ring_write(ring, |
1108 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); | 1135 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0)); |
1109 | amdgpu_ring_write(ring, 0); | 1136 | amdgpu_ring_write(ring, 0); |
1110 | amdgpu_ring_write(ring, | 1137 | amdgpu_ring_write(ring, |
1111 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); | 1138 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0)); |
1112 | amdgpu_ring_write(ring, 0); | 1139 | amdgpu_ring_write(ring, 0); |
1113 | amdgpu_ring_write(ring, | 1140 | amdgpu_ring_write(ring, |
1114 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); | 1141 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0)); |
1115 | amdgpu_ring_write(ring, 2); | 1142 | amdgpu_ring_write(ring, 2); |
1116 | } | 1143 | } |
1117 | 1144 | ||
@@ -1160,7 +1187,7 @@ static int uvd_v7_0_ring_test_ring(struct amdgpu_ring *ring) | |||
1160 | unsigned i; | 1187 | unsigned i; |
1161 | int r; | 1188 | int r; |
1162 | 1189 | ||
1163 | WREG32_SOC15(UVD, 0, mmUVD_CONTEXT_ID, 0xCAFEDEAD); | 1190 | WREG32_SOC15(UVD, ring->me, mmUVD_CONTEXT_ID, 0xCAFEDEAD); |
1164 | r = amdgpu_ring_alloc(ring, 3); | 1191 | r = amdgpu_ring_alloc(ring, 3); |
1165 | if (r) { | 1192 | if (r) { |
1166 | DRM_ERROR("amdgpu: (%d)cp failed to lock ring %d (%d).\n", | 1193 | DRM_ERROR("amdgpu: (%d)cp failed to lock ring %d (%d).\n", |
@@ -1168,11 +1195,11 @@ static int uvd_v7_0_ring_test_ring(struct amdgpu_ring *ring) | |||
1168 | return r; | 1195 | return r; |
1169 | } | 1196 | } |
1170 | amdgpu_ring_write(ring, | 1197 | amdgpu_ring_write(ring, |
1171 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0)); | 1198 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_CONTEXT_ID), 0)); |
1172 | amdgpu_ring_write(ring, 0xDEADBEEF); | 1199 | amdgpu_ring_write(ring, 0xDEADBEEF); |
1173 | amdgpu_ring_commit(ring); | 1200 | amdgpu_ring_commit(ring); |
1174 | for (i = 0; i < adev->usec_timeout; i++) { | 1201 | for (i = 0; i < adev->usec_timeout; i++) { |
1175 | tmp = RREG32_SOC15(UVD, 0, mmUVD_CONTEXT_ID); | 1202 | tmp = RREG32_SOC15(UVD, ring->me, mmUVD_CONTEXT_ID); |
1176 | if (tmp == 0xDEADBEEF) | 1203 | if (tmp == 0xDEADBEEF) |
1177 | break; | 1204 | break; |
1178 | DRM_UDELAY(1); | 1205 | DRM_UDELAY(1); |
@@ -1204,17 +1231,17 @@ static void uvd_v7_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
1204 | struct amdgpu_device *adev = ring->adev; | 1231 | struct amdgpu_device *adev = ring->adev; |
1205 | 1232 | ||
1206 | amdgpu_ring_write(ring, | 1233 | amdgpu_ring_write(ring, |
1207 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_VMID), 0)); | 1234 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_VMID), 0)); |
1208 | amdgpu_ring_write(ring, vmid); | 1235 | amdgpu_ring_write(ring, vmid); |
1209 | 1236 | ||
1210 | amdgpu_ring_write(ring, | 1237 | amdgpu_ring_write(ring, |
1211 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_LOW), 0)); | 1238 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_64BIT_BAR_LOW), 0)); |
1212 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); | 1239 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); |
1213 | amdgpu_ring_write(ring, | 1240 | amdgpu_ring_write(ring, |
1214 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH), 0)); | 1241 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH), 0)); |
1215 | amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); | 1242 | amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); |
1216 | amdgpu_ring_write(ring, | 1243 | amdgpu_ring_write(ring, |
1217 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_IB_SIZE), 0)); | 1244 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_RBC_IB_SIZE), 0)); |
1218 | amdgpu_ring_write(ring, ib->length_dw); | 1245 | amdgpu_ring_write(ring, ib->length_dw); |
1219 | } | 1246 | } |
1220 | 1247 | ||
@@ -1242,13 +1269,13 @@ static void uvd_v7_0_ring_emit_wreg(struct amdgpu_ring *ring, | |||
1242 | struct amdgpu_device *adev = ring->adev; | 1269 | struct amdgpu_device *adev = ring->adev; |
1243 | 1270 | ||
1244 | amdgpu_ring_write(ring, | 1271 | amdgpu_ring_write(ring, |
1245 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); | 1272 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0)); |
1246 | amdgpu_ring_write(ring, reg << 2); | 1273 | amdgpu_ring_write(ring, reg << 2); |
1247 | amdgpu_ring_write(ring, | 1274 | amdgpu_ring_write(ring, |
1248 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); | 1275 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0)); |
1249 | amdgpu_ring_write(ring, val); | 1276 | amdgpu_ring_write(ring, val); |
1250 | amdgpu_ring_write(ring, | 1277 | amdgpu_ring_write(ring, |
1251 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); | 1278 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0)); |
1252 | amdgpu_ring_write(ring, 8); | 1279 | amdgpu_ring_write(ring, 8); |
1253 | } | 1280 | } |
1254 | 1281 | ||
@@ -1258,16 +1285,16 @@ static void uvd_v7_0_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg, | |||
1258 | struct amdgpu_device *adev = ring->adev; | 1285 | struct amdgpu_device *adev = ring->adev; |
1259 | 1286 | ||
1260 | amdgpu_ring_write(ring, | 1287 | amdgpu_ring_write(ring, |
1261 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); | 1288 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0)); |
1262 | amdgpu_ring_write(ring, reg << 2); | 1289 | amdgpu_ring_write(ring, reg << 2); |
1263 | amdgpu_ring_write(ring, | 1290 | amdgpu_ring_write(ring, |
1264 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); | 1291 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0)); |
1265 | amdgpu_ring_write(ring, val); | 1292 | amdgpu_ring_write(ring, val); |
1266 | amdgpu_ring_write(ring, | 1293 | amdgpu_ring_write(ring, |
1267 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GP_SCRATCH8), 0)); | 1294 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GP_SCRATCH8), 0)); |
1268 | amdgpu_ring_write(ring, mask); | 1295 | amdgpu_ring_write(ring, mask); |
1269 | amdgpu_ring_write(ring, | 1296 | amdgpu_ring_write(ring, |
1270 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); | 1297 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0)); |
1271 | amdgpu_ring_write(ring, 12); | 1298 | amdgpu_ring_write(ring, 12); |
1272 | } | 1299 | } |
1273 | 1300 | ||
@@ -1292,7 +1319,7 @@ static void uvd_v7_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | |||
1292 | struct amdgpu_device *adev = ring->adev; | 1319 | struct amdgpu_device *adev = ring->adev; |
1293 | 1320 | ||
1294 | for (i = 0; i < count; i++) | 1321 | for (i = 0; i < count; i++) |
1295 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP), 0)); | 1322 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_NO_OP), 0)); |
1296 | 1323 | ||
1297 | } | 1324 | } |
1298 | 1325 | ||
@@ -1360,16 +1387,16 @@ static bool uvd_v7_0_check_soft_reset(void *handle) | |||
1360 | 1387 | ||
1361 | if (REG_GET_FIELD(tmp, SRBM_STATUS, UVD_RQ_PENDING) || | 1388 | if (REG_GET_FIELD(tmp, SRBM_STATUS, UVD_RQ_PENDING) || |
1362 | REG_GET_FIELD(tmp, SRBM_STATUS, UVD_BUSY) || | 1389 | REG_GET_FIELD(tmp, SRBM_STATUS, UVD_BUSY) || |
1363 | (RREG32_SOC15(UVD, 0, mmUVD_STATUS) & | 1390 | (RREG32_SOC15(UVD, ring->me, mmUVD_STATUS) & |
1364 | AMDGPU_UVD_STATUS_BUSY_MASK)) | 1391 | AMDGPU_UVD_STATUS_BUSY_MASK)) |
1365 | srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, | 1392 | srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, |
1366 | SRBM_SOFT_RESET, SOFT_RESET_UVD, 1); | 1393 | SRBM_SOFT_RESET, SOFT_RESET_UVD, 1); |
1367 | 1394 | ||
1368 | if (srbm_soft_reset) { | 1395 | if (srbm_soft_reset) { |
1369 | adev->uvd.inst->srbm_soft_reset = srbm_soft_reset; | 1396 | adev->uvd.inst[ring->me].srbm_soft_reset = srbm_soft_reset; |
1370 | return true; | 1397 | return true; |
1371 | } else { | 1398 | } else { |
1372 | adev->uvd.inst->srbm_soft_reset = 0; | 1399 | adev->uvd.inst[ring->me].srbm_soft_reset = 0; |
1373 | return false; | 1400 | return false; |
1374 | } | 1401 | } |
1375 | } | 1402 | } |
@@ -1378,7 +1405,7 @@ static int uvd_v7_0_pre_soft_reset(void *handle) | |||
1378 | { | 1405 | { |
1379 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1406 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1380 | 1407 | ||
1381 | if (!adev->uvd.inst->srbm_soft_reset) | 1408 | if (!adev->uvd.inst[ring->me].srbm_soft_reset) |
1382 | return 0; | 1409 | return 0; |
1383 | 1410 | ||
1384 | uvd_v7_0_stop(adev); | 1411 | uvd_v7_0_stop(adev); |
@@ -1390,9 +1417,9 @@ static int uvd_v7_0_soft_reset(void *handle) | |||
1390 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1417 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1391 | u32 srbm_soft_reset; | 1418 | u32 srbm_soft_reset; |
1392 | 1419 | ||
1393 | if (!adev->uvd.inst->srbm_soft_reset) | 1420 | if (!adev->uvd.inst[ring->me].srbm_soft_reset) |
1394 | return 0; | 1421 | return 0; |
1395 | srbm_soft_reset = adev->uvd.inst->srbm_soft_reset; | 1422 | srbm_soft_reset = adev->uvd.inst[ring->me].srbm_soft_reset; |
1396 | 1423 | ||
1397 | if (srbm_soft_reset) { | 1424 | if (srbm_soft_reset) { |
1398 | u32 tmp; | 1425 | u32 tmp; |
@@ -1420,7 +1447,7 @@ static int uvd_v7_0_post_soft_reset(void *handle) | |||
1420 | { | 1447 | { |
1421 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1448 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1422 | 1449 | ||
1423 | if (!adev->uvd.inst->srbm_soft_reset) | 1450 | if (!adev->uvd.inst[ring->me].srbm_soft_reset) |
1424 | return 0; | 1451 | return 0; |
1425 | 1452 | ||
1426 | mdelay(5); | 1453 | mdelay(5); |
@@ -1442,17 +1469,29 @@ static int uvd_v7_0_process_interrupt(struct amdgpu_device *adev, | |||
1442 | struct amdgpu_irq_src *source, | 1469 | struct amdgpu_irq_src *source, |
1443 | struct amdgpu_iv_entry *entry) | 1470 | struct amdgpu_iv_entry *entry) |
1444 | { | 1471 | { |
1472 | uint32_t ip_instance; | ||
1473 | |||
1474 | switch (entry->client_id) { | ||
1475 | case SOC15_IH_CLIENTID_UVD: | ||
1476 | ip_instance = 0; | ||
1477 | break; | ||
1478 | default: | ||
1479 | DRM_ERROR("Unhandled client id: %d\n", entry->client_id); | ||
1480 | return 0; | ||
1481 | } | ||
1482 | |||
1445 | DRM_DEBUG("IH: UVD TRAP\n"); | 1483 | DRM_DEBUG("IH: UVD TRAP\n"); |
1484 | |||
1446 | switch (entry->src_id) { | 1485 | switch (entry->src_id) { |
1447 | case 124: | 1486 | case 124: |
1448 | amdgpu_fence_process(&adev->uvd.inst->ring); | 1487 | amdgpu_fence_process(&adev->uvd.inst[ip_instance].ring); |
1449 | break; | 1488 | break; |
1450 | case 119: | 1489 | case 119: |
1451 | amdgpu_fence_process(&adev->uvd.inst->ring_enc[0]); | 1490 | amdgpu_fence_process(&adev->uvd.inst[ip_instance].ring_enc[0]); |
1452 | break; | 1491 | break; |
1453 | case 120: | 1492 | case 120: |
1454 | if (!amdgpu_sriov_vf(adev)) | 1493 | if (!amdgpu_sriov_vf(adev)) |
1455 | amdgpu_fence_process(&adev->uvd.inst->ring_enc[1]); | 1494 | amdgpu_fence_process(&adev->uvd.inst[ip_instance].ring_enc[1]); |
1456 | break; | 1495 | break; |
1457 | default: | 1496 | default: |
1458 | DRM_ERROR("Unhandled interrupt: %d %d\n", | 1497 | DRM_ERROR("Unhandled interrupt: %d %d\n", |
@@ -1468,9 +1507,9 @@ static void uvd_v7_0_set_sw_clock_gating(struct amdgpu_device *adev) | |||
1468 | { | 1507 | { |
1469 | uint32_t data, data1, data2, suvd_flags; | 1508 | uint32_t data, data1, data2, suvd_flags; |
1470 | 1509 | ||
1471 | data = RREG32_SOC15(UVD, 0, mmUVD_CGC_CTRL); | 1510 | data = RREG32_SOC15(UVD, ring->me, mmUVD_CGC_CTRL); |
1472 | data1 = RREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_GATE); | 1511 | data1 = RREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE); |
1473 | data2 = RREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_CTRL); | 1512 | data2 = RREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_CTRL); |
1474 | 1513 | ||
1475 | data &= ~(UVD_CGC_CTRL__CLK_OFF_DELAY_MASK | | 1514 | data &= ~(UVD_CGC_CTRL__CLK_OFF_DELAY_MASK | |
1476 | UVD_CGC_CTRL__CLK_GATE_DLY_TIMER_MASK); | 1515 | UVD_CGC_CTRL__CLK_GATE_DLY_TIMER_MASK); |
@@ -1514,18 +1553,18 @@ static void uvd_v7_0_set_sw_clock_gating(struct amdgpu_device *adev) | |||
1514 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK); | 1553 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK); |
1515 | data1 |= suvd_flags; | 1554 | data1 |= suvd_flags; |
1516 | 1555 | ||
1517 | WREG32_SOC15(UVD, 0, mmUVD_CGC_CTRL, data); | 1556 | WREG32_SOC15(UVD, ring->me, mmUVD_CGC_CTRL, data); |
1518 | WREG32_SOC15(UVD, 0, mmUVD_CGC_GATE, 0); | 1557 | WREG32_SOC15(UVD, ring->me, mmUVD_CGC_GATE, 0); |
1519 | WREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_GATE, data1); | 1558 | WREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE, data1); |
1520 | WREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_CTRL, data2); | 1559 | WREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_CTRL, data2); |
1521 | } | 1560 | } |
1522 | 1561 | ||
1523 | static void uvd_v7_0_set_hw_clock_gating(struct amdgpu_device *adev) | 1562 | static void uvd_v7_0_set_hw_clock_gating(struct amdgpu_device *adev) |
1524 | { | 1563 | { |
1525 | uint32_t data, data1, cgc_flags, suvd_flags; | 1564 | uint32_t data, data1, cgc_flags, suvd_flags; |
1526 | 1565 | ||
1527 | data = RREG32_SOC15(UVD, 0, mmUVD_CGC_GATE); | 1566 | data = RREG32_SOC15(UVD, ring->me, mmUVD_CGC_GATE); |
1528 | data1 = RREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_GATE); | 1567 | data1 = RREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE); |
1529 | 1568 | ||
1530 | cgc_flags = UVD_CGC_GATE__SYS_MASK | | 1569 | cgc_flags = UVD_CGC_GATE__SYS_MASK | |
1531 | UVD_CGC_GATE__UDEC_MASK | | 1570 | UVD_CGC_GATE__UDEC_MASK | |
@@ -1557,8 +1596,8 @@ static void uvd_v7_0_set_hw_clock_gating(struct amdgpu_device *adev) | |||
1557 | data |= cgc_flags; | 1596 | data |= cgc_flags; |
1558 | data1 |= suvd_flags; | 1597 | data1 |= suvd_flags; |
1559 | 1598 | ||
1560 | WREG32_SOC15(UVD, 0, mmUVD_CGC_GATE, data); | 1599 | WREG32_SOC15(UVD, ring->me, mmUVD_CGC_GATE, data); |
1561 | WREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_GATE, data1); | 1600 | WREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE, data1); |
1562 | } | 1601 | } |
1563 | 1602 | ||
1564 | static void uvd_v7_0_set_bypass_mode(struct amdgpu_device *adev, bool enable) | 1603 | static void uvd_v7_0_set_bypass_mode(struct amdgpu_device *adev, bool enable) |
@@ -1617,7 +1656,7 @@ static int uvd_v7_0_set_powergating_state(void *handle, | |||
1617 | if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD)) | 1656 | if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD)) |
1618 | return 0; | 1657 | return 0; |
1619 | 1658 | ||
1620 | WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, UVD_POWER_STATUS__UVD_PG_EN_MASK); | 1659 | WREG32_SOC15(UVD, ring->me, mmUVD_POWER_STATUS, UVD_POWER_STATUS__UVD_PG_EN_MASK); |
1621 | 1660 | ||
1622 | if (state == AMD_PG_STATE_GATE) { | 1661 | if (state == AMD_PG_STATE_GATE) { |
1623 | uvd_v7_0_stop(adev); | 1662 | uvd_v7_0_stop(adev); |
@@ -1720,18 +1759,27 @@ static const struct amdgpu_ring_funcs uvd_v7_0_enc_ring_vm_funcs = { | |||
1720 | 1759 | ||
1721 | static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev) | 1760 | static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev) |
1722 | { | 1761 | { |
1723 | adev->uvd.inst->ring.funcs = &uvd_v7_0_ring_vm_funcs; | 1762 | int i; |
1724 | DRM_INFO("UVD is enabled in VM mode\n"); | 1763 | |
1764 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { | ||
1765 | adev->uvd.inst[i].ring.funcs = &uvd_v7_0_ring_vm_funcs; | ||
1766 | adev->uvd.inst[i].ring.me = i; | ||
1767 | DRM_INFO("UVD(%d) is enabled in VM mode\n", i); | ||
1768 | } | ||
1725 | } | 1769 | } |
1726 | 1770 | ||
1727 | static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev) | 1771 | static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev) |
1728 | { | 1772 | { |
1729 | int i; | 1773 | int i, j; |
1730 | 1774 | ||
1731 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) | 1775 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
1732 | adev->uvd.inst->ring_enc[i].funcs = &uvd_v7_0_enc_ring_vm_funcs; | 1776 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { |
1777 | adev->uvd.inst[j].ring_enc[i].funcs = &uvd_v7_0_enc_ring_vm_funcs; | ||
1778 | adev->uvd.inst[j].ring_enc[i].me = j; | ||
1779 | } | ||
1733 | 1780 | ||
1734 | DRM_INFO("UVD ENC is enabled in VM mode\n"); | 1781 | DRM_INFO("UVD(%d) ENC is enabled in VM mode\n", j); |
1782 | } | ||
1735 | } | 1783 | } |
1736 | 1784 | ||
1737 | static const struct amdgpu_irq_src_funcs uvd_v7_0_irq_funcs = { | 1785 | static const struct amdgpu_irq_src_funcs uvd_v7_0_irq_funcs = { |
@@ -1741,8 +1789,12 @@ static const struct amdgpu_irq_src_funcs uvd_v7_0_irq_funcs = { | |||
1741 | 1789 | ||
1742 | static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev) | 1790 | static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev) |
1743 | { | 1791 | { |
1744 | adev->uvd.inst->irq.num_types = adev->uvd.num_enc_rings + 1; | 1792 | int i; |
1745 | adev->uvd.inst->irq.funcs = &uvd_v7_0_irq_funcs; | 1793 | |
1794 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { | ||
1795 | adev->uvd.inst[i].irq.num_types = adev->uvd.num_enc_rings + 1; | ||
1796 | adev->uvd.inst[i].irq.funcs = &uvd_v7_0_irq_funcs; | ||
1797 | } | ||
1746 | } | 1798 | } |
1747 | 1799 | ||
1748 | const struct amdgpu_ip_block_version uvd_v7_0_ip_block = | 1800 | const struct amdgpu_ip_block_version uvd_v7_0_ip_block = |