mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
drm fixes for 7.2-rc6
core: - disable the gem change handle ioctl for security reasons (plan to fix it on list later with proper test coverage) dumb-buffer: - remove strict limits on buffer geometry 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 xe: - Revert removing support for unpublished NVL-S GuC - Suspend fixes related to multi-queue i915: - Fix color blob reference handling in intel_plane_state - Revert "drm/i915/backlight: Remove try_vesa_interface" ethosu: - reject unsupported NPU_OP_RESIZE - fix index of IFM region - fix weight index - fix overflows in DMA-size calculations - reject DMA commands with uninitialized length - fix OOB write in ethosu_gem_cmdstream_copy_and_validate imx: - fix kernel-doc warnings ivpu: - add overflow checks in firmware handling and get_info_ioctl v3d: - wait for pending L2T flush before cleaning caches - fix leak of vaddr - skip CSD when it has zeroed workgroups - fix ref counting in performance monitoring -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmojVuUACgkQDHTzWXnE hr4uYxAAlYQS0NuQoNrXkLG/4jIwD8aG+83bnUWCEYn59Qurk7ojH4frwDSkxSi/ Klqzk1zdbsIC6LOjI1gevhBY1Z1ASgzBAr7G44lpofeGI7zdxiSAZ6lEu9ClUVLI I6dO73xLtGve5/0pgTrxsSz5p8ZKJhLSHhBf0oCyaKxGEsrirWR3ofV5RqWMy4HS +Y/wouBG69pe8B3OK8SZhXQhJxvhnws6i8p4+pMSAhfICIsMh5aTLsNEwRxdIGzh xXaOsE+mrhWOd6vmwK4qX4HprSocNTJyoRW7hkIFeWLwn0ZIJAmKwgWxmMAgebBe RRHB5dBAm0Krn3RDc1od8dqwZ6YxWRDi1rROJmV93u+qKoYdAIoxpofTW6eB4p4q lphLjTM0EQvreF4XShydMPWta5tiEYIUFL4OWf1eUR8C9Ejd0G8CeKZpDT/gLwWO lxozV9+EZdLAkaGLoBxeghCZPBlsmkYWZ8M++8jLaJQWx1QeCSBCulMEyDEO2MN6 4kM+awVZJ3Ou28Pjux23jSXxRgzRC/Bk373MEijX9FnB2lEYmgFDs9+kMNX1dmsj BcRi8+XSoUh9m1PoLuM+t+/Q+0neUdIfAX/6hqwbWp3knXtM7lQmUpgSo1hcpmop vMIbWZT3/ZjoFrwJSv1HuvYzpiF7YTCzv/BpVZU938FLMyBcOlk= =mrV8 -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2026-06-06' of https://gitlab.freedesktop.org/drm/kernel Pull drm fixes from Dave Airlie: "Weekly drm fixes, not contributing to things settling down unfortunately. Lots of driver fixes for various bounds checks, leaks and UAF type things, i915/xe probably the most sane, amdgpu has a mix of fixes all over, then ethosu has lots of small fixes. The problem of fixing thing in private has really hit us with the change handle ioctl, and "Sima was right" and we should have disabled the ioctl, since it was only introduced a couple of kernels ago and failed to upstream it's tests in time. The patch here fixes the problems Sima identified, but disables the ioctl as well, with a list of known problems in it and a request for proper tests to be written and upstreamed. It's a niche user ioctl designed for CRIU with AMD ROCm, so I think it's fine to just disable it. Maybe this week will settle down. core: - disable the gem change handle ioctl for security reasons (plan to fix it on list later with proper test coverage) dumb-buffer: - remove strict limits on buffer geometry 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 xe: - Revert removing support for unpublished NVL-S GuC - Suspend fixes related to multi-queue i915: - Fix color blob reference handling in intel_plane_state - Revert "drm/i915/backlight: Remove try_vesa_interface" ethosu: - reject unsupported NPU_OP_RESIZE - fix index of IFM region - fix weight index - fix overflows in DMA-size calculations - reject DMA commands with uninitialized length - fix OOB write in ethosu_gem_cmdstream_copy_and_validate imx: - fix kernel-doc warnings ivpu: - add overflow checks in firmware handling and get_info_ioctl v3d: - wait for pending L2T flush before cleaning caches - fix leak of vaddr - skip CSD when it has zeroed workgroups - fix ref counting in performance monitoring" * tag 'drm-fixes-2026-06-06' of https://gitlab.freedesktop.org/drm/kernel: (50 commits) drm/gem: Try to fix change_handle ioctl, attempt 4 Revert "drm/i915/backlight: Remove try_vesa_interface" accel/ethosu: fix OOB write in ethosu_gem_cmdstream_copy_and_validate() accel/ethosu: reject DMA commands with uninitialized length accel/ethosu: fix arithmetic issues in dma_length() accel/ethosu: fix wrong weight index in NPU_SET_SCALE1_LENGTH on U85 accel/ethosu: reject NPU_OP_RESIZE commands from userspace accel/ethosu: fix IFM region index out-of-bounds in command stream parser drm/v3d: Fix global performance monitor reference counting drm/xe/multi_queue: skip submit when primary queue is suspended drm/xe: Clear pending_disable before signaling suspend fence Revert "drm/xe: Skip exec queue schedule toggle if queue is idle during suspend" drm/amd/pm: smu_v14_0_0: use SoftMin for gfxclk in set_soft_freq_limited_range drm/amdgpu: Fix incorrect VRAM GART mappings on non-4K page size systems drm/amdgpu/userq: move wptr_obj cleanup in mqd_destroy drm/amdgpu: improve the userq seq BO free bit lookup drm/amdgpu/userq: remove the vital queue unmap logging drm/amdkfd: Fix buffer overflow in SDMA queue checkpoint/restore on GFX11 drm/amdkfd: fix NULL dereference in get_queue_ids() drm/amdgpu: set noretry=1 as default for GFX 10.1.x (Navi10/12/14) ...
This commit is contained in:
commit
8e65320d91
|
|
@ -2,6 +2,7 @@
|
|||
/* Copyright 2025 Arm, Ltd. */
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <drm/ethosu_accel.h>
|
||||
|
|
@ -163,17 +164,30 @@ static u64 dma_length(struct ethosu_validated_cmdstream_info *info,
|
|||
s8 mode = dma_st->mode;
|
||||
u64 len = dma->len;
|
||||
|
||||
if (len == U64_MAX)
|
||||
return U64_MAX;
|
||||
|
||||
if (mode >= 1) {
|
||||
if (dma->stride[0] < 0 && (u64)(-dma->stride[0]) > len)
|
||||
return U64_MAX;
|
||||
len += dma->stride[0];
|
||||
len *= dma_st->size0;
|
||||
if (check_mul_overflow(len, (u64)dma_st->size0, &len))
|
||||
return U64_MAX;
|
||||
}
|
||||
if (mode == 2) {
|
||||
if (dma->stride[1] < 0 && (u64)(-dma->stride[1]) > len)
|
||||
return U64_MAX;
|
||||
len += dma->stride[1];
|
||||
len *= dma_st->size1;
|
||||
if (check_mul_overflow(len, (u64)dma_st->size1, &len))
|
||||
return U64_MAX;
|
||||
}
|
||||
if (dma->region >= 0) {
|
||||
u64 end;
|
||||
|
||||
if (check_add_overflow(len, dma->offset, &end))
|
||||
return U64_MAX;
|
||||
info->region_size[dma->region] = max(info->region_size[dma->region], end);
|
||||
}
|
||||
if (dma->region >= 0)
|
||||
info->region_size[dma->region] = max(info->region_size[dma->region],
|
||||
len + dma->offset);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
|
@ -387,6 +401,8 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
|
|||
return -EFAULT;
|
||||
|
||||
i++;
|
||||
if (i >= size / 4)
|
||||
return -EINVAL;
|
||||
bocmds[i] = cmds[1];
|
||||
addr = cmd_to_addr(cmds);
|
||||
}
|
||||
|
|
@ -395,6 +411,8 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
|
|||
case NPU_OP_DMA_START:
|
||||
srclen = dma_length(info, &st.dma, &st.dma.src);
|
||||
dstlen = dma_length(info, &st.dma, &st.dma.dst);
|
||||
if (srclen == U64_MAX || dstlen == U64_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (st.dma.dst.region >= 0)
|
||||
info->output_region[st.dma.dst.region] = true;
|
||||
|
|
@ -431,8 +449,7 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
|
|||
return ret;
|
||||
break;
|
||||
case NPU_OP_RESIZE: // U85 only
|
||||
WARN_ON(1); // TODO
|
||||
break;
|
||||
return -EINVAL;
|
||||
case NPU_SET_KERNEL_WIDTH_M1:
|
||||
st.ifm.width = param;
|
||||
break;
|
||||
|
|
@ -464,7 +481,7 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
|
|||
st.ifm.broadcast = param;
|
||||
break;
|
||||
case NPU_SET_IFM_REGION:
|
||||
st.ifm.region = param & 0x7f;
|
||||
st.ifm.region = param & 0x7;
|
||||
break;
|
||||
case NPU_SET_IFM_WIDTH0_M1:
|
||||
st.ifm.width0 = param;
|
||||
|
|
@ -599,7 +616,7 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
|
|||
if (ethosu_is_u65(edev))
|
||||
st.scale[1].length = cmds[1];
|
||||
else
|
||||
st.weight[1].length = cmds[1];
|
||||
st.weight[2].length = cmds[1];
|
||||
break;
|
||||
case NPU_SET_WEIGHT3_BASE:
|
||||
st.weight[3].base = addr;
|
||||
|
|
|
|||
|
|
@ -259,6 +259,22 @@ static int ivpu_fw_parse(struct ivpu_device *vdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!PAGE_ALIGNED(runtime_addr)) {
|
||||
ivpu_err(vdev, "Runtime address 0x%llx not page aligned\n", runtime_addr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!PAGE_ALIGNED(runtime_size)) {
|
||||
ivpu_err(vdev, "Runtime size %llu not page aligned\n", runtime_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (runtime_size < image_size) {
|
||||
ivpu_err(vdev, "Runtime size too small: %llu, image size: %llu\n",
|
||||
runtime_size, image_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!ivpu_is_within_range(image_load_addr, image_size, &vdev->hw->ranges.runtime)) {
|
||||
ivpu_err(vdev, "Invalid firmware load address: 0x%llx and size %llu\n",
|
||||
image_load_addr, image_size);
|
||||
|
|
|
|||
|
|
@ -98,6 +98,11 @@ static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const cha
|
|||
u32 log_start = only_new_msgs ? READ_ONCE(log->read_index) : 0;
|
||||
u32 log_end = READ_ONCE(log->write_index);
|
||||
|
||||
if (log_start >= data_size)
|
||||
log_start = 0;
|
||||
if (log_end > data_size)
|
||||
log_end = data_size;
|
||||
|
||||
if (log->wrap_count == log->read_wrap_count) {
|
||||
if (log_end <= log_start) {
|
||||
drm_printf(p, "==== %s \"%s\" log empty ====\n", prefix, log->name);
|
||||
|
|
|
|||
|
|
@ -291,6 +291,13 @@ int ivpu_ms_get_info_ioctl(struct drm_device *dev, void *data, struct drm_file *
|
|||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
if (info_size > ivpu_bo_size(bo)) {
|
||||
ivpu_warn_ratelimited(vdev, "MS info overflow: %#llx > %#zx\n",
|
||||
info_size, ivpu_bo_size(bo));
|
||||
ret = -EOVERFLOW;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (args->buffer_size < info_size) {
|
||||
ret = -ENOSPC;
|
||||
goto unlock;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) ?
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -202,13 +202,6 @@ int drm_mode_create_dumb(struct drm_device *dev,
|
|||
if (!args->width || !args->height || !args->bpp)
|
||||
return -EINVAL;
|
||||
|
||||
/* Reject unreasonable inputs early. Dumb buffers are for software
|
||||
* rendering; nothing legitimate needs more than 8192x8192 at 32bpp.
|
||||
* This prevents overflows in downstream alignment helpers.
|
||||
*/
|
||||
if (args->width >= 8192 || args->height >= 8192 || args->bpp > 32)
|
||||
return -EINVAL;
|
||||
|
||||
/* overflow checks for 32bit size calculations */
|
||||
if (args->bpp > U32_MAX - 8)
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -1015,12 +1015,25 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This ioctl is disabled for security reasons but also it failed
|
||||
* to follow process in terms of adding testing in igt and verifying
|
||||
* all the corner cases which made fixing security bugs in it even
|
||||
* harder than necessary.
|
||||
*
|
||||
* To re-enable this ioctl
|
||||
* 1. land working IGT tests in igt-gpu-tools that cover
|
||||
* all corner cases and race conditions.
|
||||
* 2. handle idr_preload
|
||||
* 3. handle == 0
|
||||
* 4. handle == new_handle semantics definition.
|
||||
*/
|
||||
int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_gem_change_handle *args = data;
|
||||
struct drm_gem_object *obj, *idrobj;
|
||||
int handle, ret;
|
||||
struct drm_gem_object *obj;
|
||||
int new_handle, ret;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_GEM))
|
||||
return -EOPNOTSUPP;
|
||||
|
|
@ -1028,52 +1041,36 @@ int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data,
|
|||
/* idr_alloc() limitation. */
|
||||
if (args->new_handle > INT_MAX)
|
||||
return -EINVAL;
|
||||
handle = args->new_handle;
|
||||
new_handle = args->new_handle;
|
||||
|
||||
obj = drm_gem_object_lookup(file_priv, args->handle);
|
||||
if (!obj)
|
||||
return -ENOENT;
|
||||
|
||||
if (args->handle == handle) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
if (args->handle == new_handle)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&file_priv->prime.lock);
|
||||
|
||||
spin_lock(&file_priv->table_lock);
|
||||
|
||||
/* When create_tail allocs an obj idr, it needs to first alloc as NULL,
|
||||
* then later replace with the correct object. This is not necessary
|
||||
* here, because the only operations that could race are drm_prime
|
||||
* bookkeeping, and we hold the prime lock.
|
||||
*/
|
||||
ret = idr_alloc(&file_priv->object_idr, obj, handle, handle + 1,
|
||||
ret = idr_alloc(&file_priv->object_idr, NULL, new_handle, new_handle + 1,
|
||||
GFP_NOWAIT);
|
||||
|
||||
if (ret < 0) {
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
goto out_unlock;
|
||||
}
|
||||
if (ret < 0) {
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
idrobj = idr_replace(&file_priv->object_idr, NULL, handle);
|
||||
if (idrobj != obj) {
|
||||
idr_replace(&file_priv->object_idr, idrobj, handle);
|
||||
idr_remove(&file_priv->object_idr, args->new_handle);
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
ret = -ENOENT;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
idr_replace(&file_priv->object_idr, NULL, args->handle);
|
||||
obj = idr_replace(&file_priv->object_idr, NULL, args->handle);
|
||||
if (IS_ERR_OR_NULL(obj)) {
|
||||
idr_remove(&file_priv->object_idr, new_handle);
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
ret = -ENOENT;
|
||||
goto out_unlock;
|
||||
}
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
|
||||
if (obj->dma_buf) {
|
||||
ret = drm_prime_add_buf_handle(&file_priv->prime, obj->dma_buf,
|
||||
handle);
|
||||
new_handle);
|
||||
if (ret < 0) {
|
||||
spin_lock(&file_priv->table_lock);
|
||||
idr_remove(&file_priv->object_idr, handle);
|
||||
idr_remove(&file_priv->object_idr, new_handle);
|
||||
idr_replace(&file_priv->object_idr, obj, args->handle);
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
goto out_unlock;
|
||||
|
|
@ -1086,14 +1083,12 @@ int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data,
|
|||
|
||||
spin_lock(&file_priv->table_lock);
|
||||
idr_remove(&file_priv->object_idr, args->handle);
|
||||
idrobj = idr_replace(&file_priv->object_idr, obj, handle);
|
||||
obj = idr_replace(&file_priv->object_idr, obj, new_handle);
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
WARN_ON(idrobj != NULL);
|
||||
WARN_ON(obj != NULL);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&file_priv->prime.lock);
|
||||
out:
|
||||
drm_gem_object_put(obj);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -660,7 +660,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
|
|||
DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GEM_CHANGE_HANDLE, drm_gem_change_handle_ioctl, DRM_RENDER_ALLOW),
|
||||
/* see drm_gem.c:drm_gem_change_handle_ioctl for why this is invalid */
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_GEM_CHANGE_HANDLE, drm_invalid_op, DRM_RENDER_ALLOW),
|
||||
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, 0),
|
||||
|
||||
|
|
|
|||
|
|
@ -691,10 +691,9 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
|
|||
struct intel_dp *intel_dp = intel_attached_dp(connector);
|
||||
struct drm_device *dev = connector->base.dev;
|
||||
struct intel_panel *panel = &connector->panel;
|
||||
bool try_intel_interface = false;
|
||||
bool try_intel_interface = false, try_vesa_interface = false;
|
||||
|
||||
/*
|
||||
* Check the VBT and user's module parameters to figure out which
|
||||
/* Check the VBT and user's module parameters to figure out which
|
||||
* interfaces to probe
|
||||
*/
|
||||
switch (display->params.enable_dpcd_backlight) {
|
||||
|
|
@ -703,6 +702,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
|
|||
case INTEL_DP_AUX_BACKLIGHT_AUTO:
|
||||
switch (panel->vbt.backlight.type) {
|
||||
case INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE:
|
||||
try_vesa_interface = true;
|
||||
break;
|
||||
case INTEL_BACKLIGHT_DISPLAY_DDI:
|
||||
try_intel_interface = true;
|
||||
|
|
@ -715,12 +715,20 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
|
|||
if (panel->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE)
|
||||
try_intel_interface = true;
|
||||
|
||||
try_vesa_interface = true;
|
||||
break;
|
||||
case INTEL_DP_AUX_BACKLIGHT_FORCE_VESA:
|
||||
try_vesa_interface = true;
|
||||
break;
|
||||
case INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL:
|
||||
try_intel_interface = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/* For eDP 1.5 and above we are supposed to use VESA interface for brightness control */
|
||||
if (intel_dp->edp_dpcd[0] >= DP_EDP_15)
|
||||
try_vesa_interface = true;
|
||||
|
||||
/*
|
||||
* Since Intel has their own backlight control interface, the majority of machines out there
|
||||
* using DPCD backlight controls with Intel GPUs will be using this interface as opposed to
|
||||
|
|
@ -733,9 +741,6 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
|
|||
* panel with Intel's OUI - which is also required for us to be able to detect Intel's
|
||||
* backlight interface at all. This means that the only sensible way for us to detect both
|
||||
* interfaces is to probe for Intel's first, and VESA's second.
|
||||
*
|
||||
* Also there is a chance some VBTs may advertise false Intel backlight support even if the
|
||||
* TCON DPCD says otherwise. This means we keep VESA interface as fallback in that case.
|
||||
*/
|
||||
if (try_intel_interface && intel_dp->edp_dpcd[0] <= DP_EDP_14b &&
|
||||
intel_dp_aux_supports_hdr_backlight(connector)) {
|
||||
|
|
@ -745,7 +750,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (intel_dp_aux_supports_vesa_backlight(connector)) {
|
||||
if (try_vesa_interface && intel_dp_aux_supports_vesa_backlight(connector)) {
|
||||
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Using VESA eDP backlight controls\n",
|
||||
connector->base.base.id, connector->base.name);
|
||||
panel->backlight.funcs = &intel_dp_vesa_bl_funcs;
|
||||
|
|
|
|||
|
|
@ -144,6 +144,15 @@ intel_plane_duplicate_state(struct drm_plane *plane)
|
|||
if (intel_state->hw.fb)
|
||||
drm_framebuffer_get(intel_state->hw.fb);
|
||||
|
||||
if (intel_state->hw.degamma_lut)
|
||||
drm_property_blob_get(intel_state->hw.degamma_lut);
|
||||
if (intel_state->hw.gamma_lut)
|
||||
drm_property_blob_get(intel_state->hw.gamma_lut);
|
||||
if (intel_state->hw.ctm)
|
||||
drm_property_blob_get(intel_state->hw.ctm);
|
||||
if (intel_state->hw.lut_3d)
|
||||
drm_property_blob_get(intel_state->hw.lut_3d);
|
||||
|
||||
return &intel_state->uapi;
|
||||
}
|
||||
|
||||
|
|
@ -167,6 +176,16 @@ intel_plane_destroy_state(struct drm_plane *plane,
|
|||
__drm_atomic_helper_plane_destroy_state(&plane_state->uapi);
|
||||
if (plane_state->hw.fb)
|
||||
drm_framebuffer_put(plane_state->hw.fb);
|
||||
|
||||
if (plane_state->hw.degamma_lut)
|
||||
drm_property_blob_put(plane_state->hw.degamma_lut);
|
||||
if (plane_state->hw.gamma_lut)
|
||||
drm_property_blob_put(plane_state->hw.gamma_lut);
|
||||
if (plane_state->hw.ctm)
|
||||
drm_property_blob_put(plane_state->hw.ctm);
|
||||
if (plane_state->hw.lut_3d)
|
||||
drm_property_blob_put(plane_state->hw.lut_3d);
|
||||
|
||||
kfree(plane_state);
|
||||
}
|
||||
|
||||
|
|
@ -317,6 +336,14 @@ static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state)
|
|||
{
|
||||
if (plane_state->hw.fb)
|
||||
drm_framebuffer_put(plane_state->hw.fb);
|
||||
if (plane_state->hw.degamma_lut)
|
||||
drm_property_blob_put(plane_state->hw.degamma_lut);
|
||||
if (plane_state->hw.gamma_lut)
|
||||
drm_property_blob_put(plane_state->hw.gamma_lut);
|
||||
if (plane_state->hw.ctm)
|
||||
drm_property_blob_put(plane_state->hw.ctm);
|
||||
if (plane_state->hw.lut_3d)
|
||||
drm_property_blob_put(plane_state->hw.lut_3d);
|
||||
|
||||
memset(&plane_state->hw, 0, sizeof(plane_state->hw));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ static int exp_approx_q(int x)
|
|||
* dcss_scaler_gaussian_filter() - Generate gaussian prototype filter.
|
||||
* @fc_q: fixed-point cutoff frequency normalized to range [0, 1]
|
||||
* @use_5_taps: indicates whether to use 5 taps or 7 taps
|
||||
* @phase0_identity: whether to override phase 0 coefficients with identity filter
|
||||
* @coef: output filter coefficients
|
||||
*/
|
||||
static void dcss_scaler_gaussian_filter(int fc_q, bool use_5_taps,
|
||||
|
|
@ -262,7 +263,9 @@ static void dcss_scaler_nearest_neighbor_filter(bool use_5_taps,
|
|||
* @src_length: length of input
|
||||
* @dst_length: length of output
|
||||
* @use_5_taps: 0 for 7 taps per phase, 1 for 5 taps
|
||||
* @phase0_identity: whether to override phase 0 coefficients with identity filter
|
||||
* @coef: output coefficients
|
||||
* @nn_interpolation: whether to use nearest neighbor instead of gaussian filter
|
||||
*/
|
||||
static void dcss_scaler_filter_design(int src_length, int dst_length,
|
||||
bool use_5_taps, bool phase0_identity,
|
||||
|
|
|
|||
|
|
@ -213,6 +213,14 @@ v3d_clean_caches(struct v3d_dev *v3d)
|
|||
|
||||
trace_v3d_cache_clean_begin(dev);
|
||||
|
||||
/* GFXH-1897: Ensure pending flushes complete before writing L2TCACTL */
|
||||
if (v3d->ver < V3D_GEN_71) {
|
||||
if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) &
|
||||
V3D_L2TCACTL_L2TFLS), 100)) {
|
||||
drm_err(dev, "Timeout waiting for L2T clean\n");
|
||||
}
|
||||
}
|
||||
|
||||
V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_TMUWCF);
|
||||
if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) &
|
||||
V3D_L2TCACTL_TMUWCF), 100)) {
|
||||
|
|
|
|||
|
|
@ -309,8 +309,11 @@ static void v3d_perfmon_delete(struct v3d_file_priv *v3d_priv,
|
|||
if (perfmon == v3d->active_perfmon)
|
||||
v3d_perfmon_stop(v3d, perfmon, false);
|
||||
|
||||
/* If the global perfmon is being destroyed, set it to NULL */
|
||||
cmpxchg(&v3d->global_perfmon, perfmon, NULL);
|
||||
/* If the global perfmon is being destroyed, clean it and release
|
||||
* the reference stashed in v3d_perfmon_set_global_ioctl().
|
||||
*/
|
||||
if (cmpxchg(&v3d->global_perfmon, perfmon, NULL) == perfmon)
|
||||
v3d_perfmon_put(perfmon);
|
||||
|
||||
v3d_perfmon_put(perfmon);
|
||||
}
|
||||
|
|
@ -461,16 +464,27 @@ int v3d_perfmon_set_global_ioctl(struct drm_device *dev, void *data,
|
|||
|
||||
/* If the request is to clear the global performance monitor */
|
||||
if (req->flags & DRM_V3D_PERFMON_CLEAR_GLOBAL) {
|
||||
if (!v3d->global_perfmon)
|
||||
struct v3d_perfmon *old;
|
||||
|
||||
/* DRM_V3D_PERFMON_CLEAR_GLOBAL doesn't check if
|
||||
* v3d->global_perfmon == perfmon. Therefore, there
|
||||
* is no need to keep perfmon's reference.
|
||||
*/
|
||||
v3d_perfmon_put(perfmon);
|
||||
|
||||
old = xchg(&v3d->global_perfmon, NULL);
|
||||
if (!old)
|
||||
return -EINVAL;
|
||||
|
||||
xchg(&v3d->global_perfmon, NULL);
|
||||
v3d_perfmon_put(old);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cmpxchg(&v3d->global_perfmon, NULL, perfmon))
|
||||
if (cmpxchg(&v3d->global_perfmon, NULL, perfmon)) {
|
||||
v3d_perfmon_put(perfmon);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -352,6 +352,16 @@ v3d_csd_job_run(struct drm_sched_job *sched_job)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* The HW interprets a workgroup size of 0 as 65536; however, the
|
||||
* user-space driver exposes a maximum of 65535. Therefore, a 0 in
|
||||
* any dimension means that we have no workgroups and the compute
|
||||
* shader should not be dispatched.
|
||||
*/
|
||||
if (!V3D_GET_FIELD(job->args.cfg[0], V3D_CSD_QUEUED_CFG0_NUM_WGS_X) ||
|
||||
!V3D_GET_FIELD(job->args.cfg[1], V3D_CSD_QUEUED_CFG1_NUM_WGS_Y) ||
|
||||
!V3D_GET_FIELD(job->args.cfg[2], V3D_CSD_QUEUED_CFG2_NUM_WGS_Z))
|
||||
return NULL;
|
||||
|
||||
v3d->queue[V3D_CSD].active_job = &job->base;
|
||||
|
||||
v3d_invalidate_caches(v3d);
|
||||
|
|
@ -402,13 +412,13 @@ v3d_rewrite_csd_job_wg_counts_from_indirect(struct v3d_cpu_job *job)
|
|||
|
||||
wg_counts = (uint32_t *)(bo->vaddr + indirect_csd->offset);
|
||||
|
||||
if (wg_counts[0] == 0 || wg_counts[1] == 0 || wg_counts[2] == 0)
|
||||
return;
|
||||
|
||||
args->cfg[0] = wg_counts[0] << V3D_CSD_CFG012_WG_COUNT_SHIFT;
|
||||
args->cfg[1] = wg_counts[1] << V3D_CSD_CFG012_WG_COUNT_SHIFT;
|
||||
args->cfg[2] = wg_counts[2] << V3D_CSD_CFG012_WG_COUNT_SHIFT;
|
||||
|
||||
if (wg_counts[0] == 0 || wg_counts[1] == 0 || wg_counts[2] == 0)
|
||||
goto unmap_bo;
|
||||
|
||||
num_batches = DIV_ROUND_UP(indirect_csd->wg_size, 16) *
|
||||
(wg_counts[0] * wg_counts[1] * wg_counts[2]);
|
||||
|
||||
|
|
@ -428,6 +438,7 @@ v3d_rewrite_csd_job_wg_counts_from_indirect(struct v3d_cpu_job *job)
|
|||
}
|
||||
}
|
||||
|
||||
unmap_bo:
|
||||
v3d_put_bo_vaddr(indirect);
|
||||
v3d_put_bo_vaddr(bo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,21 +162,4 @@ int xe_exec_queue_contexts_hwsp_rebase(struct xe_exec_queue *q, void *scratch);
|
|||
struct xe_lrc *xe_exec_queue_lrc(struct xe_exec_queue *q);
|
||||
struct xe_lrc *xe_exec_queue_get_lrc(struct xe_exec_queue *q, u16 idx);
|
||||
|
||||
/**
|
||||
* xe_exec_queue_idle_skip_suspend() - Can exec queue skip suspend
|
||||
* @q: The exec_queue
|
||||
*
|
||||
* If an exec queue is not parallel and is idle, the suspend steps can be
|
||||
* skipped in the submission backend immediatley signaling the suspend fence.
|
||||
* Parallel queues cannot skip this step due to limitations in the submission
|
||||
* backend.
|
||||
*
|
||||
* Return: True if exec queue is idle and can skip suspend steps, False
|
||||
* otherwise
|
||||
*/
|
||||
static inline bool xe_exec_queue_idle_skip_suspend(struct xe_exec_queue *q)
|
||||
{
|
||||
return !xe_exec_queue_is_parallel(q) && xe_exec_queue_is_idle(q);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ exec_queue_to_guc(struct xe_exec_queue *q)
|
|||
#define EXEC_QUEUE_STATE_WEDGED (1 << 8)
|
||||
#define EXEC_QUEUE_STATE_BANNED (1 << 9)
|
||||
#define EXEC_QUEUE_STATE_PENDING_RESUME (1 << 10)
|
||||
#define EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND (1 << 11)
|
||||
|
||||
static bool exec_queue_registered(struct xe_exec_queue *q)
|
||||
{
|
||||
|
|
@ -218,21 +217,6 @@ static void clear_exec_queue_pending_resume(struct xe_exec_queue *q)
|
|||
atomic_and(~EXEC_QUEUE_STATE_PENDING_RESUME, &q->guc->state);
|
||||
}
|
||||
|
||||
static bool exec_queue_idle_skip_suspend(struct xe_exec_queue *q)
|
||||
{
|
||||
return atomic_read(&q->guc->state) & EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND;
|
||||
}
|
||||
|
||||
static void set_exec_queue_idle_skip_suspend(struct xe_exec_queue *q)
|
||||
{
|
||||
atomic_or(EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND, &q->guc->state);
|
||||
}
|
||||
|
||||
static void clear_exec_queue_idle_skip_suspend(struct xe_exec_queue *q)
|
||||
{
|
||||
atomic_and(~EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND, &q->guc->state);
|
||||
}
|
||||
|
||||
static bool exec_queue_killed_or_banned_or_wedged(struct xe_exec_queue *q)
|
||||
{
|
||||
return (atomic_read(&q->guc->state) &
|
||||
|
|
@ -1153,7 +1137,7 @@ static void submit_exec_queue(struct xe_exec_queue *q, struct xe_sched_job *job)
|
|||
if (!job->restore_replay || job->last_replay) {
|
||||
if (xe_exec_queue_is_parallel(q))
|
||||
wq_item_append(q);
|
||||
else if (!exec_queue_idle_skip_suspend(q))
|
||||
else
|
||||
xe_lrc_set_ring_tail(lrc, lrc->ring.tail);
|
||||
job->last_replay = false;
|
||||
}
|
||||
|
|
@ -1163,9 +1147,12 @@ static void submit_exec_queue(struct xe_exec_queue *q, struct xe_sched_job *job)
|
|||
|
||||
/*
|
||||
* All queues in a multi-queue group will use the primary queue
|
||||
* of the group to interface with GuC.
|
||||
* of the group to interface with GuC. If primay is suspended,
|
||||
* just return. Jobs will get scheduled once primary is resumed.
|
||||
*/
|
||||
q = xe_exec_queue_multi_queue_primary(q);
|
||||
if (exec_queue_suspended(q))
|
||||
return;
|
||||
|
||||
if (!exec_queue_enabled(q) && !exec_queue_suspended(q)) {
|
||||
action[len++] = XE_GUC_ACTION_SCHED_CONTEXT_MODE_SET;
|
||||
|
|
@ -1810,10 +1797,9 @@ static void __guc_exec_queue_process_msg_suspend(struct xe_sched_msg *msg)
|
|||
{
|
||||
struct xe_exec_queue *q = msg->private_data;
|
||||
struct xe_guc *guc = exec_queue_to_guc(q);
|
||||
bool idle_skip_suspend = xe_exec_queue_idle_skip_suspend(q);
|
||||
|
||||
if (!idle_skip_suspend && guc_exec_queue_allowed_to_change_state(q) &&
|
||||
!exec_queue_suspended(q) && exec_queue_enabled(q)) {
|
||||
if (guc_exec_queue_allowed_to_change_state(q) && !exec_queue_suspended(q) &&
|
||||
exec_queue_enabled(q)) {
|
||||
wait_event(guc->ct.wq, vf_recovery(guc) ||
|
||||
((q->guc->resume_time != RESUME_PENDING ||
|
||||
xe_guc_read_stopped(guc)) && !exec_queue_pending_disable(q)));
|
||||
|
|
@ -1832,33 +1818,11 @@ static void __guc_exec_queue_process_msg_suspend(struct xe_sched_msg *msg)
|
|||
disable_scheduling(q, false);
|
||||
}
|
||||
} else if (q->guc->suspend_pending) {
|
||||
if (idle_skip_suspend)
|
||||
set_exec_queue_idle_skip_suspend(q);
|
||||
set_exec_queue_suspended(q);
|
||||
suspend_fence_signal(q);
|
||||
}
|
||||
}
|
||||
|
||||
static void sched_context(struct xe_exec_queue *q)
|
||||
{
|
||||
struct xe_guc *guc = exec_queue_to_guc(q);
|
||||
struct xe_lrc *lrc = q->lrc[0];
|
||||
u32 action[] = {
|
||||
XE_GUC_ACTION_SCHED_CONTEXT,
|
||||
q->guc->id,
|
||||
};
|
||||
|
||||
xe_gt_assert(guc_to_gt(guc), !xe_exec_queue_is_parallel(q));
|
||||
xe_gt_assert(guc_to_gt(guc), !exec_queue_destroyed(q));
|
||||
xe_gt_assert(guc_to_gt(guc), exec_queue_registered(q));
|
||||
xe_gt_assert(guc_to_gt(guc), !exec_queue_pending_disable(q));
|
||||
|
||||
trace_xe_exec_queue_submit(q);
|
||||
|
||||
xe_lrc_set_ring_tail(lrc, lrc->ring.tail);
|
||||
xe_guc_ct_send(&guc->ct, action, ARRAY_SIZE(action), 0, 0);
|
||||
}
|
||||
|
||||
static void __guc_exec_queue_process_msg_resume(struct xe_sched_msg *msg)
|
||||
{
|
||||
struct xe_exec_queue *q = msg->private_data;
|
||||
|
|
@ -1866,22 +1830,12 @@ static void __guc_exec_queue_process_msg_resume(struct xe_sched_msg *msg)
|
|||
if (guc_exec_queue_allowed_to_change_state(q)) {
|
||||
clear_exec_queue_suspended(q);
|
||||
if (!exec_queue_enabled(q)) {
|
||||
if (exec_queue_idle_skip_suspend(q)) {
|
||||
struct xe_lrc *lrc = q->lrc[0];
|
||||
|
||||
clear_exec_queue_idle_skip_suspend(q);
|
||||
xe_lrc_set_ring_tail(lrc, lrc->ring.tail);
|
||||
}
|
||||
q->guc->resume_time = RESUME_PENDING;
|
||||
set_exec_queue_pending_resume(q);
|
||||
enable_scheduling(q);
|
||||
} else if (exec_queue_idle_skip_suspend(q)) {
|
||||
clear_exec_queue_idle_skip_suspend(q);
|
||||
sched_context(q);
|
||||
}
|
||||
} else {
|
||||
clear_exec_queue_suspended(q);
|
||||
clear_exec_queue_idle_skip_suspend(q);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2853,8 +2807,8 @@ static void handle_sched_done(struct xe_guc *guc, struct xe_exec_queue *q,
|
|||
xe_gt_assert(guc_to_gt(guc), exec_queue_pending_disable(q));
|
||||
|
||||
if (q->guc->suspend_pending) {
|
||||
suspend_fence_signal(q);
|
||||
clear_exec_queue_pending_disable(q);
|
||||
suspend_fence_signal(q);
|
||||
} else {
|
||||
if (exec_queue_banned(q)) {
|
||||
smp_wmb();
|
||||
|
|
|
|||
|
|
@ -208,21 +208,15 @@ static int xe_hw_engine_group_suspend_faulting_lr_jobs(struct xe_hw_engine_group
|
|||
lockdep_assert_held_write(&group->mode_sem);
|
||||
|
||||
list_for_each_entry(q, &group->exec_queue_list, hw_engine_group_link) {
|
||||
bool idle_skip_suspend;
|
||||
|
||||
if (!xe_vm_in_fault_mode(q->vm))
|
||||
continue;
|
||||
|
||||
idle_skip_suspend = xe_exec_queue_idle_skip_suspend(q);
|
||||
if (!idle_skip_suspend && has_deps)
|
||||
if (has_deps)
|
||||
return -EAGAIN;
|
||||
|
||||
xe_gt_stats_incr(q->gt, XE_GT_STATS_ID_HW_ENGINE_GROUP_SUSPEND_LR_QUEUE_COUNT, 1);
|
||||
if (idle_skip_suspend)
|
||||
xe_gt_stats_incr(q->gt,
|
||||
XE_GT_STATS_ID_HW_ENGINE_GROUP_SKIP_LR_QUEUE_COUNT, 1);
|
||||
|
||||
need_resume |= !idle_skip_suspend;
|
||||
need_resume = true;
|
||||
q->ops->suspend(q);
|
||||
gt = q->gt;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,6 @@ struct fw_blobs_by_type {
|
|||
#define XE_GT_TYPE_ANY XE_GT_TYPE_UNINITIALIZED
|
||||
|
||||
#define XE_GUC_FIRMWARE_DEFS(fw_def, mmp_ver, major_ver) \
|
||||
fw_def(NOVALAKE_S, GT_TYPE_ANY, mmp_ver(xe, guc, nvl, 70, 55, 4)) \
|
||||
fw_def(PANTHERLAKE, GT_TYPE_ANY, major_ver(xe, guc, ptl, 70, 54, 0)) \
|
||||
fw_def(BATTLEMAGE, GT_TYPE_ANY, major_ver(xe, guc, bmg, 70, 54, 0)) \
|
||||
fw_def(LUNARLAKE, GT_TYPE_ANY, major_ver(xe, guc, lnl, 70, 53, 0)) \
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user