amd-drm-fixes-7.1-2026-06-03:

amdgpu:
 - BT.2020 fix for DCE
 - DC bounds checking fixes
 - SDMA 7.1 fix
 - UserQ fixes
 - SI fix
 - SMU 13 fixes
 - SMU 14 fixes
 - GC 12.1 fix
 - Userptr fix
 - GC 10.1 fix
 - GART fix for non-4K pages
 
 amdkfd:
 - UAF race fix
 - Fix a potential NULL pointer dereference
 - GC 11 buffer overflow fix for SDMA
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCaiDQSwAKCRC93/aFa7yZ
 2NyEAQCcSxHe9YpLqid0MK1QTGPuTU5r4gy0qdqU0dQjsYlFdAD/YO+A13N7eME+
 9vzAlFjf5ALSkDVm0Ovwyc4Nz8AfmAw=
 =IwUZ
 -----END PGP SIGNATURE-----

Merge tag 'amd-drm-fixes-7.1-2026-06-03' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes

amd-drm-fixes-7.1-2026-06-03:

amdgpu:
- BT.2020 fix for DCE
- DC bounds checking fixes
- SDMA 7.1 fix
- UserQ fixes
- SI fix
- SMU 13 fixes
- SMU 14 fixes
- GC 12.1 fix
- Userptr fix
- GC 10.1 fix
- GART fix for non-4K pages

amdkfd:
- UAF race fix
- Fix a potential NULL pointer dereference
- GC 11 buffer overflow fix for SDMA

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

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patch.msgid.link/20260604011351.2373027-1-alexander.deucher@amd.com
This commit is contained in:
Dave Airlie 2026-06-04 11:15:28 +10:00
commit 36cda56d7e
43 changed files with 289 additions and 172 deletions

View File

@ -394,7 +394,8 @@ void amdgpu_gart_map_vram_range(struct amdgpu_device *adev, uint64_t pa,
uint64_t start_page, uint64_t num_pages,
uint64_t flags, void *dst)
{
u32 i, idx;
u32 i, j, t, idx;
u64 page_base;
/* The SYSTEM flag indicates the pages aren't in VRAM. */
WARN_ON_ONCE(flags & AMDGPU_PTE_SYSTEM);
@ -402,9 +403,12 @@ void amdgpu_gart_map_vram_range(struct amdgpu_device *adev, uint64_t pa,
if (!drm_dev_enter(adev_to_drm(adev), &idx))
return;
for (i = 0; i < num_pages; ++i) {
amdgpu_gmc_set_pte_pde(adev, dst,
start_page + i, pa + AMDGPU_GPU_PAGE_SIZE * i, flags);
page_base = pa;
for (i = 0, t = 0; i < num_pages; i++) {
for (j = 0; j < AMDGPU_GPU_PAGES_IN_CPU_PAGE; j++, t++) {
amdgpu_gmc_set_pte_pde(adev, dst, start_page + t, page_base, flags);
page_base += AMDGPU_GPU_PAGE_SIZE;
}
}
drm_dev_exit(idx);

View File

@ -170,7 +170,7 @@ int amdgpu_gmc_set_pte_pde(struct amdgpu_device *adev, void *cpu_pt_addr,
/*
* The following is for PTE only. GART does not have PDEs.
*/
value = addr & 0x0000FFFFFFFFF000ULL;
value = addr & adev->gmc.pte_addr_mask;
value |= flags;
writeq(value, ptr + (gpu_page_idx * 8));
@ -1003,7 +1003,7 @@ void amdgpu_gmc_noretry_set(struct amdgpu_device *adev)
gc_ver == IP_VERSION(9, 4, 3) ||
gc_ver == IP_VERSION(9, 4, 4) ||
gc_ver == IP_VERSION(9, 5, 0) ||
gc_ver >= IP_VERSION(10, 3, 0));
gc_ver >= IP_VERSION(10, 1, 0));
if (!amdgpu_sriov_xnack_support(adev))
gmc->noretry = 1;

View File

@ -280,6 +280,7 @@ struct amdgpu_gmc {
u64 real_vram_size;
int vram_mtrr;
u64 mc_mask;
uint64_t pte_addr_mask;
const struct firmware *fw; /* MC firmware */
uint32_t fw_version;
struct amdgpu_irq_src vm_fault;

View File

@ -203,7 +203,7 @@ int amdgpu_gtt_mgr_alloc_entries(struct amdgpu_gtt_mgr *mgr,
int r;
/* Align to TLB L2 cache entry size to work around "V bit HW bug" */
if (adev->asic_type == CHIP_TAHITI) {
if (adev->family == AMDGPU_FAMILY_SI) {
alignment = 32 * 1024 / AMDGPU_GPU_PAGE_SIZE;
num_pages = ALIGN(num_pages, alignment);
}

View File

@ -67,6 +67,7 @@ static bool amdgpu_hmm_invalidate_gfx(struct mmu_interval_notifier *mni,
{
struct amdgpu_bo *bo = container_of(mni, struct amdgpu_bo, notifier);
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
struct amdgpu_bo *vm_root = bo->vm_bo->vm->root.bo;
long r;
if (!mmu_notifier_range_blockable(range))
@ -77,8 +78,9 @@ static bool amdgpu_hmm_invalidate_gfx(struct mmu_interval_notifier *mni,
mmu_interval_set_seq(mni, cur_seq);
amdgpu_vm_bo_invalidate(bo, false);
r = dma_resv_wait_timeout(bo->tbo.base.resv, DMA_RESV_USAGE_BOOKKEEP,
false, MAX_SCHEDULE_TIMEOUT);
r = dma_resv_wait_timeout(vm_root->tbo.base.resv,
DMA_RESV_USAGE_BOOKKEEP, false,
MAX_SCHEDULE_TIMEOUT);
mutex_unlock(&adev->notifier_lock);
if (r <= 0)
DRM_ERROR("(%ld) failed to wait for user bo\n", r);

View File

@ -173,16 +173,17 @@ void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv)
int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *va,
u64 *gpu_addr, u64 **cpu_addr)
{
unsigned long bit_pos;
unsigned long bit_pos = 0;
for (;;) {
bit_pos = find_first_zero_bit(adev->seq64.used, adev->seq64.num_sem);
do {
bit_pos = find_next_zero_bit(adev->seq64.used,
adev->seq64.num_sem, bit_pos);
if (bit_pos >= adev->seq64.num_sem)
return -ENOSPC;
if (!test_and_set_bit(bit_pos, adev->seq64.used))
break;
}
bit_pos++;
} while (1);
*va = bit_pos * sizeof(u64) + amdgpu_seq64_get_va_base(adev);

View File

@ -532,10 +532,6 @@ amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_que
amdgpu_bo_unreserve(queue->db_obj.obj);
amdgpu_bo_unref(&queue->db_obj.obj);
amdgpu_bo_reserve(queue->wptr_obj.obj, true);
amdgpu_bo_unpin(queue->wptr_obj.obj);
amdgpu_bo_unreserve(queue->wptr_obj.obj);
amdgpu_bo_unref(&queue->wptr_obj.obj);
kfree(queue);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@ -887,7 +883,7 @@ amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr)
continue;
}
r = amdgpu_userq_restore_helper(queue);
r = amdgpu_userq_map_helper(queue);
if (r)
ret = r;
@ -1124,7 +1120,7 @@ amdgpu_userq_evict_all(struct amdgpu_userq_mgr *uq_mgr)
/* Try to unmap all the queues in this process ctx */
xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {
r = amdgpu_userq_preempt_helper(queue);
r = amdgpu_userq_unmap_helper(queue);
if (r)
ret = r;
}
@ -1344,8 +1340,7 @@ int amdgpu_userq_start_sched_for_enforce_isolation(struct amdgpu_device *adev,
}
void amdgpu_userq_gem_va_unmap_validate(struct amdgpu_device *adev,
struct amdgpu_bo_va_mapping *mapping,
uint64_t saddr)
struct amdgpu_bo_va_mapping *mapping)
{
u32 ip_mask = amdgpu_userq_get_supported_ip_mask(adev);
struct amdgpu_bo_va *bo_va = mapping->bo_va;
@ -1354,12 +1349,9 @@ void amdgpu_userq_gem_va_unmap_validate(struct amdgpu_device *adev,
if (!ip_mask)
return;
dev_warn_once(adev->dev, "now unmapping a vital queue va:%llx\n", saddr);
/**
* The userq VA mapping reservation should include the eviction fence,
* if the eviction fence can't signal successfully during unmapping,
* then driver will warn to flag this improper unmap of the userq VA.
* Note: The eviction fence may be attached to different BOs, and this
* The userq VA mapping reservation should include the eviction fence.
* Note: The eviction fence may be attached to different BOs and this
* unmap is only for one kind of userq VAs, so at this point suppose
* the eviction fence is always unsignaled.
*/

View File

@ -182,6 +182,5 @@ int amdgpu_userq_input_va_validate(struct amdgpu_device *adev,
u64 addr, u64 expected_size, u64 *va_out);
void amdgpu_userq_gem_va_unmap_validate(struct amdgpu_device *adev,
struct amdgpu_bo_va_mapping *mapping,
uint64_t saddr);
struct amdgpu_bo_va_mapping *mapping);
#endif

View File

@ -2006,7 +2006,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
* from user space.
*/
if (unlikely(bo_va->userq_va_mapped))
amdgpu_userq_gem_va_unmap_validate(adev, mapping, saddr);
amdgpu_userq_gem_va_unmap_validate(adev, mapping);
list_del(&mapping->list);
amdgpu_vm_it_remove(mapping, &vm->va);

View File

@ -449,12 +449,10 @@ static void gfxhub_v11_5_0_set_fault_enable_default(struct amdgpu_device *adev,
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
if (!value) {
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, 1);
}
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, !value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, !value);
WREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL, tmp);
}

View File

@ -454,12 +454,10 @@ static void gfxhub_v12_0_set_fault_enable_default(struct amdgpu_device *adev,
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
if (!value) {
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, 1);
}
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, !value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, !value);
WREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL, tmp);
}

View File

@ -633,19 +633,17 @@ static void gfxhub_v12_1_xcc_set_fault_enable_default(struct amdgpu_device *adev
tmp = REG_SET_FIELD(tmp,
GCVM_L2_PROTECTION_FAULT_CNTL_LO32,
OTHER_CLIENT_ID_NO_RETRY_FAULT_INTERRUPT, value);
if (!value)
tmp = REG_SET_FIELD(tmp,
GCVM_L2_PROTECTION_FAULT_CNTL_LO32,
CRASH_ON_NO_RETRY_FAULT, 1);
tmp = REG_SET_FIELD(tmp,
GCVM_L2_PROTECTION_FAULT_CNTL_LO32,
CRASH_ON_NO_RETRY_FAULT, !value);
WREG32_SOC15(GC, GET_INST(GC, i),
regGCVM_L2_PROTECTION_FAULT_CNTL_LO32, tmp);
tmp = RREG32_SOC15(GC, GET_INST(GC, i),
regGCVM_L2_PROTECTION_FAULT_CNTL_HI32);
if (!value)
tmp = REG_SET_FIELD(tmp,
GCVM_L2_PROTECTION_FAULT_CNTL_HI32,
CRASH_ON_RETRY_FAULT, 1);
tmp = REG_SET_FIELD(tmp,
GCVM_L2_PROTECTION_FAULT_CNTL_HI32,
CRASH_ON_RETRY_FAULT, !value);
WREG32_SOC15(GC, GET_INST(GC, i),
regGCVM_L2_PROTECTION_FAULT_CNTL_HI32, tmp);
}

View File

@ -403,12 +403,10 @@ static void gfxhub_v1_0_set_fault_enable_default(struct amdgpu_device *adev,
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL,
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
if (!value) {
tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, 1);
tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, 1);
}
tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, !value);
tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, !value);
WREG32_SOC15(GC, 0, mmVM_L2_PROTECTION_FAULT_CNTL, tmp);
}

View File

@ -516,12 +516,10 @@ static void gfxhub_v1_2_xcc_set_fault_enable_default(struct amdgpu_device *adev,
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL,
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
if (!value) {
tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, 1);
tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, 1);
}
tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, !value);
tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, !value);
WREG32_SOC15(GC, GET_INST(GC, i), regVM_L2_PROTECTION_FAULT_CNTL, tmp);
}
}

View File

@ -418,12 +418,10 @@ static void gfxhub_v2_0_set_fault_enable_default(struct amdgpu_device *adev,
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
if (!value) {
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, 1);
}
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, !value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, !value);
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL, tmp);
}

View File

@ -449,12 +449,10 @@ static void gfxhub_v2_1_set_fault_enable_default(struct amdgpu_device *adev,
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
if (!value) {
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, 1);
}
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, !value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, !value);
WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL, tmp);
}

View File

@ -446,12 +446,10 @@ static void gfxhub_v3_0_set_fault_enable_default(struct amdgpu_device *adev,
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
if (!value) {
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, 1);
}
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, !value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, !value);
WREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL, tmp);
}

View File

@ -434,12 +434,10 @@ static void gfxhub_v3_0_3_set_fault_enable_default(struct amdgpu_device *adev,
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
if (!value) {
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, 1);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, 1);
}
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_NO_RETRY_FAULT, !value);
tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
CRASH_ON_RETRY_FAULT, !value);
WREG32_SOC15(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL, tmp);
}

View File

@ -847,6 +847,7 @@ static int gmc_v10_0_sw_init(struct amdgpu_ip_block *ip_block)
* internal address space.
*/
adev->gmc.mc_mask = 0xffffffffffffULL; /* 48 bit MC */
adev->gmc.pte_addr_mask = 0x0000FFFFFFFFF000ULL; /* 48 bit PA */
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44));
if (r) {

View File

@ -821,6 +821,7 @@ static int gmc_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
* internal address space.
*/
adev->gmc.mc_mask = 0xffffffffffffULL; /* 48 bit MC */
adev->gmc.pte_addr_mask = 0x0000FFFFFFFFF000ULL; /* 48 bit PA */
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44));
if (r) {

View File

@ -812,8 +812,9 @@ static int gmc_v12_0_gart_init(struct amdgpu_device *adev)
static int gmc_v12_0_sw_init(struct amdgpu_ip_block *ip_block)
{
int r, vram_width = 0, vram_type = 0, vram_vendor = 0;
int r, vram_width = 0, vram_type = 0, vram_vendor = 0, dma_addr_bits;
struct amdgpu_device *adev = ip_block->adev;
uint64_t pte_addr_mask = 0;
int i;
adev->mmhub.funcs->init(adev);
@ -843,6 +844,8 @@ static int gmc_v12_0_sw_init(struct amdgpu_ip_block *ip_block)
* block size 512 (9bit)
*/
amdgpu_vm_adjust_size(adev, 256 * 1024, 9, 3, 48);
pte_addr_mask = 0x0000FFFFFFFFF000ULL; /* 48 bit PA */
dma_addr_bits = 44;
break;
case IP_VERSION(12, 1, 0):
bitmap_set(adev->vmhubs_mask, AMDGPU_GFXHUB(0),
@ -855,9 +858,13 @@ static int gmc_v12_0_sw_init(struct amdgpu_ip_block *ip_block)
* block size 512 (9bit)
*/
amdgpu_vm_adjust_size(adev, 128 * 1024 * 1024, 9, 4, 57);
pte_addr_mask = 0x000FFFFFFFFFF000ULL; /* 52 bit PA */
dma_addr_bits = 52;
break;
default:
break;
dev_warn(adev->dev, "Unrecognized GC IP version: 0x%08x\n",
amdgpu_ip_version(adev, GC_HWIP, 0));
return -EINVAL;
}
/* This interrupt is VMC page fault.*/
@ -911,14 +918,15 @@ static int gmc_v12_0_sw_init(struct amdgpu_ip_block *ip_block)
* internal address space.
*/
adev->gmc.mc_mask = AMDGPU_GMC_HOLE_MASK;
adev->gmc.pte_addr_mask = pte_addr_mask;
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44));
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(dma_addr_bits));
if (r) {
drm_warn(adev_to_drm(adev), "No suitable DMA available.\n");
return r;
}
adev->need_swiotlb = drm_need_swiotlb(44);
adev->need_swiotlb = drm_need_swiotlb(dma_addr_bits);
r = gmc_v12_0_mc_init(adev);
if (r)

View File

@ -836,6 +836,7 @@ static int gmc_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
amdgpu_vm_adjust_size(adev, 64, 9, 1, 40);
adev->gmc.mc_mask = 0xffffffffffULL;
adev->gmc.pte_addr_mask = 0x000000FFFFFFF000ULL;
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40));
if (r) {

View File

@ -1016,6 +1016,7 @@ static int gmc_v7_0_sw_init(struct amdgpu_ip_block *ip_block)
* internal address space.
*/
adev->gmc.mc_mask = 0xffffffffffULL; /* 40 bit MC */
adev->gmc.pte_addr_mask = 0x000000FFFFFFF000ULL; /* 40 bit PA */
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40));
if (r) {

View File

@ -1131,6 +1131,7 @@ static int gmc_v8_0_sw_init(struct amdgpu_ip_block *ip_block)
* internal address space.
*/
adev->gmc.mc_mask = 0xffffffffffULL; /* 40 bit MC */
adev->gmc.pte_addr_mask = 0x000000FFFFFFF000ULL; /* 40 bit PA */
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40));
if (r) {

View File

@ -1994,6 +1994,7 @@ static int gmc_v9_0_sw_init(struct amdgpu_ip_block *ip_block)
* internal address space.
*/
adev->gmc.mc_mask = 0xffffffffffffULL; /* 48 bit MC */
adev->gmc.pte_addr_mask = 0x0000FFFFFFFFF000ULL; /* 48 bit PA */
dma_addr_bits = amdgpu_ip_version(adev, GC_HWIP, 0) >=
IP_VERSION(9, 4, 2) ?

View File

@ -467,6 +467,11 @@ static void mes_userq_mqd_destroy(struct amdgpu_usermode_queue *queue)
kfree(queue->userq_prop);
amdgpu_bo_free_kernel(&queue->mqd.obj, &queue->mqd.gpu_addr,
&queue->mqd.cpu_ptr);
amdgpu_bo_reserve(queue->wptr_obj.obj, true);
amdgpu_bo_unpin(queue->wptr_obj.obj);
amdgpu_bo_unreserve(queue->wptr_obj.obj);
amdgpu_bo_unref(&queue->wptr_obj.obj);
}
static int mes_userq_preempt(struct amdgpu_usermode_queue *queue)

View File

@ -1316,6 +1316,7 @@ static int sdma_v7_1_sw_init(struct amdgpu_ip_block *ip_block)
ring->ring_obj = NULL;
ring->use_doorbell = true;
ring->me = i;
ring->no_user_submission = adev->sdma.no_user_submission;
for (xcc_id = 0; xcc_id < fls(adev->gfx.xcc_mask); xcc_id++) {
if (adev->sdma.instance[i].xcc_id == GET_INST(GC, xcc_id))

View File

@ -2502,6 +2502,9 @@ static int wait_on_destroy_queue(struct device_queue_manager *dqm,
if (pdd->qpd.is_debug)
return ret;
if (q->properties.is_being_destroyed)
return -EBUSY;
q->properties.is_being_destroyed = true;
if (pdd->process->debug_trap_enabled && q->properties.is_suspended) {
@ -2514,6 +2517,9 @@ static int wait_on_destroy_queue(struct device_queue_manager *dqm,
dqm_lock(dqm);
}
if (ret)
q->properties.is_being_destroyed = false;
return ret;
}
@ -2607,7 +2613,7 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm,
return retval;
failed_try_destroy_debugged_queue:
q->properties.is_being_destroyed = false;
dqm_unlock(dqm);
return retval;
}
@ -3309,7 +3315,7 @@ static void copy_context_work_handler(struct work_struct *work)
static uint32_t *get_queue_ids(uint32_t num_queues, uint32_t *usr_queue_id_array)
{
if (!usr_queue_id_array)
return NULL;
return num_queues ? ERR_PTR(-EINVAL) : NULL;
if (num_queues > KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
return ERR_PTR(-EINVAL);

View File

@ -320,8 +320,7 @@ static void checkpoint_mqd(struct mqd_manager *mm, void *mqd, void *mqd_dst, voi
static void restore_mqd(struct mqd_manager *mm, void **mqd,
struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
struct queue_properties *qp,
const void *mqd_src,
struct queue_properties *qp, const void *mqd_src,
const void *ctl_stack_src, const u32 ctl_stack_size)
{
uint64_t addr;
@ -337,14 +336,48 @@ static void restore_mqd(struct mqd_manager *mm, void **mqd,
*gart_addr = addr;
m->cp_hqd_pq_doorbell_control =
qp->doorbell_off <<
CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
pr_debug("cp_hqd_pq_doorbell_control 0x%x\n",
m->cp_hqd_pq_doorbell_control);
qp->doorbell_off << CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
pr_debug("cp_hqd_pq_doorbell_control 0x%x\n", m->cp_hqd_pq_doorbell_control);
qp->is_active = 0;
}
static void checkpoint_mqd_sdma(struct mqd_manager *mm,
void *mqd,
void *mqd_dst,
void *ctl_stack_dst)
{
struct v11_sdma_mqd *m;
m = get_sdma_mqd(mqd);
memcpy(mqd_dst, m, sizeof(struct v11_sdma_mqd));
}
static void restore_mqd_sdma(struct mqd_manager *mm, void **mqd,
struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
struct queue_properties *qp,
const void *mqd_src,
const void *ctl_stack_src,
const u32 ctl_stack_size)
{
uint64_t addr;
struct v11_sdma_mqd *m;
m = (struct v11_sdma_mqd *) mqd_mem_obj->cpu_ptr;
addr = mqd_mem_obj->gpu_addr;
memcpy(m, mqd_src, sizeof(*m));
m->sdmax_rlcx_doorbell_offset =
qp->doorbell_off << SDMA0_QUEUE0_DOORBELL_OFFSET__OFFSET__SHIFT;
*mqd = m;
if (gart_addr)
*gart_addr = addr;
qp->is_active = 0;
}
static void init_mqd_hiq(struct mqd_manager *mm, void **mqd,
struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
@ -529,8 +562,8 @@ struct mqd_manager *mqd_manager_init_v11(enum KFD_MQD_TYPE type,
mqd->update_mqd = update_mqd_sdma;
mqd->destroy_mqd = kfd_destroy_mqd_sdma;
mqd->is_occupied = kfd_is_occupied_sdma;
mqd->checkpoint_mqd = checkpoint_mqd;
mqd->restore_mqd = restore_mqd;
mqd->checkpoint_mqd = checkpoint_mqd_sdma;
mqd->restore_mqd = restore_mqd_sdma;
mqd->mqd_size = sizeof(struct v11_sdma_mqd);
mqd->mqd_stride = kfd_mqd_stride;
#if defined(CONFIG_DEBUG_FS)

View File

@ -1344,8 +1344,13 @@ static ssize_t dp_sdp_message_debugfs_write(struct file *f, const char __user *b
if (size == 0)
return 0;
if (!connector->base.state || !connector->base.state->crtc)
return -ENODEV;
acrtc_state = to_dm_crtc_state(connector->base.state->crtc->state);
write_size = min_t(size_t, size, sizeof(data));
r = copy_from_user(data, buf, write_size);
write_size -= r;

View File

@ -289,8 +289,8 @@ bool dal_vector_reserve(struct vector *vector, uint32_t capacity)
if (capacity <= vector->capacity)
return true;
new_container = krealloc(vector->container,
capacity * vector->struct_size, GFP_KERNEL);
new_container = krealloc_array(vector->container,
capacity, vector->struct_size, GFP_KERNEL);
if (new_container) {
vector->container = new_container;

View File

@ -222,6 +222,7 @@ static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
ATOM_COMMON_RECORD_HEADER *header;
ATOM_I2C_RECORD *record;
struct bios_parser *bp = BP_FROM_DCB(dcb);
int i;
if (!info)
return BP_RESULT_BADINPUT;
@ -234,7 +235,7 @@ static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
offset = le16_to_cpu(object->usRecordOffset)
+ bp->object_info_tbl_offset;
for (;;) {
for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
if (!header)
@ -293,11 +294,12 @@ static enum bp_result bios_parser_get_device_tag_record(
{
ATOM_COMMON_RECORD_HEADER *header;
uint32_t offset;
int i;
offset = le16_to_cpu(object->usRecordOffset)
+ bp->object_info_tbl_offset;
for (;;) {
for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
if (!header)
@ -966,6 +968,7 @@ static ATOM_HPD_INT_RECORD *get_hpd_record(struct bios_parser *bp,
{
ATOM_COMMON_RECORD_HEADER *header;
uint32_t offset;
int i;
if (!object) {
BREAK_TO_DEBUGGER(); /* Invalid object */
@ -975,7 +978,7 @@ static ATOM_HPD_INT_RECORD *get_hpd_record(struct bios_parser *bp,
offset = le16_to_cpu(object->usRecordOffset)
+ bp->object_info_tbl_offset;
for (;;) {
for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
if (!header)
@ -1670,6 +1673,7 @@ static ATOM_ENCODER_CAP_RECORD_V2 *get_encoder_cap_record(
{
ATOM_COMMON_RECORD_HEADER *header;
uint32_t offset;
int i;
if (!object) {
BREAK_TO_DEBUGGER(); /* Invalid object */
@ -1679,7 +1683,7 @@ static ATOM_ENCODER_CAP_RECORD_V2 *get_encoder_cap_record(
offset = le16_to_cpu(object->usRecordOffset)
+ bp->object_info_tbl_offset;
for (;;) {
for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
if (!header)
@ -2769,6 +2773,7 @@ static enum bp_result update_slot_layout_info(struct dc_bios *dcb,
{
(void)i;
unsigned int j;
unsigned int n;
struct bios_parser *bp;
ATOM_BRACKET_LAYOUT_RECORD *record;
ATOM_COMMON_RECORD_HEADER *record_header;
@ -2778,7 +2783,7 @@ static enum bp_result update_slot_layout_info(struct dc_bios *dcb,
record = NULL;
record_header = NULL;
for (;;) {
for (n = 0; n < BIOS_MAX_NUM_RECORD; n++) {
record_header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, record_offset);
if (record_header == NULL) {

View File

@ -396,6 +396,7 @@ static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
struct atom_i2c_record *record;
struct atom_i2c_record dummy_record = {0};
struct bios_parser *bp = BP_FROM_DCB(dcb);
int i;
if (!info)
return BP_RESULT_BADINPUT;
@ -429,7 +430,7 @@ static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
break;
}
for (;;) {
for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
header = GET_IMAGE(struct atom_common_record_header, offset);
if (!header)
@ -534,6 +535,7 @@ static struct atom_hpd_int_record *get_hpd_record_for_path_v3(struct bios_parser
{
struct atom_common_record_header *header;
uint32_t offset;
int i;
if (!object) {
BREAK_TO_DEBUGGER(); /* Invalid object */
@ -542,7 +544,7 @@ static struct atom_hpd_int_record *get_hpd_record_for_path_v3(struct bios_parser
offset = object->disp_recordoffset + bp->object_info_tbl_offset;
for (;;) {
for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
header = GET_IMAGE(struct atom_common_record_header, offset);
if (!header)
@ -611,6 +613,7 @@ static struct atom_hpd_int_record *get_hpd_record(
{
struct atom_common_record_header *header;
uint32_t offset;
int i;
if (!object) {
BREAK_TO_DEBUGGER(); /* Invalid object */
@ -620,7 +623,7 @@ static struct atom_hpd_int_record *get_hpd_record(
offset = le16_to_cpu(object->disp_recordoffset)
+ bp->object_info_tbl_offset;
for (;;) {
for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
header = GET_IMAGE(struct atom_common_record_header, offset);
if (!header)
@ -701,8 +704,10 @@ static enum bp_result bios_parser_get_gpio_pin_info(
info->offset_en = info->offset + 1;
info->offset_mask = info->offset - 1;
info->mask = (uint32_t) (1 <<
header->gpio_pin[i].gpio_bitshift);
if (header->gpio_pin[i].gpio_bitshift >= 32)
return BP_RESULT_BADBIOSTABLE;
info->mask = 1u << header->gpio_pin[i].gpio_bitshift;
info->mask_y = info->mask + 2;
info->mask_en = info->mask + 1;
info->mask_mask = info->mask - 1;
@ -2193,6 +2198,7 @@ static struct atom_encoder_caps_record *get_encoder_cap_record(
{
struct atom_common_record_header *header;
uint32_t offset;
int i;
if (!object) {
BREAK_TO_DEBUGGER(); /* Invalid object */
@ -2201,7 +2207,7 @@ static struct atom_encoder_caps_record *get_encoder_cap_record(
offset = object->encoder_recordoffset + bp->object_info_tbl_offset;
for (;;) {
for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
header = GET_IMAGE(struct atom_common_record_header, offset);
if (!header)
@ -2230,6 +2236,7 @@ static struct atom_disp_connector_caps_record *get_disp_connector_caps_record(
{
struct atom_common_record_header *header;
uint32_t offset;
int i;
if (!object) {
BREAK_TO_DEBUGGER(); /* Invalid object */
@ -2238,7 +2245,7 @@ static struct atom_disp_connector_caps_record *get_disp_connector_caps_record(
offset = object->disp_recordoffset + bp->object_info_tbl_offset;
for (;;) {
for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
header = GET_IMAGE(struct atom_common_record_header, offset);
if (!header)
@ -2266,6 +2273,7 @@ static struct atom_connector_caps_record *get_connector_caps_record(struct bios_
{
struct atom_common_record_header *header;
uint32_t offset;
int i;
if (!object) {
BREAK_TO_DEBUGGER(); /* Invalid object */
@ -2274,7 +2282,7 @@ static struct atom_connector_caps_record *get_connector_caps_record(struct bios_
offset = object->disp_recordoffset + bp->object_info_tbl_offset;
for (;;) {
for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
header = GET_IMAGE(struct atom_common_record_header, offset);
if (!header)
@ -2352,6 +2360,7 @@ static struct atom_connector_speed_record *get_connector_speed_cap_record(struct
{
struct atom_common_record_header *header;
uint32_t offset;
int i;
if (!object) {
BREAK_TO_DEBUGGER(); /* Invalid object */
@ -2360,7 +2369,7 @@ static struct atom_connector_speed_record *get_connector_speed_cap_record(struct
offset = object->disp_recordoffset + bp->object_info_tbl_offset;
for (;;) {
for (i = 0; i < BIOS_MAX_NUM_RECORD; i++) {
header = GET_IMAGE(struct atom_common_record_header, offset);
if (!header)
@ -2600,14 +2609,16 @@ static enum bp_result get_integrated_info_v11(
info_v11->extdispconninfo.checksum;
info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr;
info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum;
info->dp0_ext_hdmi_reg_num = min_t(u8, info_v11->dp0_retimer_set.HdmiRegNum,
ARRAY_SIZE(info->dp0_ext_hdmi_reg_settings));
for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
}
info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum;
info->dp0_ext_hdmi_6g_reg_num = min_t(u8, info_v11->dp0_retimer_set.Hdmi6GRegNum,
ARRAY_SIZE(info->dp0_ext_hdmi_6g_reg_settings));
for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
@ -2616,14 +2627,16 @@ static enum bp_result get_integrated_info_v11(
}
info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr;
info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum;
info->dp1_ext_hdmi_reg_num = min_t(u8, info_v11->dp1_retimer_set.HdmiRegNum,
ARRAY_SIZE(info->dp1_ext_hdmi_reg_settings));
for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
}
info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum;
info->dp1_ext_hdmi_6g_reg_num = min_t(u8, info_v11->dp1_retimer_set.Hdmi6GRegNum,
ARRAY_SIZE(info->dp1_ext_hdmi_6g_reg_settings));
for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
@ -2632,14 +2645,16 @@ static enum bp_result get_integrated_info_v11(
}
info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr;
info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum;
info->dp2_ext_hdmi_reg_num = min_t(u8, info_v11->dp2_retimer_set.HdmiRegNum,
ARRAY_SIZE(info->dp2_ext_hdmi_reg_settings));
for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
}
info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum;
info->dp2_ext_hdmi_6g_reg_num = min_t(u8, info_v11->dp2_retimer_set.Hdmi6GRegNum,
ARRAY_SIZE(info->dp2_ext_hdmi_6g_reg_settings));
for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
@ -2648,14 +2663,16 @@ static enum bp_result get_integrated_info_v11(
}
info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr;
info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum;
info->dp3_ext_hdmi_reg_num = min_t(u8, info_v11->dp3_retimer_set.HdmiRegNum,
ARRAY_SIZE(info->dp3_ext_hdmi_reg_settings));
for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
}
info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum;
info->dp3_ext_hdmi_6g_reg_num = min_t(u8, info_v11->dp3_retimer_set.Hdmi6GRegNum,
ARRAY_SIZE(info->dp3_ext_hdmi_6g_reg_settings));
for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
@ -2805,14 +2822,16 @@ static enum bp_result get_integrated_info_v2_1(
info->ext_disp_conn_info.checksum =
info_v2_1->extdispconninfo.checksum;
info->dp0_ext_hdmi_slv_addr = info_v2_1->dp0_retimer_set.HdmiSlvAddr;
info->dp0_ext_hdmi_reg_num = info_v2_1->dp0_retimer_set.HdmiRegNum;
info->dp0_ext_hdmi_reg_num = min_t(u8, info_v2_1->dp0_retimer_set.HdmiRegNum,
ARRAY_SIZE(info->dp0_ext_hdmi_reg_settings));
for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
}
info->dp0_ext_hdmi_6g_reg_num = info_v2_1->dp0_retimer_set.Hdmi6GRegNum;
info->dp0_ext_hdmi_6g_reg_num = min_t(u8, info_v2_1->dp0_retimer_set.Hdmi6GRegNum,
ARRAY_SIZE(info->dp0_ext_hdmi_6g_reg_settings));
for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
@ -2820,14 +2839,16 @@ static enum bp_result get_integrated_info_v2_1(
info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
}
info->dp1_ext_hdmi_slv_addr = info_v2_1->dp1_retimer_set.HdmiSlvAddr;
info->dp1_ext_hdmi_reg_num = info_v2_1->dp1_retimer_set.HdmiRegNum;
info->dp1_ext_hdmi_reg_num = min_t(u8, info_v2_1->dp1_retimer_set.HdmiRegNum,
ARRAY_SIZE(info->dp1_ext_hdmi_reg_settings));
for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
}
info->dp1_ext_hdmi_6g_reg_num = info_v2_1->dp1_retimer_set.Hdmi6GRegNum;
info->dp1_ext_hdmi_6g_reg_num = min_t(u8, info_v2_1->dp1_retimer_set.Hdmi6GRegNum,
ARRAY_SIZE(info->dp1_ext_hdmi_6g_reg_settings));
for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
@ -2835,14 +2856,16 @@ static enum bp_result get_integrated_info_v2_1(
info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
}
info->dp2_ext_hdmi_slv_addr = info_v2_1->dp2_retimer_set.HdmiSlvAddr;
info->dp2_ext_hdmi_reg_num = info_v2_1->dp2_retimer_set.HdmiRegNum;
info->dp2_ext_hdmi_reg_num = min_t(u8, info_v2_1->dp2_retimer_set.HdmiRegNum,
ARRAY_SIZE(info->dp2_ext_hdmi_reg_settings));
for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
}
info->dp2_ext_hdmi_6g_reg_num = info_v2_1->dp2_retimer_set.Hdmi6GRegNum;
info->dp2_ext_hdmi_6g_reg_num = min_t(u8, info_v2_1->dp2_retimer_set.Hdmi6GRegNum,
ARRAY_SIZE(info->dp2_ext_hdmi_6g_reg_settings));
for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
@ -2850,14 +2873,16 @@ static enum bp_result get_integrated_info_v2_1(
info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
}
info->dp3_ext_hdmi_slv_addr = info_v2_1->dp3_retimer_set.HdmiSlvAddr;
info->dp3_ext_hdmi_reg_num = info_v2_1->dp3_retimer_set.HdmiRegNum;
info->dp3_ext_hdmi_reg_num = min_t(u8, info_v2_1->dp3_retimer_set.HdmiRegNum,
ARRAY_SIZE(info->dp3_ext_hdmi_reg_settings));
for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
}
info->dp3_ext_hdmi_6g_reg_num = info_v2_1->dp3_retimer_set.Hdmi6GRegNum;
info->dp3_ext_hdmi_6g_reg_num = min_t(u8, info_v2_1->dp3_retimer_set.Hdmi6GRegNum,
ARRAY_SIZE(info->dp3_ext_hdmi_6g_reg_settings));
for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
@ -3245,6 +3270,7 @@ static enum bp_result update_slot_layout_info(
{
unsigned int record_offset;
unsigned int j;
unsigned int n;
struct atom_display_object_path_v2 *object;
struct atom_bracket_layout_record *record;
struct atom_common_record_header *record_header;
@ -3266,7 +3292,7 @@ static enum bp_result update_slot_layout_info(
(object->disp_recordoffset) +
(unsigned int)(bp->object_info_tbl_offset);
for (;;) {
for (n = 0; n < BIOS_MAX_NUM_RECORD; n++) {
record_header = (struct atom_common_record_header *)
GET_IMAGE(struct atom_common_record_header,
@ -3360,6 +3386,7 @@ static enum bp_result update_slot_layout_info_v2(
struct slot_layout_info *slot_layout_info)
{
unsigned int record_offset;
unsigned int n;
struct atom_display_object_path_v3 *object;
struct atom_bracket_layout_record_v2 *record;
struct atom_common_record_header *record_header;
@ -3382,7 +3409,7 @@ static enum bp_result update_slot_layout_info_v2(
(object->disp_recordoffset) +
(unsigned int)(bp->object_info_tbl_offset);
for (;;) {
for (n = 0; n < BIOS_MAX_NUM_RECORD; n++) {
record_header = (struct atom_common_record_header *)
GET_IMAGE(struct atom_common_record_header,

View File

@ -37,4 +37,9 @@ void bios_set_scratch_critical_state(struct dc_bios *bios, bool state);
#define GET_IMAGE(type, offset) ((type *) bios_get_image(&bp->base, offset, sizeof(type)))
/* Upper bound on the number of records in a VBIOS record chain. Prevents
* unbounded looping if the VBIOS image is malformed and lacks a terminator.
*/
#define BIOS_MAX_NUM_RECORD 256
#endif

View File

@ -1217,7 +1217,7 @@ struct dc_lttpr_caps {
union dp_main_link_channel_coding_lttpr_cap main_link_channel_coding;
union dp_128b_132b_supported_lttpr_link_rates supported_128b_132b_rates;
union dp_alpm_lttpr_cap alpm;
uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1];
uint8_t aux_rd_interval[MAX_REPEATER_CNT];
uint8_t lttpr_ieee_oui[3]; // Always read from closest LTTPR to host
uint8_t lttpr_device_id[6]; // Always read from closest LTTPR to host
};

View File

@ -110,7 +110,15 @@ static const struct out_csc_color_matrix global_color_matrix[] = {
{ COLOR_SPACE_YCBCR601_LIMITED, { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
{ COLOR_SPACE_YCBCR709_LIMITED, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }
0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
{ COLOR_SPACE_2020_RGB_FULLRANGE,
{ 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
{ COLOR_SPACE_2020_RGB_LIMITEDRANGE,
{ 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} },
{ COLOR_SPACE_2020_YCBCR_LIMITED, { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868,
0x15B2, 0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} },
{ COLOR_SPACE_2020_YCBCR_FULL, { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868, 0x15B2,
0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} }
};
static bool setup_scaling_configuration(

View File

@ -88,7 +88,15 @@ static const struct out_csc_color_matrix global_color_matrix[] = {
{ COLOR_SPACE_YCBCR601_LIMITED, { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
{ COLOR_SPACE_YCBCR709_LIMITED, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }
0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
{ COLOR_SPACE_2020_RGB_FULLRANGE,
{ 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
{ COLOR_SPACE_2020_RGB_LIMITEDRANGE,
{ 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} },
{ COLOR_SPACE_2020_YCBCR_LIMITED, { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868,
0x15B2, 0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} },
{ COLOR_SPACE_2020_YCBCR_FULL, { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868, 0x15B2,
0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} }
};
enum csc_color_mode {

View File

@ -529,7 +529,8 @@ enum mod_hdcp_status mod_hdcp_read_rx_id_list(struct mod_hdcp *hdcp)
} else {
status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
hdcp->auth.msg.hdcp2.rx_id_list,
hdcp->auth.msg.hdcp2.rx_id_list_size);
MIN(hdcp->auth.msg.hdcp2.rx_id_list_size,
sizeof(hdcp->auth.msg.hdcp2.rx_id_list)));
}
return status;
}

View File

@ -2390,28 +2390,30 @@ static int smu_v13_0_0_enable_mgpu_fan_boost(struct smu_context *smu)
}
static int smu_v13_0_0_get_power_limit(struct smu_context *smu,
uint32_t *current_power_limit,
uint32_t *default_power_limit,
uint32_t *max_power_limit,
uint32_t *min_power_limit)
uint32_t *current_power_limit,
uint32_t *default_power_limit,
uint32_t *max_power_limit,
uint32_t *min_power_limit)
{
struct smu_table_context *table_context = &smu->smu_table;
struct smu_13_0_0_powerplay_table *powerplay_table =
(struct smu_13_0_0_powerplay_table *)table_context->power_play_table;
PPTable_t *pptable = table_context->driver_pptable;
SkuTable_t *skutable = &pptable->SkuTable;
uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0;
uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
if (smu_v13_0_get_current_power_limit(smu, &power_limit))
power_limit = smu->adev->pm.ac_power ?
uint32_t pp_limit = smu->adev->pm.ac_power ?
skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] :
skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0];
uint32_t power_limit = 0, od_percent_upper = 0, od_percent_lower = 0;
int ret;
if (current_power_limit) {
ret = smu_v13_0_get_current_power_limit(smu, &power_limit);
if (ret)
*current_power_limit = pp_limit;
}
if (current_power_limit)
*current_power_limit = power_limit;
if (default_power_limit)
*default_power_limit = power_limit;
*default_power_limit = pp_limit;
if (powerplay_table) {
if (smu->od_enabled &&
@ -2425,15 +2427,15 @@ static int smu_v13_0_0_get_power_limit(struct smu_context *smu,
}
dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
od_percent_upper, od_percent_lower, power_limit);
od_percent_upper, od_percent_lower, pp_limit);
if (max_power_limit) {
*max_power_limit = msg_limit * (100 + od_percent_upper);
*max_power_limit = pp_limit * (100 + od_percent_upper);
*max_power_limit /= 100;
}
if (min_power_limit) {
*min_power_limit = power_limit * (100 - od_percent_lower);
*min_power_limit = pp_limit * (100 - od_percent_lower);
*min_power_limit /= 100;
}
@ -2801,11 +2803,19 @@ static void smu_v13_0_0_i2c_control_fini(struct smu_context *smu)
static int smu_v13_0_0_set_mp1_state(struct smu_context *smu,
enum pp_mp1_state mp1_state)
{
uint32_t param;
int ret;
switch (mp1_state) {
case PP_MP1_STATE_UNLOAD:
ret = smu_cmn_set_mp1_state(smu, mp1_state);
/*
* NOTE: Param 0x55 comes from PMFW 80.31.0, ignored in older versions.
* No PMFW version check required.
*/
param = amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) ?
0x55 : 0x00;
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PrepareMp1ForUnload,
param, NULL);
break;
default:
/* Ignore others */

View File

@ -2372,28 +2372,32 @@ static int smu_v13_0_7_enable_mgpu_fan_boost(struct smu_context *smu)
}
static int smu_v13_0_7_get_power_limit(struct smu_context *smu,
uint32_t *current_power_limit,
uint32_t *default_power_limit,
uint32_t *max_power_limit,
uint32_t *min_power_limit)
uint32_t *current_power_limit,
uint32_t *default_power_limit,
uint32_t *max_power_limit,
uint32_t *min_power_limit)
{
struct smu_table_context *table_context = &smu->smu_table;
struct smu_13_0_7_powerplay_table *powerplay_table =
(struct smu_13_0_7_powerplay_table *)table_context->power_play_table;
PPTable_t *pptable = table_context->driver_pptable;
SkuTable_t *skutable = &pptable->SkuTable;
uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0;
uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
if (smu_v13_0_get_current_power_limit(smu, &power_limit))
power_limit = smu->adev->pm.ac_power ?
uint32_t pp_limit = smu->adev->pm.ac_power ?
skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] :
skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0];
uint32_t power_limit = 0, od_percent_upper = 0, od_percent_lower = 0;
int ret;
if (current_power_limit) {
ret = smu_v13_0_get_current_power_limit(smu, &power_limit);
if (ret)
power_limit = pp_limit;
if (current_power_limit)
*current_power_limit = power_limit;
}
if (default_power_limit)
*default_power_limit = power_limit;
*default_power_limit = pp_limit;
if (powerplay_table) {
if (smu->od_enabled &&
@ -2407,15 +2411,15 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu,
}
dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
od_percent_upper, od_percent_lower, power_limit);
od_percent_upper, od_percent_lower, pp_limit);
if (max_power_limit) {
*max_power_limit = msg_limit * (100 + od_percent_upper);
*max_power_limit = pp_limit * (100 + od_percent_upper);
*max_power_limit /= 100;
}
if (min_power_limit) {
*min_power_limit = power_limit * (100 - od_percent_lower);
*min_power_limit = pp_limit * (100 - od_percent_lower);
*min_power_limit /= 100;
}

View File

@ -1231,7 +1231,8 @@ static int smu_v14_0_0_set_soft_freq_limited_range(struct smu_context *smu,
switch (clk_type) {
case SMU_GFXCLK:
case SMU_SCLK:
msg_set_min = SMU_MSG_SetHardMinGfxClk;
/* SoftMin lets PMFW throttle gfxclk; HardMin would override SoftMax. */
msg_set_min = SMU_MSG_SetSoftMinGfxclk;
msg_set_max = SMU_MSG_SetSoftMaxGfxClk;
break;
case SMU_FCLK:

View File

@ -2152,7 +2152,6 @@ static ssize_t smu_v14_0_2_get_gpu_metrics(struct smu_context *smu,
metrics->Vcn1ActivityPercentage);
gpu_metrics->average_socket_power = metrics->AverageSocketPower;
gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
if (metrics->AverageGfxActivity <= SMU_14_0_2_BUSY_THRESHOLD)
gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs;

View File

@ -272,11 +272,15 @@ static void __smu_msg_v1_send(struct smu_msg_ctl *ctl, u16 index,
{
struct amdgpu_device *adev = ctl->smu->adev;
struct smu_msg_config *cfg = &ctl->config;
u32 arg;
int i;
WREG32(cfg->resp_reg, 0);
for (i = 0; i < args->num_args; i++)
WREG32(cfg->arg_regs[i], args->args[i]);
for (i = 0; i < cfg->num_arg_regs; i++) {
/* NOTE: Clear unused argument registers to avoid stale values. */
arg = i < args->num_args ? args->args[i] : 0;
WREG32(cfg->arg_regs[i], arg);
}
WREG32(cfg->msg_reg, index);
}