mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
amd-drm-next-7.3-2026-08-12:
amdgpu: - Bounds checking fix in CS IOCTL - Bounds checking fix in GEM IOCTL - Display fixes - GPUVM fix - ASPM fix - UVD bounds checking fixes - VCE 3 fix - BT.2020 fixes - NBIF 6.3.1 fix - IP discovery fix - SMU metrics reporting fixes - SMU 15 fixes - Misc fixes - MES 11 fix - Frame size fix for some versions of clang - Userq fixes - GTT recovery fix amdkfd: - Hibernation fix - Kernel-doc warning fixes radeon: - Runtime pm fix -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCanzozgAKCRC93/aFa7yZ 2D5aAQDm97U8hKFIu1M3dy/TjD089EgWiVlCtzo0SWaVwUwSGQD/fg7keJ8uvE9q 4qEzJcSlohqjLsfv6Kg0ZrcYLobNFwk= =/gcw -----END PGP SIGNATURE----- Merge tag 'amd-drm-next-7.3-2026-08-12' of https://gitlab.freedesktop.org/agd5f/linux into drm-next amd-drm-next-7.3-2026-08-12: amdgpu: - Bounds checking fix in CS IOCTL - Bounds checking fix in GEM IOCTL - Display fixes - GPUVM fix - ASPM fix - UVD bounds checking fixes - VCE 3 fix - BT.2020 fixes - NBIF 6.3.1 fix - IP discovery fix - SMU metrics reporting fixes - SMU 15 fixes - Misc fixes - MES 11 fix - Frame size fix for some versions of clang - Userq fixes - GTT recovery fix amdkfd: - Hibernation fix - Kernel-doc warning fixes radeon: - Runtime pm fix Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patch.msgid.link/20260812214716.2156632-1-alexander.deucher@amd.com
This commit is contained in:
commit
8fc6d9951b
|
|
@ -243,6 +243,10 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
|
|||
if (size < sizeof(struct drm_amdgpu_cs_chunk_fence))
|
||||
goto free_partial_kdata;
|
||||
|
||||
/* Only a single user fence is allowed to simplify handling. */
|
||||
if (p->uf_bo)
|
||||
goto free_partial_kdata;
|
||||
|
||||
ret = amdgpu_cs_p1_user_fence(p, p->chunks[i].kdata,
|
||||
&uf_offset);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -1338,6 +1338,31 @@ static bool amdgpu_device_aspm_support_quirk(struct amdgpu_device *adev)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Some dGPUs expose their display endpoint below an internal PCIe switch.
|
||||
* Use the switch upstream port to query the host-facing link.
|
||||
*/
|
||||
static struct pci_dev *amdgpu_device_get_aspm_pdev(struct amdgpu_device *adev)
|
||||
{
|
||||
struct pci_dev *swds, *swus;
|
||||
|
||||
swds = pci_upstream_bridge(adev->pdev);
|
||||
if (!swds ||
|
||||
(swds->vendor != PCI_VENDOR_ID_ATI &&
|
||||
swds->vendor != PCI_VENDOR_ID_AMD) ||
|
||||
pci_pcie_type(swds) != PCI_EXP_TYPE_DOWNSTREAM)
|
||||
return adev->pdev;
|
||||
|
||||
swus = pci_upstream_bridge(swds);
|
||||
if (!swus ||
|
||||
(swus->vendor != PCI_VENDOR_ID_ATI &&
|
||||
swus->vendor != PCI_VENDOR_ID_AMD) ||
|
||||
pci_pcie_type(swus) != PCI_EXP_TYPE_UPSTREAM)
|
||||
return adev->pdev;
|
||||
|
||||
return swus;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_should_use_aspm - check if the device should program ASPM
|
||||
*
|
||||
|
|
@ -1350,6 +1375,9 @@ static bool amdgpu_device_aspm_support_quirk(struct amdgpu_device *adev)
|
|||
*/
|
||||
bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
|
||||
{
|
||||
struct pci_dev *aspm_pdev, *parent;
|
||||
bool enabled;
|
||||
|
||||
switch (amdgpu_aspm) {
|
||||
case -1:
|
||||
break;
|
||||
|
|
@ -1364,7 +1392,27 @@ bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
|
|||
return false;
|
||||
if (amdgpu_device_aspm_support_quirk(adev))
|
||||
return false;
|
||||
return pcie_aspm_enabled(adev->pdev);
|
||||
|
||||
/*
|
||||
* pcie_aspm_enabled() checks the link between its argument and
|
||||
* the immediate upstream bridge. Use SWUS for dGPUs with an
|
||||
* internal switch so that this is the host-facing link.
|
||||
*/
|
||||
aspm_pdev = amdgpu_device_get_aspm_pdev(adev);
|
||||
parent = pci_upstream_bridge(aspm_pdev);
|
||||
if (!parent) {
|
||||
dev_dbg(adev->dev, "ASPM: no upstream PCIe link for %s\n",
|
||||
pci_name(aspm_pdev));
|
||||
return false;
|
||||
}
|
||||
|
||||
enabled = pcie_aspm_enabled(aspm_pdev);
|
||||
/* Report the exact link used for the automatic ASPM decision. */
|
||||
dev_dbg(adev->dev, "ASPM: link %s <-> %s is %s\n",
|
||||
pci_name(parent), pci_name(aspm_pdev),
|
||||
enabled ? "enabled" : "disabled");
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/* if we get transitioned to only one device, take VGA back */
|
||||
|
|
@ -3162,8 +3210,6 @@ static int amdgpu_device_ip_suspend(struct amdgpu_device *adev)
|
|||
amdgpu_virt_request_full_gpu(adev, false);
|
||||
}
|
||||
|
||||
amdgpu_ttm_disable_buffer_funcs(adev);
|
||||
|
||||
r = amdgpu_device_ip_suspend_phase1(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
|
|
|||
|
|
@ -397,6 +397,25 @@ const struct drm_gem_object_funcs amdgpu_gem_object_funcs = {
|
|||
.vm_ops = &amdgpu_gem_vm_ops,
|
||||
};
|
||||
|
||||
static bool amdgpu_gem_are_domains_valid(u32 domains)
|
||||
{
|
||||
u32 normal = AMDGPU_GEM_DOMAIN_CPU |
|
||||
AMDGPU_GEM_DOMAIN_GTT |
|
||||
AMDGPU_GEM_DOMAIN_VRAM;
|
||||
/* Treat all non CPU/GTT/VRAM domains as special domains. */
|
||||
u32 special = AMDGPU_GEM_DOMAIN_MASK & ~normal;
|
||||
u32 normal_mask = domains & normal;
|
||||
u32 special_mask = domains & special;
|
||||
|
||||
if (!special_mask)
|
||||
return true;
|
||||
|
||||
if (normal_mask)
|
||||
return false;
|
||||
|
||||
return !(special_mask & (special_mask - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* GEM ioctls.
|
||||
*/
|
||||
|
|
@ -421,6 +440,8 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
|
|||
/* reject invalid gem domains */
|
||||
if (args->in.domains & ~AMDGPU_GEM_DOMAIN_MASK)
|
||||
return -EINVAL;
|
||||
if (!amdgpu_gem_are_domains_valid(args->in.domains))
|
||||
return -EINVAL;
|
||||
|
||||
if (!amdgpu_is_tmz(adev) && (flags & AMDGPU_GEM_CREATE_ENCRYPTED)) {
|
||||
DRM_NOTE_ONCE("Cannot allocate secure buffer since TMZ is disabled\n");
|
||||
|
|
|
|||
|
|
@ -102,6 +102,29 @@ bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *res)
|
|||
return drm_mm_node_allocated(&node->mm_nodes[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gtt_mgr_mark_bo_teardown - exclude a BO from GART recovery
|
||||
*
|
||||
* @tbo: TTM BO whose TT backing is about to be destroyed
|
||||
*
|
||||
* Keep the GART range allocated until the resource is freed, but make recovery
|
||||
* treat it like a range without a BO so it isn't touched after TT teardown has
|
||||
* started.
|
||||
*/
|
||||
void amdgpu_gtt_mgr_mark_bo_teardown(struct ttm_buffer_object *tbo)
|
||||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev);
|
||||
struct ttm_range_mgr_node *node = to_ttm_range_mgr_node(tbo->resource);
|
||||
struct amdgpu_gtt_mgr *mgr = &adev->mman.gtt_mgr;
|
||||
|
||||
dma_resv_assert_held(tbo->base.resv);
|
||||
|
||||
spin_lock(&mgr->lock);
|
||||
if (drm_mm_node_allocated(&node->mm_nodes[0]))
|
||||
node->mm_nodes[0].color = GART_ENTRY_WITHOUT_BO_COLOR;
|
||||
spin_unlock(&mgr->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gtt_mgr_new - allocate a new node
|
||||
*
|
||||
|
|
|
|||
|
|
@ -131,6 +131,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
|
|||
struct amdgpu_fence *af;
|
||||
struct amdgpu_fence *vm_af;
|
||||
bool need_ctx_switch;
|
||||
bool emit_spm_needed = false;
|
||||
bool emit_gds_needed = false;
|
||||
struct amdgpu_vm *vm;
|
||||
uint64_t fence_ctx;
|
||||
uint32_t status = 0, alloc_size;
|
||||
|
|
@ -220,7 +222,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
|
|||
vm_af = job->hw_vm_fence;
|
||||
/* VM sequence */
|
||||
vm_af->ib_wptr = ring->wptr;
|
||||
amdgpu_vm_flush(ring, job, need_pipe_sync);
|
||||
amdgpu_vm_flush(ring, job, need_pipe_sync, &emit_spm_needed,
|
||||
&emit_gds_needed);
|
||||
vm_af->ib_dw_size =
|
||||
amdgpu_ring_get_dw_distance(ring, vm_af->ib_wptr, ring->wptr);
|
||||
}
|
||||
|
|
@ -232,6 +235,15 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
|
|||
if (ring->funcs->insert_start)
|
||||
ring->funcs->insert_start(ring);
|
||||
|
||||
if (emit_spm_needed)
|
||||
adev->gfx.rlc.funcs->update_spm_vmid(adev, ring->xcc_id, ring, job->vmid);
|
||||
|
||||
if (emit_gds_needed)
|
||||
amdgpu_ring_emit_gds_switch(ring, job->vmid, job->gds_base,
|
||||
job->gds_size, job->gws_base,
|
||||
job->gws_size, job->oa_base,
|
||||
job->oa_size);
|
||||
|
||||
if ((ib->flags & AMDGPU_IB_FLAG_EMIT_MEM_SYNC) && ring->funcs->emit_mem_sync)
|
||||
ring->funcs->emit_mem_sync(ring);
|
||||
|
||||
|
|
|
|||
|
|
@ -1694,6 +1694,9 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
|
|||
static void
|
||||
amdgpu_bo_delete_mem_notify(struct ttm_buffer_object *bo)
|
||||
{
|
||||
if (bo->resource && bo->resource->mem_type == TTM_PL_TT)
|
||||
amdgpu_gtt_mgr_mark_bo_teardown(bo);
|
||||
|
||||
amdgpu_bo_move_notify(bo, false, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev);
|
|||
void amdgpu_vram_mgr_fini(struct amdgpu_device *adev);
|
||||
|
||||
bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *mem);
|
||||
void amdgpu_gtt_mgr_mark_bo_teardown(struct ttm_buffer_object *tbo);
|
||||
void amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr);
|
||||
|
||||
int amdgpu_gtt_mgr_alloc_entries(struct amdgpu_gtt_mgr *mgr,
|
||||
|
|
|
|||
|
|
@ -1070,6 +1070,16 @@ amdgpu_userq_vm_validate_and_restore_queue(struct amdgpu_userq_mgr *uq_mgr)
|
|||
if (ret)
|
||||
goto unlock_all;
|
||||
|
||||
/*
|
||||
* PRT/sparse mappings are kept off the vm_bo state lists, so
|
||||
* amdgpu_vm_handle_moved() does not touch them. Refresh their PTEs
|
||||
* explicitly here (as the CS path does) so sparse mappings survive a
|
||||
* VRAM-lost reset.
|
||||
*/
|
||||
ret = amdgpu_vm_bo_update(adev, fpriv->prt_va, false);
|
||||
if (ret)
|
||||
goto unlock_all;
|
||||
|
||||
key = 0;
|
||||
/* Validate User Ptr BOs */
|
||||
list_for_each_entry(bo_va, &vm->always_valid.idle, base.vm_status) {
|
||||
|
|
@ -1127,6 +1137,12 @@ amdgpu_userq_vm_validate_and_restore_queue(struct amdgpu_userq_mgr *uq_mgr)
|
|||
*/
|
||||
list_for_each_entry(bo_va, &vm->always_valid.idle, base.vm_status)
|
||||
dma_fence_wait(bo_va->last_pt_update, false);
|
||||
/*
|
||||
* The PRT bo_va is kept off the state lists, so its PTE update fence
|
||||
* lands in prt_va->last_pt_update rather than vm->last_update; wait on
|
||||
* it explicitly (as the CS path syncs it) before restarting queues.
|
||||
*/
|
||||
dma_fence_wait(fpriv->prt_va->last_pt_update, false);
|
||||
dma_fence_wait(vm->last_update, false);
|
||||
|
||||
xa_for_each(&uq_mgr->userq_xa, tmp_key, queue) {
|
||||
|
|
|
|||
|
|
@ -646,17 +646,15 @@ static int amdgpu_uvd_cs_msg_decode(struct amdgpu_device *adev, uint32_t *msg,
|
|||
unsigned int height = msg[7];
|
||||
unsigned int dpb_size = msg[9];
|
||||
unsigned int pitch = msg[28];
|
||||
unsigned int level = msg[57];
|
||||
|
||||
unsigned int width_in_mb = width / 16;
|
||||
unsigned int height_in_mb = ALIGN(height / 16, 2);
|
||||
unsigned int fs_in_mb = width_in_mb * height_in_mb;
|
||||
|
||||
unsigned int image_size, tmp, min_dpb_size, num_dpb_buffer;
|
||||
unsigned int min_ctx_size = ~0;
|
||||
|
||||
/* Reject invalid dimensions to prevent division by zero */
|
||||
if (width < 16 || height < 16) {
|
||||
/* Reject invalid dimensions */
|
||||
if (width < 16 || height < 16 || width > 4096 || height > 4096) {
|
||||
dev_WARN_ONCE(adev->dev, 1,
|
||||
"Invalid UVD decoding dimensions (%dx%d)!\n",
|
||||
width, height);
|
||||
|
|
@ -669,35 +667,9 @@ static int amdgpu_uvd_cs_msg_decode(struct amdgpu_device *adev, uint32_t *msg,
|
|||
|
||||
switch (stream_type) {
|
||||
case 0: /* H264 */
|
||||
switch (level) {
|
||||
case 30:
|
||||
num_dpb_buffer = 8100 / fs_in_mb;
|
||||
break;
|
||||
case 31:
|
||||
num_dpb_buffer = 18000 / fs_in_mb;
|
||||
break;
|
||||
case 32:
|
||||
num_dpb_buffer = 20480 / fs_in_mb;
|
||||
break;
|
||||
case 41:
|
||||
num_dpb_buffer = 32768 / fs_in_mb;
|
||||
break;
|
||||
case 42:
|
||||
num_dpb_buffer = 34816 / fs_in_mb;
|
||||
break;
|
||||
case 50:
|
||||
num_dpb_buffer = 110400 / fs_in_mb;
|
||||
break;
|
||||
case 51:
|
||||
num_dpb_buffer = 184320 / fs_in_mb;
|
||||
break;
|
||||
default:
|
||||
num_dpb_buffer = 184320 / fs_in_mb;
|
||||
break;
|
||||
}
|
||||
num_dpb_buffer++;
|
||||
num_dpb_buffer = ((msg[61] >> 16) & 0xff) + 1;
|
||||
if (num_dpb_buffer > 17)
|
||||
num_dpb_buffer = 17;
|
||||
return -EINVAL;
|
||||
|
||||
/* reference picture buffer */
|
||||
min_dpb_size = image_size * num_dpb_buffer;
|
||||
|
|
@ -747,35 +719,9 @@ static int amdgpu_uvd_cs_msg_decode(struct amdgpu_device *adev, uint32_t *msg,
|
|||
break;
|
||||
|
||||
case 7: /* H264 Perf */
|
||||
switch (level) {
|
||||
case 30:
|
||||
num_dpb_buffer = 8100 / fs_in_mb;
|
||||
break;
|
||||
case 31:
|
||||
num_dpb_buffer = 18000 / fs_in_mb;
|
||||
break;
|
||||
case 32:
|
||||
num_dpb_buffer = 20480 / fs_in_mb;
|
||||
break;
|
||||
case 41:
|
||||
num_dpb_buffer = 32768 / fs_in_mb;
|
||||
break;
|
||||
case 42:
|
||||
num_dpb_buffer = 34816 / fs_in_mb;
|
||||
break;
|
||||
case 50:
|
||||
num_dpb_buffer = 110400 / fs_in_mb;
|
||||
break;
|
||||
case 51:
|
||||
num_dpb_buffer = 184320 / fs_in_mb;
|
||||
break;
|
||||
default:
|
||||
num_dpb_buffer = 184320 / fs_in_mb;
|
||||
break;
|
||||
}
|
||||
num_dpb_buffer++;
|
||||
num_dpb_buffer = ((msg[61] >> 16) & 0xff) + 1;
|
||||
if (num_dpb_buffer > 17)
|
||||
num_dpb_buffer = 17;
|
||||
return -EINVAL;
|
||||
|
||||
/* reference picture buffer */
|
||||
min_dpb_size = image_size * num_dpb_buffer;
|
||||
|
|
@ -803,6 +749,9 @@ static int amdgpu_uvd_cs_msg_decode(struct amdgpu_device *adev, uint32_t *msg,
|
|||
image_size = ALIGN(image_size, 256);
|
||||
|
||||
num_dpb_buffer = (le32_to_cpu(msg[59]) & 0xff) + 2;
|
||||
if (num_dpb_buffer > 17)
|
||||
return -EINVAL;
|
||||
|
||||
min_dpb_size = image_size * num_dpb_buffer;
|
||||
min_ctx_size = ((width + 255) / 16) * ((height + 255) / 16)
|
||||
* 16 * num_dpb_buffer + 52 * 1024;
|
||||
|
|
@ -813,7 +762,7 @@ static int amdgpu_uvd_cs_msg_decode(struct amdgpu_device *adev, uint32_t *msg,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (width > pitch) {
|
||||
if (width > pitch || pitch > 4096) {
|
||||
DRM_ERROR("Invalid UVD decoding target pitch!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -825,7 +774,7 @@ static int amdgpu_uvd_cs_msg_decode(struct amdgpu_device *adev, uint32_t *msg,
|
|||
}
|
||||
|
||||
buf_sizes[0x1] = dpb_size;
|
||||
buf_sizes[0x2] = image_size;
|
||||
buf_sizes[0x2] = (pitch * height) * 3 / 2;
|
||||
buf_sizes[0x4] = min_ctx_size;
|
||||
/* store image width to adjust nb memory pstate */
|
||||
adev->uvd.decode_image_width = width;
|
||||
|
|
@ -972,15 +921,16 @@ static int amdgpu_uvd_cs_pass2(struct amdgpu_uvd_cs_ctx *ctx)
|
|||
ctx->buf_sizes[cmd]);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (cmd == 0x204 || cmd == 0x206) {
|
||||
unsigned int min_size = ctx->buf_sizes[cmd == 0x204 ? 5 : 4];
|
||||
|
||||
} else if (cmd == 0x206) {
|
||||
if ((end - start) < ctx->buf_sizes[4]) {
|
||||
if ((end - start) < min_size) {
|
||||
DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd,
|
||||
(unsigned int)(end - start),
|
||||
ctx->buf_sizes[4]);
|
||||
min_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if ((cmd != 0x100) && (cmd != 0x204)) {
|
||||
} else if ((cmd != 0x100)) {
|
||||
DRM_ERROR("invalid UVD command %X!\n", cmd);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -1110,11 +1060,12 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser,
|
|||
{
|
||||
struct amdgpu_uvd_cs_ctx ctx = {};
|
||||
unsigned int buf_sizes[] = {
|
||||
[0x00000000] = 2048,
|
||||
[0x00000000] = 3556,
|
||||
[0x00000001] = 0xFFFFFFFF,
|
||||
[0x00000002] = 0xFFFFFFFF,
|
||||
[0x00000003] = 2048,
|
||||
[0x00000004] = 0xFFFFFFFF,
|
||||
[0x00000005] = 992,
|
||||
};
|
||||
int r;
|
||||
|
||||
|
|
|
|||
|
|
@ -766,18 +766,22 @@ bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring,
|
|||
* @ring: ring to use for flush
|
||||
* @job: related job
|
||||
* @need_pipe_sync: is pipe sync needed
|
||||
* @emit_spm_needed: does the caller need to emit spm
|
||||
* @emit_gds_needed: does the caller need to emit gds
|
||||
*
|
||||
* Emit a VM flush when it is necessary.
|
||||
*/
|
||||
void amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
|
||||
bool need_pipe_sync)
|
||||
bool need_pipe_sync, bool *emit_spm_needed,
|
||||
bool *emit_gds_needed)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct amdgpu_isolation *isolation = &adev->isolation[ring->xcp_id];
|
||||
unsigned vmhub = ring->vm_hub;
|
||||
struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
|
||||
struct amdgpu_vmid *id = &id_mgr->ids[job->vmid];
|
||||
bool spm_update_needed = job->spm_update_needed;
|
||||
bool spm_update_needed = adev->gfx.rlc.funcs->update_spm_vmid &&
|
||||
job->spm_update_needed;
|
||||
bool gds_switch_needed = ring->funcs->emit_gds_switch &&
|
||||
job->gds_switch_needed;
|
||||
bool vm_flush_needed = job->vm_needs_flush;
|
||||
|
|
@ -785,6 +789,7 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
|
|||
bool pasid_mapping_needed = false;
|
||||
struct dma_fence *fence = NULL;
|
||||
unsigned int patch = 0;
|
||||
bool emit_fence;
|
||||
|
||||
if (amdgpu_vmid_had_gpu_reset(adev, id)) {
|
||||
gds_switch_needed = true;
|
||||
|
|
@ -800,6 +805,7 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
|
|||
mutex_unlock(&id_mgr->lock);
|
||||
|
||||
gds_switch_needed &= !!ring->funcs->emit_gds_switch;
|
||||
spm_update_needed &= !!adev->gfx.rlc.funcs->update_spm_vmid;
|
||||
vm_flush_needed &= !!ring->funcs->emit_vm_flush &&
|
||||
job->vm_pd_addr != AMDGPU_BO_INVALID_OFFSET;
|
||||
pasid_mapping_needed &= adev->gmc.gmc_funcs->emit_pasid_mapping &&
|
||||
|
|
@ -810,8 +816,19 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
|
|||
ring->funcs->emit_cleaner_shader && job->base.s_fence &&
|
||||
&job->base.s_fence->scheduled == isolation->spearhead;
|
||||
|
||||
emit_fence = vm_flush_needed || pasid_mapping_needed ||
|
||||
cleaner_shader_needed;
|
||||
|
||||
*emit_spm_needed = spm_update_needed;
|
||||
if (spm_update_needed && emit_fence)
|
||||
*emit_spm_needed = false;
|
||||
|
||||
*emit_gds_needed = gds_switch_needed;
|
||||
if (gds_switch_needed && emit_fence)
|
||||
*emit_gds_needed = false;
|
||||
|
||||
if (!vm_flush_needed && !gds_switch_needed && !need_pipe_sync &&
|
||||
!cleaner_shader_needed)
|
||||
!cleaner_shader_needed && !spm_update_needed)
|
||||
return;
|
||||
|
||||
amdgpu_ring_ib_begin(ring);
|
||||
|
|
@ -844,22 +861,22 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
|
|||
if (pasid_mapping_needed)
|
||||
amdgpu_gmc_emit_pasid_mapping(ring, job->vmid, job->pasid);
|
||||
|
||||
if (spm_update_needed && adev->gfx.rlc.funcs->update_spm_vmid)
|
||||
adev->gfx.rlc.funcs->update_spm_vmid(adev, ring->xcc_id, ring, job->vmid);
|
||||
if (emit_fence) {
|
||||
if (spm_update_needed)
|
||||
adev->gfx.rlc.funcs->update_spm_vmid(adev, ring->xcc_id, ring, job->vmid);
|
||||
|
||||
if (ring->funcs->emit_gds_switch &&
|
||||
gds_switch_needed) {
|
||||
amdgpu_ring_emit_gds_switch(ring, job->vmid, job->gds_base,
|
||||
job->gds_size, job->gws_base,
|
||||
job->gws_size, job->oa_base,
|
||||
job->oa_size);
|
||||
if (gds_switch_needed)
|
||||
amdgpu_ring_emit_gds_switch(ring, job->vmid, job->gds_base,
|
||||
job->gds_size, job->gws_base,
|
||||
job->gws_size, job->oa_base,
|
||||
job->oa_size);
|
||||
|
||||
amdgpu_fence_emit(ring, job->hw_vm_fence, 0);
|
||||
fence = &job->hw_vm_fence->base;
|
||||
/* get a ref for the job */
|
||||
dma_fence_get(fence);
|
||||
}
|
||||
|
||||
amdgpu_fence_emit(ring, job->hw_vm_fence, 0);
|
||||
fence = &job->hw_vm_fence->base;
|
||||
/* get a ref for the job */
|
||||
dma_fence_get(fence);
|
||||
|
||||
if (vm_flush_needed) {
|
||||
mutex_lock(&id_mgr->lock);
|
||||
dma_fence_put(id->last_flush);
|
||||
|
|
@ -1391,7 +1408,13 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
|
|||
amdgpu_vm_bo_evicted(&bo_va->base);
|
||||
else
|
||||
amdgpu_vm_bo_idle(&bo_va->base);
|
||||
} else {
|
||||
} else if (bo) {
|
||||
/*
|
||||
* A PRT/sparse mapping has no BO and is kept off the vm_bo
|
||||
* state lists (see amdgpu_vm_bo_base_init()); putting it on the
|
||||
* idle list here would let amdgpu_vm_handle_moved() dereference
|
||||
* the NULL bo after a reset.
|
||||
*/
|
||||
amdgpu_vm_bo_idle(&bo_va->base);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -511,7 +511,9 @@ int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
struct ww_acquire_ctx *ticket,
|
||||
int (*callback)(void *p, struct amdgpu_bo *bo),
|
||||
void *param);
|
||||
void amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync);
|
||||
void amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
|
||||
bool need_pipe_sync, bool *emit_spm_needed,
|
||||
bool *emit_gds_needed);
|
||||
int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm, bool immediate);
|
||||
int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
|
||||
|
|
|
|||
|
|
@ -1954,7 +1954,7 @@ static int mes_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
|
|||
if (adev->mes.ring[0].sched.ready)
|
||||
goto out;
|
||||
|
||||
adev->mes.use_rs64mem = true;
|
||||
adev->mes.use_rs64mem = false;
|
||||
|
||||
if (!adev->enable_mes_kiq) {
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
|
||||
|
|
|
|||
|
|
@ -500,7 +500,6 @@ static u32 nbif_v6_3_1_get_rom_offset(struct amdgpu_device *adev)
|
|||
static void nbif_v6_3_1_program_ltr(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t def, data;
|
||||
u16 devctl2;
|
||||
|
||||
def = RREG32_SOC15(NBIO, 0, regRCC_EP_DEV0_0_EP_PCIE_TX_LTR_CNTL);
|
||||
data = 0x35EB;
|
||||
|
|
@ -514,15 +513,8 @@ static void nbif_v6_3_1_program_ltr(struct amdgpu_device *adev)
|
|||
if (def != data)
|
||||
WREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP2, data);
|
||||
|
||||
pcie_capability_read_word(adev->pdev, PCI_EXP_DEVCTL2, &devctl2);
|
||||
|
||||
if (adev->pdev->ltr_path == (devctl2 & PCI_EXP_DEVCTL2_LTR_EN))
|
||||
return;
|
||||
|
||||
if (adev->pdev->ltr_path)
|
||||
pcie_capability_set_word(adev->pdev, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_LTR_EN);
|
||||
else
|
||||
pcie_capability_clear_word(adev->pdev, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_LTR_EN);
|
||||
pcie_capability_set_word(adev->pdev, PCI_EXP_DEVCTL2,
|
||||
PCI_EXP_DEVCTL2_LTR_EN);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -530,7 +522,7 @@ static void nbif_v6_3_1_program_aspm(struct amdgpu_device *adev)
|
|||
{
|
||||
#ifdef CONFIG_PCIEASPM
|
||||
uint32_t def, data;
|
||||
u16 devctl2, ltr;
|
||||
u16 ltr;
|
||||
|
||||
def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL);
|
||||
data &= ~PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK;
|
||||
|
|
@ -560,11 +552,8 @@ static void nbif_v6_3_1_program_aspm(struct amdgpu_device *adev)
|
|||
if (def != data)
|
||||
WREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP5, data);
|
||||
|
||||
pcie_capability_read_word(adev->pdev, PCI_EXP_DEVCTL2, &devctl2);
|
||||
data = def = devctl2;
|
||||
data &= ~PCI_EXP_DEVCTL2_LTR_EN;
|
||||
if (def != data)
|
||||
pcie_capability_set_word(adev->pdev, PCI_EXP_DEVCTL2, (u16)data);
|
||||
pcie_capability_clear_word(adev->pdev, PCI_EXP_DEVCTL2,
|
||||
PCI_EXP_DEVCTL2_LTR_EN);
|
||||
|
||||
ltr = pci_find_ext_capability(adev->pdev, PCI_EXT_CAP_ID_LTR);
|
||||
|
||||
|
|
@ -572,15 +561,13 @@ static void nbif_v6_3_1_program_aspm(struct amdgpu_device *adev)
|
|||
pci_write_config_dword(adev->pdev, ltr + PCI_LTR_MAX_SNOOP_LAT, 0x10011001);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* regPSWUSP0_PCIE_LC_CNTL2 should be replace by PCIE_LC_CNTL2 or someone else ? */
|
||||
def = data = RREG32_SOC15(NBIO, 0, regPSWUSP0_PCIE_LC_CNTL2);
|
||||
data |= PSWUSP0_PCIE_LC_CNTL2__LC_ALLOW_PDWN_IN_L1_MASK |
|
||||
PSWUSP0_PCIE_LC_CNTL2__LC_ALLOW_PDWN_IN_L23_MASK;
|
||||
data &= ~PSWUSP0_PCIE_LC_CNTL2__LC_RCV_L0_TO_RCV_L0S_DIS_MASK;
|
||||
def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL2);
|
||||
data |= PCIE_LC_CNTL2__LC_ALLOW_PDWN_IN_L1_MASK |
|
||||
PCIE_LC_CNTL2__LC_ALLOW_PDWN_IN_L23_MASK;
|
||||
data &= ~PCIE_LC_CNTL2__LC_RCV_L0_TO_RCV_L0S_DIS_MASK;
|
||||
if (def != data)
|
||||
WREG32_SOC15(NBIO, 0, regPSWUSP0_PCIE_LC_CNTL2, data);
|
||||
#endif
|
||||
WREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL2, data);
|
||||
|
||||
def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL4);
|
||||
data |= PCIE_LC_CNTL4__LC_L1_POWERDOWN_MASK;
|
||||
if (def != data)
|
||||
|
|
@ -591,7 +578,12 @@ static void nbif_v6_3_1_program_aspm(struct amdgpu_device *adev)
|
|||
if (def != data)
|
||||
WREG32_SOC15(PCIE, 0, regPCIE_LC_RXRECOVER_RXSTANDBY_CNTL, data);
|
||||
|
||||
nbif_v6_3_1_program_ltr(adev);
|
||||
/*
|
||||
* Do not enable endpoint LTR unless the Root Complex and every
|
||||
* upstream switch support it.
|
||||
*/
|
||||
if (adev->pdev->ltr_path)
|
||||
nbif_v6_3_1_program_ltr(adev);
|
||||
|
||||
def = data = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP3);
|
||||
data |= 0x5DE0 << RCC_STRAP0_RCC_BIF_STRAP3__STRAP_VLINK_ASPM_IDLE_TIMER__SHIFT;
|
||||
|
|
|
|||
|
|
@ -825,8 +825,25 @@ static int soc21_common_early_init(struct amdgpu_ip_block *ip_block)
|
|||
adev->external_rev_id = adev->rev_id + 0x1;
|
||||
break;
|
||||
case IP_VERSION(11, 5, 6):
|
||||
adev->cg_flags = 0;
|
||||
adev->pg_flags = 0;
|
||||
adev->cg_flags = AMD_CG_SUPPORT_GFX_CGCG |
|
||||
AMD_CG_SUPPORT_GFX_CGLS |
|
||||
AMD_CG_SUPPORT_GFX_MGCG |
|
||||
AMD_CG_SUPPORT_GFX_FGCG |
|
||||
AMD_CG_SUPPORT_REPEATER_FGCG |
|
||||
AMD_CG_SUPPORT_GFX_PERF_CLK |
|
||||
AMD_CG_SUPPORT_GFX_3D_CGCG |
|
||||
AMD_CG_SUPPORT_GFX_3D_CGLS |
|
||||
AMD_CG_SUPPORT_MC_MGCG |
|
||||
AMD_CG_SUPPORT_MC_LS |
|
||||
AMD_CG_SUPPORT_HDP_LS |
|
||||
AMD_CG_SUPPORT_HDP_DS |
|
||||
AMD_CG_SUPPORT_HDP_SD |
|
||||
AMD_CG_SUPPORT_ATHUB_MGCG |
|
||||
AMD_CG_SUPPORT_ATHUB_LS |
|
||||
AMD_CG_SUPPORT_IH_CG |
|
||||
AMD_CG_SUPPORT_BIF_MGCG |
|
||||
AMD_CG_SUPPORT_BIF_LS;
|
||||
adev->pg_flags = AMD_PG_SUPPORT_GFX_PG;
|
||||
adev->external_rev_id = adev->rev_id + 0xd0;
|
||||
break;
|
||||
case IP_VERSION(11, 7, 0):
|
||||
|
|
|
|||
|
|
@ -809,6 +809,23 @@ static void vce_v3_0_ring_emit_ib(struct amdgpu_ring *ring,
|
|||
amdgpu_ring_write(ring, ib->length_dw);
|
||||
}
|
||||
|
||||
static void vce_v3_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr,
|
||||
u64 seq, unsigned flags)
|
||||
{
|
||||
WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
|
||||
|
||||
amdgpu_ring_write(ring, VCE_CMD_FENCE);
|
||||
amdgpu_ring_write(ring, addr);
|
||||
amdgpu_ring_write(ring, upper_32_bits(addr));
|
||||
amdgpu_ring_write(ring, seq);
|
||||
amdgpu_ring_write(ring, VCE_CMD_TRAP);
|
||||
}
|
||||
|
||||
static void vce_v3_0_ring_insert_end(struct amdgpu_ring *ring)
|
||||
{
|
||||
amdgpu_ring_write(ring, VCE_CMD_END);
|
||||
}
|
||||
|
||||
static void vce_v3_0_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned int vmid, uint64_t pd_addr)
|
||||
{
|
||||
|
|
@ -818,7 +835,6 @@ static void vce_v3_0_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
|
||||
amdgpu_ring_write(ring, VCE_CMD_FLUSH_TLB);
|
||||
amdgpu_ring_write(ring, vmid);
|
||||
amdgpu_ring_write(ring, VCE_CMD_END);
|
||||
}
|
||||
|
||||
static void vce_v3_0_emit_pipeline_sync(struct amdgpu_ring *ring)
|
||||
|
|
@ -884,17 +900,19 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_vm_funcs = {
|
|||
.set_wptr = vce_v3_0_ring_set_wptr,
|
||||
.patch_cs_in_place = amdgpu_vce_ring_parse_cs_vm,
|
||||
.emit_frame_size =
|
||||
6 + /* vce_v3_0_emit_vm_flush */
|
||||
5 + /* vce_v3_0_emit_vm_flush */
|
||||
4 + /* vce_v3_0_emit_pipeline_sync */
|
||||
6 + 6, /* amdgpu_vce_ring_emit_fence x2 vm fence */
|
||||
5 + 5 + /* vce_v3_0_ring_emit_fence x2 vm fence */
|
||||
1, /* vce_v3_0_ring_insert_end */
|
||||
.emit_ib_size = 5, /* vce_v3_0_ring_emit_ib */
|
||||
.emit_ib = vce_v3_0_ring_emit_ib,
|
||||
.emit_vm_flush = vce_v3_0_emit_vm_flush,
|
||||
.emit_pipeline_sync = vce_v3_0_emit_pipeline_sync,
|
||||
.emit_fence = amdgpu_vce_ring_emit_fence,
|
||||
.emit_fence = vce_v3_0_ring_emit_fence,
|
||||
.test_ring = amdgpu_vce_ring_test_ring,
|
||||
.test_ib = amdgpu_vce_ring_test_ib,
|
||||
.insert_nop = amdgpu_ring_insert_nop,
|
||||
.insert_end = vce_v3_0_ring_insert_end,
|
||||
.pad_ib = amdgpu_ring_generic_pad_ib,
|
||||
.begin_use = amdgpu_vce_ring_begin_use,
|
||||
.end_use = amdgpu_vce_ring_end_use,
|
||||
|
|
|
|||
|
|
@ -1257,6 +1257,99 @@ static int resume_single_queue(struct device_queue_manager *dqm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Unpin the MQD BO at S4 suspend so it is evicted into the hibernation image;
|
||||
* dqm_repin_mqd_bo() pins it back on resume. Gated on adev->in_s4 so runtime
|
||||
* eviction is untouched.
|
||||
*/
|
||||
static void dqm_evict_mqd_bo(struct device_queue_manager *dqm, struct queue *q)
|
||||
{
|
||||
struct mqd_manager *mqd_mgr;
|
||||
struct amdgpu_bo *bo;
|
||||
|
||||
if (!dqm->dev->adev->in_s4)
|
||||
return;
|
||||
if (!mqd_on_vram(dqm->dev->adev))
|
||||
return;
|
||||
if (q->properties.type != KFD_QUEUE_TYPE_COMPUTE)
|
||||
return;
|
||||
if (!q->mqd_mem_obj || !q->mqd_mem_obj->mem)
|
||||
return;
|
||||
|
||||
/* Without update_mqd_gpu_addr() the MQD self-address cannot be fixed up
|
||||
* after a repin, so skip eviction (with a warning) instead of faulting.
|
||||
*/
|
||||
mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(q->properties.type)];
|
||||
if (!mqd_mgr->update_mqd_gpu_addr) {
|
||||
dev_warn_once(dqm->dev->adev->dev,
|
||||
"MQD is in VRAM but update_mqd_gpu_addr is not implemented; skipping hibernation eviction\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bo = q->mqd_mem_obj->mem;
|
||||
if (amdgpu_bo_reserve(bo, false))
|
||||
return;
|
||||
|
||||
amdgpu_bo_unpin(bo);
|
||||
amdgpu_bo_unreserve(bo);
|
||||
q->mqd = NULL;
|
||||
q->needs_mqd_repin = true;
|
||||
}
|
||||
|
||||
/* Repin the MQD BO to VRAM and refresh the cached mapping and GPU addresses.
|
||||
* Used both on resume and when a queue is destroyed before resume has repinned
|
||||
* it. A no-op unless a repin is owed (needs_mqd_repin set).
|
||||
*/
|
||||
static int dqm_repin_mqd_bo(struct device_queue_manager *dqm, struct queue *q)
|
||||
{
|
||||
struct mqd_manager *mqd_mgr;
|
||||
struct amdgpu_bo *bo;
|
||||
void *cpu_ptr;
|
||||
int r;
|
||||
|
||||
if (!q->needs_mqd_repin)
|
||||
return 0;
|
||||
if (!q->mqd_mem_obj || !q->mqd_mem_obj->mem)
|
||||
return 0;
|
||||
|
||||
bo = q->mqd_mem_obj->mem;
|
||||
r = amdgpu_bo_reserve(bo, false);
|
||||
if (r)
|
||||
return r;
|
||||
r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_VRAM);
|
||||
if (r) {
|
||||
amdgpu_bo_unreserve(bo);
|
||||
dev_err(dqm->dev->adev->dev,
|
||||
"Failed to repin MQD of queue %d to VRAM: %d\n",
|
||||
q->properties.queue_id, r);
|
||||
return r;
|
||||
}
|
||||
/* The BO may have moved; refresh the kernel mapping and gpu address. */
|
||||
amdgpu_bo_kunmap(bo);
|
||||
r = amdgpu_bo_kmap(bo, &cpu_ptr);
|
||||
amdgpu_bo_unreserve(bo);
|
||||
if (r) {
|
||||
dev_err(dqm->dev->adev->dev,
|
||||
"Failed to remap MQD of queue %d: %d\n",
|
||||
q->properties.queue_id, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
q->mqd_mem_obj->cpu_ptr = cpu_ptr;
|
||||
q->mqd_mem_obj->gpu_addr = amdgpu_bo_gpu_offset(bo);
|
||||
q->gart_mqd_addr = q->mqd_mem_obj->gpu_addr;
|
||||
q->mqd = cpu_ptr;
|
||||
|
||||
mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(
|
||||
q->properties.type)];
|
||||
if (mqd_mgr->update_mqd_gpu_addr)
|
||||
mqd_mgr->update_mqd_gpu_addr(mqd_mgr, q->mqd,
|
||||
q->mqd_mem_obj,
|
||||
&q->properties);
|
||||
|
||||
q->needs_mqd_repin = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int evict_process_queues_nocpsch(struct device_queue_manager *dqm,
|
||||
struct qcm_process_device *qpd)
|
||||
{
|
||||
|
|
@ -1353,6 +1446,8 @@ static int evict_process_queues_cpsch(struct device_queue_manager *dqm,
|
|||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
dqm_evict_mqd_bo(dqm, q);
|
||||
}
|
||||
|
||||
if (!dqm->dev->kfd->shared_resources.enable_mes) {
|
||||
|
|
@ -1492,6 +1587,13 @@ static int restore_process_queues_cpsch(struct device_queue_manager *dqm,
|
|||
q->properties.is_active = true;
|
||||
increment_queue_count(dqm, &pdd->qpd, q);
|
||||
|
||||
retval = dqm_repin_mqd_bo(dqm, q);
|
||||
if (retval) {
|
||||
dev_err(dev, "Failed to repin MQD for queue %d\n",
|
||||
q->properties.queue_id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dqm->dev->kfd->shared_resources.enable_mes) {
|
||||
retval = add_queue_mes(dqm, q, qpd);
|
||||
if (retval) {
|
||||
|
|
@ -2763,6 +2865,8 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm,
|
|||
qpd->pqm->process, q->device,
|
||||
-1, false, NULL, 0);
|
||||
|
||||
/* Repin the MQD BO if still evicted for hibernation, before it is freed. */
|
||||
dqm_repin_mqd_bo(dqm, q);
|
||||
mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
|
||||
|
||||
return retval;
|
||||
|
|
@ -3020,6 +3124,8 @@ static int process_termination_cpsch(struct device_queue_manager *dqm,
|
|||
list_del(&q->list);
|
||||
qpd->queue_count--;
|
||||
dqm_unlock(dqm);
|
||||
/* Repin the MQD BO if still evicted for hibernation, before free. */
|
||||
dqm_repin_mqd_bo(dqm, q);
|
||||
mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
|
||||
dqm_lock(dqm);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,14 @@ struct mqd_manager {
|
|||
const void *ctl_stack_src,
|
||||
const u32 ctl_stack_size);
|
||||
|
||||
/* Patch the MQD's cached self GPU address after the MQD BO has moved
|
||||
* (e.g. repinned to a new VRAM location on hibernation resume). The MQD
|
||||
* contents are otherwise preserved.
|
||||
*/
|
||||
void (*update_mqd_gpu_addr)(struct mqd_manager *mm, void *mqd,
|
||||
struct kfd_mem_obj *mqd_mem_obj,
|
||||
struct queue_properties *p);
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
int (*debugfs_show_mqd)(struct seq_file *m, void *data);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -476,6 +476,20 @@ static void restore_mqd(struct mqd_manager *mm, void **mqd,
|
|||
qp->is_active = 0;
|
||||
}
|
||||
|
||||
static void update_mqd_gpu_addr(struct mqd_manager *mm, void *mqd,
|
||||
struct kfd_mem_obj *mqd_mem_obj,
|
||||
struct queue_properties *qp)
|
||||
{
|
||||
struct v9_mqd *m = get_mqd(mqd);
|
||||
uint64_t addr = mqd_mem_obj->gpu_addr;
|
||||
|
||||
m->cp_mqd_base_addr_lo = lower_32_bits(addr);
|
||||
m->cp_mqd_base_addr_hi = upper_32_bits(addr);
|
||||
|
||||
if (mqd_on_vram(mm->dev->adev))
|
||||
amdgpu_device_flush_hdp(mm->dev->adev, NULL);
|
||||
}
|
||||
|
||||
static void init_mqd_hiq(struct mqd_manager *mm, void **mqd,
|
||||
struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr,
|
||||
struct queue_properties *q)
|
||||
|
|
@ -860,6 +874,30 @@ static void restore_mqd_v9_4_3(struct mqd_manager *mm, void **mqd,
|
|||
if (mqd_on_vram(mm->dev->adev))
|
||||
amdgpu_device_flush_hdp(mm->dev->adev, NULL);
|
||||
}
|
||||
|
||||
static void update_mqd_gpu_addr_v9_4_3(struct mqd_manager *mm, void *mqd,
|
||||
struct kfd_mem_obj *mqd_mem_obj,
|
||||
struct queue_properties *qp)
|
||||
{
|
||||
struct kfd_mem_obj xcc_mqd_mem_obj;
|
||||
uint64_t offset = mm->mqd_stride(mm, qp);
|
||||
u32 num_xcc = NUM_XCC(mm->dev->xcc_mask);
|
||||
struct v9_mqd *m;
|
||||
int xcc;
|
||||
|
||||
memset(&xcc_mqd_mem_obj, 0x0, sizeof(struct kfd_mem_obj));
|
||||
|
||||
for (xcc = 0; xcc < num_xcc; xcc++) {
|
||||
get_xcc_mqd(mqd_mem_obj, &xcc_mqd_mem_obj, offset * xcc);
|
||||
m = get_mqd(mqd + offset * xcc);
|
||||
m->cp_mqd_base_addr_lo = lower_32_bits(xcc_mqd_mem_obj.gpu_addr);
|
||||
m->cp_mqd_base_addr_hi = upper_32_bits(xcc_mqd_mem_obj.gpu_addr);
|
||||
}
|
||||
|
||||
if (mqd_on_vram(mm->dev->adev))
|
||||
amdgpu_device_flush_hdp(mm->dev->adev, NULL);
|
||||
}
|
||||
|
||||
static int destroy_mqd_v9_4_3(struct mqd_manager *mm, void *mqd,
|
||||
enum kfd_preempt_type type, unsigned int timeout,
|
||||
uint32_t pipe_id, uint32_t queue_id)
|
||||
|
|
@ -1017,6 +1055,7 @@ struct mqd_manager *mqd_manager_init_v9(enum KFD_MQD_TYPE type,
|
|||
mqd->get_wave_state = get_wave_state_v9_4_3;
|
||||
mqd->checkpoint_mqd = checkpoint_mqd_v9_4_3;
|
||||
mqd->restore_mqd = restore_mqd_v9_4_3;
|
||||
mqd->update_mqd_gpu_addr = update_mqd_gpu_addr_v9_4_3;
|
||||
} else {
|
||||
mqd->init_mqd = init_mqd;
|
||||
mqd->load_mqd = load_mqd;
|
||||
|
|
@ -1025,6 +1064,7 @@ struct mqd_manager *mqd_manager_init_v9(enum KFD_MQD_TYPE type,
|
|||
mqd->get_wave_state = get_wave_state;
|
||||
mqd->checkpoint_mqd = checkpoint_mqd;
|
||||
mqd->restore_mqd = restore_mqd;
|
||||
mqd->update_mqd_gpu_addr = update_mqd_gpu_addr;
|
||||
}
|
||||
break;
|
||||
case KFD_MQD_TYPE_HIQ:
|
||||
|
|
|
|||
|
|
@ -638,6 +638,12 @@ struct queue {
|
|||
uint32_t gang_ctx_array_index;
|
||||
|
||||
struct amdgpu_bo *wptr_bo_gart;
|
||||
|
||||
/* The VRAM-resident MQD BO (mqd_on_vram()) is unpinned at S4 suspend so
|
||||
* TTM evicts it into the hibernation image, and repinned on resume. Set
|
||||
* while the BO is unpinned so the resume path knows to repin it.
|
||||
*/
|
||||
bool needs_mqd_repin;
|
||||
};
|
||||
|
||||
enum KFD_MQD_TYPE {
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ static inline int amdgpu_dm_crtc_set_vblank(struct drm_crtc *crtc, bool enable)
|
|||
|
||||
irq_type = amdgpu_display_crtc_idx_to_irq_type(adev, acrtc->crtc_id);
|
||||
|
||||
if (enable) {
|
||||
if (enable && acrtc_state->stream) {
|
||||
struct dc *dc = adev->dm.dc;
|
||||
struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
|
||||
struct psr_settings *psr = &acrtc_state->stream->link->psr_settings;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,11 @@ void dc_fpu_end(const char *function_name, const int line);
|
|||
#else
|
||||
#define DC_FP_START() BUILD_BUG()
|
||||
#define DC_FP_END() BUILD_BUG()
|
||||
#define DC_RUN_WITH_PREEMPTION_ENABLED(code) code
|
||||
#define DC_RUN_WITH_PREEMPTION_ENABLED(code) \
|
||||
do { \
|
||||
BUILD_BUG(); \
|
||||
code; \
|
||||
} while (0)
|
||||
#endif // !_LINUX_FPU_COMPILATION_UNIT
|
||||
|
||||
#endif /* __DC_FPU_H__ */
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ enum dc_color_space_type {
|
|||
COLOR_SPACE_RGB_LIMITED_TYPE,
|
||||
COLOR_SPACE_YCBCR601_TYPE,
|
||||
COLOR_SPACE_YCBCR709_TYPE,
|
||||
COLOR_SPACE_YCBCR2020_TYPE,
|
||||
COLOR_SPACE_YCBCR2020_LIMITED_TYPE,
|
||||
COLOR_SPACE_YCBCR2020_FULL_TYPE,
|
||||
COLOR_SPACE_YCBCR601_LIMITED_TYPE,
|
||||
COLOR_SPACE_YCBCR709_LIMITED_TYPE,
|
||||
COLOR_SPACE_YCBCR709_BLACK_TYPE,
|
||||
|
|
@ -112,9 +113,15 @@ static const struct out_csc_color_matrix_type output_csc_matrix[] = {
|
|||
{ 0xE00, 0xF349, 0xFEB7, 0x1000,
|
||||
0x6CE, 0x16E3, 0x24F, 0x200,
|
||||
0xFCCB, 0xF535, 0xE00, 0x1000} },
|
||||
{ COLOR_SPACE_YCBCR2020_TYPE,
|
||||
/* Corrected. Not included in the TODO above. */
|
||||
{ COLOR_SPACE_YCBCR2020_LIMITED_TYPE,
|
||||
{ 0x0E04, 0xF31D, 0xFEDF, 0x1004,
|
||||
0x0733, 0x1294, 0x01A0, 0x0201,
|
||||
0xFC16, 0xF5E6, 0x0E04, 0x1004} },
|
||||
/* Corrected. Not included in the TODO above. */
|
||||
{ COLOR_SPACE_YCBCR2020_FULL_TYPE,
|
||||
{ 0x1000, 0xF149, 0xFEB7, 0x1004,
|
||||
0x0868, 0x15B2, 0x01E6, 0x201,
|
||||
0x0868, 0x15B2, 0x01E6, 0,
|
||||
0xFB88, 0xF478, 0x1000, 0x1004} },
|
||||
{ COLOR_SPACE_YCBCR709_BLACK_TYPE,
|
||||
{ 0x0000, 0x0000, 0x0000, 0x1000,
|
||||
|
|
@ -181,14 +188,14 @@ static bool is_ycbcr709_type(
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool is_ycbcr2020_type(
|
||||
enum dc_color_space color_space)
|
||||
static bool is_ycbcr2020_limited_type(enum dc_color_space color_space)
|
||||
{
|
||||
bool ret = false;
|
||||
return color_space == COLOR_SPACE_2020_YCBCR_LIMITED;
|
||||
}
|
||||
|
||||
if (color_space == COLOR_SPACE_2020_YCBCR_LIMITED || color_space == COLOR_SPACE_2020_YCBCR_FULL)
|
||||
ret = true;
|
||||
return ret;
|
||||
static bool is_ycbcr2020_full_type(enum dc_color_space color_space)
|
||||
{
|
||||
return color_space == COLOR_SPACE_2020_YCBCR_FULL;
|
||||
}
|
||||
|
||||
static bool is_ycbcr709_limited_type(
|
||||
|
|
@ -217,8 +224,10 @@ static enum dc_color_space_type get_color_space_type(enum dc_color_space color_s
|
|||
type = COLOR_SPACE_YCBCR601_LIMITED_TYPE;
|
||||
else if (is_ycbcr709_limited_type(color_space))
|
||||
type = COLOR_SPACE_YCBCR709_LIMITED_TYPE;
|
||||
else if (is_ycbcr2020_type(color_space))
|
||||
type = COLOR_SPACE_YCBCR2020_TYPE;
|
||||
else if (is_ycbcr2020_limited_type(color_space))
|
||||
type = COLOR_SPACE_YCBCR2020_LIMITED_TYPE;
|
||||
else if (is_ycbcr2020_full_type(color_space))
|
||||
type = COLOR_SPACE_YCBCR2020_FULL_TYPE;
|
||||
else if (color_space == COLOR_SPACE_YCBCR709)
|
||||
type = COLOR_SPACE_YCBCR709_BLACK_TYPE;
|
||||
else if (color_space == COLOR_SPACE_YCBCR709_BLACK)
|
||||
|
|
|
|||
|
|
@ -115,10 +115,11 @@ static const struct out_csc_color_matrix global_color_matrix[] = {
|
|||
{ 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
|
||||
{ COLOR_SPACE_2020_RGB_LIMITEDRANGE,
|
||||
{ 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} },
|
||||
{ COLOR_SPACE_2020_YCBCR_LIMITED, { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868,
|
||||
0x15B2, 0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} },
|
||||
/* COLOR_SPACE_2020_YCBCR_* values corrected. Not included in the TODO above. */
|
||||
{ COLOR_SPACE_2020_YCBCR_LIMITED, { 0x0E04, 0xF31D, 0xFEDF, 0x1004, 0x0733,
|
||||
0x1294, 0x01A0, 0x201, 0xFC16, 0xF5E6, 0x0E04, 0x1004} },
|
||||
{ COLOR_SPACE_2020_YCBCR_FULL, { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868, 0x15B2,
|
||||
0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} }
|
||||
0x01E6, 0, 0xFB88, 0xF478, 0x1000, 0x1004} }
|
||||
};
|
||||
|
||||
static bool setup_scaling_configuration(
|
||||
|
|
|
|||
|
|
@ -93,10 +93,11 @@ static const struct out_csc_color_matrix global_color_matrix[] = {
|
|||
{ 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
|
||||
{ COLOR_SPACE_2020_RGB_LIMITEDRANGE,
|
||||
{ 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} },
|
||||
{ COLOR_SPACE_2020_YCBCR_LIMITED, { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868,
|
||||
0x15B2, 0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} },
|
||||
/* COLOR_SPACE_2020_YCBCR_* values corrected. Not included in the TODO above. */
|
||||
{ COLOR_SPACE_2020_YCBCR_LIMITED, { 0x0E04, 0xF31D, 0xFEDF, 0x1004, 0x0733,
|
||||
0x1294, 0x01A0, 0x201, 0xFC16, 0xF5E6, 0x0E04, 0x1004} },
|
||||
{ COLOR_SPACE_2020_YCBCR_FULL, { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868, 0x15B2,
|
||||
0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} }
|
||||
0x01E6, 0, 0xFB88, 0xF478, 0x1000, 0x1004} }
|
||||
};
|
||||
|
||||
enum csc_color_mode {
|
||||
|
|
|
|||
|
|
@ -75,11 +75,19 @@ $(foreach obj,$(DML2_RELATIVE_O_FILES),$(eval CFLAGS_REMOVE_$(AMDDALPATH)/$(obj)
|
|||
CFLAGS_$(AMDDALPATH)/dc/dml2_0/display_mode_core.o := $(dml2_ccflags) $(frame_warn_flag)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.o := $(dml2_ccflags) $(frame_warn_flag)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.o := $(dml2_ccflags) $(frame_warn_flag)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.o := $(dml2_ccflags) $(frame_warn_flag)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_support.o := $(dml2_ccflags) $(frame_warn_flag)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_programming.o := $(dml2_ccflags) $(frame_warn_flag)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.o := $(dml2_ccflags) $(frame_warn_flag)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml2_wrapper.o := $(dml2_rcflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml2_0/dml21/dml21_wrapper.o := $(dml2_rcflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/display_mode_core.o := $(dml2_rcflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.o := $(dml2_rcflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.o := $(dml2_rcflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.o := $(dml2_rcflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_support.o := $(dml2_rcflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_programming.o := $(dml2_rcflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.o := $(dml2_rcflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml2_wrapper.o := $(dml2_ccflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml2_0/dml21/dml21_wrapper.o := $(dml2_ccflags)
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <linux/nospec.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/units.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
#define MAX_NUM_OF_FEATURES_PER_SUBSET 8
|
||||
|
|
@ -4876,9 +4877,8 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
|
|||
{
|
||||
uint32_t mp1_ver = amdgpu_ip_version(adev, MP1_HWIP, 0);
|
||||
uint32_t gc_ver = amdgpu_ip_version(adev, GC_HWIP, 0);
|
||||
uint32_t value, mwatt, centiwatt;
|
||||
uint64_t value64 = 0;
|
||||
uint32_t query = 0;
|
||||
uint32_t value;
|
||||
int size;
|
||||
|
||||
/* GPU Clocks */
|
||||
|
|
@ -4899,25 +4899,22 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
|
|||
seq_printf(m, "\t%u mV (VDDGFX)\n", value);
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB, (void *)&value, &size))
|
||||
seq_printf(m, "\t%u mV (VDDNB)\n", value);
|
||||
size = sizeof(uint32_t);
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&query, &size)) {
|
||||
mwatt = query;
|
||||
centiwatt = DIV_ROUND_CLOSEST(mwatt, 10);
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&value, &size)) {
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
seq_printf(m, "\t%u.%02u W (average SoC including CPU)\n", centiwatt / 100, centiwatt % 100);
|
||||
seq_printf(m, "\t%u.%02u W (average SoC including CPU)\n",
|
||||
(u32)(value / MILLIWATT_PER_WATT), (u32)(value % MILLIWATT_PER_WATT) / 10);
|
||||
else
|
||||
seq_printf(m, "\t%u.%02u W (average SoC)\n", centiwatt / 100, centiwatt % 100);
|
||||
seq_printf(m, "\t%u.%02u W (average SoC)\n",
|
||||
(u32)(value / MILLIWATT_PER_WATT), (u32)(value % MILLIWATT_PER_WATT) / 10);
|
||||
}
|
||||
size = sizeof(uint32_t);
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER, (void *)&query, &size)) {
|
||||
mwatt = query;
|
||||
centiwatt = DIV_ROUND_CLOSEST(mwatt, 10);
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER, (void *)&value, &size)) {
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
seq_printf(m, "\t%u.%02u W (current SoC including CPU)\n", centiwatt / 100, centiwatt % 100);
|
||||
seq_printf(m, "\t%u.%02u W (current SoC including CPU)\n",
|
||||
(u32)(value / MILLIWATT_PER_WATT), (u32)(value % MILLIWATT_PER_WATT) / 10);
|
||||
else
|
||||
seq_printf(m, "\t%u.%02u W (current SoC)\n", centiwatt / 100, centiwatt % 100);
|
||||
seq_printf(m, "\t%u.%02u W (current SoC)\n",
|
||||
(u32)(value / MILLIWATT_PER_WATT), (u32)(value % MILLIWATT_PER_WATT) / 10);
|
||||
}
|
||||
size = sizeof(value);
|
||||
seq_printf(m, "\n");
|
||||
|
||||
/* GPU Temp */
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
#define SMU_THERMAL_MINIMUM_ALERT_TEMP 0
|
||||
#define SMU_THERMAL_MAXIMUM_ALERT_TEMP 255
|
||||
#define SMU_TEMPERATURE_UNITS_PER_CENTIGRADES 1000
|
||||
#define SMU_TEMPERATURE_UNITS_PER_CENTIGRADES MILLIDEGREE_PER_DEGREE
|
||||
#define SMU_FW_NAME_LEN 0x24
|
||||
|
||||
#define SMU_DPM_USER_PROFILE_RESTORE (1 << 0)
|
||||
|
|
|
|||
|
|
@ -55,6 +55,13 @@
|
|||
#define SMUQ10_TO_UINT(x) ((x) >> 10)
|
||||
#define SMUQ10_FRAC(x) ((x) & 0x3ff)
|
||||
#define SMUQ10_ROUND(x) ((SMUQ10_TO_UINT(x)) + ((SMUQ10_FRAC(x)) >= 0x200))
|
||||
/* Convert Q10 watts to milliwatts, preserving the fractional part */
|
||||
#define SMUQ10_TO_MILLIWATT(x) (SMUQ10_TO_UINT(x) * MILLIWATT_PER_WATT + \
|
||||
((SMUQ10_FRAC(x) * MILLIWATT_PER_WATT) >> 10))
|
||||
/* Convert Q10 degrees Celsius to millidegrees, preserving the fractional part */
|
||||
#define SMUQ10_TO_MILLICELSIUS(x) \
|
||||
(SMUQ10_TO_UINT(x) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES + \
|
||||
((SMUQ10_FRAC(x) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES) >> 10))
|
||||
#define SMU_V13_SOFT_FREQ_ROUND(x) ((x) + 1)
|
||||
|
||||
extern const int pmfw_decoded_link_speed[5];
|
||||
|
|
|
|||
|
|
@ -434,23 +434,19 @@ int smu_v13_0_12_get_smu_metrics_data(struct smu_context *smu,
|
|||
*value = SMUQ10_ROUND(metrics->DramBandwidthUtilization);
|
||||
break;
|
||||
case METRICS_CURR_SOCKETPOWER:
|
||||
*value = SMUQ10_ROUND(metrics->SocketPower) *
|
||||
MILLIWATT_PER_WATT;
|
||||
*value = SMUQ10_TO_MILLIWATT(metrics->SocketPower);
|
||||
break;
|
||||
case METRICS_TEMPERATURE_HOTSPOT:
|
||||
*value = SMUQ10_ROUND(metrics->MaxSocketTemperature) *
|
||||
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
*value = SMUQ10_TO_MILLICELSIUS(metrics->MaxSocketTemperature);
|
||||
break;
|
||||
case METRICS_TEMPERATURE_MEM:
|
||||
*value = SMUQ10_ROUND(metrics->MaxHbmTemperature) *
|
||||
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
*value = SMUQ10_TO_MILLICELSIUS(metrics->MaxHbmTemperature);
|
||||
break;
|
||||
/* This is the max of all VRs and not just SOC VR.
|
||||
* No need to define another data type for the same.
|
||||
*/
|
||||
case METRICS_TEMPERATURE_VRSOC:
|
||||
*value = SMUQ10_ROUND(metrics->MaxVrTemperature) *
|
||||
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
*value = SMUQ10_TO_MILLICELSIUS(metrics->MaxVrTemperature);
|
||||
break;
|
||||
default:
|
||||
*value = UINT_MAX;
|
||||
|
|
|
|||
|
|
@ -1303,23 +1303,19 @@ static int smu_v13_0_6_get_smu_metrics_data(struct smu_context *smu,
|
|||
*value = SMUQ10_ROUND(GET_METRIC_FIELD(DramBandwidthUtilization, version));
|
||||
break;
|
||||
case METRICS_CURR_SOCKETPOWER:
|
||||
*value = SMUQ10_ROUND(GET_METRIC_FIELD(SocketPower, version)) *
|
||||
MILLIWATT_PER_WATT;
|
||||
*value = SMUQ10_TO_MILLIWATT(GET_METRIC_FIELD(SocketPower, version));
|
||||
break;
|
||||
case METRICS_TEMPERATURE_HOTSPOT:
|
||||
*value = SMUQ10_ROUND(GET_METRIC_FIELD(MaxSocketTemperature, version)) *
|
||||
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
*value = SMUQ10_TO_MILLICELSIUS(GET_METRIC_FIELD(MaxSocketTemperature, version));
|
||||
break;
|
||||
case METRICS_TEMPERATURE_MEM:
|
||||
*value = SMUQ10_ROUND(GET_METRIC_FIELD(MaxHbmTemperature, version)) *
|
||||
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
*value = SMUQ10_TO_MILLICELSIUS(GET_METRIC_FIELD(MaxHbmTemperature, version));
|
||||
break;
|
||||
/* This is the max of all VRs and not just SOC VR.
|
||||
* No need to define another data type for the same.
|
||||
*/
|
||||
case METRICS_TEMPERATURE_VRSOC:
|
||||
*value = SMUQ10_ROUND(GET_METRIC_FIELD(MaxVrTemperature, version)) *
|
||||
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
*value = SMUQ10_TO_MILLICELSIUS(GET_METRIC_FIELD(MaxVrTemperature, version));
|
||||
break;
|
||||
default:
|
||||
*value = UINT_MAX;
|
||||
|
|
|
|||
|
|
@ -583,6 +583,7 @@ int smu_v15_0_gfx_off_control(struct smu_context *smu, bool enable)
|
|||
|
||||
switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
|
||||
case IP_VERSION(15, 0, 0):
|
||||
case IP_VERSION(15, 0, 5):
|
||||
case IP_VERSION(15, 0, 9):
|
||||
if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -55,6 +55,13 @@
|
|||
#define SMUQ10_TO_UINT(x) ((x) >> 10)
|
||||
#define SMUQ10_FRAC(x) ((x) & 0x3ff)
|
||||
#define SMUQ10_ROUND(x) ((SMUQ10_TO_UINT(x)) + ((SMUQ10_FRAC(x)) >= 0x200))
|
||||
/* Convert Q10 watts to milliwatts, preserving the fractional part */
|
||||
#define SMUQ10_TO_MILLIWATT(x) (SMUQ10_TO_UINT(x) * MILLIWATT_PER_WATT + \
|
||||
((SMUQ10_FRAC(x) * MILLIWATT_PER_WATT) >> 10))
|
||||
/* Convert Q10 degrees Celsius to millidegrees, preserving the fractional part */
|
||||
#define SMUQ10_TO_MILLICELSIUS(x) \
|
||||
(SMUQ10_TO_UINT(x) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES + \
|
||||
((SMUQ10_FRAC(x) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES) >> 10))
|
||||
|
||||
#define hbm_stack_mask_valid(umc_mask) \
|
||||
(((umc_mask) & 0xF) == 0xF)
|
||||
|
|
@ -413,12 +420,10 @@ static int smu_v15_0_8_get_smu_metrics_data(struct smu_context *smu,
|
|||
*value = SMUQ10_ROUND(metrics->DramBandwidthUtilization);
|
||||
break;
|
||||
case METRICS_CURR_SOCKETPOWER:
|
||||
*value = SMUQ10_ROUND(metrics->SocketPower) *
|
||||
MILLIWATT_PER_WATT;
|
||||
*value = SMUQ10_TO_MILLIWATT(metrics->SocketPower);
|
||||
break;
|
||||
case METRICS_TEMPERATURE_HOTSPOT:
|
||||
*value = SMUQ10_ROUND(metrics->MaxSocketTemperature) *
|
||||
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
*value = SMUQ10_TO_MILLICELSIUS(metrics->MaxSocketTemperature);
|
||||
break;
|
||||
case METRICS_TEMPERATURE_MEM:
|
||||
{
|
||||
|
|
@ -436,19 +441,18 @@ static int smu_v15_0_8_get_smu_metrics_data(struct smu_context *smu,
|
|||
if (!hbm_stack_mask_valid(mask))
|
||||
continue;
|
||||
|
||||
temp = SMUQ10_ROUND(metrics->HbmTemperature[stack_idx]);
|
||||
temp = metrics->HbmTemperature[stack_idx];
|
||||
if (temp > max_hbm_temp)
|
||||
max_hbm_temp = temp;
|
||||
}
|
||||
}
|
||||
*value = max_hbm_temp * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
*value = SMUQ10_TO_MILLICELSIUS(max_hbm_temp);
|
||||
break;
|
||||
}
|
||||
/* This is the max of all VRs and not just SOC VR.
|
||||
*/
|
||||
case METRICS_TEMPERATURE_VRSOC:
|
||||
*value = SMUQ10_ROUND(metrics->MaxVrTemperature) *
|
||||
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
*value = SMUQ10_TO_MILLICELSIUS(metrics->MaxVrTemperature);
|
||||
break;
|
||||
default:
|
||||
*value = UINT_MAX;
|
||||
|
|
@ -1947,7 +1951,7 @@ static int smu_v15_0_8_set_performance_level(struct smu_context *smu,
|
|||
struct smu_dpm_table *gfx_table = &dpm_context->dpm_tables.gfx_table;
|
||||
struct smu_dpm_table *uclk_table = &dpm_context->dpm_tables.uclk_table;
|
||||
struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
switch (level) {
|
||||
case AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM:
|
||||
|
|
@ -1988,9 +1992,6 @@ static int smu_v15_0_8_set_performance_level(struct smu_context *smu,
|
|||
SMU_DPM_TABLE_MAX(uclk_table);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
smu_cmn_reset_custom_level(smu);
|
||||
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ void radeon_driver_unload_kms(struct drm_device *dev)
|
|||
if (radeon_is_px(dev)) {
|
||||
pm_runtime_get_sync(dev->dev);
|
||||
pm_runtime_forbid(dev->dev);
|
||||
pm_runtime_dont_use_autosuspend(dev->dev);
|
||||
}
|
||||
|
||||
radeon_acpi_fini(rdev);
|
||||
|
|
|
|||
|
|
@ -690,7 +690,7 @@ enum kfd_criu_op {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_criu_args - Arguments perform CRIU operation
|
||||
* struct kfd_ioctl_criu_args - Arguments perform CRIU operation
|
||||
* @devices: [in/out] User pointer to memory location for devices information.
|
||||
* This is an array of type kfd_criu_device_bucket.
|
||||
* @bos: [in/out] User pointer to memory location for BOs information
|
||||
|
|
@ -698,11 +698,11 @@ enum kfd_criu_op {
|
|||
* @priv_data: [in/out] User pointer to memory location for private data
|
||||
* @priv_data_size: [in/out] Size of priv_data in bytes
|
||||
* @num_devices: [in/out] Number of GPUs used by process. Size of @devices array.
|
||||
* @num_bos [in/out] Number of BOs used by process. Size of @bos array.
|
||||
* @num_bos: [in/out] Number of BOs used by process. Size of @bos array.
|
||||
* @num_objects: [in/out] Number of objects used by process. Objects are opaque to
|
||||
* user application.
|
||||
* @pid: [in/out] PID of the process being checkpointed
|
||||
* @op [in] Type of operation (kfd_criu_op)
|
||||
* @op: [in] Type of operation (kfd_criu_op)
|
||||
*
|
||||
* Return: 0 on success, -errno on failure
|
||||
*/
|
||||
|
|
@ -764,7 +764,7 @@ enum kfd_mmio_remap {
|
|||
#define KFD_IOCTL_SVM_FLAG_EXT_COHERENT 0x00000080
|
||||
|
||||
/**
|
||||
* kfd_ioctl_svm_op - SVM ioctl operations
|
||||
* enum kfd_ioctl_svm_op - SVM ioctl operations
|
||||
*
|
||||
* @KFD_IOCTL_SVM_OP_SET_ATTR: Modify one or more attributes
|
||||
* @KFD_IOCTL_SVM_OP_GET_ATTR: Query one or more attributes
|
||||
|
|
@ -786,7 +786,7 @@ enum kfd_ioctl_svm_location {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_svm_attr_type - SVM attribute types
|
||||
* enum kfd_ioctl_svm_attr_type - SVM attribute types
|
||||
*
|
||||
* @KFD_IOCTL_SVM_ATTR_PREFERRED_LOC: gpuid of the preferred location, 0 for
|
||||
* system memory
|
||||
|
|
@ -815,7 +815,7 @@ enum kfd_ioctl_svm_attr_type {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_svm_attribute - Attributes as pairs of type and value
|
||||
* struct kfd_ioctl_svm_attribute - Attributes as pairs of type and value
|
||||
*
|
||||
* The meaning of the @value depends on the attribute type.
|
||||
*
|
||||
|
|
@ -828,7 +828,7 @@ struct kfd_ioctl_svm_attribute {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_svm_args - Arguments for SVM ioctl
|
||||
* struct kfd_ioctl_svm_args - Arguments for SVM ioctl
|
||||
*
|
||||
* @op specifies the operation to perform (see enum
|
||||
* @kfd_ioctl_svm_op). @start_addr and @size are common for all
|
||||
|
|
@ -875,7 +875,7 @@ struct kfd_ioctl_svm_args {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_set_xnack_mode_args - Arguments for set_xnack_mode
|
||||
* struct kfd_ioctl_set_xnack_mode_args - Arguments for set_xnack_mode
|
||||
*
|
||||
* @xnack_enabled: [in/out] Whether to enable XNACK mode for this process
|
||||
*
|
||||
|
|
@ -1055,15 +1055,15 @@ struct kfd_runtime_info {
|
|||
#define KFD_RUNTIME_ENABLE_MODE_TTMP_SAVE_MASK 2
|
||||
|
||||
/**
|
||||
* kfd_ioctl_runtime_enable_args - Arguments for runtime enable
|
||||
* struct kfd_ioctl_runtime_enable_args - Arguments for runtime enable
|
||||
*
|
||||
* Coordinates debug exception signalling and debug device enablement with runtime.
|
||||
*
|
||||
* @r_debug - pointer to user struct for sharing information between ROCr and the debuggger
|
||||
* @mode_mask - mask to set mode
|
||||
* @r_debug: pointer to user struct for sharing information between ROCr and the debuggger
|
||||
* @mode_mask: mask to set mode
|
||||
* KFD_RUNTIME_ENABLE_MODE_ENABLE_MASK - enable runtime for debugging, otherwise disable
|
||||
* KFD_RUNTIME_ENABLE_MODE_TTMP_SAVE_MASK - enable trap temporary setup (ignore on disable)
|
||||
* @capabilities_mask - mask to notify runtime on what KFD supports
|
||||
* @capabilities_mask: mask to notify runtime on what KFD supports
|
||||
*
|
||||
* Return - 0 on SUCCESS.
|
||||
* - EBUSY if runtime enable call already pending.
|
||||
|
|
@ -1158,17 +1158,15 @@ enum kfd_dbg_trap_operations {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_enable_args
|
||||
*
|
||||
* Arguments for KFD_IOC_DBG_TRAP_ENABLE.
|
||||
* struct kfd_ioctl_dbg_trap_enable_args - Arguments for KFD_IOC_DBG_TRAP_ENABLE.
|
||||
*
|
||||
* Enables debug session for target process. Call @op KFD_IOC_DBG_TRAP_DISABLE in
|
||||
* kfd_ioctl_dbg_trap_args to disable debug session.
|
||||
*
|
||||
* @exception_mask (IN) - exceptions to raise to the debugger
|
||||
* @rinfo_ptr (IN) - pointer to runtime info buffer (see kfd_runtime_info)
|
||||
* @rinfo_size (IN/OUT) - size of runtime info buffer in bytes
|
||||
* @dbg_fd (IN) - fd the KFD will nofify the debugger with of raised
|
||||
* @exception_mask: (IN) - exceptions to raise to the debugger
|
||||
* @rinfo_ptr: (IN) - pointer to runtime info buffer (see kfd_runtime_info)
|
||||
* @rinfo_size: (IN/OUT) - size of runtime info buffer in bytes
|
||||
* @dbg_fd: (IN) - fd the KFD will nofify the debugger with of raised
|
||||
* exceptions set in exception_mask.
|
||||
*
|
||||
* Generic errors apply (see kfd_dbg_trap_operations).
|
||||
|
|
@ -1188,15 +1186,14 @@ struct kfd_ioctl_dbg_trap_enable_args {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_send_runtime_event_args
|
||||
* struct kfd_ioctl_dbg_trap_send_runtime_event_args - Arguments for
|
||||
* KFD_IOC_DBG_TRAP_SEND_RUNTIME_EVENT.
|
||||
*
|
||||
*
|
||||
* Arguments for KFD_IOC_DBG_TRAP_SEND_RUNTIME_EVENT.
|
||||
* Raises exceptions to runtime.
|
||||
*
|
||||
* @exception_mask (IN) - exceptions to raise to runtime
|
||||
* @gpu_id (IN) - target device id
|
||||
* @queue_id (IN) - target queue id
|
||||
* @exception_mask: (IN) - exceptions to raise to runtime
|
||||
* @gpu_id: (IN) - target device id
|
||||
* @queue_id: (IN) - target queue id
|
||||
*
|
||||
* Generic errors apply (see kfd_dbg_trap_operations).
|
||||
* Return - 0 on SUCCESS.
|
||||
|
|
@ -1213,12 +1210,12 @@ struct kfd_ioctl_dbg_trap_send_runtime_event_args {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_set_exceptions_enabled_args
|
||||
* struct kfd_ioctl_dbg_trap_set_exceptions_enabled_args - Arguments for
|
||||
* KFD_IOC_SET_EXCEPTIONS_ENABLED
|
||||
*
|
||||
* Arguments for KFD_IOC_SET_EXCEPTIONS_ENABLED
|
||||
* Set new exceptions to be raised to the debugger.
|
||||
*
|
||||
* @exception_mask (IN) - new exceptions to raise the debugger
|
||||
* @exception_mask: (IN) - new exceptions to raise the debugger
|
||||
*
|
||||
* Generic errors apply (see kfd_dbg_trap_operations).
|
||||
* Return - 0 on SUCCESS.
|
||||
|
|
@ -1228,16 +1225,16 @@ struct kfd_ioctl_dbg_trap_set_exceptions_enabled_args {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_set_wave_launch_override_args
|
||||
* struct kfd_ioctl_dbg_trap_set_wave_launch_override_args - Arguments for
|
||||
* KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE
|
||||
*
|
||||
* Arguments for KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE
|
||||
* Enable HW exceptions to raise trap.
|
||||
*
|
||||
* @override_mode (IN) - see kfd_dbg_trap_override_mode
|
||||
* @enable_mask (IN/OUT) - reference kfd_dbg_trap_mask.
|
||||
* @override_mode: (IN) - see kfd_dbg_trap_override_mode
|
||||
* @enable_mask: (IN/OUT) - reference kfd_dbg_trap_mask.
|
||||
* IN is the override modes requested to be enabled.
|
||||
* OUT is referenced in Return below.
|
||||
* @support_request_mask (IN/OUT) - reference kfd_dbg_trap_mask.
|
||||
* @support_request_mask: (IN/OUT) - reference kfd_dbg_trap_mask.
|
||||
* IN is the override modes requested for support check.
|
||||
* OUT is referenced in Return below.
|
||||
*
|
||||
|
|
@ -1254,36 +1251,38 @@ struct kfd_ioctl_dbg_trap_set_wave_launch_override_args {
|
|||
__u32 override_mode;
|
||||
__u32 enable_mask;
|
||||
__u32 support_request_mask;
|
||||
/* private: */
|
||||
__u32 pad;
|
||||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_set_wave_launch_mode_args
|
||||
* struct kfd_ioctl_dbg_trap_set_wave_launch_mode_args - Arguments for
|
||||
* KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE
|
||||
*
|
||||
* Arguments for KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE
|
||||
* Set wave launch mode.
|
||||
*
|
||||
* @mode (IN) - see kfd_dbg_trap_wave_launch_mode
|
||||
* @launch_mode: (IN) - see kfd_dbg_trap_wave_launch_mode
|
||||
*
|
||||
* Generic errors apply (see kfd_dbg_trap_operations).
|
||||
* Return - 0 on SUCCESS.
|
||||
*/
|
||||
struct kfd_ioctl_dbg_trap_set_wave_launch_mode_args {
|
||||
__u32 launch_mode;
|
||||
/* private: */
|
||||
__u32 pad;
|
||||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_suspend_queues_ags
|
||||
* struct kfd_ioctl_dbg_trap_suspend_queues_args - Arguments for
|
||||
* KFD_IOC_DBG_TRAP_SUSPEND_QUEUES
|
||||
*
|
||||
* Arguments for KFD_IOC_DBG_TRAP_SUSPEND_QUEUES
|
||||
* Suspend queues.
|
||||
*
|
||||
* @exception_mask (IN) - raised exceptions to clear
|
||||
* @queue_array_ptr (IN) - pointer to array of queue ids (u32 per queue id)
|
||||
* @exception_mask: (IN) - raised exceptions to clear
|
||||
* @queue_array_ptr: (IN) - pointer to array of queue ids (u32 per queue id)
|
||||
* to suspend
|
||||
* @num_queues (IN) - number of queues to suspend in @queue_array_ptr
|
||||
* @grace_period (IN) - wave time allowance before preemption
|
||||
* @num_queues: (IN) - number of queues to suspend in @queue_array_ptr
|
||||
* @grace_period: (IN) - wave time allowance before preemption
|
||||
* per 1K GPU clock cycle unit
|
||||
*
|
||||
* Generic errors apply (see kfd_dbg_trap_operations).
|
||||
|
|
@ -1311,14 +1310,14 @@ struct kfd_ioctl_dbg_trap_suspend_queues_args {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_resume_queues_args
|
||||
* struct kfd_ioctl_dbg_trap_resume_queues_args - Arguments for
|
||||
* KFD_IOC_DBG_TRAP_RESUME_QUEUES
|
||||
*
|
||||
* Arguments for KFD_IOC_DBG_TRAP_RESUME_QUEUES
|
||||
* Resume queues.
|
||||
*
|
||||
* @queue_array_ptr (IN) - pointer to array of queue ids (u32 per queue id)
|
||||
* @queue_array_ptr: (IN) - pointer to array of queue ids (u32 per queue id)
|
||||
* to resume
|
||||
* @num_queues (IN) - number of queues to resume in @queue_array_ptr
|
||||
* @num_queues: (IN) - number of queues to resume in @queue_array_ptr
|
||||
*
|
||||
* Generic errors apply (see kfd_dbg_trap_operations).
|
||||
* Return - Number of queues resumed on SUCCESS.
|
||||
|
|
@ -1331,20 +1330,21 @@ struct kfd_ioctl_dbg_trap_suspend_queues_args {
|
|||
struct kfd_ioctl_dbg_trap_resume_queues_args {
|
||||
__u64 queue_array_ptr;
|
||||
__u32 num_queues;
|
||||
/* private: */
|
||||
__u32 pad;
|
||||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_set_node_address_watch_args
|
||||
* struct kfd_ioctl_dbg_trap_set_node_address_watch_args - Arguments for
|
||||
* KFD_IOC_DBG_TRAP_SET_NODE_ADDRESS_WATCH
|
||||
*
|
||||
* Arguments for KFD_IOC_DBG_TRAP_SET_NODE_ADDRESS_WATCH
|
||||
* Sets address watch for device.
|
||||
*
|
||||
* @address (IN) - watch address to set
|
||||
* @mode (IN) - see kfd_dbg_trap_address_watch_mode
|
||||
* @mask (IN) - watch address mask
|
||||
* @gpu_id (IN) - target gpu to set watch point
|
||||
* @id (OUT) - watch id allocated
|
||||
* @address: (IN) - watch address to set
|
||||
* @mode: (IN) - see kfd_dbg_trap_address_watch_mode
|
||||
* @mask: (IN) - watch address mask
|
||||
* @gpu_id: (IN) - target gpu to set watch point
|
||||
* @id: (OUT) - watch id allocated
|
||||
*
|
||||
* Generic errors apply (see kfd_dbg_trap_operations).
|
||||
* Return - 0 on SUCCESS.
|
||||
|
|
@ -1361,13 +1361,13 @@ struct kfd_ioctl_dbg_trap_set_node_address_watch_args {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_clear_node_address_watch_args
|
||||
* struct kfd_ioctl_dbg_trap_clear_node_address_watch_args - Arguments for
|
||||
* KFD_IOC_DBG_TRAP_CLEAR_NODE_ADDRESS_WATCH
|
||||
*
|
||||
* Arguments for KFD_IOC_DBG_TRAP_CLEAR_NODE_ADDRESS_WATCH
|
||||
* Clear address watch for device.
|
||||
*
|
||||
* @gpu_id (IN) - target device to clear watch point
|
||||
* @id (IN) - allocated watch id to clear
|
||||
* @gpu_id: (IN) - target device to clear watch point
|
||||
* @id: (IN) - allocated watch id to clear
|
||||
*
|
||||
* Generic errors apply (see kfd_dbg_trap_operations).
|
||||
* Return - 0 on SUCCESS.
|
||||
|
|
@ -1380,12 +1380,12 @@ struct kfd_ioctl_dbg_trap_clear_node_address_watch_args {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_set_flags_args
|
||||
* struct kfd_ioctl_dbg_trap_set_flags_args - Arguments for
|
||||
* KFD_IOC_DBG_TRAP_SET_FLAGS
|
||||
*
|
||||
* Arguments for KFD_IOC_DBG_TRAP_SET_FLAGS
|
||||
* Sets flags for wave behaviour.
|
||||
*
|
||||
* @flags (IN/OUT) - IN = flags to enable, OUT = flags previously enabled
|
||||
* @flags: (IN/OUT) - IN = flags to enable, OUT = flags previously enabled
|
||||
*
|
||||
* Generic errors apply (see kfd_dbg_trap_operations).
|
||||
* Return - 0 on SUCCESS.
|
||||
|
|
@ -1393,13 +1393,13 @@ struct kfd_ioctl_dbg_trap_clear_node_address_watch_args {
|
|||
*/
|
||||
struct kfd_ioctl_dbg_trap_set_flags_args {
|
||||
__u32 flags;
|
||||
/* private: */
|
||||
__u32 pad;
|
||||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_query_debug_event_args
|
||||
*
|
||||
* Arguments for KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT
|
||||
* struct kfd_ioctl_dbg_trap_query_debug_event_args - Arguments for
|
||||
* KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT
|
||||
*
|
||||
* Find one or more raised exceptions. This function can return multiple
|
||||
* exceptions from a single queue or a single device with one call. To find
|
||||
|
|
@ -1409,9 +1409,9 @@ struct kfd_ioctl_dbg_trap_set_flags_args {
|
|||
* However, clearing an exception prevents retrieving further information
|
||||
* about it with KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO.
|
||||
*
|
||||
* @exception_mask (IN/OUT) - exception to clear (IN) and raised (OUT)
|
||||
* @gpu_id (OUT) - gpu id of exceptions raised
|
||||
* @queue_id (OUT) - queue id of exceptions raised
|
||||
* @exception_mask: (IN/OUT) - exception to clear (IN) and raised (OUT)
|
||||
* @gpu_id: (OUT) - gpu id of exceptions raised
|
||||
* @queue_id: (OUT) - queue id of exceptions raised
|
||||
*
|
||||
* Generic errors apply (see kfd_dbg_trap_operations).
|
||||
* Return - 0 on raised exception found
|
||||
|
|
@ -1426,16 +1426,16 @@ struct kfd_ioctl_dbg_trap_query_debug_event_args {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_query_exception_info_args
|
||||
* struct kfd_ioctl_dbg_trap_query_exception_info_args - Arguments for
|
||||
* KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO
|
||||
*
|
||||
* Arguments KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO
|
||||
* Get additional info on raised exception.
|
||||
*
|
||||
* @info_ptr (IN) - pointer to exception info buffer to copy to
|
||||
* @info_size (IN/OUT) - exception info buffer size (bytes)
|
||||
* @source_id (IN) - target gpu or queue id
|
||||
* @exception_code (IN) - target exception
|
||||
* @clear_exception (IN) - clear raised @exception_code exception
|
||||
* @info_ptr: (IN) - pointer to exception info buffer to copy to
|
||||
* @info_size: (IN/OUT) - exception info buffer size (bytes)
|
||||
* @source_id: (IN) - target gpu or queue id
|
||||
* @exception_code: (IN) - target exception
|
||||
* @clear_exception: (IN) - clear raised @exception_code exception
|
||||
* (0 = false, 1 = true)
|
||||
*
|
||||
* Generic errors apply (see kfd_dbg_trap_operations).
|
||||
|
|
@ -1455,20 +1455,20 @@ struct kfd_ioctl_dbg_trap_query_exception_info_args {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_get_queue_snapshot_args
|
||||
* struct kfd_ioctl_dbg_trap_queue_snapshot_args - Arguments for
|
||||
* KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT
|
||||
*
|
||||
* Arguments KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT
|
||||
* Get queue information.
|
||||
*
|
||||
* @exception_mask (IN) - exceptions raised to clear
|
||||
* @snapshot_buf_ptr (IN) - queue snapshot entry buffer (see kfd_queue_snapshot_entry)
|
||||
* @num_queues (IN/OUT) - number of queue snapshot entries
|
||||
* @exception_mask: (IN) - exceptions raised to clear
|
||||
* @snapshot_buf_ptr: (IN) - queue snapshot entry buffer (see kfd_queue_snapshot_entry)
|
||||
* @num_queues: (IN/OUT) - number of queue snapshot entries
|
||||
* The debugger specifies the size of the array allocated in @num_queues.
|
||||
* KFD returns the number of queues that actually existed. If this is
|
||||
* larger than the size specified by the debugger, KFD will not overflow
|
||||
* the array allocated by the debugger.
|
||||
*
|
||||
* @entry_size (IN/OUT) - size per entry in bytes
|
||||
* @entry_size: (IN/OUT) - size per entry in bytes
|
||||
* The debugger specifies sizeof(struct kfd_queue_snapshot_entry) in
|
||||
* @entry_size. KFD returns the number of bytes actually populated per
|
||||
* entry. The debugger should use the KFD_IOCTL_MINOR_VERSION to determine,
|
||||
|
|
@ -1491,20 +1491,20 @@ struct kfd_ioctl_dbg_trap_queue_snapshot_args {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_get_device_snapshot_args
|
||||
* struct kfd_ioctl_dbg_trap_device_snapshot_args - Arguments for
|
||||
* KFD_IOC_DBG_TRAP_GET_DEVICE_SNAPSHOT
|
||||
*
|
||||
* Arguments for KFD_IOC_DBG_TRAP_GET_DEVICE_SNAPSHOT
|
||||
* Get device information.
|
||||
*
|
||||
* @exception_mask (IN) - exceptions raised to clear
|
||||
* @snapshot_buf_ptr (IN) - pointer to snapshot buffer (see kfd_dbg_device_info_entry)
|
||||
* @num_devices (IN/OUT) - number of debug devices to snapshot
|
||||
* @exception_mask: (IN) - exceptions raised to clear
|
||||
* @snapshot_buf_ptr: (IN) - pointer to snapshot buffer (see kfd_dbg_device_info_entry)
|
||||
* @num_devices: (IN/OUT) - number of debug devices to snapshot
|
||||
* The debugger specifies the size of the array allocated in @num_devices.
|
||||
* KFD returns the number of devices that actually existed. If this is
|
||||
* larger than the size specified by the debugger, KFD will not overflow
|
||||
* the array allocated by the debugger.
|
||||
*
|
||||
* @entry_size (IN/OUT) - size per entry in bytes
|
||||
* @entry_size: (IN/OUT) - size per entry in bytes
|
||||
* The debugger specifies sizeof(struct kfd_dbg_device_info_entry) in
|
||||
* @entry_size. KFD returns the number of bytes actually populated. The
|
||||
* debugger should use KFD_IOCTL_MINOR_VERSION to determine, which fields
|
||||
|
|
@ -1527,12 +1527,10 @@ struct kfd_ioctl_dbg_trap_device_snapshot_args {
|
|||
};
|
||||
|
||||
/**
|
||||
* kfd_ioctl_dbg_trap_args
|
||||
* struct kfd_ioctl_dbg_trap_args - Arguments to debug target process.
|
||||
*
|
||||
* Arguments to debug target process.
|
||||
*
|
||||
* @pid - target process to debug
|
||||
* @op - debug operation (see kfd_dbg_trap_operations)
|
||||
* @pid: target process to debug
|
||||
* @op: debug operation (see kfd_dbg_trap_operations)
|
||||
*
|
||||
* @op determines which union struct args to use.
|
||||
* Refer to kern docs for each kfd_ioctl_dbg_trap_*_args struct.
|
||||
|
|
@ -1567,7 +1565,7 @@ enum kfd_profiler_ops {
|
|||
};
|
||||
|
||||
/**
|
||||
* Enables/Disables GPU Specific profiler settings
|
||||
* struct kfd_ioctl_pmc_settings - Enables/Disables GPU Specific profiler settings
|
||||
*/
|
||||
struct kfd_ioctl_pmc_settings {
|
||||
__u32 gpu_id; /* This is the user_gpu_id */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user