mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Merge tag 'drm-fixes-2025-10-17' of https://gitlab.freedesktop.org/drm/kernel
Pull drm fixes from Dave Airlie:
"As per usual xe/amdgpu are the leaders, with some i915 and then a
bunch of scattered fixes. There are a bunch of stability fixes for
some older amdgpu cards.
draw:
- Avoid color truncation
gpuvm:
- Avoid kernel-doc warning
sched:
- Avoid double free
i915:
- Skip GuC communication warning if reset is in progress
- Couple frontbuffer related fixes
- Deactivate PSR only on LNL and when selective fetch enabled
xe:
- Increase global invalidation timeout to handle some workloads
- Fix NPD while evicting BOs in an array of VM binds
- Fix resizable BAR to account for possibly needing to move BARs
other than the LMEMBAR
- Fix error handling in xe_migrate_init()
- Fix atomic fault handling with mixed mappings or if the page is
already in VRAM
- Enable media samplers power gating for platforms before Xe2
- Fix de-registering exec queue from GuC when unbinding
- Ensure data migration to system if indicated by madvise with SVM
- Fix kerneldoc for kunit change
- Always account for cacheline alignment on migration
- Drop bogus assertion on eviction
amdgpu:
- Backlight fix
- SI fixes
- CIK fix
- Make CE support debug only
- IP discovery fix
- Ring reset fixes
- GPUVM fault memory barrier fix
- Drop unused structures in amdgpu_drm.h
- JPEG debugfs fix
- VRAM handling fixes for GPUs without VRAM
- GC 12 MES fixes
amdkfd:
- MES fix
ast:
- Fix display output after reboot
bridge:
- lt9211: Fix version check
panthor:
- Fix MCU suspend
qaic:
- Init bootlog in correct order
- Treat remaining == 0 as error in find_and_map_user_pages()
- Lock access to DBC request queue
rockchip:
- vop2: Fix destination size in atomic check"
* tag 'drm-fixes-2025-10-17' of https://gitlab.freedesktop.org/drm/kernel: (44 commits)
drm/sched: Fix potential double free in drm_sched_job_add_resv_dependencies
drm/xe/evict: drop bogus assert
drm/xe/migrate: don't misalign current bytes
drm/xe/kunit: Fix kerneldoc for parameterized tests
drm/xe/svm: Ensure data will be migrated to system if indicated by madvise.
drm/gpuvm: Fix kernel-doc warning for drm_gpuvm_map_req.map
drm/i915/psr: Deactivate PSR only on LNL and when selective fetch enabled
drm/ast: Blank with VGACR17 sync enable, always clear VGACRB6 sync off
accel/qaic: Synchronize access to DBC request queue head & tail pointer
accel/qaic: Treat remaining == 0 as error in find_and_map_user_pages()
accel/qaic: Fix bootlog initialization ordering
drm/rockchip: vop2: use correct destination rectangle height check
drm/draw: fix color truncation in drm_draw_fill24
drm/xe/guc: Check GuC running state before deregistering exec queue
drm/xe: Enable media sampler power gating
drm/xe: Handle mixed mappings and existing VRAM on atomic faults
drm/xe/migrate: Fix an error path
drm/xe: Move rebar to be done earlier
drm/xe: Don't allow evicting of BOs in same VM in array of VM binds
drm/xe: Increase global invalidation timeout to 1000us
...
This commit is contained in:
@@ -97,6 +97,8 @@ struct dma_bridge_chan {
|
||||
* response queue's head and tail pointer of this DBC.
|
||||
*/
|
||||
void __iomem *dbc_base;
|
||||
/* Synchronizes access to Request queue's head and tail pointer */
|
||||
struct mutex req_lock;
|
||||
/* Head of list where each node is a memory handle queued in request queue */
|
||||
struct list_head xfer_list;
|
||||
/* Synchronizes DBC readers during cleanup */
|
||||
|
||||
@@ -407,7 +407,7 @@ static int find_and_map_user_pages(struct qaic_device *qdev,
|
||||
return -EINVAL;
|
||||
remaining = in_trans->size - resources->xferred_dma_size;
|
||||
if (remaining == 0)
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
|
||||
if (check_add_overflow(xfer_start_addr, remaining, &end))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1356,13 +1356,17 @@ static int __qaic_execute_bo_ioctl(struct drm_device *dev, void *data, struct dr
|
||||
goto release_ch_rcu;
|
||||
}
|
||||
|
||||
ret = mutex_lock_interruptible(&dbc->req_lock);
|
||||
if (ret)
|
||||
goto release_ch_rcu;
|
||||
|
||||
head = readl(dbc->dbc_base + REQHP_OFF);
|
||||
tail = readl(dbc->dbc_base + REQTP_OFF);
|
||||
|
||||
if (head == U32_MAX || tail == U32_MAX) {
|
||||
/* PCI link error */
|
||||
ret = -ENODEV;
|
||||
goto release_ch_rcu;
|
||||
goto unlock_req_lock;
|
||||
}
|
||||
|
||||
queue_level = head <= tail ? tail - head : dbc->nelem - (head - tail);
|
||||
@@ -1370,11 +1374,12 @@ static int __qaic_execute_bo_ioctl(struct drm_device *dev, void *data, struct dr
|
||||
ret = send_bo_list_to_device(qdev, file_priv, exec, args->hdr.count, is_partial, dbc,
|
||||
head, &tail);
|
||||
if (ret)
|
||||
goto release_ch_rcu;
|
||||
goto unlock_req_lock;
|
||||
|
||||
/* Finalize commit to hardware */
|
||||
submit_ts = ktime_get_ns();
|
||||
writel(tail, dbc->dbc_base + REQTP_OFF);
|
||||
mutex_unlock(&dbc->req_lock);
|
||||
|
||||
update_profiling_data(file_priv, exec, args->hdr.count, is_partial, received_ts,
|
||||
submit_ts, queue_level);
|
||||
@@ -1382,6 +1387,9 @@ static int __qaic_execute_bo_ioctl(struct drm_device *dev, void *data, struct dr
|
||||
if (datapath_polling)
|
||||
schedule_work(&dbc->poll_work);
|
||||
|
||||
unlock_req_lock:
|
||||
if (ret)
|
||||
mutex_unlock(&dbc->req_lock);
|
||||
release_ch_rcu:
|
||||
srcu_read_unlock(&dbc->ch_lock, rcu_id);
|
||||
unlock_dev_srcu:
|
||||
|
||||
@@ -218,6 +218,9 @@ static int qaic_bootlog_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_d
|
||||
if (ret)
|
||||
goto destroy_workqueue;
|
||||
|
||||
dev_set_drvdata(&mhi_dev->dev, qdev);
|
||||
qdev->bootlog_ch = mhi_dev;
|
||||
|
||||
for (i = 0; i < BOOTLOG_POOL_SIZE; i++) {
|
||||
msg = devm_kzalloc(&qdev->pdev->dev, sizeof(*msg), GFP_KERNEL);
|
||||
if (!msg) {
|
||||
@@ -233,8 +236,6 @@ static int qaic_bootlog_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_d
|
||||
goto mhi_unprepare;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&mhi_dev->dev, qdev);
|
||||
qdev->bootlog_ch = mhi_dev;
|
||||
return 0;
|
||||
|
||||
mhi_unprepare:
|
||||
|
||||
@@ -454,6 +454,9 @@ static struct qaic_device *create_qdev(struct pci_dev *pdev,
|
||||
return NULL;
|
||||
init_waitqueue_head(&qdev->dbc[i].dbc_release);
|
||||
INIT_LIST_HEAD(&qdev->dbc[i].bo_lists);
|
||||
ret = drmm_mutex_init(drm, &qdev->dbc[i].req_lock);
|
||||
if (ret)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return qdev;
|
||||
|
||||
@@ -1290,6 +1290,7 @@ struct amdgpu_device {
|
||||
bool debug_disable_gpu_ring_reset;
|
||||
bool debug_vm_userptr;
|
||||
bool debug_disable_ce_logs;
|
||||
bool debug_enable_ce_cs;
|
||||
|
||||
/* Protection for the following isolation structure */
|
||||
struct mutex enforce_isolation_mutex;
|
||||
|
||||
@@ -2329,10 +2329,9 @@ void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_mem *mem)
|
||||
int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev,
|
||||
struct kfd_vm_fault_info *mem)
|
||||
{
|
||||
if (atomic_read(&adev->gmc.vm_fault_info_updated) == 1) {
|
||||
if (atomic_read_acquire(&adev->gmc.vm_fault_info_updated) == 1) {
|
||||
*mem = *adev->gmc.vm_fault_info;
|
||||
mb(); /* make sure read happened */
|
||||
atomic_set(&adev->gmc.vm_fault_info_updated, 0);
|
||||
atomic_set_release(&adev->gmc.vm_fault_info_updated, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -364,6 +364,12 @@ static int amdgpu_cs_p2_ib(struct amdgpu_cs_parser *p,
|
||||
if (p->uf_bo && ring->funcs->no_user_fence)
|
||||
return -EINVAL;
|
||||
|
||||
if (!p->adev->debug_enable_ce_cs &&
|
||||
chunk_ib->flags & AMDGPU_IB_FLAG_CE) {
|
||||
dev_err_ratelimited(p->adev->dev, "CE CS is blocked, use debug=0x400 to override\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (chunk_ib->ip_type == AMDGPU_HW_IP_GFX &&
|
||||
chunk_ib->flags & AMDGPU_IB_FLAG_PREEMPT) {
|
||||
if (chunk_ib->flags & AMDGPU_IB_FLAG_CE)
|
||||
@@ -702,7 +708,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev,
|
||||
*/
|
||||
const s64 us_upper_bound = 200000;
|
||||
|
||||
if (!adev->mm_stats.log2_max_MBps) {
|
||||
if ((!adev->mm_stats.log2_max_MBps) || !ttm_resource_manager_used(&adev->mman.vram_mgr.manager)) {
|
||||
*max_bytes = 0;
|
||||
*max_vis_bytes = 0;
|
||||
return;
|
||||
|
||||
@@ -1882,6 +1882,13 @@ static bool amdgpu_device_pcie_dynamic_switching_supported(struct amdgpu_device
|
||||
|
||||
static bool amdgpu_device_aspm_support_quirk(struct amdgpu_device *adev)
|
||||
{
|
||||
/* Enabling ASPM causes randoms hangs on Tahiti and Oland on Zen4.
|
||||
* It's unclear if this is a platform-specific or GPU-specific issue.
|
||||
* Disable ASPM on SI for the time being.
|
||||
*/
|
||||
if (adev->family == AMDGPU_FAMILY_SI)
|
||||
return true;
|
||||
|
||||
#if IS_ENABLED(CONFIG_X86)
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
|
||||
@@ -1033,7 +1033,9 @@ static uint8_t amdgpu_discovery_get_harvest_info(struct amdgpu_device *adev,
|
||||
/* Until a uniform way is figured, get mask based on hwid */
|
||||
switch (hw_id) {
|
||||
case VCN_HWID:
|
||||
harvest = ((1 << inst) & adev->vcn.inst_mask) == 0;
|
||||
/* VCN vs UVD+VCE */
|
||||
if (!amdgpu_ip_version(adev, VCE_HWIP, 0))
|
||||
harvest = ((1 << inst) & adev->vcn.inst_mask) == 0;
|
||||
break;
|
||||
case DMU_HWID:
|
||||
if (adev->harvest_ip_mask & AMD_HARVEST_IP_DMU_MASK)
|
||||
@@ -2565,7 +2567,9 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_discovery_init(adev);
|
||||
vega10_reg_base_init(adev);
|
||||
adev->sdma.num_instances = 2;
|
||||
adev->sdma.sdma_mask = 3;
|
||||
adev->gmc.num_umc = 4;
|
||||
adev->gfx.xcc_mask = 1;
|
||||
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 0, 0);
|
||||
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 0, 0);
|
||||
adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 0, 0);
|
||||
@@ -2592,7 +2596,9 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_discovery_init(adev);
|
||||
vega10_reg_base_init(adev);
|
||||
adev->sdma.num_instances = 2;
|
||||
adev->sdma.sdma_mask = 3;
|
||||
adev->gmc.num_umc = 4;
|
||||
adev->gfx.xcc_mask = 1;
|
||||
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 3, 0);
|
||||
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 3, 0);
|
||||
adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 0, 1);
|
||||
@@ -2619,8 +2625,10 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_discovery_init(adev);
|
||||
vega10_reg_base_init(adev);
|
||||
adev->sdma.num_instances = 1;
|
||||
adev->sdma.sdma_mask = 1;
|
||||
adev->vcn.num_vcn_inst = 1;
|
||||
adev->gmc.num_umc = 2;
|
||||
adev->gfx.xcc_mask = 1;
|
||||
if (adev->apu_flags & AMD_APU_IS_RAVEN2) {
|
||||
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 2, 0);
|
||||
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 2, 0);
|
||||
@@ -2665,7 +2673,9 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_discovery_init(adev);
|
||||
vega20_reg_base_init(adev);
|
||||
adev->sdma.num_instances = 2;
|
||||
adev->sdma.sdma_mask = 3;
|
||||
adev->gmc.num_umc = 8;
|
||||
adev->gfx.xcc_mask = 1;
|
||||
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 0);
|
||||
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 0);
|
||||
adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 2, 0);
|
||||
@@ -2693,8 +2703,10 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_discovery_init(adev);
|
||||
arct_reg_base_init(adev);
|
||||
adev->sdma.num_instances = 8;
|
||||
adev->sdma.sdma_mask = 0xff;
|
||||
adev->vcn.num_vcn_inst = 2;
|
||||
adev->gmc.num_umc = 8;
|
||||
adev->gfx.xcc_mask = 1;
|
||||
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 1);
|
||||
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 1);
|
||||
adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 2, 1);
|
||||
@@ -2726,8 +2738,10 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_discovery_init(adev);
|
||||
aldebaran_reg_base_init(adev);
|
||||
adev->sdma.num_instances = 5;
|
||||
adev->sdma.sdma_mask = 0x1f;
|
||||
adev->vcn.num_vcn_inst = 2;
|
||||
adev->gmc.num_umc = 4;
|
||||
adev->gfx.xcc_mask = 1;
|
||||
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 2);
|
||||
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 2);
|
||||
adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 4, 0);
|
||||
@@ -2762,6 +2776,8 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
} else {
|
||||
cyan_skillfish_reg_base_init(adev);
|
||||
adev->sdma.num_instances = 2;
|
||||
adev->sdma.sdma_mask = 3;
|
||||
adev->gfx.xcc_mask = 1;
|
||||
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(2, 0, 3);
|
||||
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(2, 0, 3);
|
||||
adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(5, 0, 1);
|
||||
|
||||
@@ -144,7 +144,8 @@ enum AMDGPU_DEBUG_MASK {
|
||||
AMDGPU_DEBUG_DISABLE_GPU_RING_RESET = BIT(6),
|
||||
AMDGPU_DEBUG_SMU_POOL = BIT(7),
|
||||
AMDGPU_DEBUG_VM_USERPTR = BIT(8),
|
||||
AMDGPU_DEBUG_DISABLE_RAS_CE_LOG = BIT(9)
|
||||
AMDGPU_DEBUG_DISABLE_RAS_CE_LOG = BIT(9),
|
||||
AMDGPU_DEBUG_ENABLE_CE_CS = BIT(10)
|
||||
};
|
||||
|
||||
unsigned int amdgpu_vram_limit = UINT_MAX;
|
||||
@@ -2289,6 +2290,11 @@ static void amdgpu_init_debug_options(struct amdgpu_device *adev)
|
||||
pr_info("debug: disable kernel logs of correctable errors\n");
|
||||
adev->debug_disable_ce_logs = true;
|
||||
}
|
||||
|
||||
if (amdgpu_debug_mask & AMDGPU_DEBUG_ENABLE_CE_CS) {
|
||||
pr_info("debug: allowing command submission to CE engine\n");
|
||||
adev->debug_enable_ce_cs = true;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long amdgpu_fix_asic_type(struct pci_dev *pdev, unsigned long flags)
|
||||
|
||||
@@ -758,11 +758,42 @@ void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring)
|
||||
* @fence: fence of the ring to signal
|
||||
*
|
||||
*/
|
||||
void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *fence)
|
||||
void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *af)
|
||||
{
|
||||
dma_fence_set_error(&fence->base, -ETIME);
|
||||
amdgpu_fence_write(fence->ring, fence->seq);
|
||||
amdgpu_fence_process(fence->ring);
|
||||
struct dma_fence *unprocessed;
|
||||
struct dma_fence __rcu **ptr;
|
||||
struct amdgpu_fence *fence;
|
||||
struct amdgpu_ring *ring = af->ring;
|
||||
unsigned long flags;
|
||||
u32 seq, last_seq;
|
||||
|
||||
last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
|
||||
seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
|
||||
|
||||
/* mark all fences from the guilty context with an error */
|
||||
spin_lock_irqsave(&ring->fence_drv.lock, flags);
|
||||
do {
|
||||
last_seq++;
|
||||
last_seq &= ring->fence_drv.num_fences_mask;
|
||||
|
||||
ptr = &ring->fence_drv.fences[last_seq];
|
||||
rcu_read_lock();
|
||||
unprocessed = rcu_dereference(*ptr);
|
||||
|
||||
if (unprocessed && !dma_fence_is_signaled_locked(unprocessed)) {
|
||||
fence = container_of(unprocessed, struct amdgpu_fence, base);
|
||||
|
||||
if (fence == af)
|
||||
dma_fence_set_error(&fence->base, -ETIME);
|
||||
else if (fence->context == af->context)
|
||||
dma_fence_set_error(&fence->base, -ECANCELED);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
} while (last_seq != seq);
|
||||
spin_unlock_irqrestore(&ring->fence_drv.lock, flags);
|
||||
/* signal the guilty fence */
|
||||
amdgpu_fence_write(ring, af->seq);
|
||||
amdgpu_fence_process(ring);
|
||||
}
|
||||
|
||||
void amdgpu_fence_save_wptr(struct dma_fence *fence)
|
||||
@@ -790,14 +821,19 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
|
||||
struct dma_fence *unprocessed;
|
||||
struct dma_fence __rcu **ptr;
|
||||
struct amdgpu_fence *fence;
|
||||
u64 wptr, i, seqno;
|
||||
u64 wptr;
|
||||
u32 seq, last_seq;
|
||||
|
||||
seqno = amdgpu_fence_read(ring);
|
||||
last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
|
||||
seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
|
||||
wptr = ring->fence_drv.signalled_wptr;
|
||||
ring->ring_backup_entries_to_copy = 0;
|
||||
|
||||
for (i = seqno + 1; i <= ring->fence_drv.sync_seq; ++i) {
|
||||
ptr = &ring->fence_drv.fences[i & ring->fence_drv.num_fences_mask];
|
||||
do {
|
||||
last_seq++;
|
||||
last_seq &= ring->fence_drv.num_fences_mask;
|
||||
|
||||
ptr = &ring->fence_drv.fences[last_seq];
|
||||
rcu_read_lock();
|
||||
unprocessed = rcu_dereference(*ptr);
|
||||
|
||||
@@ -813,7 +849,7 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
|
||||
wptr = fence->wptr;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
} while (last_seq != seq);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -371,7 +371,7 @@ static int amdgpu_debugfs_jpeg_sched_mask_set(void *data, u64 val)
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
|
||||
ring = &adev->jpeg.inst[i].ring_dec[j];
|
||||
if (val & (BIT_ULL(1) << ((i * adev->jpeg.num_jpeg_rings) + j)))
|
||||
if (val & (BIT_ULL((i * adev->jpeg.num_jpeg_rings) + j)))
|
||||
ring->sched.ready = true;
|
||||
else
|
||||
ring->sched.ready = false;
|
||||
|
||||
@@ -758,7 +758,8 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
ui64 = atomic64_read(&adev->num_vram_cpu_page_faults);
|
||||
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
|
||||
case AMDGPU_INFO_VRAM_USAGE:
|
||||
ui64 = ttm_resource_manager_usage(&adev->mman.vram_mgr.manager);
|
||||
ui64 = ttm_resource_manager_used(&adev->mman.vram_mgr.manager) ?
|
||||
ttm_resource_manager_usage(&adev->mman.vram_mgr.manager) : 0;
|
||||
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
|
||||
case AMDGPU_INFO_VIS_VRAM_USAGE:
|
||||
ui64 = amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr);
|
||||
@@ -804,8 +805,8 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
mem.vram.usable_heap_size = adev->gmc.real_vram_size -
|
||||
atomic64_read(&adev->vram_pin_size) -
|
||||
AMDGPU_VM_RESERVED_VRAM;
|
||||
mem.vram.heap_usage =
|
||||
ttm_resource_manager_usage(vram_man);
|
||||
mem.vram.heap_usage = ttm_resource_manager_used(&adev->mman.vram_mgr.manager) ?
|
||||
ttm_resource_manager_usage(vram_man) : 0;
|
||||
mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4;
|
||||
|
||||
mem.cpu_accessible_vram.total_heap_size =
|
||||
|
||||
@@ -409,7 +409,7 @@ int amdgpu_mes_detect_and_reset_hung_queues(struct amdgpu_device *adev,
|
||||
return -EINVAL;
|
||||
|
||||
/* Clear the doorbell array before detection */
|
||||
memset(adev->mes.hung_queue_db_array_cpu_addr, 0,
|
||||
memset(adev->mes.hung_queue_db_array_cpu_addr, AMDGPU_MES_INVALID_DB_OFFSET,
|
||||
adev->mes.hung_queue_db_array_size * sizeof(u32));
|
||||
input.queue_type = queue_type;
|
||||
input.detect_only = detect_only;
|
||||
@@ -420,12 +420,17 @@ int amdgpu_mes_detect_and_reset_hung_queues(struct amdgpu_device *adev,
|
||||
dev_err(adev->dev, "failed to detect and reset\n");
|
||||
} else {
|
||||
*hung_db_num = 0;
|
||||
for (i = 0; i < adev->mes.hung_queue_db_array_size; i++) {
|
||||
for (i = 0; i < adev->mes.hung_queue_hqd_info_offset; i++) {
|
||||
if (db_array[i] != AMDGPU_MES_INVALID_DB_OFFSET) {
|
||||
hung_db_array[i] = db_array[i];
|
||||
*hung_db_num += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: return HQD info for MES scheduled user compute queue reset cases
|
||||
* stored in hung_db_array hqd info offset to full array size
|
||||
*/
|
||||
}
|
||||
|
||||
return r;
|
||||
@@ -686,14 +691,11 @@ out:
|
||||
bool amdgpu_mes_suspend_resume_all_supported(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t mes_rev = adev->mes.sched_version & AMDGPU_MES_VERSION_MASK;
|
||||
bool is_supported = false;
|
||||
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(11, 0, 0) &&
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(12, 0, 0) &&
|
||||
mes_rev >= 0x63)
|
||||
is_supported = true;
|
||||
|
||||
return is_supported;
|
||||
return ((amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(11, 0, 0) &&
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(12, 0, 0) &&
|
||||
mes_rev >= 0x63) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 0, 0));
|
||||
}
|
||||
|
||||
/* Fix me -- node_id is used to identify the correct MES instances in the future */
|
||||
|
||||
@@ -149,6 +149,7 @@ struct amdgpu_mes {
|
||||
void *resource_1_addr[AMDGPU_MAX_MES_PIPES];
|
||||
|
||||
int hung_queue_db_array_size;
|
||||
int hung_queue_hqd_info_offset;
|
||||
struct amdgpu_bo *hung_queue_db_array_gpu_obj;
|
||||
uint64_t hung_queue_db_array_gpu_addr;
|
||||
void *hung_queue_db_array_cpu_addr;
|
||||
|
||||
@@ -811,7 +811,7 @@ int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring,
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* signal the fence of the bad job */
|
||||
/* signal the guilty fence and set an error on all fences from the context */
|
||||
if (guilty_fence)
|
||||
amdgpu_fence_driver_guilty_force_completion(guilty_fence);
|
||||
/* Re-emit the non-guilty commands */
|
||||
|
||||
@@ -155,7 +155,7 @@ extern const struct drm_sched_backend_ops amdgpu_sched_ops;
|
||||
void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring);
|
||||
void amdgpu_fence_driver_set_error(struct amdgpu_ring *ring, int error);
|
||||
void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);
|
||||
void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *fence);
|
||||
void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *af);
|
||||
void amdgpu_fence_save_wptr(struct dma_fence *fence);
|
||||
|
||||
int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
|
||||
|
||||
@@ -598,8 +598,8 @@ static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev)
|
||||
vf2pf_info->driver_cert = 0;
|
||||
vf2pf_info->os_info.all = 0;
|
||||
|
||||
vf2pf_info->fb_usage =
|
||||
ttm_resource_manager_usage(&adev->mman.vram_mgr.manager) >> 20;
|
||||
vf2pf_info->fb_usage = ttm_resource_manager_used(&adev->mman.vram_mgr.manager) ?
|
||||
ttm_resource_manager_usage(&adev->mman.vram_mgr.manager) >> 20 : 0;
|
||||
vf2pf_info->fb_vis_usage =
|
||||
amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr) >> 20;
|
||||
vf2pf_info->fb_size = adev->gmc.real_vram_size >> 20;
|
||||
|
||||
@@ -234,6 +234,9 @@ static umode_t amdgpu_vram_attrs_is_visible(struct kobject *kobj,
|
||||
!adev->gmc.vram_vendor)
|
||||
return 0;
|
||||
|
||||
if (!ttm_resource_manager_used(&adev->mman.vram_mgr.manager))
|
||||
return 0;
|
||||
|
||||
return attr->mode;
|
||||
}
|
||||
|
||||
|
||||
@@ -5862,8 +5862,6 @@ static void gfx_v11_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
||||
unsigned vmid = AMDGPU_JOB_GET_VMID(job);
|
||||
u32 header, control = 0;
|
||||
|
||||
BUG_ON(ib->flags & AMDGPU_IB_FLAG_CE);
|
||||
|
||||
header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
|
||||
|
||||
control |= ib->length_dw | (vmid << 24);
|
||||
|
||||
@@ -4419,8 +4419,6 @@ static void gfx_v12_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
||||
unsigned vmid = AMDGPU_JOB_GET_VMID(job);
|
||||
u32 header, control = 0;
|
||||
|
||||
BUG_ON(ib->flags & AMDGPU_IB_FLAG_CE);
|
||||
|
||||
header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
|
||||
|
||||
control |= ib->length_dw | (vmid << 24);
|
||||
|
||||
@@ -1068,7 +1068,7 @@ static int gmc_v7_0_sw_init(struct amdgpu_ip_block *ip_block)
|
||||
GFP_KERNEL);
|
||||
if (!adev->gmc.vm_fault_info)
|
||||
return -ENOMEM;
|
||||
atomic_set(&adev->gmc.vm_fault_info_updated, 0);
|
||||
atomic_set_release(&adev->gmc.vm_fault_info_updated, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1290,7 +1290,7 @@ static int gmc_v7_0_process_interrupt(struct amdgpu_device *adev,
|
||||
vmid = REG_GET_FIELD(status, VM_CONTEXT1_PROTECTION_FAULT_STATUS,
|
||||
VMID);
|
||||
if (amdgpu_amdkfd_is_kfd_vmid(adev, vmid)
|
||||
&& !atomic_read(&adev->gmc.vm_fault_info_updated)) {
|
||||
&& !atomic_read_acquire(&adev->gmc.vm_fault_info_updated)) {
|
||||
struct kfd_vm_fault_info *info = adev->gmc.vm_fault_info;
|
||||
u32 protections = REG_GET_FIELD(status,
|
||||
VM_CONTEXT1_PROTECTION_FAULT_STATUS,
|
||||
@@ -1306,8 +1306,7 @@ static int gmc_v7_0_process_interrupt(struct amdgpu_device *adev,
|
||||
info->prot_read = protections & 0x8 ? true : false;
|
||||
info->prot_write = protections & 0x10 ? true : false;
|
||||
info->prot_exec = protections & 0x20 ? true : false;
|
||||
mb();
|
||||
atomic_set(&adev->gmc.vm_fault_info_updated, 1);
|
||||
atomic_set_release(&adev->gmc.vm_fault_info_updated, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1183,7 +1183,7 @@ static int gmc_v8_0_sw_init(struct amdgpu_ip_block *ip_block)
|
||||
GFP_KERNEL);
|
||||
if (!adev->gmc.vm_fault_info)
|
||||
return -ENOMEM;
|
||||
atomic_set(&adev->gmc.vm_fault_info_updated, 0);
|
||||
atomic_set_release(&adev->gmc.vm_fault_info_updated, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1478,7 +1478,7 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev,
|
||||
vmid = REG_GET_FIELD(status, VM_CONTEXT1_PROTECTION_FAULT_STATUS,
|
||||
VMID);
|
||||
if (amdgpu_amdkfd_is_kfd_vmid(adev, vmid)
|
||||
&& !atomic_read(&adev->gmc.vm_fault_info_updated)) {
|
||||
&& !atomic_read_acquire(&adev->gmc.vm_fault_info_updated)) {
|
||||
struct kfd_vm_fault_info *info = adev->gmc.vm_fault_info;
|
||||
u32 protections = REG_GET_FIELD(status,
|
||||
VM_CONTEXT1_PROTECTION_FAULT_STATUS,
|
||||
@@ -1494,8 +1494,7 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev,
|
||||
info->prot_read = protections & 0x8 ? true : false;
|
||||
info->prot_write = protections & 0x10 ? true : false;
|
||||
info->prot_exec = protections & 0x20 ? true : false;
|
||||
mb();
|
||||
atomic_set(&adev->gmc.vm_fault_info_updated, 1);
|
||||
atomic_set_release(&adev->gmc.vm_fault_info_updated, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -208,10 +208,10 @@ static int mes_userq_detect_and_reset(struct amdgpu_device *adev,
|
||||
struct amdgpu_userq_mgr *uqm, *tmp;
|
||||
unsigned int hung_db_num = 0;
|
||||
int queue_id, r, i;
|
||||
u32 db_array[4];
|
||||
u32 db_array[8];
|
||||
|
||||
if (db_array_size > 4) {
|
||||
dev_err(adev->dev, "DB array size (%d vs 4) too small\n",
|
||||
if (db_array_size > 8) {
|
||||
dev_err(adev->dev, "DB array size (%d vs 8) too small\n",
|
||||
db_array_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,8 @@ static int mes_v11_0_kiq_hw_fini(struct amdgpu_device *adev);
|
||||
#define GFX_MES_DRAM_SIZE 0x80000
|
||||
#define MES11_HW_RESOURCE_1_SIZE (128 * AMDGPU_GPU_PAGE_SIZE)
|
||||
|
||||
#define MES11_HUNG_DB_OFFSET_ARRAY_SIZE 4
|
||||
#define MES11_HUNG_DB_OFFSET_ARRAY_SIZE 8 /* [0:3] = db offset, [4:7] = hqd info */
|
||||
#define MES11_HUNG_HQD_INFO_OFFSET 4
|
||||
|
||||
static void mes_v11_0_ring_set_wptr(struct amdgpu_ring *ring)
|
||||
{
|
||||
@@ -1720,8 +1721,9 @@ static int mes_v11_0_early_init(struct amdgpu_ip_block *ip_block)
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
int pipe, r;
|
||||
|
||||
adev->mes.hung_queue_db_array_size =
|
||||
MES11_HUNG_DB_OFFSET_ARRAY_SIZE;
|
||||
adev->mes.hung_queue_db_array_size = MES11_HUNG_DB_OFFSET_ARRAY_SIZE;
|
||||
adev->mes.hung_queue_hqd_info_offset = MES11_HUNG_HQD_INFO_OFFSET;
|
||||
|
||||
for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) {
|
||||
if (!adev->enable_mes_kiq && pipe == AMDGPU_MES_KIQ_PIPE)
|
||||
continue;
|
||||
|
||||
@@ -47,7 +47,8 @@ static int mes_v12_0_kiq_hw_fini(struct amdgpu_device *adev);
|
||||
|
||||
#define MES_EOP_SIZE 2048
|
||||
|
||||
#define MES12_HUNG_DB_OFFSET_ARRAY_SIZE 4
|
||||
#define MES12_HUNG_DB_OFFSET_ARRAY_SIZE 8 /* [0:3] = db offset [4:7] hqd info */
|
||||
#define MES12_HUNG_HQD_INFO_OFFSET 4
|
||||
|
||||
static void mes_v12_0_ring_set_wptr(struct amdgpu_ring *ring)
|
||||
{
|
||||
@@ -228,7 +229,12 @@ static int mes_v12_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
||||
pipe, x_pkt->header.opcode);
|
||||
|
||||
r = amdgpu_fence_wait_polling(ring, seq, timeout);
|
||||
if (r < 1 || !*status_ptr) {
|
||||
|
||||
/*
|
||||
* status_ptr[31:0] == 0 (fail) or status_ptr[63:0] == 1 (success).
|
||||
* If status_ptr[31:0] == 0 then status_ptr[63:32] will have debug error information.
|
||||
*/
|
||||
if (r < 1 || !(lower_32_bits(*status_ptr))) {
|
||||
|
||||
if (misc_op_str)
|
||||
dev_err(adev->dev, "MES(%d) failed to respond to msg=%s (%s)\n",
|
||||
@@ -1899,8 +1905,9 @@ static int mes_v12_0_early_init(struct amdgpu_ip_block *ip_block)
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
int pipe, r;
|
||||
|
||||
adev->mes.hung_queue_db_array_size =
|
||||
MES12_HUNG_DB_OFFSET_ARRAY_SIZE;
|
||||
adev->mes.hung_queue_db_array_size = MES12_HUNG_DB_OFFSET_ARRAY_SIZE;
|
||||
adev->mes.hung_queue_hqd_info_offset = MES12_HUNG_HQD_INFO_OFFSET;
|
||||
|
||||
for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) {
|
||||
r = amdgpu_mes_init_microcode(adev, pipe);
|
||||
if (r)
|
||||
|
||||
@@ -1209,6 +1209,15 @@ static int evict_process_queues_cpsch(struct device_queue_manager *dqm,
|
||||
pr_debug_ratelimited("Evicting process pid %d queues\n",
|
||||
pdd->process->lead_thread->pid);
|
||||
|
||||
if (dqm->dev->kfd->shared_resources.enable_mes) {
|
||||
pdd->last_evict_timestamp = get_jiffies_64();
|
||||
retval = suspend_all_queues_mes(dqm);
|
||||
if (retval) {
|
||||
dev_err(dev, "Suspending all queues failed");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark all queues as evicted. Deactivate all active queues on
|
||||
* the qpd.
|
||||
*/
|
||||
@@ -1221,23 +1230,27 @@ static int evict_process_queues_cpsch(struct device_queue_manager *dqm,
|
||||
decrement_queue_count(dqm, qpd, q);
|
||||
|
||||
if (dqm->dev->kfd->shared_resources.enable_mes) {
|
||||
int err;
|
||||
|
||||
err = remove_queue_mes(dqm, q, qpd);
|
||||
if (err) {
|
||||
retval = remove_queue_mes(dqm, q, qpd);
|
||||
if (retval) {
|
||||
dev_err(dev, "Failed to evict queue %d\n",
|
||||
q->properties.queue_id);
|
||||
retval = err;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
pdd->last_evict_timestamp = get_jiffies_64();
|
||||
if (!dqm->dev->kfd->shared_resources.enable_mes)
|
||||
|
||||
if (!dqm->dev->kfd->shared_resources.enable_mes) {
|
||||
pdd->last_evict_timestamp = get_jiffies_64();
|
||||
retval = execute_queues_cpsch(dqm,
|
||||
qpd->is_debug ?
|
||||
KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES :
|
||||
KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0,
|
||||
USE_DEFAULT_GRACE_PERIOD);
|
||||
} else {
|
||||
retval = resume_all_queues_mes(dqm);
|
||||
if (retval)
|
||||
dev_err(dev, "Resuming all queues failed");
|
||||
}
|
||||
|
||||
out:
|
||||
dqm_unlock(dqm);
|
||||
@@ -3098,61 +3111,17 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int kfd_dqm_evict_pasid_mes(struct device_queue_manager *dqm,
|
||||
struct qcm_process_device *qpd)
|
||||
{
|
||||
struct device *dev = dqm->dev->adev->dev;
|
||||
int ret = 0;
|
||||
|
||||
/* Check if process is already evicted */
|
||||
dqm_lock(dqm);
|
||||
if (qpd->evicted) {
|
||||
/* Increment the evicted count to make sure the
|
||||
* process stays evicted before its terminated.
|
||||
*/
|
||||
qpd->evicted++;
|
||||
dqm_unlock(dqm);
|
||||
goto out;
|
||||
}
|
||||
dqm_unlock(dqm);
|
||||
|
||||
ret = suspend_all_queues_mes(dqm);
|
||||
if (ret) {
|
||||
dev_err(dev, "Suspending all queues failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = dqm->ops.evict_process_queues(dqm, qpd);
|
||||
if (ret) {
|
||||
dev_err(dev, "Evicting process queues failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = resume_all_queues_mes(dqm);
|
||||
if (ret)
|
||||
dev_err(dev, "Resuming all queues failed");
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kfd_evict_process_device(struct kfd_process_device *pdd)
|
||||
{
|
||||
struct device_queue_manager *dqm;
|
||||
struct kfd_process *p;
|
||||
int ret = 0;
|
||||
|
||||
p = pdd->process;
|
||||
dqm = pdd->dev->dqm;
|
||||
|
||||
WARN(debug_evictions, "Evicting pid %d", p->lead_thread->pid);
|
||||
|
||||
if (dqm->dev->kfd->shared_resources.enable_mes)
|
||||
ret = kfd_dqm_evict_pasid_mes(dqm, &pdd->qpd);
|
||||
else
|
||||
ret = dqm->ops.evict_process_queues(dqm, &pdd->qpd);
|
||||
|
||||
return ret;
|
||||
return dqm->ops.evict_process_queues(dqm, &pdd->qpd);
|
||||
}
|
||||
|
||||
int reserve_debug_trap_vmid(struct device_queue_manager *dqm,
|
||||
|
||||
@@ -2085,8 +2085,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
||||
|
||||
dc_hardware_init(adev->dm.dc);
|
||||
|
||||
adev->dm.restore_backlight = true;
|
||||
|
||||
adev->dm.hpd_rx_offload_wq = hpd_rx_irq_create_workqueue(adev);
|
||||
if (!adev->dm.hpd_rx_offload_wq) {
|
||||
drm_err(adev_to_drm(adev), "failed to create hpd rx offload workqueue.\n");
|
||||
@@ -3442,7 +3440,6 @@ static int dm_resume(struct amdgpu_ip_block *ip_block)
|
||||
dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);
|
||||
|
||||
dc_resume(dm->dc);
|
||||
adev->dm.restore_backlight = true;
|
||||
|
||||
amdgpu_dm_irq_resume_early(adev);
|
||||
|
||||
@@ -9969,6 +9966,7 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
|
||||
bool mode_set_reset_required = false;
|
||||
u32 i;
|
||||
struct dc_commit_streams_params params = {dc_state->streams, dc_state->stream_count};
|
||||
bool set_backlight_level = false;
|
||||
|
||||
/* Disable writeback */
|
||||
for_each_old_connector_in_state(state, connector, old_con_state, i) {
|
||||
@@ -10088,6 +10086,7 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
|
||||
acrtc->hw_mode = new_crtc_state->mode;
|
||||
crtc->hwmode = new_crtc_state->mode;
|
||||
mode_set_reset_required = true;
|
||||
set_backlight_level = true;
|
||||
} else if (modereset_required(new_crtc_state)) {
|
||||
drm_dbg_atomic(dev,
|
||||
"Atomic commit: RESET. crtc id %d:[%p]\n",
|
||||
@@ -10144,16 +10143,13 @@ static void amdgpu_dm_commit_streams(struct drm_atomic_state *state,
|
||||
* to fix a flicker issue.
|
||||
* It will cause the dm->actual_brightness is not the current panel brightness
|
||||
* level. (the dm->brightness is the correct panel level)
|
||||
* So we set the backlight level with dm->brightness value after initial
|
||||
* set mode. Use restore_backlight flag to avoid setting backlight level
|
||||
* for every subsequent mode set.
|
||||
* So we set the backlight level with dm->brightness value after set mode
|
||||
*/
|
||||
if (dm->restore_backlight) {
|
||||
if (set_backlight_level) {
|
||||
for (i = 0; i < dm->num_of_edps; i++) {
|
||||
if (dm->backlight_dev[i])
|
||||
amdgpu_dm_backlight_set_level(dm, i, dm->brightness[i]);
|
||||
}
|
||||
dm->restore_backlight = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -630,13 +630,6 @@ struct amdgpu_display_manager {
|
||||
*/
|
||||
u32 actual_brightness[AMDGPU_DM_MAX_NUM_EDP];
|
||||
|
||||
/**
|
||||
* @restore_backlight:
|
||||
*
|
||||
* Flag to indicate whether to restore backlight after modeset.
|
||||
*/
|
||||
bool restore_backlight;
|
||||
|
||||
/**
|
||||
* @aux_hpd_discon_quirk:
|
||||
*
|
||||
|
||||
@@ -3500,6 +3500,11 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,
|
||||
* for these GPUs to calculate bandwidth requirements.
|
||||
*/
|
||||
if (high_pixelclock_count) {
|
||||
/* Work around flickering lines at the bottom edge
|
||||
* of the screen when using a single 4K 60Hz monitor.
|
||||
*/
|
||||
disable_mclk_switching = true;
|
||||
|
||||
/* On Oland, we observe some flickering when two 4K 60Hz
|
||||
* displays are connected, possibly because voltage is too low.
|
||||
* Raise the voltage by requiring a higher SCLK.
|
||||
|
||||
@@ -5444,8 +5444,7 @@ static int smu7_get_thermal_temperature_range(struct pp_hwmgr *hwmgr,
|
||||
thermal_data->max = table_info->cac_dtp_table->usSoftwareShutdownTemp *
|
||||
PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
else if (hwmgr->pp_table_version == PP_TABLE_V0)
|
||||
thermal_data->max = data->thermal_temp_setting.temperature_shutdown *
|
||||
PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
thermal_data->max = data->thermal_temp_setting.temperature_shutdown;
|
||||
|
||||
thermal_data->sw_ctf_threshold = thermal_data->max;
|
||||
|
||||
|
||||
@@ -836,22 +836,24 @@ ast_crtc_helper_atomic_flush(struct drm_crtc *crtc,
|
||||
static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
|
||||
{
|
||||
struct ast_device *ast = to_ast_device(crtc->dev);
|
||||
u8 vgacr17 = 0x00;
|
||||
u8 vgacrb6 = 0xff;
|
||||
|
||||
ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, 0x00);
|
||||
ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0x00);
|
||||
vgacr17 |= AST_IO_VGACR17_SYNC_ENABLE;
|
||||
vgacrb6 &= ~(AST_IO_VGACRB6_VSYNC_OFF | AST_IO_VGACRB6_HSYNC_OFF);
|
||||
|
||||
ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x17, 0x7f, vgacr17);
|
||||
ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, vgacrb6);
|
||||
}
|
||||
|
||||
static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
|
||||
struct ast_device *ast = to_ast_device(crtc->dev);
|
||||
u8 vgacrb6;
|
||||
u8 vgacr17 = 0xff;
|
||||
|
||||
ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, AST_IO_VGASR1_SD);
|
||||
|
||||
vgacrb6 = AST_IO_VGACRB6_VSYNC_OFF |
|
||||
AST_IO_VGACRB6_HSYNC_OFF;
|
||||
ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, vgacrb6);
|
||||
vgacr17 &= ~AST_IO_VGACR17_SYNC_ENABLE;
|
||||
ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x17, 0x7f, vgacr17);
|
||||
|
||||
/*
|
||||
* HW cursors require the underlying primary plane and CRTC to
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#define AST_IO_VGAGRI (0x4E)
|
||||
|
||||
#define AST_IO_VGACRI (0x54)
|
||||
#define AST_IO_VGACR17_SYNC_ENABLE BIT(7) /* called "Hardware reset" in docs */
|
||||
#define AST_IO_VGACR80_PASSWORD (0xa8)
|
||||
#define AST_IO_VGACR99_VGAMEM_RSRV_MASK GENMASK(1, 0)
|
||||
#define AST_IO_VGACRA1_VGAIO_DISABLED BIT(1)
|
||||
|
||||
@@ -121,8 +121,7 @@ static int lt9211_read_chipid(struct lt9211 *ctx)
|
||||
}
|
||||
|
||||
/* Test for known Chip ID. */
|
||||
if (chipid[0] != REG_CHIPID0_VALUE || chipid[1] != REG_CHIPID1_VALUE ||
|
||||
chipid[2] != REG_CHIPID2_VALUE) {
|
||||
if (chipid[0] != REG_CHIPID0_VALUE || chipid[1] != REG_CHIPID1_VALUE) {
|
||||
dev_err(ctx->dev, "Unknown Chip ID: 0x%02x 0x%02x 0x%02x\n",
|
||||
chipid[0], chipid[1], chipid[2]);
|
||||
return -EINVAL;
|
||||
|
||||
@@ -127,7 +127,7 @@ EXPORT_SYMBOL(drm_draw_fill16);
|
||||
|
||||
void drm_draw_fill24(struct iosys_map *dmap, unsigned int dpitch,
|
||||
unsigned int height, unsigned int width,
|
||||
u16 color)
|
||||
u32 color)
|
||||
{
|
||||
unsigned int y, x;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ void drm_draw_fill16(struct iosys_map *dmap, unsigned int dpitch,
|
||||
|
||||
void drm_draw_fill24(struct iosys_map *dmap, unsigned int dpitch,
|
||||
unsigned int height, unsigned int width,
|
||||
u16 color);
|
||||
u32 color);
|
||||
|
||||
void drm_draw_fill32(struct iosys_map *dmap, unsigned int dpitch,
|
||||
unsigned int height, unsigned int width,
|
||||
|
||||
@@ -2113,10 +2113,10 @@ static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
|
||||
if (intel_fb_uses_dpt(fb))
|
||||
intel_dpt_destroy(intel_fb->dpt_vm);
|
||||
|
||||
intel_frontbuffer_put(intel_fb->frontbuffer);
|
||||
|
||||
intel_fb_bo_framebuffer_fini(intel_fb_bo(fb));
|
||||
|
||||
intel_frontbuffer_put(intel_fb->frontbuffer);
|
||||
|
||||
kfree(intel_fb);
|
||||
}
|
||||
|
||||
@@ -2218,15 +2218,17 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
int ret = -EINVAL;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* intel_frontbuffer_get() must be done before
|
||||
* intel_fb_bo_framebuffer_init() to avoid set_tiling vs. addfb race.
|
||||
*/
|
||||
intel_fb->frontbuffer = intel_frontbuffer_get(obj);
|
||||
if (!intel_fb->frontbuffer)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = intel_fb_bo_framebuffer_init(fb, obj, mode_cmd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
intel_fb->frontbuffer = intel_frontbuffer_get(obj);
|
||||
if (!intel_fb->frontbuffer) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
goto err_frontbuffer_put;
|
||||
|
||||
ret = -EINVAL;
|
||||
if (!drm_any_plane_has_format(display->drm,
|
||||
@@ -2235,7 +2237,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
drm_dbg_kms(display->drm,
|
||||
"unsupported pixel format %p4cc / modifier 0x%llx\n",
|
||||
&mode_cmd->pixel_format, mode_cmd->modifier[0]);
|
||||
goto err_frontbuffer_put;
|
||||
goto err_bo_framebuffer_fini;
|
||||
}
|
||||
|
||||
max_stride = intel_fb_max_stride(display, mode_cmd->pixel_format,
|
||||
@@ -2246,7 +2248,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
mode_cmd->modifier[0] != DRM_FORMAT_MOD_LINEAR ?
|
||||
"tiled" : "linear",
|
||||
mode_cmd->pitches[0], max_stride);
|
||||
goto err_frontbuffer_put;
|
||||
goto err_bo_framebuffer_fini;
|
||||
}
|
||||
|
||||
/* FIXME need to adjust LINOFF/TILEOFF accordingly. */
|
||||
@@ -2254,7 +2256,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
drm_dbg_kms(display->drm,
|
||||
"plane 0 offset (0x%08x) must be 0\n",
|
||||
mode_cmd->offsets[0]);
|
||||
goto err_frontbuffer_put;
|
||||
goto err_bo_framebuffer_fini;
|
||||
}
|
||||
|
||||
drm_helper_mode_fill_fb_struct(display->drm, fb, info, mode_cmd);
|
||||
@@ -2264,7 +2266,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
|
||||
if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
|
||||
drm_dbg_kms(display->drm, "bad plane %d handle\n", i);
|
||||
goto err_frontbuffer_put;
|
||||
goto err_bo_framebuffer_fini;
|
||||
}
|
||||
|
||||
stride_alignment = intel_fb_stride_alignment(fb, i);
|
||||
@@ -2272,7 +2274,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
drm_dbg_kms(display->drm,
|
||||
"plane %d pitch (%d) must be at least %u byte aligned\n",
|
||||
i, fb->pitches[i], stride_alignment);
|
||||
goto err_frontbuffer_put;
|
||||
goto err_bo_framebuffer_fini;
|
||||
}
|
||||
|
||||
if (intel_fb_is_gen12_ccs_aux_plane(fb, i)) {
|
||||
@@ -2282,7 +2284,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
drm_dbg_kms(display->drm,
|
||||
"ccs aux plane %d pitch (%d) must be %d\n",
|
||||
i, fb->pitches[i], ccs_aux_stride);
|
||||
goto err_frontbuffer_put;
|
||||
goto err_bo_framebuffer_fini;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2291,7 +2293,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
|
||||
ret = intel_fill_fb_info(display, intel_fb);
|
||||
if (ret)
|
||||
goto err_frontbuffer_put;
|
||||
goto err_bo_framebuffer_fini;
|
||||
|
||||
if (intel_fb_uses_dpt(fb)) {
|
||||
struct i915_address_space *vm;
|
||||
@@ -2317,10 +2319,10 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
err_free_dpt:
|
||||
if (intel_fb_uses_dpt(fb))
|
||||
intel_dpt_destroy(intel_fb->dpt_vm);
|
||||
err_bo_framebuffer_fini:
|
||||
intel_fb_bo_framebuffer_fini(obj);
|
||||
err_frontbuffer_put:
|
||||
intel_frontbuffer_put(intel_fb->frontbuffer);
|
||||
err:
|
||||
intel_fb_bo_framebuffer_fini(obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -270,6 +270,8 @@ static void frontbuffer_release(struct kref *ref)
|
||||
spin_unlock(&display->fb_tracking.lock);
|
||||
|
||||
i915_active_fini(&front->write);
|
||||
|
||||
drm_gem_object_put(obj);
|
||||
kfree_rcu(front, rcu);
|
||||
}
|
||||
|
||||
@@ -287,6 +289,8 @@ intel_frontbuffer_get(struct drm_gem_object *obj)
|
||||
if (!front)
|
||||
return NULL;
|
||||
|
||||
drm_gem_object_get(obj);
|
||||
|
||||
front->obj = obj;
|
||||
kref_init(&front->ref);
|
||||
atomic_set(&front->bits, 0);
|
||||
@@ -299,8 +303,12 @@ intel_frontbuffer_get(struct drm_gem_object *obj)
|
||||
spin_lock(&display->fb_tracking.lock);
|
||||
cur = intel_bo_set_frontbuffer(obj, front);
|
||||
spin_unlock(&display->fb_tracking.lock);
|
||||
if (cur != front)
|
||||
|
||||
if (cur != front) {
|
||||
drm_gem_object_put(obj);
|
||||
kfree(front);
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
|
||||
@@ -3402,6 +3402,7 @@ static void _psr_flush_handle(struct intel_dp *intel_dp)
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
|
||||
if (DISPLAY_VER(display) < 20 && intel_dp->psr.psr2_sel_fetch_enabled) {
|
||||
/* Selective fetch prior LNL */
|
||||
if (intel_dp->psr.psr2_sel_fetch_cff_enabled) {
|
||||
/* can we turn CFF off? */
|
||||
if (intel_dp->psr.busy_frontbuffer_bits == 0)
|
||||
@@ -3420,12 +3421,19 @@ static void _psr_flush_handle(struct intel_dp *intel_dp)
|
||||
intel_psr_configure_full_frame_update(intel_dp);
|
||||
|
||||
intel_psr_force_update(intel_dp);
|
||||
} else if (!intel_dp->psr.psr2_sel_fetch_enabled) {
|
||||
/*
|
||||
* PSR1 on all platforms
|
||||
* PSR2 HW tracking
|
||||
* Panel Replay Full frame update
|
||||
*/
|
||||
intel_psr_force_update(intel_dp);
|
||||
} else {
|
||||
/* Selective update LNL onwards */
|
||||
intel_psr_exit(intel_dp);
|
||||
}
|
||||
|
||||
if ((!intel_dp->psr.psr2_sel_fetch_enabled || DISPLAY_VER(display) >= 20) &&
|
||||
!intel_dp->psr.busy_frontbuffer_bits)
|
||||
if (!intel_dp->psr.active && !intel_dp->psr.busy_frontbuffer_bits)
|
||||
queue_work(display->wq.unordered, &intel_dp->psr.work);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,12 +89,10 @@ i915_gem_object_set_frontbuffer(struct drm_i915_gem_object *obj,
|
||||
|
||||
if (!front) {
|
||||
RCU_INIT_POINTER(obj->frontbuffer, NULL);
|
||||
drm_gem_object_put(intel_bo_to_drm_bo(obj));
|
||||
} else if (rcu_access_pointer(obj->frontbuffer)) {
|
||||
cur = rcu_dereference_protected(obj->frontbuffer, true);
|
||||
kref_get(&cur->ref);
|
||||
} else {
|
||||
drm_gem_object_get(intel_bo_to_drm_bo(obj));
|
||||
rcu_assign_pointer(obj->frontbuffer, front);
|
||||
}
|
||||
|
||||
|
||||
@@ -1325,9 +1325,16 @@ static int ct_receive(struct intel_guc_ct *ct)
|
||||
|
||||
static void ct_try_receive_message(struct intel_guc_ct *ct)
|
||||
{
|
||||
struct intel_guc *guc = ct_to_guc(ct);
|
||||
int ret;
|
||||
|
||||
if (GEM_WARN_ON(!ct->enabled))
|
||||
if (!ct->enabled) {
|
||||
GEM_WARN_ON(!guc_to_gt(guc)->uc.reset_in_progress);
|
||||
return;
|
||||
}
|
||||
|
||||
/* When interrupt disabled, message handling is not expected */
|
||||
if (!guc->interrupts.enabled)
|
||||
return;
|
||||
|
||||
ret = ct_receive(ct);
|
||||
|
||||
@@ -1099,6 +1099,7 @@ void panthor_fw_pre_reset(struct panthor_device *ptdev, bool on_hang)
|
||||
}
|
||||
|
||||
panthor_job_irq_suspend(&ptdev->fw->irq);
|
||||
panthor_fw_stop(ptdev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1031,7 +1031,7 @@ static int vop2_plane_atomic_check(struct drm_plane *plane,
|
||||
return format;
|
||||
|
||||
if (drm_rect_width(src) >> 16 < 4 || drm_rect_height(src) >> 16 < 4 ||
|
||||
drm_rect_width(dest) < 4 || drm_rect_width(dest) < 4) {
|
||||
drm_rect_width(dest) < 4 || drm_rect_height(dest) < 4) {
|
||||
drm_err(vop2->drm, "Invalid size: %dx%d->%dx%d, min size is 4x4\n",
|
||||
drm_rect_width(src) >> 16, drm_rect_height(src) >> 16,
|
||||
drm_rect_width(dest), drm_rect_height(dest));
|
||||
|
||||
@@ -965,13 +965,14 @@ int drm_sched_job_add_resv_dependencies(struct drm_sched_job *job,
|
||||
dma_resv_assert_held(resv);
|
||||
|
||||
dma_resv_for_each_fence(&cursor, resv, usage, fence) {
|
||||
/* Make sure to grab an additional ref on the added fence */
|
||||
dma_fence_get(fence);
|
||||
ret = drm_sched_job_add_dependency(job, fence);
|
||||
if (ret) {
|
||||
dma_fence_put(fence);
|
||||
/*
|
||||
* As drm_sched_job_add_dependency always consumes the fence
|
||||
* reference (even when it fails), and dma_resv_for_each_fence
|
||||
* is not obtaining one, we need to grab one before calling.
|
||||
*/
|
||||
ret = drm_sched_job_add_dependency(job, dma_fence_get(fence));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -342,6 +342,7 @@
|
||||
#define POWERGATE_ENABLE XE_REG(0xa210)
|
||||
#define RENDER_POWERGATE_ENABLE REG_BIT(0)
|
||||
#define MEDIA_POWERGATE_ENABLE REG_BIT(1)
|
||||
#define MEDIA_SAMPLERS_POWERGATE_ENABLE REG_BIT(2)
|
||||
#define VDN_HCP_POWERGATE_ENABLE(n) REG_BIT(3 + 2 * (n))
|
||||
#define VDN_MFXVDENC_POWERGATE_ENABLE(n) REG_BIT(4 + 2 * (n))
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ KUNIT_ARRAY_PARAM(platform, cases, xe_pci_fake_data_desc);
|
||||
|
||||
/**
|
||||
* xe_pci_fake_data_gen_params - Generate struct xe_pci_fake_data parameters
|
||||
* @test: test context object
|
||||
* @prev: the pointer to the previous parameter to iterate from or NULL
|
||||
* @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
|
||||
*
|
||||
@@ -242,6 +243,7 @@ KUNIT_ARRAY_PARAM(pci_id, pciidlist, xe_pci_id_kunit_desc);
|
||||
|
||||
/**
|
||||
* xe_pci_graphics_ip_gen_param - Generate graphics struct xe_ip parameters
|
||||
* @test: test context object
|
||||
* @prev: the pointer to the previous parameter to iterate from or NULL
|
||||
* @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
|
||||
*
|
||||
@@ -266,6 +268,7 @@ EXPORT_SYMBOL_IF_KUNIT(xe_pci_graphics_ip_gen_param);
|
||||
|
||||
/**
|
||||
* xe_pci_media_ip_gen_param - Generate media struct xe_ip parameters
|
||||
* @test: test context object
|
||||
* @prev: the pointer to the previous parameter to iterate from or NULL
|
||||
* @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
|
||||
*
|
||||
@@ -290,6 +293,7 @@ EXPORT_SYMBOL_IF_KUNIT(xe_pci_media_ip_gen_param);
|
||||
|
||||
/**
|
||||
* xe_pci_id_gen_param - Generate struct pci_device_id parameters
|
||||
* @test: test context object
|
||||
* @prev: the pointer to the previous parameter to iterate from or NULL
|
||||
* @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
|
||||
*
|
||||
@@ -376,6 +380,7 @@ EXPORT_SYMBOL_IF_KUNIT(xe_pci_fake_device_init);
|
||||
|
||||
/**
|
||||
* xe_pci_live_device_gen_param - Helper to iterate Xe devices as KUnit parameters
|
||||
* @test: test context object
|
||||
* @prev: the previously returned value, or NULL for the first iteration
|
||||
* @desc: the buffer for a parameter name
|
||||
*
|
||||
|
||||
@@ -182,7 +182,6 @@ int xe_bo_evict_all(struct xe_device *xe)
|
||||
|
||||
static int xe_bo_restore_and_map_ggtt(struct xe_bo *bo)
|
||||
{
|
||||
struct xe_device *xe = xe_bo_device(bo);
|
||||
int ret;
|
||||
|
||||
ret = xe_bo_restore_pinned(bo);
|
||||
@@ -201,13 +200,6 @@ static int xe_bo_restore_and_map_ggtt(struct xe_bo *bo)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We expect validate to trigger a move VRAM and our move code
|
||||
* should setup the iosys map.
|
||||
*/
|
||||
xe_assert(xe, !(bo->flags & XE_BO_FLAG_PINNED_LATE_RESTORE) ||
|
||||
!iosys_map_is_null(&bo->vmap));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1070,7 +1070,7 @@ void xe_device_l2_flush(struct xe_device *xe)
|
||||
spin_lock(>->global_invl_lock);
|
||||
|
||||
xe_mmio_write32(>->mmio, XE2_GLOBAL_INVAL, 0x1);
|
||||
if (xe_mmio_wait32(>->mmio, XE2_GLOBAL_INVAL, 0x1, 0x0, 500, NULL, true))
|
||||
if (xe_mmio_wait32(>->mmio, XE2_GLOBAL_INVAL, 0x1, 0x0, 1000, NULL, true))
|
||||
xe_gt_err_once(gt, "Global invalidation timeout\n");
|
||||
|
||||
spin_unlock(>->global_invl_lock);
|
||||
|
||||
@@ -124,6 +124,9 @@ void xe_gt_idle_enable_pg(struct xe_gt *gt)
|
||||
if (xe_gt_is_main_type(gt))
|
||||
gtidle->powergate_enable |= RENDER_POWERGATE_ENABLE;
|
||||
|
||||
if (MEDIA_VERx100(xe) >= 1100 && MEDIA_VERx100(xe) < 1255)
|
||||
gtidle->powergate_enable |= MEDIA_SAMPLERS_POWERGATE_ENABLE;
|
||||
|
||||
if (xe->info.platform != XE_DG1) {
|
||||
for (i = XE_HW_ENGINE_VCS0, j = 0; i <= XE_HW_ENGINE_VCS7; ++i, ++j) {
|
||||
if ((gt->info.engine_mask & BIT(i)))
|
||||
@@ -246,6 +249,11 @@ int xe_gt_idle_pg_print(struct xe_gt *gt, struct drm_printer *p)
|
||||
drm_printf(p, "Media Slice%d Power Gate Status: %s\n", n,
|
||||
str_up_down(pg_status & media_slices[n].status_bit));
|
||||
}
|
||||
|
||||
if (MEDIA_VERx100(xe) >= 1100 && MEDIA_VERx100(xe) < 1255)
|
||||
drm_printf(p, "Media Samplers Power Gating Enabled: %s\n",
|
||||
str_yes_no(pg_enabled & MEDIA_SAMPLERS_POWERGATE_ENABLE));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "xe_ring_ops_types.h"
|
||||
#include "xe_sched_job.h"
|
||||
#include "xe_trace.h"
|
||||
#include "xe_uc_fw.h"
|
||||
#include "xe_vm.h"
|
||||
|
||||
static struct xe_guc *
|
||||
@@ -1489,7 +1490,17 @@ static void __guc_exec_queue_process_msg_cleanup(struct xe_sched_msg *msg)
|
||||
xe_gt_assert(guc_to_gt(guc), !(q->flags & EXEC_QUEUE_FLAG_PERMANENT));
|
||||
trace_xe_exec_queue_cleanup_entity(q);
|
||||
|
||||
if (exec_queue_registered(q))
|
||||
/*
|
||||
* Expected state transitions for cleanup:
|
||||
* - If the exec queue is registered and GuC firmware is running, we must first
|
||||
* disable scheduling and deregister the queue to ensure proper teardown and
|
||||
* resource release in the GuC, then destroy the exec queue on driver side.
|
||||
* - If the GuC is already stopped (e.g., during driver unload or GPU reset),
|
||||
* we cannot expect a response for the deregister request. In this case,
|
||||
* it is safe to directly destroy the exec queue on driver side, as the GuC
|
||||
* will not process further requests and all resources must be cleaned up locally.
|
||||
*/
|
||||
if (exec_queue_registered(q) && xe_uc_fw_is_running(&guc->fw))
|
||||
disable_scheduling_deregister(guc, q);
|
||||
else
|
||||
__guc_exec_queue_destroy(guc, q);
|
||||
|
||||
@@ -434,7 +434,7 @@ int xe_migrate_init(struct xe_migrate *m)
|
||||
|
||||
err = xe_migrate_lock_prepare_vm(tile, m, vm);
|
||||
if (err)
|
||||
return err;
|
||||
goto err_out;
|
||||
|
||||
if (xe->info.has_usm) {
|
||||
struct xe_hw_engine *hwe = xe_gt_hw_engine(primary_gt,
|
||||
@@ -2113,7 +2113,9 @@ int xe_migrate_access_memory(struct xe_migrate *m, struct xe_bo *bo,
|
||||
if (current_bytes & ~PAGE_MASK) {
|
||||
int pitch = 4;
|
||||
|
||||
current_bytes = min_t(int, current_bytes, S16_MAX * pitch);
|
||||
current_bytes = min_t(int, current_bytes,
|
||||
round_down(S16_MAX * pitch,
|
||||
XE_CACHELINE_BYTES));
|
||||
}
|
||||
|
||||
__fence = xe_migrate_vram(m, current_bytes,
|
||||
|
||||
@@ -867,6 +867,8 @@ static int xe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
xe_vram_resize_bar(xe);
|
||||
|
||||
err = xe_device_probe_early(xe);
|
||||
/*
|
||||
* In Boot Survivability mode, no drm card is exposed and driver
|
||||
|
||||
@@ -1034,6 +1034,9 @@ retry:
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dpagemap = xe_vma_resolve_pagemap(vma, tile);
|
||||
if (!dpagemap && !ctx.devmem_only)
|
||||
ctx.device_private_page_owner = NULL;
|
||||
range = xe_svm_range_find_or_insert(vm, fault_addr, vma, &ctx);
|
||||
|
||||
if (IS_ERR(range))
|
||||
@@ -1054,7 +1057,6 @@ retry:
|
||||
|
||||
range_debug(range, "PAGE FAULT");
|
||||
|
||||
dpagemap = xe_vma_resolve_pagemap(vma, tile);
|
||||
if (--migrate_try_count >= 0 &&
|
||||
xe_svm_range_needs_migrate_to_vram(range, vma, !!dpagemap || ctx.devmem_only)) {
|
||||
ktime_t migrate_start = xe_svm_stats_ktime_get();
|
||||
@@ -1073,7 +1075,17 @@ retry:
|
||||
drm_dbg(&vm->xe->drm,
|
||||
"VRAM allocation failed, falling back to retrying fault, asid=%u, errno=%pe\n",
|
||||
vm->usm.asid, ERR_PTR(err));
|
||||
goto retry;
|
||||
|
||||
/*
|
||||
* In the devmem-only case, mixed mappings may
|
||||
* be found. The get_pages function will fix
|
||||
* these up to a single location, allowing the
|
||||
* page fault handler to make forward progress.
|
||||
*/
|
||||
if (ctx.devmem_only)
|
||||
goto get_pages;
|
||||
else
|
||||
goto retry;
|
||||
} else {
|
||||
drm_err(&vm->xe->drm,
|
||||
"VRAM allocation failed, retry count exceeded, asid=%u, errno=%pe\n",
|
||||
@@ -1083,6 +1095,7 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
get_pages:
|
||||
get_pages_start = xe_svm_stats_ktime_get();
|
||||
|
||||
range_debug(range, "GET PAGES");
|
||||
|
||||
@@ -2832,7 +2832,7 @@ static void vm_bind_ioctl_ops_unwind(struct xe_vm *vm,
|
||||
}
|
||||
|
||||
static int vma_lock_and_validate(struct drm_exec *exec, struct xe_vma *vma,
|
||||
bool validate)
|
||||
bool res_evict, bool validate)
|
||||
{
|
||||
struct xe_bo *bo = xe_vma_bo(vma);
|
||||
struct xe_vm *vm = xe_vma_vm(vma);
|
||||
@@ -2843,7 +2843,8 @@ static int vma_lock_and_validate(struct drm_exec *exec, struct xe_vma *vma,
|
||||
err = drm_exec_lock_obj(exec, &bo->ttm.base);
|
||||
if (!err && validate)
|
||||
err = xe_bo_validate(bo, vm,
|
||||
!xe_vm_in_preempt_fence_mode(vm), exec);
|
||||
!xe_vm_in_preempt_fence_mode(vm) &&
|
||||
res_evict, exec);
|
||||
}
|
||||
|
||||
return err;
|
||||
@@ -2913,14 +2914,23 @@ static int prefetch_ranges(struct xe_vm *vm, struct xe_vma_op *op)
|
||||
}
|
||||
|
||||
static int op_lock_and_prep(struct drm_exec *exec, struct xe_vm *vm,
|
||||
struct xe_vma_op *op)
|
||||
struct xe_vma_ops *vops, struct xe_vma_op *op)
|
||||
{
|
||||
int err = 0;
|
||||
bool res_evict;
|
||||
|
||||
/*
|
||||
* We only allow evicting a BO within the VM if it is not part of an
|
||||
* array of binds, as an array of binds can evict another BO within the
|
||||
* bind.
|
||||
*/
|
||||
res_evict = !(vops->flags & XE_VMA_OPS_ARRAY_OF_BINDS);
|
||||
|
||||
switch (op->base.op) {
|
||||
case DRM_GPUVA_OP_MAP:
|
||||
if (!op->map.invalidate_on_bind)
|
||||
err = vma_lock_and_validate(exec, op->map.vma,
|
||||
res_evict,
|
||||
!xe_vm_in_fault_mode(vm) ||
|
||||
op->map.immediate);
|
||||
break;
|
||||
@@ -2931,11 +2941,13 @@ static int op_lock_and_prep(struct drm_exec *exec, struct xe_vm *vm,
|
||||
|
||||
err = vma_lock_and_validate(exec,
|
||||
gpuva_to_vma(op->base.remap.unmap->va),
|
||||
false);
|
||||
res_evict, false);
|
||||
if (!err && op->remap.prev)
|
||||
err = vma_lock_and_validate(exec, op->remap.prev, true);
|
||||
err = vma_lock_and_validate(exec, op->remap.prev,
|
||||
res_evict, true);
|
||||
if (!err && op->remap.next)
|
||||
err = vma_lock_and_validate(exec, op->remap.next, true);
|
||||
err = vma_lock_and_validate(exec, op->remap.next,
|
||||
res_evict, true);
|
||||
break;
|
||||
case DRM_GPUVA_OP_UNMAP:
|
||||
err = check_ufence(gpuva_to_vma(op->base.unmap.va));
|
||||
@@ -2944,7 +2956,7 @@ static int op_lock_and_prep(struct drm_exec *exec, struct xe_vm *vm,
|
||||
|
||||
err = vma_lock_and_validate(exec,
|
||||
gpuva_to_vma(op->base.unmap.va),
|
||||
false);
|
||||
res_evict, false);
|
||||
break;
|
||||
case DRM_GPUVA_OP_PREFETCH:
|
||||
{
|
||||
@@ -2959,7 +2971,7 @@ static int op_lock_and_prep(struct drm_exec *exec, struct xe_vm *vm,
|
||||
|
||||
err = vma_lock_and_validate(exec,
|
||||
gpuva_to_vma(op->base.prefetch.va),
|
||||
false);
|
||||
res_evict, false);
|
||||
if (!err && !xe_vma_has_no_bo(vma))
|
||||
err = xe_bo_migrate(xe_vma_bo(vma),
|
||||
region_to_mem_type[region],
|
||||
@@ -3005,7 +3017,7 @@ static int vm_bind_ioctl_ops_lock_and_prep(struct drm_exec *exec,
|
||||
return err;
|
||||
|
||||
list_for_each_entry(op, &vops->list, link) {
|
||||
err = op_lock_and_prep(exec, vm, op);
|
||||
err = op_lock_and_prep(exec, vm, vops, op);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
@@ -3638,6 +3650,8 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
||||
}
|
||||
|
||||
xe_vma_ops_init(&vops, vm, q, syncs, num_syncs);
|
||||
if (args->num_binds > 1)
|
||||
vops.flags |= XE_VMA_OPS_ARRAY_OF_BINDS;
|
||||
for (i = 0; i < args->num_binds; ++i) {
|
||||
u64 range = bind_ops[i].range;
|
||||
u64 addr = bind_ops[i].addr;
|
||||
|
||||
@@ -476,6 +476,7 @@ struct xe_vma_ops {
|
||||
/** @flag: signify the properties within xe_vma_ops*/
|
||||
#define XE_VMA_OPS_FLAG_HAS_SVM_PREFETCH BIT(0)
|
||||
#define XE_VMA_OPS_FLAG_MADVISE BIT(1)
|
||||
#define XE_VMA_OPS_ARRAY_OF_BINDS BIT(2)
|
||||
u32 flags;
|
||||
#ifdef TEST_VM_OPS_ERROR
|
||||
/** @inject_error: inject error to test error handling */
|
||||
|
||||
@@ -26,15 +26,35 @@
|
||||
|
||||
#define BAR_SIZE_SHIFT 20
|
||||
|
||||
static void
|
||||
_resize_bar(struct xe_device *xe, int resno, resource_size_t size)
|
||||
/*
|
||||
* Release all the BARs that could influence/block LMEMBAR resizing, i.e.
|
||||
* assigned IORESOURCE_MEM_64 BARs
|
||||
*/
|
||||
static void release_bars(struct pci_dev *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
int i;
|
||||
|
||||
pci_dev_for_each_resource(pdev, res, i) {
|
||||
/* Resource already un-assigned, do not reset it */
|
||||
if (!res->parent)
|
||||
continue;
|
||||
|
||||
/* No need to release unrelated BARs */
|
||||
if (!(res->flags & IORESOURCE_MEM_64))
|
||||
continue;
|
||||
|
||||
pci_release_resource(pdev, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void resize_bar(struct xe_device *xe, int resno, resource_size_t size)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
|
||||
int bar_size = pci_rebar_bytes_to_size(size);
|
||||
int ret;
|
||||
|
||||
if (pci_resource_len(pdev, resno))
|
||||
pci_release_resource(pdev, resno);
|
||||
release_bars(pdev);
|
||||
|
||||
ret = pci_resize_resource(pdev, resno, bar_size);
|
||||
if (ret) {
|
||||
@@ -50,7 +70,7 @@ _resize_bar(struct xe_device *xe, int resno, resource_size_t size)
|
||||
* if force_vram_bar_size is set, attempt to set to the requested size
|
||||
* else set to maximum possible size
|
||||
*/
|
||||
static void resize_vram_bar(struct xe_device *xe)
|
||||
void xe_vram_resize_bar(struct xe_device *xe)
|
||||
{
|
||||
int force_vram_bar_size = xe_modparam.force_vram_bar_size;
|
||||
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
|
||||
@@ -119,7 +139,7 @@ static void resize_vram_bar(struct xe_device *xe)
|
||||
pci_read_config_dword(pdev, PCI_COMMAND, &pci_cmd);
|
||||
pci_write_config_dword(pdev, PCI_COMMAND, pci_cmd & ~PCI_COMMAND_MEMORY);
|
||||
|
||||
_resize_bar(xe, LMEM_BAR, rebar_size);
|
||||
resize_bar(xe, LMEM_BAR, rebar_size);
|
||||
|
||||
pci_assign_unassigned_bus_resources(pdev->bus);
|
||||
pci_write_config_dword(pdev, PCI_COMMAND, pci_cmd);
|
||||
@@ -148,8 +168,6 @@ static int determine_lmem_bar_size(struct xe_device *xe, struct xe_vram_region *
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
resize_vram_bar(xe);
|
||||
|
||||
lmem_bar->io_start = pci_resource_start(pdev, LMEM_BAR);
|
||||
lmem_bar->io_size = pci_resource_len(pdev, LMEM_BAR);
|
||||
if (!lmem_bar->io_size)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
struct xe_device;
|
||||
struct xe_vram_region;
|
||||
|
||||
void xe_vram_resize_bar(struct xe_device *xe);
|
||||
int xe_vram_probe(struct xe_device *xe);
|
||||
|
||||
struct xe_vram_region *xe_vram_region_alloc(struct xe_device *xe, u8 id, u32 placement);
|
||||
|
||||
@@ -1078,7 +1078,7 @@ struct drm_gpuva_ops {
|
||||
*/
|
||||
struct drm_gpuvm_map_req {
|
||||
/**
|
||||
* @op_map: struct drm_gpuva_op_map
|
||||
* @map: struct drm_gpuva_op_map
|
||||
*/
|
||||
struct drm_gpuva_op_map map;
|
||||
};
|
||||
|
||||
@@ -1555,27 +1555,6 @@ struct drm_amdgpu_info_hw_ip {
|
||||
__u32 userq_num_slots;
|
||||
};
|
||||
|
||||
/* GFX metadata BO sizes and alignment info (in bytes) */
|
||||
struct drm_amdgpu_info_uq_fw_areas_gfx {
|
||||
/* shadow area size */
|
||||
__u32 shadow_size;
|
||||
/* shadow area base virtual mem alignment */
|
||||
__u32 shadow_alignment;
|
||||
/* context save area size */
|
||||
__u32 csa_size;
|
||||
/* context save area base virtual mem alignment */
|
||||
__u32 csa_alignment;
|
||||
};
|
||||
|
||||
/* IP specific fw related information used in the
|
||||
* subquery AMDGPU_INFO_UQ_FW_AREAS
|
||||
*/
|
||||
struct drm_amdgpu_info_uq_fw_areas {
|
||||
union {
|
||||
struct drm_amdgpu_info_uq_fw_areas_gfx gfx;
|
||||
};
|
||||
};
|
||||
|
||||
struct drm_amdgpu_info_num_handles {
|
||||
/** Max handles as supported by firmware for UVD */
|
||||
__u32 uvd_max_handles;
|
||||
|
||||
Reference in New Issue
Block a user