diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
42 files changed, 1961 insertions, 891 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index 68e9f584c570..a51c5a960750 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile | |||
@@ -62,11 +62,13 @@ amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ | |||
62 | amdgpu-$(CONFIG_DRM_AMDGPU_SI)+= si.o gmc_v6_0.o gfx_v6_0.o si_ih.o si_dma.o dce_v6_0.o si_dpm.o si_smc.o | 62 | amdgpu-$(CONFIG_DRM_AMDGPU_SI)+= si.o gmc_v6_0.o gfx_v6_0.o si_ih.o si_dma.o dce_v6_0.o si_dpm.o si_smc.o |
63 | 63 | ||
64 | amdgpu-y += \ | 64 | amdgpu-y += \ |
65 | vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o | 65 | vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o \ |
66 | vega20_reg_init.o | ||
66 | 67 | ||
67 | # add DF block | 68 | # add DF block |
68 | amdgpu-y += \ | 69 | amdgpu-y += \ |
69 | df_v1_7.o | 70 | df_v1_7.o \ |
71 | df_v3_6.o | ||
70 | 72 | ||
71 | # add GMC block | 73 | # add GMC block |
72 | amdgpu-y += \ | 74 | amdgpu-y += \ |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 03a2c0be0bf2..a59c07590cee 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1401,6 +1401,8 @@ struct amdgpu_df_funcs { | |||
1401 | bool enable); | 1401 | bool enable); |
1402 | void (*get_clockgating_state)(struct amdgpu_device *adev, | 1402 | void (*get_clockgating_state)(struct amdgpu_device *adev, |
1403 | u32 *flags); | 1403 | u32 *flags); |
1404 | void (*enable_ecc_force_par_wr_rmw)(struct amdgpu_device *adev, | ||
1405 | bool enable); | ||
1404 | }; | 1406 | }; |
1405 | /* Define the HW IP blocks will be used in driver , add more if necessary */ | 1407 | /* Define the HW IP blocks will be used in driver , add more if necessary */ |
1406 | enum amd_hw_ip_block_type { | 1408 | enum amd_hw_ip_block_type { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c index a0f48cb9b8f0..236915849cfe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | |||
@@ -322,3 +322,47 @@ int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev) | |||
322 | 322 | ||
323 | return ret; | 323 | return ret; |
324 | } | 324 | } |
325 | |||
326 | union gfx_info { | ||
327 | struct atom_gfx_info_v2_4 v24; | ||
328 | }; | ||
329 | |||
330 | int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev) | ||
331 | { | ||
332 | struct amdgpu_mode_info *mode_info = &adev->mode_info; | ||
333 | int index; | ||
334 | uint8_t frev, crev; | ||
335 | uint16_t data_offset; | ||
336 | |||
337 | index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, | ||
338 | gfx_info); | ||
339 | if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL, | ||
340 | &frev, &crev, &data_offset)) { | ||
341 | union gfx_info *gfx_info = (union gfx_info *) | ||
342 | (mode_info->atom_context->bios + data_offset); | ||
343 | switch (crev) { | ||
344 | case 4: | ||
345 | adev->gfx.config.max_shader_engines = gfx_info->v24.gc_num_se; | ||
346 | adev->gfx.config.max_cu_per_sh = gfx_info->v24.gc_num_cu_per_sh; | ||
347 | adev->gfx.config.max_sh_per_se = gfx_info->v24.gc_num_sh_per_se; | ||
348 | adev->gfx.config.max_backends_per_se = gfx_info->v24.gc_num_rb_per_se; | ||
349 | adev->gfx.config.max_texture_channel_caches = gfx_info->v24.gc_num_tccs; | ||
350 | adev->gfx.config.max_gprs = le16_to_cpu(gfx_info->v24.gc_num_gprs); | ||
351 | adev->gfx.config.max_gs_threads = gfx_info->v24.gc_num_max_gs_thds; | ||
352 | adev->gfx.config.gs_vgt_table_depth = gfx_info->v24.gc_gs_table_depth; | ||
353 | adev->gfx.config.gs_prim_buffer_depth = | ||
354 | le16_to_cpu(gfx_info->v24.gc_gsprim_buff_depth); | ||
355 | adev->gfx.config.double_offchip_lds_buf = | ||
356 | gfx_info->v24.gc_double_offchip_lds_buffer; | ||
357 | adev->gfx.cu_info.wave_front_size = le16_to_cpu(gfx_info->v24.gc_wave_size); | ||
358 | adev->gfx.cu_info.max_waves_per_simd = le16_to_cpu(gfx_info->v24.gc_max_waves_per_simd); | ||
359 | adev->gfx.cu_info.max_scratch_slots_per_cu = gfx_info->v24.gc_max_scratch_slots_per_cu; | ||
360 | adev->gfx.cu_info.lds_size = le16_to_cpu(gfx_info->v24.gc_lds_size); | ||
361 | return 0; | ||
362 | default: | ||
363 | return -EINVAL; | ||
364 | } | ||
365 | |||
366 | } | ||
367 | return -EINVAL; | ||
368 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h index 7689c961c4ef..20f158fd3b76 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h | |||
@@ -30,5 +30,6 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev); | |||
30 | int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev); | 30 | int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev); |
31 | int amdgpu_atomfirmware_get_vram_type(struct amdgpu_device *adev); | 31 | int amdgpu_atomfirmware_get_vram_type(struct amdgpu_device *adev); |
32 | int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev); | 32 | int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev); |
33 | int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev); | ||
33 | 34 | ||
34 | #endif | 35 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 5b3d3bf5b599..e950730f1933 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | |||
@@ -400,6 +400,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, | |||
400 | case CHIP_VEGA12: | 400 | case CHIP_VEGA12: |
401 | strcpy(fw_name, "amdgpu/vega12_smc.bin"); | 401 | strcpy(fw_name, "amdgpu/vega12_smc.bin"); |
402 | break; | 402 | break; |
403 | case CHIP_VEGA20: | ||
404 | strcpy(fw_name, "amdgpu/vega20_smc.bin"); | ||
405 | break; | ||
403 | default: | 406 | default: |
404 | DRM_ERROR("SMC firmware not supported\n"); | 407 | DRM_ERROR("SMC firmware not supported\n"); |
405 | return -EINVAL; | 408 | return -EINVAL; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index a8e531d604fa..c5bb36275e93 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | |||
@@ -173,9 +173,14 @@ static void amdgpu_ctx_do_release(struct kref *ref) | |||
173 | 173 | ||
174 | ctx = container_of(ref, struct amdgpu_ctx, refcount); | 174 | ctx = container_of(ref, struct amdgpu_ctx, refcount); |
175 | 175 | ||
176 | for (i = 0; i < ctx->adev->num_rings; i++) | 176 | for (i = 0; i < ctx->adev->num_rings; i++) { |
177 | |||
178 | if (ctx->adev->rings[i] == &ctx->adev->gfx.kiq.ring) | ||
179 | continue; | ||
180 | |||
177 | drm_sched_entity_fini(&ctx->adev->rings[i]->sched, | 181 | drm_sched_entity_fini(&ctx->adev->rings[i]->sched, |
178 | &ctx->rings[i].entity); | 182 | &ctx->rings[i].entity); |
183 | } | ||
179 | 184 | ||
180 | amdgpu_ctx_fini(ref); | 185 | amdgpu_ctx_fini(ref); |
181 | } | 186 | } |
@@ -452,12 +457,17 @@ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr) | |||
452 | if (!ctx->adev) | 457 | if (!ctx->adev) |
453 | return; | 458 | return; |
454 | 459 | ||
455 | for (i = 0; i < ctx->adev->num_rings; i++) | 460 | for (i = 0; i < ctx->adev->num_rings; i++) { |
461 | |||
462 | if (ctx->adev->rings[i] == &ctx->adev->gfx.kiq.ring) | ||
463 | continue; | ||
464 | |||
456 | if (kref_read(&ctx->refcount) == 1) | 465 | if (kref_read(&ctx->refcount) == 1) |
457 | drm_sched_entity_do_release(&ctx->adev->rings[i]->sched, | 466 | drm_sched_entity_do_release(&ctx->adev->rings[i]->sched, |
458 | &ctx->rings[i].entity); | 467 | &ctx->rings[i].entity); |
459 | else | 468 | else |
460 | DRM_ERROR("ctx %p is still alive\n", ctx); | 469 | DRM_ERROR("ctx %p is still alive\n", ctx); |
470 | } | ||
461 | } | 471 | } |
462 | } | 472 | } |
463 | 473 | ||
@@ -474,12 +484,17 @@ void amdgpu_ctx_mgr_entity_cleanup(struct amdgpu_ctx_mgr *mgr) | |||
474 | if (!ctx->adev) | 484 | if (!ctx->adev) |
475 | return; | 485 | return; |
476 | 486 | ||
477 | for (i = 0; i < ctx->adev->num_rings; i++) | 487 | for (i = 0; i < ctx->adev->num_rings; i++) { |
488 | |||
489 | if (ctx->adev->rings[i] == &ctx->adev->gfx.kiq.ring) | ||
490 | continue; | ||
491 | |||
478 | if (kref_read(&ctx->refcount) == 1) | 492 | if (kref_read(&ctx->refcount) == 1) |
479 | drm_sched_entity_cleanup(&ctx->adev->rings[i]->sched, | 493 | drm_sched_entity_cleanup(&ctx->adev->rings[i]->sched, |
480 | &ctx->rings[i].entity); | 494 | &ctx->rings[i].entity); |
481 | else | 495 | else |
482 | DRM_ERROR("ctx %p is still alive\n", ctx); | 496 | DRM_ERROR("ctx %p is still alive\n", ctx); |
497 | } | ||
483 | } | 498 | } |
484 | } | 499 | } |
485 | 500 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 9fb20a53d5b2..290e279abf0d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -86,6 +86,7 @@ static const char *amdgpu_asic_name[] = { | |||
86 | "VEGAM", | 86 | "VEGAM", |
87 | "VEGA10", | 87 | "VEGA10", |
88 | "VEGA12", | 88 | "VEGA12", |
89 | "VEGA20", | ||
89 | "RAVEN", | 90 | "RAVEN", |
90 | "LAST", | 91 | "LAST", |
91 | }; | 92 | }; |
@@ -1387,6 +1388,7 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) | |||
1387 | case CHIP_KABINI: | 1388 | case CHIP_KABINI: |
1388 | case CHIP_MULLINS: | 1389 | case CHIP_MULLINS: |
1389 | #endif | 1390 | #endif |
1391 | case CHIP_VEGA20: | ||
1390 | default: | 1392 | default: |
1391 | return 0; | 1393 | return 0; |
1392 | case CHIP_VEGA10: | 1394 | case CHIP_VEGA10: |
@@ -1521,6 +1523,7 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev) | |||
1521 | #endif | 1523 | #endif |
1522 | case CHIP_VEGA10: | 1524 | case CHIP_VEGA10: |
1523 | case CHIP_VEGA12: | 1525 | case CHIP_VEGA12: |
1526 | case CHIP_VEGA20: | ||
1524 | case CHIP_RAVEN: | 1527 | case CHIP_RAVEN: |
1525 | if (adev->asic_type == CHIP_RAVEN) | 1528 | if (adev->asic_type == CHIP_RAVEN) |
1526 | adev->family = AMDGPU_FAMILY_RV; | 1529 | adev->family = AMDGPU_FAMILY_RV; |
@@ -1715,6 +1718,7 @@ static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev) | |||
1715 | /* skip CG for VCE/UVD, it's handled specially */ | 1718 | /* skip CG for VCE/UVD, it's handled specially */ |
1716 | if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && | 1719 | if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && |
1717 | adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE && | 1720 | adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE && |
1721 | adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCN && | ||
1718 | adev->ip_blocks[i].version->funcs->set_clockgating_state) { | 1722 | adev->ip_blocks[i].version->funcs->set_clockgating_state) { |
1719 | /* enable clockgating to save power */ | 1723 | /* enable clockgating to save power */ |
1720 | r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev, | 1724 | r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev, |
@@ -1814,6 +1818,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) | |||
1814 | 1818 | ||
1815 | if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && | 1819 | if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && |
1816 | adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE && | 1820 | adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE && |
1821 | adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCN && | ||
1817 | adev->ip_blocks[i].version->funcs->set_clockgating_state) { | 1822 | adev->ip_blocks[i].version->funcs->set_clockgating_state) { |
1818 | /* ungate blocks before hw fini so that we can shutdown the blocks safely */ | 1823 | /* ungate blocks before hw fini so that we can shutdown the blocks safely */ |
1819 | r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev, | 1824 | r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev, |
@@ -2155,6 +2160,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) | |||
2155 | case CHIP_FIJI: | 2160 | case CHIP_FIJI: |
2156 | case CHIP_VEGA10: | 2161 | case CHIP_VEGA10: |
2157 | case CHIP_VEGA12: | 2162 | case CHIP_VEGA12: |
2163 | case CHIP_VEGA20: | ||
2158 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) | 2164 | #if defined(CONFIG_DRM_AMD_DC_DCN1_0) |
2159 | case CHIP_RAVEN: | 2165 | case CHIP_RAVEN: |
2160 | #endif | 2166 | #endif |
@@ -3172,7 +3178,6 @@ error: | |||
3172 | int amdgpu_device_gpu_recover(struct amdgpu_device *adev, | 3178 | int amdgpu_device_gpu_recover(struct amdgpu_device *adev, |
3173 | struct amdgpu_job *job, bool force) | 3179 | struct amdgpu_job *job, bool force) |
3174 | { | 3180 | { |
3175 | struct drm_atomic_state *state = NULL; | ||
3176 | int i, r, resched; | 3181 | int i, r, resched; |
3177 | 3182 | ||
3178 | if (!force && !amdgpu_device_ip_check_soft_reset(adev)) { | 3183 | if (!force && !amdgpu_device_ip_check_soft_reset(adev)) { |
@@ -3195,10 +3200,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, | |||
3195 | /* block TTM */ | 3200 | /* block TTM */ |
3196 | resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); | 3201 | resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); |
3197 | 3202 | ||
3198 | /* store modesetting */ | ||
3199 | if (amdgpu_device_has_dc_support(adev)) | ||
3200 | state = drm_atomic_helper_suspend(adev->ddev); | ||
3201 | |||
3202 | /* block all schedulers and reset given job's ring */ | 3203 | /* block all schedulers and reset given job's ring */ |
3203 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 3204 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
3204 | struct amdgpu_ring *ring = adev->rings[i]; | 3205 | struct amdgpu_ring *ring = adev->rings[i]; |
@@ -3238,10 +3239,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, | |||
3238 | kthread_unpark(ring->sched.thread); | 3239 | kthread_unpark(ring->sched.thread); |
3239 | } | 3240 | } |
3240 | 3241 | ||
3241 | if (amdgpu_device_has_dc_support(adev)) { | 3242 | if (!amdgpu_device_has_dc_support(adev)) { |
3242 | if (drm_atomic_helper_resume(adev->ddev, state)) | ||
3243 | dev_info(adev->dev, "drm resume failed:%d\n", r); | ||
3244 | } else { | ||
3245 | drm_helper_resume_force_mode(adev->ddev); | 3243 | drm_helper_resume_force_mode(adev->ddev); |
3246 | } | 3244 | } |
3247 | 3245 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 739e7e09c8b0..b0bf2f24da48 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | |||
@@ -560,6 +560,13 @@ static const struct pci_device_id pciidlist[] = { | |||
560 | {0x1002, 0x69A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12}, | 560 | {0x1002, 0x69A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12}, |
561 | {0x1002, 0x69A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12}, | 561 | {0x1002, 0x69A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12}, |
562 | {0x1002, 0x69AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12}, | 562 | {0x1002, 0x69AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12}, |
563 | /* Vega 20 */ | ||
564 | {0x1002, 0x66A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20|AMD_EXP_HW_SUPPORT}, | ||
565 | {0x1002, 0x66A1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20|AMD_EXP_HW_SUPPORT}, | ||
566 | {0x1002, 0x66A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20|AMD_EXP_HW_SUPPORT}, | ||
567 | {0x1002, 0x66A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20|AMD_EXP_HW_SUPPORT}, | ||
568 | {0x1002, 0x66A7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20|AMD_EXP_HW_SUPPORT}, | ||
569 | {0x1002, 0x66AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20|AMD_EXP_HW_SUPPORT}, | ||
563 | /* Raven */ | 570 | /* Raven */ |
564 | {0x1002, 0x15dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RAVEN|AMD_IS_APU}, | 571 | {0x1002, 0x15dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RAVEN|AMD_IS_APU}, |
565 | 572 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index d09fcab2398f..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.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.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.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 eb4785e51573..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.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.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_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index c7d43e064fc7..9f1a5bd39ae8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | |||
@@ -52,6 +52,7 @@ static int psp_sw_init(void *handle) | |||
52 | switch (adev->asic_type) { | 52 | switch (adev->asic_type) { |
53 | case CHIP_VEGA10: | 53 | case CHIP_VEGA10: |
54 | case CHIP_VEGA12: | 54 | case CHIP_VEGA12: |
55 | case CHIP_VEGA20: | ||
55 | psp_v3_1_set_psp_funcs(psp); | 56 | psp_v3_1_set_psp_funcs(psp); |
56 | break; | 57 | break; |
57 | case CHIP_RAVEN: | 58 | case CHIP_RAVEN: |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c index 262c1267249e..8af16e81c7d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c | |||
@@ -66,6 +66,8 @@ static int amdgpu_identity_map(struct amdgpu_device *adev, | |||
66 | u32 ring, | 66 | u32 ring, |
67 | struct amdgpu_ring **out_ring) | 67 | struct amdgpu_ring **out_ring) |
68 | { | 68 | { |
69 | u32 instance; | ||
70 | |||
69 | switch (mapper->hw_ip) { | 71 | switch (mapper->hw_ip) { |
70 | case AMDGPU_HW_IP_GFX: | 72 | case AMDGPU_HW_IP_GFX: |
71 | *out_ring = &adev->gfx.gfx_ring[ring]; | 73 | *out_ring = &adev->gfx.gfx_ring[ring]; |
@@ -77,13 +79,16 @@ static int amdgpu_identity_map(struct amdgpu_device *adev, | |||
77 | *out_ring = &adev->sdma.instance[ring].ring; | 79 | *out_ring = &adev->sdma.instance[ring].ring; |
78 | break; | 80 | break; |
79 | case AMDGPU_HW_IP_UVD: | 81 | case AMDGPU_HW_IP_UVD: |
80 | *out_ring = &adev->uvd.ring; | 82 | instance = ring; |
83 | *out_ring = &adev->uvd.inst[instance].ring; | ||
81 | break; | 84 | break; |
82 | case AMDGPU_HW_IP_VCE: | 85 | case AMDGPU_HW_IP_VCE: |
83 | *out_ring = &adev->vce.ring[ring]; | 86 | *out_ring = &adev->vce.ring[ring]; |
84 | break; | 87 | break; |
85 | case AMDGPU_HW_IP_UVD_ENC: | 88 | case AMDGPU_HW_IP_UVD_ENC: |
86 | *out_ring = &adev->uvd.ring_enc[ring]; | 89 | instance = ring / adev->uvd.num_enc_rings; |
90 | *out_ring = | ||
91 | &adev->uvd.inst[instance].ring_enc[ring%adev->uvd.num_enc_rings]; | ||
87 | break; | 92 | break; |
88 | case AMDGPU_HW_IP_VCN_DEC: | 93 | case AMDGPU_HW_IP_VCN_DEC: |
89 | *out_ring = &adev->vcn.ring_dec; | 94 | *out_ring = &adev->vcn.ring_dec; |
@@ -240,13 +245,14 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev, | |||
240 | ip_num_rings = adev->sdma.num_instances; | 245 | ip_num_rings = adev->sdma.num_instances; |
241 | break; | 246 | break; |
242 | case AMDGPU_HW_IP_UVD: | 247 | case AMDGPU_HW_IP_UVD: |
243 | ip_num_rings = 1; | 248 | ip_num_rings = adev->uvd.num_uvd_inst; |
244 | break; | 249 | break; |
245 | case AMDGPU_HW_IP_VCE: | 250 | case AMDGPU_HW_IP_VCE: |
246 | ip_num_rings = adev->vce.num_rings; | 251 | ip_num_rings = adev->vce.num_rings; |
247 | break; | 252 | break; |
248 | case AMDGPU_HW_IP_UVD_ENC: | 253 | case AMDGPU_HW_IP_UVD_ENC: |
249 | ip_num_rings = adev->uvd.num_enc_rings; | 254 | ip_num_rings = |
255 | adev->uvd.num_enc_rings * adev->uvd.num_uvd_inst; | ||
250 | break; | 256 | break; |
251 | case AMDGPU_HW_IP_VCN_DEC: | 257 | case AMDGPU_HW_IP_VCN_DEC: |
252 | ip_num_rings = 1; | 258 | ip_num_rings = 1; |
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_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 4f8dac2d36a5..1513124c5659 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <drm/drm_print.h> | 29 | #include <drm/drm_print.h> |
30 | 30 | ||
31 | /* max number of rings */ | 31 | /* max number of rings */ |
32 | #define AMDGPU_MAX_RINGS 18 | 32 | #define AMDGPU_MAX_RINGS 21 |
33 | #define AMDGPU_MAX_GFX_RINGS 1 | 33 | #define AMDGPU_MAX_GFX_RINGS 1 |
34 | #define AMDGPU_MAX_COMPUTE_RINGS 8 | 34 | #define AMDGPU_MAX_COMPUTE_RINGS 8 |
35 | #define AMDGPU_MAX_VCE_RINGS 3 | 35 | #define AMDGPU_MAX_VCE_RINGS 3 |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 69a2b25b3696..e93a0a237dc3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | |||
@@ -63,16 +63,44 @@ static void amdgpu_ttm_debugfs_fini(struct amdgpu_device *adev); | |||
63 | /* | 63 | /* |
64 | * Global memory. | 64 | * Global memory. |
65 | */ | 65 | */ |
66 | |||
67 | /** | ||
68 | * amdgpu_ttm_mem_global_init - Initialize and acquire reference to | ||
69 | * memory object | ||
70 | * | ||
71 | * @ref: Object for initialization. | ||
72 | * | ||
73 | * This is called by drm_global_item_ref() when an object is being | ||
74 | * initialized. | ||
75 | */ | ||
66 | static int amdgpu_ttm_mem_global_init(struct drm_global_reference *ref) | 76 | static int amdgpu_ttm_mem_global_init(struct drm_global_reference *ref) |
67 | { | 77 | { |
68 | return ttm_mem_global_init(ref->object); | 78 | return ttm_mem_global_init(ref->object); |
69 | } | 79 | } |
70 | 80 | ||
81 | /** | ||
82 | * amdgpu_ttm_mem_global_release - Drop reference to a memory object | ||
83 | * | ||
84 | * @ref: Object being removed | ||
85 | * | ||
86 | * This is called by drm_global_item_unref() when an object is being | ||
87 | * released. | ||
88 | */ | ||
71 | static void amdgpu_ttm_mem_global_release(struct drm_global_reference *ref) | 89 | static void amdgpu_ttm_mem_global_release(struct drm_global_reference *ref) |
72 | { | 90 | { |
73 | ttm_mem_global_release(ref->object); | 91 | ttm_mem_global_release(ref->object); |
74 | } | 92 | } |
75 | 93 | ||
94 | /** | ||
95 | * amdgpu_ttm_global_init - Initialize global TTM memory reference | ||
96 | * structures. | ||
97 | * | ||
98 | * @adev: AMDGPU device for which the global structures need to be | ||
99 | * registered. | ||
100 | * | ||
101 | * This is called as part of the AMDGPU ttm init from amdgpu_ttm_init() | ||
102 | * during bring up. | ||
103 | */ | ||
76 | static int amdgpu_ttm_global_init(struct amdgpu_device *adev) | 104 | static int amdgpu_ttm_global_init(struct amdgpu_device *adev) |
77 | { | 105 | { |
78 | struct drm_global_reference *global_ref; | 106 | struct drm_global_reference *global_ref; |
@@ -80,7 +108,9 @@ static int amdgpu_ttm_global_init(struct amdgpu_device *adev) | |||
80 | struct drm_sched_rq *rq; | 108 | struct drm_sched_rq *rq; |
81 | int r; | 109 | int r; |
82 | 110 | ||
111 | /* ensure reference is false in case init fails */ | ||
83 | adev->mman.mem_global_referenced = false; | 112 | adev->mman.mem_global_referenced = false; |
113 | |||
84 | global_ref = &adev->mman.mem_global_ref; | 114 | global_ref = &adev->mman.mem_global_ref; |
85 | global_ref->global_type = DRM_GLOBAL_TTM_MEM; | 115 | global_ref->global_type = DRM_GLOBAL_TTM_MEM; |
86 | global_ref->size = sizeof(struct ttm_mem_global); | 116 | global_ref->size = sizeof(struct ttm_mem_global); |
@@ -146,6 +176,18 @@ static int amdgpu_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags) | |||
146 | return 0; | 176 | return 0; |
147 | } | 177 | } |
148 | 178 | ||
179 | /** | ||
180 | * amdgpu_init_mem_type - Initialize a memory manager for a specific | ||
181 | * type of memory request. | ||
182 | * | ||
183 | * @bdev: The TTM BO device object (contains a reference to | ||
184 | * amdgpu_device) | ||
185 | * @type: The type of memory requested | ||
186 | * @man: | ||
187 | * | ||
188 | * This is called by ttm_bo_init_mm() when a buffer object is being | ||
189 | * initialized. | ||
190 | */ | ||
149 | static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | 191 | static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, |
150 | struct ttm_mem_type_manager *man) | 192 | struct ttm_mem_type_manager *man) |
151 | { | 193 | { |
@@ -161,6 +203,7 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
161 | man->default_caching = TTM_PL_FLAG_CACHED; | 203 | man->default_caching = TTM_PL_FLAG_CACHED; |
162 | break; | 204 | break; |
163 | case TTM_PL_TT: | 205 | case TTM_PL_TT: |
206 | /* GTT memory */ | ||
164 | man->func = &amdgpu_gtt_mgr_func; | 207 | man->func = &amdgpu_gtt_mgr_func; |
165 | man->gpu_offset = adev->gmc.gart_start; | 208 | man->gpu_offset = adev->gmc.gart_start; |
166 | man->available_caching = TTM_PL_MASK_CACHING; | 209 | man->available_caching = TTM_PL_MASK_CACHING; |
@@ -193,6 +236,14 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
193 | return 0; | 236 | return 0; |
194 | } | 237 | } |
195 | 238 | ||
239 | /** | ||
240 | * amdgpu_evict_flags - Compute placement flags | ||
241 | * | ||
242 | * @bo: The buffer object to evict | ||
243 | * @placement: Possible destination(s) for evicted BO | ||
244 | * | ||
245 | * Fill in placement data when ttm_bo_evict() is called | ||
246 | */ | ||
196 | static void amdgpu_evict_flags(struct ttm_buffer_object *bo, | 247 | static void amdgpu_evict_flags(struct ttm_buffer_object *bo, |
197 | struct ttm_placement *placement) | 248 | struct ttm_placement *placement) |
198 | { | 249 | { |
@@ -204,12 +255,14 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, | |||
204 | .flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM | 255 | .flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM |
205 | }; | 256 | }; |
206 | 257 | ||
258 | /* Don't handle scatter gather BOs */ | ||
207 | if (bo->type == ttm_bo_type_sg) { | 259 | if (bo->type == ttm_bo_type_sg) { |
208 | placement->num_placement = 0; | 260 | placement->num_placement = 0; |
209 | placement->num_busy_placement = 0; | 261 | placement->num_busy_placement = 0; |
210 | return; | 262 | return; |
211 | } | 263 | } |
212 | 264 | ||
265 | /* Object isn't an AMDGPU object so ignore */ | ||
213 | if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) { | 266 | if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) { |
214 | placement->placement = &placements; | 267 | placement->placement = &placements; |
215 | placement->busy_placement = &placements; | 268 | placement->busy_placement = &placements; |
@@ -217,10 +270,12 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, | |||
217 | placement->num_busy_placement = 1; | 270 | placement->num_busy_placement = 1; |
218 | return; | 271 | return; |
219 | } | 272 | } |
273 | |||
220 | abo = ttm_to_amdgpu_bo(bo); | 274 | abo = ttm_to_amdgpu_bo(bo); |
221 | switch (bo->mem.mem_type) { | 275 | switch (bo->mem.mem_type) { |
222 | case TTM_PL_VRAM: | 276 | case TTM_PL_VRAM: |
223 | if (!adev->mman.buffer_funcs_enabled) { | 277 | if (!adev->mman.buffer_funcs_enabled) { |
278 | /* Move to system memory */ | ||
224 | amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_CPU); | 279 | amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_CPU); |
225 | } else if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size && | 280 | } else if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size && |
226 | !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) && | 281 | !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) && |
@@ -238,6 +293,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, | |||
238 | abo->placement.busy_placement = &abo->placements[1]; | 293 | abo->placement.busy_placement = &abo->placements[1]; |
239 | abo->placement.num_busy_placement = 1; | 294 | abo->placement.num_busy_placement = 1; |
240 | } else { | 295 | } else { |
296 | /* Move to GTT memory */ | ||
241 | amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT); | 297 | amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT); |
242 | } | 298 | } |
243 | break; | 299 | break; |
@@ -248,6 +304,15 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, | |||
248 | *placement = abo->placement; | 304 | *placement = abo->placement; |
249 | } | 305 | } |
250 | 306 | ||
307 | /** | ||
308 | * amdgpu_verify_access - Verify access for a mmap call | ||
309 | * | ||
310 | * @bo: The buffer object to map | ||
311 | * @filp: The file pointer from the process performing the mmap | ||
312 | * | ||
313 | * This is called by ttm_bo_mmap() to verify whether a process | ||
314 | * has the right to mmap a BO to their process space. | ||
315 | */ | ||
251 | static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp) | 316 | static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp) |
252 | { | 317 | { |
253 | struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo); | 318 | struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo); |
@@ -265,6 +330,15 @@ static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp) | |||
265 | filp->private_data); | 330 | filp->private_data); |
266 | } | 331 | } |
267 | 332 | ||
333 | /** | ||
334 | * amdgpu_move_null - Register memory for a buffer object | ||
335 | * | ||
336 | * @bo: The bo to assign the memory to | ||
337 | * @new_mem: The memory to be assigned. | ||
338 | * | ||
339 | * Assign the memory from new_mem to the memory of the buffer object | ||
340 | * bo. | ||
341 | */ | ||
268 | static void amdgpu_move_null(struct ttm_buffer_object *bo, | 342 | static void amdgpu_move_null(struct ttm_buffer_object *bo, |
269 | struct ttm_mem_reg *new_mem) | 343 | struct ttm_mem_reg *new_mem) |
270 | { | 344 | { |
@@ -275,6 +349,10 @@ static void amdgpu_move_null(struct ttm_buffer_object *bo, | |||
275 | new_mem->mm_node = NULL; | 349 | new_mem->mm_node = NULL; |
276 | } | 350 | } |
277 | 351 | ||
352 | /** | ||
353 | * amdgpu_mm_node_addr - Compute the GPU relative offset of a GTT | ||
354 | * buffer. | ||
355 | */ | ||
278 | static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo, | 356 | static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo, |
279 | struct drm_mm_node *mm_node, | 357 | struct drm_mm_node *mm_node, |
280 | struct ttm_mem_reg *mem) | 358 | struct ttm_mem_reg *mem) |
@@ -289,9 +367,10 @@ static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo, | |||
289 | } | 367 | } |
290 | 368 | ||
291 | /** | 369 | /** |
292 | * amdgpu_find_mm_node - Helper function finds the drm_mm_node | 370 | * amdgpu_find_mm_node - Helper function finds the drm_mm_node |
293 | * corresponding to @offset. It also modifies the offset to be | 371 | * corresponding to @offset. It also modifies |
294 | * within the drm_mm_node returned | 372 | * the offset to be within the drm_mm_node |
373 | * returned | ||
295 | */ | 374 | */ |
296 | static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem, | 375 | static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem, |
297 | unsigned long *offset) | 376 | unsigned long *offset) |
@@ -430,7 +509,12 @@ error: | |||
430 | return r; | 509 | return r; |
431 | } | 510 | } |
432 | 511 | ||
433 | 512 | /** | |
513 | * amdgpu_move_blit - Copy an entire buffer to another buffer | ||
514 | * | ||
515 | * This is a helper called by amdgpu_bo_move() and | ||
516 | * amdgpu_move_vram_ram() to help move buffers to and from VRAM. | ||
517 | */ | ||
434 | static int amdgpu_move_blit(struct ttm_buffer_object *bo, | 518 | static int amdgpu_move_blit(struct ttm_buffer_object *bo, |
435 | bool evict, bool no_wait_gpu, | 519 | bool evict, bool no_wait_gpu, |
436 | struct ttm_mem_reg *new_mem, | 520 | struct ttm_mem_reg *new_mem, |
@@ -465,6 +549,11 @@ error: | |||
465 | return r; | 549 | return r; |
466 | } | 550 | } |
467 | 551 | ||
552 | /** | ||
553 | * amdgpu_move_vram_ram - Copy VRAM buffer to RAM buffer | ||
554 | * | ||
555 | * Called by amdgpu_bo_move(). | ||
556 | */ | ||
468 | static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict, | 557 | static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict, |
469 | struct ttm_operation_ctx *ctx, | 558 | struct ttm_operation_ctx *ctx, |
470 | struct ttm_mem_reg *new_mem) | 559 | struct ttm_mem_reg *new_mem) |
@@ -477,6 +566,8 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict, | |||
477 | int r; | 566 | int r; |
478 | 567 | ||
479 | adev = amdgpu_ttm_adev(bo->bdev); | 568 | adev = amdgpu_ttm_adev(bo->bdev); |
569 | |||
570 | /* create space/pages for new_mem in GTT space */ | ||
480 | tmp_mem = *new_mem; | 571 | tmp_mem = *new_mem; |
481 | tmp_mem.mm_node = NULL; | 572 | tmp_mem.mm_node = NULL; |
482 | placement.num_placement = 1; | 573 | placement.num_placement = 1; |
@@ -491,25 +582,36 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict, | |||
491 | return r; | 582 | return r; |
492 | } | 583 | } |
493 | 584 | ||
585 | /* set caching flags */ | ||
494 | r = ttm_tt_set_placement_caching(bo->ttm, tmp_mem.placement); | 586 | r = ttm_tt_set_placement_caching(bo->ttm, tmp_mem.placement); |
495 | if (unlikely(r)) { | 587 | if (unlikely(r)) { |
496 | goto out_cleanup; | 588 | goto out_cleanup; |
497 | } | 589 | } |
498 | 590 | ||
591 | /* Bind the memory to the GTT space */ | ||
499 | r = ttm_tt_bind(bo->ttm, &tmp_mem, ctx); | 592 | r = ttm_tt_bind(bo->ttm, &tmp_mem, ctx); |
500 | if (unlikely(r)) { | 593 | if (unlikely(r)) { |
501 | goto out_cleanup; | 594 | goto out_cleanup; |
502 | } | 595 | } |
596 | |||
597 | /* blit VRAM to GTT */ | ||
503 | r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, &tmp_mem, old_mem); | 598 | r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, &tmp_mem, old_mem); |
504 | if (unlikely(r)) { | 599 | if (unlikely(r)) { |
505 | goto out_cleanup; | 600 | goto out_cleanup; |
506 | } | 601 | } |
602 | |||
603 | /* move BO (in tmp_mem) to new_mem */ | ||
507 | r = ttm_bo_move_ttm(bo, ctx, new_mem); | 604 | r = ttm_bo_move_ttm(bo, ctx, new_mem); |
508 | out_cleanup: | 605 | out_cleanup: |
509 | ttm_bo_mem_put(bo, &tmp_mem); | 606 | ttm_bo_mem_put(bo, &tmp_mem); |
510 | return r; | 607 | return r; |
511 | } | 608 | } |
512 | 609 | ||
610 | /** | ||
611 | * amdgpu_move_ram_vram - Copy buffer from RAM to VRAM | ||
612 | * | ||
613 | * Called by amdgpu_bo_move(). | ||
614 | */ | ||
513 | static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict, | 615 | static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict, |
514 | struct ttm_operation_ctx *ctx, | 616 | struct ttm_operation_ctx *ctx, |
515 | struct ttm_mem_reg *new_mem) | 617 | struct ttm_mem_reg *new_mem) |
@@ -522,6 +624,8 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict, | |||
522 | int r; | 624 | int r; |
523 | 625 | ||
524 | adev = amdgpu_ttm_adev(bo->bdev); | 626 | adev = amdgpu_ttm_adev(bo->bdev); |
627 | |||
628 | /* make space in GTT for old_mem buffer */ | ||
525 | tmp_mem = *new_mem; | 629 | tmp_mem = *new_mem; |
526 | tmp_mem.mm_node = NULL; | 630 | tmp_mem.mm_node = NULL; |
527 | placement.num_placement = 1; | 631 | placement.num_placement = 1; |
@@ -535,10 +639,14 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict, | |||
535 | if (unlikely(r)) { | 639 | if (unlikely(r)) { |
536 | return r; | 640 | return r; |
537 | } | 641 | } |
642 | |||
643 | /* move/bind old memory to GTT space */ | ||
538 | r = ttm_bo_move_ttm(bo, ctx, &tmp_mem); | 644 | r = ttm_bo_move_ttm(bo, ctx, &tmp_mem); |
539 | if (unlikely(r)) { | 645 | if (unlikely(r)) { |
540 | goto out_cleanup; | 646 | goto out_cleanup; |
541 | } | 647 | } |
648 | |||
649 | /* copy to VRAM */ | ||
542 | r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, new_mem, old_mem); | 650 | r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, new_mem, old_mem); |
543 | if (unlikely(r)) { | 651 | if (unlikely(r)) { |
544 | goto out_cleanup; | 652 | goto out_cleanup; |
@@ -548,6 +656,11 @@ out_cleanup: | |||
548 | return r; | 656 | return r; |
549 | } | 657 | } |
550 | 658 | ||
659 | /** | ||
660 | * amdgpu_bo_move - Move a buffer object to a new memory location | ||
661 | * | ||
662 | * Called by ttm_bo_handle_move_mem() | ||
663 | */ | ||
551 | static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict, | 664 | static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict, |
552 | struct ttm_operation_ctx *ctx, | 665 | struct ttm_operation_ctx *ctx, |
553 | struct ttm_mem_reg *new_mem) | 666 | struct ttm_mem_reg *new_mem) |
@@ -613,6 +726,11 @@ memcpy: | |||
613 | return 0; | 726 | return 0; |
614 | } | 727 | } |
615 | 728 | ||
729 | /** | ||
730 | * amdgpu_ttm_io_mem_reserve - Reserve a block of memory during a fault | ||
731 | * | ||
732 | * Called by ttm_mem_io_reserve() ultimately via ttm_bo_vm_fault() | ||
733 | */ | ||
616 | static int amdgpu_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) | 734 | static int amdgpu_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) |
617 | { | 735 | { |
618 | struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; | 736 | struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; |
@@ -690,6 +808,14 @@ struct amdgpu_ttm_tt { | |||
690 | uint32_t last_set_pages; | 808 | uint32_t last_set_pages; |
691 | }; | 809 | }; |
692 | 810 | ||
811 | /** | ||
812 | * amdgpu_ttm_tt_get_user_pages - Pin pages of memory pointed to | ||
813 | * by a USERPTR pointer to memory | ||
814 | * | ||
815 | * Called by amdgpu_gem_userptr_ioctl() and amdgpu_cs_parser_bos(). | ||
816 | * This provides a wrapper around the get_user_pages() call to provide | ||
817 | * device accessible pages that back user memory. | ||
818 | */ | ||
693 | int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages) | 819 | int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages) |
694 | { | 820 | { |
695 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 821 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
@@ -719,6 +845,7 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages) | |||
719 | } | 845 | } |
720 | } | 846 | } |
721 | 847 | ||
848 | /* loop enough times using contiguous pages of memory */ | ||
722 | do { | 849 | do { |
723 | unsigned num_pages = ttm->num_pages - pinned; | 850 | unsigned num_pages = ttm->num_pages - pinned; |
724 | uint64_t userptr = gtt->userptr + pinned * PAGE_SIZE; | 851 | uint64_t userptr = gtt->userptr + pinned * PAGE_SIZE; |
@@ -757,6 +884,14 @@ release_pages: | |||
757 | return r; | 884 | return r; |
758 | } | 885 | } |
759 | 886 | ||
887 | /** | ||
888 | * amdgpu_ttm_tt_set_user_pages - Copy pages in, putting old pages | ||
889 | * as necessary. | ||
890 | * | ||
891 | * Called by amdgpu_cs_list_validate(). This creates the page list | ||
892 | * that backs user memory and will ultimately be mapped into the device | ||
893 | * address space. | ||
894 | */ | ||
760 | void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages) | 895 | void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages) |
761 | { | 896 | { |
762 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 897 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
@@ -771,6 +906,11 @@ void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages) | |||
771 | } | 906 | } |
772 | } | 907 | } |
773 | 908 | ||
909 | /** | ||
910 | * amdgpu_ttm_tt_mark_user_page - Mark pages as dirty | ||
911 | * | ||
912 | * Called while unpinning userptr pages | ||
913 | */ | ||
774 | void amdgpu_ttm_tt_mark_user_pages(struct ttm_tt *ttm) | 914 | void amdgpu_ttm_tt_mark_user_pages(struct ttm_tt *ttm) |
775 | { | 915 | { |
776 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 916 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
@@ -789,7 +929,12 @@ void amdgpu_ttm_tt_mark_user_pages(struct ttm_tt *ttm) | |||
789 | } | 929 | } |
790 | } | 930 | } |
791 | 931 | ||
792 | /* prepare the sg table with the user pages */ | 932 | /** |
933 | * amdgpu_ttm_tt_pin_userptr - prepare the sg table with the | ||
934 | * user pages | ||
935 | * | ||
936 | * Called by amdgpu_ttm_backend_bind() | ||
937 | **/ | ||
793 | static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) | 938 | static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) |
794 | { | 939 | { |
795 | struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); | 940 | struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); |
@@ -801,17 +946,20 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) | |||
801 | enum dma_data_direction direction = write ? | 946 | enum dma_data_direction direction = write ? |
802 | DMA_BIDIRECTIONAL : DMA_TO_DEVICE; | 947 | DMA_BIDIRECTIONAL : DMA_TO_DEVICE; |
803 | 948 | ||
949 | /* Allocate an SG array and squash pages into it */ | ||
804 | r = sg_alloc_table_from_pages(ttm->sg, ttm->pages, ttm->num_pages, 0, | 950 | r = sg_alloc_table_from_pages(ttm->sg, ttm->pages, ttm->num_pages, 0, |
805 | ttm->num_pages << PAGE_SHIFT, | 951 | ttm->num_pages << PAGE_SHIFT, |
806 | GFP_KERNEL); | 952 | GFP_KERNEL); |
807 | if (r) | 953 | if (r) |
808 | goto release_sg; | 954 | goto release_sg; |
809 | 955 | ||
956 | /* Map SG to device */ | ||
810 | r = -ENOMEM; | 957 | r = -ENOMEM; |
811 | nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction); | 958 | nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction); |
812 | if (nents != ttm->sg->nents) | 959 | if (nents != ttm->sg->nents) |
813 | goto release_sg; | 960 | goto release_sg; |
814 | 961 | ||
962 | /* convert SG to linear array of pages and dma addresses */ | ||
815 | drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, | 963 | drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, |
816 | gtt->ttm.dma_address, ttm->num_pages); | 964 | gtt->ttm.dma_address, ttm->num_pages); |
817 | 965 | ||
@@ -822,6 +970,9 @@ release_sg: | |||
822 | return r; | 970 | return r; |
823 | } | 971 | } |
824 | 972 | ||
973 | /** | ||
974 | * amdgpu_ttm_tt_unpin_userptr - Unpin and unmap userptr pages | ||
975 | */ | ||
825 | static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm) | 976 | static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm) |
826 | { | 977 | { |
827 | struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); | 978 | struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); |
@@ -835,9 +986,10 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm) | |||
835 | if (!ttm->sg->sgl) | 986 | if (!ttm->sg->sgl) |
836 | return; | 987 | return; |
837 | 988 | ||
838 | /* free the sg table and pages again */ | 989 | /* unmap the pages mapped to the device */ |
839 | dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction); | 990 | dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction); |
840 | 991 | ||
992 | /* mark the pages as dirty */ | ||
841 | amdgpu_ttm_tt_mark_user_pages(ttm); | 993 | amdgpu_ttm_tt_mark_user_pages(ttm); |
842 | 994 | ||
843 | sg_free_table(ttm->sg); | 995 | sg_free_table(ttm->sg); |
@@ -882,6 +1034,12 @@ gart_bind_fail: | |||
882 | return r; | 1034 | return r; |
883 | } | 1035 | } |
884 | 1036 | ||
1037 | /** | ||
1038 | * amdgpu_ttm_backend_bind - Bind GTT memory | ||
1039 | * | ||
1040 | * Called by ttm_tt_bind() on behalf of ttm_bo_handle_move_mem(). | ||
1041 | * This handles binding GTT memory to the device address space. | ||
1042 | */ | ||
885 | static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm, | 1043 | static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm, |
886 | struct ttm_mem_reg *bo_mem) | 1044 | struct ttm_mem_reg *bo_mem) |
887 | { | 1045 | { |
@@ -912,7 +1070,10 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm, | |||
912 | return 0; | 1070 | return 0; |
913 | } | 1071 | } |
914 | 1072 | ||
1073 | /* compute PTE flags relevant to this BO memory */ | ||
915 | flags = amdgpu_ttm_tt_pte_flags(adev, ttm, bo_mem); | 1074 | flags = amdgpu_ttm_tt_pte_flags(adev, ttm, bo_mem); |
1075 | |||
1076 | /* bind pages into GART page tables */ | ||
916 | gtt->offset = (u64)bo_mem->start << PAGE_SHIFT; | 1077 | gtt->offset = (u64)bo_mem->start << PAGE_SHIFT; |
917 | r = amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages, | 1078 | r = amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages, |
918 | ttm->pages, gtt->ttm.dma_address, flags); | 1079 | ttm->pages, gtt->ttm.dma_address, flags); |
@@ -923,6 +1084,9 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm, | |||
923 | return r; | 1084 | return r; |
924 | } | 1085 | } |
925 | 1086 | ||
1087 | /** | ||
1088 | * amdgpu_ttm_alloc_gart - Allocate GART memory for buffer object | ||
1089 | */ | ||
926 | int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo) | 1090 | int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo) |
927 | { | 1091 | { |
928 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); | 1092 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); |
@@ -938,6 +1102,7 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo) | |||
938 | amdgpu_gtt_mgr_has_gart_addr(&bo->mem)) | 1102 | amdgpu_gtt_mgr_has_gart_addr(&bo->mem)) |
939 | return 0; | 1103 | return 0; |
940 | 1104 | ||
1105 | /* allocate GTT space */ | ||
941 | tmp = bo->mem; | 1106 | tmp = bo->mem; |
942 | tmp.mm_node = NULL; | 1107 | tmp.mm_node = NULL; |
943 | placement.num_placement = 1; | 1108 | placement.num_placement = 1; |
@@ -953,7 +1118,10 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo) | |||
953 | if (unlikely(r)) | 1118 | if (unlikely(r)) |
954 | return r; | 1119 | return r; |
955 | 1120 | ||
1121 | /* compute PTE flags for this buffer object */ | ||
956 | flags = amdgpu_ttm_tt_pte_flags(adev, bo->ttm, &tmp); | 1122 | flags = amdgpu_ttm_tt_pte_flags(adev, bo->ttm, &tmp); |
1123 | |||
1124 | /* Bind pages */ | ||
957 | gtt->offset = (u64)tmp.start << PAGE_SHIFT; | 1125 | gtt->offset = (u64)tmp.start << PAGE_SHIFT; |
958 | r = amdgpu_ttm_gart_bind(adev, bo, flags); | 1126 | r = amdgpu_ttm_gart_bind(adev, bo, flags); |
959 | if (unlikely(r)) { | 1127 | if (unlikely(r)) { |
@@ -969,6 +1137,12 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo) | |||
969 | return 0; | 1137 | return 0; |
970 | } | 1138 | } |
971 | 1139 | ||
1140 | /** | ||
1141 | * amdgpu_ttm_recover_gart - Rebind GTT pages | ||
1142 | * | ||
1143 | * Called by amdgpu_gtt_mgr_recover() from amdgpu_device_reset() to | ||
1144 | * rebind GTT pages during a GPU reset. | ||
1145 | */ | ||
972 | int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo) | 1146 | int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo) |
973 | { | 1147 | { |
974 | struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev); | 1148 | struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev); |
@@ -984,12 +1158,19 @@ int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo) | |||
984 | return r; | 1158 | return r; |
985 | } | 1159 | } |
986 | 1160 | ||
1161 | /** | ||
1162 | * amdgpu_ttm_backend_unbind - Unbind GTT mapped pages | ||
1163 | * | ||
1164 | * Called by ttm_tt_unbind() on behalf of ttm_bo_move_ttm() and | ||
1165 | * ttm_tt_destroy(). | ||
1166 | */ | ||
987 | static int amdgpu_ttm_backend_unbind(struct ttm_tt *ttm) | 1167 | static int amdgpu_ttm_backend_unbind(struct ttm_tt *ttm) |
988 | { | 1168 | { |
989 | struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); | 1169 | struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); |
990 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 1170 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
991 | int r; | 1171 | int r; |
992 | 1172 | ||
1173 | /* if the pages have userptr pinning then clear that first */ | ||
993 | if (gtt->userptr) | 1174 | if (gtt->userptr) |
994 | amdgpu_ttm_tt_unpin_userptr(ttm); | 1175 | amdgpu_ttm_tt_unpin_userptr(ttm); |
995 | 1176 | ||
@@ -1021,6 +1202,13 @@ static struct ttm_backend_func amdgpu_backend_func = { | |||
1021 | .destroy = &amdgpu_ttm_backend_destroy, | 1202 | .destroy = &amdgpu_ttm_backend_destroy, |
1022 | }; | 1203 | }; |
1023 | 1204 | ||
1205 | /** | ||
1206 | * amdgpu_ttm_tt_create - Create a ttm_tt object for a given BO | ||
1207 | * | ||
1208 | * @bo: The buffer object to create a GTT ttm_tt object around | ||
1209 | * | ||
1210 | * Called by ttm_tt_create(). | ||
1211 | */ | ||
1024 | static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo, | 1212 | static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo, |
1025 | uint32_t page_flags) | 1213 | uint32_t page_flags) |
1026 | { | 1214 | { |
@@ -1034,6 +1222,8 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo, | |||
1034 | return NULL; | 1222 | return NULL; |
1035 | } | 1223 | } |
1036 | gtt->ttm.ttm.func = &amdgpu_backend_func; | 1224 | gtt->ttm.ttm.func = &amdgpu_backend_func; |
1225 | |||
1226 | /* allocate space for the uninitialized page entries */ | ||
1037 | if (ttm_sg_tt_init(>t->ttm, bo, page_flags)) { | 1227 | if (ttm_sg_tt_init(>t->ttm, bo, page_flags)) { |
1038 | kfree(gtt); | 1228 | kfree(gtt); |
1039 | return NULL; | 1229 | return NULL; |
@@ -1041,6 +1231,12 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo, | |||
1041 | return >t->ttm.ttm; | 1231 | return >t->ttm.ttm; |
1042 | } | 1232 | } |
1043 | 1233 | ||
1234 | /** | ||
1235 | * amdgpu_ttm_tt_populate - Map GTT pages visible to the device | ||
1236 | * | ||
1237 | * Map the pages of a ttm_tt object to an address space visible | ||
1238 | * to the underlying device. | ||
1239 | */ | ||
1044 | static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm, | 1240 | static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm, |
1045 | struct ttm_operation_ctx *ctx) | 1241 | struct ttm_operation_ctx *ctx) |
1046 | { | 1242 | { |
@@ -1048,6 +1244,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm, | |||
1048 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 1244 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
1049 | bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); | 1245 | bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); |
1050 | 1246 | ||
1247 | /* user pages are bound by amdgpu_ttm_tt_pin_userptr() */ | ||
1051 | if (gtt && gtt->userptr) { | 1248 | if (gtt && gtt->userptr) { |
1052 | ttm->sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL); | 1249 | ttm->sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL); |
1053 | if (!ttm->sg) | 1250 | if (!ttm->sg) |
@@ -1072,9 +1269,17 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm, | |||
1072 | } | 1269 | } |
1073 | #endif | 1270 | #endif |
1074 | 1271 | ||
1272 | /* fall back to generic helper to populate the page array | ||
1273 | * and map them to the device */ | ||
1075 | return ttm_populate_and_map_pages(adev->dev, >t->ttm, ctx); | 1274 | return ttm_populate_and_map_pages(adev->dev, >t->ttm, ctx); |
1076 | } | 1275 | } |
1077 | 1276 | ||
1277 | /** | ||
1278 | * amdgpu_ttm_tt_unpopulate - unmap GTT pages and unpopulate page arrays | ||
1279 | * | ||
1280 | * Unmaps pages of a ttm_tt object from the device address space and | ||
1281 | * unpopulates the page array backing it. | ||
1282 | */ | ||
1078 | static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) | 1283 | static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) |
1079 | { | 1284 | { |
1080 | struct amdgpu_device *adev; | 1285 | struct amdgpu_device *adev; |
@@ -1100,9 +1305,21 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) | |||
1100 | } | 1305 | } |
1101 | #endif | 1306 | #endif |
1102 | 1307 | ||
1308 | /* fall back to generic helper to unmap and unpopulate array */ | ||
1103 | ttm_unmap_and_unpopulate_pages(adev->dev, >t->ttm); | 1309 | ttm_unmap_and_unpopulate_pages(adev->dev, >t->ttm); |
1104 | } | 1310 | } |
1105 | 1311 | ||
1312 | /** | ||
1313 | * amdgpu_ttm_tt_set_userptr - Initialize userptr GTT ttm_tt | ||
1314 | * for the current task | ||
1315 | * | ||
1316 | * @ttm: The ttm_tt object to bind this userptr object to | ||
1317 | * @addr: The address in the current tasks VM space to use | ||
1318 | * @flags: Requirements of userptr object. | ||
1319 | * | ||
1320 | * Called by amdgpu_gem_userptr_ioctl() to bind userptr pages | ||
1321 | * to current task | ||
1322 | */ | ||
1106 | int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, | 1323 | int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, |
1107 | uint32_t flags) | 1324 | uint32_t flags) |
1108 | { | 1325 | { |
@@ -1127,6 +1344,9 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, | |||
1127 | return 0; | 1344 | return 0; |
1128 | } | 1345 | } |
1129 | 1346 | ||
1347 | /** | ||
1348 | * amdgpu_ttm_tt_get_usermm - Return memory manager for ttm_tt object | ||
1349 | */ | ||
1130 | struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm) | 1350 | struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm) |
1131 | { | 1351 | { |
1132 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 1352 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
@@ -1140,6 +1360,12 @@ struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm) | |||
1140 | return gtt->usertask->mm; | 1360 | return gtt->usertask->mm; |
1141 | } | 1361 | } |
1142 | 1362 | ||
1363 | /** | ||
1364 | * amdgpu_ttm_tt_affect_userptr - Determine if a ttm_tt object lays | ||
1365 | * inside an address range for the | ||
1366 | * current task. | ||
1367 | * | ||
1368 | */ | ||
1143 | bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, | 1369 | bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, |
1144 | unsigned long end) | 1370 | unsigned long end) |
1145 | { | 1371 | { |
@@ -1150,10 +1376,16 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, | |||
1150 | if (gtt == NULL || !gtt->userptr) | 1376 | if (gtt == NULL || !gtt->userptr) |
1151 | return false; | 1377 | return false; |
1152 | 1378 | ||
1379 | /* Return false if no part of the ttm_tt object lies within | ||
1380 | * the range | ||
1381 | */ | ||
1153 | size = (unsigned long)gtt->ttm.ttm.num_pages * PAGE_SIZE; | 1382 | size = (unsigned long)gtt->ttm.ttm.num_pages * PAGE_SIZE; |
1154 | if (gtt->userptr > end || gtt->userptr + size <= start) | 1383 | if (gtt->userptr > end || gtt->userptr + size <= start) |
1155 | return false; | 1384 | return false; |
1156 | 1385 | ||
1386 | /* Search the lists of tasks that hold this mapping and see | ||
1387 | * if current is one of them. If it is return false. | ||
1388 | */ | ||
1157 | spin_lock(>t->guptasklock); | 1389 | spin_lock(>t->guptasklock); |
1158 | list_for_each_entry(entry, >t->guptasks, list) { | 1390 | list_for_each_entry(entry, >t->guptasks, list) { |
1159 | if (entry->task == current) { | 1391 | if (entry->task == current) { |
@@ -1168,6 +1400,10 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, | |||
1168 | return true; | 1400 | return true; |
1169 | } | 1401 | } |
1170 | 1402 | ||
1403 | /** | ||
1404 | * amdgpu_ttm_tt_userptr_invalidated - Has the ttm_tt object been | ||
1405 | * invalidated? | ||
1406 | */ | ||
1171 | bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, | 1407 | bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, |
1172 | int *last_invalidated) | 1408 | int *last_invalidated) |
1173 | { | 1409 | { |
@@ -1178,6 +1414,12 @@ bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, | |||
1178 | return prev_invalidated != *last_invalidated; | 1414 | return prev_invalidated != *last_invalidated; |
1179 | } | 1415 | } |
1180 | 1416 | ||
1417 | /** | ||
1418 | * amdgpu_ttm_tt_userptr_needs_pages - Have the pages backing this | ||
1419 | * ttm_tt object been invalidated | ||
1420 | * since the last time they've | ||
1421 | * been set? | ||
1422 | */ | ||
1181 | bool amdgpu_ttm_tt_userptr_needs_pages(struct ttm_tt *ttm) | 1423 | bool amdgpu_ttm_tt_userptr_needs_pages(struct ttm_tt *ttm) |
1182 | { | 1424 | { |
1183 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 1425 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
@@ -1188,6 +1430,9 @@ bool amdgpu_ttm_tt_userptr_needs_pages(struct ttm_tt *ttm) | |||
1188 | return atomic_read(>t->mmu_invalidations) != gtt->last_set_pages; | 1430 | return atomic_read(>t->mmu_invalidations) != gtt->last_set_pages; |
1189 | } | 1431 | } |
1190 | 1432 | ||
1433 | /** | ||
1434 | * amdgpu_ttm_tt_is_readonly - Is the ttm_tt object read only? | ||
1435 | */ | ||
1191 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm) | 1436 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm) |
1192 | { | 1437 | { |
1193 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 1438 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |
@@ -1198,6 +1443,12 @@ bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm) | |||
1198 | return !!(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY); | 1443 | return !!(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY); |
1199 | } | 1444 | } |
1200 | 1445 | ||
1446 | /** | ||
1447 | * amdgpu_ttm_tt_pte_flags - Compute PTE flags for ttm_tt object | ||
1448 | * | ||
1449 | * @ttm: The ttm_tt object to compute the flags for | ||
1450 | * @mem: The memory registry backing this ttm_tt object | ||
1451 | */ | ||
1201 | uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, | 1452 | uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, |
1202 | struct ttm_mem_reg *mem) | 1453 | struct ttm_mem_reg *mem) |
1203 | { | 1454 | { |
@@ -1222,6 +1473,16 @@ uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, | |||
1222 | return flags; | 1473 | return flags; |
1223 | } | 1474 | } |
1224 | 1475 | ||
1476 | /** | ||
1477 | * amdgpu_ttm_bo_eviction_valuable - Check to see if we can evict | ||
1478 | * a buffer object. | ||
1479 | * | ||
1480 | * Return true if eviction is sensible. Called by | ||
1481 | * ttm_mem_evict_first() on behalf of ttm_bo_mem_force_space() | ||
1482 | * which tries to evict buffer objects until it can find space | ||
1483 | * for a new object and by ttm_bo_force_list_clean() which is | ||
1484 | * used to clean out a memory space. | ||
1485 | */ | ||
1225 | static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, | 1486 | static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, |
1226 | const struct ttm_place *place) | 1487 | const struct ttm_place *place) |
1227 | { | 1488 | { |
@@ -1268,6 +1529,19 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, | |||
1268 | return ttm_bo_eviction_valuable(bo, place); | 1529 | return ttm_bo_eviction_valuable(bo, place); |
1269 | } | 1530 | } |
1270 | 1531 | ||
1532 | /** | ||
1533 | * amdgpu_ttm_access_memory - Read or Write memory that backs a | ||
1534 | * buffer object. | ||
1535 | * | ||
1536 | * @bo: The buffer object to read/write | ||
1537 | * @offset: Offset into buffer object | ||
1538 | * @buf: Secondary buffer to write/read from | ||
1539 | * @len: Length in bytes of access | ||
1540 | * @write: true if writing | ||
1541 | * | ||
1542 | * This is used to access VRAM that backs a buffer object via MMIO | ||
1543 | * access for debugging purposes. | ||
1544 | */ | ||
1271 | static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo, | 1545 | static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo, |
1272 | unsigned long offset, | 1546 | unsigned long offset, |
1273 | void *buf, int len, int write) | 1547 | void *buf, int len, int write) |
@@ -1444,13 +1718,22 @@ error_create: | |||
1444 | adev->fw_vram_usage.reserved_bo = NULL; | 1718 | adev->fw_vram_usage.reserved_bo = NULL; |
1445 | return r; | 1719 | return r; |
1446 | } | 1720 | } |
1447 | 1721 | /** | |
1722 | * amdgpu_ttm_init - Init the memory management (ttm) as well as | ||
1723 | * various gtt/vram related fields. | ||
1724 | * | ||
1725 | * This initializes all of the memory space pools that the TTM layer | ||
1726 | * will need such as the GTT space (system memory mapped to the device), | ||
1727 | * VRAM (on-board memory), and on-chip memories (GDS, GWS, OA) which | ||
1728 | * can be mapped per VMID. | ||
1729 | */ | ||
1448 | int amdgpu_ttm_init(struct amdgpu_device *adev) | 1730 | int amdgpu_ttm_init(struct amdgpu_device *adev) |
1449 | { | 1731 | { |
1450 | uint64_t gtt_size; | 1732 | uint64_t gtt_size; |
1451 | int r; | 1733 | int r; |
1452 | u64 vis_vram_limit; | 1734 | u64 vis_vram_limit; |
1453 | 1735 | ||
1736 | /* initialize global references for vram/gtt */ | ||
1454 | r = amdgpu_ttm_global_init(adev); | 1737 | r = amdgpu_ttm_global_init(adev); |
1455 | if (r) { | 1738 | if (r) { |
1456 | return r; | 1739 | return r; |
@@ -1471,6 +1754,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) | |||
1471 | /* We opt to avoid OOM on system pages allocations */ | 1754 | /* We opt to avoid OOM on system pages allocations */ |
1472 | adev->mman.bdev.no_retry = true; | 1755 | adev->mman.bdev.no_retry = true; |
1473 | 1756 | ||
1757 | /* Initialize VRAM pool with all of VRAM divided into pages */ | ||
1474 | r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_VRAM, | 1758 | r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_VRAM, |
1475 | adev->gmc.real_vram_size >> PAGE_SHIFT); | 1759 | adev->gmc.real_vram_size >> PAGE_SHIFT); |
1476 | if (r) { | 1760 | if (r) { |
@@ -1500,6 +1784,10 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) | |||
1500 | return r; | 1784 | return r; |
1501 | } | 1785 | } |
1502 | 1786 | ||
1787 | /* allocate memory as required for VGA | ||
1788 | * This is used for VGA emulation and pre-OS scanout buffers to | ||
1789 | * avoid display artifacts while transitioning between pre-OS | ||
1790 | * and driver. */ | ||
1503 | if (adev->gmc.stolen_size) { | 1791 | if (adev->gmc.stolen_size) { |
1504 | r = amdgpu_bo_create_kernel(adev, adev->gmc.stolen_size, PAGE_SIZE, | 1792 | r = amdgpu_bo_create_kernel(adev, adev->gmc.stolen_size, PAGE_SIZE, |
1505 | AMDGPU_GEM_DOMAIN_VRAM, | 1793 | AMDGPU_GEM_DOMAIN_VRAM, |
@@ -1511,6 +1799,8 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) | |||
1511 | DRM_INFO("amdgpu: %uM of VRAM memory ready\n", | 1799 | DRM_INFO("amdgpu: %uM of VRAM memory ready\n", |
1512 | (unsigned) (adev->gmc.real_vram_size / (1024 * 1024))); | 1800 | (unsigned) (adev->gmc.real_vram_size / (1024 * 1024))); |
1513 | 1801 | ||
1802 | /* Compute GTT size, either bsaed on 3/4th the size of RAM size | ||
1803 | * or whatever the user passed on module init */ | ||
1514 | if (amdgpu_gtt_size == -1) { | 1804 | if (amdgpu_gtt_size == -1) { |
1515 | struct sysinfo si; | 1805 | struct sysinfo si; |
1516 | 1806 | ||
@@ -1521,6 +1811,8 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) | |||
1521 | } | 1811 | } |
1522 | else | 1812 | else |
1523 | gtt_size = (uint64_t)amdgpu_gtt_size << 20; | 1813 | gtt_size = (uint64_t)amdgpu_gtt_size << 20; |
1814 | |||
1815 | /* Initialize GTT memory pool */ | ||
1524 | r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_TT, gtt_size >> PAGE_SHIFT); | 1816 | r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_TT, gtt_size >> PAGE_SHIFT); |
1525 | if (r) { | 1817 | if (r) { |
1526 | DRM_ERROR("Failed initializing GTT heap.\n"); | 1818 | DRM_ERROR("Failed initializing GTT heap.\n"); |
@@ -1529,6 +1821,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) | |||
1529 | DRM_INFO("amdgpu: %uM of GTT memory ready.\n", | 1821 | DRM_INFO("amdgpu: %uM of GTT memory ready.\n", |
1530 | (unsigned)(gtt_size / (1024 * 1024))); | 1822 | (unsigned)(gtt_size / (1024 * 1024))); |
1531 | 1823 | ||
1824 | /* Initialize various on-chip memory pools */ | ||
1532 | adev->gds.mem.total_size = adev->gds.mem.total_size << AMDGPU_GDS_SHIFT; | 1825 | adev->gds.mem.total_size = adev->gds.mem.total_size << AMDGPU_GDS_SHIFT; |
1533 | adev->gds.mem.gfx_partition_size = adev->gds.mem.gfx_partition_size << AMDGPU_GDS_SHIFT; | 1826 | adev->gds.mem.gfx_partition_size = adev->gds.mem.gfx_partition_size << AMDGPU_GDS_SHIFT; |
1534 | adev->gds.mem.cs_partition_size = adev->gds.mem.cs_partition_size << AMDGPU_GDS_SHIFT; | 1827 | adev->gds.mem.cs_partition_size = adev->gds.mem.cs_partition_size << AMDGPU_GDS_SHIFT; |
@@ -1568,6 +1861,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) | |||
1568 | } | 1861 | } |
1569 | } | 1862 | } |
1570 | 1863 | ||
1864 | /* Register debugfs entries for amdgpu_ttm */ | ||
1571 | r = amdgpu_ttm_debugfs_init(adev); | 1865 | r = amdgpu_ttm_debugfs_init(adev); |
1572 | if (r) { | 1866 | if (r) { |
1573 | DRM_ERROR("Failed to init debugfs\n"); | 1867 | DRM_ERROR("Failed to init debugfs\n"); |
@@ -1576,11 +1870,19 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) | |||
1576 | return 0; | 1870 | return 0; |
1577 | } | 1871 | } |
1578 | 1872 | ||
1873 | /** | ||
1874 | * amdgpu_ttm_late_init - Handle any late initialization for | ||
1875 | * amdgpu_ttm | ||
1876 | */ | ||
1579 | void amdgpu_ttm_late_init(struct amdgpu_device *adev) | 1877 | void amdgpu_ttm_late_init(struct amdgpu_device *adev) |
1580 | { | 1878 | { |
1879 | /* return the VGA stolen memory (if any) back to VRAM */ | ||
1581 | amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL); | 1880 | amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL); |
1582 | } | 1881 | } |
1583 | 1882 | ||
1883 | /** | ||
1884 | * amdgpu_ttm_fini - De-initialize the TTM memory pools | ||
1885 | */ | ||
1584 | void amdgpu_ttm_fini(struct amdgpu_device *adev) | 1886 | void amdgpu_ttm_fini(struct amdgpu_device *adev) |
1585 | { | 1887 | { |
1586 | if (!adev->mman.initialized) | 1888 | if (!adev->mman.initialized) |
@@ -1908,6 +2210,11 @@ static const struct drm_info_list amdgpu_ttm_debugfs_list[] = { | |||
1908 | #endif | 2210 | #endif |
1909 | }; | 2211 | }; |
1910 | 2212 | ||
2213 | /** | ||
2214 | * amdgpu_ttm_vram_read - Linear read access to VRAM | ||
2215 | * | ||
2216 | * Accesses VRAM via MMIO for debugging purposes. | ||
2217 | */ | ||
1911 | static ssize_t amdgpu_ttm_vram_read(struct file *f, char __user *buf, | 2218 | static ssize_t amdgpu_ttm_vram_read(struct file *f, char __user *buf, |
1912 | size_t size, loff_t *pos) | 2219 | size_t size, loff_t *pos) |
1913 | { | 2220 | { |
@@ -1947,6 +2254,11 @@ static ssize_t amdgpu_ttm_vram_read(struct file *f, char __user *buf, | |||
1947 | return result; | 2254 | return result; |
1948 | } | 2255 | } |
1949 | 2256 | ||
2257 | /** | ||
2258 | * amdgpu_ttm_vram_write - Linear write access to VRAM | ||
2259 | * | ||
2260 | * Accesses VRAM via MMIO for debugging purposes. | ||
2261 | */ | ||
1950 | static ssize_t amdgpu_ttm_vram_write(struct file *f, const char __user *buf, | 2262 | static ssize_t amdgpu_ttm_vram_write(struct file *f, const char __user *buf, |
1951 | size_t size, loff_t *pos) | 2263 | size_t size, loff_t *pos) |
1952 | { | 2264 | { |
@@ -1995,6 +2307,9 @@ static const struct file_operations amdgpu_ttm_vram_fops = { | |||
1995 | 2307 | ||
1996 | #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS | 2308 | #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS |
1997 | 2309 | ||
2310 | /** | ||
2311 | * amdgpu_ttm_gtt_read - Linear read access to GTT memory | ||
2312 | */ | ||
1998 | static ssize_t amdgpu_ttm_gtt_read(struct file *f, char __user *buf, | 2313 | static ssize_t amdgpu_ttm_gtt_read(struct file *f, char __user *buf, |
1999 | size_t size, loff_t *pos) | 2314 | size_t size, loff_t *pos) |
2000 | { | 2315 | { |
@@ -2042,6 +2357,13 @@ static const struct file_operations amdgpu_ttm_gtt_fops = { | |||
2042 | 2357 | ||
2043 | #endif | 2358 | #endif |
2044 | 2359 | ||
2360 | /** | ||
2361 | * amdgpu_iomem_read - Virtual read access to GPU mapped memory | ||
2362 | * | ||
2363 | * This function is used to read memory that has been mapped to the | ||
2364 | * GPU and the known addresses are not physical addresses but instead | ||
2365 | * bus addresses (e.g., what you'd put in an IB or ring buffer). | ||
2366 | */ | ||
2045 | static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf, | 2367 | static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf, |
2046 | size_t size, loff_t *pos) | 2368 | size_t size, loff_t *pos) |
2047 | { | 2369 | { |
@@ -2050,6 +2372,7 @@ static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf, | |||
2050 | ssize_t result = 0; | 2372 | ssize_t result = 0; |
2051 | int r; | 2373 | int r; |
2052 | 2374 | ||
2375 | /* retrieve the IOMMU domain if any for this device */ | ||
2053 | dom = iommu_get_domain_for_dev(adev->dev); | 2376 | dom = iommu_get_domain_for_dev(adev->dev); |
2054 | 2377 | ||
2055 | while (size) { | 2378 | while (size) { |
@@ -2062,6 +2385,10 @@ static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf, | |||
2062 | 2385 | ||
2063 | bytes = bytes < size ? bytes : size; | 2386 | bytes = bytes < size ? bytes : size; |
2064 | 2387 | ||
2388 | /* Translate the bus address to a physical address. If | ||
2389 | * the domain is NULL it means there is no IOMMU active | ||
2390 | * and the address translation is the identity | ||
2391 | */ | ||
2065 | addr = dom ? iommu_iova_to_phys(dom, addr) : addr; | 2392 | addr = dom ? iommu_iova_to_phys(dom, addr) : addr; |
2066 | 2393 | ||
2067 | pfn = addr >> PAGE_SHIFT; | 2394 | pfn = addr >> PAGE_SHIFT; |
@@ -2086,6 +2413,13 @@ static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf, | |||
2086 | return result; | 2413 | return result; |
2087 | } | 2414 | } |
2088 | 2415 | ||
2416 | /** | ||
2417 | * amdgpu_iomem_write - Virtual write access to GPU mapped memory | ||
2418 | * | ||
2419 | * This function is used to write memory that has been mapped to the | ||
2420 | * GPU and the known addresses are not physical addresses but instead | ||
2421 | * bus addresses (e.g., what you'd put in an IB or ring buffer). | ||
2422 | */ | ||
2089 | static ssize_t amdgpu_iomem_write(struct file *f, const char __user *buf, | 2423 | static ssize_t amdgpu_iomem_write(struct file *f, const char __user *buf, |
2090 | size_t size, loff_t *pos) | 2424 | size_t size, loff_t *pos) |
2091 | { | 2425 | { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index 75592bd04d6a..f55f72a37ca8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | |||
@@ -307,6 +307,8 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type) | |||
307 | return AMDGPU_FW_LOAD_DIRECT; | 307 | return AMDGPU_FW_LOAD_DIRECT; |
308 | else | 308 | else |
309 | return AMDGPU_FW_LOAD_PSP; | 309 | return AMDGPU_FW_LOAD_PSP; |
310 | case CHIP_VEGA20: | ||
311 | return AMDGPU_FW_LOAD_DIRECT; | ||
310 | default: | 312 | default: |
311 | DRM_ERROR("Unknown firmware load type\n"); | 313 | DRM_ERROR("Unknown firmware load type\n"); |
312 | } | 314 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index de4d77af02ae..bcf68f80bbf0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | |||
@@ -70,12 +70,14 @@ | |||
70 | 70 | ||
71 | #define FIRMWARE_VEGA10 "amdgpu/vega10_uvd.bin" | 71 | #define FIRMWARE_VEGA10 "amdgpu/vega10_uvd.bin" |
72 | #define FIRMWARE_VEGA12 "amdgpu/vega12_uvd.bin" | 72 | #define FIRMWARE_VEGA12 "amdgpu/vega12_uvd.bin" |
73 | #define FIRMWARE_VEGA20 "amdgpu/vega20_uvd.bin" | ||
73 | 74 | ||
74 | #define mmUVD_GPCOM_VCPU_DATA0_VEGA10 (0x03c4 + 0x7e00) | 75 | /* These are common relative offsets for all asics, from uvd_7_0_offset.h, */ |
75 | #define mmUVD_GPCOM_VCPU_DATA1_VEGA10 (0x03c5 + 0x7e00) | 76 | #define UVD_GPCOM_VCPU_CMD 0x03c3 |
76 | #define mmUVD_GPCOM_VCPU_CMD_VEGA10 (0x03c3 + 0x7e00) | 77 | #define UVD_GPCOM_VCPU_DATA0 0x03c4 |
77 | #define mmUVD_NO_OP_VEGA10 (0x03ff + 0x7e00) | 78 | #define UVD_GPCOM_VCPU_DATA1 0x03c5 |
78 | #define mmUVD_ENGINE_CNTL_VEGA10 (0x03c6 + 0x7e00) | 79 | #define UVD_NO_OP 0x03ff |
80 | #define UVD_BASE_SI 0x3800 | ||
79 | 81 | ||
80 | /** | 82 | /** |
81 | * amdgpu_uvd_cs_ctx - Command submission parser context | 83 | * amdgpu_uvd_cs_ctx - Command submission parser context |
@@ -114,6 +116,7 @@ MODULE_FIRMWARE(FIRMWARE_VEGAM); | |||
114 | 116 | ||
115 | MODULE_FIRMWARE(FIRMWARE_VEGA10); | 117 | MODULE_FIRMWARE(FIRMWARE_VEGA10); |
116 | MODULE_FIRMWARE(FIRMWARE_VEGA12); | 118 | MODULE_FIRMWARE(FIRMWARE_VEGA12); |
119 | MODULE_FIRMWARE(FIRMWARE_VEGA20); | ||
117 | 120 | ||
118 | static void amdgpu_uvd_idle_work_handler(struct work_struct *work); | 121 | static void amdgpu_uvd_idle_work_handler(struct work_struct *work); |
119 | 122 | ||
@@ -125,9 +128,9 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) | |||
125 | const char *fw_name; | 128 | const char *fw_name; |
126 | const struct common_firmware_header *hdr; | 129 | const struct common_firmware_header *hdr; |
127 | unsigned version_major, version_minor, family_id; | 130 | unsigned version_major, version_minor, family_id; |
128 | int i, r; | 131 | int i, j, r; |
129 | 132 | ||
130 | INIT_DELAYED_WORK(&adev->uvd.idle_work, amdgpu_uvd_idle_work_handler); | 133 | INIT_DELAYED_WORK(&adev->uvd.inst->idle_work, amdgpu_uvd_idle_work_handler); |
131 | 134 | ||
132 | switch (adev->asic_type) { | 135 | switch (adev->asic_type) { |
133 | #ifdef CONFIG_DRM_AMDGPU_CIK | 136 | #ifdef CONFIG_DRM_AMDGPU_CIK |
@@ -177,6 +180,9 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) | |||
177 | case CHIP_VEGAM: | 180 | case CHIP_VEGAM: |
178 | fw_name = FIRMWARE_VEGAM; | 181 | fw_name = FIRMWARE_VEGAM; |
179 | break; | 182 | break; |
183 | case CHIP_VEGA20: | ||
184 | fw_name = FIRMWARE_VEGA20; | ||
185 | break; | ||
180 | default: | 186 | default: |
181 | return -EINVAL; | 187 | return -EINVAL; |
182 | } | 188 | } |
@@ -231,28 +237,30 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) | |||
231 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) | 237 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) |
232 | bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); | 238 | bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); |
233 | 239 | ||
234 | r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE, | 240 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
235 | AMDGPU_GEM_DOMAIN_VRAM, &adev->uvd.vcpu_bo, | ||
236 | &adev->uvd.gpu_addr, &adev->uvd.cpu_addr); | ||
237 | if (r) { | ||
238 | dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r); | ||
239 | return r; | ||
240 | } | ||
241 | 241 | ||
242 | ring = &adev->uvd.ring; | 242 | r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE, |
243 | rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; | 243 | AMDGPU_GEM_DOMAIN_VRAM, &adev->uvd.inst[j].vcpu_bo, |
244 | r = drm_sched_entity_init(&ring->sched, &adev->uvd.entity, | 244 | &adev->uvd.inst[j].gpu_addr, &adev->uvd.inst[j].cpu_addr); |
245 | rq, NULL); | 245 | if (r) { |
246 | if (r != 0) { | 246 | dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r); |
247 | DRM_ERROR("Failed setting up UVD run queue.\n"); | 247 | return r; |
248 | return r; | 248 | } |
249 | } | ||
250 | 249 | ||
251 | for (i = 0; i < adev->uvd.max_handles; ++i) { | 250 | ring = &adev->uvd.inst[j].ring; |
252 | atomic_set(&adev->uvd.handles[i], 0); | 251 | rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; |
253 | adev->uvd.filp[i] = NULL; | 252 | r = drm_sched_entity_init(&ring->sched, &adev->uvd.inst[j].entity, |
254 | } | 253 | rq, NULL); |
254 | if (r != 0) { | ||
255 | DRM_ERROR("Failed setting up UVD(%d) run queue.\n", j); | ||
256 | return r; | ||
257 | } | ||
255 | 258 | ||
259 | for (i = 0; i < adev->uvd.max_handles; ++i) { | ||
260 | atomic_set(&adev->uvd.inst[j].handles[i], 0); | ||
261 | adev->uvd.inst[j].filp[i] = NULL; | ||
262 | } | ||
263 | } | ||
256 | /* from uvd v5.0 HW addressing capacity increased to 64 bits */ | 264 | /* from uvd v5.0 HW addressing capacity increased to 64 bits */ |
257 | if (!amdgpu_device_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0)) | 265 | if (!amdgpu_device_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0)) |
258 | adev->uvd.address_64_bit = true; | 266 | adev->uvd.address_64_bit = true; |
@@ -279,20 +287,22 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) | |||
279 | 287 | ||
280 | int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) | 288 | int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) |
281 | { | 289 | { |
282 | int i; | 290 | int i, j; |
283 | kfree(adev->uvd.saved_bo); | ||
284 | 291 | ||
285 | drm_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity); | 292 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { |
293 | kfree(adev->uvd.inst[j].saved_bo); | ||
286 | 294 | ||
287 | amdgpu_bo_free_kernel(&adev->uvd.vcpu_bo, | 295 | drm_sched_entity_fini(&adev->uvd.inst[j].ring.sched, &adev->uvd.inst[j].entity); |
288 | &adev->uvd.gpu_addr, | ||
289 | (void **)&adev->uvd.cpu_addr); | ||
290 | 296 | ||
291 | amdgpu_ring_fini(&adev->uvd.ring); | 297 | amdgpu_bo_free_kernel(&adev->uvd.inst[j].vcpu_bo, |
298 | &adev->uvd.inst[j].gpu_addr, | ||
299 | (void **)&adev->uvd.inst[j].cpu_addr); | ||
292 | 300 | ||
293 | for (i = 0; i < AMDGPU_MAX_UVD_ENC_RINGS; ++i) | 301 | amdgpu_ring_fini(&adev->uvd.inst[j].ring); |
294 | amdgpu_ring_fini(&adev->uvd.ring_enc[i]); | ||
295 | 302 | ||
303 | for (i = 0; i < AMDGPU_MAX_UVD_ENC_RINGS; ++i) | ||
304 | amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]); | ||
305 | } | ||
296 | release_firmware(adev->uvd.fw); | 306 | release_firmware(adev->uvd.fw); |
297 | 307 | ||
298 | return 0; | 308 | return 0; |
@@ -302,32 +312,33 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) | |||
302 | { | 312 | { |
303 | unsigned size; | 313 | unsigned size; |
304 | void *ptr; | 314 | void *ptr; |
305 | int i; | 315 | int i, j; |
306 | |||
307 | if (adev->uvd.vcpu_bo == NULL) | ||
308 | return 0; | ||
309 | 316 | ||
310 | cancel_delayed_work_sync(&adev->uvd.idle_work); | 317 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { |
318 | if (adev->uvd.inst[j].vcpu_bo == NULL) | ||
319 | continue; | ||
311 | 320 | ||
312 | /* only valid for physical mode */ | 321 | cancel_delayed_work_sync(&adev->uvd.inst[j].idle_work); |
313 | if (adev->asic_type < CHIP_POLARIS10) { | ||
314 | for (i = 0; i < adev->uvd.max_handles; ++i) | ||
315 | if (atomic_read(&adev->uvd.handles[i])) | ||
316 | break; | ||
317 | 322 | ||
318 | if (i == adev->uvd.max_handles) | 323 | /* only valid for physical mode */ |
319 | return 0; | 324 | if (adev->asic_type < CHIP_POLARIS10) { |
320 | } | 325 | for (i = 0; i < adev->uvd.max_handles; ++i) |
326 | if (atomic_read(&adev->uvd.inst[j].handles[i])) | ||
327 | break; | ||
321 | 328 | ||
322 | size = amdgpu_bo_size(adev->uvd.vcpu_bo); | 329 | if (i == adev->uvd.max_handles) |
323 | ptr = adev->uvd.cpu_addr; | 330 | continue; |
331 | } | ||
324 | 332 | ||
325 | adev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); | 333 | size = amdgpu_bo_size(adev->uvd.inst[j].vcpu_bo); |
326 | if (!adev->uvd.saved_bo) | 334 | ptr = adev->uvd.inst[j].cpu_addr; |
327 | return -ENOMEM; | ||
328 | 335 | ||
329 | memcpy_fromio(adev->uvd.saved_bo, ptr, size); | 336 | adev->uvd.inst[j].saved_bo = kmalloc(size, GFP_KERNEL); |
337 | if (!adev->uvd.inst[j].saved_bo) | ||
338 | return -ENOMEM; | ||
330 | 339 | ||
340 | memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size); | ||
341 | } | ||
331 | return 0; | 342 | return 0; |
332 | } | 343 | } |
333 | 344 | ||
@@ -335,59 +346,65 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) | |||
335 | { | 346 | { |
336 | unsigned size; | 347 | unsigned size; |
337 | void *ptr; | 348 | void *ptr; |
349 | int i; | ||
338 | 350 | ||
339 | if (adev->uvd.vcpu_bo == NULL) | 351 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { |
340 | return -EINVAL; | 352 | if (adev->uvd.inst[i].vcpu_bo == NULL) |
353 | return -EINVAL; | ||
341 | 354 | ||
342 | size = amdgpu_bo_size(adev->uvd.vcpu_bo); | 355 | size = amdgpu_bo_size(adev->uvd.inst[i].vcpu_bo); |
343 | ptr = adev->uvd.cpu_addr; | 356 | ptr = adev->uvd.inst[i].cpu_addr; |
344 | 357 | ||
345 | if (adev->uvd.saved_bo != NULL) { | 358 | if (adev->uvd.inst[i].saved_bo != NULL) { |
346 | memcpy_toio(ptr, adev->uvd.saved_bo, size); | 359 | memcpy_toio(ptr, adev->uvd.inst[i].saved_bo, size); |
347 | kfree(adev->uvd.saved_bo); | 360 | kfree(adev->uvd.inst[i].saved_bo); |
348 | adev->uvd.saved_bo = NULL; | 361 | adev->uvd.inst[i].saved_bo = NULL; |
349 | } else { | 362 | } else { |
350 | const struct common_firmware_header *hdr; | 363 | const struct common_firmware_header *hdr; |
351 | unsigned offset; | 364 | unsigned offset; |
352 | 365 | ||
353 | hdr = (const struct common_firmware_header *)adev->uvd.fw->data; | 366 | hdr = (const struct common_firmware_header *)adev->uvd.fw->data; |
354 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { | 367 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { |
355 | offset = le32_to_cpu(hdr->ucode_array_offset_bytes); | 368 | offset = le32_to_cpu(hdr->ucode_array_offset_bytes); |
356 | memcpy_toio(adev->uvd.cpu_addr, adev->uvd.fw->data + offset, | 369 | memcpy_toio(adev->uvd.inst[i].cpu_addr, adev->uvd.fw->data + offset, |
357 | le32_to_cpu(hdr->ucode_size_bytes)); | 370 | le32_to_cpu(hdr->ucode_size_bytes)); |
358 | size -= le32_to_cpu(hdr->ucode_size_bytes); | 371 | size -= le32_to_cpu(hdr->ucode_size_bytes); |
359 | ptr += le32_to_cpu(hdr->ucode_size_bytes); | 372 | ptr += le32_to_cpu(hdr->ucode_size_bytes); |
373 | } | ||
374 | memset_io(ptr, 0, size); | ||
375 | /* to restore uvd fence seq */ | ||
376 | amdgpu_fence_driver_force_completion(&adev->uvd.inst[i].ring); | ||
360 | } | 377 | } |
361 | memset_io(ptr, 0, size); | ||
362 | /* to restore uvd fence seq */ | ||
363 | amdgpu_fence_driver_force_completion(&adev->uvd.ring); | ||
364 | } | 378 | } |
365 | |||
366 | return 0; | 379 | return 0; |
367 | } | 380 | } |
368 | 381 | ||
369 | void amdgpu_uvd_free_handles(struct amdgpu_device *adev, struct drm_file *filp) | 382 | void amdgpu_uvd_free_handles(struct amdgpu_device *adev, struct drm_file *filp) |
370 | { | 383 | { |
371 | struct amdgpu_ring *ring = &adev->uvd.ring; | 384 | struct amdgpu_ring *ring; |
372 | int i, r; | 385 | int i, j, r; |
373 | 386 | ||
374 | for (i = 0; i < adev->uvd.max_handles; ++i) { | 387 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
375 | uint32_t handle = atomic_read(&adev->uvd.handles[i]); | 388 | ring = &adev->uvd.inst[j].ring; |
376 | if (handle != 0 && adev->uvd.filp[i] == filp) { | 389 | |
377 | struct dma_fence *fence; | 390 | for (i = 0; i < adev->uvd.max_handles; ++i) { |
378 | 391 | uint32_t handle = atomic_read(&adev->uvd.inst[j].handles[i]); | |
379 | r = amdgpu_uvd_get_destroy_msg(ring, handle, | 392 | if (handle != 0 && adev->uvd.inst[j].filp[i] == filp) { |
380 | false, &fence); | 393 | struct dma_fence *fence; |
381 | if (r) { | 394 | |
382 | DRM_ERROR("Error destroying UVD (%d)!\n", r); | 395 | r = amdgpu_uvd_get_destroy_msg(ring, handle, |
383 | continue; | 396 | false, &fence); |
384 | } | 397 | if (r) { |
398 | DRM_ERROR("Error destroying UVD(%d) %d!\n", j, r); | ||
399 | continue; | ||
400 | } | ||
385 | 401 | ||
386 | dma_fence_wait(fence, false); | 402 | dma_fence_wait(fence, false); |
387 | dma_fence_put(fence); | 403 | dma_fence_put(fence); |
388 | 404 | ||
389 | adev->uvd.filp[i] = NULL; | 405 | adev->uvd.inst[j].filp[i] = NULL; |
390 | atomic_set(&adev->uvd.handles[i], 0); | 406 | atomic_set(&adev->uvd.inst[j].handles[i], 0); |
407 | } | ||
391 | } | 408 | } |
392 | } | 409 | } |
393 | } | 410 | } |
@@ -662,15 +679,16 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, | |||
662 | void *ptr; | 679 | void *ptr; |
663 | long r; | 680 | long r; |
664 | int i; | 681 | int i; |
682 | uint32_t ip_instance = ctx->parser->job->ring->me; | ||
665 | 683 | ||
666 | if (offset & 0x3F) { | 684 | if (offset & 0x3F) { |
667 | DRM_ERROR("UVD messages must be 64 byte aligned!\n"); | 685 | DRM_ERROR("UVD(%d) messages must be 64 byte aligned!\n", ip_instance); |
668 | return -EINVAL; | 686 | return -EINVAL; |
669 | } | 687 | } |
670 | 688 | ||
671 | r = amdgpu_bo_kmap(bo, &ptr); | 689 | r = amdgpu_bo_kmap(bo, &ptr); |
672 | if (r) { | 690 | if (r) { |
673 | DRM_ERROR("Failed mapping the UVD message (%ld)!\n", r); | 691 | DRM_ERROR("Failed mapping the UVD(%d) message (%ld)!\n", ip_instance, r); |
674 | return r; | 692 | return r; |
675 | } | 693 | } |
676 | 694 | ||
@@ -680,7 +698,7 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, | |||
680 | handle = msg[2]; | 698 | handle = msg[2]; |
681 | 699 | ||
682 | if (handle == 0) { | 700 | if (handle == 0) { |
683 | DRM_ERROR("Invalid UVD handle!\n"); | 701 | DRM_ERROR("Invalid UVD(%d) handle!\n", ip_instance); |
684 | return -EINVAL; | 702 | return -EINVAL; |
685 | } | 703 | } |
686 | 704 | ||
@@ -691,18 +709,18 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, | |||
691 | 709 | ||
692 | /* try to alloc a new handle */ | 710 | /* try to alloc a new handle */ |
693 | for (i = 0; i < adev->uvd.max_handles; ++i) { | 711 | for (i = 0; i < adev->uvd.max_handles; ++i) { |
694 | if (atomic_read(&adev->uvd.handles[i]) == handle) { | 712 | if (atomic_read(&adev->uvd.inst[ip_instance].handles[i]) == handle) { |
695 | DRM_ERROR("Handle 0x%x already in use!\n", handle); | 713 | DRM_ERROR("(%d)Handle 0x%x already in use!\n", ip_instance, handle); |
696 | return -EINVAL; | 714 | return -EINVAL; |
697 | } | 715 | } |
698 | 716 | ||
699 | if (!atomic_cmpxchg(&adev->uvd.handles[i], 0, handle)) { | 717 | if (!atomic_cmpxchg(&adev->uvd.inst[ip_instance].handles[i], 0, handle)) { |
700 | adev->uvd.filp[i] = ctx->parser->filp; | 718 | adev->uvd.inst[ip_instance].filp[i] = ctx->parser->filp; |
701 | return 0; | 719 | return 0; |
702 | } | 720 | } |
703 | } | 721 | } |
704 | 722 | ||
705 | DRM_ERROR("No more free UVD handles!\n"); | 723 | DRM_ERROR("No more free UVD(%d) handles!\n", ip_instance); |
706 | return -ENOSPC; | 724 | return -ENOSPC; |
707 | 725 | ||
708 | case 1: | 726 | case 1: |
@@ -714,27 +732,27 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, | |||
714 | 732 | ||
715 | /* validate the handle */ | 733 | /* validate the handle */ |
716 | for (i = 0; i < adev->uvd.max_handles; ++i) { | 734 | for (i = 0; i < adev->uvd.max_handles; ++i) { |
717 | if (atomic_read(&adev->uvd.handles[i]) == handle) { | 735 | if (atomic_read(&adev->uvd.inst[ip_instance].handles[i]) == handle) { |
718 | if (adev->uvd.filp[i] != ctx->parser->filp) { | 736 | if (adev->uvd.inst[ip_instance].filp[i] != ctx->parser->filp) { |
719 | DRM_ERROR("UVD handle collision detected!\n"); | 737 | DRM_ERROR("UVD(%d) handle collision detected!\n", ip_instance); |
720 | return -EINVAL; | 738 | return -EINVAL; |
721 | } | 739 | } |
722 | return 0; | 740 | return 0; |
723 | } | 741 | } |
724 | } | 742 | } |
725 | 743 | ||
726 | DRM_ERROR("Invalid UVD handle 0x%x!\n", handle); | 744 | DRM_ERROR("Invalid UVD(%d) handle 0x%x!\n", ip_instance, handle); |
727 | return -ENOENT; | 745 | return -ENOENT; |
728 | 746 | ||
729 | case 2: | 747 | case 2: |
730 | /* it's a destroy msg, free the handle */ | 748 | /* it's a destroy msg, free the handle */ |
731 | for (i = 0; i < adev->uvd.max_handles; ++i) | 749 | for (i = 0; i < adev->uvd.max_handles; ++i) |
732 | atomic_cmpxchg(&adev->uvd.handles[i], handle, 0); | 750 | atomic_cmpxchg(&adev->uvd.inst[ip_instance].handles[i], handle, 0); |
733 | amdgpu_bo_kunmap(bo); | 751 | amdgpu_bo_kunmap(bo); |
734 | return 0; | 752 | return 0; |
735 | 753 | ||
736 | default: | 754 | default: |
737 | DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); | 755 | DRM_ERROR("Illegal UVD(%d) message type (%d)!\n", ip_instance, msg_type); |
738 | return -EINVAL; | 756 | return -EINVAL; |
739 | } | 757 | } |
740 | BUG(); | 758 | BUG(); |
@@ -805,7 +823,7 @@ static int amdgpu_uvd_cs_pass2(struct amdgpu_uvd_cs_ctx *ctx) | |||
805 | } | 823 | } |
806 | 824 | ||
807 | if ((cmd == 0 || cmd == 0x3) && | 825 | if ((cmd == 0 || cmd == 0x3) && |
808 | (start >> 28) != (ctx->parser->adev->uvd.gpu_addr >> 28)) { | 826 | (start >> 28) != (ctx->parser->adev->uvd.inst->gpu_addr >> 28)) { |
809 | DRM_ERROR("msg/fb buffer %LX-%LX out of 256MB segment!\n", | 827 | DRM_ERROR("msg/fb buffer %LX-%LX out of 256MB segment!\n", |
810 | start, end); | 828 | start, end); |
811 | return -EINVAL; | 829 | return -EINVAL; |
@@ -973,6 +991,8 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo, | |||
973 | uint64_t addr; | 991 | uint64_t addr; |
974 | long r; | 992 | long r; |
975 | int i; | 993 | int i; |
994 | unsigned offset_idx = 0; | ||
995 | unsigned offset[3] = { UVD_BASE_SI, 0, 0 }; | ||
976 | 996 | ||
977 | amdgpu_bo_kunmap(bo); | 997 | amdgpu_bo_kunmap(bo); |
978 | amdgpu_bo_unpin(bo); | 998 | amdgpu_bo_unpin(bo); |
@@ -992,17 +1012,16 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo, | |||
992 | goto err; | 1012 | goto err; |
993 | 1013 | ||
994 | if (adev->asic_type >= CHIP_VEGA10) { | 1014 | if (adev->asic_type >= CHIP_VEGA10) { |
995 | data[0] = PACKET0(mmUVD_GPCOM_VCPU_DATA0_VEGA10, 0); | 1015 | offset_idx = 1 + ring->me; |
996 | data[1] = PACKET0(mmUVD_GPCOM_VCPU_DATA1_VEGA10, 0); | 1016 | offset[1] = adev->reg_offset[UVD_HWIP][0][1]; |
997 | data[2] = PACKET0(mmUVD_GPCOM_VCPU_CMD_VEGA10, 0); | 1017 | offset[2] = adev->reg_offset[UVD_HWIP][1][1]; |
998 | data[3] = PACKET0(mmUVD_NO_OP_VEGA10, 0); | ||
999 | } else { | ||
1000 | data[0] = PACKET0(mmUVD_GPCOM_VCPU_DATA0, 0); | ||
1001 | data[1] = PACKET0(mmUVD_GPCOM_VCPU_DATA1, 0); | ||
1002 | data[2] = PACKET0(mmUVD_GPCOM_VCPU_CMD, 0); | ||
1003 | data[3] = PACKET0(mmUVD_NO_OP, 0); | ||
1004 | } | 1018 | } |
1005 | 1019 | ||
1020 | data[0] = PACKET0(offset[offset_idx] + UVD_GPCOM_VCPU_DATA0, 0); | ||
1021 | data[1] = PACKET0(offset[offset_idx] + UVD_GPCOM_VCPU_DATA1, 0); | ||
1022 | data[2] = PACKET0(offset[offset_idx] + UVD_GPCOM_VCPU_CMD, 0); | ||
1023 | data[3] = PACKET0(offset[offset_idx] + UVD_NO_OP, 0); | ||
1024 | |||
1006 | ib = &job->ibs[0]; | 1025 | ib = &job->ibs[0]; |
1007 | addr = amdgpu_bo_gpu_offset(bo); | 1026 | addr = amdgpu_bo_gpu_offset(bo); |
1008 | ib->ptr[0] = data[0]; | 1027 | ib->ptr[0] = data[0]; |
@@ -1038,7 +1057,7 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo, | |||
1038 | if (r) | 1057 | if (r) |
1039 | goto err_free; | 1058 | goto err_free; |
1040 | 1059 | ||
1041 | r = amdgpu_job_submit(job, ring, &adev->uvd.entity, | 1060 | r = amdgpu_job_submit(job, ring, &adev->uvd.inst[ring->me].entity, |
1042 | AMDGPU_FENCE_OWNER_UNDEFINED, &f); | 1061 | AMDGPU_FENCE_OWNER_UNDEFINED, &f); |
1043 | if (r) | 1062 | if (r) |
1044 | goto err_free; | 1063 | goto err_free; |
@@ -1126,8 +1145,15 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, | |||
1126 | static void amdgpu_uvd_idle_work_handler(struct work_struct *work) | 1145 | static void amdgpu_uvd_idle_work_handler(struct work_struct *work) |
1127 | { | 1146 | { |
1128 | struct amdgpu_device *adev = | 1147 | struct amdgpu_device *adev = |
1129 | container_of(work, struct amdgpu_device, uvd.idle_work.work); | 1148 | container_of(work, struct amdgpu_device, uvd.inst->idle_work.work); |
1130 | unsigned fences = amdgpu_fence_count_emitted(&adev->uvd.ring); | 1149 | unsigned fences = 0, i, j; |
1150 | |||
1151 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { | ||
1152 | fences += amdgpu_fence_count_emitted(&adev->uvd.inst[i].ring); | ||
1153 | for (j = 0; j < adev->uvd.num_enc_rings; ++j) { | ||
1154 | fences += amdgpu_fence_count_emitted(&adev->uvd.inst[i].ring_enc[j]); | ||
1155 | } | ||
1156 | } | ||
1131 | 1157 | ||
1132 | if (fences == 0) { | 1158 | if (fences == 0) { |
1133 | if (adev->pm.dpm_enabled) { | 1159 | if (adev->pm.dpm_enabled) { |
@@ -1141,7 +1167,7 @@ static void amdgpu_uvd_idle_work_handler(struct work_struct *work) | |||
1141 | AMD_CG_STATE_GATE); | 1167 | AMD_CG_STATE_GATE); |
1142 | } | 1168 | } |
1143 | } else { | 1169 | } else { |
1144 | schedule_delayed_work(&adev->uvd.idle_work, UVD_IDLE_TIMEOUT); | 1170 | schedule_delayed_work(&adev->uvd.inst->idle_work, UVD_IDLE_TIMEOUT); |
1145 | } | 1171 | } |
1146 | } | 1172 | } |
1147 | 1173 | ||
@@ -1153,7 +1179,7 @@ void amdgpu_uvd_ring_begin_use(struct amdgpu_ring *ring) | |||
1153 | if (amdgpu_sriov_vf(adev)) | 1179 | if (amdgpu_sriov_vf(adev)) |
1154 | return; | 1180 | return; |
1155 | 1181 | ||
1156 | set_clocks = !cancel_delayed_work_sync(&adev->uvd.idle_work); | 1182 | set_clocks = !cancel_delayed_work_sync(&adev->uvd.inst->idle_work); |
1157 | if (set_clocks) { | 1183 | if (set_clocks) { |
1158 | if (adev->pm.dpm_enabled) { | 1184 | if (adev->pm.dpm_enabled) { |
1159 | amdgpu_dpm_enable_uvd(adev, true); | 1185 | amdgpu_dpm_enable_uvd(adev, true); |
@@ -1170,7 +1196,7 @@ void amdgpu_uvd_ring_begin_use(struct amdgpu_ring *ring) | |||
1170 | void amdgpu_uvd_ring_end_use(struct amdgpu_ring *ring) | 1196 | void amdgpu_uvd_ring_end_use(struct amdgpu_ring *ring) |
1171 | { | 1197 | { |
1172 | if (!amdgpu_sriov_vf(ring->adev)) | 1198 | if (!amdgpu_sriov_vf(ring->adev)) |
1173 | schedule_delayed_work(&ring->adev->uvd.idle_work, UVD_IDLE_TIMEOUT); | 1199 | schedule_delayed_work(&ring->adev->uvd.inst->idle_work, UVD_IDLE_TIMEOUT); |
1174 | } | 1200 | } |
1175 | 1201 | ||
1176 | /** | 1202 | /** |
@@ -1184,27 +1210,28 @@ int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
1184 | { | 1210 | { |
1185 | struct dma_fence *fence; | 1211 | struct dma_fence *fence; |
1186 | long r; | 1212 | long r; |
1213 | uint32_t ip_instance = ring->me; | ||
1187 | 1214 | ||
1188 | r = amdgpu_uvd_get_create_msg(ring, 1, NULL); | 1215 | r = amdgpu_uvd_get_create_msg(ring, 1, NULL); |
1189 | if (r) { | 1216 | if (r) { |
1190 | DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r); | 1217 | DRM_ERROR("amdgpu: (%d)failed to get create msg (%ld).\n", ip_instance, r); |
1191 | goto error; | 1218 | goto error; |
1192 | } | 1219 | } |
1193 | 1220 | ||
1194 | r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence); | 1221 | r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence); |
1195 | if (r) { | 1222 | if (r) { |
1196 | DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r); | 1223 | DRM_ERROR("amdgpu: (%d)failed to get destroy ib (%ld).\n", ip_instance, r); |
1197 | goto error; | 1224 | goto error; |
1198 | } | 1225 | } |
1199 | 1226 | ||
1200 | r = dma_fence_wait_timeout(fence, false, timeout); | 1227 | r = dma_fence_wait_timeout(fence, false, timeout); |
1201 | if (r == 0) { | 1228 | if (r == 0) { |
1202 | DRM_ERROR("amdgpu: IB test timed out.\n"); | 1229 | DRM_ERROR("amdgpu: (%d)IB test timed out.\n", ip_instance); |
1203 | r = -ETIMEDOUT; | 1230 | r = -ETIMEDOUT; |
1204 | } else if (r < 0) { | 1231 | } else if (r < 0) { |
1205 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | 1232 | DRM_ERROR("amdgpu: (%d)fence wait failed (%ld).\n", ip_instance, r); |
1206 | } else { | 1233 | } else { |
1207 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | 1234 | DRM_DEBUG("ib test on (%d)ring %d succeeded\n", ip_instance, ring->idx); |
1208 | r = 0; | 1235 | r = 0; |
1209 | } | 1236 | } |
1210 | 1237 | ||
@@ -1232,7 +1259,7 @@ uint32_t amdgpu_uvd_used_handles(struct amdgpu_device *adev) | |||
1232 | * necessarily linear. So we need to count | 1259 | * necessarily linear. So we need to count |
1233 | * all non-zero handles. | 1260 | * all non-zero handles. |
1234 | */ | 1261 | */ |
1235 | if (atomic_read(&adev->uvd.handles[i])) | 1262 | if (atomic_read(&adev->uvd.inst->handles[i])) |
1236 | used_handles++; | 1263 | used_handles++; |
1237 | } | 1264 | } |
1238 | 1265 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h index 32ea20b99e53..b1579fba134c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h | |||
@@ -31,30 +31,37 @@ | |||
31 | #define AMDGPU_UVD_SESSION_SIZE (50*1024) | 31 | #define AMDGPU_UVD_SESSION_SIZE (50*1024) |
32 | #define AMDGPU_UVD_FIRMWARE_OFFSET 256 | 32 | #define AMDGPU_UVD_FIRMWARE_OFFSET 256 |
33 | 33 | ||
34 | #define AMDGPU_MAX_UVD_INSTANCES 2 | ||
35 | |||
34 | #define AMDGPU_UVD_FIRMWARE_SIZE(adev) \ | 36 | #define AMDGPU_UVD_FIRMWARE_SIZE(adev) \ |
35 | (AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(((const struct common_firmware_header *)(adev)->uvd.fw->data)->ucode_size_bytes) + \ | 37 | (AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(((const struct common_firmware_header *)(adev)->uvd.fw->data)->ucode_size_bytes) + \ |
36 | 8) - AMDGPU_UVD_FIRMWARE_OFFSET) | 38 | 8) - AMDGPU_UVD_FIRMWARE_OFFSET) |
37 | 39 | ||
38 | struct amdgpu_uvd { | 40 | struct amdgpu_uvd_inst { |
39 | struct amdgpu_bo *vcpu_bo; | 41 | struct amdgpu_bo *vcpu_bo; |
40 | void *cpu_addr; | 42 | void *cpu_addr; |
41 | uint64_t gpu_addr; | 43 | uint64_t gpu_addr; |
42 | unsigned fw_version; | ||
43 | void *saved_bo; | 44 | void *saved_bo; |
44 | unsigned max_handles; | ||
45 | atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; | 45 | atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; |
46 | struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; | 46 | struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; |
47 | struct delayed_work idle_work; | 47 | struct delayed_work idle_work; |
48 | const struct firmware *fw; /* UVD firmware */ | ||
49 | struct amdgpu_ring ring; | 48 | struct amdgpu_ring ring; |
50 | struct amdgpu_ring ring_enc[AMDGPU_MAX_UVD_ENC_RINGS]; | 49 | struct amdgpu_ring ring_enc[AMDGPU_MAX_UVD_ENC_RINGS]; |
51 | struct amdgpu_irq_src irq; | 50 | struct amdgpu_irq_src irq; |
52 | bool address_64_bit; | ||
53 | bool use_ctx_buf; | ||
54 | struct drm_sched_entity entity; | 51 | struct drm_sched_entity entity; |
55 | struct drm_sched_entity entity_enc; | 52 | struct drm_sched_entity entity_enc; |
56 | uint32_t srbm_soft_reset; | 53 | uint32_t srbm_soft_reset; |
54 | }; | ||
55 | |||
56 | struct amdgpu_uvd { | ||
57 | const struct firmware *fw; /* UVD firmware */ | ||
58 | unsigned fw_version; | ||
59 | unsigned max_handles; | ||
57 | unsigned num_enc_rings; | 60 | unsigned num_enc_rings; |
61 | uint8_t num_uvd_inst; | ||
62 | bool address_64_bit; | ||
63 | bool use_ctx_buf; | ||
64 | struct amdgpu_uvd_inst inst[AMDGPU_MAX_UVD_INSTANCES]; | ||
58 | }; | 65 | }; |
59 | 66 | ||
60 | int amdgpu_uvd_sw_init(struct amdgpu_device *adev); | 67 | int amdgpu_uvd_sw_init(struct amdgpu_device *adev); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index a86322f5164f..23d960ec1cf2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | |||
@@ -57,6 +57,7 @@ | |||
57 | 57 | ||
58 | #define FIRMWARE_VEGA10 "amdgpu/vega10_vce.bin" | 58 | #define FIRMWARE_VEGA10 "amdgpu/vega10_vce.bin" |
59 | #define FIRMWARE_VEGA12 "amdgpu/vega12_vce.bin" | 59 | #define FIRMWARE_VEGA12 "amdgpu/vega12_vce.bin" |
60 | #define FIRMWARE_VEGA20 "amdgpu/vega20_vce.bin" | ||
60 | 61 | ||
61 | #ifdef CONFIG_DRM_AMDGPU_CIK | 62 | #ifdef CONFIG_DRM_AMDGPU_CIK |
62 | MODULE_FIRMWARE(FIRMWARE_BONAIRE); | 63 | MODULE_FIRMWARE(FIRMWARE_BONAIRE); |
@@ -76,6 +77,7 @@ MODULE_FIRMWARE(FIRMWARE_VEGAM); | |||
76 | 77 | ||
77 | MODULE_FIRMWARE(FIRMWARE_VEGA10); | 78 | MODULE_FIRMWARE(FIRMWARE_VEGA10); |
78 | MODULE_FIRMWARE(FIRMWARE_VEGA12); | 79 | MODULE_FIRMWARE(FIRMWARE_VEGA12); |
80 | MODULE_FIRMWARE(FIRMWARE_VEGA20); | ||
79 | 81 | ||
80 | static void amdgpu_vce_idle_work_handler(struct work_struct *work); | 82 | static void amdgpu_vce_idle_work_handler(struct work_struct *work); |
81 | 83 | ||
@@ -143,6 +145,9 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size) | |||
143 | case CHIP_VEGA12: | 145 | case CHIP_VEGA12: |
144 | fw_name = FIRMWARE_VEGA12; | 146 | fw_name = FIRMWARE_VEGA12; |
145 | break; | 147 | break; |
148 | case CHIP_VEGA20: | ||
149 | fw_name = FIRMWARE_VEGA20; | ||
150 | break; | ||
146 | 151 | ||
147 | default: | 152 | default: |
148 | return -EINVAL; | 153 | return -EINVAL; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index e5d234cf804f..8851bcdfc260 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | |||
@@ -205,13 +205,18 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work) | |||
205 | struct amdgpu_device *adev = | 205 | struct amdgpu_device *adev = |
206 | container_of(work, struct amdgpu_device, vcn.idle_work.work); | 206 | container_of(work, struct amdgpu_device, vcn.idle_work.work); |
207 | unsigned fences = amdgpu_fence_count_emitted(&adev->vcn.ring_dec); | 207 | unsigned fences = amdgpu_fence_count_emitted(&adev->vcn.ring_dec); |
208 | unsigned i; | ||
209 | |||
210 | for (i = 0; i < adev->vcn.num_enc_rings; ++i) { | ||
211 | fences += amdgpu_fence_count_emitted(&adev->vcn.ring_enc[i]); | ||
212 | } | ||
208 | 213 | ||
209 | if (fences == 0) { | 214 | if (fences == 0) { |
210 | if (adev->pm.dpm_enabled) { | 215 | if (adev->pm.dpm_enabled) |
211 | /* might be used when with pg/cg | ||
212 | amdgpu_dpm_enable_uvd(adev, false); | 216 | amdgpu_dpm_enable_uvd(adev, false); |
213 | */ | 217 | else |
214 | } | 218 | amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, |
219 | AMD_PG_STATE_GATE); | ||
215 | } else { | 220 | } else { |
216 | schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT); | 221 | schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT); |
217 | } | 222 | } |
@@ -223,9 +228,11 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring) | |||
223 | bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work); | 228 | bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work); |
224 | 229 | ||
225 | if (set_clocks && adev->pm.dpm_enabled) { | 230 | if (set_clocks && adev->pm.dpm_enabled) { |
226 | /* might be used when with pg/cg | 231 | if (adev->pm.dpm_enabled) |
227 | amdgpu_dpm_enable_uvd(adev, true); | 232 | amdgpu_dpm_enable_uvd(adev, true); |
228 | */ | 233 | else |
234 | amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, | ||
235 | AMD_PG_STATE_UNGATE); | ||
229 | } | 236 | } |
230 | } | 237 | } |
231 | 238 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h index 2fd7db891689..181e6afa9847 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | |||
@@ -45,6 +45,17 @@ | |||
45 | #define VCN_ENC_CMD_REG_WRITE 0x0000000b | 45 | #define VCN_ENC_CMD_REG_WRITE 0x0000000b |
46 | #define VCN_ENC_CMD_REG_WAIT 0x0000000c | 46 | #define VCN_ENC_CMD_REG_WAIT 0x0000000c |
47 | 47 | ||
48 | enum engine_status_constants { | ||
49 | UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON = 0x2AAAA0, | ||
50 | UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON = 0x00000002, | ||
51 | UVD_STATUS__UVD_BUSY = 0x00000004, | ||
52 | GB_ADDR_CONFIG_DEFAULT = 0x26010011, | ||
53 | UVD_STATUS__IDLE = 0x2, | ||
54 | UVD_STATUS__BUSY = 0x5, | ||
55 | UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF = 0x1, | ||
56 | UVD_STATUS__RBC_BUSY = 0x1, | ||
57 | }; | ||
58 | |||
48 | struct amdgpu_vcn { | 59 | struct amdgpu_vcn { |
49 | struct amdgpu_bo *vcpu_bo; | 60 | struct amdgpu_bo *vcpu_bo; |
50 | void *cpu_addr; | 61 | void *cpu_addr; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 1a8f4e0dd023..ccba88cc8c54 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -119,9 +119,7 @@ static void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base, | |||
119 | * is currently evicted. add the bo to the evicted list to make sure it | 119 | * is currently evicted. add the bo to the evicted list to make sure it |
120 | * is validated on next vm use to avoid fault. | 120 | * is validated on next vm use to avoid fault. |
121 | * */ | 121 | * */ |
122 | spin_lock(&vm->status_lock); | ||
123 | list_move_tail(&base->vm_status, &vm->evicted); | 122 | list_move_tail(&base->vm_status, &vm->evicted); |
124 | spin_unlock(&vm->status_lock); | ||
125 | } | 123 | } |
126 | 124 | ||
127 | /** | 125 | /** |
@@ -226,24 +224,16 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
226 | void *param) | 224 | void *param) |
227 | { | 225 | { |
228 | struct ttm_bo_global *glob = adev->mman.bdev.glob; | 226 | struct ttm_bo_global *glob = adev->mman.bdev.glob; |
229 | int r; | 227 | struct amdgpu_vm_bo_base *bo_base, *tmp; |
230 | 228 | int r = 0; | |
231 | spin_lock(&vm->status_lock); | ||
232 | while (!list_empty(&vm->evicted)) { | ||
233 | struct amdgpu_vm_bo_base *bo_base; | ||
234 | struct amdgpu_bo *bo; | ||
235 | 229 | ||
236 | bo_base = list_first_entry(&vm->evicted, | 230 | list_for_each_entry_safe(bo_base, tmp, &vm->evicted, vm_status) { |
237 | struct amdgpu_vm_bo_base, | 231 | struct amdgpu_bo *bo = bo_base->bo; |
238 | vm_status); | ||
239 | spin_unlock(&vm->status_lock); | ||
240 | 232 | ||
241 | bo = bo_base->bo; | ||
242 | BUG_ON(!bo); | ||
243 | if (bo->parent) { | 233 | if (bo->parent) { |
244 | r = validate(param, bo); | 234 | r = validate(param, bo); |
245 | if (r) | 235 | if (r) |
246 | return r; | 236 | break; |
247 | 237 | ||
248 | spin_lock(&glob->lru_lock); | 238 | spin_lock(&glob->lru_lock); |
249 | ttm_bo_move_to_lru_tail(&bo->tbo); | 239 | ttm_bo_move_to_lru_tail(&bo->tbo); |
@@ -252,22 +242,29 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
252 | spin_unlock(&glob->lru_lock); | 242 | spin_unlock(&glob->lru_lock); |
253 | } | 243 | } |
254 | 244 | ||
255 | if (bo->tbo.type == ttm_bo_type_kernel && | 245 | if (bo->tbo.type != ttm_bo_type_kernel) { |
256 | vm->use_cpu_for_update) { | 246 | spin_lock(&vm->moved_lock); |
257 | r = amdgpu_bo_kmap(bo, NULL); | ||
258 | if (r) | ||
259 | return r; | ||
260 | } | ||
261 | |||
262 | spin_lock(&vm->status_lock); | ||
263 | if (bo->tbo.type != ttm_bo_type_kernel) | ||
264 | list_move(&bo_base->vm_status, &vm->moved); | 247 | list_move(&bo_base->vm_status, &vm->moved); |
265 | else | 248 | spin_unlock(&vm->moved_lock); |
249 | } else { | ||
266 | list_move(&bo_base->vm_status, &vm->relocated); | 250 | list_move(&bo_base->vm_status, &vm->relocated); |
251 | } | ||
267 | } | 252 | } |
268 | spin_unlock(&vm->status_lock); | ||
269 | 253 | ||
270 | return 0; | 254 | spin_lock(&glob->lru_lock); |
255 | list_for_each_entry(bo_base, &vm->idle, vm_status) { | ||
256 | struct amdgpu_bo *bo = bo_base->bo; | ||
257 | |||
258 | if (!bo->parent) | ||
259 | continue; | ||
260 | |||
261 | ttm_bo_move_to_lru_tail(&bo->tbo); | ||
262 | if (bo->shadow) | ||
263 | ttm_bo_move_to_lru_tail(&bo->shadow->tbo); | ||
264 | } | ||
265 | spin_unlock(&glob->lru_lock); | ||
266 | |||
267 | return r; | ||
271 | } | 268 | } |
272 | 269 | ||
273 | /** | 270 | /** |
@@ -279,13 +276,7 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
279 | */ | 276 | */ |
280 | bool amdgpu_vm_ready(struct amdgpu_vm *vm) | 277 | bool amdgpu_vm_ready(struct amdgpu_vm *vm) |
281 | { | 278 | { |
282 | bool ready; | 279 | return list_empty(&vm->evicted); |
283 | |||
284 | spin_lock(&vm->status_lock); | ||
285 | ready = list_empty(&vm->evicted); | ||
286 | spin_unlock(&vm->status_lock); | ||
287 | |||
288 | return ready; | ||
289 | } | 280 | } |
290 | 281 | ||
291 | /** | 282 | /** |
@@ -477,9 +468,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, | |||
477 | pt->parent = amdgpu_bo_ref(parent->base.bo); | 468 | pt->parent = amdgpu_bo_ref(parent->base.bo); |
478 | 469 | ||
479 | amdgpu_vm_bo_base_init(&entry->base, vm, pt); | 470 | amdgpu_vm_bo_base_init(&entry->base, vm, pt); |
480 | spin_lock(&vm->status_lock); | ||
481 | list_move(&entry->base.vm_status, &vm->relocated); | 471 | list_move(&entry->base.vm_status, &vm->relocated); |
482 | spin_unlock(&vm->status_lock); | ||
483 | } | 472 | } |
484 | 473 | ||
485 | if (level < AMDGPU_VM_PTB) { | 474 | if (level < AMDGPU_VM_PTB) { |
@@ -926,10 +915,8 @@ static void amdgpu_vm_invalidate_level(struct amdgpu_device *adev, | |||
926 | if (!entry->base.bo) | 915 | if (!entry->base.bo) |
927 | continue; | 916 | continue; |
928 | 917 | ||
929 | spin_lock(&vm->status_lock); | 918 | if (!entry->base.moved) |
930 | if (list_empty(&entry->base.vm_status)) | 919 | list_move(&entry->base.vm_status, &vm->relocated); |
931 | list_add(&entry->base.vm_status, &vm->relocated); | ||
932 | spin_unlock(&vm->status_lock); | ||
933 | amdgpu_vm_invalidate_level(adev, vm, entry, level + 1); | 920 | amdgpu_vm_invalidate_level(adev, vm, entry, level + 1); |
934 | } | 921 | } |
935 | } | 922 | } |
@@ -959,6 +946,14 @@ restart: | |||
959 | params.adev = adev; | 946 | params.adev = adev; |
960 | 947 | ||
961 | if (vm->use_cpu_for_update) { | 948 | if (vm->use_cpu_for_update) { |
949 | struct amdgpu_vm_bo_base *bo_base; | ||
950 | |||
951 | list_for_each_entry(bo_base, &vm->relocated, vm_status) { | ||
952 | r = amdgpu_bo_kmap(bo_base->bo, NULL); | ||
953 | if (unlikely(r)) | ||
954 | return r; | ||
955 | } | ||
956 | |||
962 | r = amdgpu_vm_wait_pd(adev, vm, AMDGPU_FENCE_OWNER_VM); | 957 | r = amdgpu_vm_wait_pd(adev, vm, AMDGPU_FENCE_OWNER_VM); |
963 | if (unlikely(r)) | 958 | if (unlikely(r)) |
964 | return r; | 959 | return r; |
@@ -974,7 +969,6 @@ restart: | |||
974 | params.func = amdgpu_vm_do_set_ptes; | 969 | params.func = amdgpu_vm_do_set_ptes; |
975 | } | 970 | } |
976 | 971 | ||
977 | spin_lock(&vm->status_lock); | ||
978 | while (!list_empty(&vm->relocated)) { | 972 | while (!list_empty(&vm->relocated)) { |
979 | struct amdgpu_vm_bo_base *bo_base, *parent; | 973 | struct amdgpu_vm_bo_base *bo_base, *parent; |
980 | struct amdgpu_vm_pt *pt, *entry; | 974 | struct amdgpu_vm_pt *pt, *entry; |
@@ -983,14 +977,12 @@ restart: | |||
983 | bo_base = list_first_entry(&vm->relocated, | 977 | bo_base = list_first_entry(&vm->relocated, |
984 | struct amdgpu_vm_bo_base, | 978 | struct amdgpu_vm_bo_base, |
985 | vm_status); | 979 | vm_status); |
986 | list_del_init(&bo_base->vm_status); | 980 | bo_base->moved = false; |
987 | spin_unlock(&vm->status_lock); | 981 | list_move(&bo_base->vm_status, &vm->idle); |
988 | 982 | ||
989 | bo = bo_base->bo->parent; | 983 | bo = bo_base->bo->parent; |
990 | if (!bo) { | 984 | if (!bo) |
991 | spin_lock(&vm->status_lock); | ||
992 | continue; | 985 | continue; |
993 | } | ||
994 | 986 | ||
995 | parent = list_first_entry(&bo->va, struct amdgpu_vm_bo_base, | 987 | parent = list_first_entry(&bo->va, struct amdgpu_vm_bo_base, |
996 | bo_list); | 988 | bo_list); |
@@ -999,12 +991,10 @@ restart: | |||
999 | 991 | ||
1000 | amdgpu_vm_update_pde(¶ms, vm, pt, entry); | 992 | amdgpu_vm_update_pde(¶ms, vm, pt, entry); |
1001 | 993 | ||
1002 | spin_lock(&vm->status_lock); | ||
1003 | if (!vm->use_cpu_for_update && | 994 | if (!vm->use_cpu_for_update && |
1004 | (ndw - params.ib->length_dw) < 32) | 995 | (ndw - params.ib->length_dw) < 32) |
1005 | break; | 996 | break; |
1006 | } | 997 | } |
1007 | spin_unlock(&vm->status_lock); | ||
1008 | 998 | ||
1009 | if (vm->use_cpu_for_update) { | 999 | if (vm->use_cpu_for_update) { |
1010 | /* Flush HDP */ | 1000 | /* Flush HDP */ |
@@ -1107,9 +1097,7 @@ static void amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p, | |||
1107 | if (entry->huge) { | 1097 | if (entry->huge) { |
1108 | /* Add the entry to the relocated list to update it. */ | 1098 | /* Add the entry to the relocated list to update it. */ |
1109 | entry->huge = false; | 1099 | entry->huge = false; |
1110 | spin_lock(&p->vm->status_lock); | ||
1111 | list_move(&entry->base.vm_status, &p->vm->relocated); | 1100 | list_move(&entry->base.vm_status, &p->vm->relocated); |
1112 | spin_unlock(&p->vm->status_lock); | ||
1113 | } | 1101 | } |
1114 | return; | 1102 | return; |
1115 | } | 1103 | } |
@@ -1588,18 +1576,22 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, | |||
1588 | amdgpu_asic_flush_hdp(adev, NULL); | 1576 | amdgpu_asic_flush_hdp(adev, NULL); |
1589 | } | 1577 | } |
1590 | 1578 | ||
1591 | spin_lock(&vm->status_lock); | 1579 | spin_lock(&vm->moved_lock); |
1592 | list_del_init(&bo_va->base.vm_status); | 1580 | list_del_init(&bo_va->base.vm_status); |
1581 | spin_unlock(&vm->moved_lock); | ||
1593 | 1582 | ||
1594 | /* If the BO is not in its preferred location add it back to | 1583 | /* If the BO is not in its preferred location add it back to |
1595 | * the evicted list so that it gets validated again on the | 1584 | * the evicted list so that it gets validated again on the |
1596 | * next command submission. | 1585 | * next command submission. |
1597 | */ | 1586 | */ |
1598 | if (bo && bo->tbo.resv == vm->root.base.bo->tbo.resv && | 1587 | if (bo && bo->tbo.resv == vm->root.base.bo->tbo.resv) { |
1599 | !(bo->preferred_domains & | 1588 | uint32_t mem_type = bo->tbo.mem.mem_type; |
1600 | amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type))) | 1589 | |
1601 | list_add_tail(&bo_va->base.vm_status, &vm->evicted); | 1590 | if (!(bo->preferred_domains & amdgpu_mem_type_to_domain(mem_type))) |
1602 | spin_unlock(&vm->status_lock); | 1591 | list_add_tail(&bo_va->base.vm_status, &vm->evicted); |
1592 | else | ||
1593 | list_add(&bo_va->base.vm_status, &vm->idle); | ||
1594 | } | ||
1603 | 1595 | ||
1604 | list_splice_init(&bo_va->invalids, &bo_va->valids); | 1596 | list_splice_init(&bo_va->invalids, &bo_va->valids); |
1605 | bo_va->cleared = clear; | 1597 | bo_va->cleared = clear; |
@@ -1808,19 +1800,18 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, | |||
1808 | int amdgpu_vm_handle_moved(struct amdgpu_device *adev, | 1800 | int amdgpu_vm_handle_moved(struct amdgpu_device *adev, |
1809 | struct amdgpu_vm *vm) | 1801 | struct amdgpu_vm *vm) |
1810 | { | 1802 | { |
1803 | struct amdgpu_bo_va *bo_va, *tmp; | ||
1804 | struct list_head moved; | ||
1811 | bool clear; | 1805 | bool clear; |
1812 | int r = 0; | 1806 | int r; |
1813 | |||
1814 | spin_lock(&vm->status_lock); | ||
1815 | while (!list_empty(&vm->moved)) { | ||
1816 | struct amdgpu_bo_va *bo_va; | ||
1817 | struct reservation_object *resv; | ||
1818 | 1807 | ||
1819 | bo_va = list_first_entry(&vm->moved, | 1808 | INIT_LIST_HEAD(&moved); |
1820 | struct amdgpu_bo_va, base.vm_status); | 1809 | spin_lock(&vm->moved_lock); |
1821 | spin_unlock(&vm->status_lock); | 1810 | list_splice_init(&vm->moved, &moved); |
1811 | spin_unlock(&vm->moved_lock); | ||
1822 | 1812 | ||
1823 | resv = bo_va->base.bo->tbo.resv; | 1813 | list_for_each_entry_safe(bo_va, tmp, &moved, base.vm_status) { |
1814 | struct reservation_object *resv = bo_va->base.bo->tbo.resv; | ||
1824 | 1815 | ||
1825 | /* Per VM BOs never need to bo cleared in the page tables */ | 1816 | /* Per VM BOs never need to bo cleared in the page tables */ |
1826 | if (resv == vm->root.base.bo->tbo.resv) | 1817 | if (resv == vm->root.base.bo->tbo.resv) |
@@ -1833,17 +1824,19 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev, | |||
1833 | clear = true; | 1824 | clear = true; |
1834 | 1825 | ||
1835 | r = amdgpu_vm_bo_update(adev, bo_va, clear); | 1826 | r = amdgpu_vm_bo_update(adev, bo_va, clear); |
1836 | if (r) | 1827 | if (r) { |
1828 | spin_lock(&vm->moved_lock); | ||
1829 | list_splice(&moved, &vm->moved); | ||
1830 | spin_unlock(&vm->moved_lock); | ||
1837 | return r; | 1831 | return r; |
1832 | } | ||
1838 | 1833 | ||
1839 | if (!clear && resv != vm->root.base.bo->tbo.resv) | 1834 | if (!clear && resv != vm->root.base.bo->tbo.resv) |
1840 | reservation_object_unlock(resv); | 1835 | reservation_object_unlock(resv); |
1841 | 1836 | ||
1842 | spin_lock(&vm->status_lock); | ||
1843 | } | 1837 | } |
1844 | spin_unlock(&vm->status_lock); | ||
1845 | 1838 | ||
1846 | return r; | 1839 | return 0; |
1847 | } | 1840 | } |
1848 | 1841 | ||
1849 | /** | 1842 | /** |
@@ -1902,11 +1895,11 @@ static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev, | |||
1902 | if (mapping->flags & AMDGPU_PTE_PRT) | 1895 | if (mapping->flags & AMDGPU_PTE_PRT) |
1903 | amdgpu_vm_prt_get(adev); | 1896 | amdgpu_vm_prt_get(adev); |
1904 | 1897 | ||
1905 | if (bo && bo->tbo.resv == vm->root.base.bo->tbo.resv) { | 1898 | if (bo && bo->tbo.resv == vm->root.base.bo->tbo.resv && |
1906 | spin_lock(&vm->status_lock); | 1899 | !bo_va->base.moved) { |
1907 | if (list_empty(&bo_va->base.vm_status)) | 1900 | spin_lock(&vm->moved_lock); |
1908 | list_add(&bo_va->base.vm_status, &vm->moved); | 1901 | list_move(&bo_va->base.vm_status, &vm->moved); |
1909 | spin_unlock(&vm->status_lock); | 1902 | spin_unlock(&vm->moved_lock); |
1910 | } | 1903 | } |
1911 | trace_amdgpu_vm_bo_map(bo_va, mapping); | 1904 | trace_amdgpu_vm_bo_map(bo_va, mapping); |
1912 | } | 1905 | } |
@@ -2216,9 +2209,9 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, | |||
2216 | 2209 | ||
2217 | list_del(&bo_va->base.bo_list); | 2210 | list_del(&bo_va->base.bo_list); |
2218 | 2211 | ||
2219 | spin_lock(&vm->status_lock); | 2212 | spin_lock(&vm->moved_lock); |
2220 | list_del(&bo_va->base.vm_status); | 2213 | list_del(&bo_va->base.vm_status); |
2221 | spin_unlock(&vm->status_lock); | 2214 | spin_unlock(&vm->moved_lock); |
2222 | 2215 | ||
2223 | list_for_each_entry_safe(mapping, next, &bo_va->valids, list) { | 2216 | list_for_each_entry_safe(mapping, next, &bo_va->valids, list) { |
2224 | list_del(&mapping->list); | 2217 | list_del(&mapping->list); |
@@ -2258,31 +2251,28 @@ void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, | |||
2258 | 2251 | ||
2259 | list_for_each_entry(bo_base, &bo->va, bo_list) { | 2252 | list_for_each_entry(bo_base, &bo->va, bo_list) { |
2260 | struct amdgpu_vm *vm = bo_base->vm; | 2253 | struct amdgpu_vm *vm = bo_base->vm; |
2254 | bool was_moved = bo_base->moved; | ||
2261 | 2255 | ||
2262 | bo_base->moved = true; | 2256 | bo_base->moved = true; |
2263 | if (evicted && bo->tbo.resv == vm->root.base.bo->tbo.resv) { | 2257 | if (evicted && bo->tbo.resv == vm->root.base.bo->tbo.resv) { |
2264 | spin_lock(&bo_base->vm->status_lock); | ||
2265 | if (bo->tbo.type == ttm_bo_type_kernel) | 2258 | if (bo->tbo.type == ttm_bo_type_kernel) |
2266 | list_move(&bo_base->vm_status, &vm->evicted); | 2259 | list_move(&bo_base->vm_status, &vm->evicted); |
2267 | else | 2260 | else |
2268 | list_move_tail(&bo_base->vm_status, | 2261 | list_move_tail(&bo_base->vm_status, |
2269 | &vm->evicted); | 2262 | &vm->evicted); |
2270 | spin_unlock(&bo_base->vm->status_lock); | ||
2271 | continue; | 2263 | continue; |
2272 | } | 2264 | } |
2273 | 2265 | ||
2274 | if (bo->tbo.type == ttm_bo_type_kernel) { | 2266 | if (was_moved) |
2275 | spin_lock(&bo_base->vm->status_lock); | ||
2276 | if (list_empty(&bo_base->vm_status)) | ||
2277 | list_add(&bo_base->vm_status, &vm->relocated); | ||
2278 | spin_unlock(&bo_base->vm->status_lock); | ||
2279 | continue; | 2267 | continue; |
2280 | } | ||
2281 | 2268 | ||
2282 | spin_lock(&bo_base->vm->status_lock); | 2269 | if (bo->tbo.type == ttm_bo_type_kernel) { |
2283 | if (list_empty(&bo_base->vm_status)) | 2270 | list_move(&bo_base->vm_status, &vm->relocated); |
2284 | list_add(&bo_base->vm_status, &vm->moved); | 2271 | } else { |
2285 | spin_unlock(&bo_base->vm->status_lock); | 2272 | spin_lock(&bo_base->vm->moved_lock); |
2273 | list_move(&bo_base->vm_status, &vm->moved); | ||
2274 | spin_unlock(&bo_base->vm->moved_lock); | ||
2275 | } | ||
2286 | } | 2276 | } |
2287 | } | 2277 | } |
2288 | 2278 | ||
@@ -2391,10 +2381,11 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
2391 | vm->va = RB_ROOT_CACHED; | 2381 | vm->va = RB_ROOT_CACHED; |
2392 | for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) | 2382 | for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) |
2393 | vm->reserved_vmid[i] = NULL; | 2383 | vm->reserved_vmid[i] = NULL; |
2394 | spin_lock_init(&vm->status_lock); | ||
2395 | INIT_LIST_HEAD(&vm->evicted); | 2384 | INIT_LIST_HEAD(&vm->evicted); |
2396 | INIT_LIST_HEAD(&vm->relocated); | 2385 | INIT_LIST_HEAD(&vm->relocated); |
2386 | spin_lock_init(&vm->moved_lock); | ||
2397 | INIT_LIST_HEAD(&vm->moved); | 2387 | INIT_LIST_HEAD(&vm->moved); |
2388 | INIT_LIST_HEAD(&vm->idle); | ||
2398 | INIT_LIST_HEAD(&vm->freed); | 2389 | INIT_LIST_HEAD(&vm->freed); |
2399 | 2390 | ||
2400 | /* create scheduler entity for page table updates */ | 2391 | /* create scheduler entity for page table updates */ |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 4cf678684a12..061b99a18cb8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | |||
@@ -168,9 +168,6 @@ struct amdgpu_vm { | |||
168 | /* tree of virtual addresses mapped */ | 168 | /* tree of virtual addresses mapped */ |
169 | struct rb_root_cached va; | 169 | struct rb_root_cached va; |
170 | 170 | ||
171 | /* protecting invalidated */ | ||
172 | spinlock_t status_lock; | ||
173 | |||
174 | /* BOs who needs a validation */ | 171 | /* BOs who needs a validation */ |
175 | struct list_head evicted; | 172 | struct list_head evicted; |
176 | 173 | ||
@@ -179,6 +176,10 @@ struct amdgpu_vm { | |||
179 | 176 | ||
180 | /* BOs moved, but not yet updated in the PT */ | 177 | /* BOs moved, but not yet updated in the PT */ |
181 | struct list_head moved; | 178 | struct list_head moved; |
179 | spinlock_t moved_lock; | ||
180 | |||
181 | /* All BOs of this VM not currently in the state machine */ | ||
182 | struct list_head idle; | ||
182 | 183 | ||
183 | /* BO mappings freed, but not yet updated in the PT */ | 184 | /* BO mappings freed, but not yet updated in the PT */ |
184 | struct list_head freed; | 185 | struct list_head freed; |
@@ -187,9 +188,6 @@ struct amdgpu_vm { | |||
187 | struct amdgpu_vm_pt root; | 188 | struct amdgpu_vm_pt root; |
188 | struct dma_fence *last_update; | 189 | struct dma_fence *last_update; |
189 | 190 | ||
190 | /* protecting freed */ | ||
191 | spinlock_t freed_lock; | ||
192 | |||
193 | /* Scheduler entity for page table updates */ | 191 | /* Scheduler entity for page table updates */ |
194 | struct drm_sched_entity entity; | 192 | struct drm_sched_entity entity; |
195 | 193 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c index de7be3de0f41..dbf2ccd0c744 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c | |||
@@ -473,6 +473,7 @@ static int dce_virtual_hw_init(void *handle) | |||
473 | break; | 473 | break; |
474 | case CHIP_VEGA10: | 474 | case CHIP_VEGA10: |
475 | case CHIP_VEGA12: | 475 | case CHIP_VEGA12: |
476 | case CHIP_VEGA20: | ||
476 | break; | 477 | break; |
477 | default: | 478 | default: |
478 | DRM_ERROR("Virtual display unsupported ASIC type: 0x%X\n", adev->asic_type); | 479 | DRM_ERROR("Virtual display unsupported ASIC type: 0x%X\n", adev->asic_type); |
diff --git a/drivers/gpu/drm/amd/amdgpu/df_v1_7.c b/drivers/gpu/drm/amd/amdgpu/df_v1_7.c index 4ffda996660f..9935371db7ce 100644 --- a/drivers/gpu/drm/amd/amdgpu/df_v1_7.c +++ b/drivers/gpu/drm/amd/amdgpu/df_v1_7.c | |||
@@ -102,6 +102,13 @@ static void df_v1_7_get_clockgating_state(struct amdgpu_device *adev, | |||
102 | *flags |= AMD_CG_SUPPORT_DF_MGCG; | 102 | *flags |= AMD_CG_SUPPORT_DF_MGCG; |
103 | } | 103 | } |
104 | 104 | ||
105 | static void df_v1_7_enable_ecc_force_par_wr_rmw(struct amdgpu_device *adev, | ||
106 | bool enable) | ||
107 | { | ||
108 | WREG32_FIELD15(DF, 0, DF_CS_AON0_CoherentSlaveModeCtrlA0, | ||
109 | ForceParWrRMW, enable); | ||
110 | } | ||
111 | |||
105 | const struct amdgpu_df_funcs df_v1_7_funcs = { | 112 | const struct amdgpu_df_funcs df_v1_7_funcs = { |
106 | .init = df_v1_7_init, | 113 | .init = df_v1_7_init, |
107 | .enable_broadcast_mode = df_v1_7_enable_broadcast_mode, | 114 | .enable_broadcast_mode = df_v1_7_enable_broadcast_mode, |
@@ -109,4 +116,5 @@ const struct amdgpu_df_funcs df_v1_7_funcs = { | |||
109 | .get_hbm_channel_number = df_v1_7_get_hbm_channel_number, | 116 | .get_hbm_channel_number = df_v1_7_get_hbm_channel_number, |
110 | .update_medium_grain_clock_gating = df_v1_7_update_medium_grain_clock_gating, | 117 | .update_medium_grain_clock_gating = df_v1_7_update_medium_grain_clock_gating, |
111 | .get_clockgating_state = df_v1_7_get_clockgating_state, | 118 | .get_clockgating_state = df_v1_7_get_clockgating_state, |
119 | .enable_ecc_force_par_wr_rmw = df_v1_7_enable_ecc_force_par_wr_rmw, | ||
112 | }; | 120 | }; |
diff --git a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c new file mode 100644 index 000000000000..60608b3df881 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* | ||
2 | * Copyright 2018 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | #include "amdgpu.h" | ||
24 | #include "df_v3_6.h" | ||
25 | |||
26 | #include "df/df_3_6_default.h" | ||
27 | #include "df/df_3_6_offset.h" | ||
28 | #include "df/df_3_6_sh_mask.h" | ||
29 | |||
30 | static u32 df_v3_6_channel_number[] = {1, 2, 0, 4, 0, 8, 0, | ||
31 | 16, 32, 0, 0, 0, 2, 4, 8}; | ||
32 | |||
33 | static void df_v3_6_init(struct amdgpu_device *adev) | ||
34 | { | ||
35 | } | ||
36 | |||
37 | static void df_v3_6_enable_broadcast_mode(struct amdgpu_device *adev, | ||
38 | bool enable) | ||
39 | { | ||
40 | u32 tmp; | ||
41 | |||
42 | if (enable) { | ||
43 | tmp = RREG32_SOC15(DF, 0, mmFabricConfigAccessControl); | ||
44 | tmp &= ~FabricConfigAccessControl__CfgRegInstAccEn_MASK; | ||
45 | WREG32_SOC15(DF, 0, mmFabricConfigAccessControl, tmp); | ||
46 | } else | ||
47 | WREG32_SOC15(DF, 0, mmFabricConfigAccessControl, | ||
48 | mmFabricConfigAccessControl_DEFAULT); | ||
49 | } | ||
50 | |||
51 | static u32 df_v3_6_get_fb_channel_number(struct amdgpu_device *adev) | ||
52 | { | ||
53 | u32 tmp; | ||
54 | |||
55 | tmp = RREG32_SOC15(DF, 0, mmDF_CS_UMC_AON0_DramBaseAddress0); | ||
56 | tmp &= DF_CS_UMC_AON0_DramBaseAddress0__IntLvNumChan_MASK; | ||
57 | tmp >>= DF_CS_UMC_AON0_DramBaseAddress0__IntLvNumChan__SHIFT; | ||
58 | |||
59 | return tmp; | ||
60 | } | ||
61 | |||
62 | static u32 df_v3_6_get_hbm_channel_number(struct amdgpu_device *adev) | ||
63 | { | ||
64 | int fb_channel_number; | ||
65 | |||
66 | fb_channel_number = adev->df_funcs->get_fb_channel_number(adev); | ||
67 | if (fb_channel_number > ARRAY_SIZE(df_v3_6_channel_number)) | ||
68 | fb_channel_number = 0; | ||
69 | |||
70 | return df_v3_6_channel_number[fb_channel_number]; | ||
71 | } | ||
72 | |||
73 | static void df_v3_6_update_medium_grain_clock_gating(struct amdgpu_device *adev, | ||
74 | bool enable) | ||
75 | { | ||
76 | u32 tmp; | ||
77 | |||
78 | /* Put DF on broadcast mode */ | ||
79 | adev->df_funcs->enable_broadcast_mode(adev, true); | ||
80 | |||
81 | if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DF_MGCG)) { | ||
82 | tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater); | ||
83 | tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK; | ||
84 | tmp |= DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY; | ||
85 | WREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater, tmp); | ||
86 | } else { | ||
87 | tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater); | ||
88 | tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK; | ||
89 | tmp |= DF_V3_6_MGCG_DISABLE; | ||
90 | WREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater, tmp); | ||
91 | } | ||
92 | |||
93 | /* Exit broadcast mode */ | ||
94 | adev->df_funcs->enable_broadcast_mode(adev, false); | ||
95 | } | ||
96 | |||
97 | static void df_v3_6_get_clockgating_state(struct amdgpu_device *adev, | ||
98 | u32 *flags) | ||
99 | { | ||
100 | u32 tmp; | ||
101 | |||
102 | /* AMD_CG_SUPPORT_DF_MGCG */ | ||
103 | tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater); | ||
104 | if (tmp & DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY) | ||
105 | *flags |= AMD_CG_SUPPORT_DF_MGCG; | ||
106 | } | ||
107 | |||
108 | const struct amdgpu_df_funcs df_v3_6_funcs = { | ||
109 | .init = df_v3_6_init, | ||
110 | .enable_broadcast_mode = df_v3_6_enable_broadcast_mode, | ||
111 | .get_fb_channel_number = df_v3_6_get_fb_channel_number, | ||
112 | .get_hbm_channel_number = df_v3_6_get_hbm_channel_number, | ||
113 | .update_medium_grain_clock_gating = | ||
114 | df_v3_6_update_medium_grain_clock_gating, | ||
115 | .get_clockgating_state = df_v3_6_get_clockgating_state, | ||
116 | }; | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/df_v3_6.h b/drivers/gpu/drm/amd/amdgpu/df_v3_6.h new file mode 100644 index 000000000000..e79c58e5efcb --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/df_v3_6.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * Copyright 2018 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifndef __DF_V3_6_H__ | ||
25 | #define __DF_V3_6_H__ | ||
26 | |||
27 | #include "soc15_common.h" | ||
28 | |||
29 | enum DF_V3_6_MGCG { | ||
30 | DF_V3_6_MGCG_DISABLE = 0, | ||
31 | DF_V3_6_MGCG_ENABLE_00_CYCLE_DELAY = 1, | ||
32 | DF_V3_6_MGCG_ENABLE_01_CYCLE_DELAY = 2, | ||
33 | DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY = 13, | ||
34 | DF_V3_6_MGCG_ENABLE_31_CYCLE_DELAY = 14, | ||
35 | DF_V3_6_MGCG_ENABLE_63_CYCLE_DELAY = 15 | ||
36 | }; | ||
37 | |||
38 | extern const struct amdgpu_df_funcs df_v3_6_funcs; | ||
39 | |||
40 | #endif | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index fc1911834ab5..d7530fdfaad5 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "amdgpu_gfx.h" | 27 | #include "amdgpu_gfx.h" |
28 | #include "soc15.h" | 28 | #include "soc15.h" |
29 | #include "soc15d.h" | 29 | #include "soc15d.h" |
30 | #include "amdgpu_atomfirmware.h" | ||
30 | 31 | ||
31 | #include "gc/gc_9_0_offset.h" | 32 | #include "gc/gc_9_0_offset.h" |
32 | #include "gc/gc_9_0_sh_mask.h" | 33 | #include "gc/gc_9_0_sh_mask.h" |
@@ -63,6 +64,13 @@ MODULE_FIRMWARE("amdgpu/vega12_mec.bin"); | |||
63 | MODULE_FIRMWARE("amdgpu/vega12_mec2.bin"); | 64 | MODULE_FIRMWARE("amdgpu/vega12_mec2.bin"); |
64 | MODULE_FIRMWARE("amdgpu/vega12_rlc.bin"); | 65 | MODULE_FIRMWARE("amdgpu/vega12_rlc.bin"); |
65 | 66 | ||
67 | MODULE_FIRMWARE("amdgpu/vega20_ce.bin"); | ||
68 | MODULE_FIRMWARE("amdgpu/vega20_pfp.bin"); | ||
69 | MODULE_FIRMWARE("amdgpu/vega20_me.bin"); | ||
70 | MODULE_FIRMWARE("amdgpu/vega20_mec.bin"); | ||
71 | MODULE_FIRMWARE("amdgpu/vega20_mec2.bin"); | ||
72 | MODULE_FIRMWARE("amdgpu/vega20_rlc.bin"); | ||
73 | |||
66 | MODULE_FIRMWARE("amdgpu/raven_ce.bin"); | 74 | MODULE_FIRMWARE("amdgpu/raven_ce.bin"); |
67 | MODULE_FIRMWARE("amdgpu/raven_pfp.bin"); | 75 | MODULE_FIRMWARE("amdgpu/raven_pfp.bin"); |
68 | MODULE_FIRMWARE("amdgpu/raven_me.bin"); | 76 | MODULE_FIRMWARE("amdgpu/raven_me.bin"); |
@@ -72,29 +80,22 @@ MODULE_FIRMWARE("amdgpu/raven_rlc.bin"); | |||
72 | 80 | ||
73 | static const struct soc15_reg_golden golden_settings_gc_9_0[] = | 81 | static const struct soc15_reg_golden golden_settings_gc_9_0[] = |
74 | { | 82 | { |
75 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCPC_UTCL1_CNTL, 0x08000000, 0x08000080), | ||
76 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCPF_UTCL1_CNTL, 0x08000000, 0x08000080), | ||
77 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCPG_UTCL1_CNTL, 0x08000000, 0x08000080), | ||
78 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG2, 0xf00fffff, 0x00000420), | 83 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG2, 0xf00fffff, 0x00000420), |
79 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_GPU_ID, 0x0000000f, 0x00000000), | 84 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_GPU_ID, 0x0000000f, 0x00000000), |
80 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmIA_UTCL1_CNTL, 0x08000000, 0x08000080), | ||
81 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_EVENT_CNTL_3, 0x00000003, 0x82400024), | 85 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_EVENT_CNTL_3, 0x00000003, 0x82400024), |
82 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE, 0x3fffffff, 0x00000001), | 86 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE, 0x3fffffff, 0x00000001), |
83 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000), | 87 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000), |
84 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_GPM_UTCL1_CNTL_0, 0x08000000, 0x08000080), | ||
85 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_GPM_UTCL1_CNTL_1, 0x08000000, 0x08000080), | ||
86 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_GPM_UTCL1_CNTL_2, 0x08000000, 0x08000080), | ||
87 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_PREWALKER_UTCL1_CNTL, 0x08000000, 0x08000080), | ||
88 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmRLC_SPM_UTCL1_CNTL, 0x08000000, 0x08000080), | ||
89 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSH_MEM_CONFIG, 0x00001000, 0x00001000), | 88 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSH_MEM_CONFIG, 0x00001000, 0x00001000), |
90 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0x0000000f, 0x01000107), | 89 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_RESOURCE_RESERVE_CU_0, 0x0007ffff, 0x00000800), |
90 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_RESOURCE_RESERVE_CU_1, 0x0007ffff, 0x00000800), | ||
91 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_RESOURCE_RESERVE_EN_CU_0, 0x01ffffff, 0x0000ff87), | ||
92 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_RESOURCE_RESERVE_EN_CU_1, 0x01ffffff, 0x0000ff8f), | ||
91 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQC_CONFIG, 0x03000000, 0x020a2000), | 93 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQC_CONFIG, 0x03000000, 0x020a2000), |
92 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfffffeef, 0x010b0000), | 94 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfffffeef, 0x010b0000), |
93 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_HI, 0xffffffff, 0x4a2c0e68), | 95 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_HI, 0xffffffff, 0x4a2c0e68), |
94 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_LO, 0xffffffff, 0xb5d3f197), | 96 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CHAN_STEER_LO, 0xffffffff, 0xb5d3f197), |
95 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_CACHE_INVALIDATION, 0x3fff3af3, 0x19200000), | 97 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_CACHE_INVALIDATION, 0x3fff3af3, 0x19200000), |
96 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000003ff), | 98 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000003ff) |
97 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmWD_UTCL1_CNTL, 0x08000000, 0x08000080) | ||
98 | }; | 99 | }; |
99 | 100 | ||
100 | static const struct soc15_reg_golden golden_settings_gc_9_0_vg10[] = | 101 | static const struct soc15_reg_golden golden_settings_gc_9_0_vg10[] = |
@@ -108,6 +109,20 @@ static const struct soc15_reg_golden golden_settings_gc_9_0_vg10[] = | |||
108 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x00001800, 0x00000800) | 109 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x00001800, 0x00000800) |
109 | }; | 110 | }; |
110 | 111 | ||
112 | static const struct soc15_reg_golden golden_settings_gc_9_0_vg20[] = | ||
113 | { | ||
114 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_2, 0x0f000000, 0x0a000000), | ||
115 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_3, 0x30000000, 0x10000000), | ||
116 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0xf3e777ff, 0x22014042), | ||
117 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG_READ, 0xf3e777ff, 0x22014042), | ||
118 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG2, 0x00003e00, 0x00000400), | ||
119 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_1, 0xff840000, 0x04040000), | ||
120 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_UTCL1_CNTL2, 0x00030000, 0x00030000), | ||
121 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0xffff010f, 0x01000107), | ||
122 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0x000b0000, 0x000b0000), | ||
123 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTD_CNTL, 0x01000000, 0x01000000) | ||
124 | }; | ||
125 | |||
111 | static const struct soc15_reg_golden golden_settings_gc_9_1[] = | 126 | static const struct soc15_reg_golden golden_settings_gc_9_1[] = |
112 | { | 127 | { |
113 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL, 0xfffdf3cf, 0x00014104), | 128 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL, 0xfffdf3cf, 0x00014104), |
@@ -241,6 +256,14 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev) | |||
241 | golden_settings_gc_9_2_1_vg12, | 256 | golden_settings_gc_9_2_1_vg12, |
242 | ARRAY_SIZE(golden_settings_gc_9_2_1_vg12)); | 257 | ARRAY_SIZE(golden_settings_gc_9_2_1_vg12)); |
243 | break; | 258 | break; |
259 | case CHIP_VEGA20: | ||
260 | soc15_program_register_sequence(adev, | ||
261 | golden_settings_gc_9_0, | ||
262 | ARRAY_SIZE(golden_settings_gc_9_0)); | ||
263 | soc15_program_register_sequence(adev, | ||
264 | golden_settings_gc_9_0_vg20, | ||
265 | ARRAY_SIZE(golden_settings_gc_9_0_vg20)); | ||
266 | break; | ||
244 | case CHIP_RAVEN: | 267 | case CHIP_RAVEN: |
245 | soc15_program_register_sequence(adev, | 268 | soc15_program_register_sequence(adev, |
246 | golden_settings_gc_9_1, | 269 | golden_settings_gc_9_1, |
@@ -468,6 +491,9 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) | |||
468 | case CHIP_VEGA12: | 491 | case CHIP_VEGA12: |
469 | chip_name = "vega12"; | 492 | chip_name = "vega12"; |
470 | break; | 493 | break; |
494 | case CHIP_VEGA20: | ||
495 | chip_name = "vega20"; | ||
496 | break; | ||
471 | case CHIP_RAVEN: | 497 | case CHIP_RAVEN: |
472 | chip_name = "raven"; | 498 | chip_name = "raven"; |
473 | break; | 499 | break; |
@@ -1088,9 +1114,10 @@ static const struct amdgpu_gfx_funcs gfx_v9_0_gfx_funcs = { | |||
1088 | .select_me_pipe_q = &gfx_v9_0_select_me_pipe_q | 1114 | .select_me_pipe_q = &gfx_v9_0_select_me_pipe_q |
1089 | }; | 1115 | }; |
1090 | 1116 | ||
1091 | static void gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) | 1117 | static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) |
1092 | { | 1118 | { |
1093 | u32 gb_addr_config; | 1119 | u32 gb_addr_config; |
1120 | int err; | ||
1094 | 1121 | ||
1095 | adev->gfx.funcs = &gfx_v9_0_gfx_funcs; | 1122 | adev->gfx.funcs = &gfx_v9_0_gfx_funcs; |
1096 | 1123 | ||
@@ -1112,6 +1139,20 @@ static void gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) | |||
1112 | gb_addr_config = VEGA12_GB_ADDR_CONFIG_GOLDEN; | 1139 | gb_addr_config = VEGA12_GB_ADDR_CONFIG_GOLDEN; |
1113 | DRM_INFO("fix gfx.config for vega12\n"); | 1140 | DRM_INFO("fix gfx.config for vega12\n"); |
1114 | break; | 1141 | break; |
1142 | case CHIP_VEGA20: | ||
1143 | adev->gfx.config.max_hw_contexts = 8; | ||
1144 | adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; | ||
1145 | adev->gfx.config.sc_prim_fifo_size_backend = 0x100; | ||
1146 | adev->gfx.config.sc_hiz_tile_fifo_size = 0x30; | ||
1147 | adev->gfx.config.sc_earlyz_tile_fifo_size = 0x4C0; | ||
1148 | gb_addr_config = RREG32_SOC15(GC, 0, mmGB_ADDR_CONFIG); | ||
1149 | gb_addr_config &= ~0xf3e777ff; | ||
1150 | gb_addr_config |= 0x22014042; | ||
1151 | /* check vbios table if gpu info is not available */ | ||
1152 | err = amdgpu_atomfirmware_get_gfx_info(adev); | ||
1153 | if (err) | ||
1154 | return err; | ||
1155 | break; | ||
1115 | case CHIP_RAVEN: | 1156 | case CHIP_RAVEN: |
1116 | adev->gfx.config.max_hw_contexts = 8; | 1157 | adev->gfx.config.max_hw_contexts = 8; |
1117 | adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; | 1158 | adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; |
@@ -1161,6 +1202,8 @@ static void gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) | |||
1161 | adev->gfx.config.gb_addr_config, | 1202 | adev->gfx.config.gb_addr_config, |
1162 | GB_ADDR_CONFIG, | 1203 | GB_ADDR_CONFIG, |
1163 | PIPE_INTERLEAVE_SIZE)); | 1204 | PIPE_INTERLEAVE_SIZE)); |
1205 | |||
1206 | return 0; | ||
1164 | } | 1207 | } |
1165 | 1208 | ||
1166 | static int gfx_v9_0_ngg_create_buf(struct amdgpu_device *adev, | 1209 | static int gfx_v9_0_ngg_create_buf(struct amdgpu_device *adev, |
@@ -1394,6 +1437,7 @@ static int gfx_v9_0_sw_init(void *handle) | |||
1394 | switch (adev->asic_type) { | 1437 | switch (adev->asic_type) { |
1395 | case CHIP_VEGA10: | 1438 | case CHIP_VEGA10: |
1396 | case CHIP_VEGA12: | 1439 | case CHIP_VEGA12: |
1440 | case CHIP_VEGA20: | ||
1397 | case CHIP_RAVEN: | 1441 | case CHIP_RAVEN: |
1398 | adev->gfx.mec.num_mec = 2; | 1442 | adev->gfx.mec.num_mec = 2; |
1399 | break; | 1443 | break; |
@@ -1521,7 +1565,9 @@ static int gfx_v9_0_sw_init(void *handle) | |||
1521 | 1565 | ||
1522 | adev->gfx.ce_ram_size = 0x8000; | 1566 | adev->gfx.ce_ram_size = 0x8000; |
1523 | 1567 | ||
1524 | gfx_v9_0_gpu_early_init(adev); | 1568 | r = gfx_v9_0_gpu_early_init(adev); |
1569 | if (r) | ||
1570 | return r; | ||
1525 | 1571 | ||
1526 | r = gfx_v9_0_ngg_init(adev); | 1572 | r = gfx_v9_0_ngg_init(adev); |
1527 | if (r) | 1573 | if (r) |
@@ -3688,6 +3734,7 @@ static int gfx_v9_0_set_clockgating_state(void *handle, | |||
3688 | switch (adev->asic_type) { | 3734 | switch (adev->asic_type) { |
3689 | case CHIP_VEGA10: | 3735 | case CHIP_VEGA10: |
3690 | case CHIP_VEGA12: | 3736 | case CHIP_VEGA12: |
3737 | case CHIP_VEGA20: | ||
3691 | case CHIP_RAVEN: | 3738 | case CHIP_RAVEN: |
3692 | gfx_v9_0_update_gfx_clock_gating(adev, | 3739 | gfx_v9_0_update_gfx_clock_gating(adev, |
3693 | state == AMD_CG_STATE_GATE ? true : false); | 3740 | state == AMD_CG_STATE_GATE ? true : false); |
@@ -4680,6 +4727,7 @@ static void gfx_v9_0_set_rlc_funcs(struct amdgpu_device *adev) | |||
4680 | switch (adev->asic_type) { | 4727 | switch (adev->asic_type) { |
4681 | case CHIP_VEGA10: | 4728 | case CHIP_VEGA10: |
4682 | case CHIP_VEGA12: | 4729 | case CHIP_VEGA12: |
4730 | case CHIP_VEGA20: | ||
4683 | case CHIP_RAVEN: | 4731 | case CHIP_RAVEN: |
4684 | adev->gfx.rlc.funcs = &gfx_v9_0_rlc_funcs; | 4732 | adev->gfx.rlc.funcs = &gfx_v9_0_rlc_funcs; |
4685 | break; | 4733 | break; |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 6cccf0e0acd7..3c0a85d4e4ab 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | |||
@@ -675,6 +675,7 @@ static int gmc_v9_0_late_init(void *handle) | |||
675 | DRM_INFO("ECC is active.\n"); | 675 | DRM_INFO("ECC is active.\n"); |
676 | } else if (r == 0) { | 676 | } else if (r == 0) { |
677 | DRM_INFO("ECC is not present.\n"); | 677 | DRM_INFO("ECC is not present.\n"); |
678 | adev->df_funcs->enable_ecc_force_par_wr_rmw(adev, false); | ||
678 | } else { | 679 | } else { |
679 | DRM_ERROR("gmc_v9_0_ecc_available() failed. r: %d\n", r); | 680 | DRM_ERROR("gmc_v9_0_ecc_available() failed. r: %d\n", r); |
680 | return r; | 681 | return r; |
@@ -693,10 +694,7 @@ static void gmc_v9_0_vram_gtt_location(struct amdgpu_device *adev, | |||
693 | amdgpu_device_vram_location(adev, &adev->gmc, base); | 694 | amdgpu_device_vram_location(adev, &adev->gmc, base); |
694 | amdgpu_device_gart_location(adev, mc); | 695 | amdgpu_device_gart_location(adev, mc); |
695 | /* base offset of vram pages */ | 696 | /* base offset of vram pages */ |
696 | if (adev->flags & AMD_IS_APU) | 697 | adev->vm_manager.vram_base_offset = gfxhub_v1_0_get_mc_fb_offset(adev); |
697 | adev->vm_manager.vram_base_offset = gfxhub_v1_0_get_mc_fb_offset(adev); | ||
698 | else | ||
699 | adev->vm_manager.vram_base_offset = 0; | ||
700 | } | 698 | } |
701 | 699 | ||
702 | /** | 700 | /** |
@@ -755,6 +753,7 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev) | |||
755 | switch (adev->asic_type) { | 753 | switch (adev->asic_type) { |
756 | case CHIP_VEGA10: /* all engines support GPUVM */ | 754 | case CHIP_VEGA10: /* all engines support GPUVM */ |
757 | case CHIP_VEGA12: /* all engines support GPUVM */ | 755 | case CHIP_VEGA12: /* all engines support GPUVM */ |
756 | case CHIP_VEGA20: | ||
758 | default: | 757 | default: |
759 | adev->gmc.gart_size = 512ULL << 20; | 758 | adev->gmc.gart_size = 512ULL << 20; |
760 | break; | 759 | break; |
@@ -860,6 +859,7 @@ static int gmc_v9_0_sw_init(void *handle) | |||
860 | break; | 859 | break; |
861 | case CHIP_VEGA10: | 860 | case CHIP_VEGA10: |
862 | case CHIP_VEGA12: | 861 | case CHIP_VEGA12: |
862 | case CHIP_VEGA20: | ||
863 | /* | 863 | /* |
864 | * To fulfill 4-level page support, | 864 | * To fulfill 4-level page support, |
865 | * vm size is 256TB (48bit), maximum size of Vega10, | 865 | * vm size is 256TB (48bit), maximum size of Vega10, |
@@ -977,6 +977,7 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) | |||
977 | 977 | ||
978 | switch (adev->asic_type) { | 978 | switch (adev->asic_type) { |
979 | case CHIP_VEGA10: | 979 | case CHIP_VEGA10: |
980 | case CHIP_VEGA20: | ||
980 | soc15_program_register_sequence(adev, | 981 | soc15_program_register_sequence(adev, |
981 | golden_settings_mmhub_1_0_0, | 982 | golden_settings_mmhub_1_0_0, |
982 | ARRAY_SIZE(golden_settings_mmhub_1_0_0)); | 983 | ARRAY_SIZE(golden_settings_mmhub_1_0_0)); |
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c index 43f925773b57..3d53c4413f13 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c | |||
@@ -734,6 +734,7 @@ int mmhub_v1_0_set_clockgating(struct amdgpu_device *adev, | |||
734 | switch (adev->asic_type) { | 734 | switch (adev->asic_type) { |
735 | case CHIP_VEGA10: | 735 | case CHIP_VEGA10: |
736 | case CHIP_VEGA12: | 736 | case CHIP_VEGA12: |
737 | case CHIP_VEGA20: | ||
737 | case CHIP_RAVEN: | 738 | case CHIP_RAVEN: |
738 | mmhub_v1_0_update_medium_grain_clock_gating(adev, | 739 | mmhub_v1_0_update_medium_grain_clock_gating(adev, |
739 | state == AMD_CG_STATE_GATE ? true : false); | 740 | state == AMD_CG_STATE_GATE ? true : false); |
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c index df34dc79d444..365517c0121e 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c | |||
@@ -34,10 +34,19 @@ | |||
34 | #define smnCPM_CONTROL 0x11180460 | 34 | #define smnCPM_CONTROL 0x11180460 |
35 | #define smnPCIE_CNTL2 0x11180070 | 35 | #define smnPCIE_CNTL2 0x11180070 |
36 | 36 | ||
37 | /* vega20 */ | ||
38 | #define mmRCC_DEV0_EPF0_STRAP0_VG20 0x0011 | ||
39 | #define mmRCC_DEV0_EPF0_STRAP0_VG20_BASE_IDX 2 | ||
40 | |||
37 | static u32 nbio_v7_0_get_rev_id(struct amdgpu_device *adev) | 41 | static u32 nbio_v7_0_get_rev_id(struct amdgpu_device *adev) |
38 | { | 42 | { |
39 | u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0); | 43 | u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0); |
40 | 44 | ||
45 | if (adev->asic_type == CHIP_VEGA20) | ||
46 | tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0_VG20); | ||
47 | else | ||
48 | tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0); | ||
49 | |||
41 | tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; | 50 | tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; |
42 | tmp >>= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT; | 51 | tmp >>= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT; |
43 | 52 | ||
@@ -75,10 +84,14 @@ static void nbio_v7_0_sdma_doorbell_range(struct amdgpu_device *adev, int instan | |||
75 | SOC15_REG_OFFSET(NBIO, 0, mmBIF_SDMA1_DOORBELL_RANGE); | 84 | SOC15_REG_OFFSET(NBIO, 0, mmBIF_SDMA1_DOORBELL_RANGE); |
76 | 85 | ||
77 | u32 doorbell_range = RREG32(reg); | 86 | u32 doorbell_range = RREG32(reg); |
87 | u32 range = 2; | ||
88 | |||
89 | if (adev->asic_type == CHIP_VEGA20) | ||
90 | range = 8; | ||
78 | 91 | ||
79 | if (use_doorbell) { | 92 | if (use_doorbell) { |
80 | doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, OFFSET, doorbell_index); | 93 | doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, OFFSET, doorbell_index); |
81 | doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, SIZE, 2); | 94 | doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, SIZE, range); |
82 | } else | 95 | } else |
83 | doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, SIZE, 0); | 96 | doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, SIZE, 0); |
84 | 97 | ||
@@ -133,6 +146,9 @@ static void nbio_v7_0_update_medium_grain_clock_gating(struct amdgpu_device *ade | |||
133 | { | 146 | { |
134 | uint32_t def, data; | 147 | uint32_t def, data; |
135 | 148 | ||
149 | if (adev->asic_type == CHIP_VEGA20) | ||
150 | return; | ||
151 | |||
136 | /* NBIF_MGCG_CTRL_LCLK */ | 152 | /* NBIF_MGCG_CTRL_LCLK */ |
137 | def = data = RREG32_PCIE(smnNBIF_MGCG_CTRL_LCLK); | 153 | def = data = RREG32_PCIE(smnNBIF_MGCG_CTRL_LCLK); |
138 | 154 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c index 196e75def1f2..0c768e388ace 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c | |||
@@ -41,6 +41,9 @@ MODULE_FIRMWARE("amdgpu/vega10_sos.bin"); | |||
41 | MODULE_FIRMWARE("amdgpu/vega10_asd.bin"); | 41 | MODULE_FIRMWARE("amdgpu/vega10_asd.bin"); |
42 | MODULE_FIRMWARE("amdgpu/vega12_sos.bin"); | 42 | MODULE_FIRMWARE("amdgpu/vega12_sos.bin"); |
43 | MODULE_FIRMWARE("amdgpu/vega12_asd.bin"); | 43 | MODULE_FIRMWARE("amdgpu/vega12_asd.bin"); |
44 | MODULE_FIRMWARE("amdgpu/vega20_sos.bin"); | ||
45 | MODULE_FIRMWARE("amdgpu/vega20_asd.bin"); | ||
46 | |||
44 | 47 | ||
45 | #define smnMP1_FIRMWARE_FLAGS 0x3010028 | 48 | #define smnMP1_FIRMWARE_FLAGS 0x3010028 |
46 | 49 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 03a36cbe7557..ca53b3fba422 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | |||
@@ -42,6 +42,8 @@ MODULE_FIRMWARE("amdgpu/vega10_sdma.bin"); | |||
42 | MODULE_FIRMWARE("amdgpu/vega10_sdma1.bin"); | 42 | MODULE_FIRMWARE("amdgpu/vega10_sdma1.bin"); |
43 | MODULE_FIRMWARE("amdgpu/vega12_sdma.bin"); | 43 | MODULE_FIRMWARE("amdgpu/vega12_sdma.bin"); |
44 | MODULE_FIRMWARE("amdgpu/vega12_sdma1.bin"); | 44 | MODULE_FIRMWARE("amdgpu/vega12_sdma1.bin"); |
45 | MODULE_FIRMWARE("amdgpu/vega20_sdma.bin"); | ||
46 | MODULE_FIRMWARE("amdgpu/vega20_sdma1.bin"); | ||
45 | MODULE_FIRMWARE("amdgpu/raven_sdma.bin"); | 47 | MODULE_FIRMWARE("amdgpu/raven_sdma.bin"); |
46 | 48 | ||
47 | #define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x000000F8L | 49 | #define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x000000F8L |
@@ -107,6 +109,28 @@ static const struct soc15_reg_golden golden_settings_sdma_4_1[] = | |||
107 | SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0) | 109 | SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0) |
108 | }; | 110 | }; |
109 | 111 | ||
112 | static const struct soc15_reg_golden golden_settings_sdma_4_2[] = | ||
113 | { | ||
114 | SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_CHICKEN_BITS, 0xfe931f07, 0x02831d07), | ||
115 | SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_CLK_CTRL, 0xffffffff, 0x3f000100), | ||
116 | SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0000773f, 0x00004002), | ||
117 | SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002), | ||
118 | SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GFX_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), | ||
119 | SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_PAGE_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), | ||
120 | SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff0, 0x00403000), | ||
121 | SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), | ||
122 | SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0), | ||
123 | SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CHICKEN_BITS, 0xfe931f07, 0x02831d07), | ||
124 | SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CLK_CTRL, 0xffffffff, 0x3f000100), | ||
125 | SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG, 0x0000773f, 0x00004002), | ||
126 | SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002), | ||
127 | SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GFX_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), | ||
128 | SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_PAGE_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), | ||
129 | SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), | ||
130 | SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), | ||
131 | SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_PAGE, 0x000003ff, 0x000003c0) | ||
132 | }; | ||
133 | |||
110 | static const struct soc15_reg_golden golden_settings_sdma_rv1[] = | 134 | static const struct soc15_reg_golden golden_settings_sdma_rv1[] = |
111 | { | 135 | { |
112 | SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0018773f, 0x00000002), | 136 | SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0018773f, 0x00000002), |
@@ -139,6 +163,11 @@ static void sdma_v4_0_init_golden_registers(struct amdgpu_device *adev) | |||
139 | golden_settings_sdma_vg12, | 163 | golden_settings_sdma_vg12, |
140 | ARRAY_SIZE(golden_settings_sdma_vg12)); | 164 | ARRAY_SIZE(golden_settings_sdma_vg12)); |
141 | break; | 165 | break; |
166 | case CHIP_VEGA20: | ||
167 | soc15_program_register_sequence(adev, | ||
168 | golden_settings_sdma_4_2, | ||
169 | ARRAY_SIZE(golden_settings_sdma_4_2)); | ||
170 | break; | ||
142 | case CHIP_RAVEN: | 171 | case CHIP_RAVEN: |
143 | soc15_program_register_sequence(adev, | 172 | soc15_program_register_sequence(adev, |
144 | golden_settings_sdma_4_1, | 173 | golden_settings_sdma_4_1, |
@@ -182,6 +211,9 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev) | |||
182 | case CHIP_VEGA12: | 211 | case CHIP_VEGA12: |
183 | chip_name = "vega12"; | 212 | chip_name = "vega12"; |
184 | break; | 213 | break; |
214 | case CHIP_VEGA20: | ||
215 | chip_name = "vega20"; | ||
216 | break; | ||
185 | case CHIP_RAVEN: | 217 | case CHIP_RAVEN: |
186 | chip_name = "raven"; | 218 | chip_name = "raven"; |
187 | break; | 219 | break; |
@@ -1516,6 +1548,7 @@ static int sdma_v4_0_set_clockgating_state(void *handle, | |||
1516 | switch (adev->asic_type) { | 1548 | switch (adev->asic_type) { |
1517 | case CHIP_VEGA10: | 1549 | case CHIP_VEGA10: |
1518 | case CHIP_VEGA12: | 1550 | case CHIP_VEGA12: |
1551 | case CHIP_VEGA20: | ||
1519 | case CHIP_RAVEN: | 1552 | case CHIP_RAVEN: |
1520 | sdma_v4_0_update_medium_grain_clock_gating(adev, | 1553 | sdma_v4_0_update_medium_grain_clock_gating(adev, |
1521 | state == AMD_CG_STATE_GATE ? true : false); | 1554 | state == AMD_CG_STATE_GATE ? true : false); |
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 90065766fffb..68b4a22a8892 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c | |||
@@ -41,8 +41,6 @@ | |||
41 | #include "sdma1/sdma1_4_0_offset.h" | 41 | #include "sdma1/sdma1_4_0_offset.h" |
42 | #include "hdp/hdp_4_0_offset.h" | 42 | #include "hdp/hdp_4_0_offset.h" |
43 | #include "hdp/hdp_4_0_sh_mask.h" | 43 | #include "hdp/hdp_4_0_sh_mask.h" |
44 | #include "mp/mp_9_0_offset.h" | ||
45 | #include "mp/mp_9_0_sh_mask.h" | ||
46 | #include "smuio/smuio_9_0_offset.h" | 44 | #include "smuio/smuio_9_0_offset.h" |
47 | #include "smuio/smuio_9_0_sh_mask.h" | 45 | #include "smuio/smuio_9_0_sh_mask.h" |
48 | 46 | ||
@@ -53,6 +51,7 @@ | |||
53 | #include "gfxhub_v1_0.h" | 51 | #include "gfxhub_v1_0.h" |
54 | #include "mmhub_v1_0.h" | 52 | #include "mmhub_v1_0.h" |
55 | #include "df_v1_7.h" | 53 | #include "df_v1_7.h" |
54 | #include "df_v3_6.h" | ||
56 | #include "vega10_ih.h" | 55 | #include "vega10_ih.h" |
57 | #include "sdma_v4_0.h" | 56 | #include "sdma_v4_0.h" |
58 | #include "uvd_v7_0.h" | 57 | #include "uvd_v7_0.h" |
@@ -489,16 +488,24 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev) | |||
489 | case CHIP_RAVEN: | 488 | case CHIP_RAVEN: |
490 | vega10_reg_base_init(adev); | 489 | vega10_reg_base_init(adev); |
491 | break; | 490 | break; |
491 | case CHIP_VEGA20: | ||
492 | vega20_reg_base_init(adev); | ||
493 | break; | ||
492 | default: | 494 | default: |
493 | return -EINVAL; | 495 | return -EINVAL; |
494 | } | 496 | } |
495 | 497 | ||
496 | if (adev->flags & AMD_IS_APU) | 498 | if (adev->flags & AMD_IS_APU) |
497 | adev->nbio_funcs = &nbio_v7_0_funcs; | 499 | adev->nbio_funcs = &nbio_v7_0_funcs; |
500 | else if (adev->asic_type == CHIP_VEGA20) | ||
501 | adev->nbio_funcs = &nbio_v7_0_funcs; | ||
498 | else | 502 | else |
499 | adev->nbio_funcs = &nbio_v6_1_funcs; | 503 | adev->nbio_funcs = &nbio_v6_1_funcs; |
500 | 504 | ||
501 | adev->df_funcs = &df_v1_7_funcs; | 505 | if (adev->asic_type == CHIP_VEGA20) |
506 | adev->df_funcs = &df_v3_6_funcs; | ||
507 | else | ||
508 | adev->df_funcs = &df_v1_7_funcs; | ||
502 | adev->nbio_funcs->detect_hw_virt(adev); | 509 | adev->nbio_funcs->detect_hw_virt(adev); |
503 | 510 | ||
504 | if (amdgpu_sriov_vf(adev)) | 511 | if (amdgpu_sriov_vf(adev)) |
@@ -507,12 +514,15 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev) | |||
507 | switch (adev->asic_type) { | 514 | switch (adev->asic_type) { |
508 | case CHIP_VEGA10: | 515 | case CHIP_VEGA10: |
509 | case CHIP_VEGA12: | 516 | case CHIP_VEGA12: |
517 | case CHIP_VEGA20: | ||
510 | amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); | 518 | amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); |
511 | amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); | 519 | amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); |
512 | amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); | 520 | amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); |
513 | amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block); | 521 | if (adev->asic_type != CHIP_VEGA20) { |
514 | if (!amdgpu_sriov_vf(adev)) | 522 | amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block); |
515 | amdgpu_device_ip_block_add(adev, &pp_smu_ip_block); | 523 | if (!amdgpu_sriov_vf(adev)) |
524 | amdgpu_device_ip_block_add(adev, &pp_smu_ip_block); | ||
525 | } | ||
516 | if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) | 526 | if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) |
517 | amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); | 527 | amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); |
518 | #if defined(CONFIG_DRM_AMD_DC) | 528 | #if defined(CONFIG_DRM_AMD_DC) |
@@ -660,6 +670,27 @@ static int soc15_common_early_init(void *handle) | |||
660 | adev->pg_flags = 0; | 670 | adev->pg_flags = 0; |
661 | adev->external_rev_id = adev->rev_id + 0x14; | 671 | adev->external_rev_id = adev->rev_id + 0x14; |
662 | break; | 672 | break; |
673 | case CHIP_VEGA20: | ||
674 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | | ||
675 | AMD_CG_SUPPORT_GFX_MGLS | | ||
676 | AMD_CG_SUPPORT_GFX_CGCG | | ||
677 | AMD_CG_SUPPORT_GFX_CGLS | | ||
678 | AMD_CG_SUPPORT_GFX_3D_CGCG | | ||
679 | AMD_CG_SUPPORT_GFX_3D_CGLS | | ||
680 | AMD_CG_SUPPORT_GFX_CP_LS | | ||
681 | AMD_CG_SUPPORT_MC_LS | | ||
682 | AMD_CG_SUPPORT_MC_MGCG | | ||
683 | AMD_CG_SUPPORT_SDMA_MGCG | | ||
684 | AMD_CG_SUPPORT_SDMA_LS | | ||
685 | AMD_CG_SUPPORT_BIF_MGCG | | ||
686 | AMD_CG_SUPPORT_BIF_LS | | ||
687 | AMD_CG_SUPPORT_HDP_MGCG | | ||
688 | AMD_CG_SUPPORT_ROM_MGCG | | ||
689 | AMD_CG_SUPPORT_VCE_MGCG | | ||
690 | AMD_CG_SUPPORT_UVD_MGCG; | ||
691 | adev->pg_flags = 0; | ||
692 | adev->external_rev_id = adev->rev_id + 0x28; | ||
693 | break; | ||
663 | case CHIP_RAVEN: | 694 | case CHIP_RAVEN: |
664 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | | 695 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
665 | AMD_CG_SUPPORT_GFX_MGLS | | 696 | AMD_CG_SUPPORT_GFX_MGLS | |
@@ -679,8 +710,10 @@ static int soc15_common_early_init(void *handle) | |||
679 | AMD_CG_SUPPORT_MC_MGCG | | 710 | AMD_CG_SUPPORT_MC_MGCG | |
680 | AMD_CG_SUPPORT_MC_LS | | 711 | AMD_CG_SUPPORT_MC_LS | |
681 | AMD_CG_SUPPORT_SDMA_MGCG | | 712 | AMD_CG_SUPPORT_SDMA_MGCG | |
682 | AMD_CG_SUPPORT_SDMA_LS; | 713 | AMD_CG_SUPPORT_SDMA_LS | |
683 | adev->pg_flags = AMD_PG_SUPPORT_SDMA; | 714 | AMD_CG_SUPPORT_VCN_MGCG; |
715 | |||
716 | adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN; | ||
684 | 717 | ||
685 | if (adev->powerplay.pp_feature & PP_GFXOFF_MASK) | 718 | if (adev->powerplay.pp_feature & PP_GFXOFF_MASK) |
686 | adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG | | 719 | adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG | |
@@ -872,6 +905,7 @@ static int soc15_common_set_clockgating_state(void *handle, | |||
872 | switch (adev->asic_type) { | 905 | switch (adev->asic_type) { |
873 | case CHIP_VEGA10: | 906 | case CHIP_VEGA10: |
874 | case CHIP_VEGA12: | 907 | case CHIP_VEGA12: |
908 | case CHIP_VEGA20: | ||
875 | adev->nbio_funcs->update_medium_grain_clock_gating(adev, | 909 | adev->nbio_funcs->update_medium_grain_clock_gating(adev, |
876 | state == AMD_CG_STATE_GATE ? true : false); | 910 | state == AMD_CG_STATE_GATE ? true : false); |
877 | adev->nbio_funcs->update_medium_grain_light_sleep(adev, | 911 | adev->nbio_funcs->update_medium_grain_light_sleep(adev, |
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.h b/drivers/gpu/drm/amd/amdgpu/soc15.h index f70da8a29f86..1f714b7af520 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.h +++ b/drivers/gpu/drm/amd/amdgpu/soc15.h | |||
@@ -55,5 +55,6 @@ void soc15_program_register_sequence(struct amdgpu_device *adev, | |||
55 | const u32 array_size); | 55 | const u32 array_size); |
56 | 56 | ||
57 | int vega10_reg_base_init(struct amdgpu_device *adev); | 57 | int vega10_reg_base_init(struct amdgpu_device *adev); |
58 | int vega20_reg_base_init(struct amdgpu_device *adev); | ||
58 | 59 | ||
59 | #endif | 60 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h index def865067edd..0942f492d2e1 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h +++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h | |||
@@ -47,6 +47,21 @@ | |||
47 | #define WREG32_SOC15_OFFSET(ip, inst, reg, offset, value) \ | 47 | #define WREG32_SOC15_OFFSET(ip, inst, reg, offset, value) \ |
48 | WREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, value) | 48 | WREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, value) |
49 | 49 | ||
50 | #define SOC15_WAIT_ON_RREG(ip, inst, reg, expected_value, mask, ret) \ | ||
51 | do { \ | ||
52 | uint32_t tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \ | ||
53 | uint32_t loop = adev->usec_timeout; \ | ||
54 | while ((tmp_ & (mask)) != (expected_value)) { \ | ||
55 | udelay(2); \ | ||
56 | tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \ | ||
57 | loop--; \ | ||
58 | if (!loop) { \ | ||
59 | ret = -ETIMEDOUT; \ | ||
60 | break; \ | ||
61 | } \ | ||
62 | } \ | ||
63 | } while (0) | ||
64 | |||
50 | #endif | 65 | #endif |
51 | 66 | ||
52 | 67 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index 87cbb142dd0b..6fed3d7797a8 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | |||
@@ -93,6 +93,7 @@ static void uvd_v4_2_ring_set_wptr(struct amdgpu_ring *ring) | |||
93 | static int uvd_v4_2_early_init(void *handle) | 93 | static int uvd_v4_2_early_init(void *handle) |
94 | { | 94 | { |
95 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 95 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
96 | adev->uvd.num_uvd_inst = 1; | ||
96 | 97 | ||
97 | uvd_v4_2_set_ring_funcs(adev); | 98 | uvd_v4_2_set_ring_funcs(adev); |
98 | uvd_v4_2_set_irq_funcs(adev); | 99 | uvd_v4_2_set_irq_funcs(adev); |
@@ -107,7 +108,7 @@ static int uvd_v4_2_sw_init(void *handle) | |||
107 | int r; | 108 | int r; |
108 | 109 | ||
109 | /* UVD TRAP */ | 110 | /* UVD TRAP */ |
110 | r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.irq); | 111 | r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.inst->irq); |
111 | if (r) | 112 | if (r) |
112 | return r; | 113 | return r; |
113 | 114 | ||
@@ -119,9 +120,9 @@ static int uvd_v4_2_sw_init(void *handle) | |||
119 | if (r) | 120 | if (r) |
120 | return r; | 121 | return r; |
121 | 122 | ||
122 | ring = &adev->uvd.ring; | 123 | ring = &adev->uvd.inst->ring; |
123 | sprintf(ring->name, "uvd"); | 124 | sprintf(ring->name, "uvd"); |
124 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); | 125 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0); |
125 | 126 | ||
126 | return r; | 127 | return r; |
127 | } | 128 | } |
@@ -150,7 +151,7 @@ static void uvd_v4_2_enable_mgcg(struct amdgpu_device *adev, | |||
150 | static int uvd_v4_2_hw_init(void *handle) | 151 | static int uvd_v4_2_hw_init(void *handle) |
151 | { | 152 | { |
152 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 153 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
153 | struct amdgpu_ring *ring = &adev->uvd.ring; | 154 | struct amdgpu_ring *ring = &adev->uvd.inst->ring; |
154 | uint32_t tmp; | 155 | uint32_t tmp; |
155 | int r; | 156 | int r; |
156 | 157 | ||
@@ -208,7 +209,7 @@ done: | |||
208 | static int uvd_v4_2_hw_fini(void *handle) | 209 | static int uvd_v4_2_hw_fini(void *handle) |
209 | { | 210 | { |
210 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 211 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
211 | struct amdgpu_ring *ring = &adev->uvd.ring; | 212 | struct amdgpu_ring *ring = &adev->uvd.inst->ring; |
212 | 213 | ||
213 | if (RREG32(mmUVD_STATUS) != 0) | 214 | if (RREG32(mmUVD_STATUS) != 0) |
214 | uvd_v4_2_stop(adev); | 215 | uvd_v4_2_stop(adev); |
@@ -251,7 +252,7 @@ static int uvd_v4_2_resume(void *handle) | |||
251 | */ | 252 | */ |
252 | static int uvd_v4_2_start(struct amdgpu_device *adev) | 253 | static int uvd_v4_2_start(struct amdgpu_device *adev) |
253 | { | 254 | { |
254 | struct amdgpu_ring *ring = &adev->uvd.ring; | 255 | struct amdgpu_ring *ring = &adev->uvd.inst->ring; |
255 | uint32_t rb_bufsz; | 256 | uint32_t rb_bufsz; |
256 | int i, j, r; | 257 | int i, j, r; |
257 | u32 tmp; | 258 | u32 tmp; |
@@ -523,6 +524,18 @@ static void uvd_v4_2_ring_emit_ib(struct amdgpu_ring *ring, | |||
523 | amdgpu_ring_write(ring, ib->length_dw); | 524 | amdgpu_ring_write(ring, ib->length_dw); |
524 | } | 525 | } |
525 | 526 | ||
527 | static void uvd_v4_2_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | ||
528 | { | ||
529 | int i; | ||
530 | |||
531 | WARN_ON(ring->wptr % 2 || count % 2); | ||
532 | |||
533 | for (i = 0; i < count / 2; i++) { | ||
534 | amdgpu_ring_write(ring, PACKET0(mmUVD_NO_OP, 0)); | ||
535 | amdgpu_ring_write(ring, 0); | ||
536 | } | ||
537 | } | ||
538 | |||
526 | /** | 539 | /** |
527 | * uvd_v4_2_mc_resume - memory controller programming | 540 | * uvd_v4_2_mc_resume - memory controller programming |
528 | * | 541 | * |
@@ -536,7 +549,7 @@ static void uvd_v4_2_mc_resume(struct amdgpu_device *adev) | |||
536 | uint32_t size; | 549 | uint32_t size; |
537 | 550 | ||
538 | /* programm the VCPU memory controller bits 0-27 */ | 551 | /* programm the VCPU memory controller bits 0-27 */ |
539 | addr = (adev->uvd.gpu_addr + AMDGPU_UVD_FIRMWARE_OFFSET) >> 3; | 552 | addr = (adev->uvd.inst->gpu_addr + AMDGPU_UVD_FIRMWARE_OFFSET) >> 3; |
540 | size = AMDGPU_UVD_FIRMWARE_SIZE(adev) >> 3; | 553 | size = AMDGPU_UVD_FIRMWARE_SIZE(adev) >> 3; |
541 | WREG32(mmUVD_VCPU_CACHE_OFFSET0, addr); | 554 | WREG32(mmUVD_VCPU_CACHE_OFFSET0, addr); |
542 | WREG32(mmUVD_VCPU_CACHE_SIZE0, size); | 555 | WREG32(mmUVD_VCPU_CACHE_SIZE0, size); |
@@ -553,11 +566,11 @@ static void uvd_v4_2_mc_resume(struct amdgpu_device *adev) | |||
553 | WREG32(mmUVD_VCPU_CACHE_SIZE2, size); | 566 | WREG32(mmUVD_VCPU_CACHE_SIZE2, size); |
554 | 567 | ||
555 | /* bits 28-31 */ | 568 | /* bits 28-31 */ |
556 | addr = (adev->uvd.gpu_addr >> 28) & 0xF; | 569 | addr = (adev->uvd.inst->gpu_addr >> 28) & 0xF; |
557 | WREG32(mmUVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0)); | 570 | WREG32(mmUVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0)); |
558 | 571 | ||
559 | /* bits 32-39 */ | 572 | /* bits 32-39 */ |
560 | addr = (adev->uvd.gpu_addr >> 32) & 0xFF; | 573 | addr = (adev->uvd.inst->gpu_addr >> 32) & 0xFF; |
561 | WREG32(mmUVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31)); | 574 | WREG32(mmUVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31)); |
562 | 575 | ||
563 | WREG32(mmUVD_UDEC_ADDR_CONFIG, adev->gfx.config.gb_addr_config); | 576 | WREG32(mmUVD_UDEC_ADDR_CONFIG, adev->gfx.config.gb_addr_config); |
@@ -664,7 +677,7 @@ static int uvd_v4_2_process_interrupt(struct amdgpu_device *adev, | |||
664 | struct amdgpu_iv_entry *entry) | 677 | struct amdgpu_iv_entry *entry) |
665 | { | 678 | { |
666 | DRM_DEBUG("IH: UVD TRAP\n"); | 679 | DRM_DEBUG("IH: UVD TRAP\n"); |
667 | amdgpu_fence_process(&adev->uvd.ring); | 680 | amdgpu_fence_process(&adev->uvd.inst->ring); |
668 | return 0; | 681 | return 0; |
669 | } | 682 | } |
670 | 683 | ||
@@ -732,7 +745,6 @@ static const struct amd_ip_funcs uvd_v4_2_ip_funcs = { | |||
732 | static const struct amdgpu_ring_funcs uvd_v4_2_ring_funcs = { | 745 | static const struct amdgpu_ring_funcs uvd_v4_2_ring_funcs = { |
733 | .type = AMDGPU_RING_TYPE_UVD, | 746 | .type = AMDGPU_RING_TYPE_UVD, |
734 | .align_mask = 0xf, | 747 | .align_mask = 0xf, |
735 | .nop = PACKET0(mmUVD_NO_OP, 0), | ||
736 | .support_64bit_ptrs = false, | 748 | .support_64bit_ptrs = false, |
737 | .get_rptr = uvd_v4_2_ring_get_rptr, | 749 | .get_rptr = uvd_v4_2_ring_get_rptr, |
738 | .get_wptr = uvd_v4_2_ring_get_wptr, | 750 | .get_wptr = uvd_v4_2_ring_get_wptr, |
@@ -745,7 +757,7 @@ static const struct amdgpu_ring_funcs uvd_v4_2_ring_funcs = { | |||
745 | .emit_fence = uvd_v4_2_ring_emit_fence, | 757 | .emit_fence = uvd_v4_2_ring_emit_fence, |
746 | .test_ring = uvd_v4_2_ring_test_ring, | 758 | .test_ring = uvd_v4_2_ring_test_ring, |
747 | .test_ib = amdgpu_uvd_ring_test_ib, | 759 | .test_ib = amdgpu_uvd_ring_test_ib, |
748 | .insert_nop = amdgpu_ring_insert_nop, | 760 | .insert_nop = uvd_v4_2_ring_insert_nop, |
749 | .pad_ib = amdgpu_ring_generic_pad_ib, | 761 | .pad_ib = amdgpu_ring_generic_pad_ib, |
750 | .begin_use = amdgpu_uvd_ring_begin_use, | 762 | .begin_use = amdgpu_uvd_ring_begin_use, |
751 | .end_use = amdgpu_uvd_ring_end_use, | 763 | .end_use = amdgpu_uvd_ring_end_use, |
@@ -753,7 +765,7 @@ static const struct amdgpu_ring_funcs uvd_v4_2_ring_funcs = { | |||
753 | 765 | ||
754 | static void uvd_v4_2_set_ring_funcs(struct amdgpu_device *adev) | 766 | static void uvd_v4_2_set_ring_funcs(struct amdgpu_device *adev) |
755 | { | 767 | { |
756 | adev->uvd.ring.funcs = &uvd_v4_2_ring_funcs; | 768 | adev->uvd.inst->ring.funcs = &uvd_v4_2_ring_funcs; |
757 | } | 769 | } |
758 | 770 | ||
759 | static const struct amdgpu_irq_src_funcs uvd_v4_2_irq_funcs = { | 771 | static const struct amdgpu_irq_src_funcs uvd_v4_2_irq_funcs = { |
@@ -763,8 +775,8 @@ static const struct amdgpu_irq_src_funcs uvd_v4_2_irq_funcs = { | |||
763 | 775 | ||
764 | static void uvd_v4_2_set_irq_funcs(struct amdgpu_device *adev) | 776 | static void uvd_v4_2_set_irq_funcs(struct amdgpu_device *adev) |
765 | { | 777 | { |
766 | adev->uvd.irq.num_types = 1; | 778 | adev->uvd.inst->irq.num_types = 1; |
767 | adev->uvd.irq.funcs = &uvd_v4_2_irq_funcs; | 779 | adev->uvd.inst->irq.funcs = &uvd_v4_2_irq_funcs; |
768 | } | 780 | } |
769 | 781 | ||
770 | const struct amdgpu_ip_block_version uvd_v4_2_ip_block = | 782 | const struct amdgpu_ip_block_version uvd_v4_2_ip_block = |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index 6445d55e7d5a..341ee6d55ce8 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | |||
@@ -89,6 +89,7 @@ static void uvd_v5_0_ring_set_wptr(struct amdgpu_ring *ring) | |||
89 | static int uvd_v5_0_early_init(void *handle) | 89 | static int uvd_v5_0_early_init(void *handle) |
90 | { | 90 | { |
91 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 91 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
92 | adev->uvd.num_uvd_inst = 1; | ||
92 | 93 | ||
93 | uvd_v5_0_set_ring_funcs(adev); | 94 | uvd_v5_0_set_ring_funcs(adev); |
94 | uvd_v5_0_set_irq_funcs(adev); | 95 | uvd_v5_0_set_irq_funcs(adev); |
@@ -103,7 +104,7 @@ static int uvd_v5_0_sw_init(void *handle) | |||
103 | int r; | 104 | int r; |
104 | 105 | ||
105 | /* UVD TRAP */ | 106 | /* UVD TRAP */ |
106 | r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.irq); | 107 | r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.inst->irq); |
107 | if (r) | 108 | if (r) |
108 | return r; | 109 | return r; |
109 | 110 | ||
@@ -115,9 +116,9 @@ static int uvd_v5_0_sw_init(void *handle) | |||
115 | if (r) | 116 | if (r) |
116 | return r; | 117 | return r; |
117 | 118 | ||
118 | ring = &adev->uvd.ring; | 119 | ring = &adev->uvd.inst->ring; |
119 | sprintf(ring->name, "uvd"); | 120 | sprintf(ring->name, "uvd"); |
120 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); | 121 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0); |
121 | 122 | ||
122 | return r; | 123 | return r; |
123 | } | 124 | } |
@@ -144,7 +145,7 @@ static int uvd_v5_0_sw_fini(void *handle) | |||
144 | static int uvd_v5_0_hw_init(void *handle) | 145 | static int uvd_v5_0_hw_init(void *handle) |
145 | { | 146 | { |
146 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 147 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
147 | struct amdgpu_ring *ring = &adev->uvd.ring; | 148 | struct amdgpu_ring *ring = &adev->uvd.inst->ring; |
148 | uint32_t tmp; | 149 | uint32_t tmp; |
149 | int r; | 150 | int r; |
150 | 151 | ||
@@ -204,7 +205,7 @@ done: | |||
204 | static int uvd_v5_0_hw_fini(void *handle) | 205 | static int uvd_v5_0_hw_fini(void *handle) |
205 | { | 206 | { |
206 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 207 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
207 | struct amdgpu_ring *ring = &adev->uvd.ring; | 208 | struct amdgpu_ring *ring = &adev->uvd.inst->ring; |
208 | 209 | ||
209 | if (RREG32(mmUVD_STATUS) != 0) | 210 | if (RREG32(mmUVD_STATUS) != 0) |
210 | uvd_v5_0_stop(adev); | 211 | uvd_v5_0_stop(adev); |
@@ -253,9 +254,9 @@ static void uvd_v5_0_mc_resume(struct amdgpu_device *adev) | |||
253 | 254 | ||
254 | /* programm memory controller bits 0-27 */ | 255 | /* programm memory controller bits 0-27 */ |
255 | WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, | 256 | WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, |
256 | lower_32_bits(adev->uvd.gpu_addr)); | 257 | lower_32_bits(adev->uvd.inst->gpu_addr)); |
257 | WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, | 258 | WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, |
258 | upper_32_bits(adev->uvd.gpu_addr)); | 259 | upper_32_bits(adev->uvd.inst->gpu_addr)); |
259 | 260 | ||
260 | offset = AMDGPU_UVD_FIRMWARE_OFFSET; | 261 | offset = AMDGPU_UVD_FIRMWARE_OFFSET; |
261 | size = AMDGPU_UVD_FIRMWARE_SIZE(adev); | 262 | size = AMDGPU_UVD_FIRMWARE_SIZE(adev); |
@@ -287,7 +288,7 @@ static void uvd_v5_0_mc_resume(struct amdgpu_device *adev) | |||
287 | */ | 288 | */ |
288 | static int uvd_v5_0_start(struct amdgpu_device *adev) | 289 | static int uvd_v5_0_start(struct amdgpu_device *adev) |
289 | { | 290 | { |
290 | struct amdgpu_ring *ring = &adev->uvd.ring; | 291 | struct amdgpu_ring *ring = &adev->uvd.inst->ring; |
291 | uint32_t rb_bufsz, tmp; | 292 | uint32_t rb_bufsz, tmp; |
292 | uint32_t lmi_swap_cntl; | 293 | uint32_t lmi_swap_cntl; |
293 | uint32_t mp_swap_cntl; | 294 | uint32_t mp_swap_cntl; |
@@ -540,6 +541,18 @@ static void uvd_v5_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
540 | amdgpu_ring_write(ring, ib->length_dw); | 541 | amdgpu_ring_write(ring, ib->length_dw); |
541 | } | 542 | } |
542 | 543 | ||
544 | static void uvd_v5_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | ||
545 | { | ||
546 | int i; | ||
547 | |||
548 | WARN_ON(ring->wptr % 2 || count % 2); | ||
549 | |||
550 | for (i = 0; i < count / 2; i++) { | ||
551 | amdgpu_ring_write(ring, PACKET0(mmUVD_NO_OP, 0)); | ||
552 | amdgpu_ring_write(ring, 0); | ||
553 | } | ||
554 | } | ||
555 | |||
543 | static bool uvd_v5_0_is_idle(void *handle) | 556 | static bool uvd_v5_0_is_idle(void *handle) |
544 | { | 557 | { |
545 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 558 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
@@ -586,7 +599,7 @@ static int uvd_v5_0_process_interrupt(struct amdgpu_device *adev, | |||
586 | struct amdgpu_iv_entry *entry) | 599 | struct amdgpu_iv_entry *entry) |
587 | { | 600 | { |
588 | DRM_DEBUG("IH: UVD TRAP\n"); | 601 | DRM_DEBUG("IH: UVD TRAP\n"); |
589 | amdgpu_fence_process(&adev->uvd.ring); | 602 | amdgpu_fence_process(&adev->uvd.inst->ring); |
590 | return 0; | 603 | return 0; |
591 | } | 604 | } |
592 | 605 | ||
@@ -840,7 +853,6 @@ static const struct amd_ip_funcs uvd_v5_0_ip_funcs = { | |||
840 | static const struct amdgpu_ring_funcs uvd_v5_0_ring_funcs = { | 853 | static const struct amdgpu_ring_funcs uvd_v5_0_ring_funcs = { |
841 | .type = AMDGPU_RING_TYPE_UVD, | 854 | .type = AMDGPU_RING_TYPE_UVD, |
842 | .align_mask = 0xf, | 855 | .align_mask = 0xf, |
843 | .nop = PACKET0(mmUVD_NO_OP, 0), | ||
844 | .support_64bit_ptrs = false, | 856 | .support_64bit_ptrs = false, |
845 | .get_rptr = uvd_v5_0_ring_get_rptr, | 857 | .get_rptr = uvd_v5_0_ring_get_rptr, |
846 | .get_wptr = uvd_v5_0_ring_get_wptr, | 858 | .get_wptr = uvd_v5_0_ring_get_wptr, |
@@ -853,7 +865,7 @@ static const struct amdgpu_ring_funcs uvd_v5_0_ring_funcs = { | |||
853 | .emit_fence = uvd_v5_0_ring_emit_fence, | 865 | .emit_fence = uvd_v5_0_ring_emit_fence, |
854 | .test_ring = uvd_v5_0_ring_test_ring, | 866 | .test_ring = uvd_v5_0_ring_test_ring, |
855 | .test_ib = amdgpu_uvd_ring_test_ib, | 867 | .test_ib = amdgpu_uvd_ring_test_ib, |
856 | .insert_nop = amdgpu_ring_insert_nop, | 868 | .insert_nop = uvd_v5_0_ring_insert_nop, |
857 | .pad_ib = amdgpu_ring_generic_pad_ib, | 869 | .pad_ib = amdgpu_ring_generic_pad_ib, |
858 | .begin_use = amdgpu_uvd_ring_begin_use, | 870 | .begin_use = amdgpu_uvd_ring_begin_use, |
859 | .end_use = amdgpu_uvd_ring_end_use, | 871 | .end_use = amdgpu_uvd_ring_end_use, |
@@ -861,7 +873,7 @@ static const struct amdgpu_ring_funcs uvd_v5_0_ring_funcs = { | |||
861 | 873 | ||
862 | static void uvd_v5_0_set_ring_funcs(struct amdgpu_device *adev) | 874 | static void uvd_v5_0_set_ring_funcs(struct amdgpu_device *adev) |
863 | { | 875 | { |
864 | adev->uvd.ring.funcs = &uvd_v5_0_ring_funcs; | 876 | adev->uvd.inst->ring.funcs = &uvd_v5_0_ring_funcs; |
865 | } | 877 | } |
866 | 878 | ||
867 | static const struct amdgpu_irq_src_funcs uvd_v5_0_irq_funcs = { | 879 | static const struct amdgpu_irq_src_funcs uvd_v5_0_irq_funcs = { |
@@ -871,8 +883,8 @@ static const struct amdgpu_irq_src_funcs uvd_v5_0_irq_funcs = { | |||
871 | 883 | ||
872 | static void uvd_v5_0_set_irq_funcs(struct amdgpu_device *adev) | 884 | static void uvd_v5_0_set_irq_funcs(struct amdgpu_device *adev) |
873 | { | 885 | { |
874 | adev->uvd.irq.num_types = 1; | 886 | adev->uvd.inst->irq.num_types = 1; |
875 | adev->uvd.irq.funcs = &uvd_v5_0_irq_funcs; | 887 | adev->uvd.inst->irq.funcs = &uvd_v5_0_irq_funcs; |
876 | } | 888 | } |
877 | 889 | ||
878 | const struct amdgpu_ip_block_version uvd_v5_0_ip_block = | 890 | const struct amdgpu_ip_block_version uvd_v5_0_ip_block = |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index ca6ab56357b5..bfddf97dd13e 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | |||
@@ -91,7 +91,7 @@ static uint64_t uvd_v6_0_enc_ring_get_rptr(struct amdgpu_ring *ring) | |||
91 | { | 91 | { |
92 | struct amdgpu_device *adev = ring->adev; | 92 | struct amdgpu_device *adev = ring->adev; |
93 | 93 | ||
94 | if (ring == &adev->uvd.ring_enc[0]) | 94 | if (ring == &adev->uvd.inst->ring_enc[0]) |
95 | return RREG32(mmUVD_RB_RPTR); | 95 | return RREG32(mmUVD_RB_RPTR); |
96 | else | 96 | else |
97 | return RREG32(mmUVD_RB_RPTR2); | 97 | return RREG32(mmUVD_RB_RPTR2); |
@@ -121,7 +121,7 @@ static uint64_t uvd_v6_0_enc_ring_get_wptr(struct amdgpu_ring *ring) | |||
121 | { | 121 | { |
122 | struct amdgpu_device *adev = ring->adev; | 122 | struct amdgpu_device *adev = ring->adev; |
123 | 123 | ||
124 | if (ring == &adev->uvd.ring_enc[0]) | 124 | if (ring == &adev->uvd.inst->ring_enc[0]) |
125 | return RREG32(mmUVD_RB_WPTR); | 125 | return RREG32(mmUVD_RB_WPTR); |
126 | else | 126 | else |
127 | return RREG32(mmUVD_RB_WPTR2); | 127 | return RREG32(mmUVD_RB_WPTR2); |
@@ -152,7 +152,7 @@ static void uvd_v6_0_enc_ring_set_wptr(struct amdgpu_ring *ring) | |||
152 | { | 152 | { |
153 | struct amdgpu_device *adev = ring->adev; | 153 | struct amdgpu_device *adev = ring->adev; |
154 | 154 | ||
155 | if (ring == &adev->uvd.ring_enc[0]) | 155 | if (ring == &adev->uvd.inst->ring_enc[0]) |
156 | WREG32(mmUVD_RB_WPTR, | 156 | WREG32(mmUVD_RB_WPTR, |
157 | lower_32_bits(ring->wptr)); | 157 | lower_32_bits(ring->wptr)); |
158 | else | 158 | else |
@@ -375,6 +375,7 @@ error: | |||
375 | static int uvd_v6_0_early_init(void *handle) | 375 | static int uvd_v6_0_early_init(void *handle) |
376 | { | 376 | { |
377 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 377 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
378 | adev->uvd.num_uvd_inst = 1; | ||
378 | 379 | ||
379 | if (!(adev->flags & AMD_IS_APU) && | 380 | if (!(adev->flags & AMD_IS_APU) && |
380 | (RREG32_SMC(ixCC_HARVEST_FUSES) & CC_HARVEST_FUSES__UVD_DISABLE_MASK)) | 381 | (RREG32_SMC(ixCC_HARVEST_FUSES) & CC_HARVEST_FUSES__UVD_DISABLE_MASK)) |
@@ -399,14 +400,14 @@ static int uvd_v6_0_sw_init(void *handle) | |||
399 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 400 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
400 | 401 | ||
401 | /* UVD TRAP */ | 402 | /* UVD TRAP */ |
402 | r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.irq); | 403 | r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, 124, &adev->uvd.inst->irq); |
403 | if (r) | 404 | if (r) |
404 | return r; | 405 | return r; |
405 | 406 | ||
406 | /* UVD ENC TRAP */ | 407 | /* UVD ENC TRAP */ |
407 | if (uvd_v6_0_enc_support(adev)) { | 408 | if (uvd_v6_0_enc_support(adev)) { |
408 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | 409 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { |
409 | r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i + 119, &adev->uvd.irq); | 410 | r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_LEGACY, i + 119, &adev->uvd.inst->irq); |
410 | if (r) | 411 | if (r) |
411 | return r; | 412 | return r; |
412 | } | 413 | } |
@@ -418,17 +419,17 @@ static int uvd_v6_0_sw_init(void *handle) | |||
418 | 419 | ||
419 | if (!uvd_v6_0_enc_support(adev)) { | 420 | if (!uvd_v6_0_enc_support(adev)) { |
420 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) | 421 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) |
421 | adev->uvd.ring_enc[i].funcs = NULL; | 422 | adev->uvd.inst->ring_enc[i].funcs = NULL; |
422 | 423 | ||
423 | adev->uvd.irq.num_types = 1; | 424 | adev->uvd.inst->irq.num_types = 1; |
424 | adev->uvd.num_enc_rings = 0; | 425 | adev->uvd.num_enc_rings = 0; |
425 | 426 | ||
426 | DRM_INFO("UVD ENC is disabled\n"); | 427 | DRM_INFO("UVD ENC is disabled\n"); |
427 | } else { | 428 | } else { |
428 | struct drm_sched_rq *rq; | 429 | struct drm_sched_rq *rq; |
429 | ring = &adev->uvd.ring_enc[0]; | 430 | ring = &adev->uvd.inst->ring_enc[0]; |
430 | rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; | 431 | rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; |
431 | r = drm_sched_entity_init(&ring->sched, &adev->uvd.entity_enc, | 432 | r = drm_sched_entity_init(&ring->sched, &adev->uvd.inst->entity_enc, |
432 | rq, NULL); | 433 | rq, NULL); |
433 | if (r) { | 434 | if (r) { |
434 | DRM_ERROR("Failed setting up UVD ENC run queue.\n"); | 435 | DRM_ERROR("Failed setting up UVD ENC run queue.\n"); |
@@ -440,17 +441,17 @@ static int uvd_v6_0_sw_init(void *handle) | |||
440 | if (r) | 441 | if (r) |
441 | return r; | 442 | return r; |
442 | 443 | ||
443 | ring = &adev->uvd.ring; | 444 | ring = &adev->uvd.inst->ring; |
444 | sprintf(ring->name, "uvd"); | 445 | sprintf(ring->name, "uvd"); |
445 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); | 446 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0); |
446 | if (r) | 447 | if (r) |
447 | return r; | 448 | return r; |
448 | 449 | ||
449 | if (uvd_v6_0_enc_support(adev)) { | 450 | if (uvd_v6_0_enc_support(adev)) { |
450 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | 451 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { |
451 | ring = &adev->uvd.ring_enc[i]; | 452 | ring = &adev->uvd.inst->ring_enc[i]; |
452 | sprintf(ring->name, "uvd_enc%d", i); | 453 | sprintf(ring->name, "uvd_enc%d", i); |
453 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); | 454 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0); |
454 | if (r) | 455 | if (r) |
455 | return r; | 456 | return r; |
456 | } | 457 | } |
@@ -469,10 +470,10 @@ static int uvd_v6_0_sw_fini(void *handle) | |||
469 | return r; | 470 | return r; |
470 | 471 | ||
471 | if (uvd_v6_0_enc_support(adev)) { | 472 | if (uvd_v6_0_enc_support(adev)) { |
472 | drm_sched_entity_fini(&adev->uvd.ring_enc[0].sched, &adev->uvd.entity_enc); | 473 | drm_sched_entity_fini(&adev->uvd.inst->ring_enc[0].sched, &adev->uvd.inst->entity_enc); |
473 | 474 | ||
474 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) | 475 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) |
475 | amdgpu_ring_fini(&adev->uvd.ring_enc[i]); | 476 | amdgpu_ring_fini(&adev->uvd.inst->ring_enc[i]); |
476 | } | 477 | } |
477 | 478 | ||
478 | return amdgpu_uvd_sw_fini(adev); | 479 | return amdgpu_uvd_sw_fini(adev); |
@@ -488,7 +489,7 @@ static int uvd_v6_0_sw_fini(void *handle) | |||
488 | static int uvd_v6_0_hw_init(void *handle) | 489 | static int uvd_v6_0_hw_init(void *handle) |
489 | { | 490 | { |
490 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 491 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
491 | struct amdgpu_ring *ring = &adev->uvd.ring; | 492 | struct amdgpu_ring *ring = &adev->uvd.inst->ring; |
492 | uint32_t tmp; | 493 | uint32_t tmp; |
493 | int i, r; | 494 | int i, r; |
494 | 495 | ||
@@ -532,7 +533,7 @@ static int uvd_v6_0_hw_init(void *handle) | |||
532 | 533 | ||
533 | if (uvd_v6_0_enc_support(adev)) { | 534 | if (uvd_v6_0_enc_support(adev)) { |
534 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | 535 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { |
535 | ring = &adev->uvd.ring_enc[i]; | 536 | ring = &adev->uvd.inst->ring_enc[i]; |
536 | ring->ready = true; | 537 | ring->ready = true; |
537 | r = amdgpu_ring_test_ring(ring); | 538 | r = amdgpu_ring_test_ring(ring); |
538 | if (r) { | 539 | if (r) { |
@@ -563,7 +564,7 @@ done: | |||
563 | static int uvd_v6_0_hw_fini(void *handle) | 564 | static int uvd_v6_0_hw_fini(void *handle) |
564 | { | 565 | { |
565 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 566 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
566 | struct amdgpu_ring *ring = &adev->uvd.ring; | 567 | struct amdgpu_ring *ring = &adev->uvd.inst->ring; |
567 | 568 | ||
568 | if (RREG32(mmUVD_STATUS) != 0) | 569 | if (RREG32(mmUVD_STATUS) != 0) |
569 | uvd_v6_0_stop(adev); | 570 | uvd_v6_0_stop(adev); |
@@ -611,9 +612,9 @@ static void uvd_v6_0_mc_resume(struct amdgpu_device *adev) | |||
611 | 612 | ||
612 | /* programm memory controller bits 0-27 */ | 613 | /* programm memory controller bits 0-27 */ |
613 | WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, | 614 | WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, |
614 | lower_32_bits(adev->uvd.gpu_addr)); | 615 | lower_32_bits(adev->uvd.inst->gpu_addr)); |
615 | WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, | 616 | WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, |
616 | upper_32_bits(adev->uvd.gpu_addr)); | 617 | upper_32_bits(adev->uvd.inst->gpu_addr)); |
617 | 618 | ||
618 | offset = AMDGPU_UVD_FIRMWARE_OFFSET; | 619 | offset = AMDGPU_UVD_FIRMWARE_OFFSET; |
619 | size = AMDGPU_UVD_FIRMWARE_SIZE(adev); | 620 | size = AMDGPU_UVD_FIRMWARE_SIZE(adev); |
@@ -726,7 +727,7 @@ static void cz_set_uvd_clock_gating_branches(struct amdgpu_device *adev, | |||
726 | */ | 727 | */ |
727 | static int uvd_v6_0_start(struct amdgpu_device *adev) | 728 | static int uvd_v6_0_start(struct amdgpu_device *adev) |
728 | { | 729 | { |
729 | struct amdgpu_ring *ring = &adev->uvd.ring; | 730 | struct amdgpu_ring *ring = &adev->uvd.inst->ring; |
730 | uint32_t rb_bufsz, tmp; | 731 | uint32_t rb_bufsz, tmp; |
731 | uint32_t lmi_swap_cntl; | 732 | uint32_t lmi_swap_cntl; |
732 | uint32_t mp_swap_cntl; | 733 | uint32_t mp_swap_cntl; |
@@ -866,14 +867,14 @@ static int uvd_v6_0_start(struct amdgpu_device *adev) | |||
866 | WREG32_FIELD(UVD_RBC_RB_CNTL, RB_NO_FETCH, 0); | 867 | WREG32_FIELD(UVD_RBC_RB_CNTL, RB_NO_FETCH, 0); |
867 | 868 | ||
868 | if (uvd_v6_0_enc_support(adev)) { | 869 | if (uvd_v6_0_enc_support(adev)) { |
869 | ring = &adev->uvd.ring_enc[0]; | 870 | ring = &adev->uvd.inst->ring_enc[0]; |
870 | WREG32(mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); | 871 | WREG32(mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); |
871 | WREG32(mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); | 872 | WREG32(mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); |
872 | WREG32(mmUVD_RB_BASE_LO, ring->gpu_addr); | 873 | WREG32(mmUVD_RB_BASE_LO, ring->gpu_addr); |
873 | WREG32(mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); | 874 | WREG32(mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); |
874 | WREG32(mmUVD_RB_SIZE, ring->ring_size / 4); | 875 | WREG32(mmUVD_RB_SIZE, ring->ring_size / 4); |
875 | 876 | ||
876 | ring = &adev->uvd.ring_enc[1]; | 877 | ring = &adev->uvd.inst->ring_enc[1]; |
877 | WREG32(mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); | 878 | WREG32(mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); |
878 | WREG32(mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); | 879 | WREG32(mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); |
879 | WREG32(mmUVD_RB_BASE_LO2, ring->gpu_addr); | 880 | WREG32(mmUVD_RB_BASE_LO2, ring->gpu_addr); |
@@ -1099,6 +1100,18 @@ static void uvd_v6_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring) | |||
1099 | amdgpu_ring_write(ring, 0xE); | 1100 | amdgpu_ring_write(ring, 0xE); |
1100 | } | 1101 | } |
1101 | 1102 | ||
1103 | static void uvd_v6_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | ||
1104 | { | ||
1105 | int i; | ||
1106 | |||
1107 | WARN_ON(ring->wptr % 2 || count % 2); | ||
1108 | |||
1109 | for (i = 0; i < count / 2; i++) { | ||
1110 | amdgpu_ring_write(ring, PACKET0(mmUVD_NO_OP, 0)); | ||
1111 | amdgpu_ring_write(ring, 0); | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1102 | static void uvd_v6_0_enc_ring_emit_pipeline_sync(struct amdgpu_ring *ring) | 1115 | static void uvd_v6_0_enc_ring_emit_pipeline_sync(struct amdgpu_ring *ring) |
1103 | { | 1116 | { |
1104 | uint32_t seq = ring->fence_drv.sync_seq; | 1117 | uint32_t seq = ring->fence_drv.sync_seq; |
@@ -1158,10 +1171,10 @@ static bool uvd_v6_0_check_soft_reset(void *handle) | |||
1158 | srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_UVD, 1); | 1171 | srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_UVD, 1); |
1159 | 1172 | ||
1160 | if (srbm_soft_reset) { | 1173 | if (srbm_soft_reset) { |
1161 | adev->uvd.srbm_soft_reset = srbm_soft_reset; | 1174 | adev->uvd.inst->srbm_soft_reset = srbm_soft_reset; |
1162 | return true; | 1175 | return true; |
1163 | } else { | 1176 | } else { |
1164 | adev->uvd.srbm_soft_reset = 0; | 1177 | adev->uvd.inst->srbm_soft_reset = 0; |
1165 | return false; | 1178 | return false; |
1166 | } | 1179 | } |
1167 | } | 1180 | } |
@@ -1170,7 +1183,7 @@ static int uvd_v6_0_pre_soft_reset(void *handle) | |||
1170 | { | 1183 | { |
1171 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1184 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1172 | 1185 | ||
1173 | if (!adev->uvd.srbm_soft_reset) | 1186 | if (!adev->uvd.inst->srbm_soft_reset) |
1174 | return 0; | 1187 | return 0; |
1175 | 1188 | ||
1176 | uvd_v6_0_stop(adev); | 1189 | uvd_v6_0_stop(adev); |
@@ -1182,9 +1195,9 @@ static int uvd_v6_0_soft_reset(void *handle) | |||
1182 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1195 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1183 | u32 srbm_soft_reset; | 1196 | u32 srbm_soft_reset; |
1184 | 1197 | ||
1185 | if (!adev->uvd.srbm_soft_reset) | 1198 | if (!adev->uvd.inst->srbm_soft_reset) |
1186 | return 0; | 1199 | return 0; |
1187 | srbm_soft_reset = adev->uvd.srbm_soft_reset; | 1200 | srbm_soft_reset = adev->uvd.inst->srbm_soft_reset; |
1188 | 1201 | ||
1189 | if (srbm_soft_reset) { | 1202 | if (srbm_soft_reset) { |
1190 | u32 tmp; | 1203 | u32 tmp; |
@@ -1212,7 +1225,7 @@ static int uvd_v6_0_post_soft_reset(void *handle) | |||
1212 | { | 1225 | { |
1213 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1226 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1214 | 1227 | ||
1215 | if (!adev->uvd.srbm_soft_reset) | 1228 | if (!adev->uvd.inst->srbm_soft_reset) |
1216 | return 0; | 1229 | return 0; |
1217 | 1230 | ||
1218 | mdelay(5); | 1231 | mdelay(5); |
@@ -1238,17 +1251,17 @@ static int uvd_v6_0_process_interrupt(struct amdgpu_device *adev, | |||
1238 | 1251 | ||
1239 | switch (entry->src_id) { | 1252 | switch (entry->src_id) { |
1240 | case 124: | 1253 | case 124: |
1241 | amdgpu_fence_process(&adev->uvd.ring); | 1254 | amdgpu_fence_process(&adev->uvd.inst->ring); |
1242 | break; | 1255 | break; |
1243 | case 119: | 1256 | case 119: |
1244 | if (likely(uvd_v6_0_enc_support(adev))) | 1257 | if (likely(uvd_v6_0_enc_support(adev))) |
1245 | amdgpu_fence_process(&adev->uvd.ring_enc[0]); | 1258 | amdgpu_fence_process(&adev->uvd.inst->ring_enc[0]); |
1246 | else | 1259 | else |
1247 | int_handled = false; | 1260 | int_handled = false; |
1248 | break; | 1261 | break; |
1249 | case 120: | 1262 | case 120: |
1250 | if (likely(uvd_v6_0_enc_support(adev))) | 1263 | if (likely(uvd_v6_0_enc_support(adev))) |
1251 | amdgpu_fence_process(&adev->uvd.ring_enc[1]); | 1264 | amdgpu_fence_process(&adev->uvd.inst->ring_enc[1]); |
1252 | else | 1265 | else |
1253 | int_handled = false; | 1266 | int_handled = false; |
1254 | break; | 1267 | break; |
@@ -1531,7 +1544,6 @@ static const struct amd_ip_funcs uvd_v6_0_ip_funcs = { | |||
1531 | static const struct amdgpu_ring_funcs uvd_v6_0_ring_phys_funcs = { | 1544 | static const struct amdgpu_ring_funcs uvd_v6_0_ring_phys_funcs = { |
1532 | .type = AMDGPU_RING_TYPE_UVD, | 1545 | .type = AMDGPU_RING_TYPE_UVD, |
1533 | .align_mask = 0xf, | 1546 | .align_mask = 0xf, |
1534 | .nop = PACKET0(mmUVD_NO_OP, 0), | ||
1535 | .support_64bit_ptrs = false, | 1547 | .support_64bit_ptrs = false, |
1536 | .get_rptr = uvd_v6_0_ring_get_rptr, | 1548 | .get_rptr = uvd_v6_0_ring_get_rptr, |
1537 | .get_wptr = uvd_v6_0_ring_get_wptr, | 1549 | .get_wptr = uvd_v6_0_ring_get_wptr, |
@@ -1547,7 +1559,7 @@ static const struct amdgpu_ring_funcs uvd_v6_0_ring_phys_funcs = { | |||
1547 | .emit_hdp_flush = uvd_v6_0_ring_emit_hdp_flush, | 1559 | .emit_hdp_flush = uvd_v6_0_ring_emit_hdp_flush, |
1548 | .test_ring = uvd_v6_0_ring_test_ring, | 1560 | .test_ring = uvd_v6_0_ring_test_ring, |
1549 | .test_ib = amdgpu_uvd_ring_test_ib, | 1561 | .test_ib = amdgpu_uvd_ring_test_ib, |
1550 | .insert_nop = amdgpu_ring_insert_nop, | 1562 | .insert_nop = uvd_v6_0_ring_insert_nop, |
1551 | .pad_ib = amdgpu_ring_generic_pad_ib, | 1563 | .pad_ib = amdgpu_ring_generic_pad_ib, |
1552 | .begin_use = amdgpu_uvd_ring_begin_use, | 1564 | .begin_use = amdgpu_uvd_ring_begin_use, |
1553 | .end_use = amdgpu_uvd_ring_end_use, | 1565 | .end_use = amdgpu_uvd_ring_end_use, |
@@ -1612,10 +1624,10 @@ static const struct amdgpu_ring_funcs uvd_v6_0_enc_ring_vm_funcs = { | |||
1612 | static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev) | 1624 | static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev) |
1613 | { | 1625 | { |
1614 | if (adev->asic_type >= CHIP_POLARIS10) { | 1626 | if (adev->asic_type >= CHIP_POLARIS10) { |
1615 | adev->uvd.ring.funcs = &uvd_v6_0_ring_vm_funcs; | 1627 | adev->uvd.inst->ring.funcs = &uvd_v6_0_ring_vm_funcs; |
1616 | DRM_INFO("UVD is enabled in VM mode\n"); | 1628 | DRM_INFO("UVD is enabled in VM mode\n"); |
1617 | } else { | 1629 | } else { |
1618 | adev->uvd.ring.funcs = &uvd_v6_0_ring_phys_funcs; | 1630 | adev->uvd.inst->ring.funcs = &uvd_v6_0_ring_phys_funcs; |
1619 | DRM_INFO("UVD is enabled in physical mode\n"); | 1631 | DRM_INFO("UVD is enabled in physical mode\n"); |
1620 | } | 1632 | } |
1621 | } | 1633 | } |
@@ -1625,7 +1637,7 @@ static void uvd_v6_0_set_enc_ring_funcs(struct amdgpu_device *adev) | |||
1625 | int i; | 1637 | int i; |
1626 | 1638 | ||
1627 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) | 1639 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) |
1628 | adev->uvd.ring_enc[i].funcs = &uvd_v6_0_enc_ring_vm_funcs; | 1640 | adev->uvd.inst->ring_enc[i].funcs = &uvd_v6_0_enc_ring_vm_funcs; |
1629 | 1641 | ||
1630 | DRM_INFO("UVD ENC is enabled in VM mode\n"); | 1642 | DRM_INFO("UVD ENC is enabled in VM mode\n"); |
1631 | } | 1643 | } |
@@ -1638,11 +1650,11 @@ static const struct amdgpu_irq_src_funcs uvd_v6_0_irq_funcs = { | |||
1638 | static void uvd_v6_0_set_irq_funcs(struct amdgpu_device *adev) | 1650 | static void uvd_v6_0_set_irq_funcs(struct amdgpu_device *adev) |
1639 | { | 1651 | { |
1640 | if (uvd_v6_0_enc_support(adev)) | 1652 | if (uvd_v6_0_enc_support(adev)) |
1641 | adev->uvd.irq.num_types = adev->uvd.num_enc_rings + 1; | 1653 | adev->uvd.inst->irq.num_types = adev->uvd.num_enc_rings + 1; |
1642 | else | 1654 | else |
1643 | adev->uvd.irq.num_types = 1; | 1655 | adev->uvd.inst->irq.num_types = 1; |
1644 | 1656 | ||
1645 | adev->uvd.irq.funcs = &uvd_v6_0_irq_funcs; | 1657 | adev->uvd.inst->irq.funcs = &uvd_v6_0_irq_funcs; |
1646 | } | 1658 | } |
1647 | 1659 | ||
1648 | const struct amdgpu_ip_block_version uvd_v6_0_ip_block = | 1660 | const struct amdgpu_ip_block_version uvd_v6_0_ip_block = |
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index 0ca63d588670..57d32f21b3a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include "mmhub/mmhub_1_0_offset.h" | 40 | #include "mmhub/mmhub_1_0_offset.h" |
41 | #include "mmhub/mmhub_1_0_sh_mask.h" | 41 | #include "mmhub/mmhub_1_0_sh_mask.h" |
42 | 42 | ||
43 | #define UVD7_MAX_HW_INSTANCES_VEGA20 2 | ||
44 | |||
43 | static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev); | 45 | static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev); |
44 | static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev); | 46 | static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev); |
45 | static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev); | 47 | static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev); |
@@ -47,6 +49,11 @@ static int uvd_v7_0_start(struct amdgpu_device *adev); | |||
47 | static void uvd_v7_0_stop(struct amdgpu_device *adev); | 49 | static void uvd_v7_0_stop(struct amdgpu_device *adev); |
48 | static int uvd_v7_0_sriov_start(struct amdgpu_device *adev); | 50 | static int uvd_v7_0_sriov_start(struct amdgpu_device *adev); |
49 | 51 | ||
52 | static int amdgpu_ih_clientid_uvds[] = { | ||
53 | SOC15_IH_CLIENTID_UVD, | ||
54 | SOC15_IH_CLIENTID_UVD1 | ||
55 | }; | ||
56 | |||
50 | /** | 57 | /** |
51 | * uvd_v7_0_ring_get_rptr - get read pointer | 58 | * uvd_v7_0_ring_get_rptr - get read pointer |
52 | * | 59 | * |
@@ -58,7 +65,7 @@ static uint64_t uvd_v7_0_ring_get_rptr(struct amdgpu_ring *ring) | |||
58 | { | 65 | { |
59 | struct amdgpu_device *adev = ring->adev; | 66 | struct amdgpu_device *adev = ring->adev; |
60 | 67 | ||
61 | return RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR); | 68 | return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_RPTR); |
62 | } | 69 | } |
63 | 70 | ||
64 | /** | 71 | /** |
@@ -72,10 +79,10 @@ static uint64_t uvd_v7_0_enc_ring_get_rptr(struct amdgpu_ring *ring) | |||
72 | { | 79 | { |
73 | struct amdgpu_device *adev = ring->adev; | 80 | struct amdgpu_device *adev = ring->adev; |
74 | 81 | ||
75 | if (ring == &adev->uvd.ring_enc[0]) | 82 | if (ring == &adev->uvd.inst[ring->me].ring_enc[0]) |
76 | return RREG32_SOC15(UVD, 0, mmUVD_RB_RPTR); | 83 | return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR); |
77 | else | 84 | else |
78 | return RREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2); | 85 | return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR2); |
79 | } | 86 | } |
80 | 87 | ||
81 | /** | 88 | /** |
@@ -89,7 +96,7 @@ static uint64_t uvd_v7_0_ring_get_wptr(struct amdgpu_ring *ring) | |||
89 | { | 96 | { |
90 | struct amdgpu_device *adev = ring->adev; | 97 | struct amdgpu_device *adev = ring->adev; |
91 | 98 | ||
92 | return RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR); | 99 | return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR); |
93 | } | 100 | } |
94 | 101 | ||
95 | /** | 102 | /** |
@@ -106,10 +113,10 @@ static uint64_t uvd_v7_0_enc_ring_get_wptr(struct amdgpu_ring *ring) | |||
106 | if (ring->use_doorbell) | 113 | if (ring->use_doorbell) |
107 | return adev->wb.wb[ring->wptr_offs]; | 114 | return adev->wb.wb[ring->wptr_offs]; |
108 | 115 | ||
109 | if (ring == &adev->uvd.ring_enc[0]) | 116 | if (ring == &adev->uvd.inst[ring->me].ring_enc[0]) |
110 | return RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR); | 117 | return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR); |
111 | else | 118 | else |
112 | return RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2); | 119 | return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2); |
113 | } | 120 | } |
114 | 121 | ||
115 | /** | 122 | /** |
@@ -123,7 +130,7 @@ static void uvd_v7_0_ring_set_wptr(struct amdgpu_ring *ring) | |||
123 | { | 130 | { |
124 | struct amdgpu_device *adev = ring->adev; | 131 | struct amdgpu_device *adev = ring->adev; |
125 | 132 | ||
126 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr)); | 133 | WREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr)); |
127 | } | 134 | } |
128 | 135 | ||
129 | /** | 136 | /** |
@@ -144,11 +151,11 @@ static void uvd_v7_0_enc_ring_set_wptr(struct amdgpu_ring *ring) | |||
144 | return; | 151 | return; |
145 | } | 152 | } |
146 | 153 | ||
147 | if (ring == &adev->uvd.ring_enc[0]) | 154 | if (ring == &adev->uvd.inst[ring->me].ring_enc[0]) |
148 | WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, | 155 | WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR, |
149 | lower_32_bits(ring->wptr)); | 156 | lower_32_bits(ring->wptr)); |
150 | else | 157 | else |
151 | WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, | 158 | WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2, |
152 | lower_32_bits(ring->wptr)); | 159 | lower_32_bits(ring->wptr)); |
153 | } | 160 | } |
154 | 161 | ||
@@ -170,8 +177,8 @@ static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring) | |||
170 | 177 | ||
171 | r = amdgpu_ring_alloc(ring, 16); | 178 | r = amdgpu_ring_alloc(ring, 16); |
172 | if (r) { | 179 | if (r) { |
173 | DRM_ERROR("amdgpu: uvd enc failed to lock ring %d (%d).\n", | 180 | DRM_ERROR("amdgpu: uvd enc failed to lock (%d)ring %d (%d).\n", |
174 | ring->idx, r); | 181 | ring->me, ring->idx, r); |
175 | return r; | 182 | return r; |
176 | } | 183 | } |
177 | amdgpu_ring_write(ring, HEVC_ENC_CMD_END); | 184 | amdgpu_ring_write(ring, HEVC_ENC_CMD_END); |
@@ -184,11 +191,11 @@ static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring) | |||
184 | } | 191 | } |
185 | 192 | ||
186 | if (i < adev->usec_timeout) { | 193 | if (i < adev->usec_timeout) { |
187 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", | 194 | DRM_DEBUG("(%d)ring test on %d succeeded in %d usecs\n", |
188 | ring->idx, i); | 195 | ring->me, ring->idx, i); |
189 | } else { | 196 | } else { |
190 | DRM_ERROR("amdgpu: ring %d test failed\n", | 197 | DRM_ERROR("amdgpu: (%d)ring %d test failed\n", |
191 | ring->idx); | 198 | ring->me, ring->idx); |
192 | r = -ETIMEDOUT; | 199 | r = -ETIMEDOUT; |
193 | } | 200 | } |
194 | 201 | ||
@@ -342,24 +349,24 @@ static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
342 | 349 | ||
343 | r = uvd_v7_0_enc_get_create_msg(ring, 1, NULL); | 350 | r = uvd_v7_0_enc_get_create_msg(ring, 1, NULL); |
344 | if (r) { | 351 | if (r) { |
345 | DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r); | 352 | DRM_ERROR("amdgpu: (%d)failed to get create msg (%ld).\n", ring->me, r); |
346 | goto error; | 353 | goto error; |
347 | } | 354 | } |
348 | 355 | ||
349 | r = uvd_v7_0_enc_get_destroy_msg(ring, 1, true, &fence); | 356 | r = uvd_v7_0_enc_get_destroy_msg(ring, 1, true, &fence); |
350 | if (r) { | 357 | if (r) { |
351 | DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r); | 358 | DRM_ERROR("amdgpu: (%d)failed to get destroy ib (%ld).\n", ring->me, r); |
352 | goto error; | 359 | goto error; |
353 | } | 360 | } |
354 | 361 | ||
355 | r = dma_fence_wait_timeout(fence, false, timeout); | 362 | r = dma_fence_wait_timeout(fence, false, timeout); |
356 | if (r == 0) { | 363 | if (r == 0) { |
357 | DRM_ERROR("amdgpu: IB test timed out.\n"); | 364 | DRM_ERROR("amdgpu: (%d)IB test timed out.\n", ring->me); |
358 | r = -ETIMEDOUT; | 365 | r = -ETIMEDOUT; |
359 | } else if (r < 0) { | 366 | } else if (r < 0) { |
360 | DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); | 367 | DRM_ERROR("amdgpu: (%d)fence wait failed (%ld).\n", ring->me, r); |
361 | } else { | 368 | } else { |
362 | DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); | 369 | DRM_DEBUG("ib test on (%d)ring %d succeeded\n", ring->me, ring->idx); |
363 | r = 0; | 370 | r = 0; |
364 | } | 371 | } |
365 | error: | 372 | error: |
@@ -370,6 +377,10 @@ error: | |||
370 | static int uvd_v7_0_early_init(void *handle) | 377 | static int uvd_v7_0_early_init(void *handle) |
371 | { | 378 | { |
372 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 379 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
380 | if (adev->asic_type == CHIP_VEGA20) | ||
381 | adev->uvd.num_uvd_inst = UVD7_MAX_HW_INSTANCES_VEGA20; | ||
382 | else | ||
383 | adev->uvd.num_uvd_inst = 1; | ||
373 | 384 | ||
374 | if (amdgpu_sriov_vf(adev)) | 385 | if (amdgpu_sriov_vf(adev)) |
375 | adev->uvd.num_enc_rings = 1; | 386 | adev->uvd.num_enc_rings = 1; |
@@ -386,19 +397,21 @@ static int uvd_v7_0_sw_init(void *handle) | |||
386 | { | 397 | { |
387 | struct amdgpu_ring *ring; | 398 | struct amdgpu_ring *ring; |
388 | struct drm_sched_rq *rq; | 399 | struct drm_sched_rq *rq; |
389 | int i, r; | 400 | int i, j, r; |
390 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 401 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
391 | 402 | ||
392 | /* UVD TRAP */ | 403 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
393 | r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UVD, 124, &adev->uvd.irq); | 404 | /* UVD TRAP */ |
394 | if (r) | 405 | r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], 124, &adev->uvd.inst[j].irq); |
395 | return r; | ||
396 | |||
397 | /* UVD ENC TRAP */ | ||
398 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | ||
399 | r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UVD, i + 119, &adev->uvd.irq); | ||
400 | if (r) | 406 | if (r) |
401 | return r; | 407 | return r; |
408 | |||
409 | /* UVD ENC TRAP */ | ||
410 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | ||
411 | r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], i + 119, &adev->uvd.inst[j].irq); | ||
412 | if (r) | ||
413 | return r; | ||
414 | } | ||
402 | } | 415 | } |
403 | 416 | ||
404 | r = amdgpu_uvd_sw_init(adev); | 417 | r = amdgpu_uvd_sw_init(adev); |
@@ -415,43 +428,48 @@ static int uvd_v7_0_sw_init(void *handle) | |||
415 | DRM_INFO("PSP loading UVD firmware\n"); | 428 | DRM_INFO("PSP loading UVD firmware\n"); |
416 | } | 429 | } |
417 | 430 | ||
418 | ring = &adev->uvd.ring_enc[0]; | 431 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
419 | rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; | 432 | ring = &adev->uvd.inst[j].ring_enc[0]; |
420 | r = drm_sched_entity_init(&ring->sched, &adev->uvd.entity_enc, | 433 | rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; |
421 | rq, NULL); | 434 | r = drm_sched_entity_init(&ring->sched, &adev->uvd.inst[j].entity_enc, |
422 | if (r) { | 435 | rq, NULL); |
423 | DRM_ERROR("Failed setting up UVD ENC run queue.\n"); | 436 | if (r) { |
424 | return r; | 437 | DRM_ERROR("(%d)Failed setting up UVD ENC run queue.\n", j); |
438 | return r; | ||
439 | } | ||
425 | } | 440 | } |
426 | 441 | ||
427 | r = amdgpu_uvd_resume(adev); | 442 | r = amdgpu_uvd_resume(adev); |
428 | if (r) | 443 | if (r) |
429 | return r; | 444 | return r; |
430 | if (!amdgpu_sriov_vf(adev)) { | ||
431 | ring = &adev->uvd.ring; | ||
432 | sprintf(ring->name, "uvd"); | ||
433 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); | ||
434 | if (r) | ||
435 | return r; | ||
436 | } | ||
437 | 445 | ||
438 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | 446 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
439 | ring = &adev->uvd.ring_enc[i]; | 447 | if (!amdgpu_sriov_vf(adev)) { |
440 | sprintf(ring->name, "uvd_enc%d", i); | 448 | ring = &adev->uvd.inst[j].ring; |
441 | if (amdgpu_sriov_vf(adev)) { | 449 | sprintf(ring->name, "uvd<%d>", j); |
442 | ring->use_doorbell = true; | 450 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0); |
443 | 451 | if (r) | |
444 | /* currently only use the first enconding ring for | 452 | return r; |
445 | * sriov, so set unused location for other unused rings. | 453 | } |
446 | */ | 454 | |
447 | if (i == 0) | 455 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { |
448 | ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING0_1 * 2; | 456 | ring = &adev->uvd.inst[j].ring_enc[i]; |
449 | else | 457 | sprintf(ring->name, "uvd_enc%d<%d>", i, j); |
450 | ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING2_3 * 2 + 1; | 458 | if (amdgpu_sriov_vf(adev)) { |
459 | ring->use_doorbell = true; | ||
460 | |||
461 | /* currently only use the first enconding ring for | ||
462 | * sriov, so set unused location for other unused rings. | ||
463 | */ | ||
464 | if (i == 0) | ||
465 | ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING0_1 * 2; | ||
466 | else | ||
467 | ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING2_3 * 2 + 1; | ||
468 | } | ||
469 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0); | ||
470 | if (r) | ||
471 | return r; | ||
451 | } | 472 | } |
452 | r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0); | ||
453 | if (r) | ||
454 | return r; | ||
455 | } | 473 | } |
456 | 474 | ||
457 | r = amdgpu_virt_alloc_mm_table(adev); | 475 | r = amdgpu_virt_alloc_mm_table(adev); |
@@ -463,7 +481,7 @@ static int uvd_v7_0_sw_init(void *handle) | |||
463 | 481 | ||
464 | static int uvd_v7_0_sw_fini(void *handle) | 482 | static int uvd_v7_0_sw_fini(void *handle) |
465 | { | 483 | { |
466 | int i, r; | 484 | int i, j, r; |
467 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 485 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
468 | 486 | ||
469 | amdgpu_virt_free_mm_table(adev); | 487 | amdgpu_virt_free_mm_table(adev); |
@@ -472,11 +490,12 @@ static int uvd_v7_0_sw_fini(void *handle) | |||
472 | if (r) | 490 | if (r) |
473 | return r; | 491 | return r; |
474 | 492 | ||
475 | drm_sched_entity_fini(&adev->uvd.ring_enc[0].sched, &adev->uvd.entity_enc); | 493 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { |
476 | 494 | drm_sched_entity_fini(&adev->uvd.inst[j].ring_enc[0].sched, &adev->uvd.inst[j].entity_enc); | |
477 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) | ||
478 | amdgpu_ring_fini(&adev->uvd.ring_enc[i]); | ||
479 | 495 | ||
496 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) | ||
497 | amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]); | ||
498 | } | ||
480 | return amdgpu_uvd_sw_fini(adev); | 499 | return amdgpu_uvd_sw_fini(adev); |
481 | } | 500 | } |
482 | 501 | ||
@@ -490,9 +509,9 @@ static int uvd_v7_0_sw_fini(void *handle) | |||
490 | static int uvd_v7_0_hw_init(void *handle) | 509 | static int uvd_v7_0_hw_init(void *handle) |
491 | { | 510 | { |
492 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 511 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
493 | struct amdgpu_ring *ring = &adev->uvd.ring; | 512 | struct amdgpu_ring *ring; |
494 | uint32_t tmp; | 513 | uint32_t tmp; |
495 | int i, r; | 514 | int i, j, r; |
496 | 515 | ||
497 | if (amdgpu_sriov_vf(adev)) | 516 | if (amdgpu_sriov_vf(adev)) |
498 | r = uvd_v7_0_sriov_start(adev); | 517 | r = uvd_v7_0_sriov_start(adev); |
@@ -501,57 +520,60 @@ static int uvd_v7_0_hw_init(void *handle) | |||
501 | if (r) | 520 | if (r) |
502 | goto done; | 521 | goto done; |
503 | 522 | ||
504 | if (!amdgpu_sriov_vf(adev)) { | 523 | for (j = 0; j < adev->uvd.num_uvd_inst; ++j) { |
505 | ring->ready = true; | 524 | ring = &adev->uvd.inst[j].ring; |
506 | r = amdgpu_ring_test_ring(ring); | 525 | |
507 | if (r) { | 526 | if (!amdgpu_sriov_vf(adev)) { |
508 | ring->ready = false; | 527 | ring->ready = true; |
509 | goto done; | 528 | r = amdgpu_ring_test_ring(ring); |
510 | } | 529 | if (r) { |
511 | 530 | ring->ready = false; | |
512 | r = amdgpu_ring_alloc(ring, 10); | 531 | goto done; |
513 | if (r) { | 532 | } |
514 | DRM_ERROR("amdgpu: ring failed to lock UVD ring (%d).\n", r); | 533 | |
515 | goto done; | 534 | r = amdgpu_ring_alloc(ring, 10); |
535 | if (r) { | ||
536 | DRM_ERROR("amdgpu: (%d)ring failed to lock UVD ring (%d).\n", j, r); | ||
537 | goto done; | ||
538 | } | ||
539 | |||
540 | tmp = PACKET0(SOC15_REG_OFFSET(UVD, j, | ||
541 | mmUVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL), 0); | ||
542 | amdgpu_ring_write(ring, tmp); | ||
543 | amdgpu_ring_write(ring, 0xFFFFF); | ||
544 | |||
545 | tmp = PACKET0(SOC15_REG_OFFSET(UVD, j, | ||
546 | mmUVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL), 0); | ||
547 | amdgpu_ring_write(ring, tmp); | ||
548 | amdgpu_ring_write(ring, 0xFFFFF); | ||
549 | |||
550 | tmp = PACKET0(SOC15_REG_OFFSET(UVD, j, | ||
551 | mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL), 0); | ||
552 | amdgpu_ring_write(ring, tmp); | ||
553 | amdgpu_ring_write(ring, 0xFFFFF); | ||
554 | |||
555 | /* Clear timeout status bits */ | ||
556 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, j, | ||
557 | mmUVD_SEMA_TIMEOUT_STATUS), 0)); | ||
558 | amdgpu_ring_write(ring, 0x8); | ||
559 | |||
560 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, j, | ||
561 | mmUVD_SEMA_CNTL), 0)); | ||
562 | amdgpu_ring_write(ring, 3); | ||
563 | |||
564 | amdgpu_ring_commit(ring); | ||
516 | } | 565 | } |
517 | 566 | ||
518 | tmp = PACKET0(SOC15_REG_OFFSET(UVD, 0, | 567 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { |
519 | mmUVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL), 0); | 568 | ring = &adev->uvd.inst[j].ring_enc[i]; |
520 | amdgpu_ring_write(ring, tmp); | 569 | ring->ready = true; |
521 | amdgpu_ring_write(ring, 0xFFFFF); | 570 | r = amdgpu_ring_test_ring(ring); |
522 | 571 | if (r) { | |
523 | tmp = PACKET0(SOC15_REG_OFFSET(UVD, 0, | 572 | ring->ready = false; |
524 | mmUVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL), 0); | 573 | goto done; |
525 | amdgpu_ring_write(ring, tmp); | 574 | } |
526 | amdgpu_ring_write(ring, 0xFFFFF); | ||
527 | |||
528 | tmp = PACKET0(SOC15_REG_OFFSET(UVD, 0, | ||
529 | mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL), 0); | ||
530 | amdgpu_ring_write(ring, tmp); | ||
531 | amdgpu_ring_write(ring, 0xFFFFF); | ||
532 | |||
533 | /* Clear timeout status bits */ | ||
534 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0, | ||
535 | mmUVD_SEMA_TIMEOUT_STATUS), 0)); | ||
536 | amdgpu_ring_write(ring, 0x8); | ||
537 | |||
538 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0, | ||
539 | mmUVD_SEMA_CNTL), 0)); | ||
540 | amdgpu_ring_write(ring, 3); | ||
541 | |||
542 | amdgpu_ring_commit(ring); | ||
543 | } | ||
544 | |||
545 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { | ||
546 | ring = &adev->uvd.ring_enc[i]; | ||
547 | ring->ready = true; | ||
548 | r = amdgpu_ring_test_ring(ring); | ||
549 | if (r) { | ||
550 | ring->ready = false; | ||
551 | goto done; | ||
552 | } | 575 | } |
553 | } | 576 | } |
554 | |||
555 | done: | 577 | done: |
556 | if (!r) | 578 | if (!r) |
557 | DRM_INFO("UVD and UVD ENC initialized successfully.\n"); | 579 | DRM_INFO("UVD and UVD ENC initialized successfully.\n"); |
@@ -569,7 +591,7 @@ done: | |||
569 | static int uvd_v7_0_hw_fini(void *handle) | 591 | static int uvd_v7_0_hw_fini(void *handle) |
570 | { | 592 | { |
571 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 593 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
572 | struct amdgpu_ring *ring = &adev->uvd.ring; | 594 | int i; |
573 | 595 | ||
574 | if (!amdgpu_sriov_vf(adev)) | 596 | if (!amdgpu_sriov_vf(adev)) |
575 | uvd_v7_0_stop(adev); | 597 | uvd_v7_0_stop(adev); |
@@ -578,7 +600,8 @@ static int uvd_v7_0_hw_fini(void *handle) | |||
578 | DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); | 600 | DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); |
579 | } | 601 | } |
580 | 602 | ||
581 | ring->ready = false; | 603 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) |
604 | adev->uvd.inst[i].ring.ready = false; | ||
582 | 605 | ||
583 | return 0; | 606 | return 0; |
584 | } | 607 | } |
@@ -618,48 +641,51 @@ static void uvd_v7_0_mc_resume(struct amdgpu_device *adev) | |||
618 | { | 641 | { |
619 | uint32_t size = AMDGPU_UVD_FIRMWARE_SIZE(adev); | 642 | uint32_t size = AMDGPU_UVD_FIRMWARE_SIZE(adev); |
620 | uint32_t offset; | 643 | uint32_t offset; |
644 | int i; | ||
621 | 645 | ||
622 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { | 646 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
623 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, | 647 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { |
624 | lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); | 648 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, |
625 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, | 649 | lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); |
626 | upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); | 650 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, |
627 | offset = 0; | 651 | upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); |
628 | } else { | 652 | offset = 0; |
629 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, | 653 | } else { |
630 | lower_32_bits(adev->uvd.gpu_addr)); | 654 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, |
631 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, | 655 | lower_32_bits(adev->uvd.inst[i].gpu_addr)); |
632 | upper_32_bits(adev->uvd.gpu_addr)); | 656 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, |
633 | offset = size; | 657 | upper_32_bits(adev->uvd.inst[i].gpu_addr)); |
634 | } | 658 | offset = size; |
659 | } | ||
635 | 660 | ||
636 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0, | 661 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET0, |
637 | AMDGPU_UVD_FIRMWARE_OFFSET >> 3); | 662 | AMDGPU_UVD_FIRMWARE_OFFSET >> 3); |
638 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE0, size); | 663 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE0, size); |
639 | 664 | ||
640 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW, | 665 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW, |
641 | lower_32_bits(adev->uvd.gpu_addr + offset)); | 666 | lower_32_bits(adev->uvd.inst[i].gpu_addr + offset)); |
642 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH, | 667 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH, |
643 | upper_32_bits(adev->uvd.gpu_addr + offset)); | 668 | upper_32_bits(adev->uvd.inst[i].gpu_addr + offset)); |
644 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1, (1 << 21)); | 669 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET1, (1 << 21)); |
645 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_UVD_HEAP_SIZE); | 670 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_UVD_HEAP_SIZE); |
646 | 671 | ||
647 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW, | 672 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW, |
648 | lower_32_bits(adev->uvd.gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); | 673 | lower_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); |
649 | WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH, | 674 | WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH, |
650 | upper_32_bits(adev->uvd.gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); | 675 | upper_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); |
651 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2, (2 << 21)); | 676 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET2, (2 << 21)); |
652 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, | 677 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE2, |
653 | AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40)); | 678 | AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40)); |
654 | 679 | ||
655 | WREG32_SOC15(UVD, 0, mmUVD_UDEC_ADDR_CONFIG, | 680 | WREG32_SOC15(UVD, i, mmUVD_UDEC_ADDR_CONFIG, |
656 | adev->gfx.config.gb_addr_config); | 681 | adev->gfx.config.gb_addr_config); |
657 | WREG32_SOC15(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG, | 682 | WREG32_SOC15(UVD, i, mmUVD_UDEC_DB_ADDR_CONFIG, |
658 | adev->gfx.config.gb_addr_config); | 683 | adev->gfx.config.gb_addr_config); |
659 | WREG32_SOC15(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG, | 684 | WREG32_SOC15(UVD, i, mmUVD_UDEC_DBW_ADDR_CONFIG, |
660 | adev->gfx.config.gb_addr_config); | 685 | adev->gfx.config.gb_addr_config); |
661 | 686 | ||
662 | WREG32_SOC15(UVD, 0, mmUVD_GP_SCRATCH4, adev->uvd.max_handles); | 687 | WREG32_SOC15(UVD, i, mmUVD_GP_SCRATCH4, adev->uvd.max_handles); |
688 | } | ||
663 | } | 689 | } |
664 | 690 | ||
665 | static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev, | 691 | static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev, |
@@ -669,6 +695,7 @@ static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev, | |||
669 | uint64_t addr = table->gpu_addr; | 695 | uint64_t addr = table->gpu_addr; |
670 | struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)table->cpu_addr; | 696 | struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)table->cpu_addr; |
671 | uint32_t size; | 697 | uint32_t size; |
698 | int i; | ||
672 | 699 | ||
673 | size = header->header_size + header->vce_table_size + header->uvd_table_size; | 700 | size = header->header_size + header->vce_table_size + header->uvd_table_size; |
674 | 701 | ||
@@ -688,11 +715,12 @@ static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev, | |||
688 | /* 4, set resp to zero */ | 715 | /* 4, set resp to zero */ |
689 | WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP, 0); | 716 | WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP, 0); |
690 | 717 | ||
691 | WDOORBELL32(adev->uvd.ring_enc[0].doorbell_index, 0); | 718 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
692 | adev->wb.wb[adev->uvd.ring_enc[0].wptr_offs] = 0; | 719 | WDOORBELL32(adev->uvd.inst[i].ring_enc[0].doorbell_index, 0); |
693 | adev->uvd.ring_enc[0].wptr = 0; | 720 | adev->wb.wb[adev->uvd.inst[i].ring_enc[0].wptr_offs] = 0; |
694 | adev->uvd.ring_enc[0].wptr_old = 0; | 721 | adev->uvd.inst[i].ring_enc[0].wptr = 0; |
695 | 722 | adev->uvd.inst[i].ring_enc[0].wptr_old = 0; | |
723 | } | ||
696 | /* 5, kick off the initialization and wait until VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero */ | 724 | /* 5, kick off the initialization and wait until VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero */ |
697 | WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_HOST, 0x10000001); | 725 | WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_HOST, 0x10000001); |
698 | 726 | ||
@@ -725,6 +753,7 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev) | |||
725 | struct mmsch_v1_0_cmd_end end = { {0} }; | 753 | struct mmsch_v1_0_cmd_end end = { {0} }; |
726 | uint32_t *init_table = adev->virt.mm_table.cpu_addr; | 754 | uint32_t *init_table = adev->virt.mm_table.cpu_addr; |
727 | struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)init_table; | 755 | struct mmsch_v1_0_init_header *header = (struct mmsch_v1_0_init_header *)init_table; |
756 | uint8_t i = 0; | ||
728 | 757 | ||
729 | direct_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_WRITE; | 758 | direct_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_WRITE; |
730 | direct_rd_mod_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE; | 759 | direct_rd_mod_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE; |
@@ -742,120 +771,121 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev) | |||
742 | 771 | ||
743 | init_table += header->uvd_table_offset; | 772 | init_table += header->uvd_table_offset; |
744 | 773 | ||
745 | ring = &adev->uvd.ring; | 774 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
746 | ring->wptr = 0; | 775 | ring = &adev->uvd.inst[i].ring; |
747 | size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4); | 776 | ring->wptr = 0; |
748 | 777 | size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4); | |
749 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), | 778 | |
750 | 0xFFFFFFFF, 0x00000004); | 779 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS), |
751 | /* mc resume*/ | 780 | 0xFFFFFFFF, 0x00000004); |
752 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { | 781 | /* mc resume*/ |
753 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), | 782 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { |
754 | lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); | 783 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), |
755 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), | 784 | lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); |
756 | upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); | 785 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), |
757 | offset = 0; | 786 | upper_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr)); |
758 | } else { | 787 | offset = 0; |
759 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), | 788 | } else { |
760 | lower_32_bits(adev->uvd.gpu_addr)); | 789 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), |
761 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), | 790 | lower_32_bits(adev->uvd.inst[i].gpu_addr)); |
762 | upper_32_bits(adev->uvd.gpu_addr)); | 791 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), |
763 | offset = size; | 792 | upper_32_bits(adev->uvd.inst[i].gpu_addr)); |
793 | offset = size; | ||
794 | } | ||
795 | |||
796 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_OFFSET0), | ||
797 | AMDGPU_UVD_FIRMWARE_OFFSET >> 3); | ||
798 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE0), size); | ||
799 | |||
800 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), | ||
801 | lower_32_bits(adev->uvd.inst[i].gpu_addr + offset)); | ||
802 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), | ||
803 | upper_32_bits(adev->uvd.inst[i].gpu_addr + offset)); | ||
804 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_OFFSET1), (1 << 21)); | ||
805 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_UVD_HEAP_SIZE); | ||
806 | |||
807 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), | ||
808 | lower_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); | ||
809 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), | ||
810 | upper_32_bits(adev->uvd.inst[i].gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); | ||
811 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_OFFSET2), (2 << 21)); | ||
812 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CACHE_SIZE2), | ||
813 | AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40)); | ||
814 | |||
815 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_GP_SCRATCH4), adev->uvd.max_handles); | ||
816 | /* mc resume end*/ | ||
817 | |||
818 | /* disable clock gating */ | ||
819 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_CGC_CTRL), | ||
820 | ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK, 0); | ||
821 | |||
822 | /* disable interupt */ | ||
823 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN), | ||
824 | ~UVD_MASTINT_EN__VCPU_EN_MASK, 0); | ||
825 | |||
826 | /* stall UMC and register bus before resetting VCPU */ | ||
827 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2), | ||
828 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, | ||
829 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
830 | |||
831 | /* put LMI, VCPU, RBC etc... into reset */ | ||
832 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_SOFT_RESET), | ||
833 | (uint32_t)(UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | | ||
834 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | | ||
835 | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | | ||
836 | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | | ||
837 | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | | ||
838 | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | | ||
839 | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | | ||
840 | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK)); | ||
841 | |||
842 | /* initialize UVD memory controller */ | ||
843 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL), | ||
844 | (uint32_t)((0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | | ||
845 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | | ||
846 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | | ||
847 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | | ||
848 | UVD_LMI_CTRL__REQ_MODE_MASK | | ||
849 | 0x00100000L)); | ||
850 | |||
851 | /* take all subblocks out of reset, except VCPU */ | ||
852 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_SOFT_RESET), | ||
853 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
854 | |||
855 | /* enable VCPU clock */ | ||
856 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL), | ||
857 | UVD_VCPU_CNTL__CLK_EN_MASK); | ||
858 | |||
859 | /* enable master interrupt */ | ||
860 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN), | ||
861 | ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK), | ||
862 | (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK)); | ||
863 | |||
864 | /* clear the bit 4 of UVD_STATUS */ | ||
865 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS), | ||
866 | ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT), 0); | ||
867 | |||
868 | /* force RBC into idle state */ | ||
869 | size = order_base_2(ring->ring_size); | ||
870 | tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, size); | ||
871 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); | ||
872 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RBC_RB_CNTL), tmp); | ||
873 | |||
874 | ring = &adev->uvd.inst[i].ring_enc[0]; | ||
875 | ring->wptr = 0; | ||
876 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_BASE_LO), ring->gpu_addr); | ||
877 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_BASE_HI), upper_32_bits(ring->gpu_addr)); | ||
878 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_SIZE), ring->ring_size / 4); | ||
879 | |||
880 | /* boot up the VCPU */ | ||
881 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_SOFT_RESET), 0); | ||
882 | |||
883 | /* enable UMC */ | ||
884 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2), | ||
885 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, 0); | ||
886 | |||
887 | MMSCH_V1_0_INSERT_DIRECT_POLL(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS), 0x02, 0x02); | ||
764 | } | 888 | } |
765 | |||
766 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0), | ||
767 | AMDGPU_UVD_FIRMWARE_OFFSET >> 3); | ||
768 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE0), size); | ||
769 | |||
770 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), | ||
771 | lower_32_bits(adev->uvd.gpu_addr + offset)); | ||
772 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), | ||
773 | upper_32_bits(adev->uvd.gpu_addr + offset)); | ||
774 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1), (1 << 21)); | ||
775 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_UVD_HEAP_SIZE); | ||
776 | |||
777 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), | ||
778 | lower_32_bits(adev->uvd.gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); | ||
779 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), | ||
780 | upper_32_bits(adev->uvd.gpu_addr + offset + AMDGPU_UVD_HEAP_SIZE)); | ||
781 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2), (2 << 21)); | ||
782 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE2), | ||
783 | AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40)); | ||
784 | |||
785 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_GP_SCRATCH4), adev->uvd.max_handles); | ||
786 | /* mc resume end*/ | ||
787 | |||
788 | /* disable clock gating */ | ||
789 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_CGC_CTRL), | ||
790 | ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK, 0); | ||
791 | |||
792 | /* disable interupt */ | ||
793 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), | ||
794 | ~UVD_MASTINT_EN__VCPU_EN_MASK, 0); | ||
795 | |||
796 | /* stall UMC and register bus before resetting VCPU */ | ||
797 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), | ||
798 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, | ||
799 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
800 | |||
801 | /* put LMI, VCPU, RBC etc... into reset */ | ||
802 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), | ||
803 | (uint32_t)(UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | | ||
804 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | | ||
805 | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | | ||
806 | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | | ||
807 | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | | ||
808 | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | | ||
809 | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | | ||
810 | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK)); | ||
811 | |||
812 | /* initialize UVD memory controller */ | ||
813 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL), | ||
814 | (uint32_t)((0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | | ||
815 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | | ||
816 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | | ||
817 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | | ||
818 | UVD_LMI_CTRL__REQ_MODE_MASK | | ||
819 | 0x00100000L)); | ||
820 | |||
821 | /* take all subblocks out of reset, except VCPU */ | ||
822 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), | ||
823 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
824 | |||
825 | /* enable VCPU clock */ | ||
826 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CNTL), | ||
827 | UVD_VCPU_CNTL__CLK_EN_MASK); | ||
828 | |||
829 | /* enable master interrupt */ | ||
830 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), | ||
831 | ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK), | ||
832 | (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK)); | ||
833 | |||
834 | /* clear the bit 4 of UVD_STATUS */ | ||
835 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), | ||
836 | ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT), 0); | ||
837 | |||
838 | /* force RBC into idle state */ | ||
839 | size = order_base_2(ring->ring_size); | ||
840 | tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, size); | ||
841 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); | ||
842 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), tmp); | ||
843 | |||
844 | ring = &adev->uvd.ring_enc[0]; | ||
845 | ring->wptr = 0; | ||
846 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_LO), ring->gpu_addr); | ||
847 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_HI), upper_32_bits(ring->gpu_addr)); | ||
848 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_SIZE), ring->ring_size / 4); | ||
849 | |||
850 | /* boot up the VCPU */ | ||
851 | MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0); | ||
852 | |||
853 | /* enable UMC */ | ||
854 | MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), | ||
855 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, 0); | ||
856 | |||
857 | MMSCH_V1_0_INSERT_DIRECT_POLL(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0x02, 0x02); | ||
858 | |||
859 | /* add end packet */ | 889 | /* add end packet */ |
860 | memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end)); | 890 | memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end)); |
861 | table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4; | 891 | table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4; |
@@ -874,15 +904,17 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev) | |||
874 | */ | 904 | */ |
875 | static int uvd_v7_0_start(struct amdgpu_device *adev) | 905 | static int uvd_v7_0_start(struct amdgpu_device *adev) |
876 | { | 906 | { |
877 | struct amdgpu_ring *ring = &adev->uvd.ring; | 907 | struct amdgpu_ring *ring; |
878 | uint32_t rb_bufsz, tmp; | 908 | uint32_t rb_bufsz, tmp; |
879 | uint32_t lmi_swap_cntl; | 909 | uint32_t lmi_swap_cntl; |
880 | uint32_t mp_swap_cntl; | 910 | uint32_t mp_swap_cntl; |
881 | int i, j, r; | 911 | int i, j, k, r; |
882 | 912 | ||
883 | /* disable DPG */ | 913 | for (k = 0; k < adev->uvd.num_uvd_inst; ++k) { |
884 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), 0, | 914 | /* disable DPG */ |
885 | ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); | 915 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_POWER_STATUS), 0, |
916 | ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); | ||
917 | } | ||
886 | 918 | ||
887 | /* disable byte swapping */ | 919 | /* disable byte swapping */ |
888 | lmi_swap_cntl = 0; | 920 | lmi_swap_cntl = 0; |
@@ -890,157 +922,159 @@ static int uvd_v7_0_start(struct amdgpu_device *adev) | |||
890 | 922 | ||
891 | uvd_v7_0_mc_resume(adev); | 923 | uvd_v7_0_mc_resume(adev); |
892 | 924 | ||
893 | /* disable clock gating */ | 925 | for (k = 0; k < adev->uvd.num_uvd_inst; ++k) { |
894 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_CGC_CTRL), 0, | 926 | ring = &adev->uvd.inst[k].ring; |
895 | ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK); | 927 | /* disable clock gating */ |
896 | 928 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_CGC_CTRL), 0, | |
897 | /* disable interupt */ | 929 | ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK); |
898 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0, | ||
899 | ~UVD_MASTINT_EN__VCPU_EN_MASK); | ||
900 | |||
901 | /* stall UMC and register bus before resetting VCPU */ | ||
902 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), | ||
903 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, | ||
904 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
905 | mdelay(1); | ||
906 | |||
907 | /* put LMI, VCPU, RBC etc... into reset */ | ||
908 | WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, | ||
909 | UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | | ||
910 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | | ||
911 | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | | ||
912 | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | | ||
913 | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | | ||
914 | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | | ||
915 | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | | ||
916 | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK); | ||
917 | mdelay(5); | ||
918 | 930 | ||
919 | /* initialize UVD memory controller */ | 931 | /* disable interupt */ |
920 | WREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL, | 932 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_MASTINT_EN), 0, |
921 | (0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | | 933 | ~UVD_MASTINT_EN__VCPU_EN_MASK); |
922 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | | 934 | |
923 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | | 935 | /* stall UMC and register bus before resetting VCPU */ |
924 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | | 936 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_LMI_CTRL2), |
925 | UVD_LMI_CTRL__REQ_MODE_MASK | | 937 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, |
926 | 0x00100000L); | 938 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); |
939 | mdelay(1); | ||
940 | |||
941 | /* put LMI, VCPU, RBC etc... into reset */ | ||
942 | WREG32_SOC15(UVD, k, mmUVD_SOFT_RESET, | ||
943 | UVD_SOFT_RESET__LMI_SOFT_RESET_MASK | | ||
944 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | | ||
945 | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK | | ||
946 | UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | | ||
947 | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK | | ||
948 | UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | | ||
949 | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK | | ||
950 | UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK); | ||
951 | mdelay(5); | ||
952 | |||
953 | /* initialize UVD memory controller */ | ||
954 | WREG32_SOC15(UVD, k, mmUVD_LMI_CTRL, | ||
955 | (0x40 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) | | ||
956 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK | | ||
957 | UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK | | ||
958 | UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK | | ||
959 | UVD_LMI_CTRL__REQ_MODE_MASK | | ||
960 | 0x00100000L); | ||
927 | 961 | ||
928 | #ifdef __BIG_ENDIAN | 962 | #ifdef __BIG_ENDIAN |
929 | /* swap (8 in 32) RB and IB */ | 963 | /* swap (8 in 32) RB and IB */ |
930 | lmi_swap_cntl = 0xa; | 964 | lmi_swap_cntl = 0xa; |
931 | mp_swap_cntl = 0; | 965 | mp_swap_cntl = 0; |
932 | #endif | 966 | #endif |
933 | WREG32_SOC15(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl); | 967 | WREG32_SOC15(UVD, k, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl); |
934 | WREG32_SOC15(UVD, 0, mmUVD_MP_SWAP_CNTL, mp_swap_cntl); | 968 | WREG32_SOC15(UVD, k, mmUVD_MP_SWAP_CNTL, mp_swap_cntl); |
935 | |||
936 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA0, 0x40c2040); | ||
937 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA1, 0x0); | ||
938 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB0, 0x40c2040); | ||
939 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB1, 0x0); | ||
940 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_ALU, 0); | ||
941 | WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUX, 0x88); | ||
942 | |||
943 | /* take all subblocks out of reset, except VCPU */ | ||
944 | WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, | ||
945 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
946 | mdelay(5); | ||
947 | 969 | ||
948 | /* enable VCPU clock */ | 970 | WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXA0, 0x40c2040); |
949 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, | 971 | WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXA1, 0x0); |
950 | UVD_VCPU_CNTL__CLK_EN_MASK); | 972 | WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXB0, 0x40c2040); |
973 | WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUXB1, 0x0); | ||
974 | WREG32_SOC15(UVD, k, mmUVD_MPC_SET_ALU, 0); | ||
975 | WREG32_SOC15(UVD, k, mmUVD_MPC_SET_MUX, 0x88); | ||
951 | 976 | ||
952 | /* enable UMC */ | 977 | /* take all subblocks out of reset, except VCPU */ |
953 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0, | 978 | WREG32_SOC15(UVD, k, mmUVD_SOFT_RESET, |
954 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | 979 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); |
980 | mdelay(5); | ||
981 | |||
982 | /* enable VCPU clock */ | ||
983 | WREG32_SOC15(UVD, k, mmUVD_VCPU_CNTL, | ||
984 | UVD_VCPU_CNTL__CLK_EN_MASK); | ||
985 | |||
986 | /* enable UMC */ | ||
987 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_LMI_CTRL2), 0, | ||
988 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
955 | 989 | ||
956 | /* boot up the VCPU */ | 990 | /* boot up the VCPU */ |
957 | WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, 0); | 991 | WREG32_SOC15(UVD, k, mmUVD_SOFT_RESET, 0); |
958 | mdelay(10); | 992 | mdelay(10); |
959 | 993 | ||
960 | for (i = 0; i < 10; ++i) { | 994 | for (i = 0; i < 10; ++i) { |
961 | uint32_t status; | 995 | uint32_t status; |
962 | 996 | ||
963 | for (j = 0; j < 100; ++j) { | 997 | for (j = 0; j < 100; ++j) { |
964 | status = RREG32_SOC15(UVD, 0, mmUVD_STATUS); | 998 | status = RREG32_SOC15(UVD, k, mmUVD_STATUS); |
999 | if (status & 2) | ||
1000 | break; | ||
1001 | mdelay(10); | ||
1002 | } | ||
1003 | r = 0; | ||
965 | if (status & 2) | 1004 | if (status & 2) |
966 | break; | 1005 | break; |
1006 | |||
1007 | DRM_ERROR("UVD(%d) not responding, trying to reset the VCPU!!!\n", k); | ||
1008 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_SOFT_RESET), | ||
1009 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK, | ||
1010 | ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
967 | mdelay(10); | 1011 | mdelay(10); |
1012 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_SOFT_RESET), 0, | ||
1013 | ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
1014 | mdelay(10); | ||
1015 | r = -1; | ||
968 | } | 1016 | } |
969 | r = 0; | ||
970 | if (status & 2) | ||
971 | break; | ||
972 | |||
973 | DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n"); | ||
974 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), | ||
975 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK, | ||
976 | ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
977 | mdelay(10); | ||
978 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0, | ||
979 | ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
980 | mdelay(10); | ||
981 | r = -1; | ||
982 | } | ||
983 | 1017 | ||
984 | if (r) { | 1018 | if (r) { |
985 | DRM_ERROR("UVD not responding, giving up!!!\n"); | 1019 | DRM_ERROR("UVD(%d) not responding, giving up!!!\n", k); |
986 | return r; | 1020 | return r; |
987 | } | 1021 | } |
988 | /* enable master interrupt */ | 1022 | /* enable master interrupt */ |
989 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), | 1023 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_MASTINT_EN), |
990 | (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK), | 1024 | (UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK), |
991 | ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK)); | 1025 | ~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK)); |
992 | |||
993 | /* clear the bit 4 of UVD_STATUS */ | ||
994 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0, | ||
995 | ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); | ||
996 | |||
997 | /* force RBC into idle state */ | ||
998 | rb_bufsz = order_base_2(ring->ring_size); | ||
999 | tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz); | ||
1000 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); | ||
1001 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); | ||
1002 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0); | ||
1003 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); | ||
1004 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); | ||
1005 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp); | ||
1006 | |||
1007 | /* set the write pointer delay */ | ||
1008 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR_CNTL, 0); | ||
1009 | |||
1010 | /* set the wb address */ | ||
1011 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR_ADDR, | ||
1012 | (upper_32_bits(ring->gpu_addr) >> 2)); | ||
1013 | |||
1014 | /* programm the RB_BASE for ring buffer */ | ||
1015 | WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW, | ||
1016 | lower_32_bits(ring->gpu_addr)); | ||
1017 | WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH, | ||
1018 | upper_32_bits(ring->gpu_addr)); | ||
1019 | |||
1020 | /* Initialize the ring buffer's read and write pointers */ | ||
1021 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR, 0); | ||
1022 | |||
1023 | ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR); | ||
1024 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, | ||
1025 | lower_32_bits(ring->wptr)); | ||
1026 | |||
1027 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0, | ||
1028 | ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK); | ||
1029 | |||
1030 | ring = &adev->uvd.ring_enc[0]; | ||
1031 | WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); | ||
1032 | WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); | ||
1033 | WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr); | ||
1034 | WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); | ||
1035 | WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4); | ||
1036 | 1026 | ||
1037 | ring = &adev->uvd.ring_enc[1]; | 1027 | /* clear the bit 4 of UVD_STATUS */ |
1038 | WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); | 1028 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_STATUS), 0, |
1039 | WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); | 1029 | ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT)); |
1040 | WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr); | ||
1041 | WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); | ||
1042 | WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4); | ||
1043 | 1030 | ||
1031 | /* force RBC into idle state */ | ||
1032 | rb_bufsz = order_base_2(ring->ring_size); | ||
1033 | tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz); | ||
1034 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1); | ||
1035 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1); | ||
1036 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0); | ||
1037 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1); | ||
1038 | tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); | ||
1039 | WREG32_SOC15(UVD, k, mmUVD_RBC_RB_CNTL, tmp); | ||
1040 | |||
1041 | /* set the write pointer delay */ | ||
1042 | WREG32_SOC15(UVD, k, mmUVD_RBC_RB_WPTR_CNTL, 0); | ||
1043 | |||
1044 | /* set the wb address */ | ||
1045 | WREG32_SOC15(UVD, k, mmUVD_RBC_RB_RPTR_ADDR, | ||
1046 | (upper_32_bits(ring->gpu_addr) >> 2)); | ||
1047 | |||
1048 | /* programm the RB_BASE for ring buffer */ | ||
1049 | WREG32_SOC15(UVD, k, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW, | ||
1050 | lower_32_bits(ring->gpu_addr)); | ||
1051 | WREG32_SOC15(UVD, k, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH, | ||
1052 | upper_32_bits(ring->gpu_addr)); | ||
1053 | |||
1054 | /* Initialize the ring buffer's read and write pointers */ | ||
1055 | WREG32_SOC15(UVD, k, mmUVD_RBC_RB_RPTR, 0); | ||
1056 | |||
1057 | ring->wptr = RREG32_SOC15(UVD, k, mmUVD_RBC_RB_RPTR); | ||
1058 | WREG32_SOC15(UVD, k, mmUVD_RBC_RB_WPTR, | ||
1059 | lower_32_bits(ring->wptr)); | ||
1060 | |||
1061 | WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_RBC_RB_CNTL), 0, | ||
1062 | ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK); | ||
1063 | |||
1064 | ring = &adev->uvd.inst[k].ring_enc[0]; | ||
1065 | WREG32_SOC15(UVD, k, mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); | ||
1066 | WREG32_SOC15(UVD, k, mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); | ||
1067 | WREG32_SOC15(UVD, k, mmUVD_RB_BASE_LO, ring->gpu_addr); | ||
1068 | WREG32_SOC15(UVD, k, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); | ||
1069 | WREG32_SOC15(UVD, k, mmUVD_RB_SIZE, ring->ring_size / 4); | ||
1070 | |||
1071 | ring = &adev->uvd.inst[k].ring_enc[1]; | ||
1072 | WREG32_SOC15(UVD, k, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); | ||
1073 | WREG32_SOC15(UVD, k, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); | ||
1074 | WREG32_SOC15(UVD, k, mmUVD_RB_BASE_LO2, ring->gpu_addr); | ||
1075 | WREG32_SOC15(UVD, k, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); | ||
1076 | WREG32_SOC15(UVD, k, mmUVD_RB_SIZE2, ring->ring_size / 4); | ||
1077 | } | ||
1044 | return 0; | 1078 | return 0; |
1045 | } | 1079 | } |
1046 | 1080 | ||
@@ -1053,26 +1087,30 @@ static int uvd_v7_0_start(struct amdgpu_device *adev) | |||
1053 | */ | 1087 | */ |
1054 | static void uvd_v7_0_stop(struct amdgpu_device *adev) | 1088 | static void uvd_v7_0_stop(struct amdgpu_device *adev) |
1055 | { | 1089 | { |
1056 | /* force RBC into idle state */ | 1090 | uint8_t i = 0; |
1057 | WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, 0x11010101); | ||
1058 | |||
1059 | /* Stall UMC and register bus before resetting VCPU */ | ||
1060 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), | ||
1061 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, | ||
1062 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
1063 | mdelay(1); | ||
1064 | |||
1065 | /* put VCPU into reset */ | ||
1066 | WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, | ||
1067 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
1068 | mdelay(5); | ||
1069 | 1091 | ||
1070 | /* disable VCPU clock */ | 1092 | for (i = 0; i < adev->uvd.num_uvd_inst; ++i) { |
1071 | WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, 0x0); | 1093 | /* force RBC into idle state */ |
1094 | WREG32_SOC15(UVD, i, mmUVD_RBC_RB_CNTL, 0x11010101); | ||
1095 | |||
1096 | /* Stall UMC and register bus before resetting VCPU */ | ||
1097 | WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2), | ||
1098 | UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, | ||
1099 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
1100 | mdelay(1); | ||
1101 | |||
1102 | /* put VCPU into reset */ | ||
1103 | WREG32_SOC15(UVD, i, mmUVD_SOFT_RESET, | ||
1104 | UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK); | ||
1105 | mdelay(5); | ||
1072 | 1106 | ||
1073 | /* Unstall UMC and register bus */ | 1107 | /* disable VCPU clock */ |
1074 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0, | 1108 | WREG32_SOC15(UVD, i, mmUVD_VCPU_CNTL, 0x0); |
1075 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | 1109 | |
1110 | /* Unstall UMC and register bus */ | ||
1111 | WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2), 0, | ||
1112 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | ||
1113 | } | ||
1076 | } | 1114 | } |
1077 | 1115 | ||
1078 | /** | 1116 | /** |
@@ -1091,26 +1129,26 @@ static void uvd_v7_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq | |||
1091 | WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); | 1129 | WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); |
1092 | 1130 | ||
1093 | amdgpu_ring_write(ring, | 1131 | amdgpu_ring_write(ring, |
1094 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0)); | 1132 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_CONTEXT_ID), 0)); |
1095 | amdgpu_ring_write(ring, seq); | 1133 | amdgpu_ring_write(ring, seq); |
1096 | amdgpu_ring_write(ring, | 1134 | amdgpu_ring_write(ring, |
1097 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); | 1135 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0)); |
1098 | amdgpu_ring_write(ring, addr & 0xffffffff); | 1136 | amdgpu_ring_write(ring, addr & 0xffffffff); |
1099 | amdgpu_ring_write(ring, | 1137 | amdgpu_ring_write(ring, |
1100 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); | 1138 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0)); |
1101 | amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff); | 1139 | amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff); |
1102 | amdgpu_ring_write(ring, | 1140 | amdgpu_ring_write(ring, |
1103 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); | 1141 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0)); |
1104 | amdgpu_ring_write(ring, 0); | 1142 | amdgpu_ring_write(ring, 0); |
1105 | 1143 | ||
1106 | amdgpu_ring_write(ring, | 1144 | amdgpu_ring_write(ring, |
1107 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); | 1145 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0)); |
1108 | amdgpu_ring_write(ring, 0); | 1146 | amdgpu_ring_write(ring, 0); |
1109 | amdgpu_ring_write(ring, | 1147 | amdgpu_ring_write(ring, |
1110 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); | 1148 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0)); |
1111 | amdgpu_ring_write(ring, 0); | 1149 | amdgpu_ring_write(ring, 0); |
1112 | amdgpu_ring_write(ring, | 1150 | amdgpu_ring_write(ring, |
1113 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); | 1151 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0)); |
1114 | amdgpu_ring_write(ring, 2); | 1152 | amdgpu_ring_write(ring, 2); |
1115 | } | 1153 | } |
1116 | 1154 | ||
@@ -1159,30 +1197,30 @@ static int uvd_v7_0_ring_test_ring(struct amdgpu_ring *ring) | |||
1159 | unsigned i; | 1197 | unsigned i; |
1160 | int r; | 1198 | int r; |
1161 | 1199 | ||
1162 | WREG32_SOC15(UVD, 0, mmUVD_CONTEXT_ID, 0xCAFEDEAD); | 1200 | WREG32_SOC15(UVD, ring->me, mmUVD_CONTEXT_ID, 0xCAFEDEAD); |
1163 | r = amdgpu_ring_alloc(ring, 3); | 1201 | r = amdgpu_ring_alloc(ring, 3); |
1164 | if (r) { | 1202 | if (r) { |
1165 | DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", | 1203 | DRM_ERROR("amdgpu: (%d)cp failed to lock ring %d (%d).\n", |
1166 | ring->idx, r); | 1204 | ring->me, ring->idx, r); |
1167 | return r; | 1205 | return r; |
1168 | } | 1206 | } |
1169 | amdgpu_ring_write(ring, | 1207 | amdgpu_ring_write(ring, |
1170 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0)); | 1208 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_CONTEXT_ID), 0)); |
1171 | amdgpu_ring_write(ring, 0xDEADBEEF); | 1209 | amdgpu_ring_write(ring, 0xDEADBEEF); |
1172 | amdgpu_ring_commit(ring); | 1210 | amdgpu_ring_commit(ring); |
1173 | for (i = 0; i < adev->usec_timeout; i++) { | 1211 | for (i = 0; i < adev->usec_timeout; i++) { |
1174 | tmp = RREG32_SOC15(UVD, 0, mmUVD_CONTEXT_ID); | 1212 | tmp = RREG32_SOC15(UVD, ring->me, mmUVD_CONTEXT_ID); |
1175 | if (tmp == 0xDEADBEEF) | 1213 | if (tmp == 0xDEADBEEF) |
1176 | break; | 1214 | break; |
1177 | DRM_UDELAY(1); | 1215 | DRM_UDELAY(1); |
1178 | } | 1216 | } |
1179 | 1217 | ||
1180 | if (i < adev->usec_timeout) { | 1218 | if (i < adev->usec_timeout) { |
1181 | DRM_DEBUG("ring test on %d succeeded in %d usecs\n", | 1219 | DRM_DEBUG("(%d)ring test on %d succeeded in %d usecs\n", |
1182 | ring->idx, i); | 1220 | ring->me, ring->idx, i); |
1183 | } else { | 1221 | } else { |
1184 | DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", | 1222 | DRM_ERROR("(%d)amdgpu: ring %d test failed (0x%08X)\n", |
1185 | ring->idx, tmp); | 1223 | ring->me, ring->idx, tmp); |
1186 | r = -EINVAL; | 1224 | r = -EINVAL; |
1187 | } | 1225 | } |
1188 | return r; | 1226 | return r; |
@@ -1203,17 +1241,17 @@ static void uvd_v7_0_ring_emit_ib(struct amdgpu_ring *ring, | |||
1203 | struct amdgpu_device *adev = ring->adev; | 1241 | struct amdgpu_device *adev = ring->adev; |
1204 | 1242 | ||
1205 | amdgpu_ring_write(ring, | 1243 | amdgpu_ring_write(ring, |
1206 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_VMID), 0)); | 1244 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_VMID), 0)); |
1207 | amdgpu_ring_write(ring, vmid); | 1245 | amdgpu_ring_write(ring, vmid); |
1208 | 1246 | ||
1209 | amdgpu_ring_write(ring, | 1247 | amdgpu_ring_write(ring, |
1210 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_LOW), 0)); | 1248 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_64BIT_BAR_LOW), 0)); |
1211 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); | 1249 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); |
1212 | amdgpu_ring_write(ring, | 1250 | amdgpu_ring_write(ring, |
1213 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH), 0)); | 1251 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH), 0)); |
1214 | amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); | 1252 | amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr)); |
1215 | amdgpu_ring_write(ring, | 1253 | amdgpu_ring_write(ring, |
1216 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_IB_SIZE), 0)); | 1254 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_RBC_IB_SIZE), 0)); |
1217 | amdgpu_ring_write(ring, ib->length_dw); | 1255 | amdgpu_ring_write(ring, ib->length_dw); |
1218 | } | 1256 | } |
1219 | 1257 | ||
@@ -1241,13 +1279,13 @@ static void uvd_v7_0_ring_emit_wreg(struct amdgpu_ring *ring, | |||
1241 | struct amdgpu_device *adev = ring->adev; | 1279 | struct amdgpu_device *adev = ring->adev; |
1242 | 1280 | ||
1243 | amdgpu_ring_write(ring, | 1281 | amdgpu_ring_write(ring, |
1244 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); | 1282 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0)); |
1245 | amdgpu_ring_write(ring, reg << 2); | 1283 | amdgpu_ring_write(ring, reg << 2); |
1246 | amdgpu_ring_write(ring, | 1284 | amdgpu_ring_write(ring, |
1247 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); | 1285 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0)); |
1248 | amdgpu_ring_write(ring, val); | 1286 | amdgpu_ring_write(ring, val); |
1249 | amdgpu_ring_write(ring, | 1287 | amdgpu_ring_write(ring, |
1250 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); | 1288 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0)); |
1251 | amdgpu_ring_write(ring, 8); | 1289 | amdgpu_ring_write(ring, 8); |
1252 | } | 1290 | } |
1253 | 1291 | ||
@@ -1257,16 +1295,16 @@ static void uvd_v7_0_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg, | |||
1257 | struct amdgpu_device *adev = ring->adev; | 1295 | struct amdgpu_device *adev = ring->adev; |
1258 | 1296 | ||
1259 | amdgpu_ring_write(ring, | 1297 | amdgpu_ring_write(ring, |
1260 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); | 1298 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA0), 0)); |
1261 | amdgpu_ring_write(ring, reg << 2); | 1299 | amdgpu_ring_write(ring, reg << 2); |
1262 | amdgpu_ring_write(ring, | 1300 | amdgpu_ring_write(ring, |
1263 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); | 1301 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_DATA1), 0)); |
1264 | amdgpu_ring_write(ring, val); | 1302 | amdgpu_ring_write(ring, val); |
1265 | amdgpu_ring_write(ring, | 1303 | amdgpu_ring_write(ring, |
1266 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GP_SCRATCH8), 0)); | 1304 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GP_SCRATCH8), 0)); |
1267 | amdgpu_ring_write(ring, mask); | 1305 | amdgpu_ring_write(ring, mask); |
1268 | amdgpu_ring_write(ring, | 1306 | amdgpu_ring_write(ring, |
1269 | PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); | 1307 | PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_GPCOM_VCPU_CMD), 0)); |
1270 | amdgpu_ring_write(ring, 12); | 1308 | amdgpu_ring_write(ring, 12); |
1271 | } | 1309 | } |
1272 | 1310 | ||
@@ -1287,12 +1325,15 @@ static void uvd_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring, | |||
1287 | 1325 | ||
1288 | static void uvd_v7_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | 1326 | static void uvd_v7_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) |
1289 | { | 1327 | { |
1290 | int i; | ||
1291 | struct amdgpu_device *adev = ring->adev; | 1328 | struct amdgpu_device *adev = ring->adev; |
1329 | int i; | ||
1292 | 1330 | ||
1293 | for (i = 0; i < count; i++) | 1331 | WARN_ON(ring->wptr % 2 || count % 2); |
1294 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP), 0)); | ||
1295 | 1332 | ||
1333 | for (i = 0; i < count / 2; i++) { | ||
1334 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, ring->me, mmUVD_NO_OP), 0)); | ||
1335 | amdgpu_ring_write(ring, 0); | ||
1336 | } | ||
1296 | } | 1337 | } |
1297 | 1338 | ||
1298 | static void uvd_v7_0_enc_ring_insert_end(struct amdgpu_ring *ring) | 1339 | static void uvd_v7_0_enc_ring_insert_end(struct amdgpu_ring *ring) |
@@ -1359,16 +1400,16 @@ static bool uvd_v7_0_check_soft_reset(void *handle) | |||
1359 | 1400 | ||
1360 | if (REG_GET_FIELD(tmp, SRBM_STATUS, UVD_RQ_PENDING) || | 1401 | if (REG_GET_FIELD(tmp, SRBM_STATUS, UVD_RQ_PENDING) || |
1361 | REG_GET_FIELD(tmp, SRBM_STATUS, UVD_BUSY) || | 1402 | REG_GET_FIELD(tmp, SRBM_STATUS, UVD_BUSY) || |
1362 | (RREG32_SOC15(UVD, 0, mmUVD_STATUS) & | 1403 | (RREG32_SOC15(UVD, ring->me, mmUVD_STATUS) & |
1363 | AMDGPU_UVD_STATUS_BUSY_MASK)) | 1404 | AMDGPU_UVD_STATUS_BUSY_MASK)) |
1364 | srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, | 1405 | srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, |
1365 | SRBM_SOFT_RESET, SOFT_RESET_UVD, 1); | 1406 | SRBM_SOFT_RESET, SOFT_RESET_UVD, 1); |
1366 | 1407 | ||
1367 | if (srbm_soft_reset) { | 1408 | if (srbm_soft_reset) { |
1368 | adev->uvd.srbm_soft_reset = srbm_soft_reset; | 1409 | adev->uvd.inst[ring->me].srbm_soft_reset = srbm_soft_reset; |
1369 | return true; | 1410 | return true; |
1370 | } else { | 1411 | } else { |
1371 | adev->uvd.srbm_soft_reset = 0; | 1412 | adev->uvd.inst[ring->me].srbm_soft_reset = 0; |
1372 | return false; | 1413 | return false; |
1373 | } | 1414 | } |
1374 | } | 1415 | } |
@@ -1377,7 +1418,7 @@ static int uvd_v7_0_pre_soft_reset(void *handle) | |||
1377 | { | 1418 | { |
1378 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1419 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1379 | 1420 | ||
1380 | if (!adev->uvd.srbm_soft_reset) | 1421 | if (!adev->uvd.inst[ring->me].srbm_soft_reset) |
1381 | return 0; | 1422 | return 0; |
1382 | 1423 | ||
1383 | uvd_v7_0_stop(adev); | 1424 | uvd_v7_0_stop(adev); |
@@ -1389,9 +1430,9 @@ static int uvd_v7_0_soft_reset(void *handle) | |||
1389 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1430 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1390 | u32 srbm_soft_reset; | 1431 | u32 srbm_soft_reset; |
1391 | 1432 | ||
1392 | if (!adev->uvd.srbm_soft_reset) | 1433 | if (!adev->uvd.inst[ring->me].srbm_soft_reset) |
1393 | return 0; | 1434 | return 0; |
1394 | srbm_soft_reset = adev->uvd.srbm_soft_reset; | 1435 | srbm_soft_reset = adev->uvd.inst[ring->me].srbm_soft_reset; |
1395 | 1436 | ||
1396 | if (srbm_soft_reset) { | 1437 | if (srbm_soft_reset) { |
1397 | u32 tmp; | 1438 | u32 tmp; |
@@ -1419,7 +1460,7 @@ static int uvd_v7_0_post_soft_reset(void *handle) | |||
1419 | { | 1460 | { |
1420 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1461 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
1421 | 1462 | ||
1422 | if (!adev->uvd.srbm_soft_reset) | 1463 | if (!adev->uvd.inst[ring->me].srbm_soft_reset) |
1423 | return 0; | 1464 | return 0; |
1424 | 1465 | ||
1425 | mdelay(5); | 1466 | mdelay(5); |
@@ -1441,17 +1482,32 @@ static int uvd_v7_0_process_interrupt(struct amdgpu_device *adev, | |||
1441 | struct amdgpu_irq_src *source, | 1482 | struct amdgpu_irq_src *source, |
1442 | struct amdgpu_iv_entry *entry) | 1483 | struct amdgpu_iv_entry *entry) |
1443 | { | 1484 | { |
1485 | uint32_t ip_instance; | ||
1486 | |||
1487 | switch (entry->client_id) { | ||
1488 | case SOC15_IH_CLIENTID_UVD: | ||
1489 | ip_instance = 0; | ||
1490 | break; | ||
1491 | case SOC15_IH_CLIENTID_UVD1: | ||
1492 | ip_instance = 1; | ||
1493 | break; | ||
1494 | default: | ||
1495 | DRM_ERROR("Unhandled client id: %d\n", entry->client_id); | ||
1496 | return 0; | ||
1497 | } | ||
1498 | |||
1444 | DRM_DEBUG("IH: UVD TRAP\n"); | 1499 | DRM_DEBUG("IH: UVD TRAP\n"); |
1500 | |||
1445 | switch (entry->src_id) { | 1501 | switch (entry->src_id) { |
1446 | case 124: | 1502 | case 124: |
1447 | amdgpu_fence_process(&adev->uvd.ring); | 1503 | amdgpu_fence_process(&adev->uvd.inst[ip_instance].ring); |
1448 | break; | 1504 | break; |
1449 | case 119: | 1505 | case 119: |
1450 | amdgpu_fence_process(&adev->uvd.ring_enc[0]); | 1506 | amdgpu_fence_process(&adev->uvd.inst[ip_instance].ring_enc[0]); |
1451 | break; | 1507 | break; |
1452 | case 120: | 1508 | case 120: |
1453 | if (!amdgpu_sriov_vf(adev)) | 1509 | if (!amdgpu_sriov_vf(adev)) |
1454 | amdgpu_fence_process(&adev->uvd.ring_enc[1]); | 1510 | amdgpu_fence_process(&adev->uvd.inst[ip_instance].ring_enc[1]); |
1455 | break; | 1511 | break; |
1456 | default: | 1512 | default: |
1457 | DRM_ERROR("Unhandled interrupt: %d %d\n", | 1513 | DRM_ERROR("Unhandled interrupt: %d %d\n", |
@@ -1467,9 +1523,9 @@ static void uvd_v7_0_set_sw_clock_gating(struct amdgpu_device *adev) | |||
1467 | { | 1523 | { |
1468 | uint32_t data, data1, data2, suvd_flags; | 1524 | uint32_t data, data1, data2, suvd_flags; |
1469 | 1525 | ||
1470 | data = RREG32_SOC15(UVD, 0, mmUVD_CGC_CTRL); | 1526 | data = RREG32_SOC15(UVD, ring->me, mmUVD_CGC_CTRL); |
1471 | data1 = RREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_GATE); | 1527 | data1 = RREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE); |
1472 | data2 = RREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_CTRL); | 1528 | data2 = RREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_CTRL); |
1473 | 1529 | ||
1474 | data &= ~(UVD_CGC_CTRL__CLK_OFF_DELAY_MASK | | 1530 | data &= ~(UVD_CGC_CTRL__CLK_OFF_DELAY_MASK | |
1475 | UVD_CGC_CTRL__CLK_GATE_DLY_TIMER_MASK); | 1531 | UVD_CGC_CTRL__CLK_GATE_DLY_TIMER_MASK); |
@@ -1513,18 +1569,18 @@ static void uvd_v7_0_set_sw_clock_gating(struct amdgpu_device *adev) | |||
1513 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK); | 1569 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK); |
1514 | data1 |= suvd_flags; | 1570 | data1 |= suvd_flags; |
1515 | 1571 | ||
1516 | WREG32_SOC15(UVD, 0, mmUVD_CGC_CTRL, data); | 1572 | WREG32_SOC15(UVD, ring->me, mmUVD_CGC_CTRL, data); |
1517 | WREG32_SOC15(UVD, 0, mmUVD_CGC_GATE, 0); | 1573 | WREG32_SOC15(UVD, ring->me, mmUVD_CGC_GATE, 0); |
1518 | WREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_GATE, data1); | 1574 | WREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE, data1); |
1519 | WREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_CTRL, data2); | 1575 | WREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_CTRL, data2); |
1520 | } | 1576 | } |
1521 | 1577 | ||
1522 | static void uvd_v7_0_set_hw_clock_gating(struct amdgpu_device *adev) | 1578 | static void uvd_v7_0_set_hw_clock_gating(struct amdgpu_device *adev) |
1523 | { | 1579 | { |
1524 | uint32_t data, data1, cgc_flags, suvd_flags; | 1580 | uint32_t data, data1, cgc_flags, suvd_flags; |
1525 | 1581 | ||
1526 | data = RREG32_SOC15(UVD, 0, mmUVD_CGC_GATE); | 1582 | data = RREG32_SOC15(UVD, ring->me, mmUVD_CGC_GATE); |
1527 | data1 = RREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_GATE); | 1583 | data1 = RREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE); |
1528 | 1584 | ||
1529 | cgc_flags = UVD_CGC_GATE__SYS_MASK | | 1585 | cgc_flags = UVD_CGC_GATE__SYS_MASK | |
1530 | UVD_CGC_GATE__UDEC_MASK | | 1586 | UVD_CGC_GATE__UDEC_MASK | |
@@ -1556,8 +1612,8 @@ static void uvd_v7_0_set_hw_clock_gating(struct amdgpu_device *adev) | |||
1556 | data |= cgc_flags; | 1612 | data |= cgc_flags; |
1557 | data1 |= suvd_flags; | 1613 | data1 |= suvd_flags; |
1558 | 1614 | ||
1559 | WREG32_SOC15(UVD, 0, mmUVD_CGC_GATE, data); | 1615 | WREG32_SOC15(UVD, ring->me, mmUVD_CGC_GATE, data); |
1560 | WREG32_SOC15(UVD, 0, mmUVD_SUVD_CGC_GATE, data1); | 1616 | WREG32_SOC15(UVD, ring->me, mmUVD_SUVD_CGC_GATE, data1); |
1561 | } | 1617 | } |
1562 | 1618 | ||
1563 | static void uvd_v7_0_set_bypass_mode(struct amdgpu_device *adev, bool enable) | 1619 | static void uvd_v7_0_set_bypass_mode(struct amdgpu_device *adev, bool enable) |
@@ -1616,7 +1672,7 @@ static int uvd_v7_0_set_powergating_state(void *handle, | |||
1616 | if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD)) | 1672 | if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD)) |
1617 | return 0; | 1673 | return 0; |
1618 | 1674 | ||
1619 | WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, UVD_POWER_STATUS__UVD_PG_EN_MASK); | 1675 | WREG32_SOC15(UVD, ring->me, mmUVD_POWER_STATUS, UVD_POWER_STATUS__UVD_PG_EN_MASK); |
1620 | 1676 | ||
1621 | if (state == AMD_PG_STATE_GATE) { | 1677 | if (state == AMD_PG_STATE_GATE) { |
1622 | uvd_v7_0_stop(adev); | 1678 | uvd_v7_0_stop(adev); |
@@ -1657,7 +1713,6 @@ const struct amd_ip_funcs uvd_v7_0_ip_funcs = { | |||
1657 | static const struct amdgpu_ring_funcs uvd_v7_0_ring_vm_funcs = { | 1713 | static const struct amdgpu_ring_funcs uvd_v7_0_ring_vm_funcs = { |
1658 | .type = AMDGPU_RING_TYPE_UVD, | 1714 | .type = AMDGPU_RING_TYPE_UVD, |
1659 | .align_mask = 0xf, | 1715 | .align_mask = 0xf, |
1660 | .nop = PACKET0(0x81ff, 0), | ||
1661 | .support_64bit_ptrs = false, | 1716 | .support_64bit_ptrs = false, |
1662 | .vmhub = AMDGPU_MMHUB, | 1717 | .vmhub = AMDGPU_MMHUB, |
1663 | .get_rptr = uvd_v7_0_ring_get_rptr, | 1718 | .get_rptr = uvd_v7_0_ring_get_rptr, |
@@ -1719,18 +1774,27 @@ static const struct amdgpu_ring_funcs uvd_v7_0_enc_ring_vm_funcs = { | |||
1719 | 1774 | ||
1720 | static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev) | 1775 | static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev) |
1721 | { | 1776 | { |
1722 | adev->uvd.ring.funcs = &uvd_v7_0_ring_vm_funcs; | 1777 | int i; |
1723 | DRM_INFO("UVD is enabled in VM mode\n"); | 1778 | |
1779 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { | ||
1780 | adev->uvd.inst[i].ring.funcs = &uvd_v7_0_ring_vm_funcs; | ||
1781 | adev->uvd.inst[i].ring.me = i; | ||
1782 | DRM_INFO("UVD(%d) is enabled in VM mode\n", i); | ||
1783 | } | ||
1724 | } | 1784 | } |
1725 | 1785 | ||
1726 | static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev) | 1786 | static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev) |
1727 | { | 1787 | { |
1728 | int i; | 1788 | int i, j; |
1729 | 1789 | ||
1730 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) | 1790 | for (j = 0; j < adev->uvd.num_uvd_inst; j++) { |
1731 | adev->uvd.ring_enc[i].funcs = &uvd_v7_0_enc_ring_vm_funcs; | 1791 | for (i = 0; i < adev->uvd.num_enc_rings; ++i) { |
1792 | adev->uvd.inst[j].ring_enc[i].funcs = &uvd_v7_0_enc_ring_vm_funcs; | ||
1793 | adev->uvd.inst[j].ring_enc[i].me = j; | ||
1794 | } | ||
1732 | 1795 | ||
1733 | DRM_INFO("UVD ENC is enabled in VM mode\n"); | 1796 | DRM_INFO("UVD(%d) ENC is enabled in VM mode\n", j); |
1797 | } | ||
1734 | } | 1798 | } |
1735 | 1799 | ||
1736 | static const struct amdgpu_irq_src_funcs uvd_v7_0_irq_funcs = { | 1800 | static const struct amdgpu_irq_src_funcs uvd_v7_0_irq_funcs = { |
@@ -1740,8 +1804,12 @@ static const struct amdgpu_irq_src_funcs uvd_v7_0_irq_funcs = { | |||
1740 | 1804 | ||
1741 | static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev) | 1805 | static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev) |
1742 | { | 1806 | { |
1743 | adev->uvd.irq.num_types = adev->uvd.num_enc_rings + 1; | 1807 | int i; |
1744 | adev->uvd.irq.funcs = &uvd_v7_0_irq_funcs; | 1808 | |
1809 | for (i = 0; i < adev->uvd.num_uvd_inst; i++) { | ||
1810 | adev->uvd.inst[i].irq.num_types = adev->uvd.num_enc_rings + 1; | ||
1811 | adev->uvd.inst[i].irq.funcs = &uvd_v7_0_irq_funcs; | ||
1812 | } | ||
1745 | } | 1813 | } |
1746 | 1814 | ||
1747 | const struct amdgpu_ip_block_version uvd_v7_0_ip_block = | 1815 | const struct amdgpu_ip_block_version uvd_v7_0_ip_block = |
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 0501746b6c2c..110b294ebed3 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include "mmhub/mmhub_9_1_offset.h" | 35 | #include "mmhub/mmhub_9_1_offset.h" |
36 | #include "mmhub/mmhub_9_1_sh_mask.h" | 36 | #include "mmhub/mmhub_9_1_sh_mask.h" |
37 | 37 | ||
38 | static int vcn_v1_0_start(struct amdgpu_device *adev); | ||
39 | static int vcn_v1_0_stop(struct amdgpu_device *adev); | 38 | static int vcn_v1_0_stop(struct amdgpu_device *adev); |
40 | static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); | 39 | static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); |
41 | static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev); | 40 | static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev); |
@@ -146,10 +145,6 @@ static int vcn_v1_0_hw_init(void *handle) | |||
146 | struct amdgpu_ring *ring = &adev->vcn.ring_dec; | 145 | struct amdgpu_ring *ring = &adev->vcn.ring_dec; |
147 | int i, r; | 146 | int i, r; |
148 | 147 | ||
149 | r = vcn_v1_0_start(adev); | ||
150 | if (r) | ||
151 | goto done; | ||
152 | |||
153 | ring->ready = true; | 148 | ring->ready = true; |
154 | r = amdgpu_ring_test_ring(ring); | 149 | r = amdgpu_ring_test_ring(ring); |
155 | if (r) { | 150 | if (r) { |
@@ -185,11 +180,9 @@ static int vcn_v1_0_hw_fini(void *handle) | |||
185 | { | 180 | { |
186 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 181 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
187 | struct amdgpu_ring *ring = &adev->vcn.ring_dec; | 182 | struct amdgpu_ring *ring = &adev->vcn.ring_dec; |
188 | int r; | ||
189 | 183 | ||
190 | r = vcn_v1_0_stop(adev); | 184 | if (RREG32_SOC15(VCN, 0, mmUVD_STATUS)) |
191 | if (r) | 185 | vcn_v1_0_stop(adev); |
192 | return r; | ||
193 | 186 | ||
194 | ring->ready = false; | 187 | ring->ready = false; |
195 | 188 | ||
@@ -288,14 +281,14 @@ static void vcn_v1_0_mc_resume(struct amdgpu_device *adev) | |||
288 | * | 281 | * |
289 | * Disable clock gating for VCN block | 282 | * Disable clock gating for VCN block |
290 | */ | 283 | */ |
291 | static void vcn_v1_0_disable_clock_gating(struct amdgpu_device *adev, bool sw) | 284 | static void vcn_v1_0_disable_clock_gating(struct amdgpu_device *adev) |
292 | { | 285 | { |
293 | uint32_t data; | 286 | uint32_t data; |
294 | 287 | ||
295 | /* JPEG disable CGC */ | 288 | /* JPEG disable CGC */ |
296 | data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL); | 289 | data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL); |
297 | 290 | ||
298 | if (sw) | 291 | if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) |
299 | data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; | 292 | data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; |
300 | else | 293 | else |
301 | data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE_MASK; | 294 | data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE_MASK; |
@@ -310,7 +303,7 @@ static void vcn_v1_0_disable_clock_gating(struct amdgpu_device *adev, bool sw) | |||
310 | 303 | ||
311 | /* UVD disable CGC */ | 304 | /* UVD disable CGC */ |
312 | data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL); | 305 | data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL); |
313 | if (sw) | 306 | if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) |
314 | data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; | 307 | data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; |
315 | else | 308 | else |
316 | data &= ~ UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; | 309 | data &= ~ UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; |
@@ -415,13 +408,13 @@ static void vcn_v1_0_disable_clock_gating(struct amdgpu_device *adev, bool sw) | |||
415 | * | 408 | * |
416 | * Enable clock gating for VCN block | 409 | * Enable clock gating for VCN block |
417 | */ | 410 | */ |
418 | static void vcn_v1_0_enable_clock_gating(struct amdgpu_device *adev, bool sw) | 411 | static void vcn_v1_0_enable_clock_gating(struct amdgpu_device *adev) |
419 | { | 412 | { |
420 | uint32_t data = 0; | 413 | uint32_t data = 0; |
421 | 414 | ||
422 | /* enable JPEG CGC */ | 415 | /* enable JPEG CGC */ |
423 | data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL); | 416 | data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL); |
424 | if (sw) | 417 | if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) |
425 | data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; | 418 | data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; |
426 | else | 419 | else |
427 | data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; | 420 | data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; |
@@ -435,7 +428,7 @@ static void vcn_v1_0_enable_clock_gating(struct amdgpu_device *adev, bool sw) | |||
435 | 428 | ||
436 | /* enable UVD CGC */ | 429 | /* enable UVD CGC */ |
437 | data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL); | 430 | data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL); |
438 | if (sw) | 431 | if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG) |
439 | data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; | 432 | data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; |
440 | else | 433 | else |
441 | data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; | 434 | data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; |
@@ -480,6 +473,94 @@ static void vcn_v1_0_enable_clock_gating(struct amdgpu_device *adev, bool sw) | |||
480 | WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL, data); | 473 | WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL, data); |
481 | } | 474 | } |
482 | 475 | ||
476 | static void vcn_1_0_disable_static_power_gating(struct amdgpu_device *adev) | ||
477 | { | ||
478 | uint32_t data = 0; | ||
479 | int ret; | ||
480 | |||
481 | if (adev->pg_flags & AMD_PG_SUPPORT_VCN) { | ||
482 | data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT | ||
483 | | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT | ||
484 | | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT | ||
485 | | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT | ||
486 | | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT | ||
487 | | 2 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT | ||
488 | | 2 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT | ||
489 | | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT | ||
490 | | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT | ||
491 | | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT | ||
492 | | 2 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT); | ||
493 | |||
494 | WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data); | ||
495 | SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON, 0xFFFFFF, ret); | ||
496 | } else { | ||
497 | data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT | ||
498 | | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT | ||
499 | | 1 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT | ||
500 | | 1 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT | ||
501 | | 1 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT | ||
502 | | 1 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT | ||
503 | | 1 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT | ||
504 | | 1 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT | ||
505 | | 1 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT | ||
506 | | 1 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT | ||
507 | | 1 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT); | ||
508 | WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data); | ||
509 | SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, 0, 0xFFFFFFFF, ret); | ||
510 | } | ||
511 | |||
512 | /* polling UVD_PGFSM_STATUS to confirm UVDM_PWR_STATUS , UVDU_PWR_STATUS are 0 (power on) */ | ||
513 | |||
514 | data = RREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS); | ||
515 | data &= ~0x103; | ||
516 | if (adev->pg_flags & AMD_PG_SUPPORT_VCN) | ||
517 | data |= UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON | UVD_POWER_STATUS__UVD_PG_EN_MASK; | ||
518 | |||
519 | WREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS, data); | ||
520 | } | ||
521 | |||
522 | static void vcn_1_0_enable_static_power_gating(struct amdgpu_device *adev) | ||
523 | { | ||
524 | uint32_t data = 0; | ||
525 | int ret; | ||
526 | |||
527 | if (adev->pg_flags & AMD_PG_SUPPORT_VCN) { | ||
528 | /* Before power off, this indicator has to be turned on */ | ||
529 | data = RREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS); | ||
530 | data &= ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK; | ||
531 | data |= UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF; | ||
532 | WREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS, data); | ||
533 | |||
534 | |||
535 | data = (2 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT | ||
536 | | 2 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT | ||
537 | | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT | ||
538 | | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT | ||
539 | | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT | ||
540 | | 2 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT | ||
541 | | 2 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT | ||
542 | | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT | ||
543 | | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT | ||
544 | | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT | ||
545 | | 2 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT); | ||
546 | |||
547 | WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data); | ||
548 | |||
549 | data = (2 << UVD_PGFSM_STATUS__UVDM_PWR_STATUS__SHIFT | ||
550 | | 2 << UVD_PGFSM_STATUS__UVDU_PWR_STATUS__SHIFT | ||
551 | | 2 << UVD_PGFSM_STATUS__UVDF_PWR_STATUS__SHIFT | ||
552 | | 2 << UVD_PGFSM_STATUS__UVDC_PWR_STATUS__SHIFT | ||
553 | | 2 << UVD_PGFSM_STATUS__UVDB_PWR_STATUS__SHIFT | ||
554 | | 2 << UVD_PGFSM_STATUS__UVDIL_PWR_STATUS__SHIFT | ||
555 | | 2 << UVD_PGFSM_STATUS__UVDIR_PWR_STATUS__SHIFT | ||
556 | | 2 << UVD_PGFSM_STATUS__UVDTD_PWR_STATUS__SHIFT | ||
557 | | 2 << UVD_PGFSM_STATUS__UVDTE_PWR_STATUS__SHIFT | ||
558 | | 2 << UVD_PGFSM_STATUS__UVDE_PWR_STATUS__SHIFT | ||
559 | | 2 << UVD_PGFSM_STATUS__UVDW_PWR_STATUS__SHIFT); | ||
560 | SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, data, 0xFFFFFFFF, ret); | ||
561 | } | ||
562 | } | ||
563 | |||
483 | /** | 564 | /** |
484 | * vcn_v1_0_start - start VCN block | 565 | * vcn_v1_0_start - start VCN block |
485 | * | 566 | * |
@@ -499,8 +580,9 @@ static int vcn_v1_0_start(struct amdgpu_device *adev) | |||
499 | 580 | ||
500 | vcn_v1_0_mc_resume(adev); | 581 | vcn_v1_0_mc_resume(adev); |
501 | 582 | ||
583 | vcn_1_0_disable_static_power_gating(adev); | ||
502 | /* disable clock gating */ | 584 | /* disable clock gating */ |
503 | vcn_v1_0_disable_clock_gating(adev, true); | 585 | vcn_v1_0_disable_clock_gating(adev); |
504 | 586 | ||
505 | /* disable interupt */ | 587 | /* disable interupt */ |
506 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0, | 588 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0, |
@@ -680,16 +762,45 @@ static int vcn_v1_0_stop(struct amdgpu_device *adev) | |||
680 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0, | 762 | WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0, |
681 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); | 763 | ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK); |
682 | 764 | ||
683 | /* enable clock gating */ | 765 | WREG32_SOC15(VCN, 0, mmUVD_STATUS, 0); |
684 | vcn_v1_0_enable_clock_gating(adev, true); | ||
685 | 766 | ||
767 | vcn_v1_0_enable_clock_gating(adev); | ||
768 | vcn_1_0_enable_static_power_gating(adev); | ||
686 | return 0; | 769 | return 0; |
687 | } | 770 | } |
688 | 771 | ||
772 | bool vcn_v1_0_is_idle(void *handle) | ||
773 | { | ||
774 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
775 | |||
776 | return (RREG32_SOC15(VCN, 0, mmUVD_STATUS) == 0x2); | ||
777 | } | ||
778 | |||
779 | int vcn_v1_0_wait_for_idle(void *handle) | ||
780 | { | ||
781 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
782 | int ret = 0; | ||
783 | |||
784 | SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_STATUS, 0x2, 0x2, ret); | ||
785 | |||
786 | return ret; | ||
787 | } | ||
788 | |||
689 | static int vcn_v1_0_set_clockgating_state(void *handle, | 789 | static int vcn_v1_0_set_clockgating_state(void *handle, |
690 | enum amd_clockgating_state state) | 790 | enum amd_clockgating_state state) |
691 | { | 791 | { |
692 | /* needed for driver unload*/ | 792 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
793 | bool enable = (state == AMD_CG_STATE_GATE) ? true : false; | ||
794 | |||
795 | if (enable) { | ||
796 | /* wait for STATUS to clear */ | ||
797 | if (vcn_v1_0_is_idle(handle)) | ||
798 | return -EBUSY; | ||
799 | vcn_v1_0_enable_clock_gating(adev); | ||
800 | } else { | ||
801 | /* disable HW gating and enable Sw gating */ | ||
802 | vcn_v1_0_disable_clock_gating(adev); | ||
803 | } | ||
693 | return 0; | 804 | return 0; |
694 | } | 805 | } |
695 | 806 | ||
@@ -1048,16 +1159,36 @@ static int vcn_v1_0_process_interrupt(struct amdgpu_device *adev, | |||
1048 | return 0; | 1159 | return 0; |
1049 | } | 1160 | } |
1050 | 1161 | ||
1051 | static void vcn_v1_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | 1162 | static void vcn_v1_0_dec_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) |
1052 | { | 1163 | { |
1053 | int i; | ||
1054 | struct amdgpu_device *adev = ring->adev; | 1164 | struct amdgpu_device *adev = ring->adev; |
1165 | int i; | ||
1055 | 1166 | ||
1056 | for (i = 0; i < count; i++) | 1167 | WARN_ON(ring->wptr % 2 || count % 2); |
1057 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP), 0)); | ||
1058 | 1168 | ||
1169 | for (i = 0; i < count / 2; i++) { | ||
1170 | amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP), 0)); | ||
1171 | amdgpu_ring_write(ring, 0); | ||
1172 | } | ||
1059 | } | 1173 | } |
1060 | 1174 | ||
1175 | static int vcn_v1_0_set_powergating_state(void *handle, | ||
1176 | enum amd_powergating_state state) | ||
1177 | { | ||
1178 | /* This doesn't actually powergate the VCN block. | ||
1179 | * That's done in the dpm code via the SMC. This | ||
1180 | * just re-inits the block as necessary. The actual | ||
1181 | * gating still happens in the dpm code. We should | ||
1182 | * revisit this when there is a cleaner line between | ||
1183 | * the smc and the hw blocks | ||
1184 | */ | ||
1185 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
1186 | |||
1187 | if (state == AMD_PG_STATE_GATE) | ||
1188 | return vcn_v1_0_stop(adev); | ||
1189 | else | ||
1190 | return vcn_v1_0_start(adev); | ||
1191 | } | ||
1061 | 1192 | ||
1062 | static const struct amd_ip_funcs vcn_v1_0_ip_funcs = { | 1193 | static const struct amd_ip_funcs vcn_v1_0_ip_funcs = { |
1063 | .name = "vcn_v1_0", | 1194 | .name = "vcn_v1_0", |
@@ -1069,20 +1200,19 @@ static const struct amd_ip_funcs vcn_v1_0_ip_funcs = { | |||
1069 | .hw_fini = vcn_v1_0_hw_fini, | 1200 | .hw_fini = vcn_v1_0_hw_fini, |
1070 | .suspend = vcn_v1_0_suspend, | 1201 | .suspend = vcn_v1_0_suspend, |
1071 | .resume = vcn_v1_0_resume, | 1202 | .resume = vcn_v1_0_resume, |
1072 | .is_idle = NULL /* vcn_v1_0_is_idle */, | 1203 | .is_idle = vcn_v1_0_is_idle, |
1073 | .wait_for_idle = NULL /* vcn_v1_0_wait_for_idle */, | 1204 | .wait_for_idle = vcn_v1_0_wait_for_idle, |
1074 | .check_soft_reset = NULL /* vcn_v1_0_check_soft_reset */, | 1205 | .check_soft_reset = NULL /* vcn_v1_0_check_soft_reset */, |
1075 | .pre_soft_reset = NULL /* vcn_v1_0_pre_soft_reset */, | 1206 | .pre_soft_reset = NULL /* vcn_v1_0_pre_soft_reset */, |
1076 | .soft_reset = NULL /* vcn_v1_0_soft_reset */, | 1207 | .soft_reset = NULL /* vcn_v1_0_soft_reset */, |
1077 | .post_soft_reset = NULL /* vcn_v1_0_post_soft_reset */, | 1208 | .post_soft_reset = NULL /* vcn_v1_0_post_soft_reset */, |
1078 | .set_clockgating_state = vcn_v1_0_set_clockgating_state, | 1209 | .set_clockgating_state = vcn_v1_0_set_clockgating_state, |
1079 | .set_powergating_state = NULL /* vcn_v1_0_set_powergating_state */, | 1210 | .set_powergating_state = vcn_v1_0_set_powergating_state, |
1080 | }; | 1211 | }; |
1081 | 1212 | ||
1082 | static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = { | 1213 | static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = { |
1083 | .type = AMDGPU_RING_TYPE_VCN_DEC, | 1214 | .type = AMDGPU_RING_TYPE_VCN_DEC, |
1084 | .align_mask = 0xf, | 1215 | .align_mask = 0xf, |
1085 | .nop = PACKET0(0x81ff, 0), | ||
1086 | .support_64bit_ptrs = false, | 1216 | .support_64bit_ptrs = false, |
1087 | .vmhub = AMDGPU_MMHUB, | 1217 | .vmhub = AMDGPU_MMHUB, |
1088 | .get_rptr = vcn_v1_0_dec_ring_get_rptr, | 1218 | .get_rptr = vcn_v1_0_dec_ring_get_rptr, |
@@ -1101,7 +1231,7 @@ static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = { | |||
1101 | .emit_vm_flush = vcn_v1_0_dec_ring_emit_vm_flush, | 1231 | .emit_vm_flush = vcn_v1_0_dec_ring_emit_vm_flush, |
1102 | .test_ring = amdgpu_vcn_dec_ring_test_ring, | 1232 | .test_ring = amdgpu_vcn_dec_ring_test_ring, |
1103 | .test_ib = amdgpu_vcn_dec_ring_test_ib, | 1233 | .test_ib = amdgpu_vcn_dec_ring_test_ib, |
1104 | .insert_nop = vcn_v1_0_ring_insert_nop, | 1234 | .insert_nop = vcn_v1_0_dec_ring_insert_nop, |
1105 | .insert_start = vcn_v1_0_dec_ring_insert_start, | 1235 | .insert_start = vcn_v1_0_dec_ring_insert_start, |
1106 | .insert_end = vcn_v1_0_dec_ring_insert_end, | 1236 | .insert_end = vcn_v1_0_dec_ring_insert_end, |
1107 | .pad_ib = amdgpu_ring_generic_pad_ib, | 1237 | .pad_ib = amdgpu_ring_generic_pad_ib, |
diff --git a/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c b/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c new file mode 100644 index 000000000000..52778de93ab0 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Copyright 2018 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | #include "amdgpu.h" | ||
24 | #include "soc15.h" | ||
25 | |||
26 | #include "soc15_common.h" | ||
27 | #include "soc15_hw_ip.h" | ||
28 | #include "vega20_ip_offset.h" | ||
29 | |||
30 | int vega20_reg_base_init(struct amdgpu_device *adev) | ||
31 | { | ||
32 | /* HW has more IP blocks, only initialized the blocke beend by our driver */ | ||
33 | uint32_t i; | ||
34 | for (i = 0 ; i < MAX_INSTANCE ; ++i) { | ||
35 | adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i])); | ||
36 | adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i])); | ||
37 | adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i])); | ||
38 | adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i])); | ||
39 | adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i])); | ||
40 | adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i])); | ||
41 | adev->reg_offset[UVD_HWIP][i] = (uint32_t *)(&(UVD_BASE.instance[i])); | ||
42 | adev->reg_offset[VCE_HWIP][i] = (uint32_t *)(&(VCE_BASE.instance[i])); | ||
43 | adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i])); | ||
44 | adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DCE_BASE.instance[i])); | ||
45 | adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i])); | ||
46 | adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(SDMA0_BASE.instance[i])); | ||
47 | adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(SDMA1_BASE.instance[i])); | ||
48 | adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i])); | ||
49 | } | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | |||