amd-drm-fixes-6.16-2025-07-01:

amdgpu:
 - SDMA 5.x reset fix
 - Add missing firmware declaration
 - Fix leak in amdgpu_ctx_mgr_entity_fini()
 - Freesync fix
 - OLED backlight fix
 
 amdkfd:
 - mtype fix for ext coherent system memory
 - MMU notifier fix
 - gfx7/8 fix
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCaGQ1LQAKCRC93/aFa7yZ
 2K5YAQCsVwUTRCmlTEcWP7cssQ+z2tHnoOYZtCRiANndhBGo3wD+NbiFyk1tkJiQ
 UEhECfmdgKvukbEIvqyG61+vVe+DuQ4=
 =vohC
 -----END PGP SIGNATURE-----

Merge tag 'amd-drm-fixes-6.16-2025-07-01' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes

amd-drm-fixes-6.16-2025-07-01:

amdgpu:
- SDMA 5.x reset fix
- Add missing firmware declaration
- Fix leak in amdgpu_ctx_mgr_entity_fini()
- Freesync fix
- OLED backlight fix

amdkfd:
- mtype fix for ext coherent system memory
- MMU notifier fix
- gfx7/8 fix

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://lore.kernel.org/r/20250701192642.32490-1-alexander.deucher@amd.com
This commit is contained in:
Dave Airlie 2025-07-02 11:17:25 +10:00
commit bf906c988d
10 changed files with 67 additions and 31 deletions

View File

@ -561,6 +561,13 @@ static uint32_t read_vmid_from_vmfault_reg(struct amdgpu_device *adev)
return REG_GET_FIELD(status, VM_CONTEXT1_PROTECTION_FAULT_STATUS, VMID);
}
static uint32_t kgd_hqd_sdma_get_doorbell(struct amdgpu_device *adev,
int engine, int queue)
{
return 0;
}
const struct kfd2kgd_calls gfx_v7_kfd2kgd = {
.program_sh_mem_settings = kgd_program_sh_mem_settings,
.set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping,
@ -578,4 +585,5 @@ const struct kfd2kgd_calls gfx_v7_kfd2kgd = {
.set_scratch_backing_va = set_scratch_backing_va,
.set_vm_context_page_table_base = set_vm_context_page_table_base,
.read_vmid_from_vmfault_reg = read_vmid_from_vmfault_reg,
.hqd_sdma_get_doorbell = kgd_hqd_sdma_get_doorbell,
};

View File

@ -582,6 +582,13 @@ static void set_vm_context_page_table_base(struct amdgpu_device *adev,
lower_32_bits(page_table_base));
}
static uint32_t kgd_hqd_sdma_get_doorbell(struct amdgpu_device *adev,
int engine, int queue)
{
return 0;
}
const struct kfd2kgd_calls gfx_v8_kfd2kgd = {
.program_sh_mem_settings = kgd_program_sh_mem_settings,
.set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping,
@ -599,4 +606,5 @@ const struct kfd2kgd_calls gfx_v8_kfd2kgd = {
get_atc_vmid_pasid_mapping_info,
.set_scratch_backing_va = set_scratch_backing_va,
.set_vm_context_page_table_base = set_vm_context_page_table_base,
.hqd_sdma_get_doorbell = kgd_hqd_sdma_get_doorbell,
};

View File

@ -944,6 +944,7 @@ static void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
drm_sched_entity_fini(entity);
}
}
kref_put(&ctx->refcount, amdgpu_ctx_fini);
}
}

View File

@ -45,6 +45,7 @@
#include "amdgpu_ras.h"
MODULE_FIRMWARE("amdgpu/sdma_4_4_2.bin");
MODULE_FIRMWARE("amdgpu/sdma_4_4_4.bin");
MODULE_FIRMWARE("amdgpu/sdma_4_4_5.bin");
static const struct amdgpu_hwip_reg_entry sdma_reg_list_4_4_2[] = {

View File

@ -1543,8 +1543,13 @@ static int sdma_v5_0_reset_queue(struct amdgpu_ring *ring, unsigned int vmid)
{
struct amdgpu_device *adev = ring->adev;
u32 inst_id = ring->me;
int r;
return amdgpu_sdma_reset_engine(adev, inst_id);
amdgpu_amdkfd_suspend(adev, true);
r = amdgpu_sdma_reset_engine(adev, inst_id);
amdgpu_amdkfd_resume(adev, true);
return r;
}
static int sdma_v5_0_stop_queue(struct amdgpu_ring *ring)

View File

@ -1456,8 +1456,13 @@ static int sdma_v5_2_reset_queue(struct amdgpu_ring *ring, unsigned int vmid)
{
struct amdgpu_device *adev = ring->adev;
u32 inst_id = ring->me;
int r;
return amdgpu_sdma_reset_engine(adev, inst_id);
amdgpu_amdkfd_suspend(adev, true);
r = amdgpu_sdma_reset_engine(adev, inst_id);
amdgpu_amdkfd_resume(adev, true);
return r;
}
static int sdma_v5_2_stop_queue(struct amdgpu_ring *ring)

View File

@ -1171,13 +1171,12 @@ svm_range_split_head(struct svm_range *prange, uint64_t new_start,
}
static void
svm_range_add_child(struct svm_range *prange, struct mm_struct *mm,
struct svm_range *pchild, enum svm_work_list_ops op)
svm_range_add_child(struct svm_range *prange, struct svm_range *pchild, enum svm_work_list_ops op)
{
pr_debug("add child 0x%p [0x%lx 0x%lx] to prange 0x%p child list %d\n",
pchild, pchild->start, pchild->last, prange, op);
pchild->work_item.mm = mm;
pchild->work_item.mm = NULL;
pchild->work_item.op = op;
list_add_tail(&pchild->child_list, &prange->child_list);
}
@ -1278,7 +1277,7 @@ svm_range_get_pte_flags(struct kfd_node *node,
mapping_flags |= ext_coherent ? AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
/* system memory accessed by the dGPU */
} else {
if (gc_ip_version < IP_VERSION(9, 5, 0))
if (gc_ip_version < IP_VERSION(9, 5, 0) || ext_coherent)
mapping_flags |= AMDGPU_VM_MTYPE_UC;
else
mapping_flags |= AMDGPU_VM_MTYPE_NC;
@ -2394,15 +2393,17 @@ svm_range_add_list_work(struct svm_range_list *svms, struct svm_range *prange,
prange->work_item.op != SVM_OP_UNMAP_RANGE)
prange->work_item.op = op;
} else {
prange->work_item.op = op;
/* Pairs with mmput in deferred_list_work */
mmget(mm);
prange->work_item.mm = mm;
list_add_tail(&prange->deferred_list,
&prange->svms->deferred_range_list);
pr_debug("add prange 0x%p [0x%lx 0x%lx] to work list op %d\n",
prange, prange->start, prange->last, op);
/* Pairs with mmput in deferred_list_work.
* If process is exiting and mm is gone, don't update mmu notifier.
*/
if (mmget_not_zero(mm)) {
prange->work_item.mm = mm;
prange->work_item.op = op;
list_add_tail(&prange->deferred_list,
&prange->svms->deferred_range_list);
pr_debug("add prange 0x%p [0x%lx 0x%lx] to work list op %d\n",
prange, prange->start, prange->last, op);
}
}
spin_unlock(&svms->deferred_list_lock);
}
@ -2416,8 +2417,7 @@ void schedule_deferred_list_work(struct svm_range_list *svms)
}
static void
svm_range_unmap_split(struct mm_struct *mm, struct svm_range *parent,
struct svm_range *prange, unsigned long start,
svm_range_unmap_split(struct svm_range *parent, struct svm_range *prange, unsigned long start,
unsigned long last)
{
struct svm_range *head;
@ -2438,12 +2438,12 @@ svm_range_unmap_split(struct mm_struct *mm, struct svm_range *parent,
svm_range_split(tail, last + 1, tail->last, &head);
if (head != prange && tail != prange) {
svm_range_add_child(parent, mm, head, SVM_OP_UNMAP_RANGE);
svm_range_add_child(parent, mm, tail, SVM_OP_ADD_RANGE);
svm_range_add_child(parent, head, SVM_OP_UNMAP_RANGE);
svm_range_add_child(parent, tail, SVM_OP_ADD_RANGE);
} else if (tail != prange) {
svm_range_add_child(parent, mm, tail, SVM_OP_UNMAP_RANGE);
svm_range_add_child(parent, tail, SVM_OP_UNMAP_RANGE);
} else if (head != prange) {
svm_range_add_child(parent, mm, head, SVM_OP_UNMAP_RANGE);
svm_range_add_child(parent, head, SVM_OP_UNMAP_RANGE);
} else if (parent != prange) {
prange->work_item.op = SVM_OP_UNMAP_RANGE;
}
@ -2520,14 +2520,14 @@ svm_range_unmap_from_cpu(struct mm_struct *mm, struct svm_range *prange,
l = min(last, pchild->last);
if (l >= s)
svm_range_unmap_from_gpus(pchild, s, l, trigger);
svm_range_unmap_split(mm, prange, pchild, start, last);
svm_range_unmap_split(prange, pchild, start, last);
mutex_unlock(&pchild->lock);
}
s = max(start, prange->start);
l = min(last, prange->last);
if (l >= s)
svm_range_unmap_from_gpus(prange, s, l, trigger);
svm_range_unmap_split(mm, prange, prange, start, last);
svm_range_unmap_split(prange, prange, start, last);
if (unmap_parent)
svm_range_add_list_work(svms, prange, mm, SVM_OP_UNMAP_RANGE);
@ -2570,8 +2570,6 @@ svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni,
if (range->event == MMU_NOTIFY_RELEASE)
return true;
if (!mmget_not_zero(mni->mm))
return true;
start = mni->interval_tree.start;
last = mni->interval_tree.last;
@ -2598,7 +2596,6 @@ svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni,
}
svm_range_unlock(prange);
mmput(mni->mm);
return true;
}

View File

@ -3610,13 +3610,15 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
luminance_range = &conn_base->display_info.luminance_range;
if (luminance_range->max_luminance) {
caps->aux_min_input_signal = luminance_range->min_luminance;
if (luminance_range->max_luminance)
caps->aux_max_input_signal = luminance_range->max_luminance;
} else {
caps->aux_min_input_signal = 0;
else
caps->aux_max_input_signal = 512;
}
if (luminance_range->min_luminance)
caps->aux_min_input_signal = luminance_range->min_luminance;
else
caps->aux_min_input_signal = 1;
min_input_signal_override = drm_get_panel_min_brightness_quirk(aconnector->drm_edid);
if (min_input_signal_override >= 0)

View File

@ -974,6 +974,7 @@ struct dc_crtc_timing {
uint32_t pix_clk_100hz;
uint32_t min_refresh_in_uhz;
uint32_t max_refresh_in_uhz;
uint32_t vic;
uint32_t hdmi_vic;

View File

@ -155,6 +155,14 @@ unsigned int mod_freesync_calc_v_total_from_refresh(
v_total = div64_u64(div64_u64(((unsigned long long)(
frame_duration_in_ns) * (stream->timing.pix_clk_100hz / 10)),
stream->timing.h_total), 1000000);
} else if (refresh_in_uhz >= stream->timing.max_refresh_in_uhz) {
/* When the target refresh rate is the maximum panel refresh rate
* round up the vtotal value to prevent off-by-one error causing
* v_total_min to be below the panel's lower bound
*/
v_total = div64_u64(div64_u64(((unsigned long long)(
frame_duration_in_ns) * (stream->timing.pix_clk_100hz / 10)),
stream->timing.h_total) + (1000000 - 1), 1000000);
} else {
v_total = div64_u64(div64_u64(((unsigned long long)(
frame_duration_in_ns) * (stream->timing.pix_clk_100hz / 10)),