Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: handle more than 10 UVD sessions (v2)

Change History
--------------

v2:
- Make firmware version check correctly. Firmware
versions >= 1.80 should all support 40 UVD
instances.
- Replace AMDGPU_MAX_UVD_HANDLES with max_handles
variable.

v1:
- The firmware can handle upto 40 UVD sessions.

Signed-off-by: Arindam Nath <arindam.nath@amd.com>
Signed-off-by: Ayyappa Chandolu <ayyappa.chandolu@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Arindam Nath and committed by
Alex Deucher
c0365541 aeba709a

+41 -18
+7 -4
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 1593 1593 /* 1594 1594 * UVD 1595 1595 */ 1596 - #define AMDGPU_MAX_UVD_HANDLES 10 1597 - #define AMDGPU_UVD_STACK_SIZE (1024*1024) 1598 - #define AMDGPU_UVD_HEAP_SIZE (1024*1024) 1599 - #define AMDGPU_UVD_FIRMWARE_OFFSET 256 1596 + #define AMDGPU_DEFAULT_UVD_HANDLES 10 1597 + #define AMDGPU_MAX_UVD_HANDLES 40 1598 + #define AMDGPU_UVD_STACK_SIZE (200*1024) 1599 + #define AMDGPU_UVD_HEAP_SIZE (256*1024) 1600 + #define AMDGPU_UVD_SESSION_SIZE (50*1024) 1601 + #define AMDGPU_UVD_FIRMWARE_OFFSET 256 1600 1602 1601 1603 struct amdgpu_uvd { 1602 1604 struct amdgpu_bo *vcpu_bo; 1603 1605 void *cpu_addr; 1604 1606 uint64_t gpu_addr; 1605 1607 void *saved_bo; 1608 + unsigned max_handles; 1606 1609 atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; 1607 1610 struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; 1608 1611 struct delayed_work idle_work;
+22 -8
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
··· 151 151 return r; 152 152 } 153 153 154 + /* Set the default UVD handles that the firmware can handle */ 155 + adev->uvd.max_handles = AMDGPU_DEFAULT_UVD_HANDLES; 156 + 154 157 hdr = (const struct common_firmware_header *)adev->uvd.fw->data; 155 158 family_id = le32_to_cpu(hdr->ucode_version) & 0xff; 156 159 version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff; ··· 161 158 DRM_INFO("Found UVD firmware Version: %hu.%hu Family ID: %hu\n", 162 159 version_major, version_minor, family_id); 163 160 161 + /* 162 + * Limit the number of UVD handles depending on microcode major 163 + * and minor versions. The firmware version which has 40 UVD 164 + * instances support is 1.80. So all subsequent versions should 165 + * also have the same support. 166 + */ 167 + if ((version_major > 0x01) || 168 + ((version_major == 0x01) && (version_minor >= 0x50))) 169 + adev->uvd.max_handles = AMDGPU_MAX_UVD_HANDLES; 170 + 164 171 bo_size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8) 165 - + AMDGPU_UVD_STACK_SIZE + AMDGPU_UVD_HEAP_SIZE; 172 + + AMDGPU_UVD_STACK_SIZE + AMDGPU_UVD_HEAP_SIZE 173 + + AMDGPU_UVD_SESSION_SIZE * adev->uvd.max_handles; 166 174 r = amdgpu_bo_create(adev, bo_size, PAGE_SIZE, true, 167 175 AMDGPU_GEM_DOMAIN_VRAM, 168 176 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, ··· 216 202 return r; 217 203 } 218 204 219 - for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { 205 + for (i = 0; i < adev->uvd.max_handles; ++i) { 220 206 atomic_set(&adev->uvd.handles[i], 0); 221 207 adev->uvd.filp[i] = NULL; 222 208 } ··· 262 248 if (adev->uvd.vcpu_bo == NULL) 263 249 return 0; 264 250 265 - for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) 251 + for (i = 0; i < adev->uvd.max_handles; ++i) 266 252 if (atomic_read(&adev->uvd.handles[i])) 267 253 break; 268 254 ··· 317 303 struct amdgpu_ring *ring = &adev->uvd.ring; 318 304 int i, r; 319 305 320 - for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { 306 + for (i = 0; i < adev->uvd.max_handles; ++i) { 321 307 uint32_t handle = atomic_read(&adev->uvd.handles[i]); 322 308 if (handle != 0 && adev->uvd.filp[i] == filp) { 323 309 struct fence *fence; ··· 577 563 amdgpu_bo_kunmap(bo); 578 564 579 565 /* try to alloc a new handle */ 580 - for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { 566 + for (i = 0; i < adev->uvd.max_handles; ++i) { 581 567 if (atomic_read(&adev->uvd.handles[i]) == handle) { 582 568 DRM_ERROR("Handle 0x%x already in use!\n", handle); 583 569 return -EINVAL; ··· 600 586 return r; 601 587 602 588 /* validate the handle */ 603 - for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { 589 + for (i = 0; i < adev->uvd.max_handles; ++i) { 604 590 if (atomic_read(&adev->uvd.handles[i]) == handle) { 605 591 if (adev->uvd.filp[i] != ctx->parser->filp) { 606 592 DRM_ERROR("UVD handle collision detected!\n"); ··· 615 601 616 602 case 2: 617 603 /* it's a destroy msg, free the handle */ 618 - for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) 604 + for (i = 0; i < adev->uvd.max_handles; ++i) 619 605 atomic_cmpxchg(&adev->uvd.handles[i], handle, 0); 620 606 amdgpu_bo_kunmap(bo); 621 607 return 0; ··· 1027 1013 1028 1014 fences = amdgpu_fence_count_emitted(&adev->uvd.ring); 1029 1015 1030 - for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) 1016 + for (i = 0; i < adev->uvd.max_handles; ++i) 1031 1017 if (atomic_read(&adev->uvd.handles[i])) 1032 1018 ++handles; 1033 1019
+3 -2
drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
··· 559 559 WREG32(mmUVD_VCPU_CACHE_SIZE0, size); 560 560 561 561 addr += size; 562 - size = AMDGPU_UVD_STACK_SIZE >> 3; 562 + size = AMDGPU_UVD_HEAP_SIZE >> 3; 563 563 WREG32(mmUVD_VCPU_CACHE_OFFSET1, addr); 564 564 WREG32(mmUVD_VCPU_CACHE_SIZE1, size); 565 565 566 566 addr += size; 567 - size = AMDGPU_UVD_HEAP_SIZE >> 3; 567 + size = (AMDGPU_UVD_STACK_SIZE + 568 + (AMDGPU_UVD_SESSION_SIZE * adev->uvd.max_handles)) >> 3; 568 569 WREG32(mmUVD_VCPU_CACHE_OFFSET2, addr); 569 570 WREG32(mmUVD_VCPU_CACHE_SIZE2, size); 570 571
+3 -2
drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
··· 272 272 WREG32(mmUVD_VCPU_CACHE_SIZE0, size); 273 273 274 274 offset += size; 275 - size = AMDGPU_UVD_STACK_SIZE; 275 + size = AMDGPU_UVD_HEAP_SIZE; 276 276 WREG32(mmUVD_VCPU_CACHE_OFFSET1, offset >> 3); 277 277 WREG32(mmUVD_VCPU_CACHE_SIZE1, size); 278 278 279 279 offset += size; 280 - size = AMDGPU_UVD_HEAP_SIZE; 280 + size = AMDGPU_UVD_STACK_SIZE + 281 + (AMDGPU_UVD_SESSION_SIZE * adev->uvd.max_handles); 281 282 WREG32(mmUVD_VCPU_CACHE_OFFSET2, offset >> 3); 282 283 WREG32(mmUVD_VCPU_CACHE_SIZE2, size); 283 284
+5 -2
drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
··· 272 272 WREG32(mmUVD_VCPU_CACHE_SIZE0, size); 273 273 274 274 offset += size; 275 - size = AMDGPU_UVD_STACK_SIZE; 275 + size = AMDGPU_UVD_HEAP_SIZE; 276 276 WREG32(mmUVD_VCPU_CACHE_OFFSET1, offset >> 3); 277 277 WREG32(mmUVD_VCPU_CACHE_SIZE1, size); 278 278 279 279 offset += size; 280 - size = AMDGPU_UVD_HEAP_SIZE; 280 + size = AMDGPU_UVD_STACK_SIZE + 281 + (AMDGPU_UVD_SESSION_SIZE * adev->uvd.max_handles); 281 282 WREG32(mmUVD_VCPU_CACHE_OFFSET2, offset >> 3); 282 283 WREG32(mmUVD_VCPU_CACHE_SIZE2, size); 283 284 284 285 WREG32(mmUVD_UDEC_ADDR_CONFIG, adev->gfx.config.gb_addr_config); 285 286 WREG32(mmUVD_UDEC_DB_ADDR_CONFIG, adev->gfx.config.gb_addr_config); 286 287 WREG32(mmUVD_UDEC_DBW_ADDR_CONFIG, adev->gfx.config.gb_addr_config); 288 + 289 + WREG32(mmUVD_GP_SCRATCH4, adev->uvd.max_handles); 287 290 } 288 291 289 292 #if 0
+1
drivers/gpu/drm/amd/include/asic_reg/uvd/uvd_6_0_d.h
··· 111 111 #define mmUVD_MIF_RECON1_ADDR_CONFIG 0x39c5 112 112 #define ixUVD_MIF_SCLR_ADDR_CONFIG 0x4 113 113 #define mmUVD_JPEG_ADDR_CONFIG 0x3a1f 114 + #define mmUVD_GP_SCRATCH4 0x3d38 114 115 115 116 #endif /* UVD_6_0_D_H */