diff options
author | Huang Rui <ray.huang@amd.com> | 2017-03-03 16:20:35 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-03-29 23:54:40 -0400 |
commit | 2445b22751a0c039c2d1f35412e45350e847855d (patch) | |
tree | bd9621cccaaf47882076e13e7bfe6f745e670d7b /drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | |
parent | 9079ac7666c23fecc0b59d136efd349fc1038ba6 (diff) |
drm/amdgpu: rework common ucode handling for vega10
Handle ucode differences in vega10.
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Huang Rui <ray.huang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 70 |
1 files changed, 47 insertions, 23 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index 73c3e664d99a..a1891c93cdbf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | |||
@@ -260,10 +260,12 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type) | |||
260 | return AMDGPU_FW_LOAD_DIRECT; | 260 | return AMDGPU_FW_LOAD_DIRECT; |
261 | } | 261 | } |
262 | 262 | ||
263 | static int amdgpu_ucode_init_single_fw(struct amdgpu_firmware_info *ucode, | 263 | static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, |
264 | uint64_t mc_addr, void *kptr) | 264 | struct amdgpu_firmware_info *ucode, |
265 | uint64_t mc_addr, void *kptr) | ||
265 | { | 266 | { |
266 | const struct common_firmware_header *header = NULL; | 267 | const struct common_firmware_header *header = NULL; |
268 | const struct gfx_firmware_header_v1_0 *cp_hdr = NULL; | ||
267 | 269 | ||
268 | if (NULL == ucode->fw) | 270 | if (NULL == ucode->fw) |
269 | return 0; | 271 | return 0; |
@@ -276,11 +278,35 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_firmware_info *ucode, | |||
276 | 278 | ||
277 | header = (const struct common_firmware_header *)ucode->fw->data; | 279 | header = (const struct common_firmware_header *)ucode->fw->data; |
278 | 280 | ||
279 | ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes); | 281 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; |
280 | 282 | ||
281 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + | 283 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP || |
282 | le32_to_cpu(header->ucode_array_offset_bytes)), | 284 | (ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1 && |
283 | ucode->ucode_size); | 285 | ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2 && |
286 | ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1_JT && | ||
287 | ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT)) { | ||
288 | ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes); | ||
289 | |||
290 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + | ||
291 | le32_to_cpu(header->ucode_array_offset_bytes)), | ||
292 | ucode->ucode_size); | ||
293 | } else if (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC1 || | ||
294 | ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2) { | ||
295 | ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) - | ||
296 | le32_to_cpu(cp_hdr->jt_size) * 4; | ||
297 | |||
298 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + | ||
299 | le32_to_cpu(header->ucode_array_offset_bytes)), | ||
300 | ucode->ucode_size); | ||
301 | } else if (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC1_JT || | ||
302 | ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2_JT) { | ||
303 | ucode->ucode_size = le32_to_cpu(cp_hdr->jt_size) * 4; | ||
304 | |||
305 | memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + | ||
306 | le32_to_cpu(header->ucode_array_offset_bytes) + | ||
307 | le32_to_cpu(cp_hdr->jt_offset) * 4), | ||
308 | ucode->ucode_size); | ||
309 | } | ||
284 | 310 | ||
285 | return 0; | 311 | return 0; |
286 | } | 312 | } |
@@ -306,17 +332,18 @@ static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode, | |||
306 | (le32_to_cpu(header->jt_offset) * 4); | 332 | (le32_to_cpu(header->jt_offset) * 4); |
307 | memcpy(dst_addr, src_addr, le32_to_cpu(header->jt_size) * 4); | 333 | memcpy(dst_addr, src_addr, le32_to_cpu(header->jt_size) * 4); |
308 | 334 | ||
335 | ucode->ucode_size += le32_to_cpu(header->jt_size) * 4; | ||
336 | |||
309 | return 0; | 337 | return 0; |
310 | } | 338 | } |
311 | 339 | ||
312 | |||
313 | int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | 340 | int amdgpu_ucode_init_bo(struct amdgpu_device *adev) |
314 | { | 341 | { |
315 | struct amdgpu_bo **bo = &adev->firmware.fw_buf; | 342 | struct amdgpu_bo **bo = &adev->firmware.fw_buf; |
316 | uint64_t fw_mc_addr; | 343 | uint64_t fw_mc_addr; |
317 | void *fw_buf_ptr = NULL; | 344 | void *fw_buf_ptr = NULL; |
318 | uint64_t fw_offset = 0; | 345 | uint64_t fw_offset = 0; |
319 | int i, err, max; | 346 | int i, err; |
320 | struct amdgpu_firmware_info *ucode = NULL; | 347 | struct amdgpu_firmware_info *ucode = NULL; |
321 | const struct common_firmware_header *header = NULL; | 348 | const struct common_firmware_header *header = NULL; |
322 | 349 | ||
@@ -349,29 +376,32 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | |||
349 | 376 | ||
350 | amdgpu_bo_unreserve(*bo); | 377 | amdgpu_bo_unreserve(*bo); |
351 | 378 | ||
379 | memset(fw_buf_ptr, 0, adev->firmware.fw_size); | ||
380 | |||
352 | /* | 381 | /* |
353 | * if SMU loaded firmware, it needn't add SMC, UVD, and VCE | 382 | * if SMU loaded firmware, it needn't add SMC, UVD, and VCE |
354 | * ucode info here | 383 | * ucode info here |
355 | */ | 384 | */ |
356 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) | 385 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) |
357 | max = AMDGPU_UCODE_ID_MAXIMUM - 3; | 386 | adev->firmware.max_ucodes = AMDGPU_UCODE_ID_MAXIMUM - 4; |
358 | else | 387 | else |
359 | max = AMDGPU_UCODE_ID_MAXIMUM; | 388 | adev->firmware.max_ucodes = AMDGPU_UCODE_ID_MAXIMUM; |
360 | 389 | ||
361 | for (i = 0; i < max; i++) { | 390 | for (i = 0; i < adev->firmware.max_ucodes; i++) { |
362 | ucode = &adev->firmware.ucode[i]; | 391 | ucode = &adev->firmware.ucode[i]; |
363 | if (ucode->fw) { | 392 | if (ucode->fw) { |
364 | header = (const struct common_firmware_header *)ucode->fw->data; | 393 | header = (const struct common_firmware_header *)ucode->fw->data; |
365 | amdgpu_ucode_init_single_fw(ucode, fw_mc_addr + fw_offset, | 394 | amdgpu_ucode_init_single_fw(adev, ucode, fw_mc_addr + fw_offset, |
366 | fw_buf_ptr + fw_offset); | 395 | (void *)((uint8_t *)fw_buf_ptr + fw_offset)); |
367 | if (i == AMDGPU_UCODE_ID_CP_MEC1) { | 396 | if (i == AMDGPU_UCODE_ID_CP_MEC1 && |
397 | adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { | ||
368 | const struct gfx_firmware_header_v1_0 *cp_hdr; | 398 | const struct gfx_firmware_header_v1_0 *cp_hdr; |
369 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; | 399 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; |
370 | amdgpu_ucode_patch_jt(ucode, fw_mc_addr + fw_offset, | 400 | amdgpu_ucode_patch_jt(ucode, fw_mc_addr + fw_offset, |
371 | fw_buf_ptr + fw_offset); | 401 | fw_buf_ptr + fw_offset); |
372 | fw_offset += ALIGN(le32_to_cpu(cp_hdr->jt_size) << 2, PAGE_SIZE); | 402 | fw_offset += ALIGN(le32_to_cpu(cp_hdr->jt_size) << 2, PAGE_SIZE); |
373 | } | 403 | } |
374 | fw_offset += ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE); | 404 | fw_offset += ALIGN(ucode->ucode_size, PAGE_SIZE); |
375 | } | 405 | } |
376 | } | 406 | } |
377 | return 0; | 407 | return 0; |
@@ -393,14 +423,8 @@ int amdgpu_ucode_fini_bo(struct amdgpu_device *adev) | |||
393 | { | 423 | { |
394 | int i; | 424 | int i; |
395 | struct amdgpu_firmware_info *ucode = NULL; | 425 | struct amdgpu_firmware_info *ucode = NULL; |
396 | int max; | ||
397 | |||
398 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) | ||
399 | max = AMDGPU_UCODE_ID_MAXIMUM - 3; | ||
400 | else | ||
401 | max = AMDGPU_UCODE_ID_MAXIMUM; | ||
402 | 426 | ||
403 | for (i = 0; i < max; i++) { | 427 | for (i = 0; i < adev->firmware.max_ucodes; i++) { |
404 | ucode = &adev->firmware.ucode[i]; | 428 | ucode = &adev->firmware.ucode[i]; |
405 | if (ucode->fw) { | 429 | if (ucode->fw) { |
406 | ucode->mc_addr = 0; | 430 | ucode->mc_addr = 0; |