diff options
| author | Dave Airlie <airlied@redhat.com> | 2026-04-02 13:00:58 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2026-04-02 13:17:38 +1000 |
| commit | cdd65e8bb9540b67d164cec760614ff74c560c49 (patch) | |
| tree | d967c380d801fee53019763906b353380fda5959 /drivers/gpu/drm/amd/amdgpu | |
| parent | 9bdbf7eb25b3121ef19533df4fb70f2c39fc0d6a (diff) | |
| parent | 8b3e8fa6d7bdab292447a43f70532db437d5d4f5 (diff) | |
Merge tag 'amd-drm-next-7.1-2026-04-01' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-7.1-2026-04-01:
amdgpu:
- UserQ fixes
- PASID handling fix
- S4 fix for smu11 chips
- devcoredump fixes
- RAS fixes
- Misc small fixes
- DCN 4.2 updates
- DVI fixes
- DML fixes
- DC pipe validation fixes
- eDP DSC seamless boot
- DC FP rework
- swsmu cleanups
- GC 11.5.4 updates
- Add DC idle state manager
- Add support for using multiple engines for buffer fills and clears
- Misc SMU7 fixes
amdkfd:
- Non-4K page fixes
- Logging cleanups
- sysfs fixes
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patch.msgid.link/20260401184456.3576660-1-alexander.deucher@amd.com
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
28 files changed, 555 insertions, 323 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c index 7f4751e5caaf..cd9aa5b45e94 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c @@ -373,249 +373,280 @@ int amdgpu_atomfirmware_get_uma_carveout_info(struct amdgpu_device *adev, return -ENODEV; } -int -amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, +int amdgpu_atomfirmware_get_integrated_system_info(struct amdgpu_device *adev, int *vram_width, int *vram_type, int *vram_vendor) { struct amdgpu_mode_info *mode_info = &adev->mode_info; - int index, i = 0; + int index; u16 data_offset, size; union igp_info *igp_info; - union vram_info *vram_info; - union umc_info *umc_info; - union vram_module *vram_module; u8 frev, crev; u8 mem_type; - u8 mem_vendor; u32 mem_channel_number; u32 mem_channel_width; - u32 module_id; - if (adev->flags & AMD_IS_APU) - index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, + index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, integratedsysteminfo); - else { - switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { - case IP_VERSION(12, 0, 0): - case IP_VERSION(12, 0, 1): - index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, umc_info); + if (amdgpu_atom_parse_data_header(mode_info->atom_context, + index, &size, + &frev, &crev, &data_offset)) { + igp_info = (union igp_info *) + (mode_info->atom_context->bios + data_offset); + switch (frev) { + case 1: + switch (crev) { + case 11: + case 12: + mem_channel_number = igp_info->v11.umachannelnumber; + if (!mem_channel_number) + mem_channel_number = 1; + mem_type = igp_info->v11.memorytype; + if (mem_type == LpDdr5MemType) + mem_channel_width = 32; + else + mem_channel_width = 64; + if (vram_width) + *vram_width = mem_channel_number * mem_channel_width; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + break; + default: + return -EINVAL; + } + break; + case 2: + switch (crev) { + case 1: + case 2: + mem_channel_number = igp_info->v21.umachannelnumber; + if (!mem_channel_number) + mem_channel_number = 1; + mem_type = igp_info->v21.memorytype; + if (mem_type == LpDdr5MemType) + mem_channel_width = 32; + else + mem_channel_width = 64; + if (vram_width) + *vram_width = mem_channel_number * mem_channel_width; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + break; + case 3: + mem_channel_number = igp_info->v23.umachannelnumber; + if (!mem_channel_number) + mem_channel_number = 1; + mem_type = igp_info->v23.memorytype; + if (mem_type == LpDdr5MemType) + mem_channel_width = 32; + else + mem_channel_width = 64; + if (vram_width) + *vram_width = mem_channel_number * mem_channel_width; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + break; + default: + return -EINVAL; + } break; default: - index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, vram_info); + return -EINVAL; } + } else { + return -EINVAL; } + return 0; +} + +int amdgpu_atomfirmware_get_umc_info(struct amdgpu_device *adev, + int *vram_width, int *vram_type, + int *vram_vendor) +{ + struct amdgpu_mode_info *mode_info = &adev->mode_info; + int index; + u16 data_offset, size; + union umc_info *umc_info; + u8 frev, crev; + u8 mem_type; + u8 mem_vendor; + u32 mem_channel_number; + u32 mem_channel_width; + + index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, umc_info); + if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, &size, &frev, &crev, &data_offset)) { - if (adev->flags & AMD_IS_APU) { - igp_info = (union igp_info *) - (mode_info->atom_context->bios + data_offset); - switch (frev) { - case 1: - switch (crev) { - case 11: - case 12: - mem_channel_number = igp_info->v11.umachannelnumber; - if (!mem_channel_number) - mem_channel_number = 1; - mem_type = igp_info->v11.memorytype; - if (mem_type == LpDdr5MemType) - mem_channel_width = 32; - else - mem_channel_width = 64; - if (vram_width) - *vram_width = mem_channel_number * mem_channel_width; - if (vram_type) - *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); - break; - default: - return -EINVAL; - } - break; - case 2: - switch (crev) { - case 1: - case 2: - mem_channel_number = igp_info->v21.umachannelnumber; - if (!mem_channel_number) - mem_channel_number = 1; - mem_type = igp_info->v21.memorytype; - if (mem_type == LpDdr5MemType) - mem_channel_width = 32; - else - mem_channel_width = 64; - if (vram_width) - *vram_width = mem_channel_number * mem_channel_width; - if (vram_type) - *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); - break; - case 3: - mem_channel_number = igp_info->v23.umachannelnumber; - if (!mem_channel_number) - mem_channel_number = 1; - mem_type = igp_info->v23.memorytype; - if (mem_type == LpDdr5MemType) - mem_channel_width = 32; - else - mem_channel_width = 64; - if (vram_width) - *vram_width = mem_channel_number * mem_channel_width; - if (vram_type) - *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); - break; - default: - return -EINVAL; - } + umc_info = (union umc_info *)(mode_info->atom_context->bios + data_offset); + + if (frev == 4) { + switch (crev) { + case 0: + mem_channel_number = le32_to_cpu(umc_info->v40.channel_num); + mem_type = le32_to_cpu(umc_info->v40.vram_type); + mem_channel_width = le32_to_cpu(umc_info->v40.channel_width); + mem_vendor = RREG32(adev->bios_scratch_reg_offset + 4) & 0xF; + if (vram_vendor) + *vram_vendor = mem_vendor; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + if (vram_width) + *vram_width = mem_channel_number * (1 << mem_channel_width); break; default: return -EINVAL; } } else { - switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { - case IP_VERSION(12, 0, 0): - case IP_VERSION(12, 0, 1): - umc_info = (union umc_info *)(mode_info->atom_context->bios + data_offset); - - if (frev == 4) { - switch (crev) { - case 0: - mem_channel_number = le32_to_cpu(umc_info->v40.channel_num); - mem_type = le32_to_cpu(umc_info->v40.vram_type); - mem_channel_width = le32_to_cpu(umc_info->v40.channel_width); - mem_vendor = RREG32(adev->bios_scratch_reg_offset + 4) & 0xF; - if (vram_vendor) - *vram_vendor = mem_vendor; - if (vram_type) - *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); - if (vram_width) - *vram_width = mem_channel_number * (1 << mem_channel_width); - break; - default: - return -EINVAL; - } - } else - return -EINVAL; + return -EINVAL; + } + } else { + return -EINVAL; + } + + return 0; +} + +int amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, + int *vram_width, int *vram_type, + int *vram_vendor) +{ + struct amdgpu_mode_info *mode_info = &adev->mode_info; + int index, i = 0; + u16 data_offset, size; + union vram_info *vram_info; + union vram_module *vram_module; + u8 frev, crev; + u8 mem_type; + u8 mem_vendor; + u32 mem_channel_number; + u32 mem_channel_width; + u32 module_id; + + index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, vram_info); + + if (amdgpu_atom_parse_data_header(mode_info->atom_context, + index, &size, + &frev, &crev, &data_offset)) { + vram_info = (union vram_info *) + (mode_info->atom_context->bios + data_offset); + + module_id = (RREG32(adev->bios_scratch_reg_offset + 4) & 0x00ff0000) >> 16; + if (frev == 3) { + switch (crev) { + /* v30 */ + case 0: + vram_module = (union vram_module *)vram_info->v30.vram_module; + mem_vendor = (vram_module->v30.dram_vendor_id) & 0xF; + if (vram_vendor) + *vram_vendor = mem_vendor; + mem_type = vram_info->v30.memory_type; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + mem_channel_number = vram_info->v30.channel_num; + mem_channel_width = vram_info->v30.channel_width; + if (vram_width) + *vram_width = mem_channel_number * 16; break; default: - vram_info = (union vram_info *) - (mode_info->atom_context->bios + data_offset); - - module_id = (RREG32(adev->bios_scratch_reg_offset + 4) & 0x00ff0000) >> 16; - if (frev == 3) { - switch (crev) { - /* v30 */ - case 0: - vram_module = (union vram_module *)vram_info->v30.vram_module; - mem_vendor = (vram_module->v30.dram_vendor_id) & 0xF; - if (vram_vendor) - *vram_vendor = mem_vendor; - mem_type = vram_info->v30.memory_type; - if (vram_type) - *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); - mem_channel_number = vram_info->v30.channel_num; - mem_channel_width = vram_info->v30.channel_width; - if (vram_width) - *vram_width = mem_channel_number * 16; - break; - default: - return -EINVAL; - } - } else if (frev == 2) { - switch (crev) { - /* v23 */ - case 3: - if (module_id > vram_info->v23.vram_module_num) - module_id = 0; - vram_module = (union vram_module *)vram_info->v23.vram_module; - while (i < module_id) { - vram_module = (union vram_module *) - ((u8 *)vram_module + vram_module->v9.vram_module_size); - i++; - } - mem_type = vram_module->v9.memory_type; - if (vram_type) - *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); - mem_channel_number = vram_module->v9.channel_num; - mem_channel_width = vram_module->v9.channel_width; - if (vram_width) - *vram_width = mem_channel_number * (1 << mem_channel_width); - mem_vendor = (vram_module->v9.vender_rev_id) & 0xF; - if (vram_vendor) - *vram_vendor = mem_vendor; - break; - /* v24 */ - case 4: - if (module_id > vram_info->v24.vram_module_num) - module_id = 0; - vram_module = (union vram_module *)vram_info->v24.vram_module; - while (i < module_id) { - vram_module = (union vram_module *) - ((u8 *)vram_module + vram_module->v10.vram_module_size); - i++; - } - mem_type = vram_module->v10.memory_type; - if (vram_type) - *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); - mem_channel_number = vram_module->v10.channel_num; - mem_channel_width = vram_module->v10.channel_width; - if (vram_width) - *vram_width = mem_channel_number * (1 << mem_channel_width); - mem_vendor = (vram_module->v10.vender_rev_id) & 0xF; - if (vram_vendor) - *vram_vendor = mem_vendor; - break; - /* v25 */ - case 5: - if (module_id > vram_info->v25.vram_module_num) - module_id = 0; - vram_module = (union vram_module *)vram_info->v25.vram_module; - while (i < module_id) { - vram_module = (union vram_module *) - ((u8 *)vram_module + vram_module->v11.vram_module_size); - i++; - } - mem_type = vram_module->v11.memory_type; - if (vram_type) - *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); - mem_channel_number = vram_module->v11.channel_num; - mem_channel_width = vram_module->v11.channel_width; - if (vram_width) - *vram_width = mem_channel_number * (1 << mem_channel_width); - mem_vendor = (vram_module->v11.vender_rev_id) & 0xF; - if (vram_vendor) - *vram_vendor = mem_vendor; - break; - /* v26 */ - case 6: - if (module_id > vram_info->v26.vram_module_num) - module_id = 0; - vram_module = (union vram_module *)vram_info->v26.vram_module; - while (i < module_id) { - vram_module = (union vram_module *) - ((u8 *)vram_module + vram_module->v9.vram_module_size); - i++; - } - mem_type = vram_module->v9.memory_type; - if (vram_type) - *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); - mem_channel_number = vram_module->v9.channel_num; - mem_channel_width = vram_module->v9.channel_width; - if (vram_width) - *vram_width = mem_channel_number * (1 << mem_channel_width); - mem_vendor = (vram_module->v9.vender_rev_id) & 0xF; - if (vram_vendor) - *vram_vendor = mem_vendor; - break; - default: - return -EINVAL; - } - } else { - /* invalid frev */ - return -EINVAL; + return -EINVAL; + } + } else if (frev == 2) { + switch (crev) { + /* v23 */ + case 3: + if (module_id > vram_info->v23.vram_module_num) + module_id = 0; + vram_module = (union vram_module *)vram_info->v23.vram_module; + while (i < module_id) { + vram_module = (union vram_module *) + ((u8 *)vram_module + vram_module->v9.vram_module_size); + i++; } + mem_type = vram_module->v9.memory_type; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + mem_channel_number = vram_module->v9.channel_num; + mem_channel_width = vram_module->v9.channel_width; + if (vram_width) + *vram_width = mem_channel_number * (1 << mem_channel_width); + mem_vendor = (vram_module->v9.vender_rev_id) & 0xF; + if (vram_vendor) + *vram_vendor = mem_vendor; + break; + /* v24 */ + case 4: + if (module_id > vram_info->v24.vram_module_num) + module_id = 0; + vram_module = (union vram_module *)vram_info->v24.vram_module; + while (i < module_id) { + vram_module = (union vram_module *) + ((u8 *)vram_module + vram_module->v10.vram_module_size); + i++; + } + mem_type = vram_module->v10.memory_type; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + mem_channel_number = vram_module->v10.channel_num; + mem_channel_width = vram_module->v10.channel_width; + if (vram_width) + *vram_width = mem_channel_number * (1 << mem_channel_width); + mem_vendor = (vram_module->v10.vender_rev_id) & 0xF; + if (vram_vendor) + *vram_vendor = mem_vendor; + break; + /* v25 */ + case 5: + if (module_id > vram_info->v25.vram_module_num) + module_id = 0; + vram_module = (union vram_module *)vram_info->v25.vram_module; + while (i < module_id) { + vram_module = (union vram_module *) + ((u8 *)vram_module + vram_module->v11.vram_module_size); + i++; + } + mem_type = vram_module->v11.memory_type; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + mem_channel_number = vram_module->v11.channel_num; + mem_channel_width = vram_module->v11.channel_width; + if (vram_width) + *vram_width = mem_channel_number * (1 << mem_channel_width); + mem_vendor = (vram_module->v11.vender_rev_id) & 0xF; + if (vram_vendor) + *vram_vendor = mem_vendor; + break; + /* v26 */ + case 6: + if (module_id > vram_info->v26.vram_module_num) + module_id = 0; + vram_module = (union vram_module *)vram_info->v26.vram_module; + while (i < module_id) { + vram_module = (union vram_module *) + ((u8 *)vram_module + vram_module->v9.vram_module_size); + i++; + } + mem_type = vram_module->v9.memory_type; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + mem_channel_number = vram_module->v9.channel_num; + mem_channel_width = vram_module->v9.channel_width; + if (vram_width) + *vram_width = mem_channel_number * (1 << mem_channel_width); + mem_vendor = (vram_module->v9.vender_rev_id) & 0xF; + if (vram_vendor) + *vram_vendor = mem_vendor; + break; + default: + return -EINVAL; } + } else { + /* invalid frev */ + return -EINVAL; } + + } else { + return -EINVAL; } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h index 67c8d105729b..0760e4510513 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h @@ -30,6 +30,10 @@ uint32_t amdgpu_atomfirmware_query_firmware_capability(struct amdgpu_device *ade bool amdgpu_atomfirmware_gpu_virtualization_supported(struct amdgpu_device *adev); void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev); int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev); +int amdgpu_atomfirmware_get_integrated_system_info(struct amdgpu_device *adev, + int *vram_width, int *vram_type, int *vram_vendor); +int amdgpu_atomfirmware_get_umc_info(struct amdgpu_device *adev, + int *vram_width, int *vram_type, int *vram_vendor); int amdgpu_atomfirmware_get_vram_info(struct amdgpu_device *adev, int *vram_width, int *vram_type, int *vram_vendor); int amdgpu_atomfirmware_get_uma_carveout_info(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index c048217615c1..b24d5d21be5f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -908,9 +908,8 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, goto out_free_user_pages; amdgpu_bo_list_for_each_entry(e, p->bo_list) { - /* One fence for TTM and one for each CS job */ r = drm_exec_prepare_obj(&p->exec, &e->bo->tbo.base, - 1 + p->gang_size); + TTM_NUM_MOVE_FENCES + p->gang_size); drm_exec_retry_on_contention(&p->exec); if (unlikely(r)) goto out_free_user_pages; @@ -920,7 +919,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, if (p->uf_bo) { r = drm_exec_prepare_obj(&p->exec, &p->uf_bo->tbo.base, - 1 + p->gang_size); + TTM_NUM_MOVE_FENCES + p->gang_size); drm_exec_retry_on_contention(&p->exec); if (unlikely(r)) goto out_free_user_pages; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c index 2b54a67437c2..fddf4e1252bd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c @@ -35,6 +35,9 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check, void amdgpu_coredump_init(struct amdgpu_device *adev) { } +void amdgpu_coredump_fini(struct amdgpu_device *adev) +{ +} #else #define AMDGPU_CORE_DUMP_SIZE_MAX (256 * 1024 * 1024) @@ -192,12 +195,16 @@ static void amdgpu_devcoredump_fw_info(struct amdgpu_device *adev, drm_printf(p, "VPE feature version: %u, fw version: 0x%08x\n", adev->vpe.feature_version, adev->vpe.fw_version); - drm_printf(p, "\nVBIOS Information\n"); - drm_printf(p, "vbios name : %s\n", ctx->name); - drm_printf(p, "vbios pn : %s\n", ctx->vbios_pn); - drm_printf(p, "vbios version : %d\n", ctx->version); - drm_printf(p, "vbios ver_str : %s\n", ctx->vbios_ver_str); - drm_printf(p, "vbios date : %s\n", ctx->date); + if (adev->bios) { + drm_printf(p, "\nVBIOS Information\n"); + drm_printf(p, "vbios name : %s\n", ctx->name); + drm_printf(p, "vbios pn : %s\n", ctx->vbios_pn); + drm_printf(p, "vbios version : %d\n", ctx->version); + drm_printf(p, "vbios ver_str : %s\n", ctx->vbios_ver_str); + drm_printf(p, "vbios date : %s\n", ctx->date); + }else { + drm_printf(p, "\nVBIOS Information: NA\n"); + } } static ssize_t @@ -436,4 +443,10 @@ void amdgpu_coredump_init(struct amdgpu_device *adev) { INIT_WORK(&adev->coredump_work, amdgpu_devcoredump_deferred_work); } + +void amdgpu_coredump_fini(struct amdgpu_device *adev) +{ + /* Finish deferred coredump formatting before HW/IP teardown. */ + flush_work(&adev->coredump_work); +} #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h index b3582d0b4ca4..f8f2f4df129b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h @@ -50,4 +50,5 @@ struct amdgpu_coredump_info { void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check, bool vram_lost, struct amdgpu_job *job); void amdgpu_coredump_init(struct amdgpu_device *adev); +void amdgpu_coredump_fini(struct amdgpu_device *adev); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index a7038f039b10..9c936519bb2b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4225,6 +4225,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) if (pci_dev_is_disconnected(adev->pdev)) amdgpu_amdkfd_device_fini_sw(adev); + amdgpu_coredump_fini(adev); amdgpu_device_ip_fini_early(adev); amdgpu_irq_fini_hw(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index a44baa9ee78d..8ed637f92322 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -2683,8 +2683,12 @@ static int amdgpu_pmops_freeze(struct device *dev) if (r) return r; - if (amdgpu_acpi_should_gpu_reset(adev)) - return amdgpu_asic_reset(adev); + if (amdgpu_acpi_should_gpu_reset(adev)) { + amdgpu_device_lock_reset_domain(adev->reset_domain); + r = amdgpu_asic_reset(adev); + amdgpu_device_unlock_reset_domain(adev->reset_domain); + return r; + } return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index e2d32c29668a..bc772ca3dab7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -404,6 +404,50 @@ void amdgpu_gart_map_vram_range(struct amdgpu_device *adev, uint64_t pa, } /** + * amdgpu_gart_map_gfx9_mqd - map mqd and ctrl_stack dma_addresses into GART entries + * + * @adev: amdgpu_device pointer + * @offset: offset into the GPU's gart aperture + * @pages: number of pages to bind + * @dma_addr: DMA addresses of pages + * @flags: page table entry flags + * + * Map the MQD and control stack addresses into GART entries with the correct + * memory types on gfxv9. The MQD occupies the first 4KB and is followed by + * the control stack. The MQD uses UC (uncached) memory, while the control stack + * uses NC (non-coherent) memory. + */ +void amdgpu_gart_map_gfx9_mqd(struct amdgpu_device *adev, uint64_t offset, + int pages, dma_addr_t *dma_addr, uint64_t flags) +{ + uint64_t page_base; + unsigned int i, j, t; + int idx; + uint64_t ctrl_flags = AMDGPU_PTE_MTYPE_VG10(flags, AMDGPU_MTYPE_NC); + void *dst; + + if (!adev->gart.ptr) + return; + + if (!drm_dev_enter(adev_to_drm(adev), &idx)) + return; + + t = offset / AMDGPU_GPU_PAGE_SIZE; + dst = adev->gart.ptr; + for (i = 0; i < pages; i++) { + page_base = dma_addr[i]; + for (j = 0; j < AMDGPU_GPU_PAGES_IN_CPU_PAGE; j++, t++) { + if ((i == 0) && (j == 0)) + amdgpu_gmc_set_pte_pde(adev, dst, t, page_base, flags); + else + amdgpu_gmc_set_pte_pde(adev, dst, t, page_base, ctrl_flags); + page_base += AMDGPU_GPU_PAGE_SIZE; + } + } + drm_dev_exit(idx); +} + +/** * amdgpu_gart_bind - bind pages into the gart page table * * @adev: amdgpu_device pointer diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h index d3118275ddae..6ebd2da32ea6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h @@ -62,6 +62,8 @@ void amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset, void amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset, int pages, dma_addr_t *dma_addr, uint64_t flags, void *dst); +void amdgpu_gart_map_gfx9_mqd(struct amdgpu_device *adev, uint64_t offset, + int pages, dma_addr_t *dma_addr, uint64_t flags); void amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset, int pages, dma_addr_t *dma_addr, uint64_t flags); void amdgpu_gart_map_vram_range(struct amdgpu_device *adev, uint64_t pa, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 860a4405f7dd..ec74f3971732 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -34,6 +34,7 @@ #include "amdgpu_ras.h" #include "amdgpu_reset.h" #include "amdgpu_xgmi.h" +#include "amdgpu_atomfirmware.h" #include <drm/drm_drv.h> #include <drm/ttm/ttm_tt.h> @@ -1747,3 +1748,31 @@ int amdgpu_gmc_init_mem_ranges(struct amdgpu_device *adev) return 0; } + +int amdgpu_gmc_get_vram_info(struct amdgpu_device *adev, + int *vram_width, int *vram_type, int *vram_vendor) +{ + int ret = 0; + + if (adev->flags & AMD_IS_APU) + return amdgpu_atomfirmware_get_integrated_system_info(adev, + vram_width, vram_type, vram_vendor); + switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { + case IP_VERSION(12, 0, 0): + case IP_VERSION(12, 0, 1): + return amdgpu_atomfirmware_get_umc_info(adev, + vram_width, vram_type, vram_vendor); + case IP_VERSION(9, 5, 0): + case IP_VERSION(9, 4, 4): + case IP_VERSION(9, 4, 3): + ret = amdgpu_atomfirmware_get_umc_info(adev, + vram_width, vram_type, vram_vendor); + if (vram_width && !ret) + *vram_width *= hweight32(adev->aid_mask); + return ret; + default: + return amdgpu_atomfirmware_get_vram_info(adev, + vram_width, vram_type, vram_vendor); + } + return 0; +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h index b9fdc3276e81..32e73e8ba778 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h @@ -482,4 +482,6 @@ amdgpu_gmc_query_memory_partition(struct amdgpu_device *adev); int amdgpu_gmc_init_mem_ranges(struct amdgpu_device *adev); void amdgpu_gmc_init_sw_mem_ranges(struct amdgpu_device *adev, struct amdgpu_mem_partition_info *mem_ranges); +int amdgpu_gmc_get_vram_info(struct amdgpu_device *adev, + int *vram_width, int *vram_type, int *vram_vendor); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c index d88523568b62..569c5a89ff10 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c @@ -68,8 +68,11 @@ int amdgpu_pasid_alloc(unsigned int bits) return -EINVAL; spin_lock(&amdgpu_pasid_idr_lock); + /* TODO: Need to replace the idr with an xarry, and then + * handle the internal locking with ATOMIC safe paths. + */ pasid = idr_alloc_cyclic(&amdgpu_pasid_idr, NULL, 1, - 1U << bits, GFP_KERNEL); + 1U << bits, GFP_ATOMIC); spin_unlock(&amdgpu_pasid_idr_lock); if (pasid >= 0) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 90352284c5ee..51ab1a332615 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -44,6 +44,7 @@ #include <drm/display/drm_dp_mst_helper.h> #include "modules/inc/mod_freesync.h" #include "amdgpu_dm_irq_params.h" +#include "amdgpu_dm_ism.h" struct amdgpu_bo; struct amdgpu_device; @@ -486,6 +487,10 @@ struct amdgpu_crtc { int deferred_flip_completion; /* parameters access from DM IRQ handler */ struct dm_irq_params dm_irq_params; + + /* DM idle state manager */ + struct amdgpu_dm_ism ism; + /* pll sharing */ struct amdgpu_atom_ss ss; bool ss_enabled; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index cc004830a8a2..27f7567df7bf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -1325,7 +1325,8 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo) if (r) goto out; - r = amdgpu_fill_buffer(&adev->mman.clear_entity, abo, 0, &bo->base._resv, + r = amdgpu_fill_buffer(amdgpu_ttm_next_clear_entity(adev), + abo, 0, &bo->base._resv, &fence, AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE); if (WARN_ON(r)) goto out; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c index 44fba4b6aa92..cdf4909592d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c @@ -1558,6 +1558,8 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control) unsigned char buf[RAS_TABLE_HEADER_SIZE] = { 0 }; struct amdgpu_ras_eeprom_table_header *hdr = &control->tbl_hdr; struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); + int dev_var = adev->pdev->device & 0xF; + uint32_t vram_type = adev->gmc.vram_type; int res; if (amdgpu_ras_smu_eeprom_supported(adev)) @@ -1597,6 +1599,12 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control) return amdgpu_ras_eeprom_reset_table(control); } + if (!(adev->flags & AMD_IS_APU) && (dev_var == 0x5) && + (vram_type == AMDGPU_VRAM_TYPE_HBM3E) && + (hdr->version < RAS_TABLE_VER_V3)) { + return amdgpu_ras_eeprom_reset_table(control); + } + switch (hdr->version) { case RAS_TABLE_VER_V2_1: case RAS_TABLE_VER_V3: diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index b4ab309bf08a..afaaab6496de 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -387,9 +387,11 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo, { struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo); + struct amdgpu_ttm_buffer_entity *entity; struct amdgpu_copy_mem src, dst; struct dma_fence *fence = NULL; int r; + u32 e; src.bo = bo; dst.bo = bo; @@ -398,8 +400,12 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo, src.offset = 0; dst.offset = 0; + e = atomic_inc_return(&adev->mman.next_move_entity) % + adev->mman.num_move_entities; + entity = &adev->mman.move_entities[e]; + r = amdgpu_ttm_copy_mem_to_mem(adev, - &adev->mman.move_entity, + entity, &src, &dst, new_mem->size, amdgpu_bo_encrypted(abo), @@ -411,9 +417,7 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo, if (old_mem->mem_type == TTM_PL_VRAM && (abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) { struct dma_fence *wipe_fence = NULL; - - r = amdgpu_fill_buffer(&adev->mman.move_entity, - abo, 0, NULL, &wipe_fence, + r = amdgpu_fill_buffer(entity, abo, 0, NULL, &wipe_fence, AMDGPU_KERNEL_JOB_ID_MOVE_BLIT); if (r) { goto error; @@ -854,25 +858,15 @@ static void amdgpu_ttm_gart_bind_gfx9_mqd(struct amdgpu_device *adev, int num_xcc = max(1U, adev->gfx.num_xcc_per_xcp); uint64_t page_idx, pages_per_xcc; int i; - uint64_t ctrl_flags = AMDGPU_PTE_MTYPE_VG10(flags, AMDGPU_MTYPE_NC); pages_per_xcc = total_pages; do_div(pages_per_xcc, num_xcc); for (i = 0, page_idx = 0; i < num_xcc; i++, page_idx += pages_per_xcc) { - /* MQD page: use default flags */ - amdgpu_gart_bind(adev, + amdgpu_gart_map_gfx9_mqd(adev, gtt->offset + (page_idx << PAGE_SHIFT), - 1, >t->ttm.dma_address[page_idx], flags); - /* - * Ctrl pages - modify the memory type to NC (ctrl_flags) from - * the second page of the BO onward. - */ - amdgpu_gart_bind(adev, - gtt->offset + ((page_idx + 1) << PAGE_SHIFT), - pages_per_xcc - 1, - >t->ttm.dma_address[page_idx + 1], - ctrl_flags); + pages_per_xcc, >t->ttm.dma_address[page_idx], + flags); } } @@ -2345,8 +2339,9 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev) void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable) { struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM); + u32 num_clear_entities, num_move_entities; uint64_t size; - int r; + int r, i, j; if (!adev->mman.initialized || amdgpu_in_reset(adev) || adev->mman.buffer_funcs_enabled == enable || adev->gmc.is_app_apu) @@ -2361,6 +2356,8 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable) return; } + num_clear_entities = 1; + num_move_entities = 1; ring = adev->mman.buffer_funcs_ring; sched = &ring->sched; r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr, @@ -2373,36 +2370,64 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable) return; } - r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr, - &adev->mman.clear_entity, - DRM_SCHED_PRIORITY_NORMAL, - &sched, 1, 1); - if (r < 0) { - dev_err(adev->dev, - "Failed setting up TTM BO clear entity (%d)\n", r); + adev->mman.clear_entities = kcalloc(num_clear_entities, + sizeof(struct amdgpu_ttm_buffer_entity), + GFP_KERNEL); + atomic_set(&adev->mman.next_clear_entity, 0); + if (!adev->mman.clear_entities) goto error_free_default_entity; + + adev->mman.num_clear_entities = num_clear_entities; + + for (i = 0; i < num_clear_entities; i++) { + r = amdgpu_ttm_buffer_entity_init( + &adev->mman.gtt_mgr, &adev->mman.clear_entities[i], + DRM_SCHED_PRIORITY_NORMAL, &sched, 1, 1); + + if (r < 0) { + for (j = 0; j < i; j++) + amdgpu_ttm_buffer_entity_fini( + &adev->mman.gtt_mgr, &adev->mman.clear_entities[j]); + kfree(adev->mman.clear_entities); + adev->mman.num_clear_entities = 0; + adev->mman.clear_entities = NULL; + goto error_free_default_entity; + } } - r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr, - &adev->mman.move_entity, - DRM_SCHED_PRIORITY_NORMAL, - &sched, 1, 2); - if (r < 0) { - dev_err(adev->dev, - "Failed setting up TTM BO move entity (%d)\n", r); - goto error_free_clear_entity; + adev->mman.num_move_entities = num_move_entities; + atomic_set(&adev->mman.next_move_entity, 0); + for (i = 0; i < num_move_entities; i++) { + r = amdgpu_ttm_buffer_entity_init( + &adev->mman.gtt_mgr, + &adev->mman.move_entities[i], + DRM_SCHED_PRIORITY_NORMAL, &sched, 1, 2); + + if (r < 0) { + for (j = 0; j < i; j++) + amdgpu_ttm_buffer_entity_fini( + &adev->mman.gtt_mgr, &adev->mman.move_entities[j]); + adev->mman.num_move_entities = 0; + goto error_free_clear_entities; + } } } else { amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr, &adev->mman.default_entity); - amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr, - &adev->mman.clear_entity); - amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr, - &adev->mman.move_entity); + for (i = 0; i < adev->mman.num_clear_entities; i++) + amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr, + &adev->mman.clear_entities[i]); + for (i = 0; i < adev->mman.num_move_entities; i++) + amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr, + &adev->mman.move_entities[i]); /* Drop all the old fences since re-creating the scheduler entities * will allocate new contexts. */ ttm_resource_manager_cleanup(man); + kfree(adev->mman.clear_entities); + adev->mman.clear_entities = NULL; + adev->mman.num_clear_entities = 0; + adev->mman.num_move_entities = 0; } /* this just adjusts TTM size idea, which sets lpfn to the correct value */ @@ -2415,9 +2440,13 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable) return; -error_free_clear_entity: - amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr, - &adev->mman.clear_entity); +error_free_clear_entities: + for (i = 0; i < adev->mman.num_clear_entities; i++) + amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr, + &adev->mman.clear_entities[i]); + kfree(adev->mman.clear_entities); + adev->mman.clear_entities = NULL; + adev->mman.num_clear_entities = 0; error_free_default_entity: amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr, &adev->mman.default_entity); @@ -2567,8 +2596,7 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo, if (!fence) return -EINVAL; - - entity = &adev->mman.clear_entity; + entity = &adev->mman.clear_entities[0]; *fence = dma_fence_get_stub(); amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor); @@ -2620,11 +2648,8 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity, struct amdgpu_res_cursor dst; int r; - if (!adev->mman.buffer_funcs_enabled) { - dev_err(adev->dev, - "Trying to clear memory with ring turned off.\n"); + if (!entity) return -EINVAL; - } amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &dst); @@ -2660,6 +2685,20 @@ error: return r; } +struct amdgpu_ttm_buffer_entity * +amdgpu_ttm_next_clear_entity(struct amdgpu_device *adev) +{ + struct amdgpu_mman *mman = &adev->mman; + u32 i; + + if (mman->num_clear_entities == 0) + return NULL; + + i = atomic_inc_return(&mman->next_clear_entity) % + mman->num_clear_entities; + return &mman->clear_entities[i]; +} + /** * amdgpu_ttm_evict_resources - evict memory buffers * @adev: amdgpu device object diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h index bf101215757e..3b1973611446 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h @@ -72,8 +72,12 @@ struct amdgpu_mman { /* @default_entity: for workarounds, has no gart windows */ struct amdgpu_ttm_buffer_entity default_entity; - struct amdgpu_ttm_buffer_entity clear_entity; - struct amdgpu_ttm_buffer_entity move_entity; + struct amdgpu_ttm_buffer_entity *clear_entities; + atomic_t next_clear_entity; + u32 num_clear_entities; + struct amdgpu_ttm_buffer_entity move_entities[TTM_NUM_MOVE_FENCES]; + atomic_t next_move_entity; + u32 num_move_entities; struct amdgpu_vram_mgr vram_mgr; struct amdgpu_gtt_mgr gtt_mgr; @@ -191,6 +195,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity, struct dma_resv *resv, struct dma_fence **f, u64 k_job_id); +struct amdgpu_ttm_buffer_entity *amdgpu_ttm_next_clear_entity(struct amdgpu_device *adev); int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo); void amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index 7f64b783954a..366728ed03e3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -600,6 +600,13 @@ amdgpu_userq_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr, goto unpin_bo; } + /* Validate doorbell_offset is within the doorbell BO */ + if ((u64)db_info->doorbell_offset * db_size + db_size > + amdgpu_bo_size(db_obj->obj)) { + r = -EINVAL; + goto unpin_bo; + } + index = amdgpu_doorbell_index_on_bar(uq_mgr->adev, db_obj->obj, db_info->doorbell_offset, db_size); drm_dbg_driver(adev_to_drm(uq_mgr->adev), @@ -997,6 +1004,7 @@ amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr) unsigned long queue_id; int ret = 0, r; + mutex_lock(&uq_mgr->userq_mutex); /* Resume all the queues for this process */ xa_for_each(&uq_mgr->userq_xa, queue_id, queue) { @@ -1012,6 +1020,7 @@ amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr) ret = r; } + mutex_unlock(&uq_mgr->userq_mutex); if (ret) drm_file_err(uq_mgr->file, "Failed to map all the queues\n"); @@ -1215,23 +1224,21 @@ static void amdgpu_userq_restore_worker(struct work_struct *work) struct dma_fence *ev_fence; int ret; - mutex_lock(&uq_mgr->userq_mutex); ev_fence = amdgpu_evf_mgr_get_fence(&fpriv->evf_mgr); if (!dma_fence_is_signaled(ev_fence)) - goto unlock; + goto put_fence; ret = amdgpu_userq_vm_validate(uq_mgr); if (ret) { drm_file_err(uq_mgr->file, "Failed to validate BOs to restore\n"); - goto unlock; + goto put_fence; } ret = amdgpu_userq_restore_all(uq_mgr); if (ret) drm_file_err(uq_mgr->file, "Failed to restore all queues\n"); -unlock: - mutex_unlock(&uq_mgr->userq_mutex); +put_fence: dma_fence_put(ev_fence); } @@ -1454,17 +1461,19 @@ int amdgpu_userq_start_sched_for_enforce_isolation(struct amdgpu_device *adev, if (!adev->userq_halt_for_enforce_isolation) dev_warn(adev->dev, "userq scheduling already started!\n"); + adev->userq_halt_for_enforce_isolation = false; + xa_for_each(&adev->userq_doorbell_xa, queue_id, queue) { uqm = queue->userq_mgr; mutex_lock(&uqm->userq_mutex); - if (((queue->queue_type == AMDGPU_HW_IP_GFX) || - (queue->queue_type == AMDGPU_HW_IP_COMPUTE)) && - (queue->xcp_id == idx)) { + if (((queue->queue_type == AMDGPU_HW_IP_GFX) || + (queue->queue_type == AMDGPU_HW_IP_COMPUTE)) && + (queue->xcp_id == idx)) { r = amdgpu_userq_restore_helper(queue); if (r) ret = r; - } + } mutex_unlock(&uqm->userq_mutex); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c index 5cef8cd14148..e54295b56282 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c @@ -328,11 +328,9 @@ static int amdgpu_vkms_prepare_fb(struct drm_plane *plane, return r; } - r = dma_resv_reserve_fences(rbo->tbo.base.resv, 1); - if (r) { - dev_err(adev->dev, "allocating fence slot failed (%d)\n", r); + r = dma_resv_reserve_fences(rbo->tbo.base.resv, TTM_NUM_MOVE_FENCES); + if (r) goto error_unlock; - } if (plane->type != DRM_PLANE_TYPE_CURSOR) domain = amdgpu_display_supported_domains(adev, rbo->flags); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 641fe91b4f03..3b32f41c3655 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -173,7 +173,7 @@ struct amdgpu_bo_vm; #define AMDGPU_VA_RESERVED_SEQ64_SIZE (2ULL << 20) #define AMDGPU_VA_RESERVED_SEQ64_START(adev) (AMDGPU_VA_RESERVED_CSA_START(adev) \ - AMDGPU_VA_RESERVED_SEQ64_SIZE) -#define AMDGPU_VA_RESERVED_TRAP_SIZE (2ULL << 12) +#define AMDGPU_VA_RESERVED_TRAP_SIZE (1ULL << 16) #define AMDGPU_VA_RESERVED_TRAP_START(adev) (AMDGPU_VA_RESERVED_SEQ64_START(adev) \ - AMDGPU_VA_RESERVED_TRAP_SIZE) #define AMDGPU_VA_RESERVED_BOTTOM (1ULL << 16) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 78d1f3eb522e..ae39b9e1f7d6 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -1722,6 +1722,20 @@ static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block) } } break; + case IP_VERSION(11, 5, 4): + adev->gfx.cleaner_shader_ptr = gfx_11_0_3_cleaner_shader_hex; + adev->gfx.cleaner_shader_size = sizeof(gfx_11_0_3_cleaner_shader_hex); + if (adev->gfx.me_fw_version >= 4 && + adev->gfx.pfp_fw_version >= 7 && + adev->gfx.mec_fw_version >= 5) { + adev->gfx.enable_cleaner_shader = true; + r = amdgpu_gfx_cleaner_shader_sw_init(adev, adev->gfx.cleaner_shader_size); + if (r) { + adev->gfx.enable_cleaner_shader = false; + dev_err(adev->dev, "Failed to initialize cleaner shader\n"); + } + } + break; default: adev->gfx.enable_cleaner_shader = false; break; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c index 2568eeaae945..fd691b2a6e21 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c @@ -767,7 +767,7 @@ static int gmc_v10_0_sw_init(struct amdgpu_ip_block *ip_block) adev->gmc.vram_type = AMDGPU_VRAM_TYPE_GDDR6; adev->gmc.vram_width = 1 * 128; /* numchan * chansize */ } else { - r = amdgpu_atomfirmware_get_vram_info(adev, + r = amdgpu_gmc_get_vram_info(adev, &vram_width, &vram_type, &vram_vendor); adev->gmc.vram_width = vram_width; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c index 6349e239a367..e6db87b94eb1 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c @@ -751,7 +751,7 @@ static int gmc_v11_0_sw_init(struct amdgpu_ip_block *ip_block) spin_lock_init(&adev->gmc.invalidate_lock); - r = amdgpu_atomfirmware_get_vram_info(adev, + r = amdgpu_gmc_get_vram_info(adev, &vram_width, &vram_type, &vram_vendor); adev->gmc.vram_width = vram_width; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c index f1079bd8cf00..6e184ea069ef 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c @@ -825,7 +825,7 @@ static int gmc_v12_0_sw_init(struct amdgpu_ip_block *ip_block) if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(12, 1, 0)) { gmc_v12_1_init_vram_info(adev); } else { - r = amdgpu_atomfirmware_get_vram_info(adev, + r = amdgpu_gmc_get_vram_info(adev, &vram_width, &vram_type, &vram_vendor); adev->gmc.vram_width = vram_width; adev->gmc.vram_type = vram_type; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 1ca0202cfdea..d865059e884a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -1823,24 +1823,37 @@ static void gmc_v9_0_save_registers(struct amdgpu_device *adev) adev->gmc.sdpif_register = RREG32_SOC15(DCE, 0, mmDCHUBBUB_SDPIF_MMIO_CNTRL_0); } -static void gmc_v9_4_3_init_vram_info(struct amdgpu_device *adev) +static void gmc_v9_0_init_vram_info(struct amdgpu_device *adev) { static const u32 regBIF_BIOS_SCRATCH_4 = 0x50; + int dev_var = adev->pdev->device & 0xF; u32 vram_info; - adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM; - adev->gmc.vram_width = 128 * 64; - - if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0)) - adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM3E; - - if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4) && - adev->rev_id == 0x3) - adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM3E; - - if (!(adev->flags & AMD_IS_APU) && !amdgpu_sriov_vf(adev)) { - vram_info = RREG32(regBIF_BIOS_SCRATCH_4); - adev->gmc.vram_vendor = vram_info & 0xF; + if (adev->gmc.is_app_apu) { + adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM; + adev->gmc.vram_width = 128 * 64; + } else if (adev->flags & AMD_IS_APU) { + adev->gmc.vram_type = AMDGPU_VRAM_TYPE_DDR4; + adev->gmc.vram_width = 64 * 64; + } else if (amdgpu_is_multi_aid(adev)) { + adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM; + adev->gmc.vram_width = 128 * 64; + + if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0)) + adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM3E; + + if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4) && + adev->rev_id == 0x3) + adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM3E; + + if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) && + (dev_var == 0x5)) + adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM3E; + + if (!(adev->flags & AMD_IS_APU) && !amdgpu_sriov_vf(adev)) { + vram_info = RREG32(regBIF_BIOS_SCRATCH_4); + adev->gmc.vram_vendor = vram_info & 0xF; + } } } @@ -1856,19 +1869,11 @@ static int gmc_v9_0_sw_init(struct amdgpu_ip_block *ip_block) spin_lock_init(&adev->gmc.invalidate_lock); - if (amdgpu_is_multi_aid(adev)) { - gmc_v9_4_3_init_vram_info(adev); - } else if (!adev->bios) { - if (adev->flags & AMD_IS_APU) { - adev->gmc.vram_type = AMDGPU_VRAM_TYPE_DDR4; - adev->gmc.vram_width = 64 * 64; - } else { - adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM; - adev->gmc.vram_width = 128 * 64; - } + if (!adev->bios) { + gmc_v9_0_init_vram_info(adev); } else { - r = amdgpu_atomfirmware_get_vram_info(adev, - &vram_width, &vram_type, &vram_vendor); + r = amdgpu_gmc_get_vram_info(adev, + &vram_width, &vram_type, &vram_vendor); if (amdgpu_sriov_vf(adev)) /* For Vega10 SR-IOV, vram_width can't be read from ATOM as RAVEN, * and DF related registers is not readable, seems hardcord is the @@ -1896,6 +1901,7 @@ static int gmc_v9_0_sw_init(struct amdgpu_ip_block *ip_block) adev->gmc.vram_type = vram_type; adev->gmc.vram_vendor = vram_vendor; } + switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { case IP_VERSION(9, 1, 0): case IP_VERSION(9, 2, 2): diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c index 8c74894254f7..faac21ee5739 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c @@ -324,8 +324,10 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue, r = amdgpu_userq_input_va_validate(adev, queue, compute_mqd->eop_va, 2048); - if (r) + if (r) { + kfree(compute_mqd); goto free_mqd; + } userq_props->eop_gpu_addr = compute_mqd->eop_va; userq_props->hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_NORMAL; @@ -365,12 +367,16 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue, r = amdgpu_userq_input_va_validate(adev, queue, mqd_gfx_v11->shadow_va, shadow_info.shadow_size); - if (r) + if (r) { + kfree(mqd_gfx_v11); goto free_mqd; + } r = amdgpu_userq_input_va_validate(adev, queue, mqd_gfx_v11->csa_va, shadow_info.csa_size); - if (r) + if (r) { + kfree(mqd_gfx_v11); goto free_mqd; + } kfree(mqd_gfx_v11); } else if (queue->queue_type == AMDGPU_HW_IP_DMA) { @@ -390,8 +396,10 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue, } r = amdgpu_userq_input_va_validate(adev, queue, mqd_sdma_v11->csa_va, 32); - if (r) + if (r) { + kfree(mqd_sdma_v11); goto free_mqd; + } userq_props->csa_addr = mqd_sdma_v11->csa_va; kfree(mqd_sdma_v11); diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index 9aa988982304..fb7aaf5ae05c 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -170,7 +170,8 @@ static int psp_v11_0_wait_for_bootloader(struct psp_context *psp) int retry_loop; /* For a reset done at the end of S3, only wait for TOS to be unloaded */ - if (adev->in_s3 && !(adev->flags & AMD_IS_APU) && amdgpu_in_reset(adev)) + if ((adev->in_s4 || adev->in_s3) && !(adev->flags & AMD_IS_APU) && + amdgpu_in_reset(adev)) return psp_v11_wait_for_tos_unload(psp); for (retry_loop = 0; retry_loop < 20; retry_loop++) { diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index 73ce3d211ed6..8a9ba2276275 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c @@ -93,6 +93,11 @@ static void uvd_v4_2_ring_set_wptr(struct amdgpu_ring *ring) static int uvd_v4_2_early_init(struct amdgpu_ip_block *ip_block) { struct amdgpu_device *adev = ip_block->adev; + + /* UVD doesn't work without DPM, it needs DPM to ungate it. */ + if (!amdgpu_dpm) + return -ENOENT; + adev->uvd.num_uvd_inst = 1; uvd_v4_2_set_ring_funcs(adev); |
