amd-drm-next-7.2-2026-06-04:

amdgpu:
 - UserQ fix
 - Userptr fix
 - MCCS freesync fix
 - Remove some triggerable BUG() calls
 - DCN 4.2.1 fixes
 - Lockdep annotations
 - Guilty handling fix
 - VCN 5.3 fix
 - FRL fixes
 - Bounds checking fixes
 - HMM fix
 - IRQ accounting fix
 
 amdkfd:
 - Fix an event information leak
 - Events bounds check fix
 - Trap cleanup fix
 - Bounds checking fixes
 - MES fix
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCaiIG8QAKCRC93/aFa7yZ
 2Dc6AQCnjH9T6lezjM5BblhCUI0bkba6MZ+qtTaB+314Gt1A6AD9H8I5lvYC3rJR
 kIy+jiLuQ+/ohrjt+NiCgQ7AEXYIXAU=
 =wEwK
 -----END PGP SIGNATURE-----

Merge tag 'amd-drm-next-7.2-2026-06-04' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-next-7.2-2026-06-04:

amdgpu:
- UserQ fix
- Userptr fix
- MCCS freesync fix
- Remove some triggerable BUG() calls
- DCN 4.2.1 fixes
- Lockdep annotations
- Guilty handling fix
- VCN 5.3 fix
- FRL fixes
- Bounds checking fixes
- HMM fix
- IRQ accounting fix

amdkfd:
- Fix an event information leak
- Events bounds check fix
- Trap cleanup fix
- Bounds checking fixes
- MES fix

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

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patch.msgid.link/20260604231801.19979-1-alexander.deucher@amd.com
This commit is contained in:
Dave Airlie 2026-06-08 19:56:59 +10:00
commit 5ea194bc25
39 changed files with 716 additions and 309 deletions

View File

@ -69,7 +69,7 @@ amdgpu-y += amdgpu_device.o amdgpu_reg_access.o amdgpu_doorbell_mgr.o amdgpu_kms
amdgpu_vm_sdma.o amdgpu_discovery.o amdgpu_ras_eeprom.o amdgpu_nbio.o \
amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o \
amdgpu_fw_attestation.o amdgpu_securedisplay.o \
amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o amdgpu_lsdma.o \
amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o amdgpu_lsdma.o amdgpu_lockdep.o \
amdgpu_ring_mux.o amdgpu_xcp.o amdgpu_seq64.o amdgpu_aca.o amdgpu_dev_coredump.o \
amdgpu_cper.o amdgpu_userq_fence.o amdgpu_eviction_fence.o amdgpu_ip.o

View File

@ -105,6 +105,7 @@
#include "amdgpu_mca.h"
#include "amdgpu_aca.h"
#include "amdgpu_ras.h"
#include "amdgpu_lockdep.h"
#include "amdgpu_cper.h"
#include "amdgpu_xcp.h"
#include "amdgpu_seq64.h"

View File

@ -60,11 +60,6 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p,
if (!p->ctx)
return -EINVAL;
if (atomic_read(&p->ctx->guilty)) {
amdgpu_ctx_put(p->ctx);
return -ECANCELED;
}
amdgpu_sync_create(&p->sync);
drm_exec_init(&p->exec, DRM_EXEC_INTERRUPTIBLE_WAIT |
DRM_EXEC_IGNORE_DUPLICATES, 0);
@ -1277,6 +1272,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
{
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
struct amdgpu_job *leader = p->gang_leader;
struct amdgpu_vm *vm = &fpriv->vm;
struct amdgpu_bo_list_entry *e;
struct drm_gem_object *gobj;
unsigned int i;
@ -1321,7 +1317,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
amdgpu_hmm_range_free(e->range);
e->range = NULL;
}
if (r) {
if (r || !list_empty(&vm->individual.moved)) {
r = -EAGAIN;
mutex_unlock(&p->adev->notifier_lock);
return r;

View File

@ -255,7 +255,7 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
}
r = drm_sched_entity_init(&entity->entity, drm_prio, scheds, num_scheds,
&ctx->guilty);
NULL);
if (r)
goto error_free_entity;
@ -579,6 +579,27 @@ static int amdgpu_ctx_query(struct amdgpu_device *adev,
#define AMDGPU_RAS_COUNTE_DELAY_MS 3000
static bool amdgpu_ctx_guilty(struct amdgpu_ctx *ctx)
{
int i, j, r;
for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
struct amdgpu_ctx_entity *ctx_entity;
ctx_entity = ctx->entities[i][j];
if (!ctx_entity)
continue;
r = drm_sched_entity_error(&ctx_entity->entity);
if (r == -ETIME)
return true;
}
}
return false;
}
static int amdgpu_ctx_query2(struct amdgpu_device *adev,
struct amdgpu_fpriv *fpriv, uint32_t id,
union drm_amdgpu_ctx_out *out)
@ -607,7 +628,7 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev,
if (ctx->generation != amdgpu_vm_generation(adev, &fpriv->vm))
out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST;
if (atomic_read(&ctx->guilty))
if (amdgpu_ctx_guilty(ctx))
out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_GUILTY;
if (amdgpu_in_reset(adev))

View File

@ -50,7 +50,6 @@ struct amdgpu_ctx {
int32_t init_priority;
int32_t override_priority;
uint32_t stable_pstate;
atomic_t guilty;
bool preamble_presented;
uint64_t generation;
unsigned long ras_counter_ce;

View File

@ -717,7 +717,12 @@ void amdgpu_device_mm_access(struct amdgpu_device *adev, loff_t pos,
if (!drm_dev_enter(adev_to_drm(adev), &idx))
return;
BUG_ON(!IS_ALIGNED(pos, 4) || !IS_ALIGNED(size, 4));
if (!IS_ALIGNED(pos, 4) || !IS_ALIGNED(size, 4)) {
dev_err(adev->dev, "unaligned pos/size (pos=0x%llx, size=0x%zx)\n",
pos, size);
drm_dev_exit(idx);
return;
}
spin_lock_irqsave(&adev->mmio_idx_lock, flags);
for (last = pos + size; pos < last; pos += 4) {
@ -3752,6 +3757,9 @@ int amdgpu_device_init(struct amdgpu_device *adev,
mutex_init(&adev->pm.stable_pstate_ctx_lock);
mutex_init(&adev->benchmark_mutex);
mutex_init(&adev->gfx.reset_sem_mutex);
/* Associate locks with lockdep classes for ordering validation */
amdgpu_lockdep_set_class(adev);
/* Initialize the mutex for cleaner shader isolation between GFX and compute processes */
mutex_init(&adev->enforce_isolation_mutex);
for (i = 0; i < MAX_XCP; ++i) {
@ -5104,12 +5112,12 @@ int amdgpu_device_link_reset(struct amdgpu_device *adev)
int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
struct amdgpu_reset_context *reset_context)
{
int i, r = 0;
struct amdgpu_job *job = NULL;
struct dma_fence *fence = NULL;
struct amdgpu_device *tmp_adev = reset_context->reset_req_dev;
bool need_full_reset =
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
int i, r;
if (reset_context->reset_req_dev == adev)
job = reset_context->job;
@ -5135,9 +5143,6 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
amdgpu_fence_driver_isr_toggle(adev, false);
if (job && job->vm)
drm_sched_increase_karma(&job->base);
r = amdgpu_reset_prepare_hwcontext(adev, reset_context);
/* If reset handler not implemented, continue; otherwise return */
if (r == -EOPNOTSUPP)

View File

@ -3158,6 +3158,9 @@ static int __init amdgpu_init(void)
{
int r;
/* Train lockdep on correct lock ordering */
amdgpu_lockdep_init();
r = amdgpu_sync_init();
if (r)
return r;

View File

@ -174,7 +174,6 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier,
const u64 max_bytes = SZ_2G;
struct hmm_range *hmm_range = &range->hmm_range;
unsigned long timeout;
unsigned long *pfns;
unsigned long end;
int r;
@ -201,15 +200,9 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier,
pr_debug("hmm range: start = 0x%lx, end = 0x%lx",
hmm_range->start, hmm_range->end);
timeout = jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
retry:
r = hmm_range_fault(hmm_range);
if (unlikely(r)) {
if (r == -EBUSY && !time_after(jiffies, timeout))
goto retry;
if (unlikely(r))
goto out_free_pfns;
}
if (hmm_range->end == end)
break;

View File

@ -0,0 +1,195 @@
// SPDX-License-Identifier: MIT
/*
* Copyright 2024 Advanced Micro Devices, Inc.
*
* Lockdep annotation for AMDGPU lock ordering
*
* This module teaches lockdep the correct lock ordering to catch
* potential deadlocks at development time rather than runtime.
*
* Based on dma-resv lockdep approach from:
* drivers/dma-buf/dma-resv.c:dma_resv_lockdep()
*/
#include "amdgpu.h"
#include "amdgpu_reset.h"
#ifdef CONFIG_LOCKDEP
/* Lock class keys for associating with real driver locks */
static struct lock_class_key amdgpu_userq_sch_mutex_key;
static struct lock_class_key amdgpu_userq_mutex_key;
static struct lock_class_key amdgpu_notifier_lock_key;
static struct lock_class_key amdgpu_vram_lock_key;
static struct lock_class_key amdgpu_reset_sem_key;
static struct lock_class_key amdgpu_reset_lock_key;
static struct lock_class_key amdgpu_srbm_lock_key;
static struct lock_class_key amdgpu_grbm_lock_key;
static struct lock_class_key amdgpu_mmio_lock_key;
/**
* amdgpu_lockdep_set_class - Associate lock class keys with real locks
* @adev: AMDGPU device
*
* Call during device init to associate lock classes with actual locks
* so lockdep can track them properly.
*/
void amdgpu_lockdep_set_class(struct amdgpu_device *adev)
{
lockdep_set_class(&adev->gfx.userq_sch_mutex,
&amdgpu_userq_sch_mutex_key);
lockdep_set_class(&adev->notifier_lock, &amdgpu_notifier_lock_key);
lockdep_set_class(&adev->srbm_mutex, &amdgpu_srbm_lock_key);
lockdep_set_class(&adev->grbm_idx_mutex, &amdgpu_grbm_lock_key);
lockdep_set_class(&adev->mmio_idx_lock, &amdgpu_mmio_lock_key);
if (adev->reset_domain)
lockdep_set_class(&adev->reset_domain->sem,
&amdgpu_reset_sem_key);
}
/**
* amdgpu_lockdep_init - Teach lockdep the correct lock ordering
*
* Instantiates dummy objects and takes locks in the correct order to
* train lockdep. This helps catch lock ordering violations during
* development.
*
* Lock ordering hierarchy (outermost to innermost):
*
* 1. userq_sch_mutex - Global userq scheduler (enforce_isolation)
* 2. userq_mutex - Per-context userq (held across queue create/destroy)
* 3. notifier_lock - MMU notifier lock
* 4. vram_lock - VRAM allocator lock
* 5. reset_domain->sem - GPU reset synchronization
* 6. reset_lock - Reset control lock
* 7. srbm_mutex - SRBM register access
* 8. grbm_idx_mutex - GRBM index access
* 9. mmio_idx_lock - MMIO index access (spinlock)
*
* Evidence:
* - userq_sch_mutex -> userq_mutex: amdgpu_gfx_kfd_sch_ctrl() calls
* amdgpu_userq_stop_sched_for_enforce_isolation() which takes userq_mutex
* - userq_mutex -> notifier_lock: userq paths may trigger MMU notifier
* invalidation which acquires notifier_lock
* - notifier_lock -> reset_domain->sem: HMM invalidation callback holds
* notifier_lock and can wait for GPU reset completion, so notifier_lock
* must be outer to reset_domain->sem
* - vram_lock -> reset_domain->sem: VRAM management paths may need to
* wait for ongoing reset to complete
*
* Note: mmap_lock ordering relative to GPU locks is already taught
* by dma-resv (drivers/dma-buf/dma-resv.c).
*/
int amdgpu_lockdep_init(void)
{
struct amdgpu_reset_domain *reset_domain = NULL;
struct amdgpu_reset_control reset_ctl;
struct mutex userq_sch_mutex;
struct mutex userq_mutex;
struct mutex notifier_lock;
struct mutex vram_lock;
struct mutex srbm_mutex;
struct mutex grbm_idx_mutex;
spinlock_t mmio_idx_lock;
unsigned long flags;
/*
* Initialize dummy reset domain
*/
reset_domain = amdgpu_reset_create_reset_domain(SINGLE_DEVICE,
"lockdep_test");
if (!reset_domain)
return -ENOMEM;
/* Initialize dummy locks */
mutex_init(&userq_sch_mutex);
mutex_init(&userq_mutex);
mutex_init(&notifier_lock);
mutex_init(&vram_lock);
mutex_init(&reset_ctl.reset_lock);
mutex_init(&srbm_mutex);
mutex_init(&grbm_idx_mutex);
spin_lock_init(&mmio_idx_lock);
/*
* Associate dummy locks with the same class keys used for real
* driver locks. This ensures lockdep connects the ordering learned
* here with the actual locks used at runtime.
*/
lockdep_set_class(&userq_sch_mutex, &amdgpu_userq_sch_mutex_key);
lockdep_set_class(&userq_mutex, &amdgpu_userq_mutex_key);
lockdep_set_class(&notifier_lock, &amdgpu_notifier_lock_key);
lockdep_set_class(&vram_lock, &amdgpu_vram_lock_key);
lockdep_set_class(&reset_domain->sem, &amdgpu_reset_sem_key);
lockdep_set_class(&reset_ctl.reset_lock, &amdgpu_reset_lock_key);
lockdep_set_class(&srbm_mutex, &amdgpu_srbm_lock_key);
lockdep_set_class(&grbm_idx_mutex, &amdgpu_grbm_lock_key);
lockdep_set_class(&mmio_idx_lock, &amdgpu_mmio_lock_key);
/*
* Take locks in the correct order to train lockdep.
* This establishes the dependency chain.
*/
/* Level 1: Global userq scheduler mutex (outermost) */
mutex_lock(&userq_sch_mutex);
/* Level 2: Per-context userq mutex */
mutex_lock(&userq_mutex);
/* Level 3: MMU notifier lock */
mutex_lock(&notifier_lock);
/* Level 4: VRAM allocator lock */
mutex_lock(&vram_lock);
/* Level 5: Reset domain semaphore */
down_read(&reset_domain->sem);
/* Level 6: Reset control lock */
mutex_lock(&reset_ctl.reset_lock);
/*
* Mark potential memory reclaim boundary.
* GPU operations might trigger memory allocation/reclaim.
*/
fs_reclaim_acquire(GFP_KERNEL);
/* Level 7: SRBM register access */
mutex_lock(&srbm_mutex);
/* Level 8: GRBM index access */
mutex_lock(&grbm_idx_mutex);
/* Level 9: MMIO index access (innermost lock, spinlock) */
spin_lock_irqsave(&mmio_idx_lock, flags);
/*
* All locks acquired in order.
* Lockdep has now learned the valid dependency chain.
*/
/* Release in reverse order */
spin_unlock_irqrestore(&mmio_idx_lock, flags);
mutex_unlock(&grbm_idx_mutex);
mutex_unlock(&srbm_mutex);
fs_reclaim_release(GFP_KERNEL);
mutex_unlock(&reset_ctl.reset_lock);
up_read(&reset_domain->sem);
mutex_unlock(&vram_lock);
mutex_unlock(&notifier_lock);
mutex_unlock(&userq_mutex);
mutex_unlock(&userq_sch_mutex);
/* Cleanup */
amdgpu_reset_put_reset_domain(reset_domain);
pr_info("AMDGPU: Lockdep annotations initialized (9 lock levels)\n");
return 0;
}
#endif /* CONFIG_LOCKDEP */

View File

@ -0,0 +1,39 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright 2024 Advanced Micro Devices, Inc.
*
* Lockdep annotation interface for AMDGPU
*/
#ifndef __AMDGPU_LOCKDEP_H__
#define __AMDGPU_LOCKDEP_H__
#include <linux/lockdep.h>
struct amdgpu_device;
#ifdef CONFIG_LOCKDEP
/**
* amdgpu_lockdep_init - Train lockdep on correct lock ordering
*
* Call once during module init to establish the lock dependency chain.
*/
int amdgpu_lockdep_init(void);
/**
* amdgpu_lockdep_set_class - Associate lock class keys with real locks
* @adev: AMDGPU device
*
* Call during device init to associate lock classes with actual locks.
*/
void amdgpu_lockdep_set_class(struct amdgpu_device *adev);
#else /* !CONFIG_LOCKDEP */
static inline int amdgpu_lockdep_init(void) { return 0; }
static inline void amdgpu_lockdep_set_class(struct amdgpu_device *adev) {}
#endif /* CONFIG_LOCKDEP */
#endif /* __AMDGPU_LOCKDEP_H__ */

View File

@ -781,6 +781,18 @@ int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe)
return r;
}
void amdgpu_mes_validate_fw_version(struct amdgpu_device *adev)
{
u32 fw_from_ucode = adev->mes.fw_version[AMDGPU_MES_SCHED_PIPE];
u32 fw_from_reg = adev->mes.sched_version & AMDGPU_MES_VERSION_MASK;
if (fw_from_ucode != fw_from_reg)
dev_info(adev->dev,
"MES firmware reports incorrect version in ucode binary (0x%x vs 0x%x)\n",
fw_from_ucode, fw_from_reg);
}
bool amdgpu_mes_suspend_resume_all_supported(struct amdgpu_device *adev)
{
uint32_t mes_rev = adev->mes.sched_version & AMDGPU_MES_VERSION_MASK;

View File

@ -441,6 +441,7 @@ struct amdgpu_mes_funcs {
(adev)->mes.kiq_hw_fini((adev), (xcc_id))
int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe);
void amdgpu_mes_validate_fw_version(struct amdgpu_device *adev);
int amdgpu_mes_init(struct amdgpu_device *adev);
void amdgpu_mes_fini(struct amdgpu_device *adev);

View File

@ -406,7 +406,10 @@ uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset)
if (offset < adev->rmmio_size)
return (readb(adev->rmmio + offset));
BUG();
dev_err(adev->dev, "invalid MMIO read offset 0x%x (rmmio size 0x%x)\n",
offset, (unsigned int)adev->rmmio_size);
return 0;
}
/**
@ -469,10 +472,13 @@ void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value)
if (amdgpu_device_skip_hw_access(adev))
return;
if (offset < adev->rmmio_size)
if (offset < adev->rmmio_size) {
writeb(value, adev->rmmio + offset);
else
BUG();
} else {
dev_err(adev->dev, "invalid MMIO write offset 0x%x (rmmio size 0x%x)\n",
offset, (unsigned int)adev->rmmio_size);
return;
}
}
/**

View File

@ -593,7 +593,7 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
static int
amdgpu_userq_wait_count_fences(struct drm_file *filp,
struct drm_amdgpu_userq_wait *wait_info,
u32 *syncobj_handles, u32 *timeline_points,
u32 *syncobj_handles, u64 *timeline_points,
u32 *timeline_handles,
struct drm_gem_object **gobj_write,
struct drm_gem_object **gobj_read)
@ -703,7 +703,7 @@ amdgpu_userq_wait_add_fence(struct drm_amdgpu_userq_wait *wait_info,
static int
amdgpu_userq_wait_return_fence_info(struct drm_file *filp,
struct drm_amdgpu_userq_wait *wait_info,
u32 *syncobj_handles, u32 *timeline_points,
u32 *syncobj_handles, u64 *timeline_points,
u32 *timeline_handles,
struct drm_gem_object **gobj_write,
struct drm_gem_object **gobj_read)
@ -906,7 +906,8 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
int num_points, num_syncobj, num_read_bo_handles, num_write_bo_handles;
u32 *syncobj_handles, *timeline_points, *timeline_handles;
u32 *syncobj_handles, *timeline_handles;
u64 *timeline_points;
struct drm_amdgpu_userq_wait *wait_info = data;
struct drm_gem_object **gobj_write;
struct drm_gem_object **gobj_read;
@ -935,7 +936,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
}
ptr = u64_to_user_ptr(wait_info->syncobj_timeline_points);
timeline_points = memdup_array_user(ptr, num_points, sizeof(u32));
timeline_points = memdup_array_user(ptr, num_points, sizeof(u64));
if (IS_ERR(timeline_points)) {
r = PTR_ERR(timeline_points);
goto free_timeline_handles;

View File

@ -7530,6 +7530,24 @@ static int gfx_v10_0_hw_init(struct amdgpu_ip_block *ip_block)
if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(10, 3, 0) && !amdgpu_sriov_vf(adev))
gfx_v10_3_set_power_brake_sequence(adev);
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
if (r)
goto err_priv_inst;
r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
if (r)
goto err_bad_op;
return 0;
err_bad_op:
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
err_priv_inst:
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
return r;
}
@ -7539,9 +7557,9 @@ static int gfx_v10_0_hw_fini(struct amdgpu_ip_block *ip_block)
cancel_delayed_work_sync(&adev->gfx.idle_work);
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
/* WA added for Vangogh asic fixing the SMU suspend failure
* It needs to set power gating again during gfxoff control
@ -7837,26 +7855,6 @@ static int gfx_v10_0_early_init(struct amdgpu_ip_block *ip_block)
return gfx_v10_0_init_microcode(adev);
}
static int gfx_v10_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
if (r)
return r;
return 0;
}
static bool gfx_v10_0_is_rlc_enabled(struct amdgpu_device *adev)
{
uint32_t rlc_cntl;
@ -9805,7 +9803,6 @@ static void gfx_v10_0_ring_end_use(struct amdgpu_ring *ring)
static const struct amd_ip_funcs gfx_v10_0_ip_funcs = {
.name = "gfx_v10_0",
.early_init = gfx_v10_0_early_init,
.late_init = gfx_v10_0_late_init,
.sw_init = gfx_v10_0_sw_init,
.sw_fini = gfx_v10_0_sw_fini,
.hw_init = gfx_v10_0_hw_init,

View File

@ -4814,6 +4814,78 @@ static void gfx_v11_0_disable_gpa_mode(struct amdgpu_device *adev)
WREG32_SOC15(GC, 0, regCPG_PSP_DEBUG, data);
}
static int gfx_v11_0_set_userq_eop_interrupts(struct amdgpu_device *adev,
bool enable)
{
unsigned int irq_type;
int m, p, r;
if (adev->userq_funcs[AMDGPU_HW_IP_GFX]) {
for (m = 0; m < adev->gfx.me.num_me; m++) {
for (p = 0; p < adev->gfx.me.num_pipe_per_me; p++) {
irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
if (enable)
r = amdgpu_irq_get(adev, &adev->gfx.eop_irq, irq_type);
else
r = amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
if (r) {
if (!enable)
return r;
goto err_gfx;
}
}
}
}
if (adev->userq_funcs[AMDGPU_HW_IP_COMPUTE]) {
for (m = 0; m < adev->gfx.mec.num_mec; ++m) {
for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; p++) {
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ (m * adev->gfx.mec.num_pipe_per_mec)
+ p;
if (enable)
r = amdgpu_irq_get(adev, &adev->gfx.eop_irq, irq_type);
else
r = amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
if (r) {
if (!enable)
return r;
goto err_compute;
}
}
}
}
return 0;
err_compute:
for (p--; p >= 0; p--) {
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ (m * adev->gfx.mec.num_pipe_per_mec) + p;
amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
}
for (m--; m >= 0; m--) {
for (p = adev->gfx.mec.num_pipe_per_mec - 1; p >= 0; p--) {
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ (m * adev->gfx.mec.num_pipe_per_mec) + p;
amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
}
}
m = adev->gfx.me.num_me;
err_gfx:
for (p--; p >= 0; p--) {
irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
}
for (m--; m >= 0; m--) {
for (p = adev->gfx.me.num_pipe_per_me - 1; p >= 0; p--) {
irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
}
}
return r;
}
static int gfx_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
@ -4911,50 +4983,31 @@ static int gfx_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
if (!adev->gfx.imu_fw_version)
adev->gfx.imu_fw_version = RREG32_SOC15(GC, 0, regGFX_IMU_SCRATCH_0);
return r;
}
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
if (r)
return r;
static int gfx_v11_0_set_userq_eop_interrupts(struct amdgpu_device *adev,
bool enable)
{
unsigned int irq_type;
int m, p, r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
if (r)
goto err_priv_inst;
if (adev->userq_funcs[AMDGPU_HW_IP_GFX]) {
for (m = 0; m < adev->gfx.me.num_me; m++) {
for (p = 0; p < adev->gfx.me.num_pipe_per_me; p++) {
irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
if (enable)
r = amdgpu_irq_get(adev, &adev->gfx.eop_irq,
irq_type);
else
r = amdgpu_irq_put(adev, &adev->gfx.eop_irq,
irq_type);
if (r)
return r;
}
}
}
r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
if (r)
goto err_bad_op;
if (adev->userq_funcs[AMDGPU_HW_IP_COMPUTE]) {
for (m = 0; m < adev->gfx.mec.num_mec; ++m) {
for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; p++) {
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ (m * adev->gfx.mec.num_pipe_per_mec)
+ p;
if (enable)
r = amdgpu_irq_get(adev, &adev->gfx.eop_irq,
irq_type);
else
r = amdgpu_irq_put(adev, &adev->gfx.eop_irq,
irq_type);
if (r)
return r;
}
}
}
r = gfx_v11_0_set_userq_eop_interrupts(adev, true);
if (r)
goto err_userq_eop;
return 0;
err_userq_eop:
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
err_bad_op:
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
err_priv_inst:
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
return r;
}
static int gfx_v11_0_hw_fini(struct amdgpu_ip_block *ip_block)
@ -4963,10 +5016,10 @@ static int gfx_v11_0_hw_fini(struct amdgpu_ip_block *ip_block)
cancel_delayed_work_sync(&adev->gfx.idle_work);
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
gfx_v11_0_set_userq_eop_interrupts(adev, false);
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
if (!adev->no_hw_access) {
if (amdgpu_async_gfx_ring &&
@ -5356,30 +5409,6 @@ static int gfx_v11_0_early_init(struct amdgpu_ip_block *ip_block)
return gfx_v11_0_init_microcode(adev);
}
static int gfx_v11_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
if (r)
return r;
r = gfx_v11_0_set_userq_eop_interrupts(adev, true);
if (r)
return r;
return 0;
}
static bool gfx_v11_0_is_rlc_enabled(struct amdgpu_device *adev)
{
uint32_t rlc_cntl;
@ -7211,7 +7240,6 @@ static void gfx_v11_0_ring_end_use(struct amdgpu_ring *ring)
static const struct amd_ip_funcs gfx_v11_0_ip_funcs = {
.name = "gfx_v11_0",
.early_init = gfx_v11_0_early_init,
.late_init = gfx_v11_0_late_init,
.sw_init = gfx_v11_0_sw_init,
.sw_fini = gfx_v11_0_sw_fini,
.hw_init = gfx_v11_0_hw_init,

View File

@ -3655,6 +3655,78 @@ static void gfx_v12_0_init_golden_registers(struct amdgpu_device *adev)
}
}
static int gfx_v12_0_set_userq_eop_interrupts(struct amdgpu_device *adev,
bool enable)
{
unsigned int irq_type;
int m, p, r;
if (adev->userq_funcs[AMDGPU_HW_IP_GFX]) {
for (m = 0; m < adev->gfx.me.num_me; m++) {
for (p = 0; p < adev->gfx.me.num_pipe_per_me; p++) {
irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
if (enable)
r = amdgpu_irq_get(adev, &adev->gfx.eop_irq, irq_type);
else
r = amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
if (r) {
if (!enable)
return r;
goto err_gfx;
}
}
}
}
if (adev->userq_funcs[AMDGPU_HW_IP_COMPUTE]) {
for (m = 0; m < adev->gfx.mec.num_mec; ++m) {
for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; p++) {
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ (m * adev->gfx.mec.num_pipe_per_mec)
+ p;
if (enable)
r = amdgpu_irq_get(adev, &adev->gfx.eop_irq, irq_type);
else
r = amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
if (r) {
if (!enable)
return r;
goto err_compute;
}
}
}
}
return 0;
err_compute:
for (p--; p >= 0; p--) {
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ (m * adev->gfx.mec.num_pipe_per_mec) + p;
amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
}
for (m--; m >= 0; m--) {
for (p = adev->gfx.mec.num_pipe_per_mec - 1; p >= 0; p--) {
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ (m * adev->gfx.mec.num_pipe_per_mec) + p;
amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
}
}
m = adev->gfx.me.num_me;
err_gfx:
for (p--; p >= 0; p--) {
irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
}
for (m--; m >= 0; m--) {
for (p = adev->gfx.me.num_pipe_per_me - 1; p >= 0; p--) {
irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
}
}
return r;
}
static int gfx_v12_0_hw_init(struct amdgpu_ip_block *ip_block)
{
int r;
@ -3742,50 +3814,31 @@ static int gfx_v12_0_hw_init(struct amdgpu_ip_block *ip_block)
if (r)
return r;
return r;
}
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
if (r)
return r;
static int gfx_v12_0_set_userq_eop_interrupts(struct amdgpu_device *adev,
bool enable)
{
unsigned int irq_type;
int m, p, r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
if (r)
goto err_priv_inst;
if (adev->userq_funcs[AMDGPU_HW_IP_GFX]) {
for (m = 0; m < adev->gfx.me.num_me; m++) {
for (p = 0; p < adev->gfx.me.num_pipe_per_me; p++) {
irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + p;
if (enable)
r = amdgpu_irq_get(adev, &adev->gfx.eop_irq,
irq_type);
else
r = amdgpu_irq_put(adev, &adev->gfx.eop_irq,
irq_type);
if (r)
return r;
}
}
}
r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
if (r)
goto err_bad_op;
if (adev->userq_funcs[AMDGPU_HW_IP_COMPUTE]) {
for (m = 0; m < adev->gfx.mec.num_mec; ++m) {
for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; p++) {
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ (m * adev->gfx.mec.num_pipe_per_mec)
+ p;
if (enable)
r = amdgpu_irq_get(adev, &adev->gfx.eop_irq,
irq_type);
else
r = amdgpu_irq_put(adev, &adev->gfx.eop_irq,
irq_type);
if (r)
return r;
}
}
}
r = gfx_v12_0_set_userq_eop_interrupts(adev, true);
if (r)
goto err_userq_eop;
return 0;
err_userq_eop:
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
err_bad_op:
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
err_priv_inst:
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
return r;
}
static int gfx_v12_0_hw_fini(struct amdgpu_ip_block *ip_block)
@ -3795,10 +3848,10 @@ static int gfx_v12_0_hw_fini(struct amdgpu_ip_block *ip_block)
cancel_delayed_work_sync(&adev->gfx.idle_work);
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
gfx_v12_0_set_userq_eop_interrupts(adev, false);
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
if (!adev->no_hw_access) {
if (amdgpu_async_gfx_ring) {
@ -3927,30 +3980,6 @@ static int gfx_v12_0_early_init(struct amdgpu_ip_block *ip_block)
return gfx_v12_0_init_microcode(adev);
}
static int gfx_v12_0_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
if (r)
return r;
r = gfx_v12_0_set_userq_eop_interrupts(adev, true);
if (r)
return r;
return 0;
}
static bool gfx_v12_0_is_rlc_enabled(struct amdgpu_device *adev)
{
uint32_t rlc_cntl;
@ -5440,7 +5469,6 @@ static void gfx_v12_0_ring_end_use(struct amdgpu_ring *ring)
static const struct amd_ip_funcs gfx_v12_0_ip_funcs = {
.name = "gfx_v12_0",
.early_init = gfx_v12_0_early_init,
.late_init = gfx_v12_0_late_init,
.sw_init = gfx_v12_0_sw_init,
.sw_fini = gfx_v12_0_sw_fini,
.hw_init = gfx_v12_0_hw_init,

View File

@ -2735,6 +2735,50 @@ static void gfx_v12_1_init_golden_registers(struct amdgpu_device *adev)
}
}
static int gfx_v12_1_set_userq_eop_interrupts(struct amdgpu_device *adev,
bool enable)
{
unsigned int irq_type;
int m, p, r;
if (!adev->gfx.disable_kq)
return 0;
for (m = 0; m < adev->gfx.mec.num_mec; ++m) {
for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; p++) {
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ (m * adev->gfx.mec.num_pipe_per_mec)
+ p;
if (enable)
r = amdgpu_irq_get(adev, &adev->gfx.eop_irq, irq_type);
else
r = amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
if (r) {
if (!enable)
return r;
goto err_unwind;
}
}
}
return 0;
err_unwind:
for (p--; p >= 0; p--) {
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ (m * adev->gfx.mec.num_pipe_per_mec) + p;
amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
}
for (m--; m >= 0; m--) {
for (p = adev->gfx.mec.num_pipe_per_mec - 1; p >= 0; p--) {
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ (m * adev->gfx.mec.num_pipe_per_mec) + p;
amdgpu_irq_put(adev, &adev->gfx.eop_irq, irq_type);
}
}
return r;
}
static int gfx_v12_1_hw_init(struct amdgpu_ip_block *ip_block)
{
int r, i, num_xcc;
@ -2803,6 +2847,24 @@ static int gfx_v12_1_hw_init(struct amdgpu_ip_block *ip_block)
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
if (r)
goto err_priv_inst;
r = gfx_v12_1_set_userq_eop_interrupts(adev, true);
if (r)
goto err_userq_eop;
return 0;
err_userq_eop:
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
err_priv_inst:
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
return r;
}
@ -2828,41 +2890,14 @@ static void gfx_v12_1_xcc_fini(struct amdgpu_device *adev,
gfx_v12_1_xcc_enable_gui_idle_interrupt(adev, false, xcc_id);
}
static int gfx_v12_1_set_userq_eop_interrupts(struct amdgpu_device *adev,
bool enable)
{
unsigned int irq_type;
int m, p, r;
if (adev->gfx.disable_kq) {
for (m = 0; m < adev->gfx.mec.num_mec; ++m) {
for (p = 0; p < adev->gfx.mec.num_pipe_per_mec; p++) {
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
+ (m * adev->gfx.mec.num_pipe_per_mec)
+ p;
if (enable)
r = amdgpu_irq_get(adev, &adev->gfx.eop_irq,
irq_type);
else
r = amdgpu_irq_put(adev, &adev->gfx.eop_irq,
irq_type);
if (r)
return r;
}
}
}
return 0;
}
static int gfx_v12_1_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
int i, num_xcc;
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
gfx_v12_1_set_userq_eop_interrupts(adev, false);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
num_xcc = NUM_XCC(adev->gfx.xcc_mask);
for (i = 0; i < num_xcc; i++) {
@ -2963,26 +2998,6 @@ static int gfx_v12_1_early_init(struct amdgpu_ip_block *ip_block)
return gfx_v12_1_init_microcode(adev);
}
static int gfx_v12_1_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
if (r)
return r;
r = gfx_v12_1_set_userq_eop_interrupts(adev, true);
if (r)
return r;
return 0;
}
static bool gfx_v12_1_is_rlc_enabled(struct amdgpu_device *adev)
{
uint32_t rlc_cntl;
@ -3876,7 +3891,6 @@ static void gfx_v12_1_emit_mem_sync(struct amdgpu_ring *ring)
static const struct amd_ip_funcs gfx_v12_1_ip_funcs = {
.name = "gfx_v12_1",
.early_init = gfx_v12_1_early_init,
.late_init = gfx_v12_1_late_init,
.sw_init = gfx_v12_1_sw_init,
.sw_fini = gfx_v12_1_sw_fini,
.hw_init = gfx_v12_1_hw_init,

View File

@ -4050,6 +4050,24 @@ static int gfx_v9_0_hw_init(struct amdgpu_ip_block *ip_block)
!amdgpu_sriov_vf(adev))
gfx_v9_4_2_set_power_brake_sequence(adev);
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
if (r)
goto err_priv_inst;
r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
if (r)
goto err_bad_op;
return 0;
err_bad_op:
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
err_priv_inst:
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
return r;
}
@ -4057,9 +4075,9 @@ static int gfx_v9_0_hw_fini(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
/* DF freeze and kcq disable will fail */
if (!amdgpu_ras_intr_triggered())
@ -4860,18 +4878,6 @@ static int gfx_v9_0_late_init(struct amdgpu_ip_block *ip_block)
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
if (r)
return r;
r = gfx_v9_0_ecc_late_init(ip_block);
if (r)
return r;

View File

@ -2371,6 +2371,24 @@ static int gfx_v9_4_3_hw_init(struct amdgpu_ip_block *ip_block)
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
if (r)
goto err_priv_inst;
r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
if (r)
goto err_bad_op;
return 0;
err_bad_op:
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
err_priv_inst:
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
return r;
}
@ -2446,9 +2464,9 @@ static int gfx_v9_4_3_hw_fini(struct amdgpu_ip_block *ip_block)
if (adev->psp.ptl.hw_supported && !amdgpu_in_reset(adev))
gfx_v9_4_3_perf_monitor_ptl_init(adev, false);
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
num_xcc = NUM_XCC(adev->gfx.xcc_mask);
for (i = 0; i < num_xcc; i++) {
@ -2611,19 +2629,6 @@ static int gfx_v9_4_3_early_init(struct amdgpu_ip_block *ip_block)
static int gfx_v9_4_3_late_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
int r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_reg_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.priv_inst_irq, 0);
if (r)
return r;
r = amdgpu_irq_get(adev, &adev->gfx.bad_op_irq, 0);
if (r)
return r;
if (adev->gfx.ras &&
adev->gfx.ras->enable_watchdog_timer)

View File

@ -1688,6 +1688,7 @@ static int mes_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
if (r)
goto failure;
amdgpu_mes_validate_fw_version(adev);
out:
/*
* Disable KIQ ring usage from the driver once MES is enabled.

View File

@ -1871,6 +1871,7 @@ static int mes_v12_0_hw_init(struct amdgpu_ip_block *ip_block)
if (r)
goto failure;
amdgpu_mes_validate_fw_version(adev);
out:
/*
* Disable KIQ ring usage from the driver once MES is enabled.

View File

@ -1917,6 +1917,7 @@ static int mes_v12_1_xcc_hw_init(struct amdgpu_ip_block *ip_block, int xcc_id)
goto failure;
}
amdgpu_mes_validate_fw_version(adev);
out:
/*
* Disable KIQ ring usage from the driver once MES is enabled.

View File

@ -308,7 +308,7 @@ void xgpu_vi_init_golden_registers(struct amdgpu_device *adev)
xgpu_tonga_golden_common_all));
break;
default:
BUG_ON("Doesn't support chip type.\n");
dev_err(adev->dev, "Doesn't support chip type %d\n", adev->asic_type);
break;
}
}

View File

@ -1234,6 +1234,38 @@ static const struct amdgpu_ring_funcs vcn_v5_0_0_unified_ring_vm_funcs = {
.reset = vcn_v5_0_0_ring_reset,
};
static const struct amdgpu_ring_funcs vcn_v5_0_0_unified_ring_vm_funcs_secure = {
.type = AMDGPU_RING_TYPE_VCN_ENC,
.align_mask = 0x3f,
.nop = VCN_ENC_CMD_NO_OP,
.secure_submission_supported = true,
.no_user_fence = true,
.get_rptr = vcn_v5_0_0_unified_ring_get_rptr,
.get_wptr = vcn_v5_0_0_unified_ring_get_wptr,
.set_wptr = vcn_v5_0_0_unified_ring_set_wptr,
.emit_frame_size =
SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
1, /* vcn_v2_0_enc_ring_insert_end */
.emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
.emit_ib = vcn_v2_0_enc_ring_emit_ib,
.emit_fence = vcn_v2_0_enc_ring_emit_fence,
.emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
.test_ring = amdgpu_vcn_enc_ring_test_ring,
.test_ib = amdgpu_vcn_unified_ring_test_ib,
.insert_nop = amdgpu_ring_insert_nop,
.insert_end = vcn_v2_0_enc_ring_insert_end,
.pad_ib = amdgpu_ring_generic_pad_ib,
.begin_use = amdgpu_vcn_ring_begin_use,
.end_use = amdgpu_vcn_ring_end_use,
.emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
.emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
.reset = vcn_v5_0_0_ring_reset,
};
/**
* vcn_v5_0_0_set_unified_ring_funcs - set unified ring functions
*
@ -1249,7 +1281,12 @@ static void vcn_v5_0_0_set_unified_ring_funcs(struct amdgpu_device *adev)
if (adev->vcn.harvest_config & (1 << i))
continue;
adev->vcn.inst[i].ring_enc[0].funcs = &vcn_v5_0_0_unified_ring_vm_funcs;
if (amdgpu_ip_version(adev, VCN_HWIP, 0) == IP_VERSION(5, 3, 0))
adev->vcn.inst[i].ring_enc[0].funcs =
&vcn_v5_0_0_unified_ring_vm_funcs_secure;
else
adev->vcn.inst[i].ring_enc[0].funcs =
&vcn_v5_0_0_unified_ring_vm_funcs;
adev->vcn.inst[i].ring_enc[0].me = i;
}
}

View File

@ -1404,6 +1404,14 @@ int kfd_parse_crat_table(void *crat_image, struct list_head *device_list,
sub_type_hdr = (struct crat_subtype_generic *)(crat_table+1);
while ((char *)sub_type_hdr + sizeof(struct crat_subtype_generic) <
((char *)crat_image) + image_len) {
if (!sub_type_hdr->length ||
sub_type_hdr->length < sizeof(struct crat_subtype_generic)) {
pr_warn("Invalid CRAT subtype length %u\n",
sub_type_hdr->length);
ret = -EINVAL;
break;
}
if (sub_type_hdr->flags & CRAT_SUBTYPE_FLAGS_ENABLED) {
ret = kfd_parse_subtype(sub_type_hdr, device_list);
if (ret)

View File

@ -832,6 +832,12 @@ int kfd_dbg_trap_enable(struct kfd_process *target, uint32_t fd,
if (copy_to_user(runtime_info, (void *)&target->runtime_info, copy_size)) {
kfd_dbg_trap_deactivate(target, false, 0);
fput(target->dbg_ev_file);
target->dbg_ev_file = NULL;
if (target->debugger_process)
atomic_dec(&target->debugger_process->debugged_process_count);
target->debug_trap_enabled = false;
kfd_unref_process(target);
r = -EFAULT;
}

View File

@ -3264,32 +3264,24 @@ int kfd_dqm_suspend_bad_queue_mes(struct kfd_node *knode, u32 pasid, u32 doorbel
list_for_each_entry(q, &qpd->queues_list, list) {
if (q->doorbell_id == doorbell_id && q->properties.is_active) {
ret = suspend_all_queues_mes(dqm);
if (ret) {
dev_err(dev, "Suspending all queues failed");
goto out;
}
/* suspend all queues will save any good queues and mark the rest as bad */
suspend_all_queues_mes(dqm);
q->properties.is_evicted = true;
q->properties.is_active = false;
decrement_queue_count(dqm, qpd, q);
/* this will remove the bad queue and sched a GPU reset if needed */
ret = remove_queue_mes(dqm, q, qpd);
if (ret) {
dev_err(dev, "Removing bad queue failed");
goto out;
}
ret = resume_all_queues_mes(dqm);
if (ret)
dev_err(dev, "Resuming all queues failed");
dev_err(dev, "Removing bad queue failed");
/* resume the good queues */
resume_all_queues_mes(dqm);
break;
}
}
}
out:
dqm_unlock(dqm);
kfd_unref_process(p);
return ret;

View File

@ -800,6 +800,8 @@ static struct kfd_event_waiter *alloc_event_waiters(uint32_t num_events)
struct kfd_event_waiter *event_waiters;
uint32_t i;
if (num_events > KFD_SIGNAL_EVENT_LIMIT)
return NULL;
event_waiters = kzalloc_objs(struct kfd_event_waiter, num_events);
if (!event_waiters)
return NULL;

View File

@ -254,8 +254,10 @@ void kfd_smi_event_update_vmfault(struct kfd_node *dev, uint16_t pasid)
if (task_info) {
/* Report VM faults from user applications, not retry from kernel */
if (task_info->task.pid)
kfd_smi_event_add(0, dev, KFD_SMI_EVENT_VMFAULT, KFD_EVENT_FMT_VMFAULT(
task_info->task.pid, task_info->task.comm));
kfd_smi_event_add(task_info->tgid, dev,
KFD_SMI_EVENT_VMFAULT,
KFD_EVENT_FMT_VMFAULT(task_info->task.pid,
task_info->task.comm));
amdgpu_vm_put_task_info(task_info);
}
}
@ -356,7 +358,7 @@ void kfd_smi_event_process(struct kfd_process_device *pdd, bool start)
task_info = amdgpu_vm_get_task_info_vm(avm);
if (task_info) {
kfd_smi_event_add(0, pdd->dev,
kfd_smi_event_add(task_info->tgid, pdd->dev,
start ? KFD_SMI_EVENT_PROCESS_START :
KFD_SMI_EVENT_PROCESS_END,
KFD_EVENT_FMT_PROCESS(task_info->task.pid,

View File

@ -198,8 +198,7 @@ struct kfd_topology_device *kfd_create_topology_device(
#define sysfs_show_gen_prop(buffer, offs, fmt, ...) \
(offs += snprintf(buffer+offs, PAGE_SIZE-offs, \
fmt, __VA_ARGS__))
(offs += sysfs_emit_at(buffer, offs, fmt, __VA_ARGS__))
#define sysfs_show_32bit_prop(buffer, offs, name, value) \
sysfs_show_gen_prop(buffer, offs, "%s %u\n", name, value)
#define sysfs_show_64bit_prop(buffer, offs, name, value) \

View File

@ -13837,17 +13837,15 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
}
/* Handle MCCS */
if (do_mccs)
if (do_mccs) {
dm_helpers_read_mccs_caps(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
if ((sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A ||
as_type == FREESYNC_TYPE_PCON_IN_WHITELIST) &&
(!sink->edid_caps.freesync_vcp_code ||
(sink->edid_caps.freesync_vcp_code && !sink->mccs_caps.freesync_supported)))
freesync_capable = false;
if (sink->edid_caps.freesync_vcp_code && !sink->mccs_caps.freesync_supported)
freesync_capable = false;
if (do_mccs && sink->mccs_caps.freesync_supported && freesync_capable)
dm_helpers_mccs_vcp_set(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
if (sink->mccs_caps.freesync_supported && freesync_capable)
dm_helpers_mccs_vcp_set(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
}
update:
if (dm_con_state)

View File

@ -968,7 +968,7 @@ bool dm_helpers_is_dp_sink_present(struct dc_link *link)
struct amdgpu_dm_connector *aconnector = link->priv;
if (!aconnector) {
BUG_ON("Failed to find connector for link!");
DRM_ERROR("Failed to find connector for link!");
return true;
}

View File

@ -266,7 +266,7 @@ struct dc_hdmi_frl_link_settings {
};
struct dc_hdmi_frl_flags {
int force_frl_rate;
unsigned int force_frl_rate;
bool ignore_ffe;
int select_ffe;
int limit_ffe;

View File

@ -1060,7 +1060,7 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struct dc_state *context)
{
int plane_count;
int i;
unsigned int i;
plane_count = 0;
for (i = 0; i < dc->res_pool->pipe_count; i++) {

View File

@ -48,6 +48,7 @@ static enum dml2_project_id dml21_dcn_revision_to_dml2_project_id(enum dce_versi
project_id = dml2_project_dcn4x_stage2_auto_drr_svp;
break;
case DCN_VERSION_4_2:
case DCN_VERSION_4_2B:
project_id = dml2_project_dcn42;
break;
default:

View File

@ -143,8 +143,8 @@ void hpo_enc401_read_state(
struct hpo_frl_stream_encoder *enc,
struct hpo_frl_stream_encoder_state *state)
{
int pixel_encoding;
int color_depth;
uint32_t pixel_encoding;
uint32_t color_depth;
// int odm_combine;
struct dcn401_hpo_frl_stream_encoder *enc401 = DCN401_HPO_FRL_STRENC_FROM_HPO_FRL_STRENC(enc);

View File

@ -261,8 +261,8 @@ enum {
#define ASICREV_IS_GC_11_0_0(eChipRev) (eChipRev < GC_11_0_2_A0)
#define ASICREV_IS_GC_11_0_2(eChipRev) (eChipRev >= GC_11_0_2_A0 && eChipRev < GC_11_0_3_A0)
#define ASICREV_IS_GC_11_0_3(eChipRev) (eChipRev >= GC_11_0_3_A0 && eChipRev < GC_11_UNKNOWN)
#define ASICREV_IS_GC_11_0_4(eChipRev) (eChipRev >= GC_11_0_4_A0 && eChipRev < GC_11_UNKNOWN)
#define ASICREV_IS_GC_11_0_3(eChipRev) (eChipRev >= GC_11_0_3_A0 && eChipRev < GC_11_0_4_A0)
#define ASICREV_IS_GC_11_0_4(eChipRev) (eChipRev >= GC_11_0_4_A0 && eChipRev < DCN4A_SOC_VAR_B_A0)
#define ASICREV_IS_DCN36(eChipRev) ((eChipRev) >= 0x50 && (eChipRev) < 0xC0)
#define AMDGPU_FAMILY_GC_12_0_0 152 /* GC 12.0.0 */

View File

@ -806,6 +806,8 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,
while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) {
if (strlen(sub_str) == 0)
continue;
if (parameter_size >= ARRAY_SIZE(parameter))
return -EINVAL;
ret = kstrtol(sub_str, 0, &parameter[parameter_size]);
if (ret)
return -EINVAL;
@ -874,6 +876,8 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,
for (clk_index = 0 ; clk_index < ARRAY_SIZE(od_clocks) ; clk_index++) {
amdgpu_dpm_emit_clock_levels(adev, od_clocks[clk_index], buf, &size);
if (unlikely(size >= (PAGE_SIZE - 1)))
break;
}
if (size == 0)
@ -1389,7 +1393,6 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
long parameter[64];
char *sub_str, buf_cpy[128];
char *tmp_str;
uint32_t i = 0;
char tmp[2];
long int profile_mode = 0;
const char delimiter[3] = {' ', '\n', '\0'};
@ -1398,18 +1401,18 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
if (count == 0 || sysfs_streq(buf, ""))
return -EINVAL;
tmp[0] = *(buf);
tmp[0] = *(buf++);
tmp[1] = '\0';
ret = kstrtol(tmp, 0, &profile_mode);
if (ret)
return -EINVAL;
if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
if (count < 2 || count > 127)
if (count < 2 || count > sizeof(buf_cpy))
return -EINVAL;
while (isspace(*++buf))
i++;
memcpy(buf_cpy, buf, count-i);
while (isspace(*buf))
buf++;
strscpy(buf_cpy, buf, sizeof(buf_cpy));
tmp_str = buf_cpy;
while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) {
if (strlen(sub_str) == 0)
@ -3955,6 +3958,7 @@ static int parse_input_od_command_lines(const char *buf,
size_t count,
u32 *type,
long *params,
size_t params_max,
uint32_t *num_of_params)
{
const char delimiter[3] = {' ', '\n', '\0'};
@ -3990,6 +3994,9 @@ static int parse_input_od_command_lines(const char *buf,
if (strlen(sub_str) == 0)
continue;
if (parameter_size >= params_max)
return -EINVAL;
ret = kstrtol(sub_str, 0, &params[parameter_size]);
if (ret)
return -EINVAL;
@ -4021,6 +4028,7 @@ amdgpu_distribute_custom_od_settings(struct amdgpu_device *adev,
count,
&cmd_type,
parameter,
ARRAY_SIZE(parameter),
&parameter_size);
if (ret)
return ret;