amd-drm-next-6.9-2024-03-08-1:

amdgpu:
 - DCN 3.5.1 support
 - Fixes for IOMMUv2 removal
 - UAF fix
 - Misc small fixes and cleanups
 - SR-IOV fixes
 - MCBP cleanup
 - devcoredump update
 - NBIF 6.3.1 support
 - VPE 6.1.1 support
 
 amdkfd:
 - Misc fixes and cleanups
 - GFX10.1 trap fixes
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCZetE3AAKCRC93/aFa7yZ
 2K4iAQC9mqfalMDJQegU7lUHUFzklfyWMMwrxt6Ull9HjaIcBAEAvKzRdXGWl64j
 R7qt7aF8/U/90RuplIyukCBbrh7FEQI=
 =bDXu
 -----END PGP SIGNATURE-----

Merge tag 'amd-drm-next-6.9-2024-03-08-1' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-next-6.9-2024-03-08-1:

amdgpu:
- DCN 3.5.1 support
- Fixes for IOMMUv2 removal
- UAF fix
- Misc small fixes and cleanups
- SR-IOV fixes
- MCBP cleanup
- devcoredump update
- NBIF 6.3.1 support
- VPE 6.1.1 support

amdkfd:
- Misc fixes and cleanups
- GFX10.1 trap fixes

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

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240308170741.3691166-1-alexander.deucher@amd.com
This commit is contained in:
Dave Airlie 2024-03-11 13:32:07 +10:00
commit 119b225f01
74 changed files with 122899 additions and 784 deletions

View File

@ -98,7 +98,7 @@ amdgpu-y += \
vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o arct_reg_init.o mxgpu_nv.o \
nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o soc21.o \
sienna_cichlid.o smu_v13_0_10.o nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o \
nbio_v7_9.o aqua_vanjaram.o nbio_v7_11.o lsdma_v7_0.o hdp_v7_0.o
nbio_v7_9.o aqua_vanjaram.o nbio_v7_11.o lsdma_v7_0.o hdp_v7_0.o nbif_v6_3_1.o
# add DF block
amdgpu-y += \

View File

@ -1782,9 +1782,14 @@ static int amdgpu_debugfs_vm_info_show(struct seq_file *m, void *unused)
list_for_each_entry(file, &dev->filelist, lhead) {
struct amdgpu_fpriv *fpriv = file->driver_priv;
struct amdgpu_vm *vm = &fpriv->vm;
struct amdgpu_task_info *ti;
ti = amdgpu_vm_get_task_info_vm(vm);
if (ti) {
seq_printf(m, "pid:%d\tProcess:%s ----------\n", ti->pid, ti->process_name);
amdgpu_vm_put_task_info(ti);
}
seq_printf(m, "pid:%d\tProcess:%s ----------\n",
vm->task_info.pid, vm->task_info.process_name);
r = amdgpu_bo_reserve(vm->root.bo, true);
if (r)
break;

View File

@ -4056,13 +4056,13 @@ int amdgpu_device_init(struct amdgpu_device *adev,
goto unmap_memory;
}
amdgpu_device_set_mcbp(adev);
/* early init functions */
r = amdgpu_device_ip_early_init(adev);
if (r)
goto unmap_memory;
amdgpu_device_set_mcbp(adev);
/* Get rid of things like offb */
r = drm_aperture_remove_conflicting_pci_framebuffers(adev->pdev, &amdgpu_kms_driver);
if (r)

View File

@ -61,6 +61,7 @@
#include "nbio_v4_3.h"
#include "nbio_v7_2.h"
#include "nbio_v7_7.h"
#include "nbif_v6_3_1.h"
#include "hdp_v5_0.h"
#include "hdp_v5_2.h"
#include "hdp_v6_0.h"
@ -1319,6 +1320,15 @@ static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
}
}
if (le16_to_cpu(ip->hw_id) == VPE_HWID) {
if (adev->vpe.num_instances < AMDGPU_MAX_VPE_INSTANCES)
adev->vpe.num_instances++;
else
dev_err(adev->dev, "Too many VPE instances: %d vs %d\n",
adev->vpe.num_instances + 1,
AMDGPU_MAX_VPE_INSTANCES);
}
if (le16_to_cpu(ip->hw_id) == UMC_HWID) {
adev->gmc.num_umc++;
adev->umc.node_inst_num++;
@ -1936,6 +1946,7 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(3, 2, 0):
case IP_VERSION(3, 2, 1):
case IP_VERSION(3, 5, 0):
case IP_VERSION(3, 5, 1):
if (amdgpu_sriov_vf(adev))
amdgpu_discovery_set_sriov_display(adev);
else
@ -2212,6 +2223,7 @@ static int amdgpu_discovery_set_vpe_ip_blocks(struct amdgpu_device *adev)
{
switch (amdgpu_ip_version(adev, VPE_HWIP, 0)) {
case IP_VERSION(6, 1, 0):
case IP_VERSION(6, 1, 1):
amdgpu_device_ip_block_add(adev, &vpe_v6_1_ip_block);
break;
default:
@ -2558,6 +2570,10 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
adev->nbio.funcs = &nbio_v7_7_funcs;
adev->nbio.hdp_flush_reg = &nbio_v7_7_hdp_flush_reg;
break;
case IP_VERSION(6, 3, 1):
adev->nbio.funcs = &nbif_v6_3_1_funcs;
adev->nbio.hdp_flush_reg = &nbif_v6_3_1_hdp_flush_reg;
break;
default:
break;
}

View File

@ -2693,7 +2693,7 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
}
adev->in_runpm = true;
if (amdgpu_device_supports_px(drm_dev))
if (adev->pm.rpm_mode == AMDGPU_RUNPM_PX)
drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
/*
@ -2703,7 +2703,7 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
* platforms.
* TODO: this may be also needed for PX capable platform.
*/
if (amdgpu_device_supports_boco(drm_dev))
if (adev->pm.rpm_mode == AMDGPU_RUNPM_BOCO)
adev->mp1_state = PP_MP1_STATE_UNLOAD;
ret = amdgpu_device_prepare(drm_dev);
@ -2712,15 +2712,15 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
ret = amdgpu_device_suspend(drm_dev, false);
if (ret) {
adev->in_runpm = false;
if (amdgpu_device_supports_boco(drm_dev))
if (adev->pm.rpm_mode == AMDGPU_RUNPM_BOCO)
adev->mp1_state = PP_MP1_STATE_NONE;
return ret;
}
if (amdgpu_device_supports_boco(drm_dev))
if (adev->pm.rpm_mode == AMDGPU_RUNPM_BOCO)
adev->mp1_state = PP_MP1_STATE_NONE;
if (amdgpu_device_supports_px(drm_dev)) {
if (adev->pm.rpm_mode == AMDGPU_RUNPM_PX) {
/* Only need to handle PCI state in the driver for ATPX
* PCI core handles it for _PR3.
*/
@ -2729,9 +2729,9 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
pci_ignore_hotplug(pdev);
pci_set_power_state(pdev, PCI_D3cold);
drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
} else if (amdgpu_device_supports_boco(drm_dev)) {
} else if (adev->pm.rpm_mode == AMDGPU_RUNPM_BOCO) {
/* nothing to do */
} else if (amdgpu_device_supports_baco(drm_dev)) {
} else if (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO) {
amdgpu_device_baco_enter(drm_dev);
}
@ -2754,7 +2754,7 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
if (!pci_device_is_present(adev->pdev))
adev->no_hw_access = true;
if (amdgpu_device_supports_px(drm_dev)) {
if (adev->pm.rpm_mode == AMDGPU_RUNPM_PX) {
drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
/* Only need to handle PCI state in the driver for ATPX
@ -2766,22 +2766,22 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
if (ret)
return ret;
pci_set_master(pdev);
} else if (amdgpu_device_supports_boco(drm_dev)) {
} else if (adev->pm.rpm_mode == AMDGPU_RUNPM_BOCO) {
/* Only need to handle PCI state in the driver for ATPX
* PCI core handles it for _PR3.
*/
pci_set_master(pdev);
} else if (amdgpu_device_supports_baco(drm_dev)) {
} else if (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO) {
amdgpu_device_baco_exit(drm_dev);
}
ret = amdgpu_device_resume(drm_dev, false);
if (ret) {
if (amdgpu_device_supports_px(drm_dev))
if (adev->pm.rpm_mode == AMDGPU_RUNPM_PX)
pci_disable_device(pdev);
return ret;
}
if (amdgpu_device_supports_px(drm_dev))
if (adev->pm.rpm_mode == AMDGPU_RUNPM_PX)
drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
adev->in_runpm = false;
return 0;

View File

@ -208,9 +208,15 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj,
if (!WARN_ON(!vm->process_info->eviction_fence)) {
r = amdgpu_amdkfd_bo_validate_and_fence(abo, AMDGPU_GEM_DOMAIN_GTT,
&vm->process_info->eviction_fence->base);
if (r)
dev_warn(adev->dev, "%d: validate_and_fence failed: %d\n",
vm->task_info.pid, r);
if (r) {
struct amdgpu_task_info *ti = amdgpu_vm_get_task_info_vm(vm);
dev_warn(adev->dev, "validate_and_fence failed: %d\n", r);
if (ti) {
dev_warn(adev->dev, "pid %d\n", ti->pid);
amdgpu_vm_put_task_info(ti);
}
}
}
mutex_unlock(&vm->process_info->lock);

View File

@ -131,7 +131,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
struct amdgpu_ib *ib = &ibs[0];
struct dma_fence *tmp = NULL;
bool need_ctx_switch;
unsigned int patch_offset = ~0;
struct amdgpu_vm *vm;
uint64_t fence_ctx;
uint32_t status = 0, alloc_size;
@ -139,10 +138,11 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
bool secure, init_shadow;
u64 shadow_va, csa_va, gds_va;
int vmid = AMDGPU_JOB_GET_VMID(job);
bool need_pipe_sync = false;
unsigned int cond_exec;
unsigned int i;
int r = 0;
bool need_pipe_sync = false;
if (num_ibs == 0)
return -EINVAL;
@ -228,7 +228,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
init_shadow, vmid);
if (ring->funcs->init_cond_exec)
patch_offset = amdgpu_ring_init_cond_exec(ring);
cond_exec = amdgpu_ring_init_cond_exec(ring,
ring->cond_exe_gpu_addr);
amdgpu_device_flush_hdp(adev, ring);
@ -278,16 +279,9 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
fence_flags | AMDGPU_FENCE_FLAG_64BIT);
}
if (ring->funcs->emit_gfx_shadow) {
if (ring->funcs->emit_gfx_shadow && ring->funcs->init_cond_exec) {
amdgpu_ring_emit_gfx_shadow(ring, 0, 0, 0, false, 0);
if (ring->funcs->init_cond_exec) {
unsigned int ce_offset = ~0;
ce_offset = amdgpu_ring_init_cond_exec(ring);
if (ce_offset != ~0 && ring->funcs->patch_cond_exec)
amdgpu_ring_patch_cond_exec(ring, ce_offset);
}
amdgpu_ring_init_cond_exec(ring, ring->cond_exe_gpu_addr);
}
r = amdgpu_fence_emit(ring, f, job, fence_flags);
@ -302,8 +296,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
if (ring->funcs->insert_end)
ring->funcs->insert_end(ring);
if (patch_offset != ~0 && ring->funcs->patch_cond_exec)
amdgpu_ring_patch_cond_exec(ring, patch_offset);
amdgpu_ring_patch_cond_exec(ring, cond_exec);
ring->current_ctx = fence_ctx;
if (vm && ring->funcs->emit_switch_buffer)

View File

@ -35,7 +35,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
{
struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched);
struct amdgpu_job *job = to_amdgpu_job(s_job);
struct amdgpu_task_info ti;
struct amdgpu_task_info *ti;
struct amdgpu_device *adev = ring->adev;
int idx;
int r;
@ -48,7 +48,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
return DRM_GPU_SCHED_STAT_ENODEV;
}
memset(&ti, 0, sizeof(struct amdgpu_task_info));
adev->job_hang = true;
if (amdgpu_gpu_recovery &&
@ -58,12 +58,16 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
goto exit;
}
amdgpu_vm_get_task_info(ring->adev, job->pasid, &ti);
DRM_ERROR("ring %s timeout, signaled seq=%u, emitted seq=%u\n",
job->base.sched->name, atomic_read(&ring->fence_drv.last_seq),
ring->fence_drv.sync_seq);
DRM_ERROR("Process information: process %s pid %d thread %s pid %d\n",
ti.process_name, ti.tgid, ti.task_name, ti.pid);
job->base.sched->name, atomic_read(&ring->fence_drv.last_seq),
ring->fence_drv.sync_seq);
ti = amdgpu_vm_get_task_info_pasid(ring->adev, job->pasid);
if (ti) {
DRM_ERROR("Process information: process %s pid %d thread %s pid %d\n",
ti->process_name, ti->tgid, ti->task_name, ti->pid);
amdgpu_vm_put_task_info(ti);
}
dma_fence_set_error(&s_job->s_fence->finished, -ETIME);

View File

@ -196,6 +196,13 @@ amdgpu_devcoredump_read(char *buffer, loff_t offset, size_t count,
coredump->reset_task_info.process_name,
coredump->reset_task_info.pid);
if (coredump->ring) {
drm_printf(&p, "\nRing timed out details\n");
drm_printf(&p, "IP Type: %d Ring Name: %s\n",
coredump->ring->funcs->type,
coredump->ring->name);
}
if (coredump->reset_vram_lost)
drm_printf(&p, "VRAM is lost due to GPU reset!\n");
if (coredump->adev->reset_info.num_regs) {
@ -220,6 +227,8 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost,
{
struct amdgpu_coredump_info *coredump;
struct drm_device *dev = adev_to_drm(adev);
struct amdgpu_job *job = reset_context->job;
struct drm_sched_job *s_job;
coredump = kzalloc(sizeof(*coredump), GFP_NOWAIT);
@ -230,8 +239,21 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost,
coredump->reset_vram_lost = vram_lost;
if (reset_context->job && reset_context->job->vm)
coredump->reset_task_info = reset_context->job->vm->task_info;
if (reset_context->job && reset_context->job->vm) {
struct amdgpu_task_info *ti;
struct amdgpu_vm *vm = reset_context->job->vm;
ti = amdgpu_vm_get_task_info_vm(vm);
if (ti) {
coredump->reset_task_info = *ti;
amdgpu_vm_put_task_info(ti);
}
}
if (job) {
s_job = &job->base;
coredump->ring = to_amdgpu_ring(s_job->sched);
}
coredump->adev = adev;

View File

@ -97,6 +97,7 @@ struct amdgpu_coredump_info {
struct amdgpu_task_info reset_task_info;
struct timespec64 reset_time;
bool reset_vram_lost;
struct amdgpu_ring *ring;
};
#endif

View File

@ -209,8 +209,7 @@ struct amdgpu_ring_funcs {
void (*insert_end)(struct amdgpu_ring *ring);
/* pad the indirect buffer to the necessary number of dw */
void (*pad_ib)(struct amdgpu_ring *ring, struct amdgpu_ib *ib);
unsigned (*init_cond_exec)(struct amdgpu_ring *ring);
void (*patch_cond_exec)(struct amdgpu_ring *ring, unsigned offset);
unsigned (*init_cond_exec)(struct amdgpu_ring *ring, uint64_t addr);
/* note usage for clock and power gating */
void (*begin_use)(struct amdgpu_ring *ring);
void (*end_use)(struct amdgpu_ring *ring);
@ -286,6 +285,9 @@ struct amdgpu_ring {
unsigned cond_exe_offs;
u64 cond_exe_gpu_addr;
volatile u32 *cond_exe_cpu_addr;
unsigned int set_q_mode_offs;
volatile u32 *set_q_mode_ptr;
u64 set_q_mode_token;
unsigned vm_hub;
unsigned vm_inv_eng;
struct dma_fence *vmid_wait;
@ -327,8 +329,7 @@ struct amdgpu_ring {
#define amdgpu_ring_emit_reg_write_reg_wait(r, d0, d1, v, m) (r)->funcs->emit_reg_write_reg_wait((r), (d0), (d1), (v), (m))
#define amdgpu_ring_emit_frame_cntl(r, b, s) (r)->funcs->emit_frame_cntl((r), (b), (s))
#define amdgpu_ring_pad_ib(r, ib) ((r)->funcs->pad_ib((r), (ib)))
#define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r))
#define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o))
#define amdgpu_ring_init_cond_exec(r, a) (r)->funcs->init_cond_exec((r), (a))
#define amdgpu_ring_preempt_ib(r) (r)->funcs->preempt_ib(r)
#define amdgpu_ring_patch_cntl(r, o) ((r)->funcs->patch_cntl((r), (o)))
#define amdgpu_ring_patch_ce(r, o) ((r)->funcs->patch_ce((r), (o)))
@ -411,6 +412,30 @@ static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring,
ring->count_dw -= count_dw;
}
/**
* amdgpu_ring_patch_cond_exec - patch dw count of conditional execute
* @ring: amdgpu_ring structure
* @offset: offset returned by amdgpu_ring_init_cond_exec
*
* Calculate the dw count and patch it into a cond_exec command.
*/
static inline void amdgpu_ring_patch_cond_exec(struct amdgpu_ring *ring,
unsigned int offset)
{
unsigned cur;
if (!ring->funcs->init_cond_exec)
return;
WARN_ON(offset > ring->buf_mask);
WARN_ON(ring->ring[offset] != 0);
cur = (ring->wptr - 1) & ring->buf_mask;
if (cur < offset)
cur += ring->ring_size >> 2;
ring->ring[offset] = cur - offset;
}
#define amdgpu_mes_ctx_get_offs_gpu_addr(ring, offset) \
(ring->is_mes_queue && ring->mes_ctx ? \
(ring->mes_ctx->meta_data_gpu_addr + offset) : 0)

View File

@ -513,8 +513,14 @@ int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
bo = bo_base->bo;
if (dma_resv_locking_ctx(bo->tbo.base.resv) != ticket) {
pr_warn_ratelimited("Evicted user BO is not reserved in pid %d\n",
vm->task_info.pid);
struct amdgpu_task_info *ti = amdgpu_vm_get_task_info_vm(vm);
pr_warn_ratelimited("Evicted user BO is not reserved\n");
if (ti) {
pr_warn_ratelimited("pid %d\n", ti->pid);
amdgpu_vm_put_task_info(ti);
}
return -EINVAL;
}
@ -652,7 +658,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
bool vm_flush_needed = job->vm_needs_flush;
struct dma_fence *fence = NULL;
bool pasid_mapping_needed = false;
unsigned patch_offset = 0;
unsigned int patch;
int r;
if (amdgpu_vmid_had_gpu_reset(adev, id)) {
@ -679,7 +685,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
amdgpu_ring_ib_begin(ring);
if (ring->funcs->init_cond_exec)
patch_offset = amdgpu_ring_init_cond_exec(ring);
patch = amdgpu_ring_init_cond_exec(ring,
ring->cond_exe_gpu_addr);
if (need_pipe_sync)
amdgpu_ring_emit_pipeline_sync(ring);
@ -727,8 +734,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job,
}
dma_fence_put(fence);
if (ring->funcs->patch_cond_exec)
amdgpu_ring_patch_cond_exec(ring, patch_offset);
amdgpu_ring_patch_cond_exec(ring, patch);
/* the double SWITCH_BUFFER here *cannot* be skipped by COND_EXEC */
if (ring->funcs->emit_switch_buffer) {
@ -1385,10 +1391,6 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
struct amdgpu_bo_va_mapping, list);
list_del(&mapping->list);
if (vm->pte_support_ats &&
mapping->start < AMDGPU_GMC_HOLE_START)
init_pte_value = AMDGPU_PTE_DEFAULT_ATC;
r = amdgpu_vm_update_range(adev, vm, false, false, true, false,
resv, mapping->start, mapping->last,
init_pte_value, 0, 0, NULL, NULL,
@ -2225,6 +2227,108 @@ long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout)
return dma_fence_wait_timeout(vm->last_unlocked, true, timeout);
}
static void amdgpu_vm_destroy_task_info(struct kref *kref)
{
struct amdgpu_task_info *ti = container_of(kref, struct amdgpu_task_info, refcount);
kfree(ti);
}
static inline struct amdgpu_vm *
amdgpu_vm_get_vm_from_pasid(struct amdgpu_device *adev, u32 pasid)
{
struct amdgpu_vm *vm;
unsigned long flags;
xa_lock_irqsave(&adev->vm_manager.pasids, flags);
vm = xa_load(&adev->vm_manager.pasids, pasid);
xa_unlock_irqrestore(&adev->vm_manager.pasids, flags);
return vm;
}
/**
* amdgpu_vm_put_task_info - reference down the vm task_info ptr
*
* @task_info: task_info struct under discussion.
*
* frees the vm task_info ptr at the last put
*/
void amdgpu_vm_put_task_info(struct amdgpu_task_info *task_info)
{
kref_put(&task_info->refcount, amdgpu_vm_destroy_task_info);
}
/**
* amdgpu_vm_get_task_info_vm - Extracts task info for a vm.
*
* @vm: VM to get info from
*
* Returns the reference counted task_info structure, which must be
* referenced down with amdgpu_vm_put_task_info.
*/
struct amdgpu_task_info *
amdgpu_vm_get_task_info_vm(struct amdgpu_vm *vm)
{
struct amdgpu_task_info *ti = NULL;
if (vm) {
ti = vm->task_info;
kref_get(&vm->task_info->refcount);
}
return ti;
}
/**
* amdgpu_vm_get_task_info_pasid - Extracts task info for a PASID.
*
* @adev: drm device pointer
* @pasid: PASID identifier for VM
*
* Returns the reference counted task_info structure, which must be
* referenced down with amdgpu_vm_put_task_info.
*/
struct amdgpu_task_info *
amdgpu_vm_get_task_info_pasid(struct amdgpu_device *adev, u32 pasid)
{
return amdgpu_vm_get_task_info_vm(
amdgpu_vm_get_vm_from_pasid(adev, pasid));
}
static int amdgpu_vm_create_task_info(struct amdgpu_vm *vm)
{
vm->task_info = kzalloc(sizeof(struct amdgpu_task_info), GFP_KERNEL);
if (!vm->task_info)
return -ENOMEM;
kref_init(&vm->task_info->refcount);
return 0;
}
/**
* amdgpu_vm_set_task_info - Sets VMs task info.
*
* @vm: vm for which to set the info
*/
void amdgpu_vm_set_task_info(struct amdgpu_vm *vm)
{
if (!vm->task_info)
return;
if (vm->task_info->pid == current->pid)
return;
vm->task_info->pid = current->pid;
get_task_comm(vm->task_info->task_name, current);
if (current->group_leader->mm != current->mm)
return;
vm->task_info->tgid = current->group_leader->pid;
get_task_comm(vm->task_info->process_name, current->group_leader);
}
/**
* amdgpu_vm_init - initialize a vm instance
*
@ -2264,7 +2368,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (r)
return r;
vm->pte_support_ats = false;
vm->is_compute_context = false;
vm->use_cpu_for_update = !!(adev->vm_manager.vm_update_mode &
@ -2311,6 +2414,10 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (r)
goto error_free_root;
r = amdgpu_vm_create_task_info(vm);
if (r)
DRM_DEBUG("Failed to create task info for VM\n");
amdgpu_bo_unreserve(vm->root.bo);
amdgpu_bo_unref(&root_bo);
@ -2350,30 +2457,12 @@ error_free_delayed:
*/
int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm)
{
bool pte_support_ats = (adev->asic_type == CHIP_RAVEN);
int r;
r = amdgpu_bo_reserve(vm->root.bo, true);
if (r)
return r;
/* Check if PD needs to be reinitialized and do it before
* changing any other state, in case it fails.
*/
if (pte_support_ats != vm->pte_support_ats) {
/* Sanity checks */
if (!amdgpu_vm_pt_is_root_clean(adev, vm)) {
r = -EINVAL;
goto unreserve_bo;
}
vm->pte_support_ats = pte_support_ats;
r = amdgpu_vm_pt_clear(adev, vm, to_amdgpu_bo_vm(vm->root.bo),
false);
if (r)
goto unreserve_bo;
}
/* Update VM state */
vm->use_cpu_for_update = !!(adev->vm_manager.vm_update_mode &
AMDGPU_VM_USE_CPU_FOR_COMPUTE);
@ -2450,6 +2539,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
root = amdgpu_bo_ref(vm->root.bo);
amdgpu_bo_reserve(root, true);
amdgpu_vm_put_task_info(vm->task_info);
amdgpu_vm_set_pasid(adev, vm, 0);
dma_fence_wait(vm->last_unlocked, false);
dma_fence_put(vm->last_unlocked);
@ -2606,48 +2696,6 @@ int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
return 0;
}
/**
* amdgpu_vm_get_task_info - Extracts task info for a PASID.
*
* @adev: drm device pointer
* @pasid: PASID identifier for VM
* @task_info: task_info to fill.
*/
void amdgpu_vm_get_task_info(struct amdgpu_device *adev, u32 pasid,
struct amdgpu_task_info *task_info)
{
struct amdgpu_vm *vm;
unsigned long flags;
xa_lock_irqsave(&adev->vm_manager.pasids, flags);
vm = xa_load(&adev->vm_manager.pasids, pasid);
if (vm)
*task_info = vm->task_info;
xa_unlock_irqrestore(&adev->vm_manager.pasids, flags);
}
/**
* amdgpu_vm_set_task_info - Sets VMs task info.
*
* @vm: vm for which to set the info
*/
void amdgpu_vm_set_task_info(struct amdgpu_vm *vm)
{
if (vm->task_info.pid)
return;
vm->task_info.pid = current->pid;
get_task_comm(vm->task_info.task_name, current);
if (current->group_leader->mm != current->mm)
return;
vm->task_info.tgid = current->group_leader->pid;
get_task_comm(vm->task_info.process_name, current->group_leader);
}
/**
* amdgpu_vm_handle_fault - graceful handling of VM faults.
* @adev: amdgpu device pointer

View File

@ -203,10 +203,11 @@ struct amdgpu_vm_pte_funcs {
};
struct amdgpu_task_info {
char process_name[TASK_COMM_LEN];
char task_name[TASK_COMM_LEN];
pid_t pid;
pid_t tgid;
char process_name[TASK_COMM_LEN];
char task_name[TASK_COMM_LEN];
pid_t pid;
pid_t tgid;
struct kref refcount;
};
/**
@ -357,9 +358,6 @@ struct amdgpu_vm {
/* Functions to use for VM table updates */
const struct amdgpu_vm_update_funcs *update_funcs;
/* Flag to indicate ATS support from PTE for GFX9 */
bool pte_support_ats;
/* Up to 128 pending retry page faults */
DECLARE_KFIFO(faults, u64, 128);
@ -373,7 +371,7 @@ struct amdgpu_vm {
uint64_t pd_phys_addr;
/* Some basic info about the task */
struct amdgpu_task_info task_info;
struct amdgpu_task_info *task_info;
/* Store positions of group of BOs */
struct ttm_lru_bulk_move lru_bulk_move;
@ -514,8 +512,14 @@ bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring,
struct amdgpu_job *job);
void amdgpu_vm_check_compute_bug(struct amdgpu_device *adev);
void amdgpu_vm_get_task_info(struct amdgpu_device *adev, u32 pasid,
struct amdgpu_task_info *task_info);
struct amdgpu_task_info *
amdgpu_vm_get_task_info_pasid(struct amdgpu_device *adev, u32 pasid);
struct amdgpu_task_info *
amdgpu_vm_get_task_info_vm(struct amdgpu_vm *vm);
void amdgpu_vm_put_task_info(struct amdgpu_task_info *task_info);
bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid,
u32 vmid, u32 node_id, uint64_t addr,
bool write_fault);
@ -533,8 +537,6 @@ int amdgpu_vm_pt_create(struct amdgpu_device *adev, struct amdgpu_vm *vm,
int level, bool immediate, struct amdgpu_bo_vm **vmbo,
int32_t xcp_id);
void amdgpu_vm_pt_free_root(struct amdgpu_device *adev, struct amdgpu_vm *vm);
bool amdgpu_vm_pt_is_root_clean(struct amdgpu_device *adev,
struct amdgpu_vm *vm);
int amdgpu_vm_pde_update(struct amdgpu_vm_update_params *params,
struct amdgpu_vm_bo_base *entry);

View File

@ -89,22 +89,6 @@ static unsigned int amdgpu_vm_pt_num_entries(struct amdgpu_device *adev,
return AMDGPU_VM_PTE_COUNT(adev);
}
/**
* amdgpu_vm_pt_num_ats_entries - return the number of ATS entries in the root PD
*
* @adev: amdgpu_device pointer
*
* Returns:
* The number of entries in the root page directory which needs the ATS setting.
*/
static unsigned int amdgpu_vm_pt_num_ats_entries(struct amdgpu_device *adev)
{
unsigned int shift;
shift = amdgpu_vm_pt_level_shift(adev, adev->vm_manager.root_level);
return AMDGPU_GMC_HOLE_START >> (shift + AMDGPU_GPU_PAGE_SHIFT);
}
/**
* amdgpu_vm_pt_entries_mask - the mask to get the entry number of a PD/PT
*
@ -379,7 +363,7 @@ int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct ttm_operation_ctx ctx = { true, false };
struct amdgpu_vm_update_params params;
struct amdgpu_bo *ancestor = &vmbo->bo;
unsigned int entries, ats_entries;
unsigned int entries;
struct amdgpu_bo *bo = &vmbo->bo;
uint64_t addr;
int r, idx;
@ -394,27 +378,6 @@ int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm,
}
entries = amdgpu_bo_size(bo) / 8;
if (!vm->pte_support_ats) {
ats_entries = 0;
} else if (!bo->parent) {
ats_entries = amdgpu_vm_pt_num_ats_entries(adev);
ats_entries = min(ats_entries, entries);
entries -= ats_entries;
} else {
struct amdgpu_vm_bo_base *pt;
pt = ancestor->vm_bo;
ats_entries = amdgpu_vm_pt_num_ats_entries(adev);
if ((pt - to_amdgpu_bo_vm(vm->root.bo)->entries) >=
ats_entries) {
ats_entries = 0;
} else {
ats_entries = entries;
entries = 0;
}
}
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
if (r)
@ -445,44 +408,24 @@ int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm,
goto exit;
addr = 0;
if (ats_entries) {
uint64_t value = 0, flags;
flags = AMDGPU_PTE_DEFAULT_ATC;
uint64_t value = 0, flags = 0;
if (adev->asic_type >= CHIP_VEGA10) {
if (level != AMDGPU_VM_PTB) {
/* Handle leaf PDEs as PTEs */
flags |= AMDGPU_PDE_PTE;
amdgpu_gmc_get_vm_pde(adev, level, &value, &flags);
amdgpu_gmc_get_vm_pde(adev, level,
&value, &flags);
} else {
/* Workaround for fault priority problem on GMC9 */
flags = AMDGPU_PTE_EXECUTABLE;
}
r = vm->update_funcs->update(&params, vmbo, addr, 0,
ats_entries, value, flags);
if (r)
goto exit;
addr += ats_entries * 8;
}
if (entries) {
uint64_t value = 0, flags = 0;
if (adev->asic_type >= CHIP_VEGA10) {
if (level != AMDGPU_VM_PTB) {
/* Handle leaf PDEs as PTEs */
flags |= AMDGPU_PDE_PTE;
amdgpu_gmc_get_vm_pde(adev, level,
&value, &flags);
} else {
/* Workaround for fault priority problem on GMC9 */
flags = AMDGPU_PTE_EXECUTABLE;
}
}
r = vm->update_funcs->update(&params, vmbo, addr, 0, entries,
value, flags);
if (r)
goto exit;
}
r = vm->update_funcs->update(&params, vmbo, addr, 0, entries,
value, flags);
if (r)
goto exit;
r = vm->update_funcs->commit(&params, NULL);
exit:
@ -727,33 +670,6 @@ void amdgpu_vm_pt_free_root(struct amdgpu_device *adev, struct amdgpu_vm *vm)
amdgpu_vm_pt_free_dfs(adev, vm, NULL, false);
}
/**
* amdgpu_vm_pt_is_root_clean - check if a root PD is clean
*
* @adev: amdgpu_device pointer
* @vm: the VM to check
*
* Check all entries of the root PD, if any subsequent PDs are allocated,
* it means there are page table creating and filling, and is no a clean
* VM
*
* Returns:
* 0 if this VM is clean
*/
bool amdgpu_vm_pt_is_root_clean(struct amdgpu_device *adev,
struct amdgpu_vm *vm)
{
enum amdgpu_vm_level root = adev->vm_manager.root_level;
unsigned int entries = amdgpu_vm_pt_num_entries(adev, root);
unsigned int i = 0;
for (i = 0; i < entries; i++) {
if (to_amdgpu_bo_vm(vm->root.bo)->entries[i].bo)
return false;
}
return true;
}
/**
* amdgpu_vm_pde_update - update a single level in the hierarchy
*
@ -1027,7 +943,7 @@ int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params *params,
trace_amdgpu_vm_update_ptes(params, frag_start, upd_end,
min(nptes, 32u), dst, incr,
upd_flags,
vm->task_info.tgid,
vm->task_info ? vm->task_info->tgid : 0,
vm->immediate.fence_context);
amdgpu_vm_pte_update_flags(params, to_amdgpu_bo_vm(pt),
cursor.level, pe_start, dst,

View File

@ -297,6 +297,10 @@ static int vpe_early_init(void *handle)
case IP_VERSION(6, 1, 0):
vpe_v6_1_set_funcs(vpe);
break;
case IP_VERSION(6, 1, 1):
vpe_v6_1_set_funcs(vpe);
vpe->collaborate_mode = true;
break;
default:
return -EINVAL;
}
@ -304,6 +308,8 @@ static int vpe_early_init(void *handle)
vpe_set_ring_funcs(adev);
vpe_set_regs(vpe);
dev_info(adev->dev, "VPE: collaborate mode %s", vpe->collaborate_mode ? "true" : "false");
return 0;
}
@ -457,6 +463,18 @@ static uint64_t vpe_get_csa_mc_addr(struct amdgpu_ring *ring, uint32_t vmid)
return csa_mc_addr;
}
static void vpe_ring_emit_pred_exec(struct amdgpu_ring *ring,
uint32_t device_select,
uint32_t exec_count)
{
if (!ring->adev->vpe.collaborate_mode)
return;
amdgpu_ring_write(ring, VPE_CMD_HEADER(VPE_CMD_OPCODE_PRED_EXE, 0) |
(device_select << 16));
amdgpu_ring_write(ring, exec_count & 0x1fff);
}
static void vpe_ring_emit_ib(struct amdgpu_ring *ring,
struct amdgpu_job *job,
struct amdgpu_ib *ib,
@ -505,6 +523,8 @@ static void vpe_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
uint32_t seq = ring->fence_drv.sync_seq;
uint64_t addr = ring->fence_drv.gpu_addr;
vpe_ring_emit_pred_exec(ring, 0, 6);
/* wait for idle */
amdgpu_ring_write(ring, VPE_CMD_HEADER(VPE_CMD_OPCODE_POLL_REGMEM,
VPE_POLL_REGMEM_SUBOP_REGMEM) |
@ -520,6 +540,8 @@ static void vpe_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
static void vpe_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg, uint32_t val)
{
vpe_ring_emit_pred_exec(ring, 0, 3);
amdgpu_ring_write(ring, VPE_CMD_HEADER(VPE_CMD_OPCODE_REG_WRITE, 0));
amdgpu_ring_write(ring, reg << 2);
amdgpu_ring_write(ring, val);
@ -528,6 +550,8 @@ static void vpe_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg, uint32_t
static void vpe_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg,
uint32_t val, uint32_t mask)
{
vpe_ring_emit_pred_exec(ring, 0, 6);
amdgpu_ring_write(ring, VPE_CMD_HEADER(VPE_CMD_OPCODE_POLL_REGMEM,
VPE_POLL_REGMEM_SUBOP_REGMEM) |
VPE_CMD_POLL_REGMEM_HEADER_FUNC(3) | /* equal */
@ -546,34 +570,24 @@ static void vpe_ring_emit_vm_flush(struct amdgpu_ring *ring, unsigned int vmid,
amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
}
static unsigned int vpe_ring_init_cond_exec(struct amdgpu_ring *ring)
static unsigned int vpe_ring_init_cond_exec(struct amdgpu_ring *ring,
uint64_t addr)
{
unsigned int ret;
if (ring->adev->vpe.collaborate_mode)
return ~0;
amdgpu_ring_write(ring, VPE_CMD_HEADER(VPE_CMD_OPCODE_COND_EXE, 0));
amdgpu_ring_write(ring, lower_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, upper_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
amdgpu_ring_write(ring, 1);
ret = ring->wptr & ring->buf_mask;/* this is the offset we need patch later */
amdgpu_ring_write(ring, 0x55aa55aa);/* insert dummy here and patch it later */
ret = ring->wptr & ring->buf_mask;
amdgpu_ring_write(ring, 0);
return ret;
}
static void vpe_ring_patch_cond_exec(struct amdgpu_ring *ring, unsigned int offset)
{
unsigned int cur;
WARN_ON_ONCE(offset > ring->buf_mask);
WARN_ON_ONCE(ring->ring[offset] != 0x55aa55aa);
cur = (ring->wptr - 1) & ring->buf_mask;
if (cur > offset)
ring->ring[offset] = cur - offset;
else
ring->ring[offset] = (ring->buf_mask + 1) - offset + cur;
}
static int vpe_ring_preempt_ib(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
@ -695,16 +709,22 @@ static void vpe_ring_set_wptr(struct amdgpu_ring *ring)
upper_32_bits(ring->wptr << 2));
atomic64_set((atomic64_t *)ring->wptr_cpu_addr, ring->wptr << 2);
WDOORBELL64(ring->doorbell_index, ring->wptr << 2);
if (vpe->collaborate_mode)
WDOORBELL64(ring->doorbell_index + 4, ring->wptr << 2);
} else {
dev_dbg(adev->dev, "Not using doorbell, \
regVPEC_QUEUE0_RB_WPTR == 0x%08x, \
regVPEC_QUEUE0_RB_WPTR_HI == 0x%08x\n",
lower_32_bits(ring->wptr << 2),
upper_32_bits(ring->wptr << 2));
WREG32(vpe_get_reg_offset(vpe, ring->me, vpe->regs.queue0_rb_wptr_lo),
lower_32_bits(ring->wptr << 2));
WREG32(vpe_get_reg_offset(vpe, ring->me, vpe->regs.queue0_rb_wptr_hi),
upper_32_bits(ring->wptr << 2));
int i;
for (i = 0; i < vpe->num_instances; i++) {
dev_dbg(adev->dev, "Not using doorbell, \
regVPEC_QUEUE0_RB_WPTR == 0x%08x, \
regVPEC_QUEUE0_RB_WPTR_HI == 0x%08x\n",
lower_32_bits(ring->wptr << 2),
upper_32_bits(ring->wptr << 2));
WREG32(vpe_get_reg_offset(vpe, i, vpe->regs.queue0_rb_wptr_lo),
lower_32_bits(ring->wptr << 2));
WREG32(vpe_get_reg_offset(vpe, i, vpe->regs.queue0_rb_wptr_hi),
upper_32_bits(ring->wptr << 2));
}
}
}
@ -864,7 +884,6 @@ static const struct amdgpu_ring_funcs vpe_ring_funcs = {
.test_ring = vpe_ring_test_ring,
.test_ib = vpe_ring_test_ib,
.init_cond_exec = vpe_ring_init_cond_exec,
.patch_cond_exec = vpe_ring_patch_cond_exec,
.preempt_ib = vpe_ring_preempt_ib,
.begin_use = vpe_ring_begin_use,
.end_use = vpe_ring_end_use,

View File

@ -27,6 +27,8 @@
#include "amdgpu_irq.h"
#include "vpe_6_1_fw_if.h"
#define AMDGPU_MAX_VPE_INSTANCES 2
struct amdgpu_vpe;
struct vpe_funcs {
@ -74,6 +76,9 @@ struct amdgpu_vpe {
uint32_t *cmdbuf_cpu_addr;
struct delayed_work idle_work;
bool context_started;
uint32_t num_instances;
bool collaborate_mode;
};
int amdgpu_vpe_psp_update_sram(struct amdgpu_device *adev);

View File

@ -8542,34 +8542,23 @@ static void gfx_v10_0_ring_emit_cntxcntl(struct amdgpu_ring *ring,
amdgpu_ring_write(ring, 0);
}
static unsigned int gfx_v10_0_ring_emit_init_cond_exec(struct amdgpu_ring *ring)
static unsigned int gfx_v10_0_ring_emit_init_cond_exec(struct amdgpu_ring *ring,
uint64_t addr)
{
unsigned int ret;
amdgpu_ring_write(ring, PACKET3(PACKET3_COND_EXEC, 3));
amdgpu_ring_write(ring, lower_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, upper_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, 0); /* discard following DWs if *cond_exec_gpu_addr==0 */
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
/* discard following DWs if *cond_exec_gpu_addr==0 */
amdgpu_ring_write(ring, 0);
ret = ring->wptr & ring->buf_mask;
amdgpu_ring_write(ring, 0x55aa55aa); /* patch dummy value later */
/* patch dummy value later */
amdgpu_ring_write(ring, 0);
return ret;
}
static void gfx_v10_0_ring_emit_patch_cond_exec(struct amdgpu_ring *ring, unsigned int offset)
{
unsigned int cur;
BUG_ON(offset > ring->buf_mask);
BUG_ON(ring->ring[offset] != 0x55aa55aa);
cur = (ring->wptr - 1) & ring->buf_mask;
if (likely(cur > offset))
ring->ring[offset] = cur - offset;
else
ring->ring[offset] = (ring->buf_mask + 1) - offset + cur;
}
static int gfx_v10_0_ring_preempt_ib(struct amdgpu_ring *ring)
{
int i, r = 0;
@ -9224,7 +9213,6 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
.emit_switch_buffer = gfx_v10_0_ring_emit_sb,
.emit_cntxcntl = gfx_v10_0_ring_emit_cntxcntl,
.init_cond_exec = gfx_v10_0_ring_emit_init_cond_exec,
.patch_cond_exec = gfx_v10_0_ring_emit_patch_cond_exec,
.preempt_ib = gfx_v10_0_ring_preempt_ib,
.emit_frame_cntl = gfx_v10_0_ring_emit_frame_cntl,
.emit_wreg = gfx_v10_0_ring_emit_wreg,

View File

@ -5461,6 +5461,11 @@ static void gfx_v11_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
amdgpu_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
amdgpu_ring_write(ring, 0x0);
}
/* Make sure that we can't skip the SET_Q_MODE packets when the VM
* changed in any way.
*/
ring->set_q_mode_ptr = NULL;
}
static void gfx_v11_0_ring_emit_fence_kiq(struct amdgpu_ring *ring, u64 addr,
@ -5510,16 +5515,81 @@ static void gfx_v11_0_ring_emit_cntxcntl(struct amdgpu_ring *ring,
amdgpu_ring_write(ring, 0);
}
static unsigned gfx_v11_0_ring_emit_init_cond_exec(struct amdgpu_ring *ring,
uint64_t addr)
{
unsigned ret;
amdgpu_ring_write(ring, PACKET3(PACKET3_COND_EXEC, 3));
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
/* discard following DWs if *cond_exec_gpu_addr==0 */
amdgpu_ring_write(ring, 0);
ret = ring->wptr & ring->buf_mask;
/* patch dummy value later */
amdgpu_ring_write(ring, 0);
return ret;
}
static void gfx_v11_0_ring_emit_gfx_shadow(struct amdgpu_ring *ring,
u64 shadow_va, u64 csa_va,
u64 gds_va, bool init_shadow,
int vmid)
{
struct amdgpu_device *adev = ring->adev;
unsigned int offs, end;
if (!adev->gfx.cp_gfx_shadow)
if (!adev->gfx.cp_gfx_shadow || !ring->ring_obj)
return;
/*
* The logic here isn't easy to understand because we need to keep state
* accross multiple executions of the function as well as between the
* CPU and GPU. The general idea is that the newly written GPU command
* has a condition on the previous one and only executed if really
* necessary.
*/
/*
* The dw in the NOP controls if the next SET_Q_MODE packet should be
* executed or not. Reserve 64bits just to be on the save side.
*/
amdgpu_ring_write(ring, PACKET3(PACKET3_NOP, 1));
offs = ring->wptr & ring->buf_mask;
/*
* We start with skipping the prefix SET_Q_MODE and always executing
* the postfix SET_Q_MODE packet. This is changed below with a
* WRITE_DATA command when the postfix executed.
*/
amdgpu_ring_write(ring, shadow_va ? 1 : 0);
amdgpu_ring_write(ring, 0);
if (ring->set_q_mode_offs) {
uint64_t addr;
addr = amdgpu_bo_gpu_offset(ring->ring_obj);
addr += ring->set_q_mode_offs << 2;
end = gfx_v11_0_ring_emit_init_cond_exec(ring, addr);
}
/*
* When the postfix SET_Q_MODE packet executes we need to make sure that the
* next prefix SET_Q_MODE packet executes as well.
*/
if (!shadow_va) {
uint64_t addr;
addr = amdgpu_bo_gpu_offset(ring->ring_obj);
addr += offs << 2;
amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
amdgpu_ring_write(ring, WRITE_DATA_DST_SEL(5) | WR_CONFIRM);
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
amdgpu_ring_write(ring, 0x1);
}
amdgpu_ring_write(ring, PACKET3(PACKET3_SET_Q_PREEMPTION_MODE, 7));
amdgpu_ring_write(ring, lower_32_bits(shadow_va));
amdgpu_ring_write(ring, upper_32_bits(shadow_va));
@ -5531,33 +5601,26 @@ static void gfx_v11_0_ring_emit_gfx_shadow(struct amdgpu_ring *ring,
PACKET3_SET_Q_PREEMPTION_MODE_IB_VMID(vmid) : 0);
amdgpu_ring_write(ring, init_shadow ?
PACKET3_SET_Q_PREEMPTION_MODE_INIT_SHADOW_MEM : 0);
}
static unsigned gfx_v11_0_ring_emit_init_cond_exec(struct amdgpu_ring *ring)
{
unsigned ret;
if (ring->set_q_mode_offs)
amdgpu_ring_patch_cond_exec(ring, end);
amdgpu_ring_write(ring, PACKET3(PACKET3_COND_EXEC, 3));
amdgpu_ring_write(ring, lower_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, upper_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, 0); /* discard following DWs if *cond_exec_gpu_addr==0 */
ret = ring->wptr & ring->buf_mask;
amdgpu_ring_write(ring, 0x55aa55aa); /* patch dummy value later */
if (shadow_va) {
uint64_t token = shadow_va ^ csa_va ^ gds_va ^ vmid;
return ret;
}
/*
* If the tokens match try to skip the last postfix SET_Q_MODE
* packet to avoid saving/restoring the state all the time.
*/
if (ring->set_q_mode_ptr && ring->set_q_mode_token == token)
*ring->set_q_mode_ptr = 0;
static void gfx_v11_0_ring_emit_patch_cond_exec(struct amdgpu_ring *ring, unsigned offset)
{
unsigned cur;
BUG_ON(offset > ring->buf_mask);
BUG_ON(ring->ring[offset] != 0x55aa55aa);
ring->set_q_mode_token = token;
} else {
ring->set_q_mode_ptr = &ring->ring[ring->set_q_mode_offs];
}
cur = (ring->wptr - 1) & ring->buf_mask;
if (likely(cur > offset))
ring->ring[offset] = cur - offset;
else
ring->ring[offset] = (ring->buf_mask + 1) - offset + cur;
ring->set_q_mode_offs = offs;
}
static int gfx_v11_0_ring_preempt_ib(struct amdgpu_ring *ring)
@ -6124,7 +6187,7 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_gfx = {
.emit_frame_size = /* totally 247 maximum if 16 IBs */
5 + /* update_spm_vmid */
5 + /* COND_EXEC */
9 + /* SET_Q_PREEMPTION_MODE */
22 + /* SET_Q_PREEMPTION_MODE */
7 + /* PIPELINE_SYNC */
SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 +
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 +
@ -6137,6 +6200,7 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_gfx = {
31 + /* DE_META */
3 + /* CNTX_CTRL */
5 + /* HDP_INVL */
22 + /* SET_Q_PREEMPTION_MODE */
8 + 8 + /* FENCE x2 */
8, /* gfx_v11_0_emit_mem_sync */
.emit_ib_size = 4, /* gfx_v11_0_ring_emit_ib_gfx */
@ -6153,7 +6217,6 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_gfx = {
.emit_cntxcntl = gfx_v11_0_ring_emit_cntxcntl,
.emit_gfx_shadow = gfx_v11_0_ring_emit_gfx_shadow,
.init_cond_exec = gfx_v11_0_ring_emit_init_cond_exec,
.patch_cond_exec = gfx_v11_0_ring_emit_patch_cond_exec,
.preempt_ib = gfx_v11_0_ring_preempt_ib,
.emit_frame_cntl = gfx_v11_0_ring_emit_frame_cntl,
.emit_wreg = gfx_v11_0_ring_emit_wreg,

View File

@ -6326,33 +6326,22 @@ static void gfx_v8_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t flags)
amdgpu_ring_write(ring, 0);
}
static unsigned gfx_v8_0_ring_emit_init_cond_exec(struct amdgpu_ring *ring)
static unsigned gfx_v8_0_ring_emit_init_cond_exec(struct amdgpu_ring *ring,
uint64_t addr)
{
unsigned ret;
amdgpu_ring_write(ring, PACKET3(PACKET3_COND_EXEC, 3));
amdgpu_ring_write(ring, lower_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, upper_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, 0); /* discard following DWs if *cond_exec_gpu_addr==0 */
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
/* discard following DWs if *cond_exec_gpu_addr==0 */
amdgpu_ring_write(ring, 0);
ret = ring->wptr & ring->buf_mask;
amdgpu_ring_write(ring, 0x55aa55aa); /* patch dummy value later */
/* patch dummy value later */
amdgpu_ring_write(ring, 0);
return ret;
}
static void gfx_v8_0_ring_emit_patch_cond_exec(struct amdgpu_ring *ring, unsigned offset)
{
unsigned cur;
BUG_ON(offset > ring->buf_mask);
BUG_ON(ring->ring[offset] != 0x55aa55aa);
cur = (ring->wptr & ring->buf_mask) - 1;
if (likely(cur > offset))
ring->ring[offset] = cur - offset;
else
ring->ring[offset] = (ring->ring_size >> 2) - offset + cur;
}
static void gfx_v8_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg,
uint32_t reg_val_offs)
{
@ -6932,7 +6921,6 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_gfx = {
.emit_switch_buffer = gfx_v8_ring_emit_sb,
.emit_cntxcntl = gfx_v8_ring_emit_cntxcntl,
.init_cond_exec = gfx_v8_0_ring_emit_init_cond_exec,
.patch_cond_exec = gfx_v8_0_ring_emit_patch_cond_exec,
.emit_wreg = gfx_v8_0_ring_emit_wreg,
.soft_recovery = gfx_v8_0_ring_soft_recovery,
.emit_mem_sync = gfx_v8_0_emit_mem_sync,

View File

@ -2080,7 +2080,7 @@ static int gfx_v9_0_sw_init(void *handle)
ring->doorbell_index = adev->doorbell_index.gfx_ring0 << 1;
/* disable scheduler on the real ring */
ring->no_scheduler = true;
ring->no_scheduler = adev->gfx.mcbp;
ring->vm_hub = AMDGPU_GFXHUB(0);
r = amdgpu_ring_init(adev, ring, 1024, &adev->gfx.eop_irq,
AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP,
@ -2090,7 +2090,7 @@ static int gfx_v9_0_sw_init(void *handle)
}
/* set up the software rings */
if (adev->gfx.num_gfx_rings) {
if (adev->gfx.mcbp && adev->gfx.num_gfx_rings) {
for (i = 0; i < GFX9_NUM_SW_GFX_RINGS; i++) {
ring = &adev->gfx.sw_gfx_ring[i];
ring->ring_obj = NULL;
@ -2180,7 +2180,7 @@ static int gfx_v9_0_sw_fini(void *handle)
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (adev->gfx.num_gfx_rings) {
if (adev->gfx.mcbp && adev->gfx.num_gfx_rings) {
for (i = 0; i < GFX9_NUM_SW_GFX_RINGS; i++)
amdgpu_ring_fini(&adev->gfx.sw_gfx_ring[i]);
amdgpu_ring_mux_fini(&adev->gfx.muxer);
@ -5610,31 +5610,21 @@ static void gfx_v9_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t flags)
amdgpu_ring_write(ring, 0);
}
static unsigned gfx_v9_0_ring_emit_init_cond_exec(struct amdgpu_ring *ring)
static unsigned gfx_v9_0_ring_emit_init_cond_exec(struct amdgpu_ring *ring,
uint64_t addr)
{
unsigned ret;
amdgpu_ring_write(ring, PACKET3(PACKET3_COND_EXEC, 3));
amdgpu_ring_write(ring, lower_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, upper_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, 0); /* discard following DWs if *cond_exec_gpu_addr==0 */
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
/* discard following DWs if *cond_exec_gpu_addr==0 */
amdgpu_ring_write(ring, 0);
ret = ring->wptr & ring->buf_mask;
amdgpu_ring_write(ring, 0x55aa55aa); /* patch dummy value later */
/* patch dummy value later */
amdgpu_ring_write(ring, 0);
return ret;
}
static void gfx_v9_0_ring_emit_patch_cond_exec(struct amdgpu_ring *ring, unsigned offset)
{
unsigned cur;
BUG_ON(offset > ring->buf_mask);
BUG_ON(ring->ring[offset] != 0x55aa55aa);
cur = (ring->wptr - 1) & ring->buf_mask;
if (likely(cur > offset))
ring->ring[offset] = cur - offset;
else
ring->ring[offset] = (ring->ring_size>>2) - offset + cur;
}
static void gfx_v9_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg,
uint32_t reg_val_offs)
{
@ -5909,11 +5899,14 @@ static int gfx_v9_0_eop_irq(struct amdgpu_device *adev,
switch (me_id) {
case 0:
if (adev->gfx.num_gfx_rings &&
!amdgpu_mcbp_handle_trailing_fence_irq(&adev->gfx.muxer)) {
/* Fence signals are handled on the software rings*/
for (i = 0; i < GFX9_NUM_SW_GFX_RINGS; i++)
amdgpu_fence_process(&adev->gfx.sw_gfx_ring[i]);
if (adev->gfx.num_gfx_rings) {
if (!adev->gfx.mcbp) {
amdgpu_fence_process(&adev->gfx.gfx_ring[0]);
} else if (!amdgpu_mcbp_handle_trailing_fence_irq(&adev->gfx.muxer)) {
/* Fence signals are handled on the software rings*/
for (i = 0; i < GFX9_NUM_SW_GFX_RINGS; i++)
amdgpu_fence_process(&adev->gfx.sw_gfx_ring[i]);
}
}
break;
case 1:
@ -6908,7 +6901,6 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_gfx = {
.emit_switch_buffer = gfx_v9_ring_emit_sb,
.emit_cntxcntl = gfx_v9_ring_emit_cntxcntl,
.init_cond_exec = gfx_v9_0_ring_emit_init_cond_exec,
.patch_cond_exec = gfx_v9_0_ring_emit_patch_cond_exec,
.preempt_ib = gfx_v9_0_ring_preempt_ib,
.emit_frame_cntl = gfx_v9_0_ring_emit_frame_cntl,
.emit_wreg = gfx_v9_0_ring_emit_wreg,
@ -6963,7 +6955,6 @@ static const struct amdgpu_ring_funcs gfx_v9_0_sw_ring_funcs_gfx = {
.emit_switch_buffer = gfx_v9_ring_emit_sb,
.emit_cntxcntl = gfx_v9_ring_emit_cntxcntl,
.init_cond_exec = gfx_v9_0_ring_emit_init_cond_exec,
.patch_cond_exec = gfx_v9_0_ring_emit_patch_cond_exec,
.emit_frame_cntl = gfx_v9_0_ring_emit_frame_cntl,
.emit_wreg = gfx_v9_0_ring_emit_wreg,
.emit_reg_wait = gfx_v9_0_ring_emit_reg_wait,
@ -7050,7 +7041,7 @@ static void gfx_v9_0_set_ring_funcs(struct amdgpu_device *adev)
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
adev->gfx.gfx_ring[i].funcs = &gfx_v9_0_ring_funcs_gfx;
if (adev->gfx.num_gfx_rings) {
if (adev->gfx.mcbp && adev->gfx.num_gfx_rings) {
for (i = 0; i < GFX9_NUM_SW_GFX_RINGS; i++)
adev->gfx.sw_gfx_ring[i].funcs = &gfx_v9_0_sw_ring_funcs_gfx;
}

View File

@ -105,7 +105,7 @@ static int gmc_v10_0_process_interrupt(struct amdgpu_device *adev,
struct amdgpu_vmhub *hub = &adev->vmhub[vmhub_index];
bool retry_fault = !!(entry->src_data[1] & 0x80);
bool write_fault = !!(entry->src_data[1] & 0x20);
struct amdgpu_task_info task_info;
struct amdgpu_task_info *task_info;
uint32_t status = 0;
u64 addr;
@ -157,18 +157,22 @@ static int gmc_v10_0_process_interrupt(struct amdgpu_device *adev,
if (!printk_ratelimit())
return 0;
memset(&task_info, 0, sizeof(struct amdgpu_task_info));
amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
dev_err(adev->dev,
"[%s] page fault (src_id:%u ring:%u vmid:%u pasid:%u, for process %s pid %d thread %s pid %d)\n",
"[%s] page fault (src_id:%u ring:%u vmid:%u pasid:%u)\n",
entry->vmid_src ? "mmhub" : "gfxhub",
entry->src_id, entry->ring_id, entry->vmid,
entry->pasid, task_info.process_name, task_info.tgid,
task_info.task_name, task_info.pid);
entry->src_id, entry->ring_id, entry->vmid, entry->pasid);
task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid);
if (task_info) {
dev_err(adev->dev,
" in process %s pid %d thread %s pid %d\n",
task_info->process_name, task_info->tgid,
task_info->task_name, task_info->pid);
amdgpu_vm_put_task_info(task_info);
}
dev_err(adev->dev, " in page starting at address 0x%016llx from client 0x%x (%s)\n",
addr, entry->client_id,
soc15_ih_clientid_name[entry->client_id]);
addr, entry->client_id,
soc15_ih_clientid_name[entry->client_id]);
if (!amdgpu_sriov_vf(adev))
hub->vmhub_funcs->print_l2_protection_fault_status(adev,

View File

@ -126,19 +126,24 @@ static int gmc_v11_0_process_interrupt(struct amdgpu_device *adev,
}
if (printk_ratelimit()) {
struct amdgpu_task_info task_info;
memset(&task_info, 0, sizeof(struct amdgpu_task_info));
amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
struct amdgpu_task_info *task_info;
dev_err(adev->dev,
"[%s] page fault (src_id:%u ring:%u vmid:%u pasid:%u, for process %s pid %d thread %s pid %d)\n",
"[%s] page fault (src_id:%u ring:%u vmid:%u pasid:%u)\n",
entry->vmid_src ? "mmhub" : "gfxhub",
entry->src_id, entry->ring_id, entry->vmid,
entry->pasid, task_info.process_name, task_info.tgid,
task_info.task_name, task_info.pid);
entry->src_id, entry->ring_id, entry->vmid, entry->pasid);
task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid);
if (task_info) {
dev_err(adev->dev,
" in process %s pid %d thread %s pid %d)\n",
task_info->process_name, task_info->tgid,
task_info->task_name, task_info->pid);
amdgpu_vm_put_task_info(task_info);
}
dev_err(adev->dev, " in page starting at address 0x%016llx from client %d\n",
addr, entry->client_id);
addr, entry->client_id);
if (!amdgpu_sriov_vf(adev))
hub->vmhub_funcs->print_l2_protection_fault_status(adev, status);
}

View File

@ -1445,18 +1445,24 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev,
gmc_v8_0_set_fault_enable_default(adev, false);
if (printk_ratelimit()) {
struct amdgpu_task_info task_info;
struct amdgpu_task_info *task_info;
memset(&task_info, 0, sizeof(struct amdgpu_task_info));
amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
dev_err(adev->dev, "GPU fault detected: %d 0x%08x\n",
entry->src_id, entry->src_data[0]);
task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid);
if (task_info) {
dev_err(adev->dev, " for process %s pid %d thread %s pid %d\n",
task_info->process_name, task_info->tgid,
task_info->task_name, task_info->pid);
amdgpu_vm_put_task_info(task_info);
}
dev_err(adev->dev, "GPU fault detected: %d 0x%08x for process %s pid %d thread %s pid %d\n",
entry->src_id, entry->src_data[0], task_info.process_name,
task_info.tgid, task_info.task_name, task_info.pid);
dev_err(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
addr);
addr);
dev_err(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
status);
gmc_v8_0_vm_decode_fault(adev, status, addr, mc_client,
entry->pasid);
}

View File

@ -549,7 +549,7 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
bool retry_fault = !!(entry->src_data[1] & 0x80);
bool write_fault = !!(entry->src_data[1] & 0x20);
uint32_t status = 0, cid = 0, rw = 0;
struct amdgpu_task_info task_info;
struct amdgpu_task_info *task_info;
struct amdgpu_vmhub *hub;
const char *mmhub_cid;
const char *hub_name;
@ -626,15 +626,20 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
if (!printk_ratelimit())
return 0;
memset(&task_info, 0, sizeof(struct amdgpu_task_info));
amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
dev_err(adev->dev,
"[%s] %s page fault (src_id:%u ring:%u vmid:%u pasid:%u, for process %s pid %d thread %s pid %d)\n",
hub_name, retry_fault ? "retry" : "no-retry",
entry->src_id, entry->ring_id, entry->vmid,
entry->pasid, task_info.process_name, task_info.tgid,
task_info.task_name, task_info.pid);
"[%s] %s page fault (src_id:%u ring:%u vmid:%u pasid:%u)\n", hub_name,
retry_fault ? "retry" : "no-retry",
entry->src_id, entry->ring_id, entry->vmid, entry->pasid);
task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid);
if (task_info) {
dev_err(adev->dev,
" for process %s pid %d thread %s pid %d)\n",
task_info->process_name, task_info->tgid,
task_info->task_name, task_info->pid);
amdgpu_vm_put_task_info(task_info);
}
dev_err(adev->dev, " in page starting at address 0x%016llx from IH client 0x%x (%s)\n",
addr, entry->client_id,
soc15_ih_clientid_name[entry->client_id]);

View File

@ -0,0 +1,495 @@
/*
* Copyright 2023 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "nbif_v6_3_1.h"
#include "nbif/nbif_6_3_1_offset.h"
#include "nbif/nbif_6_3_1_sh_mask.h"
#include "pcie/pcie_6_1_0_offset.h"
#include "pcie/pcie_6_1_0_sh_mask.h"
#include <uapi/linux/kfd_ioctl.h>
static void nbif_v6_3_1_remap_hdp_registers(struct amdgpu_device *adev)
{
WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL,
adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL);
WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_REG_FLUSH_CNTL,
adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL);
}
static u32 nbif_v6_3_1_get_rev_id(struct amdgpu_device *adev)
{
u32 tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0);
tmp &= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK;
tmp >>= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT;
return tmp;
}
static void nbif_v6_3_1_mc_access_enable(struct amdgpu_device *adev, bool enable)
{
if (enable)
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN,
BIF_BX0_BIF_FB_EN__FB_READ_EN_MASK |
BIF_BX0_BIF_FB_EN__FB_WRITE_EN_MASK);
else
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN, 0);
}
static u32 nbif_v6_3_1_get_memsize(struct amdgpu_device *adev)
{
return RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_RCC_CONFIG_MEMSIZE);
}
static void nbif_v6_3_1_sdma_doorbell_range(struct amdgpu_device *adev,
int instance, bool use_doorbell,
int doorbell_index,
int doorbell_size)
{
if (instance == 0) {
u32 doorbell_range = RREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL);
if (use_doorbell) {
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
S2A_DOORBELL_PORT2_ENABLE,
0x1);
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
S2A_DOORBELL_PORT2_AWID,
0xe);
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
S2A_DOORBELL_PORT2_RANGE_OFFSET,
doorbell_index);
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
S2A_DOORBELL_PORT2_RANGE_SIZE,
doorbell_size);
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
S2A_DOORBELL_PORT2_AWADDR_31_28_VALUE,
0x3);
} else
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL,
S2A_DOORBELL_PORT2_RANGE_SIZE,
0);
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_2_CTRL, doorbell_range);
}
}
static void nbif_v6_3_1_vcn_doorbell_range(struct amdgpu_device *adev,
bool use_doorbell, int doorbell_index,
int instance)
{
u32 doorbell_range;
if (instance)
doorbell_range = RREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL);
else
doorbell_range = RREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL);
if (use_doorbell) {
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL,
S2A_DOORBELL_PORT4_ENABLE,
0x1);
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL,
S2A_DOORBELL_PORT4_AWID,
instance ? 0x7 : 0x4);
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL,
S2A_DOORBELL_PORT4_RANGE_OFFSET,
doorbell_index);
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL,
S2A_DOORBELL_PORT4_RANGE_SIZE,
8);
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL,
S2A_DOORBELL_PORT4_AWADDR_31_28_VALUE,
instance ? 0x7 : 0x4);
} else
doorbell_range = REG_SET_FIELD(doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL,
S2A_DOORBELL_PORT4_RANGE_SIZE,
0);
if (instance)
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL, doorbell_range);
else
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_4_CTRL, doorbell_range);
}
static void nbif_v6_3_1_gc_doorbell_init(struct amdgpu_device *adev)
{
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_0_CTRL, 0x30000007);
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_3_CTRL, 0x3000000d);
}
static void nbif_v6_3_1_enable_doorbell_aperture(struct amdgpu_device *adev,
bool enable)
{
WREG32_FIELD15_PREREG(NBIO, 0, RCC_DEV0_EPF0_RCC_DOORBELL_APER_EN,
BIF_DOORBELL_APER_EN, enable ? 1 : 0);
}
static void
nbif_v6_3_1_enable_doorbell_selfring_aperture(struct amdgpu_device *adev,
bool enable)
{
u32 tmp = 0;
if (enable) {
tmp = REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL,
DOORBELL_SELFRING_GPA_APER_EN, 1) |
REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL,
DOORBELL_SELFRING_GPA_APER_MODE, 1) |
REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL,
DOORBELL_SELFRING_GPA_APER_SIZE, 0);
WREG32_SOC15(NBIO, 0, regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_LOW,
lower_32_bits(adev->doorbell.base));
WREG32_SOC15(NBIO, 0, regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_HIGH,
upper_32_bits(adev->doorbell.base));
}
WREG32_SOC15(NBIO, 0, regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL, tmp);
}
static void nbif_v6_3_1_ih_doorbell_range(struct amdgpu_device *adev,
bool use_doorbell, int doorbell_index)
{
u32 ih_doorbell_range = RREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL);
if (use_doorbell) {
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL,
S2A_DOORBELL_PORT1_ENABLE,
0x1);
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL,
S2A_DOORBELL_PORT1_AWID,
0x0);
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL,
S2A_DOORBELL_PORT1_RANGE_OFFSET,
doorbell_index);
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL,
S2A_DOORBELL_PORT1_RANGE_SIZE,
2);
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL,
S2A_DOORBELL_PORT1_AWADDR_31_28_VALUE,
0x0);
} else
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
GDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL,
S2A_DOORBELL_PORT1_RANGE_SIZE,
0);
WREG32_SOC15(NBIO, 0, regGDC_S2A0_S2A_DOORBELL_ENTRY_1_CTRL, ih_doorbell_range);
}
static void nbif_v6_3_1_ih_control(struct amdgpu_device *adev)
{
u32 interrupt_cntl;
/* setup interrupt control */
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL2, adev->dummy_page_addr >> 8);
interrupt_cntl = RREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL);
/*
* BIF_BX0_INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi
* BIF_BX0_INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN
*/
interrupt_cntl = REG_SET_FIELD(interrupt_cntl, BIF_BX0_INTERRUPT_CNTL,
IH_DUMMY_RD_OVERRIDE, 0);
/* BIF_BX0_INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK=1 if ring is in non-cacheable memory, e.g., vram */
interrupt_cntl = REG_SET_FIELD(interrupt_cntl, BIF_BX0_INTERRUPT_CNTL,
IH_REQ_NONSNOOP_EN, 0);
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL, interrupt_cntl);
}
static void
nbif_v6_3_1_update_medium_grain_clock_gating(struct amdgpu_device *adev,
bool enable)
{
}
static void
nbif_v6_3_1_update_medium_grain_light_sleep(struct amdgpu_device *adev,
bool enable)
{
}
static void
nbif_v6_3_1_get_clockgating_state(struct amdgpu_device *adev,
u64 *flags)
{
}
static u32 nbif_v6_3_1_get_hdp_flush_req_offset(struct amdgpu_device *adev)
{
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_REQ);
}
static u32 nbif_v6_3_1_get_hdp_flush_done_offset(struct amdgpu_device *adev)
{
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_DONE);
}
static u32 nbif_v6_3_1_get_pcie_index_offset(struct amdgpu_device *adev)
{
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_RSMU_INDEX);
}
static u32 nbif_v6_3_1_get_pcie_data_offset(struct amdgpu_device *adev)
{
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_RSMU_DATA);
}
const struct nbio_hdp_flush_reg nbif_v6_3_1_hdp_flush_reg = {
.ref_and_mask_cp0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP0_MASK,
.ref_and_mask_cp1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP1_MASK,
.ref_and_mask_cp2 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP2_MASK,
.ref_and_mask_cp3 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP3_MASK,
.ref_and_mask_cp4 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP4_MASK,
.ref_and_mask_cp5 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP5_MASK,
.ref_and_mask_cp6 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP6_MASK,
.ref_and_mask_cp7 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP7_MASK,
.ref_and_mask_cp8 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP8_MASK,
.ref_and_mask_cp9 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP9_MASK,
.ref_and_mask_sdma0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA0_MASK,
.ref_and_mask_sdma1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA1_MASK,
};
static void nbif_v6_3_1_init_registers(struct amdgpu_device *adev)
{
uint32_t data;
data = RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF2_STRAP2);
data &= ~RCC_DEV0_EPF2_STRAP2__STRAP_NO_SOFT_RESET_DEV0_F2_MASK;
WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF2_STRAP2, data);
}
static u32 nbif_v6_3_1_get_rom_offset(struct amdgpu_device *adev)
{
u32 data, rom_offset;
data = RREG32_SOC15(NBIO, 0, regREGS_ROM_OFFSET_CTRL);
rom_offset = REG_GET_FIELD(data, REGS_ROM_OFFSET_CTRL, ROM_OFFSET);
return rom_offset;
}
#ifdef CONFIG_PCIEASPM
static void nbif_v6_3_1_program_ltr(struct amdgpu_device *adev)
{
uint32_t def, data;
def = RREG32_SOC15(NBIO, 0, regRCC_EP_DEV0_0_EP_PCIE_TX_LTR_CNTL);
data = 0x35EB;
data &= ~RCC_EP_DEV0_0_EP_PCIE_TX_LTR_CNTL__LTR_PRIV_MSG_DIS_IN_PM_NON_D0_MASK;
data &= ~RCC_EP_DEV0_0_EP_PCIE_TX_LTR_CNTL__LTR_PRIV_RST_LTR_IN_DL_DOWN_MASK;
if (def != data)
WREG32_SOC15(NBIO, 0, regRCC_EP_DEV0_0_EP_PCIE_TX_LTR_CNTL, data);
def = data = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP2);
data &= ~RCC_STRAP0_RCC_BIF_STRAP2__STRAP_LTR_IN_ASPML1_DIS_MASK;
if (def != data)
WREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP2, data);
def = data = RREG32_SOC15(NBIO, 0, regBIF_CFG_DEV0_EPF0_DEVICE_CNTL2);
if (adev->pdev->ltr_path)
data |= BIF_CFG_DEV0_EPF0_DEVICE_CNTL2__LTR_EN_MASK;
else
data &= ~BIF_CFG_DEV0_EPF0_DEVICE_CNTL2__LTR_EN_MASK;
if (def != data)
WREG32_SOC15(NBIO, 0, regBIF_CFG_DEV0_EPF0_DEVICE_CNTL2, data);
}
#endif
static void nbif_v6_3_1_program_aspm(struct amdgpu_device *adev)
{
#ifdef CONFIG_PCIEASPM
uint32_t def, data;
def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL);
data &= ~PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK;
data &= ~PCIE_LC_CNTL__LC_L0S_INACTIVITY_MASK;
data |= PCIE_LC_CNTL__LC_PMI_TO_L1_DIS_MASK;
if (def != data)
WREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL, data);
def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL7);
data |= PCIE_LC_CNTL7__LC_NBIF_ASPM_INPUT_EN_MASK;
if (def != data)
WREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL7, data);
def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL3);
data |= PCIE_LC_CNTL3__LC_DSC_DONT_ENTER_L23_AFTER_PME_ACK_MASK;
if (def != data)
WREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL3, data);
def = data = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP3);
data &= ~RCC_STRAP0_RCC_BIF_STRAP3__STRAP_VLINK_ASPM_IDLE_TIMER_MASK;
data &= ~RCC_STRAP0_RCC_BIF_STRAP3__STRAP_VLINK_PM_L1_ENTRY_TIMER_MASK;
if (def != data)
WREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP3, data);
def = data = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP5);
data &= ~RCC_STRAP0_RCC_BIF_STRAP5__STRAP_VLINK_LDN_ENTRY_TIMER_MASK;
if (def != data)
WREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP5, data);
def = data = RREG32_SOC15(NBIO, 0, regBIF_CFG_DEV0_EPF0_DEVICE_CNTL2);
data &= ~BIF_CFG_DEV0_EPF0_DEVICE_CNTL2__LTR_EN_MASK;
if (def != data)
WREG32_SOC15(NBIO, 0, regBIF_CFG_DEV0_EPF0_DEVICE_CNTL2, data);
WREG32_SOC15(NBIO, 0, regBIF_CFG_DEV0_EPF0_PCIE_LTR_CAP, 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;
if (def != data)
WREG32_SOC15(NBIO, 0, regPSWUSP0_PCIE_LC_CNTL2, data);
#endif
def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL4);
data |= PCIE_LC_CNTL4__LC_L1_POWERDOWN_MASK;
if (def != data)
WREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL4, data);
def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_RXRECOVER_RXSTANDBY_CNTL);
data |= PCIE_LC_RXRECOVER_RXSTANDBY_CNTL__LC_RX_L0S_STANDBY_EN_MASK;
if (def != data)
WREG32_SOC15(PCIE, 0, regPCIE_LC_RXRECOVER_RXSTANDBY_CNTL, data);
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;
data |= 0x0010 << RCC_STRAP0_RCC_BIF_STRAP3__STRAP_VLINK_PM_L1_ENTRY_TIMER__SHIFT;
if (def != data)
WREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP3, data);
def = data = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP5);
data |= 0x0010 << RCC_STRAP0_RCC_BIF_STRAP5__STRAP_VLINK_LDN_ENTRY_TIMER__SHIFT;
if (def != data)
WREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_BIF_STRAP5, data);
def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL);
data |= 0x0 << PCIE_LC_CNTL__LC_L0S_INACTIVITY__SHIFT;
data |= 0x9 << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT;
data &= ~PCIE_LC_CNTL__LC_PMI_TO_L1_DIS_MASK;
if (def != data)
WREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL, data);
def = data = RREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL3);
data &= ~PCIE_LC_CNTL3__LC_DSC_DONT_ENTER_L23_AFTER_PME_ACK_MASK;
if (def != data)
WREG32_SOC15(PCIE, 0, regPCIE_LC_CNTL3, data);
#endif
}
const struct amdgpu_nbio_funcs nbif_v6_3_1_funcs = {
.get_hdp_flush_req_offset = nbif_v6_3_1_get_hdp_flush_req_offset,
.get_hdp_flush_done_offset = nbif_v6_3_1_get_hdp_flush_done_offset,
.get_pcie_index_offset = nbif_v6_3_1_get_pcie_index_offset,
.get_pcie_data_offset = nbif_v6_3_1_get_pcie_data_offset,
.get_rev_id = nbif_v6_3_1_get_rev_id,
.mc_access_enable = nbif_v6_3_1_mc_access_enable,
.get_memsize = nbif_v6_3_1_get_memsize,
.sdma_doorbell_range = nbif_v6_3_1_sdma_doorbell_range,
.vcn_doorbell_range = nbif_v6_3_1_vcn_doorbell_range,
.gc_doorbell_init = nbif_v6_3_1_gc_doorbell_init,
.enable_doorbell_aperture = nbif_v6_3_1_enable_doorbell_aperture,
.enable_doorbell_selfring_aperture = nbif_v6_3_1_enable_doorbell_selfring_aperture,
.ih_doorbell_range = nbif_v6_3_1_ih_doorbell_range,
.update_medium_grain_clock_gating = nbif_v6_3_1_update_medium_grain_clock_gating,
.update_medium_grain_light_sleep = nbif_v6_3_1_update_medium_grain_light_sleep,
.get_clockgating_state = nbif_v6_3_1_get_clockgating_state,
.ih_control = nbif_v6_3_1_ih_control,
.init_registers = nbif_v6_3_1_init_registers,
.remap_hdp_registers = nbif_v6_3_1_remap_hdp_registers,
.get_rom_offset = nbif_v6_3_1_get_rom_offset,
.program_aspm = nbif_v6_3_1_program_aspm,
};
static void nbif_v6_3_1_sriov_ih_doorbell_range(struct amdgpu_device *adev,
bool use_doorbell, int doorbell_index)
{
}
static void nbif_v6_3_1_sriov_sdma_doorbell_range(struct amdgpu_device *adev,
int instance, bool use_doorbell,
int doorbell_index,
int doorbell_size)
{
}
static void nbif_v6_3_1_sriov_vcn_doorbell_range(struct amdgpu_device *adev,
bool use_doorbell,
int doorbell_index, int instance)
{
}
static void nbif_v6_3_1_sriov_gc_doorbell_init(struct amdgpu_device *adev)
{
}
const struct amdgpu_nbio_funcs nbif_v6_3_1_sriov_funcs = {
.get_hdp_flush_req_offset = nbif_v6_3_1_get_hdp_flush_req_offset,
.get_hdp_flush_done_offset = nbif_v6_3_1_get_hdp_flush_done_offset,
.get_pcie_index_offset = nbif_v6_3_1_get_pcie_index_offset,
.get_pcie_data_offset = nbif_v6_3_1_get_pcie_data_offset,
.get_rev_id = nbif_v6_3_1_get_rev_id,
.mc_access_enable = nbif_v6_3_1_mc_access_enable,
.get_memsize = nbif_v6_3_1_get_memsize,
.sdma_doorbell_range = nbif_v6_3_1_sriov_sdma_doorbell_range,
.vcn_doorbell_range = nbif_v6_3_1_sriov_vcn_doorbell_range,
.gc_doorbell_init = nbif_v6_3_1_sriov_gc_doorbell_init,
.enable_doorbell_aperture = nbif_v6_3_1_enable_doorbell_aperture,
.enable_doorbell_selfring_aperture = nbif_v6_3_1_enable_doorbell_selfring_aperture,
.ih_doorbell_range = nbif_v6_3_1_sriov_ih_doorbell_range,
.update_medium_grain_clock_gating = nbif_v6_3_1_update_medium_grain_clock_gating,
.update_medium_grain_light_sleep = nbif_v6_3_1_update_medium_grain_light_sleep,
.get_clockgating_state = nbif_v6_3_1_get_clockgating_state,
.ih_control = nbif_v6_3_1_ih_control,
.init_registers = nbif_v6_3_1_init_registers,
.remap_hdp_registers = nbif_v6_3_1_remap_hdp_registers,
.get_rom_offset = nbif_v6_3_1_get_rom_offset,
};

View File

@ -0,0 +1,33 @@
/*
* Copyright 2023 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __NBIO_V6_3_1_H__
#define __NBIO_V6_3_1_H__
#include "soc15_common.h"
extern const struct nbio_hdp_flush_reg nbif_v6_3_1_hdp_flush_reg;
extern const struct amdgpu_nbio_funcs nbif_v6_3_1_funcs;
extern const struct amdgpu_nbio_funcs nbif_v6_3_1_sriov_funcs;
#endif

View File

@ -2104,7 +2104,7 @@ static int sdma_v4_0_print_iv_entry(struct amdgpu_device *adev,
struct amdgpu_iv_entry *entry)
{
int instance;
struct amdgpu_task_info task_info;
struct amdgpu_task_info *task_info;
u64 addr;
instance = sdma_v4_0_irq_id_to_seq(entry->client_id);
@ -2116,15 +2116,20 @@ static int sdma_v4_0_print_iv_entry(struct amdgpu_device *adev,
addr = (u64)entry->src_data[0] << 12;
addr |= ((u64)entry->src_data[1] & 0xf) << 44;
memset(&task_info, 0, sizeof(struct amdgpu_task_info));
amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
dev_dbg_ratelimited(adev->dev,
"[sdma%d] address:0x%016llx src_id:%u ring:%u vmid:%u "
"pasid:%u, for process %s pid %d thread %s pid %d\n",
instance, addr, entry->src_id, entry->ring_id, entry->vmid,
entry->pasid, task_info.process_name, task_info.tgid,
task_info.task_name, task_info.pid);
"[sdma%d] address:0x%016llx src_id:%u ring:%u vmid:%u pasid:%u\n",
instance, addr, entry->src_id, entry->ring_id, entry->vmid,
entry->pasid);
task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid);
if (task_info) {
dev_dbg_ratelimited(adev->dev,
" for process %s pid %d thread %s pid %d\n",
task_info->process_name, task_info->tgid,
task_info->task_name, task_info->pid);
amdgpu_vm_put_task_info(task_info);
}
return 0;
}

View File

@ -1644,7 +1644,7 @@ static int sdma_v4_4_2_print_iv_entry(struct amdgpu_device *adev,
struct amdgpu_iv_entry *entry)
{
int instance;
struct amdgpu_task_info task_info;
struct amdgpu_task_info *task_info;
u64 addr;
instance = sdma_v4_4_2_irq_id_to_seq(entry->client_id);
@ -1656,15 +1656,19 @@ static int sdma_v4_4_2_print_iv_entry(struct amdgpu_device *adev,
addr = (u64)entry->src_data[0] << 12;
addr |= ((u64)entry->src_data[1] & 0xf) << 44;
memset(&task_info, 0, sizeof(struct amdgpu_task_info));
amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
dev_dbg_ratelimited(adev->dev,
"[sdma%d] address:0x%016llx src_id:%u ring:%u vmid:%u "
"pasid:%u, for process %s pid %d thread %s pid %d\n",
instance, addr, entry->src_id, entry->ring_id, entry->vmid,
entry->pasid, task_info.process_name, task_info.tgid,
task_info.task_name, task_info.pid);
"[sdma%d] address:0x%016llx src_id:%u ring:%u vmid:%u pasid:%u\n",
instance, addr, entry->src_id, entry->ring_id, entry->vmid,
entry->pasid);
task_info = amdgpu_vm_get_task_info_pasid(adev, entry->pasid);
if (task_info) {
dev_dbg_ratelimited(adev->dev, " for process %s pid %d thread %s pid %d\n",
task_info->process_name, task_info->tgid,
task_info->task_name, task_info->pid);
amdgpu_vm_put_task_info(task_info);
}
return 0;
}

View File

@ -249,35 +249,23 @@ static int sdma_v5_0_init_microcode(struct amdgpu_device *adev)
return ret;
}
static unsigned sdma_v5_0_ring_init_cond_exec(struct amdgpu_ring *ring)
static unsigned sdma_v5_0_ring_init_cond_exec(struct amdgpu_ring *ring,
uint64_t addr)
{
unsigned ret;
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_COND_EXE));
amdgpu_ring_write(ring, lower_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, upper_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
amdgpu_ring_write(ring, 1);
ret = ring->wptr & ring->buf_mask;/* this is the offset we need patch later */
amdgpu_ring_write(ring, 0x55aa55aa);/* insert dummy here and patch it later */
/* this is the offset we need patch later */
ret = ring->wptr & ring->buf_mask;
/* insert dummy here and patch it later */
amdgpu_ring_write(ring, 0);
return ret;
}
static void sdma_v5_0_ring_patch_cond_exec(struct amdgpu_ring *ring,
unsigned offset)
{
unsigned cur;
BUG_ON(offset > ring->buf_mask);
BUG_ON(ring->ring[offset] != 0x55aa55aa);
cur = (ring->wptr - 1) & ring->buf_mask;
if (cur > offset)
ring->ring[offset] = cur - offset;
else
ring->ring[offset] = (ring->buf_mask + 1) - offset + cur;
}
/**
* sdma_v5_0_ring_get_rptr - get the current read pointer
*
@ -1780,7 +1768,6 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = {
.emit_reg_wait = sdma_v5_0_ring_emit_reg_wait,
.emit_reg_write_reg_wait = sdma_v5_0_ring_emit_reg_write_reg_wait,
.init_cond_exec = sdma_v5_0_ring_init_cond_exec,
.patch_cond_exec = sdma_v5_0_ring_patch_cond_exec,
.preempt_ib = sdma_v5_0_ring_preempt_ib,
};

View File

@ -89,35 +89,23 @@ static u32 sdma_v5_2_get_reg_offset(struct amdgpu_device *adev, u32 instance, u3
return base + internal_offset;
}
static unsigned sdma_v5_2_ring_init_cond_exec(struct amdgpu_ring *ring)
static unsigned sdma_v5_2_ring_init_cond_exec(struct amdgpu_ring *ring,
uint64_t addr)
{
unsigned ret;
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_COND_EXE));
amdgpu_ring_write(ring, lower_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, upper_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
amdgpu_ring_write(ring, 1);
ret = ring->wptr & ring->buf_mask;/* this is the offset we need patch later */
amdgpu_ring_write(ring, 0x55aa55aa);/* insert dummy here and patch it later */
/* this is the offset we need patch later */
ret = ring->wptr & ring->buf_mask;
/* insert dummy here and patch it later */
amdgpu_ring_write(ring, 0);
return ret;
}
static void sdma_v5_2_ring_patch_cond_exec(struct amdgpu_ring *ring,
unsigned offset)
{
unsigned cur;
BUG_ON(offset > ring->buf_mask);
BUG_ON(ring->ring[offset] != 0x55aa55aa);
cur = (ring->wptr - 1) & ring->buf_mask;
if (cur > offset)
ring->ring[offset] = cur - offset;
else
ring->ring[offset] = (ring->buf_mask + 1) - offset + cur;
}
/**
* sdma_v5_2_ring_get_rptr - get the current read pointer
*
@ -1722,7 +1710,6 @@ static const struct amdgpu_ring_funcs sdma_v5_2_ring_funcs = {
.emit_reg_wait = sdma_v5_2_ring_emit_reg_wait,
.emit_reg_write_reg_wait = sdma_v5_2_ring_emit_reg_write_reg_wait,
.init_cond_exec = sdma_v5_2_ring_init_cond_exec,
.patch_cond_exec = sdma_v5_2_ring_patch_cond_exec,
.preempt_ib = sdma_v5_2_ring_preempt_ib,
};

View File

@ -80,35 +80,23 @@ static u32 sdma_v6_0_get_reg_offset(struct amdgpu_device *adev, u32 instance, u3
return base + internal_offset;
}
static unsigned sdma_v6_0_ring_init_cond_exec(struct amdgpu_ring *ring)
static unsigned sdma_v6_0_ring_init_cond_exec(struct amdgpu_ring *ring,
uint64_t addr)
{
unsigned ret;
amdgpu_ring_write(ring, SDMA_PKT_COPY_LINEAR_HEADER_OP(SDMA_OP_COND_EXE));
amdgpu_ring_write(ring, lower_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, upper_32_bits(ring->cond_exe_gpu_addr));
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
amdgpu_ring_write(ring, 1);
ret = ring->wptr & ring->buf_mask;/* this is the offset we need patch later */
amdgpu_ring_write(ring, 0x55aa55aa);/* insert dummy here and patch it later */
/* this is the offset we need patch later */
ret = ring->wptr & ring->buf_mask;
/* insert dummy here and patch it later */
amdgpu_ring_write(ring, 0);
return ret;
}
static void sdma_v6_0_ring_patch_cond_exec(struct amdgpu_ring *ring,
unsigned offset)
{
unsigned cur;
BUG_ON(offset > ring->buf_mask);
BUG_ON(ring->ring[offset] != 0x55aa55aa);
cur = (ring->wptr - 1) & ring->buf_mask;
if (cur > offset)
ring->ring[offset] = cur - offset;
else
ring->ring[offset] = (ring->buf_mask + 1) - offset + cur;
}
/**
* sdma_v6_0_ring_get_rptr - get the current read pointer
*
@ -1542,7 +1530,6 @@ static const struct amdgpu_ring_funcs sdma_v6_0_ring_funcs = {
.emit_reg_wait = sdma_v6_0_ring_emit_reg_wait,
.emit_reg_write_reg_wait = sdma_v6_0_ring_emit_reg_write_reg_wait,
.init_cond_exec = sdma_v6_0_ring_init_cond_exec,
.patch_cond_exec = sdma_v6_0_ring_patch_cond_exec,
.preempt_ib = sdma_v6_0_ring_preempt_ib,
};

View File

@ -388,6 +388,7 @@ soc21_asic_reset_method(struct amdgpu_device *adev)
case IP_VERSION(13, 0, 4):
case IP_VERSION(13, 0, 11):
case IP_VERSION(14, 0, 0):
case IP_VERSION(14, 0, 1):
return AMD_RESET_METHOD_MODE2;
default:
if (amdgpu_dpm_is_baco_supported(adev))

View File

@ -40,7 +40,8 @@ enum VPE_CMD_OPCODE {
VPE_CMD_OPCODE_POLL_REGMEM = 0x8,
VPE_CMD_OPCODE_COND_EXE = 0x9,
VPE_CMD_OPCODE_ATOMIC = 0xA,
VPE_CMD_OPCODE_PLANE_FILL = 0xB,
VPE_CMD_OPCODE_PRED_EXE = 0xB,
VPE_CMD_OPCODE_COLLAB_SYNC = 0xC,
VPE_CMD_OPCODE_TIMESTAMP = 0xD
};

View File

@ -33,14 +33,38 @@
#include "vpe/vpe_6_1_0_sh_mask.h"
MODULE_FIRMWARE("amdgpu/vpe_6_1_0.bin");
MODULE_FIRMWARE("amdgpu/vpe_6_1_1.bin");
#define VPE_THREAD1_UCODE_OFFSET 0x8000
#define regVPEC_COLLABORATE_CNTL 0x0013
#define regVPEC_COLLABORATE_CNTL_BASE_IDX 0
#define VPEC_COLLABORATE_CNTL__COLLABORATE_MODE_EN__SHIFT 0x0
#define VPEC_COLLABORATE_CNTL__COLLABORATE_MODE_EN_MASK 0x00000001L
#define regVPEC_COLLABORATE_CFG 0x0014
#define regVPEC_COLLABORATE_CFG_BASE_IDX 0
#define VPEC_COLLABORATE_CFG__MASTER_ID__SHIFT 0x0
#define VPEC_COLLABORATE_CFG__MASTER_EN__SHIFT 0x3
#define VPEC_COLLABORATE_CFG__SLAVE0_ID__SHIFT 0x4
#define VPEC_COLLABORATE_CFG__SLAVE0_EN__SHIFT 0x7
#define VPEC_COLLABORATE_CFG__MASTER_ID_MASK 0x00000007L
#define VPEC_COLLABORATE_CFG__MASTER_EN_MASK 0x00000008L
#define VPEC_COLLABORATE_CFG__SLAVE0_ID_MASK 0x00000070L
#define VPEC_COLLABORATE_CFG__SLAVE0_EN_MASK 0x00000080L
#define regVPEC_CNTL_6_1_1 0x0016
#define regVPEC_CNTL_6_1_1_BASE_IDX 0
#define regVPEC_QUEUE_RESET_REQ_6_1_1 0x002c
#define regVPEC_QUEUE_RESET_REQ_6_1_1_BASE_IDX 0
#define regVPEC_PUB_DUMMY2_6_1_1 0x004c
#define regVPEC_PUB_DUMMY2_6_1_1_BASE_IDX 0
static uint32_t vpe_v6_1_get_reg_offset(struct amdgpu_vpe *vpe, uint32_t inst, uint32_t offset)
{
uint32_t base;
base = vpe->ring.adev->reg_offset[VPE_HWIP][0][0];
base = vpe->ring.adev->reg_offset[VPE_HWIP][inst][0];
return base + offset;
}
@ -48,12 +72,14 @@ static uint32_t vpe_v6_1_get_reg_offset(struct amdgpu_vpe *vpe, uint32_t inst, u
static void vpe_v6_1_halt(struct amdgpu_vpe *vpe, bool halt)
{
struct amdgpu_device *adev = vpe->ring.adev;
uint32_t f32_cntl;
uint32_t i, f32_cntl;
f32_cntl = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_F32_CNTL));
f32_cntl = REG_SET_FIELD(f32_cntl, VPEC_F32_CNTL, HALT, halt ? 1 : 0);
f32_cntl = REG_SET_FIELD(f32_cntl, VPEC_F32_CNTL, TH1_RESET, halt ? 1 : 0);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_F32_CNTL), f32_cntl);
for (i = 0; i < vpe->num_instances; i++) {
f32_cntl = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_F32_CNTL));
f32_cntl = REG_SET_FIELD(f32_cntl, VPEC_F32_CNTL, HALT, halt ? 1 : 0);
f32_cntl = REG_SET_FIELD(f32_cntl, VPEC_F32_CNTL, TH1_RESET, halt ? 1 : 0);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_F32_CNTL), f32_cntl);
}
}
static int vpe_v6_1_irq_init(struct amdgpu_vpe *vpe)
@ -70,20 +96,58 @@ static int vpe_v6_1_irq_init(struct amdgpu_vpe *vpe)
return 0;
}
static void vpe_v6_1_set_collaborate_mode(struct amdgpu_vpe *vpe, bool enable)
{
struct amdgpu_device *adev = vpe->ring.adev;
uint32_t vpe_colla_cntl, vpe_colla_cfg, i;
if (!vpe->collaborate_mode)
return;
for (i = 0; i < vpe->num_instances; i++) {
vpe_colla_cntl = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_COLLABORATE_CNTL));
vpe_colla_cntl = REG_SET_FIELD(vpe_colla_cntl, VPEC_COLLABORATE_CNTL,
COLLABORATE_MODE_EN, enable ? 1 : 0);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_COLLABORATE_CNTL), vpe_colla_cntl);
vpe_colla_cfg = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_COLLABORATE_CFG));
vpe_colla_cfg = REG_SET_FIELD(vpe_colla_cfg, VPEC_COLLABORATE_CFG, MASTER_ID, 0);
vpe_colla_cfg = REG_SET_FIELD(vpe_colla_cfg, VPEC_COLLABORATE_CFG, MASTER_EN, enable ? 1 : 0);
vpe_colla_cfg = REG_SET_FIELD(vpe_colla_cfg, VPEC_COLLABORATE_CFG, SLAVE0_ID, 1);
vpe_colla_cfg = REG_SET_FIELD(vpe_colla_cfg, VPEC_COLLABORATE_CFG, SLAVE0_EN, enable ? 1 : 0);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_COLLABORATE_CFG), vpe_colla_cfg);
}
}
static int vpe_v6_1_load_microcode(struct amdgpu_vpe *vpe)
{
struct amdgpu_device *adev = vpe->ring.adev;
const struct vpe_firmware_header_v1_0 *vpe_hdr;
const __le32 *data;
uint32_t ucode_offset[2], ucode_size[2];
uint32_t i, size_dw;
uint32_t i, j, size_dw;
uint32_t ret;
// disable UMSCH_INT_ENABLE
ret = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL));
ret = REG_SET_FIELD(ret, VPEC_CNTL, UMSCH_INT_ENABLE, 0);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL), ret);
/* disable UMSCH_INT_ENABLE */
for (j = 0; j < vpe->num_instances; j++) {
if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1))
ret = RREG32(vpe_get_reg_offset(vpe, j, regVPEC_CNTL_6_1_1));
else
ret = RREG32(vpe_get_reg_offset(vpe, j, regVPEC_CNTL));
ret = REG_SET_FIELD(ret, VPEC_CNTL, UMSCH_INT_ENABLE, 0);
if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1))
WREG32(vpe_get_reg_offset(vpe, j, regVPEC_CNTL_6_1_1), ret);
else
WREG32(vpe_get_reg_offset(vpe, j, regVPEC_CNTL), ret);
}
/*
* For VPE 6.1.1, still only need to add master's offset, and psp will apply it to slave as well.
* Here use instance 0 as master.
*/
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
uint32_t f32_offset, f32_cntl;
@ -96,8 +160,7 @@ static int vpe_v6_1_load_microcode(struct amdgpu_vpe *vpe)
adev->vpe.cmdbuf_cpu_addr[1] = f32_cntl;
amdgpu_vpe_psp_update_sram(adev);
/* Config DPM */
vpe_v6_1_set_collaborate_mode(vpe, true);
amdgpu_vpe_configure_dpm(vpe);
return 0;
@ -114,25 +177,26 @@ static int vpe_v6_1_load_microcode(struct amdgpu_vpe *vpe)
vpe_v6_1_halt(vpe, true);
for (i = 0; i < 2; i++) {
if (i > 0)
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_UCODE_ADDR), VPE_THREAD1_UCODE_OFFSET);
else
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_UCODE_ADDR), 0);
for (j = 0; j < vpe->num_instances; j++) {
for (i = 0; i < 2; i++) {
if (i > 0)
WREG32(vpe_get_reg_offset(vpe, j, regVPEC_UCODE_ADDR), VPE_THREAD1_UCODE_OFFSET);
else
WREG32(vpe_get_reg_offset(vpe, j, regVPEC_UCODE_ADDR), 0);
data = (const __le32 *)(adev->vpe.fw->data + ucode_offset[i]);
size_dw = ucode_size[i] / sizeof(__le32);
data = (const __le32 *)(adev->vpe.fw->data + ucode_offset[i]);
size_dw = ucode_size[i] / sizeof(__le32);
while (size_dw--) {
if (amdgpu_emu_mode && size_dw % 500 == 0)
msleep(1);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_UCODE_DATA), le32_to_cpup(data++));
while (size_dw--) {
if (amdgpu_emu_mode && size_dw % 500 == 0)
msleep(1);
WREG32(vpe_get_reg_offset(vpe, j, regVPEC_UCODE_DATA), le32_to_cpup(data++));
}
}
}
vpe_v6_1_halt(vpe, false);
/* Config DPM */
vpe_v6_1_set_collaborate_mode(vpe, true);
amdgpu_vpe_configure_dpm(vpe);
return 0;
@ -142,68 +206,68 @@ static int vpe_v6_1_ring_start(struct amdgpu_vpe *vpe)
{
struct amdgpu_ring *ring = &vpe->ring;
struct amdgpu_device *adev = ring->adev;
uint32_t rb_bufsz, rb_cntl;
uint32_t ib_cntl;
uint32_t doorbell, doorbell_offset;
uint32_t rb_bufsz, rb_cntl;
uint32_t ib_cntl, i;
int ret;
rb_bufsz = order_base_2(ring->ring_size / 4);
rb_cntl = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_CNTL));
rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RB_SIZE, rb_bufsz);
rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RB_PRIV, 1);
rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RB_VMID, 0);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_CNTL), rb_cntl);
for (i = 0; i < vpe->num_instances; i++) {
/* Set ring buffer size in dwords */
rb_bufsz = order_base_2(ring->ring_size / 4);
rb_cntl = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_CNTL));
rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RB_SIZE, rb_bufsz);
rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RB_PRIV, 1);
rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RB_VMID, 0);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_CNTL), rb_cntl);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_RPTR), 0);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_RPTR_HI), 0);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_WPTR), 0);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_WPTR_HI), 0);
/* Initialize the ring buffer's read and write pointers */
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_RPTR), 0);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_RPTR_HI), 0);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_WPTR), 0);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_WPTR_HI), 0);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_RPTR_ADDR_LO),
lower_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFC);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_RPTR_ADDR_HI),
upper_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFF);
/* set the wb address whether it's enabled or not */
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_RPTR_ADDR_LO),
lower_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFC);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_RPTR_ADDR_HI),
upper_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFF);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_BASE), ring->gpu_addr >> 8);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_BASE_HI), ring->gpu_addr >> 40);
rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RPTR_WRITEBACK_ENABLE, 1);
ring->wptr = 0;
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_BASE), ring->gpu_addr >> 8);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_BASE_HI), ring->gpu_addr >> 40);
/* before programing wptr to a less value, need set minor_ptr_update first */
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_MINOR_PTR_UPDATE), 1);
ring->wptr = 0;
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_WPTR), lower_32_bits(ring->wptr) << 2);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_WPTR_HI), upper_32_bits(ring->wptr) << 2);
/* before programing wptr to a less value, need set minor_ptr_update first */
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_MINOR_PTR_UPDATE), 1);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_WPTR), lower_32_bits(ring->wptr) << 2);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_WPTR_HI), upper_32_bits(ring->wptr) << 2);
/* set minor_ptr_update to 0 after wptr programed */
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_MINOR_PTR_UPDATE), 0);
/* set minor_ptr_update to 0 after wptr programed */
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_MINOR_PTR_UPDATE), 0);
doorbell_offset = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_DOORBELL_OFFSET));
doorbell_offset = REG_SET_FIELD(doorbell_offset, VPEC_QUEUE0_DOORBELL_OFFSET, OFFSET, ring->doorbell_index + i*4);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_DOORBELL_OFFSET), doorbell_offset);
doorbell = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_DOORBELL));
doorbell_offset = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_DOORBELL_OFFSET));
doorbell = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_DOORBELL));
doorbell = REG_SET_FIELD(doorbell, VPEC_QUEUE0_DOORBELL, ENABLE, ring->use_doorbell ? 1 : 0);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_DOORBELL), doorbell);
doorbell = REG_SET_FIELD(doorbell, VPEC_QUEUE0_DOORBELL, ENABLE, ring->use_doorbell ? 1 : 0);
doorbell_offset = REG_SET_FIELD(doorbell_offset, VPEC_QUEUE0_DOORBELL_OFFSET, OFFSET, ring->doorbell_index);
adev->nbio.funcs->vpe_doorbell_range(adev, i, ring->use_doorbell, ring->doorbell_index + i*4, 4);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_DOORBELL), doorbell);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_DOORBELL_OFFSET), doorbell_offset);
rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RPTR_WRITEBACK_ENABLE, 1);
rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RB_ENABLE, 1);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_CNTL), rb_cntl);
adev->nbio.funcs->vpe_doorbell_range(adev, 0, ring->use_doorbell, ring->doorbell_index, 2);
rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RPTR_WRITEBACK_ENABLE, 1);
rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RB_ENABLE, 1);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_CNTL), rb_cntl);
ib_cntl = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_IB_CNTL));
ib_cntl = REG_SET_FIELD(ib_cntl, VPEC_QUEUE0_IB_CNTL, IB_ENABLE, 1);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_IB_CNTL), ib_cntl);
ring->sched.ready = true;
ib_cntl = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_IB_CNTL));
ib_cntl = REG_SET_FIELD(ib_cntl, VPEC_QUEUE0_IB_CNTL, IB_ENABLE, 1);
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_IB_CNTL), ib_cntl);
}
ret = amdgpu_ring_test_helper(ring);
if (ret) {
ring->sched.ready = false;
if (ret)
return ret;
}
return 0;
}
@ -211,17 +275,30 @@ static int vpe_v6_1_ring_start(struct amdgpu_vpe *vpe)
static int vpe_v_6_1_ring_stop(struct amdgpu_vpe *vpe)
{
struct amdgpu_device *adev = vpe->ring.adev;
uint32_t queue_reset;
uint32_t queue_reset, i;
int ret;
queue_reset = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE_RESET_REQ));
queue_reset = REG_SET_FIELD(queue_reset, VPEC_QUEUE_RESET_REQ, QUEUE0_RESET, 1);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE_RESET_REQ), queue_reset);
for (i = 0; i < vpe->num_instances; i++) {
if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1))
queue_reset = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE_RESET_REQ_6_1_1));
else
queue_reset = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE_RESET_REQ));
ret = SOC15_WAIT_ON_RREG(VPE, 0, regVPEC_QUEUE_RESET_REQ, 0,
VPEC_QUEUE_RESET_REQ__QUEUE0_RESET_MASK);
if (ret)
dev_err(adev->dev, "VPE queue reset failed\n");
queue_reset = REG_SET_FIELD(queue_reset, VPEC_QUEUE_RESET_REQ, QUEUE0_RESET, 1);
if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1)) {
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE_RESET_REQ_6_1_1), queue_reset);
ret = SOC15_WAIT_ON_RREG(VPE, i, regVPEC_QUEUE_RESET_REQ_6_1_1, 0,
VPEC_QUEUE_RESET_REQ__QUEUE0_RESET_MASK);
} else {
WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE_RESET_REQ), queue_reset);
ret = SOC15_WAIT_ON_RREG(VPE, i, regVPEC_QUEUE_RESET_REQ, 0,
VPEC_QUEUE_RESET_REQ__QUEUE0_RESET_MASK);
}
if (ret)
dev_err(adev->dev, "VPE queue reset failed\n");
}
vpe->ring.sched.ready = false;
@ -236,10 +313,18 @@ static int vpe_v6_1_set_trap_irq_state(struct amdgpu_device *adev,
struct amdgpu_vpe *vpe = &adev->vpe;
uint32_t vpe_cntl;
vpe_cntl = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL));
if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1))
vpe_cntl = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL_6_1_1));
else
vpe_cntl = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL));
vpe_cntl = REG_SET_FIELD(vpe_cntl, VPEC_CNTL, TRAP_ENABLE,
state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL), vpe_cntl);
if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1))
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL_6_1_1), vpe_cntl);
else
WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL), vpe_cntl);
return 0;
}
@ -264,13 +349,19 @@ static int vpe_v6_1_process_trap_irq(struct amdgpu_device *adev,
static int vpe_v6_1_set_regs(struct amdgpu_vpe *vpe)
{
struct amdgpu_device *adev = container_of(vpe, struct amdgpu_device, vpe);
vpe->regs.queue0_rb_rptr_lo = regVPEC_QUEUE0_RB_RPTR;
vpe->regs.queue0_rb_rptr_hi = regVPEC_QUEUE0_RB_RPTR_HI;
vpe->regs.queue0_rb_wptr_lo = regVPEC_QUEUE0_RB_WPTR;
vpe->regs.queue0_rb_wptr_hi = regVPEC_QUEUE0_RB_WPTR_HI;
vpe->regs.queue0_preempt = regVPEC_QUEUE0_PREEMPT;
vpe->regs.dpm_enable = regVPEC_PUB_DUMMY2;
if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1))
vpe->regs.dpm_enable = regVPEC_PUB_DUMMY2_6_1_1;
else
vpe->regs.dpm_enable = regVPEC_PUB_DUMMY2;
vpe->regs.dpm_pratio = regVPEC_QUEUE6_DUMMY4;
vpe->regs.dpm_request_interval = regVPEC_QUEUE5_DUMMY3;
vpe->regs.dpm_decision_threshold = regVPEC_QUEUE5_DUMMY4;

View File

@ -678,7 +678,7 @@ static const uint32_t cwsr_trap_gfx9_hex[] = {
};
static const uint32_t cwsr_trap_nv1x_hex[] = {
0xbf820001, 0xbf8201f5,
0xbf820001, 0xbf820394,
0xb0804004, 0xb978f802,
0x8a78ff78, 0x00020006,
0xb97bf803, 0x876eff78,
@ -769,13 +769,90 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
0x877c817c, 0xbf06817c,
0xbf850002, 0xbeff0380,
0xbf820002, 0xbeff03c1,
0xbf82000b, 0xbef603ff,
0x01000000, 0xe0704000,
0x705d0000, 0xe0704080,
0x705d0100, 0xe0704100,
0x705d0200, 0xe0704180,
0x705d0300, 0xbf82000a,
0xbef603ff, 0x01000000,
0xbf820058, 0xbef603ff,
0x01000000, 0xb97af803,
0x8a7a7aff, 0x10000000,
0xbf850049, 0xbe840380,
0xd7600000, 0x00000900,
0x80048104, 0xd7600001,
0x00000900, 0x80048104,
0xd7600002, 0x00000900,
0x80048104, 0xd7600003,
0x00000900, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06a004,
0xbf84ffef, 0xbe840380,
0xd7600000, 0x00000901,
0x80048104, 0xd7600001,
0x00000901, 0x80048104,
0xd7600002, 0x00000901,
0x80048104, 0xd7600003,
0x00000901, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06a004,
0xbf84ffef, 0xbe840380,
0xd7600000, 0x00000902,
0x80048104, 0xd7600001,
0x00000902, 0x80048104,
0xd7600002, 0x00000902,
0x80048104, 0xd7600003,
0x00000902, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06a004,
0xbf84ffef, 0xbe840380,
0xd7600000, 0x00000903,
0x80048104, 0xd7600001,
0x00000903, 0x80048104,
0xd7600002, 0x00000903,
0x80048104, 0xd7600003,
0x00000903, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06a004,
0xbf84ffef, 0xbf820060,
0xe0704000, 0x705d0000,
0xe0704080, 0x705d0100,
0xe0704100, 0x705d0200,
0xe0704180, 0x705d0300,
0xbf820057, 0xbef603ff,
0x01000000, 0xb97af803,
0x8a7a7aff, 0x10000000,
0xbf850049, 0xbe840380,
0xd7600000, 0x00000900,
0x80048104, 0xd7600001,
0x00000900, 0x80048104,
0xd7600002, 0x00000900,
0x80048104, 0xd7600003,
0x00000900, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06c004,
0xbf84ffef, 0xbe840380,
0xd7600000, 0x00000901,
0x80048104, 0xd7600001,
0x00000901, 0x80048104,
0xd7600002, 0x00000901,
0x80048104, 0xd7600003,
0x00000901, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06c004,
0xbf84ffef, 0xbe840380,
0xd7600000, 0x00000902,
0x80048104, 0xd7600001,
0x00000902, 0x80048104,
0xd7600002, 0x00000902,
0x80048104, 0xd7600003,
0x00000902, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06c004,
0xbf84ffef, 0xbe840380,
0xd7600000, 0x00000903,
0x80048104, 0xd7600001,
0x00000903, 0x80048104,
0xd7600002, 0x00000903,
0x80048104, 0xd7600003,
0x00000903, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06c004,
0xbf84ffef, 0xbf820008,
0xe0704000, 0x705d0000,
0xe0704100, 0x705d0100,
0xe0704200, 0x705d0200,
@ -855,9 +932,9 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
0xbf850002, 0xbeff0380,
0xbf820001, 0xbeff03c1,
0xb97b4306, 0x877bc17b,
0xbf840044, 0xbf8a0000,
0xbf840086, 0xbf8a0000,
0x877aff6d, 0x80000000,
0xbf840040, 0x8f7b867b,
0xbf840082, 0x8f7b867b,
0x8f7b827b, 0xbef6037b,
0xb9703a05, 0x80708170,
0xbf0d9973, 0xbf850002,
@ -871,16 +948,49 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
0xd7660000, 0x000200c1,
0x16000084, 0x907c9973,
0x877c817c, 0xbf06817c,
0xbefc0380, 0xbf850012,
0xbe8303ff, 0x00000080,
0xbefc0380, 0xbf850033,
0xb97af803, 0x8a7a7aff,
0x10000000, 0xbf85001d,
0xd8d80000, 0x01000000,
0xbf8c0000, 0xbe840380,
0xd7600000, 0x00000901,
0x80048104, 0xd7600001,
0x00000901, 0x80048104,
0xd7600002, 0x00000901,
0x80048104, 0xd7600003,
0x00000901, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06a004,
0xbf84ffef, 0x807cff7c,
0x00000080, 0xd5250000,
0x0001ff00, 0x00000080,
0xbf0a7b7c, 0xbf85ffe4,
0xbf820044, 0xbe8303ff,
0x00000080, 0xbf800000,
0xbf800000, 0xbf800000,
0xbf800000, 0xd8d80000,
0xd8d80000, 0x01000000,
0xbf8c0000, 0xe0704000,
0x705d0100, 0x807c037c,
0x80700370, 0xd5250000,
0x0001ff00, 0x00000080,
0xbf0a7b7c, 0xbf85fff4,
0xbf820032, 0xb97af803,
0x8a7a7aff, 0x10000000,
0xbf85001d, 0xd8d80000,
0x01000000, 0xbf8c0000,
0xe0704000, 0x705d0100,
0x807c037c, 0x80700370,
0xbe840380, 0xd7600000,
0x00000901, 0x80048104,
0xd7600001, 0x00000901,
0x80048104, 0xd7600002,
0x00000901, 0x80048104,
0xd7600003, 0x00000901,
0x80048104, 0xf469003a,
0xe0000000, 0x80709070,
0xbf06c004, 0xbf84ffef,
0x807cff7c, 0x00000100,
0xd5250000, 0x0001ff00,
0x00000080, 0xbf0a7b7c,
0xbf85fff4, 0xbf820011,
0x00000100, 0xbf0a7b7c,
0xbf85ffe4, 0xbf820011,
0xbe8303ff, 0x00000100,
0xbf800000, 0xbf800000,
0xbf800000, 0xd8d80000,
@ -898,10 +1008,52 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
0xbeff03c1, 0xb97b3a05,
0x807b817b, 0x8f7b827b,
0x907c9973, 0x877c817c,
0xbf06817c, 0xbf850017,
0xbf06817c, 0xbf85006b,
0xbef603ff, 0x01000000,
0xbefc0384, 0xbf0a7b7c,
0xbf840037, 0x7e008700,
0xbf8400fa, 0xb97af803,
0x8a7a7aff, 0x10000000,
0xbf850050, 0x7e008700,
0x7e028701, 0x7e048702,
0x7e068703, 0xbe840380,
0xd7600000, 0x00000900,
0x80048104, 0xd7600001,
0x00000900, 0x80048104,
0xd7600002, 0x00000900,
0x80048104, 0xd7600003,
0x00000900, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06a004,
0xbf84ffef, 0xbe840380,
0xd7600000, 0x00000901,
0x80048104, 0xd7600001,
0x00000901, 0x80048104,
0xd7600002, 0x00000901,
0x80048104, 0xd7600003,
0x00000901, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06a004,
0xbf84ffef, 0xbe840380,
0xd7600000, 0x00000902,
0x80048104, 0xd7600001,
0x00000902, 0x80048104,
0xd7600002, 0x00000902,
0x80048104, 0xd7600003,
0x00000902, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06a004,
0xbf84ffef, 0xbe840380,
0xd7600000, 0x00000903,
0x80048104, 0xd7600001,
0x00000903, 0x80048104,
0xd7600002, 0x00000903,
0x80048104, 0xd7600003,
0x00000903, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06a004,
0xbf84ffef, 0x807c847c,
0xbf0a7b7c, 0xbf85ffb1,
0xbf8200a6, 0x7e008700,
0x7e028701, 0x7e048702,
0x7e068703, 0xe0704000,
0x705d0000, 0xe0704080,
@ -910,9 +1062,51 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
0x705d0300, 0x807c847c,
0x8070ff70, 0x00000200,
0xbf0a7b7c, 0xbf85ffef,
0xbf820025, 0xbef603ff,
0xbf820094, 0xbef603ff,
0x01000000, 0xbefc0384,
0xbf0a7b7c, 0xbf840011,
0xbf0a7b7c, 0xbf840065,
0xb97af803, 0x8a7a7aff,
0x10000000, 0xbf850050,
0x7e008700, 0x7e028701,
0x7e048702, 0x7e068703,
0xbe840380, 0xd7600000,
0x00000900, 0x80048104,
0xd7600001, 0x00000900,
0x80048104, 0xd7600002,
0x00000900, 0x80048104,
0xd7600003, 0x00000900,
0x80048104, 0xf469003a,
0xe0000000, 0x80709070,
0xbf06c004, 0xbf84ffef,
0xbe840380, 0xd7600000,
0x00000901, 0x80048104,
0xd7600001, 0x00000901,
0x80048104, 0xd7600002,
0x00000901, 0x80048104,
0xd7600003, 0x00000901,
0x80048104, 0xf469003a,
0xe0000000, 0x80709070,
0xbf06c004, 0xbf84ffef,
0xbe840380, 0xd7600000,
0x00000902, 0x80048104,
0xd7600001, 0x00000902,
0x80048104, 0xd7600002,
0x00000902, 0x80048104,
0xd7600003, 0x00000902,
0x80048104, 0xf469003a,
0xe0000000, 0x80709070,
0xbf06c004, 0xbf84ffef,
0xbe840380, 0xd7600000,
0x00000903, 0x80048104,
0xd7600001, 0x00000903,
0x80048104, 0xd7600002,
0x00000903, 0x80048104,
0xd7600003, 0x00000903,
0x80048104, 0xf469003a,
0xe0000000, 0x80709070,
0xbf06c004, 0xbf84ffef,
0x807c847c, 0xbf0a7b7c,
0xbf85ffb1, 0xbf82003b,
0x7e008700, 0x7e028701,
0x7e048702, 0x7e068703,
0xe0704000, 0x705d0000,
@ -922,179 +1116,192 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
0x807c847c, 0x8070ff70,
0x00000400, 0xbf0a7b7c,
0xbf85ffef, 0xb97b1e06,
0x877bc17b, 0xbf84000c,
0x877bc17b, 0xbf840027,
0x8f7b837b, 0x807b7c7b,
0xbefe03c1, 0xbeff0380,
0x7e008700, 0xe0704000,
0x705d0000, 0x807c817c,
0x8070ff70, 0x00000080,
0xbf0a7b7c, 0xbf85fff8,
0xbf820144, 0xbef4037e,
0x8775ff7f, 0x0000ffff,
0x8875ff75, 0x00040000,
0xbef60380, 0xbef703ff,
0x10807fac, 0xb97202dc,
0x8f729972, 0x876eff7f,
0x04000000, 0xbf840034,
0xbefe03c1, 0x907c9972,
0x877c817c, 0xbf06817c,
0xbf850002, 0xbeff0380,
0xbf820001, 0xbeff03c1,
0xb96f4306, 0x876fc16f,
0xbf840029, 0x8f6f866f,
0x8f6f826f, 0xbef6036f,
0xb9783a05, 0x80788178,
0xbf0d9972, 0xbf850002,
0x8f788978, 0xbf820001,
0x8f788a78, 0xb96e1e06,
0x8f6e8a6e, 0x80786e78,
0x8078ff78, 0x00000200,
0x8078ff78, 0x00000080,
0xbef603ff, 0x01000000,
0x907c9972, 0x877c817c,
0xbf06817c, 0xbefc0380,
0xbf850009, 0xe0310000,
0x781d0000, 0x807cff7c,
0x00000080, 0x8078ff78,
0x00000080, 0xbf0a6f7c,
0xbf85fff8, 0xbf820008,
0xe0310000, 0x781d0000,
0x807cff7c, 0x00000100,
0x8078ff78, 0x00000100,
0xbf0a6f7c, 0xbf85fff8,
0xbef80380, 0xbefe03c1,
0xb97af803, 0x8a7a7aff,
0x10000000, 0xbf850017,
0x7e008700, 0xbe840380,
0xd7600000, 0x00000900,
0x80048104, 0xd7600001,
0x00000900, 0x80048104,
0xd7600002, 0x00000900,
0x80048104, 0xd7600003,
0x00000900, 0x80048104,
0xf469003a, 0xe0000000,
0x80709070, 0xbf06c004,
0xbf84ffef, 0x807c817c,
0xbf0a7b7c, 0xbf85ffea,
0xbf820008, 0x7e008700,
0xe0704000, 0x705d0000,
0x807c817c, 0x8070ff70,
0x00000080, 0xbf0a7b7c,
0xbf85fff8, 0xbf820144,
0xbef4037e, 0x8775ff7f,
0x0000ffff, 0x8875ff75,
0x00040000, 0xbef60380,
0xbef703ff, 0x10807fac,
0xb97202dc, 0x8f729972,
0x876eff7f, 0x04000000,
0xbf840034, 0xbefe03c1,
0x907c9972, 0x877c817c,
0xbf06817c, 0xbf850002,
0xbeff0380, 0xbf820001,
0xbeff03c1, 0xb96f3a05,
0x806f816f, 0x8f6f826f,
0x907c9972, 0x877c817c,
0xbf06817c, 0xbf850024,
0xbef603ff, 0x01000000,
0xbeee0378, 0x8078ff78,
0x00000200, 0xbefc0384,
0xbf0a6f7c, 0xbf840050,
0xe0304000, 0x785d0000,
0xe0304080, 0x785d0100,
0xe0304100, 0x785d0200,
0xe0304180, 0x785d0300,
0xbf8c3f70, 0x7e008500,
0x7e028501, 0x7e048502,
0x7e068503, 0x807c847c,
0x8078ff78, 0x00000200,
0xbf0a6f7c, 0xbf85ffee,
0xe0304000, 0x6e5d0000,
0xe0304080, 0x6e5d0100,
0xe0304100, 0x6e5d0200,
0xe0304180, 0x6e5d0300,
0xbf8c3f70, 0xbf820034,
0xbef603ff, 0x01000000,
0xbeee0378, 0x8078ff78,
0x00000400, 0xbefc0384,
0xbf0a6f7c, 0xbf840012,
0xe0304000, 0x785d0000,
0xe0304100, 0x785d0100,
0xe0304200, 0x785d0200,
0xe0304300, 0x785d0300,
0xbf8c3f70, 0x7e008500,
0x7e028501, 0x7e048502,
0x7e068503, 0x807c847c,
0x8078ff78, 0x00000400,
0xbf0a6f7c, 0xbf85ffee,
0xb96f1e06, 0x876fc16f,
0xbf84000e, 0x8f6f836f,
0x806f7c6f, 0xbefe03c1,
0xbeff0380, 0xe0304000,
0x785d0000, 0xbf8c3f70,
0x7e008500, 0x807c817c,
0x8078ff78, 0x00000080,
0xbf0a6f7c, 0xbf85fff7,
0xbeff03c1, 0xe0304000,
0x6e5d0000, 0xe0304100,
0x6e5d0100, 0xe0304200,
0x6e5d0200, 0xe0304300,
0x6e5d0300, 0xbf8c3f70,
0xb9783a05, 0x80788178,
0xbf0d9972, 0xbf850002,
0x8f788978, 0xbf820001,
0x8f788a78, 0xb96e1e06,
0x8f6e8a6e, 0x80786e78,
0x8078ff78, 0x00000200,
0x80f8ff78, 0x00000050,
0xbef603ff, 0x01000000,
0xbefc03ff, 0x0000006c,
0x80f89078, 0xf429003a,
0xf0000000, 0xbf8cc07f,
0x80fc847c, 0xbf800000,
0xbe803100, 0xbe823102,
0x80f8a078, 0xf42d003a,
0xf0000000, 0xbf8cc07f,
0x80fc887c, 0xbf800000,
0xbe803100, 0xbe823102,
0xbe843104, 0xbe863106,
0x80f8c078, 0xf431003a,
0xf0000000, 0xbf8cc07f,
0x80fc907c, 0xbf800000,
0xbe803100, 0xbe823102,
0xbe843104, 0xbe863106,
0xbe883108, 0xbe8a310a,
0xbe8c310c, 0xbe8e310e,
0xbf06807c, 0xbf84fff0,
0xba80f801, 0x00000000,
0xbf8a0000, 0xb9783a05,
0xbeff03c1, 0xb96f4306,
0x876fc16f, 0xbf840029,
0x8f6f866f, 0x8f6f826f,
0xbef6036f, 0xb9783a05,
0x80788178, 0xbf0d9972,
0xbf850002, 0x8f788978,
0xbf820001, 0x8f788a78,
0xb96e1e06, 0x8f6e8a6e,
0x80786e78, 0x8078ff78,
0x00000200, 0xbef603ff,
0x01000000, 0xf4211bfa,
0x00000200, 0x8078ff78,
0x00000080, 0xbef603ff,
0x01000000, 0x907c9972,
0x877c817c, 0xbf06817c,
0xbefc0380, 0xbf850009,
0xe0310000, 0x781d0000,
0x807cff7c, 0x00000080,
0x8078ff78, 0x00000080,
0xbf0a6f7c, 0xbf85fff8,
0xbf820008, 0xe0310000,
0x781d0000, 0x807cff7c,
0x00000100, 0x8078ff78,
0x00000100, 0xbf0a6f7c,
0xbf85fff8, 0xbef80380,
0xbefe03c1, 0x907c9972,
0x877c817c, 0xbf06817c,
0xbf850002, 0xbeff0380,
0xbf820001, 0xbeff03c1,
0xb96f3a05, 0x806f816f,
0x8f6f826f, 0x907c9972,
0x877c817c, 0xbf06817c,
0xbf850024, 0xbef603ff,
0x01000000, 0xbeee0378,
0x8078ff78, 0x00000200,
0xbefc0384, 0xbf0a6f7c,
0xbf840050, 0xe0304000,
0x785d0000, 0xe0304080,
0x785d0100, 0xe0304100,
0x785d0200, 0xe0304180,
0x785d0300, 0xbf8c3f70,
0x7e008500, 0x7e028501,
0x7e048502, 0x7e068503,
0x807c847c, 0x8078ff78,
0x00000200, 0xbf0a6f7c,
0xbf85ffee, 0xe0304000,
0x6e5d0000, 0xe0304080,
0x6e5d0100, 0xe0304100,
0x6e5d0200, 0xe0304180,
0x6e5d0300, 0xbf8c3f70,
0xbf820034, 0xbef603ff,
0x01000000, 0xbeee0378,
0x8078ff78, 0x00000400,
0xbefc0384, 0xbf0a6f7c,
0xbf840012, 0xe0304000,
0x785d0000, 0xe0304100,
0x785d0100, 0xe0304200,
0x785d0200, 0xe0304300,
0x785d0300, 0xbf8c3f70,
0x7e008500, 0x7e028501,
0x7e048502, 0x7e068503,
0x807c847c, 0x8078ff78,
0x00000400, 0xbf0a6f7c,
0xbf85ffee, 0xb96f1e06,
0x876fc16f, 0xbf84000e,
0x8f6f836f, 0x806f7c6f,
0xbefe03c1, 0xbeff0380,
0xe0304000, 0x785d0000,
0xbf8c3f70, 0x7e008500,
0x807c817c, 0x8078ff78,
0x00000080, 0xbf0a6f7c,
0xbf85fff7, 0xbeff03c1,
0xe0304000, 0x6e5d0000,
0xe0304100, 0x6e5d0100,
0xe0304200, 0x6e5d0200,
0xe0304300, 0x6e5d0300,
0xbf8c3f70, 0xb9783a05,
0x80788178, 0xbf0d9972,
0xbf850002, 0x8f788978,
0xbf820001, 0x8f788a78,
0xb96e1e06, 0x8f6e8a6e,
0x80786e78, 0x8078ff78,
0x00000200, 0x80f8ff78,
0x00000050, 0xbef603ff,
0x01000000, 0xbefc03ff,
0x0000006c, 0x80f89078,
0xf429003a, 0xf0000000,
0xbf8cc07f, 0x80fc847c,
0xbf800000, 0xbe803100,
0xbe823102, 0x80f8a078,
0xf42d003a, 0xf0000000,
0xbf8cc07f, 0x80fc887c,
0xbf800000, 0xbe803100,
0xbe823102, 0xbe843104,
0xbe863106, 0x80f8c078,
0xf431003a, 0xf0000000,
0xbf8cc07f, 0x80fc907c,
0xbf800000, 0xbe803100,
0xbe823102, 0xbe843104,
0xbe863106, 0xbe883108,
0xbe8a310a, 0xbe8c310c,
0xbe8e310e, 0xbf06807c,
0xbf84fff0, 0xba80f801,
0x00000000, 0xbf8a0000,
0xb9783a05, 0x80788178,
0xbf0d9972, 0xbf850002,
0x8f788978, 0xbf820001,
0x8f788a78, 0xb96e1e06,
0x8f6e8a6e, 0x80786e78,
0x8078ff78, 0x00000200,
0xbef603ff, 0x01000000,
0xf4211bfa, 0xf0000000,
0x80788478, 0xf4211b3a,
0xf0000000, 0x80788478,
0xf4211b3a, 0xf0000000,
0x80788478, 0xf4211b7a,
0xf4211b7a, 0xf0000000,
0x80788478, 0xf4211c3a,
0xf0000000, 0x80788478,
0xf4211c3a, 0xf0000000,
0x80788478, 0xf4211c7a,
0xf4211c7a, 0xf0000000,
0x80788478, 0xf4211eba,
0xf0000000, 0x80788478,
0xf4211eba, 0xf0000000,
0x80788478, 0xf4211efa,
0xf4211efa, 0xf0000000,
0x80788478, 0xf4211e7a,
0xf0000000, 0x80788478,
0xf4211e7a, 0xf0000000,
0x80788478, 0xf4211cfa,
0xf4211cfa, 0xf0000000,
0x80788478, 0xf4211bba,
0xf0000000, 0x80788478,
0xbf8cc07f, 0xb9eef814,
0xf4211bba, 0xf0000000,
0x80788478, 0xbf8cc07f,
0xb9eef814, 0xf4211bba,
0xf0000000, 0x80788478,
0xbf8cc07f, 0xb9eef815,
0xbefc036f, 0xbefe0370,
0xbeff0371, 0x876f7bff,
0x000003ff, 0xb9ef4803,
0xb9f9f816, 0x876f7bff,
0xfffff800, 0x906f8b6f,
0xb9efa2c3, 0xb9f3f801,
0xb96e3a05, 0x806e816e,
0xbf0d9972, 0xbf850002,
0x8f6e896e, 0xbf820001,
0x8f6e8a6e, 0xb96f1e06,
0x8f6f8a6f, 0x806e6f6e,
0x806eff6e, 0x00000200,
0x806e746e, 0x826f8075,
0x876fff6f, 0x0000ffff,
0xf4091c37, 0xfa000050,
0xf4091d37, 0xfa000060,
0xf4011e77, 0xfa000074,
0xbf8cc07f, 0x906e8977,
0x876fff6e, 0x003f8000,
0x906e8677, 0x876eff6e,
0x02000000, 0x886e6f6e,
0xb9eef807, 0x876dff6d,
0x0000ffff, 0x87fe7e7e,
0x87ea6a6a, 0xb9faf802,
0xbe80226c, 0xbf9b0000,
0xb9eef815, 0xbefc036f,
0xbefe0370, 0xbeff0371,
0x876f7bff, 0x000003ff,
0xb9ef4803, 0xb9f9f816,
0x876f7bff, 0xfffff800,
0x906f8b6f, 0xb9efa2c3,
0xb9f3f801, 0xb96e3a05,
0x806e816e, 0xbf0d9972,
0xbf850002, 0x8f6e896e,
0xbf820001, 0x8f6e8a6e,
0xb96f1e06, 0x8f6f8a6f,
0x806e6f6e, 0x806eff6e,
0x00000200, 0x806e746e,
0x826f8075, 0x876fff6f,
0x0000ffff, 0xf4091c37,
0xfa000050, 0xf4091d37,
0xfa000060, 0xf4011e77,
0xfa000074, 0xbf8cc07f,
0x906e8977, 0x876fff6e,
0x003f8000, 0x906e8677,
0x876eff6e, 0x02000000,
0x886e6f6e, 0xb9eef807,
0x876dff6d, 0x0000ffff,
0x87fe7e7e, 0x87ea6a6a,
0xb9faf802, 0xbe80226c,
0xbf9b0000, 0xbf9f0000,
0xbf9f0000, 0xbf9f0000,
0xbf9f0000, 0xbf9f0000,
0xbf9f0000, 0x00000000,
};
static const uint32_t cwsr_trap_arcturus_hex[] = {

View File

@ -44,6 +44,7 @@
#define HAVE_SENDMSG_RTN (ASIC_FAMILY >= CHIP_PLUM_BONITO)
#define HAVE_BUFFER_LDS_LOAD (ASIC_FAMILY < CHIP_PLUM_BONITO)
#define SW_SA_TRAP (ASIC_FAMILY >= CHIP_PLUM_BONITO)
#define SAVE_AFTER_XNACK_ERROR (HAVE_XNACK && !NO_SQC_STORE) // workaround for TCP store failure after XNACK error when ALLOW_REPLAY=0, for debugger
var SINGLE_STEP_MISSED_WORKAROUND = 1 //workaround for lost MODE.DEBUG_EN exception when SAVECTX raised
@ -86,6 +87,7 @@ var SQ_WAVE_TRAPSTS_WAVE_START_MASK = 0x20000
var SQ_WAVE_TRAPSTS_WAVE_END_MASK = 0x40000
var SQ_WAVE_TRAPSTS_TRAP_AFTER_INST_MASK = 0x100000
#endif
var SQ_WAVE_TRAPSTS_XNACK_ERROR_MASK = 0x10000000
var SQ_WAVE_MODE_EXCP_EN_SHIFT = 12
var SQ_WAVE_MODE_EXCP_EN_ADDR_WATCH_SHIFT = 19
@ -475,6 +477,16 @@ L_SAVE_4VGPR_WAVE32:
// VGPR Allocated in 4-GPR granularity
#if SAVE_AFTER_XNACK_ERROR
check_if_tcp_store_ok()
s_cbranch_scc1 L_SAVE_FIRST_VGPRS32_WITH_TCP
write_vgprs_to_mem_with_sqc_w32(v0, 4, s_save_buf_rsrc0, s_save_mem_offset)
s_branch L_SAVE_HWREG
L_SAVE_FIRST_VGPRS32_WITH_TCP:
#endif
#if !NO_SQC_STORE
buffer_store_dword v0, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1
#endif
@ -488,6 +500,16 @@ L_SAVE_4VGPR_WAVE64:
// VGPR Allocated in 4-GPR granularity
#if SAVE_AFTER_XNACK_ERROR
check_if_tcp_store_ok()
s_cbranch_scc1 L_SAVE_FIRST_VGPRS64_WITH_TCP
write_vgprs_to_mem_with_sqc_w64(v0, 4, s_save_buf_rsrc0, s_save_mem_offset)
s_branch L_SAVE_HWREG
L_SAVE_FIRST_VGPRS64_WITH_TCP:
#endif
#if !NO_SQC_STORE
buffer_store_dword v0, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1
#endif
@ -660,6 +682,26 @@ L_SAVE_LDS_NORMAL:
s_cbranch_scc1 L_SAVE_LDS_W64
L_SAVE_LDS_W32:
#if SAVE_AFTER_XNACK_ERROR
check_if_tcp_store_ok()
s_cbranch_scc1 L_SAVE_LDS_WITH_TCP_W32
L_SAVE_LDS_LOOP_SQC_W32:
ds_read_b32 v1, v0
s_waitcnt 0
write_vgprs_to_mem_with_sqc_w32(v1, 1, s_save_buf_rsrc0, s_save_mem_offset)
s_add_u32 m0, m0, 128 //every buffer_store_lds does 128 bytes
v_add_nc_u32 v0, v0, 128 //mem offset increased by 128 bytes
s_cmp_lt_u32 m0, s_save_alloc_size //scc=(m0 < s_save_alloc_size) ? 1 : 0
s_cbranch_scc1 L_SAVE_LDS_LOOP_SQC_W32 //LDS save is complete?
s_branch L_SAVE_LDS_DONE
L_SAVE_LDS_WITH_TCP_W32:
#endif
s_mov_b32 s3, 128
s_nop 0
s_nop 0
@ -669,7 +711,7 @@ L_SAVE_LDS_LOOP_W32:
s_waitcnt 0
buffer_store_dword v1, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1
s_add_u32 m0, m0, s3 //every buffer_store_lds does 256 bytes
s_add_u32 m0, m0, s3 //every buffer_store_lds does 128 bytes
s_add_u32 s_save_mem_offset, s_save_mem_offset, s3
v_add_nc_u32 v0, v0, 128 //mem offset increased by 128 bytes
s_cmp_lt_u32 m0, s_save_alloc_size //scc=(m0 < s_save_alloc_size) ? 1 : 0
@ -678,6 +720,26 @@ L_SAVE_LDS_LOOP_W32:
s_branch L_SAVE_LDS_DONE
L_SAVE_LDS_W64:
#if SAVE_AFTER_XNACK_ERROR
check_if_tcp_store_ok()
s_cbranch_scc1 L_SAVE_LDS_WITH_TCP_W64
L_SAVE_LDS_LOOP_SQC_W64:
ds_read_b32 v1, v0
s_waitcnt 0
write_vgprs_to_mem_with_sqc_w64(v1, 1, s_save_buf_rsrc0, s_save_mem_offset)
s_add_u32 m0, m0, 256 //every buffer_store_lds does 256 bytes
v_add_nc_u32 v0, v0, 256 //mem offset increased by 256 bytes
s_cmp_lt_u32 m0, s_save_alloc_size //scc=(m0 < s_save_alloc_size) ? 1 : 0
s_cbranch_scc1 L_SAVE_LDS_LOOP_SQC_W64 //LDS save is complete?
s_branch L_SAVE_LDS_DONE
L_SAVE_LDS_WITH_TCP_W64:
#endif
s_mov_b32 s3, 256
s_nop 0
s_nop 0
@ -727,6 +789,25 @@ L_SAVE_VGPR_NORMAL:
s_cmp_lt_u32 m0, s_save_alloc_size
s_cbranch_scc0 L_SAVE_VGPR_END
#if SAVE_AFTER_XNACK_ERROR
check_if_tcp_store_ok()
s_cbranch_scc1 L_SAVE_VGPR_W32_LOOP
L_SAVE_VGPR_LOOP_SQC_W32:
v_movrels_b32 v0, v0 //v0 = v[0+m0]
v_movrels_b32 v1, v1 //v1 = v[1+m0]
v_movrels_b32 v2, v2 //v2 = v[2+m0]
v_movrels_b32 v3, v3 //v3 = v[3+m0]
write_vgprs_to_mem_with_sqc_w32(v0, 4, s_save_buf_rsrc0, s_save_mem_offset)
s_add_u32 m0, m0, 4
s_cmp_lt_u32 m0, s_save_alloc_size
s_cbranch_scc1 L_SAVE_VGPR_LOOP_SQC_W32
s_branch L_SAVE_VGPR_END
#endif
L_SAVE_VGPR_W32_LOOP:
v_movrels_b32 v0, v0 //v0 = v[0+m0]
v_movrels_b32 v1, v1 //v1 = v[1+m0]
@ -753,6 +834,25 @@ L_SAVE_VGPR_WAVE64:
s_cmp_lt_u32 m0, s_save_alloc_size
s_cbranch_scc0 L_SAVE_SHARED_VGPR
#if SAVE_AFTER_XNACK_ERROR
check_if_tcp_store_ok()
s_cbranch_scc1 L_SAVE_VGPR_W64_LOOP
L_SAVE_VGPR_LOOP_SQC_W64:
v_movrels_b32 v0, v0 //v0 = v[0+m0]
v_movrels_b32 v1, v1 //v1 = v[1+m0]
v_movrels_b32 v2, v2 //v2 = v[2+m0]
v_movrels_b32 v3, v3 //v3 = v[3+m0]
write_vgprs_to_mem_with_sqc_w64(v0, 4, s_save_buf_rsrc0, s_save_mem_offset)
s_add_u32 m0, m0, 4
s_cmp_lt_u32 m0, s_save_alloc_size
s_cbranch_scc1 L_SAVE_VGPR_LOOP_SQC_W64
s_branch L_SAVE_VGPR_END
#endif
L_SAVE_VGPR_W64_LOOP:
v_movrels_b32 v0, v0 //v0 = v[0+m0]
v_movrels_b32 v1, v1 //v1 = v[1+m0]
@ -780,6 +880,23 @@ L_SAVE_SHARED_VGPR:
s_add_u32 s_save_alloc_size, s_save_alloc_size, m0
s_mov_b32 exec_lo, 0xFFFFFFFF
s_mov_b32 exec_hi, 0x00000000
#if SAVE_AFTER_XNACK_ERROR
check_if_tcp_store_ok()
s_cbranch_scc1 L_SAVE_SHARED_VGPR_WAVE64_LOOP
L_SAVE_SHARED_VGPR_WAVE64_LOOP_SQC:
v_movrels_b32 v0, v0
write_vgprs_to_mem_with_sqc_w64(v0, 1, s_save_buf_rsrc0, s_save_mem_offset)
s_add_u32 m0, m0, 1
s_cmp_lt_u32 m0, s_save_alloc_size
s_cbranch_scc1 L_SAVE_SHARED_VGPR_WAVE64_LOOP_SQC
s_branch L_SAVE_VGPR_END
#endif
L_SAVE_SHARED_VGPR_WAVE64_LOOP:
v_movrels_b32 v0, v0 //v0 = v[0+m0]
buffer_store_dword v0, v0, s_save_buf_rsrc0, s_save_mem_offset slc:1 glc:1
@ -1190,6 +1307,43 @@ function read_4sgpr_from_mem(s, s_rsrc, s_mem_offset)
s_buffer_load_dwordx4 s, s_rsrc, s_mem_offset glc:1
end
#if SAVE_AFTER_XNACK_ERROR
function check_if_tcp_store_ok
// If TRAPSTS.XNACK_ERROR=1 then TCP stores will fail.
s_getreg_b32 s_save_tmp, hwreg(HW_REG_TRAPSTS)
s_andn2_b32 s_save_tmp, SQ_WAVE_TRAPSTS_XNACK_ERROR_MASK, s_save_tmp
L_TCP_STORE_CHECK_DONE:
end
function write_vgpr_to_mem_with_sqc(vgpr, n_lanes, s_rsrc, s_mem_offset)
s_mov_b32 s4, 0
L_WRITE_VGPR_LANE_LOOP:
for var lane = 0; lane < 4; ++lane
v_readlane_b32 s[lane], vgpr, s4
s_add_u32 s4, s4, 1
end
s_buffer_store_dwordx4 s[0:3], s_rsrc, s_mem_offset glc:1
s_add_u32 s_mem_offset, s_mem_offset, 0x10
s_cmp_eq_u32 s4, n_lanes
s_cbranch_scc0 L_WRITE_VGPR_LANE_LOOP
end
function write_vgprs_to_mem_with_sqc_w32(vgpr0, n_vgprs, s_rsrc, s_mem_offset)
for var vgpr = 0; vgpr < n_vgprs; ++vgpr
write_vgpr_to_mem_with_sqc(vgpr0[vgpr], 32, s_rsrc, s_mem_offset)
end
end
function write_vgprs_to_mem_with_sqc_w64(vgpr0, n_vgprs, s_rsrc, s_mem_offset)
for var vgpr = 0; vgpr < n_vgprs; ++vgpr
write_vgpr_to_mem_with_sqc(vgpr0[vgpr], 64, s_rsrc, s_mem_offset)
end
end
#endif
function get_lds_size_bytes(s_lds_size_byte)
s_getreg_b32 s_lds_size_byte, hwreg(HW_REG_LDS_ALLOC, SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT, SQ_WAVE_LDS_ALLOC_LDS_SIZE_SIZE)

View File

@ -63,8 +63,10 @@ static const struct file_operations kfd_fops = {
};
static int kfd_char_dev_major = -1;
static struct class *kfd_class;
struct device *kfd_device;
static const struct class kfd_class = {
.name = kfd_dev_name,
};
static inline struct kfd_process_device *kfd_lock_pdd_by_id(struct kfd_process *p, __u32 gpu_id)
{
@ -94,14 +96,13 @@ int kfd_chardev_init(void)
if (err < 0)
goto err_register_chrdev;
kfd_class = class_create(kfd_dev_name);
err = PTR_ERR(kfd_class);
if (IS_ERR(kfd_class))
err = class_register(&kfd_class);
if (err)
goto err_class_create;
kfd_device = device_create(kfd_class, NULL,
MKDEV(kfd_char_dev_major, 0),
NULL, kfd_dev_name);
kfd_device = device_create(&kfd_class, NULL,
MKDEV(kfd_char_dev_major, 0),
NULL, kfd_dev_name);
err = PTR_ERR(kfd_device);
if (IS_ERR(kfd_device))
goto err_device_create;
@ -109,7 +110,7 @@ int kfd_chardev_init(void)
return 0;
err_device_create:
class_destroy(kfd_class);
class_unregister(&kfd_class);
err_class_create:
unregister_chrdev(kfd_char_dev_major, kfd_dev_name);
err_register_chrdev:
@ -118,8 +119,8 @@ err_register_chrdev:
void kfd_chardev_exit(void)
{
device_destroy(kfd_class, MKDEV(kfd_char_dev_major, 0));
class_destroy(kfd_class);
device_destroy(&kfd_class, MKDEV(kfd_char_dev_major, 0));
class_unregister(&kfd_class);
unregister_chrdev(kfd_char_dev_major, kfd_dev_name);
kfd_device = NULL;
}

View File

@ -466,34 +466,43 @@ static void kfd_cwsr_init(struct kfd_dev *kfd)
{
if (cwsr_enable && kfd->device_info.supports_cwsr) {
if (KFD_GC_VERSION(kfd) < IP_VERSION(9, 0, 1)) {
BUILD_BUG_ON(sizeof(cwsr_trap_gfx8_hex) > PAGE_SIZE);
BUILD_BUG_ON(sizeof(cwsr_trap_gfx8_hex)
> KFD_CWSR_TMA_OFFSET);
kfd->cwsr_isa = cwsr_trap_gfx8_hex;
kfd->cwsr_isa_size = sizeof(cwsr_trap_gfx8_hex);
} else if (KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 1)) {
BUILD_BUG_ON(sizeof(cwsr_trap_arcturus_hex) > PAGE_SIZE);
BUILD_BUG_ON(sizeof(cwsr_trap_arcturus_hex)
> KFD_CWSR_TMA_OFFSET);
kfd->cwsr_isa = cwsr_trap_arcturus_hex;
kfd->cwsr_isa_size = sizeof(cwsr_trap_arcturus_hex);
} else if (KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 2)) {
BUILD_BUG_ON(sizeof(cwsr_trap_aldebaran_hex) > PAGE_SIZE);
BUILD_BUG_ON(sizeof(cwsr_trap_aldebaran_hex)
> KFD_CWSR_TMA_OFFSET);
kfd->cwsr_isa = cwsr_trap_aldebaran_hex;
kfd->cwsr_isa_size = sizeof(cwsr_trap_aldebaran_hex);
} else if (KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 3)) {
BUILD_BUG_ON(sizeof(cwsr_trap_gfx9_4_3_hex) > PAGE_SIZE);
BUILD_BUG_ON(sizeof(cwsr_trap_gfx9_4_3_hex)
> KFD_CWSR_TMA_OFFSET);
kfd->cwsr_isa = cwsr_trap_gfx9_4_3_hex;
kfd->cwsr_isa_size = sizeof(cwsr_trap_gfx9_4_3_hex);
} else if (KFD_GC_VERSION(kfd) < IP_VERSION(10, 1, 1)) {
BUILD_BUG_ON(sizeof(cwsr_trap_gfx9_hex) > PAGE_SIZE);
BUILD_BUG_ON(sizeof(cwsr_trap_gfx9_hex)
> KFD_CWSR_TMA_OFFSET);
kfd->cwsr_isa = cwsr_trap_gfx9_hex;
kfd->cwsr_isa_size = sizeof(cwsr_trap_gfx9_hex);
} else if (KFD_GC_VERSION(kfd) < IP_VERSION(10, 3, 0)) {
BUILD_BUG_ON(sizeof(cwsr_trap_nv1x_hex) > PAGE_SIZE);
BUILD_BUG_ON(sizeof(cwsr_trap_nv1x_hex)
> KFD_CWSR_TMA_OFFSET);
kfd->cwsr_isa = cwsr_trap_nv1x_hex;
kfd->cwsr_isa_size = sizeof(cwsr_trap_nv1x_hex);
} else if (KFD_GC_VERSION(kfd) < IP_VERSION(11, 0, 0)) {
BUILD_BUG_ON(sizeof(cwsr_trap_gfx10_hex) > PAGE_SIZE);
BUILD_BUG_ON(sizeof(cwsr_trap_gfx10_hex)
> KFD_CWSR_TMA_OFFSET);
kfd->cwsr_isa = cwsr_trap_gfx10_hex;
kfd->cwsr_isa_size = sizeof(cwsr_trap_gfx10_hex);
} else {
/* The gfx11 cwsr trap handler must fit inside a single
page. */
BUILD_BUG_ON(sizeof(cwsr_trap_gfx11_hex) > PAGE_SIZE);
kfd->cwsr_isa = cwsr_trap_gfx11_hex;
kfd->cwsr_isa_size = sizeof(cwsr_trap_gfx11_hex);

View File

@ -99,11 +99,11 @@
/*
* Size of the per-process TBA+TMA buffer: 2 pages
*
* The first page is the TBA used for the CWSR ISA code. The second
* page is used as TMA for user-mode trap handler setup in daisy-chain mode.
* The first chunk is the TBA used for the CWSR ISA code. The second
* chunk is used as TMA for user-mode trap handler setup in daisy-chain mode.
*/
#define KFD_CWSR_TBA_TMA_SIZE (PAGE_SIZE * 2)
#define KFD_CWSR_TMA_OFFSET PAGE_SIZE
#define KFD_CWSR_TMA_OFFSET (PAGE_SIZE + 2048)
#define KFD_MAX_NUM_OF_QUEUES_PER_DEVICE \
(KFD_MAX_NUM_OF_PROCESSES * \

View File

@ -238,16 +238,16 @@ void kfd_smi_event_update_thermal_throttling(struct kfd_node *dev,
void kfd_smi_event_update_vmfault(struct kfd_node *dev, uint16_t pasid)
{
struct amdgpu_task_info task_info;
struct amdgpu_task_info *task_info;
memset(&task_info, 0, sizeof(struct amdgpu_task_info));
amdgpu_vm_get_task_info(dev->adev, pasid, &task_info);
/* Report VM faults from user applications, not retry from kernel */
if (!task_info.pid)
return;
kfd_smi_event_add(0, dev, KFD_SMI_EVENT_VMFAULT, "%x:%s\n",
task_info.pid, task_info.task_name);
task_info = amdgpu_vm_get_task_info_pasid(dev->adev, pasid);
if (task_info) {
/* Report VM faults from user applications, not retry from kernel */
if (task_info->pid)
kfd_smi_event_add(0, dev, KFD_SMI_EVENT_VMFAULT, "%x:%s\n",
task_info->pid, task_info->task_name);
amdgpu_vm_put_task_info(task_info);
}
}
void kfd_smi_event_page_fault_start(struct kfd_node *node, pid_t pid,

View File

@ -1219,6 +1219,7 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
case IP_VERSION(3, 1, 3):
case IP_VERSION(3, 1, 4):
case IP_VERSION(3, 5, 0):
case IP_VERSION(3, 5, 1):
hw_params.dpia_supported = true;
hw_params.disable_dpia = adev->dm.dc->debug.dpia_debug.bits.disable_dpia;
break;
@ -2040,6 +2041,7 @@ static int load_dmcu_fw(struct amdgpu_device *adev)
case IP_VERSION(3, 2, 0):
case IP_VERSION(3, 2, 1):
case IP_VERSION(3, 5, 0):
case IP_VERSION(3, 5, 1):
return 0;
default:
break;
@ -2160,6 +2162,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
dmub_asic = DMUB_ASIC_DCN321;
break;
case IP_VERSION(3, 5, 0):
case IP_VERSION(3, 5, 1):
dmub_asic = DMUB_ASIC_DCN35;
break;
default:
@ -4489,6 +4492,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
case IP_VERSION(3, 2, 1):
case IP_VERSION(2, 1, 0):
case IP_VERSION(3, 5, 0):
case IP_VERSION(3, 5, 1):
if (register_outbox_irq_handlers(dm->adev)) {
DRM_ERROR("DM: Failed to initialize IRQ\n");
goto fail;
@ -4510,6 +4514,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
case IP_VERSION(3, 2, 0):
case IP_VERSION(3, 2, 1):
case IP_VERSION(3, 5, 0):
case IP_VERSION(3, 5, 1):
psr_feature_enabled = true;
break;
default:
@ -4527,6 +4532,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
case IP_VERSION(3, 2, 0):
case IP_VERSION(3, 2, 1):
case IP_VERSION(3, 5, 0):
case IP_VERSION(3, 5, 1):
replay_feature_enabled = true;
break;
default:
@ -4679,6 +4685,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
case IP_VERSION(3, 2, 0):
case IP_VERSION(3, 2, 1):
case IP_VERSION(3, 5, 0):
case IP_VERSION(3, 5, 1):
if (dcn10_register_irq_handlers(dm->adev)) {
DRM_ERROR("DM: Failed to initialize IRQ\n");
goto fail;
@ -4810,6 +4817,7 @@ static int dm_init_microcode(struct amdgpu_device *adev)
fw_name_dmub = FIRMWARE_DCN_V3_2_1_DMCUB;
break;
case IP_VERSION(3, 5, 0):
case IP_VERSION(3, 5, 1):
fw_name_dmub = FIRMWARE_DCN_35_DMUB;
break;
default:
@ -4935,6 +4943,7 @@ static int dm_early_init(void *handle)
case IP_VERSION(3, 2, 0):
case IP_VERSION(3, 2, 1):
case IP_VERSION(3, 5, 0):
case IP_VERSION(3, 5, 1):
adev->mode_info.num_crtc = 4;
adev->mode_info.num_hpd = 4;
adev->mode_info.num_dig = 4;
@ -11293,14 +11302,23 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
if (range->flags != 1)
continue;
amdgpu_dm_connector->min_vfreq = range->min_vfreq;
amdgpu_dm_connector->max_vfreq = range->max_vfreq;
amdgpu_dm_connector->pixel_clock_mhz =
range->pixel_clock_mhz * 10;
connector->display_info.monitor_range.min_vfreq = range->min_vfreq;
connector->display_info.monitor_range.max_vfreq = range->max_vfreq;
if (edid->revision >= 4) {
if (data->pad2 & DRM_EDID_RANGE_OFFSET_MIN_VFREQ)
connector->display_info.monitor_range.min_vfreq += 255;
if (data->pad2 & DRM_EDID_RANGE_OFFSET_MAX_VFREQ)
connector->display_info.monitor_range.max_vfreq += 255;
}
amdgpu_dm_connector->min_vfreq =
connector->display_info.monitor_range.min_vfreq;
amdgpu_dm_connector->max_vfreq =
connector->display_info.monitor_range.max_vfreq;
amdgpu_dm_connector->pixel_clock_mhz =
range->pixel_clock_mhz * 10;
break;
}

View File

@ -741,6 +741,7 @@ struct hdcp_workqueue *hdcp_create_workqueue(struct amdgpu_device *adev,
dc->ctx->dce_version == DCN_VERSION_3_14 ||
dc->ctx->dce_version == DCN_VERSION_3_15 ||
dc->ctx->dce_version == DCN_VERSION_3_5 ||
dc->ctx->dce_version == DCN_VERSION_3_51 ||
dc->ctx->dce_version == DCN_VERSION_3_16)
hdcp_work[i].hdcp.config.psp.caps.dtm_v3_supported = 1;
hdcp_work[i].hdcp.config.ddc.handle = dc_get_link_at_index(dc, i);

View File

@ -81,6 +81,7 @@ bool dal_bios_parser_init_cmd_tbl_helper2(
case DCN_VERSION_3_2:
case DCN_VERSION_3_21:
case DCN_VERSION_3_5:
case DCN_VERSION_3_51:
*h = dal_cmd_tbl_helper_dce112_get_table2();
return true;

View File

@ -73,6 +73,7 @@
#include "dcn32/dcn32_resource.h"
#include "dcn321/dcn321_resource.h"
#include "dcn35/dcn35_resource.h"
#include "dcn351/dcn351_resource.h"
#define VISUAL_CONFIRM_BASE_DEFAULT 3
#define VISUAL_CONFIRM_BASE_MIN 1
@ -195,6 +196,8 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
break;
case AMDGPU_FAMILY_GC_11_5_0:
dc_version = DCN_VERSION_3_5;
if (ASICREV_IS_GC_11_0_4(asic_id.hw_internal_rev))
dc_version = DCN_VERSION_3_51;
break;
default:
dc_version = DCE_VERSION_UNKNOWN;
@ -303,6 +306,9 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc,
case DCN_VERSION_3_5:
res_pool = dcn35_create_resource_pool(init_data, dc);
break;
case DCN_VERSION_3_51:
res_pool = dcn351_create_resource_pool(init_data, dc);
break;
#endif /* CONFIG_DRM_AMD_DC_FP */
default:
break;

View File

@ -28,6 +28,7 @@
#include "dcn30/dcn30_vpg.h"
#include "dcn30/dcn30_afmt.h"
#include "stream_encoder.h"
#include "dcn10/dcn10_link_encoder.h"
#include "dcn20/dcn20_stream_encoder.h"
/* Register bit field name change */

View File

@ -92,6 +92,7 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_rq_dlg_calc_32.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_mode_vba_util_32.o := $(dml_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn321/dcn321_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn35/dcn35_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn351/dcn351_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/dcn31_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_ccflags)
CFLAGS_$(AMDDALPATH)/dc/dml/dcn302/dcn302_fpu.o := $(dml_ccflags)
@ -126,6 +127,7 @@ CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn30/dcn30_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn32/dcn32_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn321/dcn321_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn35/dcn35_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn351/dcn351_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/dcn31_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn302/dcn302_fpu.o := $(dml_rcflags)
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn303/dcn303_fpu.o := $(dml_rcflags)
@ -157,6 +159,7 @@ DML += dcn302/dcn302_fpu.o
DML += dcn303/dcn303_fpu.o
DML += dcn314/dcn314_fpu.o
DML += dcn35/dcn35_fpu.o
DML += dcn351/dcn351_fpu.o
DML += dsc/rc_calc_fpu.o
DML += calcs/dcn_calcs.o calcs/dcn_calc_math.o calcs/dcn_calc_auto.o
endif

View File

@ -0,0 +1,574 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
#include "resource.h"
#include "dcn351_fpu.h"
#include "dcn31/dcn31_resource.h"
#include "dcn32/dcn32_resource.h"
#include "dcn35/dcn35_resource.h"
#include "dcn351/dcn351_resource.h"
#include "dml/dcn31/dcn31_fpu.h"
#include "dml/dcn35/dcn35_fpu.h"
#include "dml/dml_inline_defs.h"
#include "link.h"
#define DC_LOGGER_INIT(logger)
struct _vcs_dpi_ip_params_st dcn3_51_ip = {
.VBlankNomDefaultUS = 668,
.gpuvm_enable = 1,
.gpuvm_max_page_table_levels = 1,
.hostvm_enable = 1,
.hostvm_max_page_table_levels = 2,
.rob_buffer_size_kbytes = 64,
.det_buffer_size_kbytes = 1536,
.config_return_buffer_size_in_kbytes = 1792,
.compressed_buffer_segment_size_in_kbytes = 64,
.meta_fifo_size_in_kentries = 32,
.zero_size_buffer_entries = 512,
.compbuf_reserved_space_64b = 256,
.compbuf_reserved_space_zs = 64,
.dpp_output_buffer_pixels = 2560,/*not used*/
.opp_output_buffer_lines = 1,/*not used*/
.pixel_chunk_size_kbytes = 8,
//.alpha_pixel_chunk_size_kbytes = 4;/*new*/
//.min_pixel_chunk_size_bytes = 1024;/*new*/
.meta_chunk_size_kbytes = 2,
.min_meta_chunk_size_bytes = 256,
.writeback_chunk_size_kbytes = 8,
.ptoi_supported = false,
.num_dsc = 4,
.maximum_dsc_bits_per_component = 12,/*delta from 10*/
.dsc422_native_support = true,/*delta from false*/
.is_line_buffer_bpp_fixed = true,/*new*/
.line_buffer_fixed_bpp = 32,/*delta from 48*/
.line_buffer_size_bits = 986880,/*delta from 789504*/
.max_line_buffer_lines = 32,/*delta from 12*/
.writeback_interface_buffer_size_kbytes = 90,
.max_num_dpp = 4,
.max_num_otg = 4,
.max_num_hdmi_frl_outputs = 1,
.max_num_wb = 1,
/*.max_num_hdmi_frl_outputs = 1; new in dml2*/
/*.max_num_dp2p0_outputs = 2; new in dml2*/
/*.max_num_dp2p0_streams = 4; new in dml2*/
.max_dchub_pscl_bw_pix_per_clk = 4,
.max_pscl_lb_bw_pix_per_clk = 2,
.max_lb_vscl_bw_pix_per_clk = 4,
.max_vscl_hscl_bw_pix_per_clk = 4,
.max_hscl_ratio = 6,
.max_vscl_ratio = 6,
.max_hscl_taps = 8,
.max_vscl_taps = 8,
.dpte_buffer_size_in_pte_reqs_luma = 68,/*changed from 64,*/
.dpte_buffer_size_in_pte_reqs_chroma = 36,/*changed from 34*/
/*.dcc_meta_buffer_size_bytes = 6272; new to dml2*/
.dispclk_ramp_margin_percent = 1.11,/*delta from 1*/
/*.dppclk_delay_subtotal = 47;
.dppclk_delay_scl = 50;
.dppclk_delay_scl_lb_only = 16;
.dppclk_delay_cnvc_formatter = 28;
.dppclk_delay_cnvc_cursor = 6;
.dispclk_delay_subtotal = 125;*/ /*new to dml2*/
.max_inter_dcn_tile_repeaters = 8,
.cursor_buffer_size = 16,
.cursor_chunk_size = 2,
.writeback_line_buffer_buffer_size = 0,
.writeback_min_hscl_ratio = 1,
.writeback_min_vscl_ratio = 1,
.writeback_max_hscl_ratio = 1,
.writeback_max_vscl_ratio = 1,
.writeback_max_hscl_taps = 1,
.writeback_max_vscl_taps = 1,
.dppclk_delay_subtotal = 47, /* changed from 46,*/
.dppclk_delay_scl = 50,
.dppclk_delay_scl_lb_only = 16,
.dppclk_delay_cnvc_formatter = 28,/*changed from 27,*/
.dppclk_delay_cnvc_cursor = 6,
.dispclk_delay_subtotal = 125, /*changed from 119,*/
.dynamic_metadata_vm_enabled = false,
.odm_combine_4to1_supported = false,
.dcc_supported = true,
// .config_return_buffer_segment_size_in_kbytes = 64;/*required, hard coded in dml2_translate_ip_params*/
};
struct _vcs_dpi_soc_bounding_box_st dcn3_51_soc = {
/*TODO: correct dispclk/dppclk voltage level determination*/
.clock_limits = {
{
.state = 0,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 600.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 186.0,
.dtbclk_mhz = 600.0,
},
{
.state = 1,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 209.0,
.dtbclk_mhz = 600.0,
},
{
.state = 2,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 209.0,
.dtbclk_mhz = 600.0,
},
{
.state = 3,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 371.0,
.dtbclk_mhz = 600.0,
},
{
.state = 4,
.dispclk_mhz = 1200.0,
.dppclk_mhz = 1200.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.dscclk_mhz = 417.0,
.dtbclk_mhz = 600.0,
},
},
.num_states = 5,
.sr_exit_time_us = 28.0,
.sr_enter_plus_exit_time_us = 30.0,
.sr_exit_z8_time_us = 210.0,
.sr_enter_plus_exit_z8_time_us = 320.0,
.fclk_change_latency_us = 24.0,
.usr_retraining_latency_us = 2,
.writeback_latency_us = 12.0,
.dram_channel_width_bytes = 4,/*not exist in dml2*/
.round_trip_ping_latency_dcfclk_cycles = 106,/*not exist in dml2*/
.urgent_latency_pixel_data_only_us = 4.0,
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
.urgent_latency_vm_data_only_us = 4.0,
.dram_clock_change_latency_us = 11.72,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
.pct_ideal_sdp_bw_after_urgent = 80.0,
.pct_ideal_fabric_bw_after_urgent = 80.0, /*new to dml2*/
.pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 65.0,
.pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0,
.pct_ideal_dram_sdp_bw_after_urgent_vm_only = 30.0,
.max_avg_sdp_bw_use_normal_percent = 60.0,
.max_avg_dram_bw_use_normal_percent = 60.0,
.fabric_datapath_to_dcn_data_return_bytes = 32,
.return_bus_width_bytes = 64,
.downspread_percent = 0.38,
.dcn_downspread_percent = 0.5,
.gpuvm_min_page_size_bytes = 4096,
.hostvm_min_page_size_bytes = 4096,
.do_urgent_latency_adjustment = 0,
.urgent_latency_adjustment_fabric_clock_component_us = 0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
};
/*
* dcn351_update_bw_bounding_box
*
* This would override some dcn3_51 ip_or_soc initial parameters hardcoded from
* spreadsheet with actual values as per dGPU SKU:
* - with passed few options from dc->config
* - with dentist_vco_frequency from Clk Mgr (currently hardcoded, but might
* need to get it from PM FW)
* - with passed latency values (passed in ns units) in dc-> bb override for
* debugging purposes
* - with passed latencies from VBIOS (in 100_ns units) if available for
* certain dGPU SKU
* - with number of DRAM channels from VBIOS (which differ for certain dGPU SKU
* of the same ASIC)
* - clocks levels with passed clk_table entries from Clk Mgr as reported by PM
* FW for different clocks (which might differ for certain dGPU SKU of the
* same ASIC)
*/
void dcn351_update_bw_bounding_box_fpu(struct dc *dc,
struct clk_bw_params *bw_params)
{
unsigned int i, closest_clk_lvl;
int j;
struct clk_limit_table *clk_table = &bw_params->clk_table;
struct _vcs_dpi_voltage_scaling_st *clock_limits =
dc->scratch.update_bw_bounding_box.clock_limits;
int max_dispclk_mhz = 0, max_dppclk_mhz = 0;
dc_assert_fp_enabled();
dcn3_51_ip.max_num_otg =
dc->res_pool->res_cap->num_timing_generator;
dcn3_51_ip.max_num_dpp = dc->res_pool->pipe_count;
dcn3_51_soc.num_chans = bw_params->num_channels;
ASSERT(clk_table->num_entries);
/* Prepass to find max clocks independent of voltage level. */
for (i = 0; i < clk_table->num_entries; ++i) {
if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz)
max_dispclk_mhz = clk_table->entries[i].dispclk_mhz;
if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz)
max_dppclk_mhz = clk_table->entries[i].dppclk_mhz;
}
for (i = 0; i < clk_table->num_entries; i++) {
/* loop backwards*/
for (closest_clk_lvl = 0, j = dcn3_51_soc.num_states - 1;
j >= 0; j--) {
if (dcn3_51_soc.clock_limits[j].dcfclk_mhz <=
clk_table->entries[i].dcfclk_mhz) {
closest_clk_lvl = j;
break;
}
}
if (clk_table->num_entries == 1) {
/*smu gives one DPM level, let's take the highest one*/
closest_clk_lvl = dcn3_51_soc.num_states - 1;
}
clock_limits[i].state = i;
/* Clocks dependent on voltage level. */
clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
if (clk_table->num_entries == 1 &&
clock_limits[i].dcfclk_mhz <
dcn3_51_soc.clock_limits[closest_clk_lvl].dcfclk_mhz) {
/*SMU fix not released yet*/
clock_limits[i].dcfclk_mhz =
dcn3_51_soc.clock_limits[closest_clk_lvl].dcfclk_mhz;
}
clock_limits[i].fabricclk_mhz =
clk_table->entries[i].fclk_mhz;
clock_limits[i].socclk_mhz =
clk_table->entries[i].socclk_mhz;
if (clk_table->entries[i].memclk_mhz &&
clk_table->entries[i].wck_ratio)
clock_limits[i].dram_speed_mts =
clk_table->entries[i].memclk_mhz * 2 *
clk_table->entries[i].wck_ratio;
/* Clocks independent of voltage level. */
clock_limits[i].dispclk_mhz = max_dispclk_mhz ?
max_dispclk_mhz :
dcn3_51_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
clock_limits[i].dppclk_mhz = max_dppclk_mhz ?
max_dppclk_mhz :
dcn3_51_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
clock_limits[i].dram_bw_per_chan_gbps =
dcn3_51_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
clock_limits[i].dscclk_mhz =
dcn3_51_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
clock_limits[i].dtbclk_mhz =
dcn3_51_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
clock_limits[i].phyclk_d18_mhz =
dcn3_51_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
clock_limits[i].phyclk_mhz =
dcn3_51_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
}
memcpy(dcn3_51_soc.clock_limits, clock_limits,
sizeof(dcn3_51_soc.clock_limits));
if (clk_table->num_entries)
dcn3_51_soc.num_states = clk_table->num_entries;
if (max_dispclk_mhz) {
dcn3_51_soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = max_dispclk_mhz * 2;
}
if ((int)(dcn3_51_soc.dram_clock_change_latency_us * 1000)
!= dc->debug.dram_clock_change_latency_ns
&& dc->debug.dram_clock_change_latency_ns) {
dcn3_51_soc.dram_clock_change_latency_us =
dc->debug.dram_clock_change_latency_ns / 1000.0;
}
if (dc->bb_overrides.dram_clock_change_latency_ns > 0)
dcn3_51_soc.dram_clock_change_latency_us =
dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
if (dc->bb_overrides.sr_exit_time_ns > 0)
dcn3_51_soc.sr_exit_time_us = dc->bb_overrides.sr_exit_time_ns / 1000.0;
if (dc->bb_overrides.sr_enter_plus_exit_time_ns > 0)
dcn3_51_soc.sr_enter_plus_exit_time_us =
dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
if (dc->bb_overrides.sr_exit_z8_time_ns > 0)
dcn3_51_soc.sr_exit_z8_time_us = dc->bb_overrides.sr_exit_z8_time_ns / 1000.0;
if (dc->bb_overrides.sr_enter_plus_exit_z8_time_ns > 0)
dcn3_51_soc.sr_enter_plus_exit_z8_time_us =
dc->bb_overrides.sr_enter_plus_exit_z8_time_ns / 1000.0;
/*temp till dml2 fully work without dml1*/
dml_init_instance(&dc->dml, &dcn3_51_soc, &dcn3_51_ip,
DML_PROJECT_DCN31);
/*copy to dml2, before dml2_create*/
if (clk_table->num_entries > 2) {
for (i = 0; i < clk_table->num_entries; i++) {
dc->dml2_options.bbox_overrides.clks_table.num_states =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dcfclk_mhz =
clock_limits[i].dcfclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].fclk_mhz =
clock_limits[i].fabricclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dispclk_mhz =
clock_limits[i].dispclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dppclk_mhz =
clock_limits[i].dppclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].socclk_mhz =
clock_limits[i].socclk_mhz;
dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].memclk_mhz =
clk_table->entries[i].memclk_mhz * clk_table->entries[i].wck_ratio;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dcfclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_fclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dispclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dppclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_socclk_levels =
clk_table->num_entries;
dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_memclk_levels =
clk_table->num_entries;
}
}
/* Update latency values */
dc->dml2_options.bbox_overrides.dram_clock_change_latency_us = dcn3_51_soc.dram_clock_change_latency_us;
dc->dml2_options.bbox_overrides.sr_exit_latency_us = dcn3_51_soc.sr_exit_time_us;
dc->dml2_options.bbox_overrides.sr_enter_plus_exit_latency_us = dcn3_51_soc.sr_enter_plus_exit_time_us;
dc->dml2_options.bbox_overrides.sr_exit_z8_time_us = dcn3_51_soc.sr_exit_z8_time_us;
dc->dml2_options.bbox_overrides.sr_enter_plus_exit_z8_time_us = dcn3_51_soc.sr_enter_plus_exit_z8_time_us;
}
static bool is_dual_plane(enum surface_pixel_format format)
{
return format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN ||
format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA;
}
/*
* micro_sec_to_vert_lines () - converts time to number of vertical lines for a given timing
*
* @param: num_us: number of microseconds
* @return: number of vertical lines. If exact number of vertical lines is not found then
* it will round up to next number of lines to guarantee num_us
*/
static unsigned int micro_sec_to_vert_lines(unsigned int num_us, struct dc_crtc_timing *timing)
{
unsigned int num_lines = 0;
unsigned int lines_time_in_ns = 1000.0 *
(((float)timing->h_total * 1000.0) /
((float)timing->pix_clk_100hz / 10.0));
num_lines = dml_ceil(1000.0 * num_us / lines_time_in_ns, 1.0);
return num_lines;
}
static unsigned int get_vertical_back_porch(struct dc_crtc_timing *timing)
{
unsigned int v_active = 0, v_blank = 0, v_back_porch = 0;
v_active = timing->v_border_top + timing->v_addressable + timing->v_border_bottom;
v_blank = timing->v_total - v_active;
v_back_porch = v_blank - timing->v_front_porch - timing->v_sync_width;
return v_back_porch;
}
int dcn351_populate_dml_pipes_from_context_fpu(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
bool fast_validate)
{
int i, pipe_cnt;
struct resource_context *res_ctx = &context->res_ctx;
struct pipe_ctx *pipe;
bool upscaled = false;
const unsigned int max_allowed_vblank_nom = 1023;
dcn31_populate_dml_pipes_from_context(dc, context, pipes,
fast_validate);
for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
struct dc_crtc_timing *timing;
unsigned int num_lines = 0;
unsigned int v_back_porch = 0;
if (!res_ctx->pipe_ctx[i].stream)
continue;
pipe = &res_ctx->pipe_ctx[i];
timing = &pipe->stream->timing;
num_lines = micro_sec_to_vert_lines(dcn3_51_ip.VBlankNomDefaultUS, timing);
v_back_porch = get_vertical_back_porch(timing);
if (pipe->stream->adjust.v_total_max ==
pipe->stream->adjust.v_total_min &&
pipe->stream->adjust.v_total_min > timing->v_total) {
pipes[pipe_cnt].pipe.dest.vtotal =
pipe->stream->adjust.v_total_min;
pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total -
pipes[pipe_cnt].pipe.dest.vactive;
}
pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive;
pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, num_lines);
// vblank_nom should not smaller than (VSync (timing->v_sync_width + v_back_porch) + 2)
// + 2 is because
// 1 -> VStartup_start should be 1 line before VSync
// 1 -> always reserve 1 line between start of vblank to vstartup signal
pipes[pipe_cnt].pipe.dest.vblank_nom =
max(pipes[pipe_cnt].pipe.dest.vblank_nom, timing->v_sync_width + v_back_porch + 2);
pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, max_allowed_vblank_nom);
if (pipe->plane_state &&
(pipe->plane_state->src_rect.height <
pipe->plane_state->dst_rect.height ||
pipe->plane_state->src_rect.width <
pipe->plane_state->dst_rect.width))
upscaled = true;
/*
* Immediate flip can be set dynamically after enabling the
* plane. We need to require support for immediate flip or
* underflow can be intermittently experienced depending on peak
* b/w requirements.
*/
pipes[pipe_cnt].pipe.src.immediate_flip = true;
pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
DC_FP_START();
dcn31_zero_pipe_dcc_fraction(pipes, pipe_cnt);
DC_FP_END();
pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
pipes[pipe_cnt].pipe.src.dcc_rate = 3;
pipes[pipe_cnt].dout.dsc_input_bpc = 0;
pipes[pipe_cnt].pipe.src.gpuvm_min_page_size_kbytes = 256;
if (pipes[pipe_cnt].dout.dsc_enable) {
switch (timing->display_color_depth) {
case COLOR_DEPTH_888:
pipes[pipe_cnt].dout.dsc_input_bpc = 8;
break;
case COLOR_DEPTH_101010:
pipes[pipe_cnt].dout.dsc_input_bpc = 10;
break;
case COLOR_DEPTH_121212:
pipes[pipe_cnt].dout.dsc_input_bpc = 12;
break;
default:
ASSERT(0);
break;
}
}
pipe_cnt++;
}
context->bw_ctx.dml.ip.det_buffer_size_kbytes = 384;/*per guide*/
dc->config.enable_4to1MPC = false;
if (pipe_cnt == 1 && pipe->plane_state && !dc->debug.disable_z9_mpc) {
if (is_dual_plane(pipe->plane_state->format)
&& pipe->plane_state->src_rect.width <= 1920 &&
pipe->plane_state->src_rect.height <= 1080) {
dc->config.enable_4to1MPC = true;
} else if (!is_dual_plane(pipe->plane_state->format) &&
pipe->plane_state->src_rect.width <= 5120) {
/*
* Limit to 5k max to avoid forced pipe split when there
* is not enough detile for swath
*/
context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
pipes[0].pipe.src.unbounded_req_mode = true;
}
} else if (context->stream_count >=
dc->debug.crb_alloc_policy_min_disp_count &&
dc->debug.crb_alloc_policy > DET_SIZE_DEFAULT) {
context->bw_ctx.dml.ip.det_buffer_size_kbytes =
dc->debug.crb_alloc_policy * 64;
} else if (context->stream_count >= 3 && upscaled) {
context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192;
}
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
if (!pipe->stream)
continue;
if (pipe->stream->signal == SIGNAL_TYPE_EDP &&
dc->debug.seamless_boot_odm_combine &&
pipe->stream->apply_seamless_boot_optimization) {
if (pipe->stream->apply_boot_odm_mode ==
dm_odm_combine_policy_2to1) {
context->bw_ctx.dml.vba.ODMCombinePolicy =
dm_odm_combine_policy_2to1;
break;
}
}
}
return pipe_cnt;
}
void dcn351_decide_zstate_support(struct dc *dc, struct dc_state *context)
{
enum dcn_zstate_support_state support = DCN_ZSTATE_SUPPORT_DISALLOW;
unsigned int i, plane_count = 0;
for (i = 0; i < dc->res_pool->pipe_count; i++) {
if (context->res_ctx.pipe_ctx[i].plane_state)
plane_count++;
}
/*dcn351 does not support z9/z10*/
if (context->stream_count == 0 || plane_count == 0) {
support = DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY;
} else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) {
struct dc_link *link = context->streams[0]->sink->link;
bool is_pwrseq0 = link && link->link_index == 0;
bool is_psr = (link && (link->psr_settings.psr_version == DC_PSR_VERSION_1 ||
link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) && !link->panel_config.psr.disable_psr);
bool is_replay = link && link->replay_settings.replay_feature_enabled;
int minmum_z8_residency =
dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000;
bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency;
/*for psr1/psr-su, we allow z8 and z10 based on latency, for replay with IPS enabled, it will enter ips2*/
if (is_pwrseq0 && (is_psr || is_replay))
support = allow_z8 ? allow_z8 : DCN_ZSTATE_SUPPORT_DISALLOW;
}
context->bw_ctx.bw.dcn.clk.zstate_support = support;
}

View File

@ -0,0 +1,19 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
#ifndef __DCN351_FPU_H__
#define __DCN351_FPU_H__
#include "clk_mgr.h"
void dcn351_update_bw_bounding_box_fpu(struct dc *dc,
struct clk_bw_params *bw_params);
int dcn351_populate_dml_pipes_from_context_fpu(struct dc *dc,
struct dc_state *context,
display_e2e_pipe_params_st *pipes,
bool fast_validate);
void dcn351_decide_zstate_support(struct dc *dc, struct dc_state *context);
#endif

View File

@ -110,6 +110,7 @@ bool dal_hw_factory_init(
case DCN_VERSION_3_2:
case DCN_VERSION_3_21:
case DCN_VERSION_3_5:
case DCN_VERSION_3_51:
dal_hw_factory_dcn32_init(factory);
return true;
default:

View File

@ -111,6 +111,7 @@ bool dal_hw_translate_init(
case DCN_VERSION_3_2:
case DCN_VERSION_3_21:
case DCN_VERSION_3_5:
case DCN_VERSION_3_51:
dal_hw_translate_dcn32_init(translate);
return true;
default:

View File

@ -180,6 +180,14 @@ AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN35)
###############################################################################
HWSS_DCN351 = dcn351_init.o
AMD_DAL_HWSS_DCN351 = $(addprefix $(AMDDALPATH)/dc/hwss/dcn351/,$(HWSS_DCN351))
AMD_DISPLAY_FILES += $(AMD_DAL_HWSS_DCN351)
###############################################################################
###############################################################################
endif

View File

@ -1,4 +0,0 @@
dal3_subdirectory_sources(
dcn351_init.c
dcn351_init.h
)

View File

@ -110,9 +110,8 @@ struct mpcc_blnd_cfg {
*/
enum mpcc_alpha_blend_mode alpha_mode;
/***
* @@pre_multiplied_alpha:
*
/**
* @pre_multiplied_alpha:
* Whether pixel color values were pre-multiplied by the alpha channel
* (MPCC_ALPHA_MULTIPLIED_MODE).
*/
@ -129,7 +128,7 @@ struct mpcc_blnd_cfg {
int global_alpha;
/**
* @@overlap_only: Whether overlapping of different planes is allowed.
* @overlap_only: Whether overlapping of different planes is allowed.
*/
bool overlap_only;

View File

@ -170,4 +170,13 @@ IRQ_DCN35 = irq_service_dcn35.o
AMD_DAL_IRQ_DCN35= $(addprefix $(AMDDALPATH)/dc/irq/dcn35/,$(IRQ_DCN35))
AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN35)
AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN35)
###############################################################################
# DCN 351
###############################################################################
IRQ_DCN351 = irq_service_dcn351.o
AMD_DAL_IRQ_DCN351= $(addprefix $(AMDDALPATH)/dc/irq/dcn351/,$(IRQ_DCN351))
AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN351)

View File

@ -0,0 +1,409 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
#include "dm_services.h"
#include "include/logger_interface.h"
#include "../dce110/irq_service_dce110.h"
#include "dcn/dcn_3_5_1_offset.h"
#include "dcn/dcn_3_5_1_sh_mask.h"
#include "irq_service_dcn351.h"
#include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
static enum dc_irq_source to_dal_irq_source_dcn351(
struct irq_service *irq_service,
uint32_t src_id,
uint32_t ext_id)
{
switch (src_id) {
case DCN_1_0__SRCID__DC_D1_OTG_VSTARTUP:
return DC_IRQ_SOURCE_VBLANK1;
case DCN_1_0__SRCID__DC_D2_OTG_VSTARTUP:
return DC_IRQ_SOURCE_VBLANK2;
case DCN_1_0__SRCID__DC_D3_OTG_VSTARTUP:
return DC_IRQ_SOURCE_VBLANK3;
case DCN_1_0__SRCID__DC_D4_OTG_VSTARTUP:
return DC_IRQ_SOURCE_VBLANK4;
case DCN_1_0__SRCID__DC_D5_OTG_VSTARTUP:
return DC_IRQ_SOURCE_VBLANK5;
case DCN_1_0__SRCID__DC_D6_OTG_VSTARTUP:
return DC_IRQ_SOURCE_VBLANK6;
case DCN_1_0__SRCID__OTG1_VERTICAL_INTERRUPT0_CONTROL:
return DC_IRQ_SOURCE_DC1_VLINE0;
case DCN_1_0__SRCID__OTG2_VERTICAL_INTERRUPT0_CONTROL:
return DC_IRQ_SOURCE_DC2_VLINE0;
case DCN_1_0__SRCID__OTG3_VERTICAL_INTERRUPT0_CONTROL:
return DC_IRQ_SOURCE_DC3_VLINE0;
case DCN_1_0__SRCID__OTG4_VERTICAL_INTERRUPT0_CONTROL:
return DC_IRQ_SOURCE_DC4_VLINE0;
case DCN_1_0__SRCID__OTG5_VERTICAL_INTERRUPT0_CONTROL:
return DC_IRQ_SOURCE_DC5_VLINE0;
case DCN_1_0__SRCID__OTG6_VERTICAL_INTERRUPT0_CONTROL:
return DC_IRQ_SOURCE_DC6_VLINE0;
case DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT:
return DC_IRQ_SOURCE_PFLIP1;
case DCN_1_0__SRCID__HUBP1_FLIP_INTERRUPT:
return DC_IRQ_SOURCE_PFLIP2;
case DCN_1_0__SRCID__HUBP2_FLIP_INTERRUPT:
return DC_IRQ_SOURCE_PFLIP3;
case DCN_1_0__SRCID__HUBP3_FLIP_INTERRUPT:
return DC_IRQ_SOURCE_PFLIP4;
case DCN_1_0__SRCID__HUBP4_FLIP_INTERRUPT:
return DC_IRQ_SOURCE_PFLIP5;
case DCN_1_0__SRCID__HUBP5_FLIP_INTERRUPT:
return DC_IRQ_SOURCE_PFLIP6;
case DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
return DC_IRQ_SOURCE_VUPDATE1;
case DCN_1_0__SRCID__OTG1_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
return DC_IRQ_SOURCE_VUPDATE2;
case DCN_1_0__SRCID__OTG2_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
return DC_IRQ_SOURCE_VUPDATE3;
case DCN_1_0__SRCID__OTG3_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
return DC_IRQ_SOURCE_VUPDATE4;
case DCN_1_0__SRCID__OTG4_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
return DC_IRQ_SOURCE_VUPDATE5;
case DCN_1_0__SRCID__OTG5_IHC_V_UPDATE_NO_LOCK_INTERRUPT:
return DC_IRQ_SOURCE_VUPDATE6;
case DCN_1_0__SRCID__DMCUB_OUTBOX_LOW_PRIORITY_READY_INT:
return DC_IRQ_SOURCE_DMCUB_OUTBOX;
case DCN_1_0__SRCID__DC_HPD1_INT:
/* generic src_id for all HPD and HPDRX interrupts */
switch (ext_id) {
case DCN_1_0__CTXID__DC_HPD1_INT:
return DC_IRQ_SOURCE_HPD1;
case DCN_1_0__CTXID__DC_HPD2_INT:
return DC_IRQ_SOURCE_HPD2;
case DCN_1_0__CTXID__DC_HPD3_INT:
return DC_IRQ_SOURCE_HPD3;
case DCN_1_0__CTXID__DC_HPD4_INT:
return DC_IRQ_SOURCE_HPD4;
case DCN_1_0__CTXID__DC_HPD5_INT:
return DC_IRQ_SOURCE_HPD5;
case DCN_1_0__CTXID__DC_HPD6_INT:
return DC_IRQ_SOURCE_HPD6;
case DCN_1_0__CTXID__DC_HPD1_RX_INT:
return DC_IRQ_SOURCE_HPD1RX;
case DCN_1_0__CTXID__DC_HPD2_RX_INT:
return DC_IRQ_SOURCE_HPD2RX;
case DCN_1_0__CTXID__DC_HPD3_RX_INT:
return DC_IRQ_SOURCE_HPD3RX;
case DCN_1_0__CTXID__DC_HPD4_RX_INT:
return DC_IRQ_SOURCE_HPD4RX;
case DCN_1_0__CTXID__DC_HPD5_RX_INT:
return DC_IRQ_SOURCE_HPD5RX;
case DCN_1_0__CTXID__DC_HPD6_RX_INT:
return DC_IRQ_SOURCE_HPD6RX;
default:
return DC_IRQ_SOURCE_INVALID;
}
break;
default:
return DC_IRQ_SOURCE_INVALID;
}
}
static bool hpd_ack(
struct irq_service *irq_service,
const struct irq_source_info *info)
{
uint32_t addr = info->status_reg;
uint32_t value = dm_read_reg(irq_service->ctx, addr);
uint32_t current_status =
get_reg_field_value(
value,
HPD0_DC_HPD_INT_STATUS,
DC_HPD_SENSE_DELAYED);
dal_irq_service_ack_generic(irq_service, info);
value = dm_read_reg(irq_service->ctx, info->enable_reg);
set_reg_field_value(
value,
current_status ? 0 : 1,
HPD0_DC_HPD_INT_CONTROL,
DC_HPD_INT_POLARITY);
dm_write_reg(irq_service->ctx, info->enable_reg, value);
return true;
}
static struct irq_source_info_funcs hpd_irq_info_funcs = {
.set = NULL,
.ack = hpd_ack
};
static struct irq_source_info_funcs hpd_rx_irq_info_funcs = {
.set = NULL,
.ack = NULL
};
static struct irq_source_info_funcs pflip_irq_info_funcs = {
.set = NULL,
.ack = NULL
};
static struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = {
.set = NULL,
.ack = NULL
};
static struct irq_source_info_funcs vblank_irq_info_funcs = {
.set = NULL,
.ack = NULL
};
static struct irq_source_info_funcs outbox_irq_info_funcs = {
.set = NULL,
.ack = NULL
};
static struct irq_source_info_funcs vline0_irq_info_funcs = {
.set = NULL,
.ack = NULL
};
#undef BASE_INNER
#define BASE_INNER(seg) ctx->dcn_reg_offsets[seg]
/* compile time expand base address. */
#define BASE(seg) \
BASE_INNER(seg)
#define SRI(reg_name, block, id)\
BASE(reg ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
reg ## block ## id ## _ ## reg_name
#define SRI_DMUB(reg_name)\
BASE(reg ## reg_name ## _BASE_IDX) + \
reg ## reg_name
#define IRQ_REG_ENTRY(base, block, reg_num, reg1, mask1, reg2, mask2)\
REG_STRUCT[base + reg_num].enable_reg = SRI(reg1, block, reg_num),\
REG_STRUCT[base + reg_num].enable_mask = \
block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\
REG_STRUCT[base + reg_num].enable_value[0] = \
block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK,\
REG_STRUCT[base + reg_num].enable_value[1] = \
~block ## reg_num ## _ ## reg1 ## __ ## mask1 ## _MASK, \
REG_STRUCT[base + reg_num].ack_reg = SRI(reg2, block, reg_num),\
REG_STRUCT[base + reg_num].ack_mask = \
block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK,\
REG_STRUCT[base + reg_num].ack_value = \
block ## reg_num ## _ ## reg2 ## __ ## mask2 ## _MASK \
#define IRQ_REG_ENTRY_DMUB(base, reg1, mask1, reg2, mask2)\
REG_STRUCT[base].enable_reg = SRI_DMUB(reg1),\
REG_STRUCT[base].enable_mask = \
reg1 ## __ ## mask1 ## _MASK,\
REG_STRUCT[base].enable_value[0] = \
reg1 ## __ ## mask1 ## _MASK,\
REG_STRUCT[base].enable_value[1] = \
~reg1 ## __ ## mask1 ## _MASK, \
REG_STRUCT[base].ack_reg = SRI_DMUB(reg2),\
REG_STRUCT[base].ack_mask = \
reg2 ## __ ## mask2 ## _MASK,\
REG_STRUCT[base].ack_value = \
reg2 ## __ ## mask2 ## _MASK \
#define hpd_int_entry(reg_num)\
IRQ_REG_ENTRY(DC_IRQ_SOURCE_HPD1, HPD, reg_num,\
DC_HPD_INT_CONTROL, DC_HPD_INT_EN,\
DC_HPD_INT_CONTROL, DC_HPD_INT_ACK),\
REG_STRUCT[DC_IRQ_SOURCE_HPD1 + reg_num].funcs = &hpd_irq_info_funcs;\
REG_STRUCT[DC_IRQ_SOURCE_HPD1 + reg_num].status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num);\
#define hpd_rx_int_entry(reg_num)\
IRQ_REG_ENTRY(DC_IRQ_SOURCE_HPD1RX, HPD, reg_num,\
DC_HPD_INT_CONTROL, DC_HPD_RX_INT_EN,\
DC_HPD_INT_CONTROL, DC_HPD_RX_INT_ACK),\
REG_STRUCT[DC_IRQ_SOURCE_HPD1RX + reg_num].status_reg = SRI(DC_HPD_INT_STATUS, HPD, reg_num);\
REG_STRUCT[DC_IRQ_SOURCE_HPD1RX + reg_num].funcs = &hpd_rx_irq_info_funcs;\
#define pflip_int_entry(reg_num)\
IRQ_REG_ENTRY(DC_IRQ_SOURCE_PFLIP1, HUBPREQ, reg_num,\
DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_INT_MASK,\
DCSURF_SURFACE_FLIP_INTERRUPT, SURFACE_FLIP_CLEAR),\
REG_STRUCT[DC_IRQ_SOURCE_PFLIP1 + reg_num].funcs = &pflip_irq_info_funcs\
/* vupdate_no_lock_int_entry maps to DC_IRQ_SOURCE_VUPDATEx, to match semantic
* of DCE's DC_IRQ_SOURCE_VUPDATEx.
*/
#define vupdate_no_lock_int_entry(reg_num)\
IRQ_REG_ENTRY(DC_IRQ_SOURCE_VUPDATE1, OTG, reg_num,\
OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_INT_EN,\
OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR),\
REG_STRUCT[DC_IRQ_SOURCE_VUPDATE1 + reg_num].funcs = &vupdate_no_lock_irq_info_funcs\
#define vblank_int_entry(reg_num)\
IRQ_REG_ENTRY(DC_IRQ_SOURCE_VBLANK1, OTG, reg_num,\
OTG_GLOBAL_SYNC_STATUS, VSTARTUP_INT_EN,\
OTG_GLOBAL_SYNC_STATUS, VSTARTUP_EVENT_CLEAR),\
REG_STRUCT[DC_IRQ_SOURCE_VBLANK1 + reg_num].funcs = &vblank_irq_info_funcs\
#define vline0_int_entry(reg_num)\
IRQ_REG_ENTRY(DC_IRQ_SOURCE_DC1_VLINE0, OTG, reg_num,\
OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_INT_ENABLE,\
OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_CLEAR),\
REG_STRUCT[DC_IRQ_SOURCE_DC1_VLINE0 + reg_num].funcs = &vline0_irq_info_funcs\
#define dmub_outbox_int_entry()\
IRQ_REG_ENTRY_DMUB(DC_IRQ_SOURCE_DMCUB_OUTBOX, \
DMCUB_INTERRUPT_ENABLE, DMCUB_OUTBOX1_READY_INT_EN,\
DMCUB_INTERRUPT_ACK, DMCUB_OUTBOX1_READY_INT_ACK),\
REG_STRUCT[DC_IRQ_SOURCE_DMCUB_OUTBOX].funcs = &outbox_irq_info_funcs
#define dummy_irq_entry(irqno) \
REG_STRUCT[irqno].funcs = &dummy_irq_info_funcs\
#define i2c_int_entry(reg_num) \
dummy_irq_entry(DC_IRQ_SOURCE_I2C_DDC ## reg_num)
#define dp_sink_int_entry(reg_num) \
dummy_irq_entry(DC_IRQ_SOURCE_DPSINK ## reg_num)
#define gpio_pad_int_entry(reg_num) \
dummy_irq_entry(DC_IRQ_SOURCE_GPIOPAD ## reg_num)
#define dc_underflow_int_entry(reg_num) \
dummy_irq_entry(DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW)
static struct irq_source_info_funcs dummy_irq_info_funcs = {
.set = dal_irq_service_dummy_set,
.ack = dal_irq_service_dummy_ack
};
#define dcn351_irq_init_part_1() {\
dummy_irq_entry(DC_IRQ_SOURCE_INVALID); \
hpd_int_entry(0); \
hpd_int_entry(1); \
hpd_int_entry(2); \
hpd_int_entry(3); \
hpd_int_entry(4); \
hpd_rx_int_entry(0); \
hpd_rx_int_entry(1); \
hpd_rx_int_entry(2); \
hpd_rx_int_entry(3); \
hpd_rx_int_entry(4); \
i2c_int_entry(1); \
i2c_int_entry(2); \
i2c_int_entry(3); \
i2c_int_entry(4); \
i2c_int_entry(5); \
i2c_int_entry(6); \
dp_sink_int_entry(1); \
dp_sink_int_entry(2); \
dp_sink_int_entry(3); \
dp_sink_int_entry(4); \
dp_sink_int_entry(5); \
dp_sink_int_entry(6); \
dummy_irq_entry(DC_IRQ_SOURCE_TIMER); \
pflip_int_entry(0); \
pflip_int_entry(1); \
pflip_int_entry(2); \
pflip_int_entry(3); \
dummy_irq_entry(DC_IRQ_SOURCE_PFLIP5); \
dummy_irq_entry(DC_IRQ_SOURCE_PFLIP6); \
dummy_irq_entry(DC_IRQ_SOURCE_PFLIP_UNDERLAY0); \
gpio_pad_int_entry(0); \
gpio_pad_int_entry(1); \
gpio_pad_int_entry(2); \
gpio_pad_int_entry(3); \
gpio_pad_int_entry(4); \
gpio_pad_int_entry(5); \
gpio_pad_int_entry(6); \
gpio_pad_int_entry(7); \
gpio_pad_int_entry(8); \
gpio_pad_int_entry(9); \
gpio_pad_int_entry(10); \
gpio_pad_int_entry(11); \
gpio_pad_int_entry(12); \
gpio_pad_int_entry(13); \
gpio_pad_int_entry(14); \
gpio_pad_int_entry(15); \
gpio_pad_int_entry(16); \
gpio_pad_int_entry(17); \
gpio_pad_int_entry(18); \
gpio_pad_int_entry(19); \
gpio_pad_int_entry(20); \
gpio_pad_int_entry(21); \
gpio_pad_int_entry(22); \
gpio_pad_int_entry(23); \
gpio_pad_int_entry(24); \
gpio_pad_int_entry(25); \
gpio_pad_int_entry(26); \
gpio_pad_int_entry(27); \
gpio_pad_int_entry(28); \
gpio_pad_int_entry(29); \
gpio_pad_int_entry(30); \
dc_underflow_int_entry(1); \
dc_underflow_int_entry(2); \
dc_underflow_int_entry(3); \
dc_underflow_int_entry(4); \
dc_underflow_int_entry(5); \
dc_underflow_int_entry(6); \
dummy_irq_entry(DC_IRQ_SOURCE_DMCU_SCP); \
dummy_irq_entry(DC_IRQ_SOURCE_VBIOS_SW); \
}
#define dcn351_irq_init_part_2() {\
vupdate_no_lock_int_entry(0); \
vupdate_no_lock_int_entry(1); \
vupdate_no_lock_int_entry(2); \
vupdate_no_lock_int_entry(3); \
vblank_int_entry(0); \
vblank_int_entry(1); \
vblank_int_entry(2); \
vblank_int_entry(3); \
vline0_int_entry(0); \
vline0_int_entry(1); \
vline0_int_entry(2); \
vline0_int_entry(3); \
dummy_irq_entry(DC_IRQ_SOURCE_DC5_VLINE1); \
dummy_irq_entry(DC_IRQ_SOURCE_DC6_VLINE1); \
dmub_outbox_int_entry(); \
}
#define dcn351_irq_init() {\
dcn351_irq_init_part_1(); \
dcn351_irq_init_part_2(); \
}
static struct irq_source_info irq_source_info_dcn351[DAL_IRQ_SOURCES_NUMBER] = {0};
static struct irq_service_funcs irq_service_funcs_dcn351 = {
.to_dal_irq_source = to_dal_irq_source_dcn351
};
static void dcn351_irq_construct(
struct irq_service *irq_service,
struct irq_service_init_data *init_data)
{
struct dc_context *ctx = init_data->ctx;
#define REG_STRUCT irq_source_info_dcn351
dcn351_irq_init();
dal_irq_service_construct(irq_service, init_data);
irq_service->info = irq_source_info_dcn351;
irq_service->funcs = &irq_service_funcs_dcn351;
}
struct irq_service *dal_irq_service_dcn351_create(
struct irq_service_init_data *init_data)
{
struct irq_service *irq_service = kzalloc(sizeof(*irq_service),
GFP_KERNEL);
if (!irq_service)
return NULL;
dcn351_irq_construct(irq_service, init_data);
return irq_service;
}

View File

@ -0,0 +1,12 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2021 Advanced Micro Devices, Inc. */
#ifndef __DAL_IRQ_SERVICE_DCN351_H__
#define __DAL_IRQ_SERVICE_DCN351_H__
#include "../irq_service.h"
struct irq_service *dal_irq_service_dcn351_create(
struct irq_service_init_data *init_data);
#endif /* __DAL_IRQ_SERVICE_DCN351_H__ */

View File

@ -194,6 +194,14 @@ AMD_DISPLAY_FILES += $(AMD_DAL_RESOURCE_DCN35)
###############################################################################
RESOURCE_DCN351 = dcn351_resource.o
AMD_DAL_RESOURCE_DCN351 = $(addprefix $(AMDDALPATH)/dc/resource/dcn351/,$(RESOURCE_DCN351))
AMD_DISPLAY_FILES += $(AMD_DAL_RESOURCE_DCN351)
###############################################################################
###############################################################################
endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
#ifndef _DCN351_RESOURCE_H_
#define _DCN351_RESOURCE_H_
#include "core_types.h"
extern struct _vcs_dpi_ip_params_st dcn3_51_ip;
extern struct _vcs_dpi_soc_bounding_box_st dcn3_51_soc;
#define TO_DCN351_RES_POOL(pool)\
container_of(pool, struct dcn351_resource_pool, base)
struct dcn351_resource_pool {
struct resource_pool base;
};
struct resource_pool *dcn351_create_resource_pool(
const struct dc_init_data *init_data,
struct dc *dc);
#endif /* _DCN351_RESOURCE_H_ */

View File

@ -112,6 +112,7 @@ enum dmub_asic {
DMUB_ASIC_DCN32,
DMUB_ASIC_DCN321,
DMUB_ASIC_DCN35,
DMUB_ASIC_DCN351,
DMUB_ASIC_MAX,
};

View File

@ -25,6 +25,7 @@ DMUB += dmub_dcn30.o dmub_dcn301.o dmub_dcn302.o dmub_dcn303.o
DMUB += dmub_dcn31.o dmub_dcn314.o dmub_dcn315.o dmub_dcn316.o
DMUB += dmub_dcn32.o
DMUB += dmub_dcn35.o
DMUB += dmub_dcn351.o
AMD_DAL_DMUB = $(addprefix $(AMDDALPATH)/dmub/src/,$(DMUB))

View File

@ -0,0 +1,34 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
#include "../dmub_srv.h"
#include "dmub_reg.h"
#include "dmub_dcn351.h"
#include "dcn/dcn_3_5_1_offset.h"
#include "dcn/dcn_3_5_1_sh_mask.h"
#define BASE_INNER(seg) ctx->dcn_reg_offsets[seg]
#define CTX dmub
#define REGS dmub->regs_dcn35
#define REG_OFFSET_EXP(reg_name) BASE(reg##reg_name##_BASE_IDX) + reg##reg_name
void dmub_srv_dcn351_regs_init(struct dmub_srv *dmub, struct dc_context *ctx)
{
struct dmub_srv_dcn35_regs *regs = dmub->regs_dcn35;
#define REG_STRUCT regs
#define DMUB_SR(reg) REG_STRUCT->offset.reg = REG_OFFSET_EXP(reg);
DMUB_DCN35_REGS()
DMCUB_INTERNAL_REGS()
#undef DMUB_SR
#define DMUB_SF(reg, field) REG_STRUCT->mask.reg##__##field = FD_MASK(reg, field);
DMUB_DCN35_FIELDS()
#undef DMUB_SF
#define DMUB_SF(reg, field) REG_STRUCT->shift.reg##__##field = FD_SHIFT(reg, field);
DMUB_DCN35_FIELDS()
#undef DMUB_SF
#undef REG_STRUCT
}

View File

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: MIT */
/* Copyright 2024 Advanced Micro Devices, Inc. */
#ifndef _DMUB_DCN351_H_
#define _DMUB_DCN351_H_
#include "dmub_dcn35.h"
struct dmub_srv;
void dmub_srv_dcn351_regs_init(struct dmub_srv *dmub, struct dc_context *ctx);
#endif /* _DMUB_DCN351_H_ */

View File

@ -37,6 +37,7 @@
#include "dmub_dcn316.h"
#include "dmub_dcn32.h"
#include "dmub_dcn35.h"
#include "dmub_dcn351.h"
#include "os_types.h"
/*
* Note: the DMUB service is standalone. No additional headers should be
@ -315,6 +316,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
break;
case DMUB_ASIC_DCN35:
case DMUB_ASIC_DCN351:
dmub->regs_dcn35 = &dmub_srv_dcn35_regs;
funcs->configure_dmub_in_system_memory = dmub_dcn35_configure_dmub_in_system_memory;
funcs->send_inbox0_cmd = dmub_dcn35_send_inbox0_cmd;
@ -351,6 +353,8 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
funcs->get_diagnostic_data = dmub_dcn35_get_diagnostic_data;
funcs->init_reg_offsets = dmub_srv_dcn35_regs_init;
if (asic == DMUB_ASIC_DCN351)
funcs->init_reg_offsets = dmub_srv_dcn351_regs_init;
funcs->is_hw_powered_up = dmub_dcn35_is_hw_powered_up;
funcs->should_detect = dmub_dcn35_should_detect;

View File

@ -250,11 +250,13 @@ enum {
#define GC_11_0_0_A0 0x1
#define GC_11_0_2_A0 0x10
#define GC_11_0_3_A0 0x20
#define GC_11_0_4_A0 0xC0
#define GC_11_UNKNOWN 0xFF
#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)
/*
* ASIC chip ID

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,630 @@
/*
* Copyright 2023 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef _pcie_6_1_0_OFFSET_HEADER
#define _pcie_6_1_0_OFFSET_HEADER
// addressBlock: pcie_container_pcs0_pcie_lcu_pcie_pcs_prime_pcie_master_x1_xx16_pcs_prime_dir
// base address: 0x11a08000
#define regDXIO_HWDID 0x2270800
#define regDXIO_HWDID_BASE_IDX 0
#define regDXIO_LINKAGE_LANEGRP 0x2270802
#define regDXIO_LINKAGE_LANEGRP_BASE_IDX 0
#define regDXIO_LINKAGE_KPDMX 0x2270803
#define regDXIO_LINKAGE_KPDMX_BASE_IDX 0
#define regDXIO_LINKAGE_KPMX 0x2270804
#define regDXIO_LINKAGE_KPFIFO 0x2270805
#define regDXIO_LINKAGE_KPNP 0x2270806
#define regMAC_CAPABILITIES1 0x2270814
#define regMAC_CAPABILITIES1_BASE_IDX 0
#define regMAC_CAPABILITIES2 0x2270815
#define regMAC_CAPABILITIES2_BASE_IDX 0
// addressBlock: pcie_container_pcie0_pswuscfg0_cfgdecp
// base address: 0x1a300000
#define regCOMMAND 0x0001
#define regCOMMAND_BASE_IDX 1
#define regSTATUS 0x0001
#define regSTATUS_BASE_IDX 1
#define regLATENCY 0x0003
#define regLATENCY_BASE_IDX 1
#define regHEADER 0x0003
#define regHEADER_BASE_IDX 1
#define regPCIE_LANE_ERROR_STATUS 0x009e
#define regPCIE_LANE_ERROR_STATUS_BASE_IDX 1
#define regPCIE_LANE_0_EQUALIZATION_CNTL 0x009f
#define regPCIE_LANE_0_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_1_EQUALIZATION_CNTL 0x009f
#define regPCIE_LANE_1_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_2_EQUALIZATION_CNTL 0x00a0
#define regPCIE_LANE_2_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_3_EQUALIZATION_CNTL 0x00a0
#define regPCIE_LANE_3_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_4_EQUALIZATION_CNTL 0x00a1
#define regPCIE_LANE_4_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_5_EQUALIZATION_CNTL 0x00a1
#define regPCIE_LANE_5_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_6_EQUALIZATION_CNTL 0x00a2
#define regPCIE_LANE_6_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_7_EQUALIZATION_CNTL 0x00a2
#define regPCIE_LANE_7_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_8_EQUALIZATION_CNTL 0x00a3
#define regPCIE_LANE_8_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_9_EQUALIZATION_CNTL 0x00a3
#define regPCIE_LANE_9_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_10_EQUALIZATION_CNTL 0x00a4
#define regPCIE_LANE_10_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_11_EQUALIZATION_CNTL 0x00a4
#define regPCIE_LANE_11_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_12_EQUALIZATION_CNTL 0x00a5
#define regPCIE_LANE_12_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_13_EQUALIZATION_CNTL 0x00a5
#define regPCIE_LANE_13_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_14_EQUALIZATION_CNTL 0x00a6
#define regPCIE_LANE_14_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LANE_15_EQUALIZATION_CNTL 0x00a6
#define regPCIE_LANE_15_EQUALIZATION_CNTL_BASE_IDX 1
#define regPCIE_LTR_ENH_CAP_LIST 0x00c8
#define regPCIE_LTR_ENH_CAP_LIST_BASE_IDX 1
#define regPCIE_LTR_CAP 0x00c9
#define regPCIE_LTR_CAP_BASE_IDX 1
#define regPCIE_L1_PM_SUB_CAP_LIST 0x00dc
#define regPCIE_L1_PM_SUB_CAP_LIST_BASE_IDX 1
#define regPCIE_L1_PM_SUB_CAP 0x00dd
#define regPCIE_L1_PM_SUB_CAP_BASE_IDX 1
#define regPCIE_L1_PM_SUB_CNTL 0x00de
#define regPCIE_L1_PM_SUB_CNTL_BASE_IDX 1
#define regPCIE_L1_PM_SUB_CNTL2 0x00df
#define regPCIE_L1_PM_SUB_CNTL2_BASE_IDX 1
#define regPCIE_MARGINING_ENH_CAP_LIST 0x0110
#define regPCIE_MARGINING_ENH_CAP_LIST_BASE_IDX 1
// addressBlock: pcie_container_pcie0_pswusp0_pciedir_p
// base address: 0x1a340000
#define regPCIEP_RESERVED 0x10000
#define regPCIEP_RESERVED_BASE_IDX 1
#define regPCIEP_SCRATCH 0x10001
#define regPCIEP_SCRATCH_BASE_IDX 1
#define regPCIEP_PORT_CNTL 0x10010
#define regPCIEP_PORT_CNTL_BASE_IDX 1
#define regPCIE_TX_REQUESTER_ID 0x10021
#define regPCIE_TX_REQUESTER_ID_BASE_IDX 1
#define regPCIE_P_PORT_LANE_STATUS 0x10050
#define regPCIE_P_PORT_LANE_STATUS_BASE_IDX 1
#define regPCIE_ERR_CNTL 0x1006a
#define regPCIE_ERR_CNTL_BASE_IDX 1
#define regPCIE_RX_CNTL 0x10070
#define regPCIE_RX_CNTL_BASE_IDX 1
#define regPCIE_RX_EXPECTED_SEQNUM 0x10071
#define regPCIE_RX_EXPECTED_SEQNUM_BASE_IDX 1
#define regPCIE_RX_VENDOR_SPECIFIC 0x10072
#define regPCIE_RX_VENDOR_SPECIFIC_BASE_IDX 1
#define regPCIE_RX_CNTL3 0x10074
#define regPCIE_RX_CNTL3_BASE_IDX 1
#define regPCIE_RX_CREDITS_ALLOCATED_P 0x10080
#define regPCIE_RX_CREDITS_ALLOCATED_P_BASE_IDX 1
#define regPCIE_RX_CREDITS_ALLOCATED_NP 0x10081
#define regPCIE_RX_CREDITS_ALLOCATED_NP_BASE_IDX 1
#define regPCIE_RX_CREDITS_ALLOCATED_CPL 0x10082
#define regPCIE_RX_CREDITS_ALLOCATED_CPL_BASE_IDX 1
#define regPCIEP_ERROR_INJECT_PHYSICAL 0x10083
#define regPCIEP_ERROR_INJECT_PHYSICAL_BASE_IDX 1
#define regPCIEP_ERROR_INJECT_TRANSACTION 0x10084
#define regPCIEP_ERROR_INJECT_TRANSACTION_BASE_IDX 1
#define regPCIEP_NAK_COUNTER 0x10086
#define regPCIEP_NAK_COUNTER_BASE_IDX 1
#define regPCIE_LC_CNTL 0x100a0
#define regPCIE_LC_CNTL_BASE_IDX 1
#define regPCIE_LC_TRAINING_CNTL 0x100a1
#define regPCIE_LC_TRAINING_CNTL_BASE_IDX 1
#define regPCIE_LC_LINK_WIDTH_CNTL 0x100a2
#define regPCIE_LC_LINK_WIDTH_CNTL_BASE_IDX 1
#define regPCIE_LC_N_FTS_CNTL 0x100a3
#define regPCIE_LC_N_FTS_CNTL_BASE_IDX 1
#define regPCIE_LC_SPEED_CNTL 0x100a4
#define regPCIE_LC_SPEED_CNTL_BASE_IDX 1
#define regPCIE_LC_STATE0 0x100a5
#define regPCIE_LC_STATE0_BASE_IDX 1
#define regPCIE_LC_STATE1 0x100a6
#define regPCIE_LC_STATE1_BASE_IDX 1
#define regPCIE_LC_STATE2 0x100a7
#define regPCIE_LC_STATE2_BASE_IDX 1
#define regPCIE_LC_STATE3 0x100a8
#define regPCIE_LC_STATE3_BASE_IDX 1
#define regPCIE_LC_STATE4 0x100a9
#define regPCIE_LC_STATE4_BASE_IDX 1
#define regPCIE_LC_STATE5 0x100aa
#define regPCIE_LC_STATE5_BASE_IDX 1
#define regPCIE_LC_LINK_MANAGEMENT_CNTL2 0x100ab
#define regPCIE_LC_LINK_MANAGEMENT_CNTL2_BASE_IDX 1
#define regPCIE_LC_CNTL2 0x100b1
#define regPCIE_LC_CNTL2_BASE_IDX 1
#define regPCIE_LC_BW_CHANGE_CNTL 0x100b2
#define regPCIE_LC_BW_CHANGE_CNTL_BASE_IDX 1
#define regPCIE_LC_CDR_CNTL 0x100b3
#define regPCIE_LC_CDR_CNTL_BASE_IDX 1
#define regPCIE_LC_LANE_CNTL 0x100b4
#define regPCIE_LC_LANE_CNTL_BASE_IDX 1
#define regPCIE_LC_CNTL3 0x100b5
#define regPCIE_LC_CNTL3_BASE_IDX 1
#define regPCIE_LC_CNTL4 0x100b6
#define regPCIE_LC_CNTL4_BASE_IDX 1
#define regPCIE_LC_CNTL5 0x100b7
#define regPCIE_LC_CNTL5_BASE_IDX 1
#define regPCIE_LC_FORCE_COEFF 0x100b8
#define regPCIE_LC_FORCE_COEFF_BASE_IDX 1
#define regPCIE_LC_BEST_EQ_SETTINGS 0x100b9
#define regPCIE_LC_BEST_EQ_SETTINGS_BASE_IDX 1
#define regPCIE_LC_FORCE_EQ_REQ_COEFF 0x100ba
#define regPCIE_LC_FORCE_EQ_REQ_COEFF_BASE_IDX 1
#define regPCIE_LC_CNTL6 0x100bb
#define regPCIE_LC_CNTL6_BASE_IDX 1
#define regPCIE_LC_CNTL7 0x100bc
#define regPCIE_LC_CNTL7_BASE_IDX 1
#define regPCIE_LC_LINK_MANAGEMENT_STATUS 0x100bd
#define regPCIE_LC_LINK_MANAGEMENT_STATUS_BASE_IDX 1
#define regPCIE_LC_LINK_MANAGEMENT_MASK 0x100be
#define regPCIE_LC_LINK_MANAGEMENT_MASK_BASE_IDX 1
#define regPCIE_LC_LINK_MANAGEMENT_CNTL 0x100bf
#define regPCIE_LC_LINK_MANAGEMENT_CNTL_BASE_IDX 1
#define regPCIEP_STRAP_LC 0x100c0
#define regPCIEP_STRAP_LC_BASE_IDX 1
#define regPCIEP_STRAP_MISC 0x100c1
#define regPCIEP_STRAP_MISC_BASE_IDX 1
#define regPCIEP_STRAP_LC2 0x100c2
#define regPCIEP_STRAP_LC2_BASE_IDX 1
#define regPCIE_LC_L1_PM_SUBSTATE 0x100c6
#define regPCIE_LC_L1_PM_SUBSTATE_BASE_IDX 1
#define regPCIE_LC_L1_PM_SUBSTATE2 0x100c7
#define regPCIE_LC_L1_PM_SUBSTATE2_BASE_IDX 1
#define regPCIE_LC_L1_PM_SUBSTATE3 0x100c8
#define regPCIE_LC_L1_PM_SUBSTATE3_BASE_IDX 1
#define regPCIE_LC_L1_PM_SUBSTATE4 0x100c9
#define regPCIE_LC_L1_PM_SUBSTATE4_BASE_IDX 1
#define regPCIE_LC_L1_PM_SUBSTATE5 0x100ca
#define regPCIE_LC_L1_PM_SUBSTATE5_BASE_IDX 1
#define regPCIEP_BCH_ECC_CNTL 0x100d0
#define regPCIEP_BCH_ECC_CNTL_BASE_IDX 1
#define regPCIE_LC_CNTL8 0x100dd
#define regPCIE_LC_CNTL8_BASE_IDX 1
#define regPCIE_LC_CNTL9 0x100de
#define regPCIE_LC_CNTL9_BASE_IDX 1
#define regPCIE_LC_FORCE_COEFF2 0x100df
#define regPCIE_LC_FORCE_COEFF2_BASE_IDX 1
#define regPCIE_LC_FORCE_EQ_REQ_COEFF2 0x100e0
#define regPCIE_LC_FORCE_EQ_REQ_COEFF2_BASE_IDX 1
#define regPCIE_LC_FINE_GRAIN_CLK_GATE_OVERRIDES 0x100e2
#define regPCIE_LC_FINE_GRAIN_CLK_GATE_OVERRIDES_BASE_IDX 1
#define regPCIE_LC_CNTL10 0x100e3
#define regPCIE_LC_CNTL10_BASE_IDX 1
#define regPCIE_LC_EQ_CNTL_8GT 0x100e4
#define regPCIE_LC_EQ_CNTL_8GT_BASE_IDX 1
#define regPCIE_LC_EQ_CNTL_16GT 0x100e5
#define regPCIE_LC_EQ_CNTL_16GT_BASE_IDX 1
#define regPCIE_LC_SAVE_RESTORE_1 0x100e6
#define regPCIE_LC_SAVE_RESTORE_1_BASE_IDX 1
#define regPCIE_LC_SAVE_RESTORE_2 0x100e7
#define regPCIE_LC_SAVE_RESTORE_2_BASE_IDX 1
#define regPCIE_LC_SAVE_RESTORE_3 0x100e8
#define regPCIE_LC_SAVE_RESTORE_3_BASE_IDX 1
#define regPCIE_LC_EQ_CNTL_32GT 0x10100
#define regPCIE_LC_EQ_CNTL_32GT_BASE_IDX 1
#define regPCIE_LC_PRESET_MASK_CNTL 0x10101
#define regPCIE_LC_PRESET_MASK_CNTL_BASE_IDX 1
#define regPCIE_LC_RXRECOVER_RXSTANDBY_CNTL 0x10102
#define regPCIE_LC_RXRECOVER_RXSTANDBY_CNTL_BASE_IDX 1
#define regPCIE_LC_CNTL11 0x10103
#define regPCIE_LC_CNTL11_BASE_IDX 1
#define regPCIE_LC_CNTL12 0x10104
#define regPCIE_LC_CNTL12_BASE_IDX 1
#define regPCIE_LC_SPEED_CNTL2 0x10105
#define regPCIE_LC_SPEED_CNTL2_BASE_IDX 1
#define regPCIE_LC_FORCE_COEFF3 0x10106
#define regPCIE_LC_FORCE_COEFF3_BASE_IDX 1
#define regPCIE_LC_FORCE_EQ_REQ_COEFF3 0x10107
#define regPCIE_LC_FORCE_EQ_REQ_COEFF3_BASE_IDX 1
#define regPCIE_LC_LINK_MANAGEMENT_CNTL3 0x10108
#define regPCIE_LC_LINK_MANAGEMENT_CNTL3_BASE_IDX 1
#define regPCIE_LC_Z10_IDLE_CNTL 0x1010f
#define regPCIE_LC_Z10_IDLE_CNTL_BASE_IDX 1
#define regPCIE_LC_TRANMIT_FIFO_CDC_CNTL 0x1011a
#define regPCIE_LC_TRANMIT_FIFO_CDC_CNTL_BASE_IDX 1
#define regPCIE_LC_CNTL13 0x1011c
#define regPCIE_LC_CNTL13_BASE_IDX 1
#define regPCIE_LC_SWDS_CNTL 0x1011d
#define regPCIE_LC_SWDS_CNTL_BASE_IDX 1
#define regPCIE_TX_SEQ 0x10188
#define regPCIE_TX_SEQ_BASE_IDX 1
#define regPCIE_TX_REPLAY 0x10189
#define regPCIE_TX_REPLAY_BASE_IDX 1
#define regPCIE_TX_ACK_LATENCY_LIMIT 0x1018c
#define regPCIE_TX_ACK_LATENCY_LIMIT_BASE_IDX 1
#define regPCIE_TX_CREDITS_FCU_THRESHOLD 0x10190
#define regPCIE_TX_CREDITS_FCU_THRESHOLD_BASE_IDX 1
#define regPCIE_TX_VENDOR_SPECIFIC 0x10194
#define regPCIE_TX_VENDOR_SPECIFIC_BASE_IDX 1
#define regPCIE_TX_NOP_DLLP 0x10195
#define regPCIE_TX_NOP_DLLP_BASE_IDX 1
#define regPCIE_TX_REQUEST_NUM_CNTL 0x10198
#define regPCIE_TX_REQUEST_NUM_CNTL_BASE_IDX 1
#define regPCIE_TX_CREDITS_ADVT_P 0x101a0
#define regPCIE_TX_CREDITS_ADVT_P_BASE_IDX 1
#define regPCIE_TX_CREDITS_ADVT_NP 0x101a1
#define regPCIE_TX_CREDITS_ADVT_NP_BASE_IDX 1
#define regPCIE_TX_CREDITS_ADVT_CPL 0x101a2
#define regPCIE_TX_CREDITS_ADVT_CPL_BASE_IDX 1
#define regPCIE_TX_CREDITS_INIT_P 0x101a3
#define regPCIE_TX_CREDITS_INIT_P_BASE_IDX 1
#define regPCIE_TX_CREDITS_INIT_NP 0x101a4
#define regPCIE_TX_CREDITS_INIT_NP_BASE_IDX 1
#define regPCIE_TX_CREDITS_INIT_CPL 0x101a5
#define regPCIE_TX_CREDITS_INIT_CPL_BASE_IDX 1
#define regPCIE_TX_CREDITS_STATUS 0x101a6
#define regPCIE_TX_CREDITS_STATUS_BASE_IDX 1
#define regPCIE_FC_P 0x101a8
#define regPCIE_FC_P_BASE_IDX 1
#define regPCIE_FC_NP 0x101a9
#define regPCIE_FC_NP_BASE_IDX 1
#define regPCIE_FC_CPL 0x101aa
#define regPCIE_FC_CPL_BASE_IDX 1
#define regPCIE_FC_P_VC1 0x101ab
#define regPCIE_FC_P_VC1_BASE_IDX 1
#define regPCIE_FC_NP_VC1 0x101ac
#define regPCIE_FC_NP_VC1_BASE_IDX 1
#define regPCIE_FC_CPL_VC1 0x101ad
#define regPCIE_FC_CPL_VC1_BASE_IDX 1
// addressBlock: pcie_container_pcie0_pciedir
// base address: 0x1a380000
#define regPCIE_RESERVED 0x20000
#define regPCIE_RESERVED_BASE_IDX 1
#define regPCIE_SCRATCH 0x20001
#define regPCIE_SCRATCH_BASE_IDX 1
#define regPCIE_RX_NUM_NAK 0x2000e
#define regPCIE_RX_NUM_NAK_BASE_IDX 1
#define regPCIE_RX_NUM_NAK_GENERATED 0x2000f
#define regPCIE_RX_NUM_NAK_GENERATED_BASE_IDX 1
#define regPCIE_CNTL 0x20010
#define regPCIE_CNTL_BASE_IDX 1
#define regPCIE_CONFIG_CNTL 0x20011
#define regPCIE_CONFIG_CNTL_BASE_IDX 1
#define regPCIE_DEBUG_CNTL 0x20012
#define regPCIE_DEBUG_CNTL_BASE_IDX 1
#define regPCIE_RX_CNTL5 0x20018
#define regPCIE_RX_CNTL5_BASE_IDX 1
#define regPCIE_RX_CNTL4 0x20019
#define regPCIE_RX_CNTL4_BASE_IDX 1
#define regPCIE_COMMON_AER_MASK 0x2001a
#define regPCIE_COMMON_AER_MASK_BASE_IDX 1
#define regPCIE_CNTL2 0x2001c
#define regPCIE_CNTL2_BASE_IDX 1
#define regPCIE_RX_CNTL2 0x2001d
#define regPCIE_RX_CNTL2_BASE_IDX 1
#define regPCIE_CI_CNTL 0x20020
#define regPCIE_CI_CNTL_BASE_IDX 1
#define regPCIE_BUS_CNTL 0x20021
#define regPCIE_BUS_CNTL_BASE_IDX 1
#define regPCIE_LC_STATE6 0x20022
#define regPCIE_LC_STATE6_BASE_IDX 1
#define regPCIE_LC_STATE7 0x20023
#define regPCIE_LC_STATE7_BASE_IDX 1
#define regPCIE_LC_STATE8 0x20024
#define regPCIE_LC_STATE8_BASE_IDX 1
#define regPCIE_LC_STATE9 0x20025
#define regPCIE_LC_STATE9_BASE_IDX 1
#define regPCIE_LC_STATE10 0x20026
#define regPCIE_LC_STATE10_BASE_IDX 1
#define regPCIE_LC_STATE11 0x20027
#define regPCIE_LC_STATE11_BASE_IDX 1
#define regPCIE_LC_STATUS1 0x20028
#define regPCIE_LC_STATUS1_BASE_IDX 1
#define regPCIE_LC_STATUS2 0x20029
#define regPCIE_LC_STATUS2_BASE_IDX 1
#define regPCIE_WPR_CNTL 0x20030
#define regPCIE_WPR_CNTL_BASE_IDX 1
#define regPCIE_RX_LAST_TLP0 0x20031
#define regPCIE_RX_LAST_TLP0_BASE_IDX 1
#define regPCIE_RX_LAST_TLP1 0x20032
#define regPCIE_RX_LAST_TLP1_BASE_IDX 1
#define regPCIE_RX_LAST_TLP2 0x20033
#define regPCIE_RX_LAST_TLP2_BASE_IDX 1
#define regPCIE_RX_LAST_TLP3 0x20034
#define regPCIE_RX_LAST_TLP3_BASE_IDX 1
#define regPCIE_I2C_REG_ADDR_EXPAND 0x2003a
#define regPCIE_I2C_REG_ADDR_EXPAND_BASE_IDX 1
#define regPCIE_I2C_REG_DATA 0x2003b
#define regPCIE_I2C_REG_DATA_BASE_IDX 1
#define regPCIE_CFG_CNTL 0x2003c
#define regPCIE_CFG_CNTL_BASE_IDX 1
#define regPCIE_LC_PM_CNTL 0x2003d
#define regPCIE_LC_PM_CNTL_BASE_IDX 1
#define regPCIE_LC_PM_CNTL2 0x2003e
#define regPCIE_LC_PM_CNTL2_BASE_IDX 1
#define regPCIE_LC_STRAP_BUFF_CNTL 0x2003f
#define regPCIE_LC_STRAP_BUFF_CNTL_BASE_IDX 1
#define regPCIE_P_CNTL 0x20040
#define regPCIE_P_CNTL_BASE_IDX 1
#define regPCIE_P_BUF_STATUS 0x20041
#define regPCIE_P_BUF_STATUS_BASE_IDX 1
#define regPCIE_P_DECODER_STATUS 0x20042
#define regPCIE_P_DECODER_STATUS_BASE_IDX 1
#define regPCIE_P_MISC_STATUS 0x20043
#define regPCIE_P_MISC_STATUS_BASE_IDX 1
#define regPCIE_P_RCV_L0S_FTS_DET 0x20050
#define regPCIE_P_RCV_L0S_FTS_DET_BASE_IDX 1
#define regPCIE_RX_AD 0x20062
#define regPCIE_RX_AD_BASE_IDX 1
#define regPCIE_SDP_CTRL 0x20063
#define regPCIE_SDP_CTRL_BASE_IDX 1
#define regPCIE_SDP_SWUS_SLV_ATTR_CTRL 0x20065
#define regPCIE_SDP_SWUS_SLV_ATTR_CTRL_BASE_IDX 1
#define regPCIE_SDP_CTRL2 0x20068
#define regPCIE_SDP_CTRL2_BASE_IDX 1
#define regPCIE_PERF_COUNT_CNTL 0x20080
#define regPCIE_PERF_COUNT_CNTL_BASE_IDX 1
#define regPCIE_PERF_CNTL_TXCLK1 0x20081
#define regPCIE_PERF_CNTL_TXCLK1_BASE_IDX 1
#define regPCIE_PERF_COUNT0_TXCLK1 0x20082
#define regPCIE_PERF_COUNT0_TXCLK1_BASE_IDX 1
#define regPCIE_PERF_COUNT1_TXCLK1 0x20083
#define regPCIE_PERF_COUNT1_TXCLK1_BASE_IDX 1
#define regPCIE_PERF_CNTL_TXCLK2 0x20084
#define regPCIE_PERF_CNTL_TXCLK2_BASE_IDX 1
#define regPCIE_PERF_COUNT0_TXCLK2 0x20085
#define regPCIE_PERF_COUNT0_TXCLK2_BASE_IDX 1
#define regPCIE_PERF_COUNT1_TXCLK2 0x20086
#define regPCIE_PERF_COUNT1_TXCLK2_BASE_IDX 1
#define regPCIE_PERF_CNTL_TXCLK3 0x20087
#define regPCIE_PERF_CNTL_TXCLK3_BASE_IDX 1
#define regPCIE_PERF_COUNT0_TXCLK3 0x20088
#define regPCIE_PERF_COUNT0_TXCLK3_BASE_IDX 1
#define regPCIE_PERF_COUNT1_TXCLK3 0x20089
#define regPCIE_PERF_COUNT1_TXCLK3_BASE_IDX 1
#define regPCIE_PERF_CNTL_TXCLK4 0x2008a
#define regPCIE_PERF_CNTL_TXCLK4_BASE_IDX 1
#define regPCIE_PERF_COUNT0_TXCLK4 0x2008b
#define regPCIE_PERF_COUNT0_TXCLK4_BASE_IDX 1
#define regPCIE_PERF_COUNT1_TXCLK4 0x2008c
#define regPCIE_PERF_COUNT1_TXCLK4_BASE_IDX 1
#define regPCIE_PERF_CNTL_EVENT_LC_PORT_SEL 0x20093
#define regPCIE_PERF_CNTL_EVENT_LC_PORT_SEL_BASE_IDX 1
#define regPCIE_PERF_CNTL_EVENT_CI_PORT_SEL 0x20094
#define regPCIE_PERF_CNTL_EVENT_CI_PORT_SEL_BASE_IDX 1
#define regPCIE_PERF_CNTL_TXCLK5 0x20096
#define regPCIE_PERF_CNTL_TXCLK5_BASE_IDX 1
#define regPCIE_PERF_COUNT0_TXCLK5 0x20097
#define regPCIE_PERF_COUNT0_TXCLK5_BASE_IDX 1
#define regPCIE_PERF_COUNT1_TXCLK5 0x20098
#define regPCIE_PERF_COUNT1_TXCLK5_BASE_IDX 1
#define regPCIE_PERF_CNTL_TXCLK6 0x20099
#define regPCIE_PERF_CNTL_TXCLK6_BASE_IDX 1
#define regPCIE_PERF_COUNT0_TXCLK6 0x2009a
#define regPCIE_PERF_COUNT0_TXCLK6_BASE_IDX 1
#define regPCIE_PERF_COUNT1_TXCLK6 0x2009b
#define regPCIE_PERF_COUNT1_TXCLK6_BASE_IDX 1
#define regPCIE_STRAP_F0 0x200b0
#define regPCIE_STRAP_F0_BASE_IDX 1
#define regPCIE_STRAP_MISC 0x200c0
#define regPCIE_STRAP_MISC_BASE_IDX 1
#define regPCIE_STRAP_MISC2 0x200c1
#define regPCIE_STRAP_MISC2_BASE_IDX 1
#define regPCIE_STRAP_PI 0x200c2
#define regPCIE_STRAP_PI_BASE_IDX 1
#define regPCIE_STRAP_I2C_BD 0x200c4
#define regPCIE_STRAP_I2C_BD_BASE_IDX 1
#define regPCIE_PRBS_CLR 0x200c8
#define regPCIE_PRBS_CLR_BASE_IDX 1
#define regPCIE_PRBS_STATUS1 0x200c9
#define regPCIE_PRBS_STATUS1_BASE_IDX 1
#define regPCIE_PRBS_STATUS2 0x200ca
#define regPCIE_PRBS_STATUS2_BASE_IDX 1
#define regPCIE_PRBS_FREERUN 0x200cb
#define regPCIE_PRBS_FREERUN_BASE_IDX 1
#define regPCIE_PRBS_MISC 0x200cc
#define regPCIE_PRBS_MISC_BASE_IDX 1
#define regPCIE_PRBS_USER_PATTERN 0x200cd
#define regPCIE_PRBS_USER_PATTERN_BASE_IDX 1
#define regPCIE_PRBS_LO_BITCNT 0x200ce
#define regPCIE_PRBS_LO_BITCNT_BASE_IDX 1
#define regPCIE_PRBS_HI_BITCNT 0x200cf
#define regPCIE_PRBS_HI_BITCNT_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_0 0x200d0
#define regPCIE_PRBS_ERRCNT_0_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_1 0x200d1
#define regPCIE_PRBS_ERRCNT_1_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_2 0x200d2
#define regPCIE_PRBS_ERRCNT_2_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_3 0x200d3
#define regPCIE_PRBS_ERRCNT_3_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_4 0x200d4
#define regPCIE_PRBS_ERRCNT_4_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_5 0x200d5
#define regPCIE_PRBS_ERRCNT_5_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_6 0x200d6
#define regPCIE_PRBS_ERRCNT_6_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_7 0x200d7
#define regPCIE_PRBS_ERRCNT_7_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_8 0x200d8
#define regPCIE_PRBS_ERRCNT_8_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_9 0x200d9
#define regPCIE_PRBS_ERRCNT_9_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_10 0x200da
#define regPCIE_PRBS_ERRCNT_10_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_11 0x200db
#define regPCIE_PRBS_ERRCNT_11_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_12 0x200dc
#define regPCIE_PRBS_ERRCNT_12_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_13 0x200dd
#define regPCIE_PRBS_ERRCNT_13_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_14 0x200de
#define regPCIE_PRBS_ERRCNT_14_BASE_IDX 1
#define regPCIE_PRBS_ERRCNT_15 0x200df
#define regPCIE_PRBS_ERRCNT_15_BASE_IDX 1
#define regSWRST_COMMAND_STATUS 0x20100
#define regSWRST_COMMAND_STATUS_BASE_IDX 1
#define regSWRST_GENERAL_CONTROL 0x20101
#define regSWRST_GENERAL_CONTROL_BASE_IDX 1
#define regSWRST_COMMAND_0 0x20102
#define regSWRST_COMMAND_0_BASE_IDX 1
#define regSWRST_COMMAND_1 0x20103
#define regSWRST_COMMAND_1_BASE_IDX 1
#define regSWRST_CONTROL_0 0x20104
#define regSWRST_CONTROL_0_BASE_IDX 1
#define regSWRST_CONTROL_1 0x20105
#define regSWRST_CONTROL_1_BASE_IDX 1
#define regSWRST_CONTROL_2 0x20106
#define regSWRST_CONTROL_2_BASE_IDX 1
#define regSWRST_CONTROL_3 0x20107
#define regSWRST_CONTROL_3_BASE_IDX 1
#define regSWRST_CONTROL_4 0x20108
#define regSWRST_CONTROL_4_BASE_IDX 1
#define regSWRST_CONTROL_5 0x20109
#define regSWRST_CONTROL_5_BASE_IDX 1
#define regSWRST_CONTROL_6 0x2010a
#define regSWRST_CONTROL_6_BASE_IDX 1
#define regSWRST_EP_COMMAND_0 0x2010b
#define regSWRST_EP_COMMAND_0_BASE_IDX 1
#define regSWRST_EP_CONTROL_0 0x2010c
#define regSWRST_EP_CONTROL_0_BASE_IDX 1
#define regCPM_CONTROL 0x20118
#define regCPM_CONTROL_BASE_IDX 1
#define regCPM_SPLIT_CONTROL 0x20119
#define regCPM_SPLIT_CONTROL_BASE_IDX 1
#define regCPM_CONTROL_EXT 0x2011a
#define regCPM_CONTROL_EXT_BASE_IDX 1
#define regCLKREQB_PAD_CNTL 0x2011b
#define regCLKREQB_PAD_CNTL_BASE_IDX 1
#define regSMN_APERTURE_ID_A 0x2011d
#define regSMN_APERTURE_ID_A_BASE_IDX 1
#define regSMN_APERTURE_ID_B 0x2011e
#define regSMN_APERTURE_ID_B_BASE_IDX 1
#define regLNCNT_CONTROL 0x20125
#define regLNCNT_CONTROL_BASE_IDX 1
#define regSMU_INT_PIN_SHARING_PORT_INDICATOR 0x2012f
#define regSMU_INT_PIN_SHARING_PORT_INDICATOR_BASE_IDX 1
#define regPCIE_PGMST_CNTL 0x20130
#define regPCIE_PGMST_CNTL_BASE_IDX 1
#define regPCIE_PGSLV_CNTL 0x20131
#define regPCIE_PGSLV_CNTL_BASE_IDX 1
#define regLC_CPM_CONTROL_0 0x20133
#define regLC_CPM_CONTROL_0_BASE_IDX 1
#define regLC_CPM_CONTROL_1 0x20134
#define regLC_CPM_CONTROL_1_BASE_IDX 1
#define regPCIE_RXMARGIN_CONTROL_CAPABILITIES 0x20135
#define regPCIE_RXMARGIN_CONTROL_CAPABILITIES_BASE_IDX 1
#define regPCIE_RXMARGIN_1_SETTINGS 0x20136
#define regPCIE_RXMARGIN_1_SETTINGS_BASE_IDX 1
#define regPCIE_RXMARGIN_2_SETTINGS 0x20137
#define regPCIE_RXMARGIN_2_SETTINGS_BASE_IDX 1
#define regPCIE_LC_DEBUG_CNTL 0x20139
#define regPCIE_LC_DEBUG_CNTL_BASE_IDX 1
#define regSMU_INT_PIN_SHARING_PORT_INDICATOR_TWO 0x2013a
#define regSMU_INT_PIN_SHARING_PORT_INDICATOR_TWO_BASE_IDX 1
#define regPCIE_LC_DESKEW_CNTL 0x20150
#define regPCIE_LC_DESKEW_CNTL_BASE_IDX 1
#define regPCIE_TX_LAST_TLP0 0x20180
#define regPCIE_TX_LAST_TLP0_BASE_IDX 1
#define regPCIE_TX_LAST_TLP1 0x20181
#define regPCIE_TX_LAST_TLP1_BASE_IDX 1
#define regPCIE_TX_LAST_TLP2 0x20182
#define regPCIE_TX_LAST_TLP2_BASE_IDX 1
#define regPCIE_TX_LAST_TLP3 0x20183
#define regPCIE_TX_LAST_TLP3_BASE_IDX 1
#define regPCIE_TX_TRACKING_ADDR_LO 0x20184
#define regPCIE_TX_TRACKING_ADDR_LO_BASE_IDX 1
#define regPCIE_TX_TRACKING_ADDR_HI 0x20185
#define regPCIE_TX_TRACKING_ADDR_HI_BASE_IDX 1
#define regPCIE_TX_TRACKING_CTRL_STATUS 0x20186
#define regPCIE_TX_TRACKING_CTRL_STATUS_BASE_IDX 1
#define regPCIE_TX_CTRL_4 0x2018b
#define regPCIE_TX_CTRL_4_BASE_IDX 1
#define regPCIE_TX_STATUS 0x20194
#define regPCIE_TX_STATUS_BASE_IDX 1
#define regPCIE_TX_F0_ATTR_CNTL 0x2019c
#define regPCIE_TX_F0_ATTR_CNTL_BASE_IDX 1
#define regPCIE_TX_SWUS_ATTR_CNTL 0x2019d
#define regPCIE_TX_SWUS_ATTR_CNTL_BASE_IDX 1
#define regPCIE_BW_BY_UNITID 0x201c0
#define regPCIE_BW_BY_UNITID_BASE_IDX 1
#define regPCIE_MST_CTRL_1 0x201c4
#define regPCIE_MST_CTRL_1_BASE_IDX 1
#define regPCIE_HIP_REG0 0x201e0
#define regPCIE_HIP_REG0_BASE_IDX 1
#define regPCIE_HIP_REG1 0x201e1
#define regPCIE_HIP_REG1_BASE_IDX 1
#define regPCIE_HIP_REG2 0x201e2
#define regPCIE_HIP_REG2_BASE_IDX 1
#define regPCIE_HIP_REG3 0x201e3
#define regPCIE_HIP_REG3_BASE_IDX 1
#define regPCIE_HIP_REG4 0x201e4
#define regPCIE_HIP_REG4_BASE_IDX 1
#define regPCIE_HIP_REG5 0x201e5
#define regPCIE_HIP_REG5_BASE_IDX 1
#define regPCIE_HIP_REG6 0x201e6
#define regPCIE_HIP_REG6_BASE_IDX 1
#define regPCIE_HIP_REG7 0x201e7
#define regPCIE_HIP_REG7_BASE_IDX 1
#define regPCIE_HIP_REG8 0x201e8
#define regPCIE_HIP_REG8_BASE_IDX 1
#define regPCIE_PERF_CNTL_TXCLK7 0x20222
#define regPCIE_PERF_CNTL_TXCLK7_BASE_IDX 1
#define regPCIE_PERF_COUNT0_TXCLK7 0x20223
#define regPCIE_PERF_COUNT0_TXCLK7_BASE_IDX 1
#define regPCIE_PERF_COUNT1_TXCLK7 0x20224
#define regPCIE_PERF_COUNT1_TXCLK7_BASE_IDX 1
#define regPCIE_PERF_CNTL_TXCLK8 0x20225
#define regPCIE_PERF_CNTL_TXCLK8_BASE_IDX 1
#define regPCIE_PERF_COUNT0_TXCLK8 0x20226
#define regPCIE_PERF_COUNT0_TXCLK8_BASE_IDX 1
#define regPCIE_PERF_COUNT1_TXCLK8 0x20227
#define regPCIE_PERF_COUNT1_TXCLK8_BASE_IDX 1
#define regPCIE_PERF_CNTL_TXCLK9 0x20228
#define regPCIE_PERF_CNTL_TXCLK9_BASE_IDX 1
#define regPCIE_PERF_COUNT0_TXCLK9 0x20229
#define regPCIE_PERF_COUNT0_TXCLK9_BASE_IDX 1
#define regPCIE_PERF_COUNT1_TXCLK9 0x2022a
#define regPCIE_PERF_COUNT1_TXCLK9_BASE_IDX 1
#define regPCIE_PERF_CNTL_TXCLK10 0x2022b
#define regPCIE_PERF_CNTL_TXCLK10_BASE_IDX 1
#define regPCIE_PERF_COUNT0_TXCLK10 0x2022c
#define regPCIE_PERF_COUNT0_TXCLK10_BASE_IDX 1
#define regPCIE_PERF_COUNT1_TXCLK10 0x2022d
#define regPCIE_PERF_COUNT1_TXCLK10_BASE_IDX 1
#define regPCIE_LANE_ERROR_COUNTERS_0 0x2025e
#define regPCIE_LANE_ERROR_COUNTERS_0_BASE_IDX 1
#define regPCIE_LANE_ERROR_COUNTERS_1 0x2025f
#define regPCIE_LANE_ERROR_COUNTERS_1_BASE_IDX 1
#define regPCIE_LANE_ERROR_COUNTERS_2 0x20260
#define regPCIE_LANE_ERROR_COUNTERS_2_BASE_IDX 1
#define regPCIE_LANE_ERROR_COUNTERS_3 0x20261
#define regPCIE_LANE_ERROR_COUNTERS_3_BASE_IDX 1
#define regSMU_PCIE_FENCED1_REG 0x20ffe
#define regSMU_PCIE_FENCED1_REG_BASE_IDX 1
#define regSMU_PCIE_FENCED2_REG 0x20fff
#define regSMU_PCIE_FENCED2_REG_BASE_IDX 1
#endif

File diff suppressed because it is too large Load Diff

View File

@ -2059,6 +2059,38 @@ static int pp_od_clk_voltage_attr_update(struct amdgpu_device *adev, struct amdg
return 0;
}
static int pp_dpm_dcefclk_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr,
uint32_t mask, enum amdgpu_device_attr_states *states)
{
struct device_attribute *dev_attr = &attr->dev_attr;
uint32_t gc_ver;
*states = ATTR_STATE_SUPPORTED;
if (!(attr->flags & mask)) {
*states = ATTR_STATE_UNSUPPORTED;
return 0;
}
gc_ver = amdgpu_ip_version(adev, GC_HWIP, 0);
/* dcefclk node is not available on gfx 11.0.3 sriov */
if ((gc_ver == IP_VERSION(11, 0, 3) && amdgpu_sriov_is_pp_one_vf(adev)) ||
gc_ver < IP_VERSION(9, 0, 0) ||
!amdgpu_device_has_display_hardware(adev))
*states = ATTR_STATE_UNSUPPORTED;
/* SMU MP1 does not support dcefclk level setting,
* setting should not be allowed from VF if not in one VF mode.
*/
if (gc_ver >= IP_VERSION(10, 0, 0) ||
(amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev))) {
dev_attr->attr.mode &= ~S_IWUGO;
dev_attr->store = NULL;
}
return 0;
}
/* Following items will be read out to indicate current plpd policy:
* - -1: none
* - 0: disallow
@ -2138,7 +2170,8 @@ static struct amdgpu_device_attr amdgpu_device_attrs[] = {
AMDGPU_DEVICE_ATTR_RW(pp_dpm_vclk1, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
AMDGPU_DEVICE_ATTR_RW(pp_dpm_dclk, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
AMDGPU_DEVICE_ATTR_RW(pp_dpm_dclk1, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
AMDGPU_DEVICE_ATTR_RW(pp_dpm_dcefclk, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
AMDGPU_DEVICE_ATTR_RW(pp_dpm_dcefclk, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF,
.attr_update = pp_dpm_dcefclk_attr_update),
AMDGPU_DEVICE_ATTR_RW(pp_dpm_pcie, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF),
AMDGPU_DEVICE_ATTR_RW(pp_sclk_od, ATTR_FLAG_BASIC),
AMDGPU_DEVICE_ATTR_RW(pp_mclk_od, ATTR_FLAG_BASIC),
@ -2182,10 +2215,6 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_
if (DEVICE_ATTR_IS(pp_dpm_socclk)) {
if (gc_ver < IP_VERSION(9, 0, 0))
*states = ATTR_STATE_UNSUPPORTED;
} else if (DEVICE_ATTR_IS(pp_dpm_dcefclk)) {
if (gc_ver < IP_VERSION(9, 0, 0) ||
!amdgpu_device_has_display_hardware(adev))
*states = ATTR_STATE_UNSUPPORTED;
} else if (DEVICE_ATTR_IS(pp_dpm_fclk)) {
if (mp1_ver < IP_VERSION(10, 0, 0))
*states = ATTR_STATE_UNSUPPORTED;
@ -2303,14 +2332,6 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_
break;
}
if (DEVICE_ATTR_IS(pp_dpm_dcefclk)) {
/* SMU MP1 does not support dcefclk level setting */
if (gc_ver >= IP_VERSION(10, 0, 0)) {
dev_attr->attr.mode &= ~S_IWUGO;
dev_attr->store = NULL;
}
}
/* setting should not be allowed from VF if not in one VF mode */
if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) {
dev_attr->attr.mode &= ~S_IWUGO;
@ -2581,6 +2602,7 @@ static ssize_t amdgpu_hwmon_set_pwm1_enable(struct device *dev,
{
struct amdgpu_device *adev = dev_get_drvdata(dev);
int err, ret;
u32 pwm_mode;
int value;
if (amdgpu_in_reset(adev))
@ -2592,13 +2614,22 @@ static ssize_t amdgpu_hwmon_set_pwm1_enable(struct device *dev,
if (err)
return err;
if (value == 0)
pwm_mode = AMD_FAN_CTRL_NONE;
else if (value == 1)
pwm_mode = AMD_FAN_CTRL_MANUAL;
else if (value == 2)
pwm_mode = AMD_FAN_CTRL_AUTO;
else
return -EINVAL;
ret = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (ret < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return ret;
}
ret = amdgpu_dpm_set_fan_control_mode(adev, value);
ret = amdgpu_dpm_set_fan_control_mode(adev, pwm_mode);
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);

View File

@ -712,6 +712,7 @@ static int smu_set_funcs(struct amdgpu_device *adev)
smu_v13_0_7_set_ppt_funcs(smu);
break;
case IP_VERSION(14, 0, 0):
case IP_VERSION(14, 0, 1):
smu_v14_0_0_set_ppt_funcs(smu);
break;
default:
@ -1895,6 +1896,7 @@ static int smu_disable_dpms(struct smu_context *smu)
case IP_VERSION(13, 0, 4):
case IP_VERSION(13, 0, 11):
case IP_VERSION(14, 0, 0):
case IP_VERSION(14, 0, 1):
return 0;
default:
break;

View File

@ -53,6 +53,8 @@
MODULE_FIRMWARE("amdgpu/smu_14_0_2.bin");
#define ENABLE_IMU_ARG_GFXOFF_ENABLE 1
int smu_v14_0_init_microcode(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
@ -231,6 +233,10 @@ int smu_v14_0_check_fw_version(struct smu_context *smu)
case IP_VERSION(14, 0, 0):
smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_SMU_V14_0_0;
break;
case IP_VERSION(14, 0, 1):
smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_SMU_V14_0_0;
break;
default:
dev_err(adev->dev, "smu unsupported IP version: 0x%x.\n",
amdgpu_ip_version(adev, MP1_HWIP, 0));
@ -734,6 +740,7 @@ int smu_v14_0_gfx_off_control(struct smu_context *smu, bool enable)
switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
case IP_VERSION(14, 0, 2):
case IP_VERSION(14, 0, 0):
case IP_VERSION(14, 0, 1):
if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
return 0;
if (enable)
@ -1628,11 +1635,16 @@ int smu_v14_0_baco_exit(struct smu_context *smu)
int smu_v14_0_set_gfx_power_up_by_imu(struct smu_context *smu)
{
uint16_t index;
struct amdgpu_device *adev = smu->adev;
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnableGfxImu,
ENABLE_IMU_ARG_GFXOFF_ENABLE, NULL);
}
index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG,
SMU_MSG_EnableGfxImu);
/* Param 1 to tell PMFW to enable GFXOFF feature */
return smu_cmn_send_msg_without_waiting(smu, index, 1);
return smu_cmn_send_msg_without_waiting(smu, index, ENABLE_IMU_ARG_GFXOFF_ENABLE);
}
int smu_v14_0_set_default_dpm_tables(struct smu_context *smu)