aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
diff options
context:
space:
mode:
authorHuang Rui <ray.huang@amd.com>2017-03-03 16:20:35 -0500
committerAlex Deucher <alexander.deucher@amd.com>2017-03-29 23:54:40 -0400
commit2445b22751a0c039c2d1f35412e45350e847855d (patch)
treebd9621cccaaf47882076e13e7bfe6f745e670d7b /drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
parent9079ac7666c23fecc0b59d136efd349fc1038ba6 (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.c70
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
263static int amdgpu_ucode_init_single_fw(struct amdgpu_firmware_info *ucode, 263static 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
313int amdgpu_ucode_init_bo(struct amdgpu_device *adev) 340int 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;