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

drm/amdgpu: Complete multimedia bandwidth interface

- Update SRIOV PF2VF header with latest revision

- Extend existing function in amdgpu_virt.c to read MM bandwidth config
from PF2VF message

- Add SRIOV Sienna Cichlid codec array and update the bandwidth with
PF2VF message

v2: squash in removal of unused variable (Alex)

Signed-off-by: Bokun Zhang <bokun.zhang@amd.com>
Reviewed-by: Monk liu <monk.liu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Bokun Zhang and committed by
Alex Deucher
ed9d2053 2b2339ee

+225 -7
+56
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
··· 432 432 uint32_t checksum; 433 433 uint32_t checkval; 434 434 435 + uint32_t i; 436 + uint32_t tmp; 437 + 435 438 if (adev->virt.fw_reserve.p_pf2vf == NULL) 436 439 return -EINVAL; 437 440 ··· 474 471 ((struct amd_sriov_msg_pf2vf_info *)pf2vf_info)->feature_flags.all; 475 472 adev->virt.reg_access = 476 473 ((struct amd_sriov_msg_pf2vf_info *)pf2vf_info)->reg_access_flags.all; 474 + 475 + adev->virt.decode_max_dimension_pixels = 0; 476 + adev->virt.decode_max_frame_pixels = 0; 477 + adev->virt.encode_max_dimension_pixels = 0; 478 + adev->virt.encode_max_frame_pixels = 0; 479 + adev->virt.is_mm_bw_enabled = false; 480 + for (i = 0; i < AMD_SRIOV_MSG_RESERVE_VCN_INST; i++) { 481 + tmp = ((struct amd_sriov_msg_pf2vf_info *)pf2vf_info)->mm_bw_management[i].decode_max_dimension_pixels; 482 + adev->virt.decode_max_dimension_pixels = max(tmp, adev->virt.decode_max_dimension_pixels); 483 + 484 + tmp = ((struct amd_sriov_msg_pf2vf_info *)pf2vf_info)->mm_bw_management[i].decode_max_frame_pixels; 485 + adev->virt.decode_max_frame_pixels = max(tmp, adev->virt.decode_max_frame_pixels); 486 + 487 + tmp = ((struct amd_sriov_msg_pf2vf_info *)pf2vf_info)->mm_bw_management[i].encode_max_dimension_pixels; 488 + adev->virt.encode_max_dimension_pixels = max(tmp, adev->virt.encode_max_dimension_pixels); 489 + 490 + tmp = ((struct amd_sriov_msg_pf2vf_info *)pf2vf_info)->mm_bw_management[i].encode_max_frame_pixels; 491 + adev->virt.encode_max_frame_pixels = max(tmp, adev->virt.encode_max_frame_pixels); 492 + } 493 + if((adev->virt.decode_max_dimension_pixels > 0) || (adev->virt.encode_max_dimension_pixels > 0)) 494 + adev->virt.is_mm_bw_enabled = true; 477 495 478 496 break; 479 497 default: ··· 767 743 } 768 744 769 745 return mode; 746 + } 747 + 748 + void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev, 749 + struct amdgpu_video_codec_info *encode, uint32_t encode_array_size, 750 + struct amdgpu_video_codec_info *decode, uint32_t decode_array_size) 751 + { 752 + uint32_t i; 753 + 754 + if (!adev->virt.is_mm_bw_enabled) 755 + return; 756 + 757 + if (encode) { 758 + for (i = 0; i < encode_array_size; i++) { 759 + encode[i].max_width = adev->virt.encode_max_dimension_pixels; 760 + encode[i].max_pixels_per_frame = adev->virt.encode_max_frame_pixels; 761 + if (encode[i].max_width > 0) 762 + encode[i].max_height = encode[i].max_pixels_per_frame / encode[i].max_width; 763 + else 764 + encode[i].max_height = 0; 765 + } 766 + } 767 + 768 + if (decode) { 769 + for (i = 0; i < decode_array_size; i++) { 770 + decode[i].max_width = adev->virt.decode_max_dimension_pixels; 771 + decode[i].max_pixels_per_frame = adev->virt.decode_max_frame_pixels; 772 + if (decode[i].max_width > 0) 773 + decode[i].max_height = decode[i].max_pixels_per_frame / decode[i].max_width; 774 + else 775 + decode[i].max_height = 0; 776 + } 777 + } 770 778 }
+13
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
··· 233 233 /* vf2pf message */ 234 234 struct delayed_work vf2pf_work; 235 235 uint32_t vf2pf_update_interval_ms; 236 + 237 + /* multimedia bandwidth config */ 238 + bool is_mm_bw_enabled; 239 + uint32_t decode_max_dimension_pixels; 240 + uint32_t decode_max_frame_pixels; 241 + uint32_t encode_max_dimension_pixels; 242 + uint32_t encode_max_frame_pixels; 236 243 }; 244 + 245 + struct amdgpu_video_codec_info; 237 246 238 247 #define amdgpu_sriov_enabled(adev) \ 239 248 ((adev)->virt.caps & AMDGPU_SRIOV_CAPS_ENABLE_IOV) ··· 316 307 void amdgpu_virt_disable_access_debugfs(struct amdgpu_device *adev); 317 308 318 309 enum amdgpu_sriov_vf_mode amdgpu_virt_get_sriov_vf_mode(struct amdgpu_device *adev); 310 + 311 + void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev, 312 + struct amdgpu_video_codec_info *encode, uint32_t encode_array_size, 313 + struct amdgpu_video_codec_info *decode, uint32_t decode_array_size); 319 314 #endif
+48 -6
drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
··· 56 56 57 57 #define AMD_SRIOV_MSG_RESERVE_UCODE 24 58 58 59 + #define AMD_SRIOV_MSG_RESERVE_VCN_INST 4 60 + 59 61 enum amd_sriov_ucode_engine_id { 60 62 AMD_SRIOV_UCODE_ID_VCE = 0, 61 63 AMD_SRIOV_UCODE_ID_UVD, ··· 100 98 101 99 union amd_sriov_reg_access_flags { 102 100 struct { 103 - uint32_t vf_reg_psp_access_ih : 1; 104 - uint32_t vf_reg_rlc_access_mmhub : 1; 105 - uint32_t vf_reg_rlc_access_gc : 1; 106 - uint32_t reserved : 29; 101 + uint32_t vf_reg_access_ih : 1; 102 + uint32_t vf_reg_access_mmhub : 1; 103 + uint32_t vf_reg_access_gc : 1; 104 + uint32_t reserved : 29; 107 105 } flags; 108 106 uint32_t all; 109 107 }; ··· 114 112 uint32_t reserved : 31; 115 113 } info; 116 114 uint32_t all; 115 + }; 116 + 117 + struct amd_sriov_msg_uuid_info { 118 + union { 119 + struct { 120 + uint32_t did : 16; 121 + uint32_t fcn : 8; 122 + uint32_t asic_7 : 8; 123 + }; 124 + uint32_t time_low; 125 + }; 126 + 127 + struct { 128 + uint32_t time_mid : 16; 129 + uint32_t time_high : 12; 130 + uint32_t version : 4; 131 + }; 132 + 133 + struct { 134 + struct { 135 + uint8_t clk_seq_hi : 6; 136 + uint8_t variant : 2; 137 + }; 138 + union { 139 + uint8_t clk_seq_low; 140 + uint8_t asic_6; 141 + }; 142 + uint16_t asic_4; 143 + }; 144 + 145 + uint32_t asic_0; 117 146 }; 118 147 119 148 struct amd_sriov_msg_pf2vf_info_header { ··· 193 160 /* identification in ROCm SMI */ 194 161 uint64_t uuid; 195 162 uint32_t fcn_idx; 196 - /* flags which indicate the register access method VF should use */ 163 + /* flags to indicate which register access method VF should use */ 197 164 union amd_sriov_reg_access_flags reg_access_flags; 165 + /* MM BW management */ 166 + struct { 167 + uint32_t decode_max_dimension_pixels; 168 + uint32_t decode_max_frame_pixels; 169 + uint32_t encode_max_dimension_pixels; 170 + uint32_t encode_max_frame_pixels; 171 + } mm_bw_management[AMD_SRIOV_MSG_RESERVE_VCN_INST]; 172 + /* UUID info */ 173 + struct amd_sriov_msg_uuid_info uuid_info; 198 174 /* reserved */ 199 - uint32_t reserved[256-27]; 175 + uint32_t reserved[256 - 47]; 200 176 }; 201 177 202 178 struct amd_sriov_msg_vf2pf_info_header {
+108 -1
drivers/gpu/drm/amd/amdgpu/nv.c
··· 218 218 .codec_array = sc_video_codecs_decode_array, 219 219 }; 220 220 221 + /* SRIOV Sienna Cichlid, not const since data is controlled by host */ 222 + static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] = 223 + { 224 + { 225 + .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 226 + .max_width = 4096, 227 + .max_height = 2304, 228 + .max_pixels_per_frame = 4096 * 2304, 229 + .max_level = 0, 230 + }, 231 + { 232 + .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 233 + .max_width = 4096, 234 + .max_height = 2304, 235 + .max_pixels_per_frame = 4096 * 2304, 236 + .max_level = 0, 237 + }, 238 + }; 239 + 240 + static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array[] = 241 + { 242 + { 243 + .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 244 + .max_width = 4096, 245 + .max_height = 4096, 246 + .max_pixels_per_frame = 4096 * 4096, 247 + .max_level = 3, 248 + }, 249 + { 250 + .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 251 + .max_width = 4096, 252 + .max_height = 4096, 253 + .max_pixels_per_frame = 4096 * 4096, 254 + .max_level = 5, 255 + }, 256 + { 257 + .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 258 + .max_width = 4096, 259 + .max_height = 4096, 260 + .max_pixels_per_frame = 4096 * 4096, 261 + .max_level = 52, 262 + }, 263 + { 264 + .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 265 + .max_width = 4096, 266 + .max_height = 4096, 267 + .max_pixels_per_frame = 4096 * 4096, 268 + .max_level = 4, 269 + }, 270 + { 271 + .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 272 + .max_width = 8192, 273 + .max_height = 4352, 274 + .max_pixels_per_frame = 8192 * 4352, 275 + .max_level = 186, 276 + }, 277 + { 278 + .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 279 + .max_width = 4096, 280 + .max_height = 4096, 281 + .max_pixels_per_frame = 4096 * 4096, 282 + .max_level = 0, 283 + }, 284 + { 285 + .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 286 + .max_width = 8192, 287 + .max_height = 4352, 288 + .max_pixels_per_frame = 8192 * 4352, 289 + .max_level = 0, 290 + }, 291 + { 292 + .codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 293 + .max_width = 8192, 294 + .max_height = 4352, 295 + .max_pixels_per_frame = 8192 * 4352, 296 + .max_level = 0, 297 + }, 298 + }; 299 + 300 + static struct amdgpu_video_codecs sriov_sc_video_codecs_encode = 301 + { 302 + .codec_count = ARRAY_SIZE(sriov_sc_video_codecs_encode_array), 303 + .codec_array = sriov_sc_video_codecs_encode_array, 304 + }; 305 + 306 + static struct amdgpu_video_codecs sriov_sc_video_codecs_decode = 307 + { 308 + .codec_count = ARRAY_SIZE(sriov_sc_video_codecs_decode_array), 309 + .codec_array = sriov_sc_video_codecs_decode_array, 310 + }; 311 + 221 312 static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode, 222 313 const struct amdgpu_video_codecs **codecs) 223 314 { 224 315 switch (adev->asic_type) { 225 316 case CHIP_SIENNA_CICHLID: 317 + if (amdgpu_sriov_vf(adev)) { 318 + if (encode) 319 + *codecs = &sriov_sc_video_codecs_encode; 320 + else 321 + *codecs = &sriov_sc_video_codecs_decode; 322 + } else { 323 + if (encode) 324 + *codecs = &nv_video_codecs_encode; 325 + else 326 + *codecs = &sc_video_codecs_decode; 327 + } 328 + return 0; 226 329 case CHIP_NAVY_FLOUNDER: 227 330 case CHIP_DIMGREY_CAVEFISH: 228 331 case CHIP_VANGOGH: ··· 1277 1174 { 1278 1175 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1279 1176 1280 - if (amdgpu_sriov_vf(adev)) 1177 + if (amdgpu_sriov_vf(adev)) { 1281 1178 xgpu_nv_mailbox_get_irq(adev); 1179 + amdgpu_virt_update_sriov_video_codec(adev, 1180 + sriov_sc_video_codecs_encode_array, ARRAY_SIZE(sriov_sc_video_codecs_encode_array), 1181 + sriov_sc_video_codecs_decode_array, ARRAY_SIZE(sriov_sc_video_codecs_decode_array)); 1182 + } 1282 1183 1283 1184 return 0; 1284 1185 }