Merge tag 'amd-drm-next-5.8-2020-04-30' of git://people.freedesktop.org/~agd5f/linux into drm-next
amd-drm-next-5.8-2020-04-30: amdgpu: - SR-IOV fixes - SDMA fix for Navi - VCN 2.5 DPG fixes - Display fixes - Display stuttering fixes for pageflip and cursor - Add support for handling encrypted GPU memory - Add UAPI for encrypted GPU memory - Rework IB pool handling amdkfd: - Expose asic revision in topology - Add UAPI for GWS (Global Wave Sync) resource management UAPI: - Add amdgpu UAPI for encrypted GPU memory Used by: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4401 - Add amdkfd UAPI for GWS (Global Wave Sync) resource management Thunk usage of KFD ioctl: https://github.com/RadeonOpenCompute/ROCT-Thunk-Interface/blob/roc-2.8.0/src/queues.c#L840 ROCr usage of Thunk API: https://github.com/RadeonOpenCompute/ROCR-Runtime/blob/roc-3.1.0/src/core/runtime/amd_gpu_agent.cpp#L597 HCC code using ROCr API:98ee9f3494/lib/hsa/mcwamp_hsa.cpp (L2161)
HIP code using HCC API:cf8589b8c8/src/hip_module.cpp (L567)
Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200430212951.3902-1-alexander.deucher@amd.com
This commit is contained in:
commit
370fb6b0aa
|
@ -189,6 +189,8 @@ extern int sched_policy;
|
|||
static const int sched_policy = KFD_SCHED_POLICY_HWS;
|
||||
#endif
|
||||
|
||||
extern int amdgpu_tmz;
|
||||
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
extern int amdgpu_si_support;
|
||||
#endif
|
||||
|
@ -202,8 +204,6 @@ extern int amdgpu_cik_support;
|
|||
#define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000
|
||||
#define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */
|
||||
#define AMDGPU_FENCE_JIFFIES_TIMEOUT (HZ / 2)
|
||||
/* AMDGPU_IB_POOL_SIZE must be a power of 2 */
|
||||
#define AMDGPU_IB_POOL_SIZE 16
|
||||
#define AMDGPU_DEBUGFS_MAX_COMPONENTS 32
|
||||
#define AMDGPUFB_CONN_LIMIT 4
|
||||
#define AMDGPU_BIOS_NUM_SCRATCH 16
|
||||
|
@ -400,13 +400,6 @@ struct amdgpu_sa_bo {
|
|||
int amdgpu_fence_slab_init(void);
|
||||
void amdgpu_fence_slab_fini(void);
|
||||
|
||||
enum amdgpu_ib_pool_type {
|
||||
AMDGPU_IB_POOL_NORMAL = 0,
|
||||
AMDGPU_IB_POOL_VM,
|
||||
AMDGPU_IB_POOL_DIRECT,
|
||||
|
||||
AMDGPU_IB_POOL_MAX
|
||||
};
|
||||
/*
|
||||
* IRQS.
|
||||
*/
|
||||
|
@ -864,7 +857,7 @@ struct amdgpu_device {
|
|||
unsigned num_rings;
|
||||
struct amdgpu_ring *rings[AMDGPU_MAX_RINGS];
|
||||
bool ib_pool_ready;
|
||||
struct amdgpu_sa_manager ring_tmp_bo[AMDGPU_IB_POOL_MAX];
|
||||
struct amdgpu_sa_manager ib_pools[AMDGPU_IB_POOL_MAX];
|
||||
struct amdgpu_sched gpu_sched[AMDGPU_HW_IP_NUM][AMDGPU_RING_PRIO_MAX];
|
||||
|
||||
/* interrupts */
|
||||
|
@ -945,7 +938,7 @@ struct amdgpu_device {
|
|||
atomic64_t gart_pin_size;
|
||||
|
||||
/* soc15 register offset based on ip, instance and segment */
|
||||
uint32_t *reg_offset[MAX_HWIP][HWIP_MAX_INSTANCE];
|
||||
uint32_t *reg_offset[MAX_HWIP][HWIP_MAX_INSTANCE];
|
||||
|
||||
/* delayed work_func for deferring clockgating during resume */
|
||||
struct delayed_work delayed_init_work;
|
||||
|
@ -1263,5 +1256,9 @@ _name##_show(struct device *dev, \
|
|||
\
|
||||
static struct device_attribute pmu_attr_##_name = __ATTR_RO(_name)
|
||||
|
||||
#endif
|
||||
static inline bool amdgpu_is_tmz(struct amdgpu_device *adev)
|
||||
{
|
||||
return adev->gmc.tmz_enabled;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -564,6 +564,13 @@ uint32_t amdgpu_amdkfd_get_num_gws(struct kgd_dev *kgd)
|
|||
return adev->gds.gws_size;
|
||||
}
|
||||
|
||||
uint32_t amdgpu_amdkfd_get_asic_rev_id(struct kgd_dev *kgd)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
|
||||
|
||||
return adev->rev_id;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine,
|
||||
uint32_t vmid, uint64_t gpu_addr,
|
||||
uint32_t *ib_cmd, uint32_t ib_len)
|
||||
|
|
|
@ -175,6 +175,7 @@ uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd);
|
|||
uint64_t amdgpu_amdkfd_get_unique_id(struct kgd_dev *kgd);
|
||||
uint64_t amdgpu_amdkfd_get_mmio_remap_phys_addr(struct kgd_dev *kgd);
|
||||
uint32_t amdgpu_amdkfd_get_num_gws(struct kgd_dev *kgd);
|
||||
uint32_t amdgpu_amdkfd_get_asic_rev_id(struct kgd_dev *kgd);
|
||||
uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct kgd_dev *dst, struct kgd_dev *src);
|
||||
|
||||
/* Read user wptr from a specified user address space with page fault
|
||||
|
|
|
@ -40,7 +40,7 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size,
|
|||
for (i = 0; i < n; i++) {
|
||||
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
|
||||
r = amdgpu_copy_buffer(ring, saddr, daddr, size, NULL, &fence,
|
||||
false, false);
|
||||
false, false, false);
|
||||
if (r)
|
||||
goto exit_do_move;
|
||||
r = dma_fence_wait(fence, false);
|
||||
|
|
|
@ -924,7 +924,8 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
|
|||
|
||||
ring = to_amdgpu_ring(entity->rq->sched);
|
||||
r = amdgpu_ib_get(adev, vm, ring->funcs->parse_cs ?
|
||||
chunk_ib->ib_bytes : 0, AMDGPU_IB_POOL_NORMAL, ib);
|
||||
chunk_ib->ib_bytes : 0,
|
||||
AMDGPU_IB_POOL_DELAYED, ib);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to get ib !\n");
|
||||
return r;
|
||||
|
|
|
@ -1140,6 +1140,8 @@ static int amdgpu_device_check_arguments(struct amdgpu_device *adev)
|
|||
|
||||
adev->firmware.load_type = amdgpu_ucode_get_load_type(adev, amdgpu_fw_load_type);
|
||||
|
||||
amdgpu_gmc_tmz_set(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2998,7 +3000,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
INIT_WORK(&adev->xgmi_reset_work, amdgpu_device_xgmi_reset_func);
|
||||
|
||||
adev->gfx.gfx_off_req_count = 1;
|
||||
adev->pm.ac_power = power_supply_is_system_supplied() > 0 ? true : false;
|
||||
adev->pm.ac_power = power_supply_is_system_supplied() > 0;
|
||||
|
||||
/* Registers mapping */
|
||||
/* TODO: block userspace mapping of io register */
|
||||
|
@ -3432,15 +3434,12 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
|
|||
}
|
||||
}
|
||||
|
||||
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
|
||||
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
|
||||
|
||||
amdgpu_amdkfd_suspend(adev, !fbcon);
|
||||
|
||||
amdgpu_ras_suspend(adev);
|
||||
|
||||
r = amdgpu_device_ip_suspend_phase1(adev);
|
||||
|
||||
amdgpu_amdkfd_suspend(adev, !fbcon);
|
||||
|
||||
/* evict vram memory */
|
||||
amdgpu_bo_evict_vram(adev);
|
||||
|
||||
|
|
|
@ -85,9 +85,10 @@
|
|||
* - 3.34.0 - Non-DC can flip correctly between buffers with different pitches
|
||||
* - 3.35.0 - Add drm_amdgpu_info_device::tcc_disabled_mask
|
||||
* - 3.36.0 - Allow reading more status registers on si/cik
|
||||
* - 3.37.0 - L2 is invalidated before SDMA IBs, needed for correctness
|
||||
*/
|
||||
#define KMS_DRIVER_MAJOR 3
|
||||
#define KMS_DRIVER_MINOR 36
|
||||
#define KMS_DRIVER_MINOR 37
|
||||
#define KMS_DRIVER_PATCHLEVEL 0
|
||||
|
||||
int amdgpu_vram_limit = 0;
|
||||
|
@ -144,6 +145,7 @@ int amdgpu_discovery = -1;
|
|||
int amdgpu_mes = 0;
|
||||
int amdgpu_noretry;
|
||||
int amdgpu_force_asic_type = -1;
|
||||
int amdgpu_tmz = 0;
|
||||
|
||||
struct amdgpu_mgpu_info mgpu_info = {
|
||||
.mutex = __MUTEX_INITIALIZER(mgpu_info.mutex),
|
||||
|
@ -687,13 +689,12 @@ MODULE_PARM_DESC(halt_if_hws_hang, "Halt if HWS hang is detected (0 = off (defau
|
|||
|
||||
/**
|
||||
* DOC: hws_gws_support(bool)
|
||||
* Whether HWS support gws barriers. Default value: false (not supported)
|
||||
* This will be replaced with a MEC firmware version check once firmware
|
||||
* is ready
|
||||
* Assume that HWS supports GWS barriers regardless of what firmware version
|
||||
* check says. Default value: false (rely on MEC2 firmware version check).
|
||||
*/
|
||||
bool hws_gws_support;
|
||||
module_param(hws_gws_support, bool, 0444);
|
||||
MODULE_PARM_DESC(hws_gws_support, "MEC FW support gws barriers (false = not supported (Default), true = supported)");
|
||||
MODULE_PARM_DESC(hws_gws_support, "Assume MEC2 FW supports GWS barriers (false = rely on FW version check (Default), true = force supported)");
|
||||
|
||||
/**
|
||||
* DOC: queue_preemption_timeout_ms (int)
|
||||
|
@ -728,6 +729,16 @@ uint amdgpu_dm_abm_level = 0;
|
|||
MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) ");
|
||||
module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444);
|
||||
|
||||
/**
|
||||
* DOC: tmz (int)
|
||||
* Trusted Memory Zone (TMZ) is a method to protect data being written
|
||||
* to or read from memory.
|
||||
*
|
||||
* The default value: 0 (off). TODO: change to auto till it is completed.
|
||||
*/
|
||||
MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto, 0 = off (default), 1 = on)");
|
||||
module_param_named(tmz, amdgpu_tmz, int, 0444);
|
||||
|
||||
static const struct pci_device_id pciidlist[] = {
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
{0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI},
|
||||
|
|
|
@ -192,14 +192,22 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
|
|||
* Used For polling fence.
|
||||
* Returns 0 on success, -ENOMEM on failure.
|
||||
*/
|
||||
int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s)
|
||||
int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s,
|
||||
uint32_t timeout)
|
||||
{
|
||||
uint32_t seq;
|
||||
signed long r;
|
||||
|
||||
if (!s)
|
||||
return -EINVAL;
|
||||
|
||||
seq = ++ring->fence_drv.sync_seq;
|
||||
r = amdgpu_fence_wait_polling(ring,
|
||||
seq - ring->fence_drv.num_fences_mask,
|
||||
timeout);
|
||||
if (r < 1)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,
|
||||
seq, 0);
|
||||
|
||||
|
|
|
@ -234,7 +234,8 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
|
|||
AMDGPU_GEM_CREATE_CPU_GTT_USWC |
|
||||
AMDGPU_GEM_CREATE_VRAM_CLEARED |
|
||||
AMDGPU_GEM_CREATE_VM_ALWAYS_VALID |
|
||||
AMDGPU_GEM_CREATE_EXPLICIT_SYNC))
|
||||
AMDGPU_GEM_CREATE_EXPLICIT_SYNC |
|
||||
AMDGPU_GEM_CREATE_ENCRYPTED))
|
||||
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -242,6 +243,11 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
|
|||
if (args->in.domains & ~AMDGPU_GEM_DOMAIN_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
if (!amdgpu_is_tmz(adev) && (flags & AMDGPU_GEM_CREATE_ENCRYPTED)) {
|
||||
DRM_NOTE_ONCE("Cannot allocate secure buffer since TMZ is disabled\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* create a gem object to contain this object in */
|
||||
if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS |
|
||||
AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {
|
||||
|
|
|
@ -675,13 +675,15 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg)
|
|||
|
||||
spin_lock_irqsave(&kiq->ring_lock, flags);
|
||||
if (amdgpu_device_wb_get(adev, ®_val_offs)) {
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
pr_err("critical bug! too many kiq readers\n");
|
||||
goto failed_kiq_read;
|
||||
goto failed_unlock;
|
||||
}
|
||||
amdgpu_ring_alloc(ring, 32);
|
||||
amdgpu_ring_emit_rreg(ring, reg, reg_val_offs);
|
||||
amdgpu_fence_emit_polling(ring, &seq);
|
||||
r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
|
||||
if (r)
|
||||
goto failed_undo;
|
||||
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
|
||||
|
@ -712,7 +714,13 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg)
|
|||
amdgpu_device_wb_free(adev, reg_val_offs);
|
||||
return value;
|
||||
|
||||
failed_undo:
|
||||
amdgpu_ring_undo(ring);
|
||||
failed_unlock:
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
failed_kiq_read:
|
||||
if (reg_val_offs)
|
||||
amdgpu_device_wb_free(adev, reg_val_offs);
|
||||
pr_err("failed to read reg:%x\n", reg);
|
||||
return ~0;
|
||||
}
|
||||
|
@ -730,7 +738,10 @@ void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
|
|||
spin_lock_irqsave(&kiq->ring_lock, flags);
|
||||
amdgpu_ring_alloc(ring, 32);
|
||||
amdgpu_ring_emit_wreg(ring, reg, v);
|
||||
amdgpu_fence_emit_polling(ring, &seq);
|
||||
r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
|
||||
if (r)
|
||||
goto failed_undo;
|
||||
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
|
||||
|
@ -759,6 +770,9 @@ void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
|
|||
|
||||
return;
|
||||
|
||||
failed_undo:
|
||||
amdgpu_ring_undo(ring);
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
failed_kiq_write:
|
||||
pr_err("failed to write reg:%x\n", reg);
|
||||
}
|
||||
|
|
|
@ -373,3 +373,38 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_tmz_set -- check and set if a device supports TMZ
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Check and set if an the device @adev supports Trusted Memory
|
||||
* Zones (TMZ).
|
||||
*/
|
||||
void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
|
||||
{
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_RENOIR:
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
/* Don't enable it by default yet.
|
||||
*/
|
||||
if (amdgpu_tmz < 1) {
|
||||
adev->gmc.tmz_enabled = false;
|
||||
dev_info(adev->dev,
|
||||
"Trusted Memory Zone (TMZ) feature disabled as experimental (default)\n");
|
||||
} else {
|
||||
adev->gmc.tmz_enabled = true;
|
||||
dev_info(adev->dev,
|
||||
"Trusted Memory Zone (TMZ) feature enabled as experimental (cmd line)\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
adev->gmc.tmz_enabled = false;
|
||||
dev_warn(adev->dev,
|
||||
"Trusted Memory Zone (TMZ) feature not supported\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -213,6 +213,8 @@ struct amdgpu_gmc {
|
|||
} fault_hash[AMDGPU_GMC_FAULT_HASH_SIZE];
|
||||
uint64_t last_fault:AMDGPU_GMC_FAULT_RING_ORDER;
|
||||
|
||||
bool tmz_enabled;
|
||||
|
||||
const struct amdgpu_gmc_funcs *gmc_funcs;
|
||||
|
||||
struct amdgpu_xgmi xgmi;
|
||||
|
@ -276,4 +278,6 @@ int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev);
|
|||
void amdgpu_gmc_ras_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev);
|
||||
|
||||
extern void amdgpu_gmc_tmz_set(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,14 +61,13 @@
|
|||
* Returns 0 on success, error on failure.
|
||||
*/
|
||||
int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
unsigned size,
|
||||
enum amdgpu_ib_pool_type pool_type,
|
||||
struct amdgpu_ib *ib)
|
||||
unsigned size, enum amdgpu_ib_pool_type pool_type,
|
||||
struct amdgpu_ib *ib)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (size) {
|
||||
r = amdgpu_sa_bo_new(&adev->ring_tmp_bo[pool_type],
|
||||
r = amdgpu_sa_bo_new(&adev->ib_pools[pool_type],
|
||||
&ib->sa_bo, size, 256);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "failed to get a new IB (%d)\n", r);
|
||||
|
@ -133,6 +132,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
|||
uint64_t fence_ctx;
|
||||
uint32_t status = 0, alloc_size;
|
||||
unsigned fence_flags = 0;
|
||||
bool secure;
|
||||
|
||||
unsigned i;
|
||||
int r = 0;
|
||||
|
@ -161,6 +161,12 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((ib->flags & AMDGPU_IB_FLAGS_SECURE) &&
|
||||
(ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE)) {
|
||||
dev_err(adev->dev, "secure submissions not supported on compute rings\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
alloc_size = ring->funcs->emit_frame_size + num_ibs *
|
||||
ring->funcs->emit_ib_size;
|
||||
|
||||
|
@ -217,6 +223,14 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
|||
amdgpu_ring_emit_cntxcntl(ring, status);
|
||||
}
|
||||
|
||||
/* Setup initial TMZiness and send it off.
|
||||
*/
|
||||
secure = false;
|
||||
if (job && ring->funcs->emit_frame_cntl) {
|
||||
secure = ib->flags & AMDGPU_IB_FLAGS_SECURE;
|
||||
amdgpu_ring_emit_frame_cntl(ring, true, secure);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_ibs; ++i) {
|
||||
ib = &ibs[i];
|
||||
|
||||
|
@ -228,12 +242,20 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
|||
!amdgpu_sriov_vf(adev)) /* for SRIOV preemption, Preamble CE ib must be inserted anyway */
|
||||
continue;
|
||||
|
||||
if (job && ring->funcs->emit_frame_cntl) {
|
||||
if (secure != !!(ib->flags & AMDGPU_IB_FLAGS_SECURE)) {
|
||||
amdgpu_ring_emit_frame_cntl(ring, false, secure);
|
||||
secure = !secure;
|
||||
amdgpu_ring_emit_frame_cntl(ring, true, secure);
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_ring_emit_ib(ring, job, ib, status);
|
||||
status &= ~AMDGPU_HAVE_CTX_SWITCH;
|
||||
}
|
||||
|
||||
if (ring->funcs->emit_tmz)
|
||||
amdgpu_ring_emit_tmz(ring, false);
|
||||
if (job && ring->funcs->emit_frame_cntl)
|
||||
amdgpu_ring_emit_frame_cntl(ring, false, secure);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
if (!(adev->flags & AMD_IS_APU))
|
||||
|
@ -282,30 +304,32 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
|||
*/
|
||||
int amdgpu_ib_pool_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int r, i;
|
||||
unsigned size;
|
||||
int r, i;
|
||||
|
||||
if (adev->ib_pool_ready) {
|
||||
if (adev->ib_pool_ready)
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < AMDGPU_IB_POOL_MAX; i++) {
|
||||
if (i == AMDGPU_IB_POOL_DIRECT)
|
||||
size = PAGE_SIZE * 2;
|
||||
else
|
||||
size = AMDGPU_IB_POOL_SIZE*64*1024;
|
||||
r = amdgpu_sa_bo_manager_init(adev, &adev->ring_tmp_bo[i],
|
||||
size,
|
||||
AMDGPU_GPU_PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_GTT);
|
||||
if (r) {
|
||||
for (i--; i >= 0; i--)
|
||||
amdgpu_sa_bo_manager_fini(adev, &adev->ring_tmp_bo[i]);
|
||||
return r;
|
||||
}
|
||||
size = AMDGPU_IB_POOL_SIZE;
|
||||
|
||||
r = amdgpu_sa_bo_manager_init(adev, &adev->ib_pools[i],
|
||||
size, AMDGPU_GPU_PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_GTT);
|
||||
if (r)
|
||||
goto error;
|
||||
}
|
||||
adev->ib_pool_ready = true;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
while (i--)
|
||||
amdgpu_sa_bo_manager_fini(adev, &adev->ib_pools[i]);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -320,11 +344,12 @@ void amdgpu_ib_pool_fini(struct amdgpu_device *adev)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (adev->ib_pool_ready) {
|
||||
for (i = 0; i < AMDGPU_IB_POOL_MAX; i++)
|
||||
amdgpu_sa_bo_manager_fini(adev, &adev->ring_tmp_bo[i]);
|
||||
adev->ib_pool_ready = false;
|
||||
}
|
||||
if (!adev->ib_pool_ready)
|
||||
return;
|
||||
|
||||
for (i = 0; i < AMDGPU_IB_POOL_MAX; i++)
|
||||
amdgpu_sa_bo_manager_fini(adev, &adev->ib_pools[i]);
|
||||
adev->ib_pool_ready = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -339,9 +364,9 @@ void amdgpu_ib_pool_fini(struct amdgpu_device *adev)
|
|||
*/
|
||||
int amdgpu_ib_ring_tests(struct amdgpu_device *adev)
|
||||
{
|
||||
unsigned i;
|
||||
int r, ret = 0;
|
||||
long tmo_gfx, tmo_mm;
|
||||
int r, ret = 0;
|
||||
unsigned i;
|
||||
|
||||
tmo_mm = tmo_gfx = AMDGPU_IB_TEST_TIMEOUT;
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
|
@ -419,15 +444,16 @@ static int amdgpu_debugfs_sa_info(struct seq_file *m, void *data)
|
|||
struct drm_device *dev = node->minor->dev;
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
|
||||
seq_printf(m, "-------------------- NORMAL -------------------- \n");
|
||||
amdgpu_sa_bo_dump_debug_info(&adev->ring_tmp_bo[AMDGPU_IB_POOL_NORMAL], m);
|
||||
seq_printf(m, "---------------------- VM ---------------------- \n");
|
||||
amdgpu_sa_bo_dump_debug_info(&adev->ring_tmp_bo[AMDGPU_IB_POOL_VM], m);
|
||||
seq_printf(m, "-------------------- DIRECT--------------------- \n");
|
||||
amdgpu_sa_bo_dump_debug_info(&adev->ring_tmp_bo[AMDGPU_IB_POOL_DIRECT], m);
|
||||
seq_printf(m, "--------------------- DELAYED --------------------- \n");
|
||||
amdgpu_sa_bo_dump_debug_info(&adev->ib_pools[AMDGPU_IB_POOL_DELAYED],
|
||||
m);
|
||||
seq_printf(m, "-------------------- IMMEDIATE -------------------- \n");
|
||||
amdgpu_sa_bo_dump_debug_info(&adev->ib_pools[AMDGPU_IB_POOL_IMMEDIATE],
|
||||
m);
|
||||
seq_printf(m, "--------------------- DIRECT ---------------------- \n");
|
||||
amdgpu_sa_bo_dump_debug_info(&adev->ib_pools[AMDGPU_IB_POOL_DIRECT], m);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static const struct drm_info_list amdgpu_debugfs_sa_list[] = {
|
||||
|
|
|
@ -282,7 +282,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
|
|||
!dma_fence_is_later(updates, (*id)->flushed_updates))
|
||||
updates = NULL;
|
||||
|
||||
if ((*id)->owner != vm->direct.fence_context ||
|
||||
if ((*id)->owner != vm->immediate.fence_context ||
|
||||
job->vm_pd_addr != (*id)->pd_gpu_addr ||
|
||||
updates || !(*id)->last_flush ||
|
||||
((*id)->last_flush->context != fence_context &&
|
||||
|
@ -349,7 +349,7 @@ static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
|
|||
struct dma_fence *flushed;
|
||||
|
||||
/* Check all the prerequisites to using this VMID */
|
||||
if ((*id)->owner != vm->direct.fence_context)
|
||||
if ((*id)->owner != vm->immediate.fence_context)
|
||||
continue;
|
||||
|
||||
if ((*id)->pd_gpu_addr != job->vm_pd_addr)
|
||||
|
@ -448,7 +448,7 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
|||
}
|
||||
|
||||
id->pd_gpu_addr = job->vm_pd_addr;
|
||||
id->owner = vm->direct.fence_context;
|
||||
id->owner = vm->immediate.fence_context;
|
||||
|
||||
if (job->vm_needs_flush) {
|
||||
dma_fence_put(id->last_flush);
|
||||
|
|
|
@ -62,7 +62,6 @@ struct amdgpu_job {
|
|||
/* user fence handling */
|
||||
uint64_t uf_addr;
|
||||
uint64_t uf_sequence;
|
||||
|
||||
};
|
||||
|
||||
int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
|
||||
|
|
|
@ -753,7 +753,7 @@ int amdgpu_bo_restore_shadow(struct amdgpu_bo *shadow, struct dma_fence **fence)
|
|||
|
||||
return amdgpu_copy_buffer(ring, shadow_addr, parent_addr,
|
||||
amdgpu_bo_size(shadow), NULL, fence,
|
||||
true, false);
|
||||
true, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -229,6 +229,17 @@ static inline bool amdgpu_bo_explicit_sync(struct amdgpu_bo *bo)
|
|||
return bo->flags & AMDGPU_GEM_CREATE_EXPLICIT_SYNC;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_bo_encrypted - test if the BO is encrypted
|
||||
* @bo: pointer to a buffer object
|
||||
*
|
||||
* Return true if the buffer object is encrypted, false otherwise.
|
||||
*/
|
||||
static inline bool amdgpu_bo_encrypted(struct amdgpu_bo *bo)
|
||||
{
|
||||
return bo->flags & AMDGPU_GEM_CREATE_ENCRYPTED;
|
||||
}
|
||||
|
||||
bool amdgpu_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);
|
||||
void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain);
|
||||
|
||||
|
|
|
@ -3271,26 +3271,27 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_num_states);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to create device file pp_num_states\n");
|
||||
return ret;
|
||||
}
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_cur_state);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to create device file pp_cur_state\n");
|
||||
return ret;
|
||||
}
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_force_state);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to create device file pp_force_state\n");
|
||||
return ret;
|
||||
}
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_table);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to create device file pp_table\n");
|
||||
return ret;
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_num_states);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to create device file pp_num_states\n");
|
||||
return ret;
|
||||
}
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_cur_state);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to create device file pp_cur_state\n");
|
||||
return ret;
|
||||
}
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_force_state);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to create device file pp_force_state\n");
|
||||
return ret;
|
||||
}
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_table);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to create device file pp_table\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_dpm_sclk);
|
||||
|
@ -3337,6 +3338,13 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* the reset are not needed for SRIOV one vf mode */
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
adev->pm.sysfs_initialized = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (adev->asic_type != CHIP_ARCTURUS) {
|
||||
ret = device_create_file(adev->dev, &dev_attr_pp_dpm_pcie);
|
||||
if (ret) {
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
|
||||
#define to_amdgpu_ring(s) container_of((s), struct amdgpu_ring, sched)
|
||||
|
||||
#define AMDGPU_IB_POOL_SIZE (1024 * 1024)
|
||||
|
||||
enum amdgpu_ring_type {
|
||||
AMDGPU_RING_TYPE_GFX = AMDGPU_HW_IP_GFX,
|
||||
AMDGPU_RING_TYPE_COMPUTE = AMDGPU_HW_IP_COMPUTE,
|
||||
|
@ -63,6 +65,17 @@ enum amdgpu_ring_type {
|
|||
AMDGPU_RING_TYPE_KIQ
|
||||
};
|
||||
|
||||
enum amdgpu_ib_pool_type {
|
||||
/* Normal submissions to the top of the pipeline. */
|
||||
AMDGPU_IB_POOL_DELAYED,
|
||||
/* Immediate submissions to the bottom of the pipeline. */
|
||||
AMDGPU_IB_POOL_IMMEDIATE,
|
||||
/* Direct submission to the ring buffer during init and reset. */
|
||||
AMDGPU_IB_POOL_DIRECT,
|
||||
|
||||
AMDGPU_IB_POOL_MAX
|
||||
};
|
||||
|
||||
struct amdgpu_device;
|
||||
struct amdgpu_ring;
|
||||
struct amdgpu_ib;
|
||||
|
@ -105,7 +118,8 @@ void amdgpu_fence_driver_suspend(struct amdgpu_device *adev);
|
|||
void amdgpu_fence_driver_resume(struct amdgpu_device *adev);
|
||||
int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **fence,
|
||||
unsigned flags);
|
||||
int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s);
|
||||
int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s,
|
||||
uint32_t timeout);
|
||||
bool amdgpu_fence_process(struct amdgpu_ring *ring);
|
||||
int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);
|
||||
signed long amdgpu_fence_wait_polling(struct amdgpu_ring *ring,
|
||||
|
@ -176,7 +190,8 @@ struct amdgpu_ring_funcs {
|
|||
void (*emit_reg_write_reg_wait)(struct amdgpu_ring *ring,
|
||||
uint32_t reg0, uint32_t reg1,
|
||||
uint32_t ref, uint32_t mask);
|
||||
void (*emit_tmz)(struct amdgpu_ring *ring, bool start);
|
||||
void (*emit_frame_cntl)(struct amdgpu_ring *ring, bool start,
|
||||
bool secure);
|
||||
/* Try to soft recover the ring to make the fence signal */
|
||||
void (*soft_recovery)(struct amdgpu_ring *ring, unsigned vmid);
|
||||
int (*preempt_ib)(struct amdgpu_ring *ring);
|
||||
|
@ -255,7 +270,7 @@ struct amdgpu_ring {
|
|||
#define amdgpu_ring_emit_wreg(r, d, v) (r)->funcs->emit_wreg((r), (d), (v))
|
||||
#define amdgpu_ring_emit_reg_wait(r, d, v, m) (r)->funcs->emit_reg_wait((r), (d), (v), (m))
|
||||
#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_tmz(r, b) (r)->funcs->emit_tmz((r), (b))
|
||||
#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))
|
||||
|
|
|
@ -89,7 +89,8 @@ struct amdgpu_buffer_funcs {
|
|||
/* dst addr in bytes */
|
||||
uint64_t dst_offset,
|
||||
/* number of byte to transfer */
|
||||
uint32_t byte_count);
|
||||
uint32_t byte_count,
|
||||
bool tmz);
|
||||
|
||||
/* maximum bytes in a single operation */
|
||||
uint32_t fill_max_bytes;
|
||||
|
@ -107,7 +108,7 @@ struct amdgpu_buffer_funcs {
|
|||
uint32_t byte_count);
|
||||
};
|
||||
|
||||
#define amdgpu_emit_copy_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_copy_buffer((ib), (s), (d), (b))
|
||||
#define amdgpu_emit_copy_buffer(adev, ib, s, d, b, t) (adev)->mman.buffer_funcs->emit_copy_buffer((ib), (s), (d), (b), (t))
|
||||
#define amdgpu_emit_fill_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((ib), (s), (d), (b))
|
||||
|
||||
struct amdgpu_sdma_instance *
|
||||
|
|
|
@ -249,6 +249,11 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync,
|
|||
owner != AMDGPU_FENCE_OWNER_UNDEFINED)
|
||||
continue;
|
||||
|
||||
/* Never sync to VM updates either. */
|
||||
if (fence_owner == AMDGPU_FENCE_OWNER_VM &&
|
||||
owner != AMDGPU_FENCE_OWNER_UNDEFINED)
|
||||
continue;
|
||||
|
||||
/* Ignore fences depending on the sync mode */
|
||||
switch (mode) {
|
||||
case AMDGPU_SYNC_ALWAYS:
|
||||
|
|
|
@ -44,7 +44,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
|
|||
/* Number of tests =
|
||||
* (Total GTT - IB pool - writeback page - ring buffers) / test size
|
||||
*/
|
||||
n = adev->gmc.gart_size - AMDGPU_IB_POOL_SIZE*64*1024;
|
||||
n = adev->gmc.gart_size - AMDGPU_IB_POOL_SIZE;
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
|
||||
if (adev->rings[i])
|
||||
n -= adev->rings[i]->ring_size;
|
||||
|
@ -124,7 +124,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
|
|||
amdgpu_bo_kunmap(gtt_obj[i]);
|
||||
|
||||
r = amdgpu_copy_buffer(ring, gart_addr, vram_addr,
|
||||
size, NULL, &fence, false, false);
|
||||
size, NULL, &fence, false, false, false);
|
||||
|
||||
if (r) {
|
||||
DRM_ERROR("Failed GTT->VRAM copy %d\n", i);
|
||||
|
@ -170,7 +170,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
|
|||
amdgpu_bo_kunmap(vram_obj);
|
||||
|
||||
r = amdgpu_copy_buffer(ring, vram_addr, gart_addr,
|
||||
size, NULL, &fence, false, false);
|
||||
size, NULL, &fence, false, false, false);
|
||||
|
||||
if (r) {
|
||||
DRM_ERROR("Failed VRAM->GTT copy %d\n", i);
|
||||
|
|
|
@ -62,11 +62,6 @@
|
|||
|
||||
#define AMDGPU_TTM_VRAM_MAX_DW_READ (size_t)128
|
||||
|
||||
static int amdgpu_map_buffer(struct ttm_buffer_object *bo,
|
||||
struct ttm_mem_reg *mem, unsigned num_pages,
|
||||
uint64_t offset, unsigned window,
|
||||
struct amdgpu_ring *ring,
|
||||
uint64_t *addr);
|
||||
|
||||
/**
|
||||
* amdgpu_init_mem_type - Initialize a memory manager for a specific type of
|
||||
|
@ -277,7 +272,7 @@ static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo,
|
|||
*
|
||||
*/
|
||||
static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem,
|
||||
unsigned long *offset)
|
||||
uint64_t *offset)
|
||||
{
|
||||
struct drm_mm_node *mm_node = mem->mm_node;
|
||||
|
||||
|
@ -288,92 +283,192 @@ static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem,
|
|||
return mm_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_ttm_map_buffer - Map memory into the GART windows
|
||||
* @bo: buffer object to map
|
||||
* @mem: memory object to map
|
||||
* @mm_node: drm_mm node object to map
|
||||
* @num_pages: number of pages to map
|
||||
* @offset: offset into @mm_node where to start
|
||||
* @window: which GART window to use
|
||||
* @ring: DMA ring to use for the copy
|
||||
* @tmz: if we should setup a TMZ enabled mapping
|
||||
* @addr: resulting address inside the MC address space
|
||||
*
|
||||
* Setup one of the GART windows to access a specific piece of memory or return
|
||||
* the physical address for local memory.
|
||||
*/
|
||||
static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
|
||||
struct ttm_mem_reg *mem,
|
||||
struct drm_mm_node *mm_node,
|
||||
unsigned num_pages, uint64_t offset,
|
||||
unsigned window, struct amdgpu_ring *ring,
|
||||
bool tmz, uint64_t *addr)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct amdgpu_job *job;
|
||||
unsigned num_dw, num_bytes;
|
||||
struct dma_fence *fence;
|
||||
uint64_t src_addr, dst_addr;
|
||||
void *cpu_addr;
|
||||
uint64_t flags;
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
BUG_ON(adev->mman.buffer_funcs->copy_max_bytes <
|
||||
AMDGPU_GTT_MAX_TRANSFER_SIZE * 8);
|
||||
|
||||
/* Map only what can't be accessed directly */
|
||||
if (!tmz && mem->start != AMDGPU_BO_INVALID_OFFSET) {
|
||||
*addr = amdgpu_mm_node_addr(bo, mm_node, mem) + offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*addr = adev->gmc.gart_start;
|
||||
*addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE *
|
||||
AMDGPU_GPU_PAGE_SIZE;
|
||||
*addr += offset & ~PAGE_MASK;
|
||||
|
||||
num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
|
||||
num_bytes = num_pages * 8;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4 + num_bytes,
|
||||
AMDGPU_IB_POOL_DELAYED, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
src_addr = num_dw * 4;
|
||||
src_addr += job->ibs[0].gpu_addr;
|
||||
|
||||
dst_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
|
||||
dst_addr += window * AMDGPU_GTT_MAX_TRANSFER_SIZE * 8;
|
||||
amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,
|
||||
dst_addr, num_bytes, false);
|
||||
|
||||
amdgpu_ring_pad_ib(ring, &job->ibs[0]);
|
||||
WARN_ON(job->ibs[0].length_dw > num_dw);
|
||||
|
||||
flags = amdgpu_ttm_tt_pte_flags(adev, bo->ttm, mem);
|
||||
if (tmz)
|
||||
flags |= AMDGPU_PTE_TMZ;
|
||||
|
||||
cpu_addr = &job->ibs[0].ptr[num_dw];
|
||||
|
||||
if (mem->mem_type == TTM_PL_TT) {
|
||||
struct ttm_dma_tt *dma;
|
||||
dma_addr_t *dma_address;
|
||||
|
||||
dma = container_of(bo->ttm, struct ttm_dma_tt, ttm);
|
||||
dma_address = &dma->dma_address[offset >> PAGE_SHIFT];
|
||||
r = amdgpu_gart_map(adev, 0, num_pages, dma_address, flags,
|
||||
cpu_addr);
|
||||
if (r)
|
||||
goto error_free;
|
||||
} else {
|
||||
dma_addr_t dma_address;
|
||||
|
||||
dma_address = (mm_node->start << PAGE_SHIFT) + offset;
|
||||
dma_address += adev->vm_manager.vram_base_offset;
|
||||
|
||||
for (i = 0; i < num_pages; ++i) {
|
||||
r = amdgpu_gart_map(adev, i << PAGE_SHIFT, 1,
|
||||
&dma_address, flags, cpu_addr);
|
||||
if (r)
|
||||
goto error_free;
|
||||
|
||||
dma_address += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
r = amdgpu_job_submit(job, &adev->mman.entity,
|
||||
AMDGPU_FENCE_OWNER_UNDEFINED, &fence);
|
||||
if (r)
|
||||
goto error_free;
|
||||
|
||||
dma_fence_put(fence);
|
||||
|
||||
return r;
|
||||
|
||||
error_free:
|
||||
amdgpu_job_free(job);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_copy_ttm_mem_to_mem - Helper function for copy
|
||||
* @adev: amdgpu device
|
||||
* @src: buffer/address where to read from
|
||||
* @dst: buffer/address where to write to
|
||||
* @size: number of bytes to copy
|
||||
* @tmz: if a secure copy should be used
|
||||
* @resv: resv object to sync to
|
||||
* @f: Returns the last fence if multiple jobs are submitted.
|
||||
*
|
||||
* The function copies @size bytes from {src->mem + src->offset} to
|
||||
* {dst->mem + dst->offset}. src->bo and dst->bo could be same BO for a
|
||||
* move and different for a BO to BO copy.
|
||||
*
|
||||
* @f: Returns the last fence if multiple jobs are submitted.
|
||||
*/
|
||||
int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
|
||||
struct amdgpu_copy_mem *src,
|
||||
struct amdgpu_copy_mem *dst,
|
||||
uint64_t size,
|
||||
const struct amdgpu_copy_mem *src,
|
||||
const struct amdgpu_copy_mem *dst,
|
||||
uint64_t size, bool tmz,
|
||||
struct dma_resv *resv,
|
||||
struct dma_fence **f)
|
||||
{
|
||||
const uint32_t GTT_MAX_BYTES = (AMDGPU_GTT_MAX_TRANSFER_SIZE *
|
||||
AMDGPU_GPU_PAGE_SIZE);
|
||||
|
||||
uint64_t src_node_size, dst_node_size, src_offset, dst_offset;
|
||||
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
|
||||
struct drm_mm_node *src_mm, *dst_mm;
|
||||
uint64_t src_node_start, dst_node_start, src_node_size,
|
||||
dst_node_size, src_page_offset, dst_page_offset;
|
||||
struct dma_fence *fence = NULL;
|
||||
int r = 0;
|
||||
const uint64_t GTT_MAX_BYTES = (AMDGPU_GTT_MAX_TRANSFER_SIZE *
|
||||
AMDGPU_GPU_PAGE_SIZE);
|
||||
|
||||
if (!adev->mman.buffer_funcs_enabled) {
|
||||
DRM_ERROR("Trying to move memory with ring turned off.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
src_mm = amdgpu_find_mm_node(src->mem, &src->offset);
|
||||
src_node_start = amdgpu_mm_node_addr(src->bo, src_mm, src->mem) +
|
||||
src->offset;
|
||||
src_node_size = (src_mm->size << PAGE_SHIFT) - src->offset;
|
||||
src_page_offset = src_node_start & (PAGE_SIZE - 1);
|
||||
src_offset = src->offset;
|
||||
src_mm = amdgpu_find_mm_node(src->mem, &src_offset);
|
||||
src_node_size = (src_mm->size << PAGE_SHIFT) - src_offset;
|
||||
|
||||
dst_mm = amdgpu_find_mm_node(dst->mem, &dst->offset);
|
||||
dst_node_start = amdgpu_mm_node_addr(dst->bo, dst_mm, dst->mem) +
|
||||
dst->offset;
|
||||
dst_node_size = (dst_mm->size << PAGE_SHIFT) - dst->offset;
|
||||
dst_page_offset = dst_node_start & (PAGE_SIZE - 1);
|
||||
dst_offset = dst->offset;
|
||||
dst_mm = amdgpu_find_mm_node(dst->mem, &dst_offset);
|
||||
dst_node_size = (dst_mm->size << PAGE_SHIFT) - dst_offset;
|
||||
|
||||
mutex_lock(&adev->mman.gtt_window_lock);
|
||||
|
||||
while (size) {
|
||||
unsigned long cur_size;
|
||||
uint64_t from = src_node_start, to = dst_node_start;
|
||||
uint32_t src_page_offset = src_offset & ~PAGE_MASK;
|
||||
uint32_t dst_page_offset = dst_offset & ~PAGE_MASK;
|
||||
struct dma_fence *next;
|
||||
uint32_t cur_size;
|
||||
uint64_t from, to;
|
||||
|
||||
/* Copy size cannot exceed GTT_MAX_BYTES. So if src or dst
|
||||
* begins at an offset, then adjust the size accordingly
|
||||
*/
|
||||
cur_size = min3(min(src_node_size, dst_node_size), size,
|
||||
GTT_MAX_BYTES);
|
||||
if (cur_size + src_page_offset > GTT_MAX_BYTES ||
|
||||
cur_size + dst_page_offset > GTT_MAX_BYTES)
|
||||
cur_size -= max(src_page_offset, dst_page_offset);
|
||||
cur_size = max(src_page_offset, dst_page_offset);
|
||||
cur_size = min(min3(src_node_size, dst_node_size, size),
|
||||
(uint64_t)(GTT_MAX_BYTES - cur_size));
|
||||
|
||||
/* Map only what needs to be accessed. Map src to window 0 and
|
||||
* dst to window 1
|
||||
*/
|
||||
if (src->mem->start == AMDGPU_BO_INVALID_OFFSET) {
|
||||
r = amdgpu_map_buffer(src->bo, src->mem,
|
||||
PFN_UP(cur_size + src_page_offset),
|
||||
src_node_start, 0, ring,
|
||||
&from);
|
||||
if (r)
|
||||
goto error;
|
||||
/* Adjust the offset because amdgpu_map_buffer returns
|
||||
* start of mapped page
|
||||
*/
|
||||
from += src_page_offset;
|
||||
}
|
||||
/* Map src to window 0 and dst to window 1. */
|
||||
r = amdgpu_ttm_map_buffer(src->bo, src->mem, src_mm,
|
||||
PFN_UP(cur_size + src_page_offset),
|
||||
src_offset, 0, ring, tmz, &from);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
if (dst->mem->start == AMDGPU_BO_INVALID_OFFSET) {
|
||||
r = amdgpu_map_buffer(dst->bo, dst->mem,
|
||||
PFN_UP(cur_size + dst_page_offset),
|
||||
dst_node_start, 1, ring,
|
||||
&to);
|
||||
if (r)
|
||||
goto error;
|
||||
to += dst_page_offset;
|
||||
}
|
||||
r = amdgpu_ttm_map_buffer(dst->bo, dst->mem, dst_mm,
|
||||
PFN_UP(cur_size + dst_page_offset),
|
||||
dst_offset, 1, ring, tmz, &to);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
r = amdgpu_copy_buffer(ring, from, to, cur_size,
|
||||
resv, &next, false, true);
|
||||
resv, &next, false, true, tmz);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
|
@ -386,23 +481,20 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
|
|||
|
||||
src_node_size -= cur_size;
|
||||
if (!src_node_size) {
|
||||
src_node_start = amdgpu_mm_node_addr(src->bo, ++src_mm,
|
||||
src->mem);
|
||||
src_node_size = (src_mm->size << PAGE_SHIFT);
|
||||
src_page_offset = 0;
|
||||
++src_mm;
|
||||
src_node_size = src_mm->size << PAGE_SHIFT;
|
||||
src_offset = 0;
|
||||
} else {
|
||||
src_node_start += cur_size;
|
||||
src_page_offset = src_node_start & (PAGE_SIZE - 1);
|
||||
src_offset += cur_size;
|
||||
}
|
||||
|
||||
dst_node_size -= cur_size;
|
||||
if (!dst_node_size) {
|
||||
dst_node_start = amdgpu_mm_node_addr(dst->bo, ++dst_mm,
|
||||
dst->mem);
|
||||
dst_node_size = (dst_mm->size << PAGE_SHIFT);
|
||||
dst_page_offset = 0;
|
||||
++dst_mm;
|
||||
dst_node_size = dst_mm->size << PAGE_SHIFT;
|
||||
dst_offset = 0;
|
||||
} else {
|
||||
dst_node_start += cur_size;
|
||||
dst_page_offset = dst_node_start & (PAGE_SIZE - 1);
|
||||
dst_offset += cur_size;
|
||||
}
|
||||
}
|
||||
error:
|
||||
|
@ -425,6 +517,7 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
|
|||
struct ttm_mem_reg *old_mem)
|
||||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
|
||||
struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo);
|
||||
struct amdgpu_copy_mem src, dst;
|
||||
struct dma_fence *fence = NULL;
|
||||
int r;
|
||||
|
@ -438,14 +531,14 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
|
|||
|
||||
r = amdgpu_ttm_copy_mem_to_mem(adev, &src, &dst,
|
||||
new_mem->num_pages << PAGE_SHIFT,
|
||||
amdgpu_bo_encrypted(abo),
|
||||
bo->base.resv, &fence);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
/* clear the space being freed */
|
||||
if (old_mem->mem_type == TTM_PL_VRAM &&
|
||||
(ttm_to_amdgpu_bo(bo)->flags &
|
||||
AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
|
||||
(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
|
||||
struct dma_fence *wipe_fence = NULL;
|
||||
|
||||
r = amdgpu_fill_buffer(ttm_to_amdgpu_bo(bo), AMDGPU_POISON,
|
||||
|
@ -742,8 +835,8 @@ static void amdgpu_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_re
|
|||
static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
|
||||
unsigned long page_offset)
|
||||
{
|
||||
uint64_t offset = (page_offset << PAGE_SHIFT);
|
||||
struct drm_mm_node *mm;
|
||||
unsigned long offset = (page_offset << PAGE_SHIFT);
|
||||
|
||||
mm = amdgpu_find_mm_node(&bo->mem, &offset);
|
||||
return (bo->mem.bus.base >> PAGE_SHIFT) + mm->start +
|
||||
|
@ -1027,6 +1120,9 @@ int amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
|
|||
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
||||
int r;
|
||||
|
||||
if (amdgpu_bo_encrypted(abo))
|
||||
flags |= AMDGPU_PTE_TMZ;
|
||||
|
||||
if (abo->flags & AMDGPU_GEM_CREATE_CP_MQD_GFX9) {
|
||||
uint64_t page_idx = 1;
|
||||
|
||||
|
@ -1539,6 +1635,9 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
|
|||
|
||||
switch (bo->mem.mem_type) {
|
||||
case TTM_PL_TT:
|
||||
if (amdgpu_bo_is_amdgpu_bo(bo) &&
|
||||
amdgpu_bo_encrypted(ttm_to_amdgpu_bo(bo)))
|
||||
return false;
|
||||
return true;
|
||||
|
||||
case TTM_PL_VRAM:
|
||||
|
@ -1587,8 +1686,9 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
|
|||
if (bo->mem.mem_type != TTM_PL_VRAM)
|
||||
return -EIO;
|
||||
|
||||
nodes = amdgpu_find_mm_node(&abo->tbo.mem, &offset);
|
||||
pos = (nodes->start << PAGE_SHIFT) + offset;
|
||||
pos = offset;
|
||||
nodes = amdgpu_find_mm_node(&abo->tbo.mem, &pos);
|
||||
pos += (nodes->start << PAGE_SHIFT);
|
||||
|
||||
while (len && pos < adev->gmc.mc_vram_size) {
|
||||
uint64_t aligned_pos = pos & ~(uint64_t)3;
|
||||
|
@ -2015,76 +2115,14 @@ int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
return ttm_bo_mmap(filp, vma, &adev->mman.bdev);
|
||||
}
|
||||
|
||||
static int amdgpu_map_buffer(struct ttm_buffer_object *bo,
|
||||
struct ttm_mem_reg *mem, unsigned num_pages,
|
||||
uint64_t offset, unsigned window,
|
||||
struct amdgpu_ring *ring,
|
||||
uint64_t *addr)
|
||||
{
|
||||
struct amdgpu_ttm_tt *gtt = (void *)bo->ttm;
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct ttm_tt *ttm = bo->ttm;
|
||||
struct amdgpu_job *job;
|
||||
unsigned num_dw, num_bytes;
|
||||
dma_addr_t *dma_address;
|
||||
struct dma_fence *fence;
|
||||
uint64_t src_addr, dst_addr;
|
||||
uint64_t flags;
|
||||
int r;
|
||||
|
||||
BUG_ON(adev->mman.buffer_funcs->copy_max_bytes <
|
||||
AMDGPU_GTT_MAX_TRANSFER_SIZE * 8);
|
||||
|
||||
*addr = adev->gmc.gart_start;
|
||||
*addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE *
|
||||
AMDGPU_GPU_PAGE_SIZE;
|
||||
|
||||
num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
|
||||
num_bytes = num_pages * 8;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4 + num_bytes,
|
||||
AMDGPU_IB_POOL_NORMAL, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
src_addr = num_dw * 4;
|
||||
src_addr += job->ibs[0].gpu_addr;
|
||||
|
||||
dst_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
|
||||
dst_addr += window * AMDGPU_GTT_MAX_TRANSFER_SIZE * 8;
|
||||
amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,
|
||||
dst_addr, num_bytes);
|
||||
|
||||
amdgpu_ring_pad_ib(ring, &job->ibs[0]);
|
||||
WARN_ON(job->ibs[0].length_dw > num_dw);
|
||||
|
||||
dma_address = >t->ttm.dma_address[offset >> PAGE_SHIFT];
|
||||
flags = amdgpu_ttm_tt_pte_flags(adev, ttm, mem);
|
||||
r = amdgpu_gart_map(adev, 0, num_pages, dma_address, flags,
|
||||
&job->ibs[0].ptr[num_dw]);
|
||||
if (r)
|
||||
goto error_free;
|
||||
|
||||
r = amdgpu_job_submit(job, &adev->mman.entity,
|
||||
AMDGPU_FENCE_OWNER_UNDEFINED, &fence);
|
||||
if (r)
|
||||
goto error_free;
|
||||
|
||||
dma_fence_put(fence);
|
||||
|
||||
return r;
|
||||
|
||||
error_free:
|
||||
amdgpu_job_free(job);
|
||||
return r;
|
||||
}
|
||||
|
||||
int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
|
||||
uint64_t dst_offset, uint32_t byte_count,
|
||||
struct dma_resv *resv,
|
||||
struct dma_fence **fence, bool direct_submit,
|
||||
bool vm_needs_flush)
|
||||
bool vm_needs_flush, bool tmz)
|
||||
{
|
||||
enum amdgpu_ib_pool_type pool = direct_submit ? AMDGPU_IB_POOL_DIRECT :
|
||||
AMDGPU_IB_POOL_DELAYED;
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct amdgpu_job *job;
|
||||
|
||||
|
@ -2102,8 +2140,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
|
|||
num_loops = DIV_ROUND_UP(byte_count, max_bytes);
|
||||
num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->copy_num_dw, 8);
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4,
|
||||
direct_submit ? AMDGPU_IB_POOL_DIRECT : AMDGPU_IB_POOL_NORMAL, &job);
|
||||
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, pool, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -2125,7 +2162,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
|
|||
uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
|
||||
|
||||
amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_offset,
|
||||
dst_offset, cur_size_in_bytes);
|
||||
dst_offset, cur_size_in_bytes, tmz);
|
||||
|
||||
src_offset += cur_size_in_bytes;
|
||||
dst_offset += cur_size_in_bytes;
|
||||
|
@ -2192,7 +2229,8 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
|
|||
/* for IB padding */
|
||||
num_dw += 64;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, AMDGPU_IB_POOL_NORMAL, &job);
|
||||
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, AMDGPU_IB_POOL_DELAYED,
|
||||
&job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -97,11 +97,11 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
|
|||
uint64_t dst_offset, uint32_t byte_count,
|
||||
struct dma_resv *resv,
|
||||
struct dma_fence **fence, bool direct_submit,
|
||||
bool vm_needs_flush);
|
||||
bool vm_needs_flush, bool tmz);
|
||||
int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
|
||||
struct amdgpu_copy_mem *src,
|
||||
struct amdgpu_copy_mem *dst,
|
||||
uint64_t size,
|
||||
const struct amdgpu_copy_mem *src,
|
||||
const struct amdgpu_copy_mem *dst,
|
||||
uint64_t size, bool tmz,
|
||||
struct dma_resv *resv,
|
||||
struct dma_fence **f);
|
||||
int amdgpu_fill_buffer(struct amdgpu_bo *bo,
|
||||
|
|
|
@ -1056,8 +1056,8 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
|
|||
goto err;
|
||||
}
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(adev, 64,
|
||||
direct ? AMDGPU_IB_POOL_DIRECT : AMDGPU_IB_POOL_NORMAL, &job);
|
||||
r = amdgpu_job_alloc_with_ib(adev, 64, direct ? AMDGPU_IB_POOL_DIRECT :
|
||||
AMDGPU_IB_POOL_DELAYED, &job);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
|
|
|
@ -447,7 +447,7 @@ static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
|||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
|
||||
AMDGPU_IB_POOL_DIRECT, &job);
|
||||
AMDGPU_IB_POOL_DIRECT, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -526,7 +526,8 @@ static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
|||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
|
||||
direct ? AMDGPU_IB_POOL_DIRECT : AMDGPU_IB_POOL_NORMAL, &job);
|
||||
direct ? AMDGPU_IB_POOL_DIRECT :
|
||||
AMDGPU_IB_POOL_DELAYED, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -60,7 +60,10 @@ void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
|
|||
amdgpu_ring_alloc(ring, 32);
|
||||
amdgpu_ring_emit_reg_write_reg_wait(ring, reg0, reg1,
|
||||
ref, mask);
|
||||
amdgpu_fence_emit_polling(ring, &seq);
|
||||
r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
|
||||
if (r)
|
||||
goto failed_undo;
|
||||
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
|
||||
|
@ -82,6 +85,9 @@ void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
|
|||
|
||||
return;
|
||||
|
||||
failed_undo:
|
||||
amdgpu_ring_undo(ring);
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
failed_kiq:
|
||||
pr_err("failed to write reg %x wait reg %x\n", reg0, reg1);
|
||||
}
|
||||
|
|
|
@ -726,7 +726,7 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
|
|||
* @adev: amdgpu_device pointer
|
||||
* @vm: VM to clear BO from
|
||||
* @bo: BO to clear
|
||||
* @direct: use a direct update
|
||||
* @immediate: use an immediate update
|
||||
*
|
||||
* Root PD needs to be reserved when calling this.
|
||||
*
|
||||
|
@ -736,7 +736,7 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
|
|||
static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm,
|
||||
struct amdgpu_bo *bo,
|
||||
bool direct)
|
||||
bool immediate)
|
||||
{
|
||||
struct ttm_operation_ctx ctx = { true, false };
|
||||
unsigned level = adev->vm_manager.root_level;
|
||||
|
@ -795,7 +795,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
|
|||
memset(¶ms, 0, sizeof(params));
|
||||
params.adev = adev;
|
||||
params.vm = vm;
|
||||
params.direct = direct;
|
||||
params.immediate = immediate;
|
||||
|
||||
r = vm->update_funcs->prepare(¶ms, NULL, AMDGPU_SYNC_EXPLICIT);
|
||||
if (r)
|
||||
|
@ -850,11 +850,11 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
|
|||
* @adev: amdgpu_device pointer
|
||||
* @vm: requesting vm
|
||||
* @level: the page table level
|
||||
* @direct: use a direct update
|
||||
* @immediate: use a immediate update
|
||||
* @bp: resulting BO allocation parameters
|
||||
*/
|
||||
static void amdgpu_vm_bo_param(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
int level, bool direct,
|
||||
int level, bool immediate,
|
||||
struct amdgpu_bo_param *bp)
|
||||
{
|
||||
memset(bp, 0, sizeof(*bp));
|
||||
|
@ -870,7 +870,7 @@ static void amdgpu_vm_bo_param(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
else if (!vm->root.base.bo || vm->root.base.bo->shadow)
|
||||
bp->flags |= AMDGPU_GEM_CREATE_SHADOW;
|
||||
bp->type = ttm_bo_type_kernel;
|
||||
bp->no_wait_gpu = direct;
|
||||
bp->no_wait_gpu = immediate;
|
||||
if (vm->root.base.bo)
|
||||
bp->resv = vm->root.base.bo->tbo.base.resv;
|
||||
}
|
||||
|
@ -881,7 +881,7 @@ static void amdgpu_vm_bo_param(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
* @adev: amdgpu_device pointer
|
||||
* @vm: VM to allocate page tables for
|
||||
* @cursor: Which page table to allocate
|
||||
* @direct: use a direct update
|
||||
* @immediate: use an immediate update
|
||||
*
|
||||
* Make sure a specific page table or directory is allocated.
|
||||
*
|
||||
|
@ -892,7 +892,7 @@ static void amdgpu_vm_bo_param(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
static int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm,
|
||||
struct amdgpu_vm_pt_cursor *cursor,
|
||||
bool direct)
|
||||
bool immediate)
|
||||
{
|
||||
struct amdgpu_vm_pt *entry = cursor->entry;
|
||||
struct amdgpu_bo_param bp;
|
||||
|
@ -913,7 +913,7 @@ static int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
|
|||
if (entry->base.bo)
|
||||
return 0;
|
||||
|
||||
amdgpu_vm_bo_param(adev, vm, cursor->level, direct, &bp);
|
||||
amdgpu_vm_bo_param(adev, vm, cursor->level, immediate, &bp);
|
||||
|
||||
r = amdgpu_bo_create(adev, &bp, &pt);
|
||||
if (r)
|
||||
|
@ -925,7 +925,7 @@ static int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
|
|||
pt->parent = amdgpu_bo_ref(cursor->parent->base.bo);
|
||||
amdgpu_vm_bo_base_init(&entry->base, vm, pt);
|
||||
|
||||
r = amdgpu_vm_clear_bo(adev, vm, pt, direct);
|
||||
r = amdgpu_vm_clear_bo(adev, vm, pt, immediate);
|
||||
if (r)
|
||||
goto error_free_pt;
|
||||
|
||||
|
@ -1276,7 +1276,7 @@ static void amdgpu_vm_invalidate_pds(struct amdgpu_device *adev,
|
|||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @vm: requested vm
|
||||
* @direct: submit directly to the paging queue
|
||||
* @immediate: submit immediately to the paging queue
|
||||
*
|
||||
* Makes sure all directories are up to date.
|
||||
*
|
||||
|
@ -1284,7 +1284,7 @@ static void amdgpu_vm_invalidate_pds(struct amdgpu_device *adev,
|
|||
* 0 for success, error for failure.
|
||||
*/
|
||||
int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm, bool direct)
|
||||
struct amdgpu_vm *vm, bool immediate)
|
||||
{
|
||||
struct amdgpu_vm_update_params params;
|
||||
int r;
|
||||
|
@ -1295,7 +1295,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
|
|||
memset(¶ms, 0, sizeof(params));
|
||||
params.adev = adev;
|
||||
params.vm = vm;
|
||||
params.direct = direct;
|
||||
params.immediate = immediate;
|
||||
|
||||
r = vm->update_funcs->prepare(¶ms, NULL, AMDGPU_SYNC_EXPLICIT);
|
||||
if (r)
|
||||
|
@ -1446,20 +1446,24 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
|
|||
uint64_t incr, entry_end, pe_start;
|
||||
struct amdgpu_bo *pt;
|
||||
|
||||
if (flags & (AMDGPU_PTE_VALID | AMDGPU_PTE_PRT)) {
|
||||
if (!params->unlocked) {
|
||||
/* make sure that the page tables covering the
|
||||
* address range are actually allocated
|
||||
*/
|
||||
r = amdgpu_vm_alloc_pts(params->adev, params->vm,
|
||||
&cursor, params->direct);
|
||||
&cursor, params->immediate);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
shift = amdgpu_vm_level_shift(adev, cursor.level);
|
||||
parent_shift = amdgpu_vm_level_shift(adev, cursor.level - 1);
|
||||
if (adev->asic_type < CHIP_VEGA10 &&
|
||||
(flags & AMDGPU_PTE_VALID)) {
|
||||
if (params->unlocked) {
|
||||
/* Unlocked updates are only allowed on the leaves */
|
||||
if (amdgpu_vm_pt_descendant(adev, &cursor))
|
||||
continue;
|
||||
} else if (adev->asic_type < CHIP_VEGA10 &&
|
||||
(flags & AMDGPU_PTE_VALID)) {
|
||||
/* No huge page support before GMC v9 */
|
||||
if (cursor.level != AMDGPU_VM_PTB) {
|
||||
if (!amdgpu_vm_pt_descendant(adev, &cursor))
|
||||
|
@ -1557,7 +1561,8 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
|
|||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @vm: requested vm
|
||||
* @direct: direct submission in a page fault
|
||||
* @immediate: immediate submission in a page fault
|
||||
* @unlocked: unlocked invalidation during MM callback
|
||||
* @resv: fences we need to sync to
|
||||
* @start: start of mapped range
|
||||
* @last: last mapped entry
|
||||
|
@ -1572,8 +1577,8 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
|
|||
* 0 for success, -EINVAL for failure.
|
||||
*/
|
||||
static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm, bool direct,
|
||||
struct dma_resv *resv,
|
||||
struct amdgpu_vm *vm, bool immediate,
|
||||
bool unlocked, struct dma_resv *resv,
|
||||
uint64_t start, uint64_t last,
|
||||
uint64_t flags, uint64_t addr,
|
||||
dma_addr_t *pages_addr,
|
||||
|
@ -1586,8 +1591,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
|||
memset(¶ms, 0, sizeof(params));
|
||||
params.adev = adev;
|
||||
params.vm = vm;
|
||||
params.direct = direct;
|
||||
params.immediate = immediate;
|
||||
params.pages_addr = pages_addr;
|
||||
params.unlocked = unlocked;
|
||||
|
||||
/* Implicitly sync to command submissions in the same VM before
|
||||
* unmapping. Sync to moving fences before mapping.
|
||||
|
@ -1603,11 +1609,12 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
|||
goto error_unlock;
|
||||
}
|
||||
|
||||
if (flags & (AMDGPU_PTE_VALID | AMDGPU_PTE_PRT)) {
|
||||
struct amdgpu_bo *root = vm->root.base.bo;
|
||||
if (!unlocked && !dma_fence_is_signaled(vm->last_unlocked)) {
|
||||
struct dma_fence *tmp = dma_fence_get_stub();
|
||||
|
||||
if (!dma_fence_is_signaled(vm->last_direct))
|
||||
amdgpu_bo_fence(root, vm->last_direct, true);
|
||||
amdgpu_bo_fence(vm->root.base.bo, vm->last_unlocked, true);
|
||||
swap(vm->last_unlocked, tmp);
|
||||
dma_fence_put(tmp);
|
||||
}
|
||||
|
||||
r = vm->update_funcs->prepare(¶ms, resv, sync_mode);
|
||||
|
@ -1721,7 +1728,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
|
|||
}
|
||||
|
||||
last = min((uint64_t)mapping->last, start + max_entries - 1);
|
||||
r = amdgpu_vm_bo_update_mapping(adev, vm, false, resv,
|
||||
r = amdgpu_vm_bo_update_mapping(adev, vm, false, false, resv,
|
||||
start, last, flags, addr,
|
||||
dma_addr, fence);
|
||||
if (r)
|
||||
|
@ -1784,6 +1791,10 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
|
|||
|
||||
if (bo) {
|
||||
flags = amdgpu_ttm_tt_pte_flags(adev, bo->tbo.ttm, mem);
|
||||
|
||||
if (amdgpu_bo_encrypted(bo))
|
||||
flags |= AMDGPU_PTE_TMZ;
|
||||
|
||||
bo_adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
} else {
|
||||
flags = 0x0;
|
||||
|
@ -2014,7 +2025,7 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
|
|||
mapping->start < AMDGPU_GMC_HOLE_START)
|
||||
init_pte_value = AMDGPU_PTE_DEFAULT_ATC;
|
||||
|
||||
r = amdgpu_vm_bo_update_mapping(adev, vm, false, resv,
|
||||
r = amdgpu_vm_bo_update_mapping(adev, vm, false, false, resv,
|
||||
mapping->start, mapping->last,
|
||||
init_pte_value, 0, NULL, &f);
|
||||
amdgpu_vm_free_mapping(adev, vm, mapping, f);
|
||||
|
@ -2578,7 +2589,7 @@ bool amdgpu_vm_evictable(struct amdgpu_bo *bo)
|
|||
return false;
|
||||
|
||||
/* Don't evict VM page tables while they are updated */
|
||||
if (!dma_fence_is_signaled(bo_base->vm->last_direct)) {
|
||||
if (!dma_fence_is_signaled(bo_base->vm->last_unlocked)) {
|
||||
amdgpu_vm_eviction_unlock(bo_base->vm);
|
||||
return false;
|
||||
}
|
||||
|
@ -2755,7 +2766,7 @@ long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout)
|
|||
if (timeout <= 0)
|
||||
return timeout;
|
||||
|
||||
return dma_fence_wait_timeout(vm->last_direct, true, timeout);
|
||||
return dma_fence_wait_timeout(vm->last_unlocked, true, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2791,7 +2802,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
|
||||
|
||||
/* create scheduler entities for page table updates */
|
||||
r = drm_sched_entity_init(&vm->direct, DRM_SCHED_PRIORITY_NORMAL,
|
||||
r = drm_sched_entity_init(&vm->immediate, DRM_SCHED_PRIORITY_NORMAL,
|
||||
adev->vm_manager.vm_pte_scheds,
|
||||
adev->vm_manager.vm_pte_num_scheds, NULL);
|
||||
if (r)
|
||||
|
@ -2801,7 +2812,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
adev->vm_manager.vm_pte_scheds,
|
||||
adev->vm_manager.vm_pte_num_scheds, NULL);
|
||||
if (r)
|
||||
goto error_free_direct;
|
||||
goto error_free_immediate;
|
||||
|
||||
vm->pte_support_ats = false;
|
||||
vm->is_compute_context = false;
|
||||
|
@ -2827,7 +2838,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
else
|
||||
vm->update_funcs = &amdgpu_vm_sdma_funcs;
|
||||
vm->last_update = NULL;
|
||||
vm->last_direct = dma_fence_get_stub();
|
||||
vm->last_unlocked = dma_fence_get_stub();
|
||||
|
||||
mutex_init(&vm->eviction_lock);
|
||||
vm->evicting = false;
|
||||
|
@ -2881,11 +2892,11 @@ error_free_root:
|
|||
vm->root.base.bo = NULL;
|
||||
|
||||
error_free_delayed:
|
||||
dma_fence_put(vm->last_direct);
|
||||
dma_fence_put(vm->last_unlocked);
|
||||
drm_sched_entity_destroy(&vm->delayed);
|
||||
|
||||
error_free_direct:
|
||||
drm_sched_entity_destroy(&vm->direct);
|
||||
error_free_immediate:
|
||||
drm_sched_entity_destroy(&vm->immediate);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -3082,8 +3093,8 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
|||
vm->pasid = 0;
|
||||
}
|
||||
|
||||
dma_fence_wait(vm->last_direct, false);
|
||||
dma_fence_put(vm->last_direct);
|
||||
dma_fence_wait(vm->last_unlocked, false);
|
||||
dma_fence_put(vm->last_unlocked);
|
||||
|
||||
list_for_each_entry_safe(mapping, tmp, &vm->freed, list) {
|
||||
if (mapping->flags & AMDGPU_PTE_PRT && prt_fini_needed) {
|
||||
|
@ -3100,7 +3111,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
|||
amdgpu_bo_unref(&root);
|
||||
WARN_ON(vm->root.base.bo);
|
||||
|
||||
drm_sched_entity_destroy(&vm->direct);
|
||||
drm_sched_entity_destroy(&vm->immediate);
|
||||
drm_sched_entity_destroy(&vm->delayed);
|
||||
|
||||
if (!RB_EMPTY_ROOT(&vm->va.rb_root)) {
|
||||
|
@ -3333,8 +3344,8 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, unsigned int pasid,
|
|||
value = 0;
|
||||
}
|
||||
|
||||
r = amdgpu_vm_bo_update_mapping(adev, vm, true, NULL, addr, addr + 1,
|
||||
flags, value, NULL, NULL);
|
||||
r = amdgpu_vm_bo_update_mapping(adev, vm, true, false, NULL, addr,
|
||||
addr + 1, flags, value, NULL, NULL);
|
||||
if (r)
|
||||
goto error_unlock;
|
||||
|
||||
|
|
|
@ -54,6 +54,9 @@ struct amdgpu_bo_list_entry;
|
|||
#define AMDGPU_PTE_SYSTEM (1ULL << 1)
|
||||
#define AMDGPU_PTE_SNOOPED (1ULL << 2)
|
||||
|
||||
/* RV+ */
|
||||
#define AMDGPU_PTE_TMZ (1ULL << 3)
|
||||
|
||||
/* VI only */
|
||||
#define AMDGPU_PTE_EXECUTABLE (1ULL << 4)
|
||||
|
||||
|
@ -203,9 +206,14 @@ struct amdgpu_vm_update_params {
|
|||
struct amdgpu_vm *vm;
|
||||
|
||||
/**
|
||||
* @direct: if changes should be made directly
|
||||
* @immediate: if changes should be made immediately
|
||||
*/
|
||||
bool direct;
|
||||
bool immediate;
|
||||
|
||||
/**
|
||||
* @unlocked: true if the root BO is not locked
|
||||
*/
|
||||
bool unlocked;
|
||||
|
||||
/**
|
||||
* @pages_addr:
|
||||
|
@ -271,11 +279,11 @@ struct amdgpu_vm {
|
|||
struct dma_fence *last_update;
|
||||
|
||||
/* Scheduler entities for page table updates */
|
||||
struct drm_sched_entity direct;
|
||||
struct drm_sched_entity immediate;
|
||||
struct drm_sched_entity delayed;
|
||||
|
||||
/* Last submission to the scheduler entities */
|
||||
struct dma_fence *last_direct;
|
||||
/* Last unlocked submission to the scheduler entities */
|
||||
struct dma_fence *last_unlocked;
|
||||
|
||||
unsigned int pasid;
|
||||
/* dedicated to vm */
|
||||
|
@ -376,7 +384,7 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
void *param);
|
||||
int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync);
|
||||
int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm, bool direct);
|
||||
struct amdgpu_vm *vm, bool immediate);
|
||||
int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm,
|
||||
struct dma_fence **fence);
|
||||
|
|
|
@ -84,7 +84,7 @@ static int amdgpu_vm_cpu_update(struct amdgpu_vm_update_params *p,
|
|||
|
||||
pe += (unsigned long)amdgpu_bo_kptr(bo);
|
||||
|
||||
trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags, p->direct);
|
||||
trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags, p->immediate);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
value = p->pages_addr ?
|
||||
|
|
|
@ -61,11 +61,12 @@ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
|
|||
struct dma_resv *resv,
|
||||
enum amdgpu_sync_mode sync_mode)
|
||||
{
|
||||
enum amdgpu_ib_pool_type pool = p->immediate ? AMDGPU_IB_POOL_IMMEDIATE
|
||||
: AMDGPU_IB_POOL_DELAYED;
|
||||
unsigned int ndw = AMDGPU_VM_SDMA_MIN_NUM_DW;
|
||||
int r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4,
|
||||
p->direct ? AMDGPU_IB_POOL_VM : AMDGPU_IB_POOL_NORMAL, &p->job);
|
||||
r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4, pool, &p->job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -91,11 +92,11 @@ static int amdgpu_vm_sdma_commit(struct amdgpu_vm_update_params *p,
|
|||
{
|
||||
struct amdgpu_ib *ib = p->job->ibs;
|
||||
struct drm_sched_entity *entity;
|
||||
struct dma_fence *f, *tmp;
|
||||
struct amdgpu_ring *ring;
|
||||
struct dma_fence *f;
|
||||
int r;
|
||||
|
||||
entity = p->direct ? &p->vm->direct : &p->vm->delayed;
|
||||
entity = p->immediate ? &p->vm->immediate : &p->vm->delayed;
|
||||
ring = container_of(entity->rq->sched, struct amdgpu_ring, sched);
|
||||
|
||||
WARN_ON(ib->length_dw == 0);
|
||||
|
@ -105,15 +106,16 @@ static int amdgpu_vm_sdma_commit(struct amdgpu_vm_update_params *p,
|
|||
if (r)
|
||||
goto error;
|
||||
|
||||
if (p->direct) {
|
||||
tmp = dma_fence_get(f);
|
||||
swap(p->vm->last_direct, tmp);
|
||||
if (p->unlocked) {
|
||||
struct dma_fence *tmp = dma_fence_get(f);
|
||||
|
||||
swap(p->vm->last_unlocked, f);
|
||||
dma_fence_put(tmp);
|
||||
} else {
|
||||
dma_resv_add_shared_fence(p->vm->root.base.bo->tbo.base.resv, f);
|
||||
amdgpu_bo_fence(p->vm->root.base.bo, f, true);
|
||||
}
|
||||
|
||||
if (fence && !p->direct)
|
||||
if (fence && !p->immediate)
|
||||
swap(*fence, f);
|
||||
dma_fence_put(f);
|
||||
return 0;
|
||||
|
@ -143,7 +145,7 @@ static void amdgpu_vm_sdma_copy_ptes(struct amdgpu_vm_update_params *p,
|
|||
src += p->num_dw_left * 4;
|
||||
|
||||
pe += amdgpu_gmc_sign_extend(bo->tbo.offset);
|
||||
trace_amdgpu_vm_copy_ptes(pe, src, count, p->direct);
|
||||
trace_amdgpu_vm_copy_ptes(pe, src, count, p->immediate);
|
||||
|
||||
amdgpu_vm_copy_pte(p->adev, ib, pe, src, count);
|
||||
}
|
||||
|
@ -170,7 +172,7 @@ static void amdgpu_vm_sdma_set_ptes(struct amdgpu_vm_update_params *p,
|
|||
struct amdgpu_ib *ib = p->job->ibs;
|
||||
|
||||
pe += amdgpu_gmc_sign_extend(bo->tbo.offset);
|
||||
trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags, p->direct);
|
||||
trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags, p->immediate);
|
||||
if (count < 3) {
|
||||
amdgpu_vm_write_pte(p->adev, ib, pe, addr | flags,
|
||||
count, incr);
|
||||
|
@ -199,6 +201,8 @@ static int amdgpu_vm_sdma_update(struct amdgpu_vm_update_params *p,
|
|||
uint64_t addr, unsigned count, uint32_t incr,
|
||||
uint64_t flags)
|
||||
{
|
||||
enum amdgpu_ib_pool_type pool = p->immediate ? AMDGPU_IB_POOL_IMMEDIATE
|
||||
: AMDGPU_IB_POOL_DELAYED;
|
||||
unsigned int i, ndw, nptes;
|
||||
uint64_t *pte;
|
||||
int r;
|
||||
|
@ -224,8 +228,8 @@ static int amdgpu_vm_sdma_update(struct amdgpu_vm_update_params *p,
|
|||
ndw = max(ndw, AMDGPU_VM_SDMA_MIN_NUM_DW);
|
||||
ndw = min(ndw, AMDGPU_VM_SDMA_MAX_NUM_DW);
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4,
|
||||
p->direct ? AMDGPU_IB_POOL_VM : AMDGPU_IB_POOL_NORMAL, &p->job);
|
||||
r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4, pool,
|
||||
&p->job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -395,7 +395,9 @@ int amdgpu_xgmi_set_pstate(struct amdgpu_device *adev, int pstate)
|
|||
bool init_low = hive->pstate == AMDGPU_XGMI_PSTATE_UNKNOWN;
|
||||
|
||||
/* fw bug so temporarily disable pstate switching */
|
||||
if (!hive || adev->asic_type == CHIP_VEGA20)
|
||||
return 0;
|
||||
|
||||
if (!hive || adev->asic_type != CHIP_VEGA20)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&hive->hive_lock);
|
||||
|
|
|
@ -1313,7 +1313,8 @@ static void cik_sdma_set_irq_funcs(struct amdgpu_device *adev)
|
|||
static void cik_sdma_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count)
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0);
|
||||
ib->ptr[ib->length_dw++] = byte_count;
|
||||
|
|
|
@ -3037,7 +3037,7 @@ static int gfx_v10_0_rlc_backdoor_autoload_enable(struct amdgpu_device *adev);
|
|||
static int gfx_v10_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev);
|
||||
static void gfx_v10_0_ring_emit_ce_meta(struct amdgpu_ring *ring, bool resume);
|
||||
static void gfx_v10_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume);
|
||||
static void gfx_v10_0_ring_emit_tmz(struct amdgpu_ring *ring, bool start);
|
||||
static void gfx_v10_0_ring_emit_frame_cntl(struct amdgpu_ring *ring, bool start, bool secure);
|
||||
|
||||
static void gfx10_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue_mask)
|
||||
{
|
||||
|
@ -7095,6 +7095,10 @@ static int gfx_v10_0_set_powergating_state(void *handle,
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
bool enable = (state == AMD_PG_STATE_GATE);
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
|
@ -7115,6 +7119,9 @@ static int gfx_v10_0_set_clockgating_state(void *handle,
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
|
@ -7427,7 +7434,8 @@ static void gfx_v10_0_ring_emit_sb(struct amdgpu_ring *ring)
|
|||
amdgpu_ring_write(ring, 0);
|
||||
}
|
||||
|
||||
static void gfx_v10_0_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t flags)
|
||||
static void gfx_v10_0_ring_emit_cntxcntl(struct amdgpu_ring *ring,
|
||||
uint32_t flags)
|
||||
{
|
||||
uint32_t dw2 = 0;
|
||||
|
||||
|
@ -7435,8 +7443,6 @@ static void gfx_v10_0_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t flag
|
|||
gfx_v10_0_ring_emit_ce_meta(ring,
|
||||
(!amdgpu_sriov_vf(ring->adev) && flags & AMDGPU_IB_PREEMPTED) ? true : false);
|
||||
|
||||
gfx_v10_0_ring_emit_tmz(ring, true);
|
||||
|
||||
dw2 |= 0x80000000; /* set load_enable otherwise this package is just NOPs */
|
||||
if (flags & AMDGPU_HAVE_CTX_SWITCH) {
|
||||
/* set load_global_config & load_global_uconfig */
|
||||
|
@ -7593,10 +7599,13 @@ static void gfx_v10_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume)
|
|||
sizeof(de_payload) >> 2);
|
||||
}
|
||||
|
||||
static void gfx_v10_0_ring_emit_tmz(struct amdgpu_ring *ring, bool start)
|
||||
static void gfx_v10_0_ring_emit_frame_cntl(struct amdgpu_ring *ring, bool start,
|
||||
bool secure)
|
||||
{
|
||||
uint32_t v = secure ? FRAME_TMZ : 0;
|
||||
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_FRAME_CONTROL, 0));
|
||||
amdgpu_ring_write(ring, FRAME_CMD(start ? 0 : 1)); /* frame_end */
|
||||
amdgpu_ring_write(ring, v | FRAME_CMD(start ? 0 : 1));
|
||||
}
|
||||
|
||||
static void gfx_v10_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg,
|
||||
|
@ -8050,7 +8059,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
|
|||
.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_tmz = gfx_v10_0_ring_emit_tmz,
|
||||
.emit_frame_cntl = gfx_v10_0_ring_emit_frame_cntl,
|
||||
.emit_wreg = gfx_v10_0_ring_emit_wreg,
|
||||
.emit_reg_wait = gfx_v10_0_ring_emit_reg_wait,
|
||||
.emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait,
|
||||
|
|
|
@ -2531,7 +2531,7 @@ static void gfx_v9_0_init_sq_config(struct amdgpu_device *adev)
|
|||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_v9_0_constants_init(struct amdgpu_device *adev)
|
||||
|
@ -4054,9 +4054,8 @@ static uint64_t gfx_v9_0_kiq_read_clock(struct amdgpu_device *adev)
|
|||
|
||||
spin_lock_irqsave(&kiq->ring_lock, flags);
|
||||
if (amdgpu_device_wb_get(adev, ®_val_offs)) {
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
pr_err("critical bug! too many kiq readers\n");
|
||||
goto failed_kiq_read;
|
||||
goto failed_unlock;
|
||||
}
|
||||
amdgpu_ring_alloc(ring, 32);
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_COPY_DATA, 4));
|
||||
|
@ -4070,7 +4069,10 @@ static uint64_t gfx_v9_0_kiq_read_clock(struct amdgpu_device *adev)
|
|||
reg_val_offs * 4));
|
||||
amdgpu_ring_write(ring, upper_32_bits(adev->wb.gpu_addr +
|
||||
reg_val_offs * 4));
|
||||
amdgpu_fence_emit_polling(ring, &seq);
|
||||
r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
|
||||
if (r)
|
||||
goto failed_undo;
|
||||
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
|
||||
|
@ -4102,7 +4104,13 @@ static uint64_t gfx_v9_0_kiq_read_clock(struct amdgpu_device *adev)
|
|||
amdgpu_device_wb_free(adev, reg_val_offs);
|
||||
return value;
|
||||
|
||||
failed_undo:
|
||||
amdgpu_ring_undo(ring);
|
||||
failed_unlock:
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
failed_kiq_read:
|
||||
if (reg_val_offs)
|
||||
amdgpu_device_wb_free(adev, reg_val_offs);
|
||||
pr_err("failed to read gpu clock\n");
|
||||
return ~0;
|
||||
}
|
||||
|
@ -5434,10 +5442,13 @@ static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring)
|
|||
amdgpu_ring_write_multiple(ring, (void *)&de_payload, sizeof(de_payload) >> 2);
|
||||
}
|
||||
|
||||
static void gfx_v9_0_ring_emit_tmz(struct amdgpu_ring *ring, bool start)
|
||||
static void gfx_v9_0_ring_emit_frame_cntl(struct amdgpu_ring *ring, bool start,
|
||||
bool secure)
|
||||
{
|
||||
uint32_t v = secure ? FRAME_TMZ : 0;
|
||||
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_FRAME_CONTROL, 0));
|
||||
amdgpu_ring_write(ring, FRAME_CMD(start ? 0 : 1)); /* frame_end */
|
||||
amdgpu_ring_write(ring, v | FRAME_CMD(start ? 0 : 1));
|
||||
}
|
||||
|
||||
static void gfx_v9_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t flags)
|
||||
|
@ -5447,8 +5458,6 @@ static void gfx_v9_ring_emit_cntxcntl(struct amdgpu_ring *ring, uint32_t flags)
|
|||
if (amdgpu_sriov_vf(ring->adev))
|
||||
gfx_v9_0_ring_emit_ce_meta(ring);
|
||||
|
||||
gfx_v9_0_ring_emit_tmz(ring, true);
|
||||
|
||||
dw2 |= 0x80000000; /* set load_enable otherwise this package is just NOPs */
|
||||
if (flags & AMDGPU_HAVE_CTX_SWITCH) {
|
||||
/* set load_global_config & load_global_uconfig */
|
||||
|
@ -6691,7 +6700,7 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_gfx = {
|
|||
.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_tmz = gfx_v9_0_ring_emit_tmz,
|
||||
.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,
|
||||
.emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait,
|
||||
|
|
|
@ -372,7 +372,8 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
|||
* translation. Avoid this by doing the invalidation from the SDMA
|
||||
* itself.
|
||||
*/
|
||||
r = amdgpu_job_alloc_with_ib(adev, 16 * 4, AMDGPU_IB_POOL_VM, &job);
|
||||
r = amdgpu_job_alloc_with_ib(adev, 16 * 4, AMDGPU_IB_POOL_IMMEDIATE,
|
||||
&job);
|
||||
if (r)
|
||||
goto error_alloc;
|
||||
|
||||
|
@ -426,7 +427,13 @@ static int gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
|
|||
amdgpu_ring_alloc(ring, kiq->pmf->invalidate_tlbs_size + 8);
|
||||
kiq->pmf->kiq_invalidate_tlbs(ring,
|
||||
pasid, flush_type, all_hub);
|
||||
amdgpu_fence_emit_polling(ring, &seq);
|
||||
r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
|
||||
if (r) {
|
||||
amdgpu_ring_undo(ring);
|
||||
spin_unlock(&adev->gfx.kiq.ring_lock);
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock(&adev->gfx.kiq.ring_lock);
|
||||
r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
|
||||
|
|
|
@ -621,7 +621,13 @@ static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
|
|||
pasid, 2, all_hub);
|
||||
kiq->pmf->kiq_invalidate_tlbs(ring,
|
||||
pasid, flush_type, all_hub);
|
||||
amdgpu_fence_emit_polling(ring, &seq);
|
||||
r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
|
||||
if (r) {
|
||||
amdgpu_ring_undo(ring);
|
||||
spin_unlock(&adev->gfx.kiq.ring_lock);
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock(&adev->gfx.kiq.ring_lock);
|
||||
r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#define AI_MAILBOX_POLL_ACK_TIMEDOUT 500
|
||||
#define AI_MAILBOX_POLL_MSG_TIMEDOUT 12000
|
||||
#define AI_MAILBOX_POLL_FLR_TIMEDOUT 500
|
||||
#define AI_MAILBOX_POLL_FLR_TIMEDOUT 5000
|
||||
|
||||
enum idh_request {
|
||||
IDH_REQ_GPU_INIT_ACCESS = 1,
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#define NV_MAILBOX_POLL_ACK_TIMEDOUT 500
|
||||
#define NV_MAILBOX_POLL_MSG_TIMEDOUT 6000
|
||||
#define NV_MAILBOX_POLL_FLR_TIMEDOUT 500
|
||||
#define NV_MAILBOX_POLL_FLR_TIMEDOUT 5000
|
||||
|
||||
enum idh_request {
|
||||
IDH_REQ_GPU_INIT_ACCESS = 1,
|
||||
|
|
|
@ -73,6 +73,22 @@
|
|||
#define SDMA_OP_AQL_COPY 0
|
||||
#define SDMA_OP_AQL_BARRIER_OR 0
|
||||
|
||||
#define SDMA_GCR_RANGE_IS_PA (1 << 18)
|
||||
#define SDMA_GCR_SEQ(x) (((x) & 0x3) << 16)
|
||||
#define SDMA_GCR_GL2_WB (1 << 15)
|
||||
#define SDMA_GCR_GL2_INV (1 << 14)
|
||||
#define SDMA_GCR_GL2_DISCARD (1 << 13)
|
||||
#define SDMA_GCR_GL2_RANGE(x) (((x) & 0x3) << 11)
|
||||
#define SDMA_GCR_GL2_US (1 << 10)
|
||||
#define SDMA_GCR_GL1_INV (1 << 9)
|
||||
#define SDMA_GCR_GLV_INV (1 << 8)
|
||||
#define SDMA_GCR_GLK_INV (1 << 7)
|
||||
#define SDMA_GCR_GLK_WB (1 << 6)
|
||||
#define SDMA_GCR_GLM_INV (1 << 5)
|
||||
#define SDMA_GCR_GLM_WB (1 << 4)
|
||||
#define SDMA_GCR_GL1_RANGE(x) (((x) & 0x3) << 2)
|
||||
#define SDMA_GCR_GLI_INV(x) (((x) & 0x3) << 0)
|
||||
|
||||
/*define for op field*/
|
||||
#define SDMA_PKT_HEADER_op_offset 0
|
||||
#define SDMA_PKT_HEADER_op_mask 0x000000FF
|
||||
|
|
|
@ -498,8 +498,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP &&
|
||||
!amdgpu_sriov_vf(adev))
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
|
|
|
@ -306,6 +306,7 @@
|
|||
#define PACKET3_GET_LOD_STATS 0x8E
|
||||
#define PACKET3_DRAW_MULTI_PREAMBLE 0x8F
|
||||
#define PACKET3_FRAME_CONTROL 0x90
|
||||
# define FRAME_TMZ (1 << 0)
|
||||
# define FRAME_CMD(x) ((x) << 28)
|
||||
/*
|
||||
* x=0: tmz_begin
|
||||
|
|
|
@ -137,6 +137,8 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
|
|||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
break;
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
|
||||
if (err) {
|
||||
|
|
|
@ -1200,7 +1200,8 @@ static void sdma_v2_4_set_irq_funcs(struct amdgpu_device *adev)
|
|||
static void sdma_v2_4_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count)
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
|
||||
SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
|
||||
|
|
|
@ -1638,7 +1638,8 @@ static void sdma_v3_0_set_irq_funcs(struct amdgpu_device *adev)
|
|||
static void sdma_v3_0_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count)
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
|
||||
SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
|
||||
|
|
|
@ -2458,10 +2458,12 @@ static void sdma_v4_0_set_irq_funcs(struct amdgpu_device *adev)
|
|||
static void sdma_v4_0_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count)
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
|
||||
SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
|
||||
SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR) |
|
||||
SDMA_PKT_COPY_LINEAR_HEADER_TMZ(tmz ? 1 : 0);
|
||||
ib->ptr[ib->length_dw++] = byte_count - 1;
|
||||
ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
|
||||
ib->ptr[ib->length_dw++] = lower_32_bits(src_offset);
|
||||
|
|
|
@ -410,6 +410,18 @@ static void sdma_v5_0_ring_emit_ib(struct amdgpu_ring *ring,
|
|||
unsigned vmid = AMDGPU_JOB_GET_VMID(job);
|
||||
uint64_t csa_mc_addr = amdgpu_sdma_get_csa_mc_addr(ring, vmid);
|
||||
|
||||
/* Invalidate L2, because if we don't do it, we might get stale cache
|
||||
* lines from previous IBs.
|
||||
*/
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_GCR_REQ));
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, (SDMA_GCR_GL2_INV |
|
||||
SDMA_GCR_GL2_WB |
|
||||
SDMA_GCR_GLM_INV |
|
||||
SDMA_GCR_GLM_WB) << 16);
|
||||
amdgpu_ring_write(ring, 0xffffff80);
|
||||
amdgpu_ring_write(ring, 0xffff);
|
||||
|
||||
/* An IB packet must end on a 8 DW boundary--the next dword
|
||||
* must be on a 8-dword boundary. Our IB packet below is 6
|
||||
* dwords long, thus add x number of NOPs, such that, in
|
||||
|
@ -1634,7 +1646,7 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = {
|
|||
SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
|
||||
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 * 2 +
|
||||
10 + 10 + 10, /* sdma_v5_0_ring_emit_fence x3 for user fence, vm fence */
|
||||
.emit_ib_size = 7 + 6, /* sdma_v5_0_ring_emit_ib */
|
||||
.emit_ib_size = 5 + 7 + 6, /* sdma_v5_0_ring_emit_ib */
|
||||
.emit_ib = sdma_v5_0_ring_emit_ib,
|
||||
.emit_fence = sdma_v5_0_ring_emit_fence,
|
||||
.emit_pipeline_sync = sdma_v5_0_ring_emit_pipeline_sync,
|
||||
|
@ -1694,10 +1706,12 @@ static void sdma_v5_0_set_irq_funcs(struct amdgpu_device *adev)
|
|||
static void sdma_v5_0_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count)
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
|
||||
SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
|
||||
SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR) |
|
||||
SDMA_PKT_COPY_LINEAR_HEADER_TMZ(tmz ? 1 : 0);
|
||||
ib->ptr[ib->length_dw++] = byte_count - 1;
|
||||
ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
|
||||
ib->ptr[ib->length_dw++] = lower_32_bits(src_offset);
|
||||
|
|
|
@ -776,7 +776,8 @@ static void si_dma_set_irq_funcs(struct amdgpu_device *adev)
|
|||
static void si_dma_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count)
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_COPY,
|
||||
1, 0, 0, byte_count);
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
#define RREG32_SOC15(ip, inst, reg) \
|
||||
RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg)
|
||||
|
||||
#define RREG32_SOC15_NO_KIQ(ip, inst, reg) \
|
||||
RREG32_NO_KIQ(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg)
|
||||
|
||||
#define RREG32_SOC15_OFFSET(ip, inst, reg, offset) \
|
||||
RREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset)
|
||||
|
||||
|
|
|
@ -286,6 +286,7 @@
|
|||
#define PACKET3_WAIT_ON_DE_COUNTER_DIFF 0x88
|
||||
#define PACKET3_SWITCH_BUFFER 0x8B
|
||||
#define PACKET3_FRAME_CONTROL 0x90
|
||||
# define FRAME_TMZ (1 << 0)
|
||||
# define FRAME_CMD(x) ((x) << 28)
|
||||
/*
|
||||
* x=0: tmz_begin
|
||||
|
|
|
@ -56,24 +56,43 @@ const uint32_t
|
|||
|
||||
static void umc_v6_1_enable_umc_index_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
WREG32_FIELD15(RSMU, 0, RSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU,
|
||||
uint32_t rsmu_umc_addr, rsmu_umc_val;
|
||||
|
||||
rsmu_umc_addr = SOC15_REG_OFFSET(RSMU, 0,
|
||||
mmRSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU);
|
||||
rsmu_umc_val = RREG32_PCIE(rsmu_umc_addr * 4);
|
||||
|
||||
rsmu_umc_val = REG_SET_FIELD(rsmu_umc_val,
|
||||
RSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU,
|
||||
RSMU_UMC_INDEX_MODE_EN, 1);
|
||||
|
||||
WREG32_PCIE(rsmu_umc_addr * 4, rsmu_umc_val);
|
||||
}
|
||||
|
||||
static void umc_v6_1_disable_umc_index_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
WREG32_FIELD15(RSMU, 0, RSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU,
|
||||
uint32_t rsmu_umc_addr, rsmu_umc_val;
|
||||
|
||||
rsmu_umc_addr = SOC15_REG_OFFSET(RSMU, 0,
|
||||
mmRSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU);
|
||||
rsmu_umc_val = RREG32_PCIE(rsmu_umc_addr * 4);
|
||||
|
||||
rsmu_umc_val = REG_SET_FIELD(rsmu_umc_val,
|
||||
RSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU,
|
||||
RSMU_UMC_INDEX_MODE_EN, 0);
|
||||
|
||||
WREG32_PCIE(rsmu_umc_addr * 4, rsmu_umc_val);
|
||||
}
|
||||
|
||||
static uint32_t umc_v6_1_get_umc_index_mode_state(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t rsmu_umc_index;
|
||||
uint32_t rsmu_umc_addr, rsmu_umc_val;
|
||||
|
||||
rsmu_umc_index = RREG32_SOC15(RSMU, 0,
|
||||
rsmu_umc_addr = SOC15_REG_OFFSET(RSMU, 0,
|
||||
mmRSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU);
|
||||
rsmu_umc_val = RREG32_PCIE(rsmu_umc_addr * 4);
|
||||
|
||||
return REG_GET_FIELD(rsmu_umc_index,
|
||||
return REG_GET_FIELD(rsmu_umc_val,
|
||||
RSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU,
|
||||
RSMU_UMC_INDEX_MODE_EN);
|
||||
}
|
||||
|
@ -85,6 +104,81 @@ static inline uint32_t get_umc_6_reg_offset(struct amdgpu_device *adev,
|
|||
return adev->umc.channel_offs*ch_inst + UMC_6_INST_DIST*umc_inst;
|
||||
}
|
||||
|
||||
static void umc_v6_1_clear_error_count_per_channel(struct amdgpu_device *adev,
|
||||
uint32_t umc_reg_offset)
|
||||
{
|
||||
uint32_t ecc_err_cnt_addr;
|
||||
uint32_t ecc_err_cnt_sel, ecc_err_cnt_sel_addr;
|
||||
|
||||
if (adev->asic_type == CHIP_ARCTURUS) {
|
||||
/* UMC 6_1_2 registers */
|
||||
ecc_err_cnt_sel_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0,
|
||||
mmUMCCH0_0_EccErrCntSel_ARCT);
|
||||
ecc_err_cnt_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0,
|
||||
mmUMCCH0_0_EccErrCnt_ARCT);
|
||||
} else {
|
||||
/* UMC 6_1_1 registers */
|
||||
ecc_err_cnt_sel_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0,
|
||||
mmUMCCH0_0_EccErrCntSel);
|
||||
ecc_err_cnt_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0,
|
||||
mmUMCCH0_0_EccErrCnt);
|
||||
}
|
||||
|
||||
/* select the lower chip */
|
||||
ecc_err_cnt_sel = RREG32_PCIE((ecc_err_cnt_sel_addr +
|
||||
umc_reg_offset) * 4);
|
||||
ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel,
|
||||
UMCCH0_0_EccErrCntSel,
|
||||
EccErrCntCsSel, 0);
|
||||
WREG32_PCIE((ecc_err_cnt_sel_addr + umc_reg_offset) * 4,
|
||||
ecc_err_cnt_sel);
|
||||
|
||||
/* clear lower chip error count */
|
||||
WREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4,
|
||||
UMC_V6_1_CE_CNT_INIT);
|
||||
|
||||
/* select the higher chip */
|
||||
ecc_err_cnt_sel = RREG32_PCIE((ecc_err_cnt_sel_addr +
|
||||
umc_reg_offset) * 4);
|
||||
ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel,
|
||||
UMCCH0_0_EccErrCntSel,
|
||||
EccErrCntCsSel, 1);
|
||||
WREG32_PCIE((ecc_err_cnt_sel_addr + umc_reg_offset) * 4,
|
||||
ecc_err_cnt_sel);
|
||||
|
||||
/* clear higher chip error count */
|
||||
WREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4,
|
||||
UMC_V6_1_CE_CNT_INIT);
|
||||
}
|
||||
|
||||
static void umc_v6_1_clear_error_count(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t umc_inst = 0;
|
||||
uint32_t ch_inst = 0;
|
||||
uint32_t umc_reg_offset = 0;
|
||||
uint32_t rsmu_umc_index_state =
|
||||
umc_v6_1_get_umc_index_mode_state(adev);
|
||||
|
||||
if (rsmu_umc_index_state)
|
||||
umc_v6_1_disable_umc_index_mode(adev);
|
||||
|
||||
LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
|
||||
umc_reg_offset = get_umc_6_reg_offset(adev,
|
||||
umc_inst,
|
||||
ch_inst);
|
||||
|
||||
umc_v6_1_clear_error_count_per_channel(adev,
|
||||
umc_reg_offset);
|
||||
}
|
||||
|
||||
if (rsmu_umc_index_state)
|
||||
umc_v6_1_enable_umc_index_mode(adev);
|
||||
}
|
||||
|
||||
static void umc_v6_1_query_correctable_error_count(struct amdgpu_device *adev,
|
||||
uint32_t umc_reg_offset,
|
||||
unsigned long *error_count)
|
||||
|
@ -117,23 +211,21 @@ static void umc_v6_1_query_correctable_error_count(struct amdgpu_device *adev,
|
|||
ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel, UMCCH0_0_EccErrCntSel,
|
||||
EccErrCntCsSel, 0);
|
||||
WREG32_PCIE((ecc_err_cnt_sel_addr + umc_reg_offset) * 4, ecc_err_cnt_sel);
|
||||
|
||||
ecc_err_cnt = RREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4);
|
||||
*error_count +=
|
||||
(REG_GET_FIELD(ecc_err_cnt, UMCCH0_0_EccErrCnt, EccErrCnt) -
|
||||
UMC_V6_1_CE_CNT_INIT);
|
||||
/* clear the lower chip err count */
|
||||
WREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4, UMC_V6_1_CE_CNT_INIT);
|
||||
|
||||
/* select the higher chip and check the err counter */
|
||||
ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel, UMCCH0_0_EccErrCntSel,
|
||||
EccErrCntCsSel, 1);
|
||||
WREG32_PCIE((ecc_err_cnt_sel_addr + umc_reg_offset) * 4, ecc_err_cnt_sel);
|
||||
|
||||
ecc_err_cnt = RREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4);
|
||||
*error_count +=
|
||||
(REG_GET_FIELD(ecc_err_cnt, UMCCH0_0_EccErrCnt, EccErrCnt) -
|
||||
UMC_V6_1_CE_CNT_INIT);
|
||||
/* clear the higher chip err count */
|
||||
WREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4, UMC_V6_1_CE_CNT_INIT);
|
||||
|
||||
/* check for SRAM correctable error
|
||||
MCUMC_STATUS is a 64 bit register */
|
||||
|
@ -209,6 +301,8 @@ static void umc_v6_1_query_ras_error_count(struct amdgpu_device *adev,
|
|||
|
||||
if (rsmu_umc_index_state)
|
||||
umc_v6_1_enable_umc_index_mode(adev);
|
||||
|
||||
umc_v6_1_clear_error_count(adev);
|
||||
}
|
||||
|
||||
static void umc_v6_1_query_error_address(struct amdgpu_device *adev,
|
||||
|
|
|
@ -1404,7 +1404,7 @@ static int vcn_v2_5_pause_dpg_mode(struct amdgpu_device *adev,
|
|||
{
|
||||
struct amdgpu_ring *ring;
|
||||
uint32_t reg_data = 0;
|
||||
int ret_code;
|
||||
int ret_code = 0;
|
||||
|
||||
/* pause/unpause if state is changed */
|
||||
if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) {
|
||||
|
@ -1414,7 +1414,6 @@ static int vcn_v2_5_pause_dpg_mode(struct amdgpu_device *adev,
|
|||
(~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
|
||||
|
||||
if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
|
||||
ret_code = 0;
|
||||
SOC15_WAIT_ON_RREG(UVD, inst_idx, mmUVD_POWER_STATUS, 0x1,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
|
||||
|
||||
|
@ -1469,9 +1468,10 @@ static int vcn_v2_5_pause_dpg_mode(struct amdgpu_device *adev,
|
|||
UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
|
||||
}
|
||||
} else {
|
||||
/* unpause dpg, no need to wait */
|
||||
reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_DPG_PAUSE, reg_data);
|
||||
SOC15_WAIT_ON_RREG(UVD, inst_idx, mmUVD_POWER_STATUS, 0x1,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
|
||||
}
|
||||
adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based;
|
||||
}
|
||||
|
|
|
@ -215,6 +215,7 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
|
|||
}
|
||||
|
||||
q_properties->is_interop = false;
|
||||
q_properties->is_gws = false;
|
||||
q_properties->queue_percent = args->queue_percentage;
|
||||
q_properties->priority = args->queue_priority;
|
||||
q_properties->queue_address = args->ring_base_address;
|
||||
|
@ -1584,6 +1585,45 @@ copy_from_user_failed:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int kfd_ioctl_alloc_queue_gws(struct file *filep,
|
||||
struct kfd_process *p, void *data)
|
||||
{
|
||||
int retval;
|
||||
struct kfd_ioctl_alloc_queue_gws_args *args = data;
|
||||
struct queue *q;
|
||||
struct kfd_dev *dev;
|
||||
|
||||
mutex_lock(&p->mutex);
|
||||
q = pqm_get_user_queue(&p->pqm, args->queue_id);
|
||||
|
||||
if (q) {
|
||||
dev = q->device;
|
||||
} else {
|
||||
retval = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (!dev->gws) {
|
||||
retval = -ENODEV;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS) {
|
||||
retval = -ENODEV;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
retval = pqm_set_gws(&p->pqm, args->queue_id, args->num_gws ? dev->gws : NULL);
|
||||
mutex_unlock(&p->mutex);
|
||||
|
||||
args->first_gws = 0;
|
||||
return retval;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&p->mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int kfd_ioctl_get_dmabuf_info(struct file *filep,
|
||||
struct kfd_process *p, void *data)
|
||||
{
|
||||
|
@ -1786,6 +1826,8 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
|
|||
AMDKFD_IOCTL_DEF(AMDKFD_IOC_IMPORT_DMABUF,
|
||||
kfd_ioctl_import_dmabuf, 0),
|
||||
|
||||
AMDKFD_IOCTL_DEF(AMDKFD_IOC_ALLOC_QUEUE_GWS,
|
||||
kfd_ioctl_alloc_queue_gws, 0),
|
||||
};
|
||||
|
||||
#define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls)
|
||||
|
|
|
@ -569,6 +569,23 @@ static void kfd_cwsr_init(struct kfd_dev *kfd)
|
|||
}
|
||||
}
|
||||
|
||||
static int kfd_gws_init(struct kfd_dev *kfd)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (kfd->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS)
|
||||
return 0;
|
||||
|
||||
if (hws_gws_support
|
||||
|| (kfd->device_info->asic_family >= CHIP_VEGA10
|
||||
&& kfd->device_info->asic_family <= CHIP_RAVEN
|
||||
&& kfd->mec2_fw_version >= 0x1b3))
|
||||
ret = amdgpu_amdkfd_alloc_gws(kfd->kgd,
|
||||
amdgpu_amdkfd_get_num_gws(kfd->kgd), &kfd->gws);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
||||
struct drm_device *ddev,
|
||||
const struct kgd2kfd_shared_resources *gpu_resources)
|
||||
|
@ -578,6 +595,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
|||
kfd->ddev = ddev;
|
||||
kfd->mec_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd,
|
||||
KGD_ENGINE_MEC1);
|
||||
kfd->mec2_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd,
|
||||
KGD_ENGINE_MEC2);
|
||||
kfd->sdma_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd,
|
||||
KGD_ENGINE_SDMA1);
|
||||
kfd->shared_resources = *gpu_resources;
|
||||
|
@ -598,13 +617,6 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
|||
} else
|
||||
kfd->max_proc_per_quantum = hws_max_conc_proc;
|
||||
|
||||
/* Allocate global GWS that is shared by all KFD processes */
|
||||
if (hws_gws_support && amdgpu_amdkfd_alloc_gws(kfd->kgd,
|
||||
amdgpu_amdkfd_get_num_gws(kfd->kgd), &kfd->gws)) {
|
||||
dev_err(kfd_device, "Could not allocate %d gws\n",
|
||||
amdgpu_amdkfd_get_num_gws(kfd->kgd));
|
||||
goto out;
|
||||
}
|
||||
/* calculate max size of mqds needed for queues */
|
||||
size = max_num_of_queues_per_device *
|
||||
kfd->device_info->mqd_size_aligned;
|
||||
|
@ -662,6 +674,15 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
|||
goto device_queue_manager_error;
|
||||
}
|
||||
|
||||
/* If supported on this device, allocate global GWS that is shared
|
||||
* by all KFD processes
|
||||
*/
|
||||
if (kfd_gws_init(kfd)) {
|
||||
dev_err(kfd_device, "Could not allocate %d gws\n",
|
||||
amdgpu_amdkfd_get_num_gws(kfd->kgd));
|
||||
goto gws_error;
|
||||
}
|
||||
|
||||
if (kfd_iommu_device_init(kfd)) {
|
||||
dev_err(kfd_device, "Error initializing iommuv2\n");
|
||||
goto device_iommu_error;
|
||||
|
@ -691,6 +712,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
|||
kfd_topology_add_device_error:
|
||||
kfd_resume_error:
|
||||
device_iommu_error:
|
||||
gws_error:
|
||||
device_queue_manager_uninit(kfd->dqm);
|
||||
device_queue_manager_error:
|
||||
kfd_interrupt_exit(kfd);
|
||||
|
@ -701,7 +723,7 @@ kfd_doorbell_error:
|
|||
kfd_gtt_sa_init_error:
|
||||
amdgpu_amdkfd_free_gtt_mem(kfd->kgd, kfd->gtt_mem);
|
||||
alloc_gtt_mem_failure:
|
||||
if (hws_gws_support)
|
||||
if (kfd->gws)
|
||||
amdgpu_amdkfd_free_gws(kfd->kgd, kfd->gws);
|
||||
dev_err(kfd_device,
|
||||
"device %x:%x NOT added due to errors\n",
|
||||
|
@ -720,7 +742,7 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd)
|
|||
kfd_doorbell_fini(kfd);
|
||||
kfd_gtt_sa_fini(kfd);
|
||||
amdgpu_amdkfd_free_gtt_mem(kfd->kgd, kfd->gtt_mem);
|
||||
if (hws_gws_support)
|
||||
if (kfd->gws)
|
||||
amdgpu_amdkfd_free_gws(kfd->kgd, kfd->gws);
|
||||
}
|
||||
|
||||
|
|
|
@ -505,8 +505,13 @@ static int destroy_queue_nocpsch_locked(struct device_queue_manager *dqm,
|
|||
deallocate_vmid(dqm, qpd, q);
|
||||
}
|
||||
qpd->queue_count--;
|
||||
if (q->properties.is_active)
|
||||
if (q->properties.is_active) {
|
||||
decrement_queue_count(dqm, q->properties.type);
|
||||
if (q->properties.is_gws) {
|
||||
dqm->gws_queue_count--;
|
||||
qpd->mapped_gws_queue = false;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -583,6 +588,20 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
|
|||
else if (!q->properties.is_active && prev_active)
|
||||
decrement_queue_count(dqm, q->properties.type);
|
||||
|
||||
if (q->gws && !q->properties.is_gws) {
|
||||
if (q->properties.is_active) {
|
||||
dqm->gws_queue_count++;
|
||||
pdd->qpd.mapped_gws_queue = true;
|
||||
}
|
||||
q->properties.is_gws = true;
|
||||
} else if (!q->gws && q->properties.is_gws) {
|
||||
if (q->properties.is_active) {
|
||||
dqm->gws_queue_count--;
|
||||
pdd->qpd.mapped_gws_queue = false;
|
||||
}
|
||||
q->properties.is_gws = false;
|
||||
}
|
||||
|
||||
if (dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS)
|
||||
retval = map_queues_cpsch(dqm);
|
||||
else if (q->properties.is_active &&
|
||||
|
@ -631,6 +650,10 @@ static int evict_process_queues_nocpsch(struct device_queue_manager *dqm,
|
|||
q->properties.type)];
|
||||
q->properties.is_active = false;
|
||||
decrement_queue_count(dqm, q->properties.type);
|
||||
if (q->properties.is_gws) {
|
||||
dqm->gws_queue_count--;
|
||||
qpd->mapped_gws_queue = false;
|
||||
}
|
||||
|
||||
if (WARN_ONCE(!dqm->sched_running, "Evict when stopped\n"))
|
||||
continue;
|
||||
|
@ -744,6 +767,10 @@ static int restore_process_queues_nocpsch(struct device_queue_manager *dqm,
|
|||
q->properties.type)];
|
||||
q->properties.is_active = true;
|
||||
increment_queue_count(dqm, q->properties.type);
|
||||
if (q->properties.is_gws) {
|
||||
dqm->gws_queue_count++;
|
||||
qpd->mapped_gws_queue = true;
|
||||
}
|
||||
|
||||
if (WARN_ONCE(!dqm->sched_running, "Restore when stopped\n"))
|
||||
continue;
|
||||
|
@ -913,6 +940,7 @@ static int initialize_nocpsch(struct device_queue_manager *dqm)
|
|||
INIT_LIST_HEAD(&dqm->queues);
|
||||
dqm->active_queue_count = dqm->next_pipe_to_allocate = 0;
|
||||
dqm->active_cp_queue_count = 0;
|
||||
dqm->gws_queue_count = 0;
|
||||
|
||||
for (pipe = 0; pipe < get_pipes_per_mec(dqm); pipe++) {
|
||||
int pipe_offset = pipe * get_queues_per_pipe(dqm);
|
||||
|
@ -1082,7 +1110,7 @@ static int initialize_cpsch(struct device_queue_manager *dqm)
|
|||
INIT_LIST_HEAD(&dqm->queues);
|
||||
dqm->active_queue_count = dqm->processes_count = 0;
|
||||
dqm->active_cp_queue_count = 0;
|
||||
|
||||
dqm->gws_queue_count = 0;
|
||||
dqm->active_runlist = false;
|
||||
dqm->sdma_bitmap = ~0ULL >> (64 - get_num_sdma_queues(dqm));
|
||||
dqm->xgmi_sdma_bitmap = ~0ULL >> (64 - get_num_xgmi_sdma_queues(dqm));
|
||||
|
@ -1432,6 +1460,10 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm,
|
|||
KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
|
||||
if (retval == -ETIME)
|
||||
qpd->reset_wavefronts = true;
|
||||
if (q->properties.is_gws) {
|
||||
dqm->gws_queue_count--;
|
||||
qpd->mapped_gws_queue = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1650,8 +1682,13 @@ static int process_termination_cpsch(struct device_queue_manager *dqm,
|
|||
else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
|
||||
deallocate_sdma_queue(dqm, q);
|
||||
|
||||
if (q->properties.is_active)
|
||||
if (q->properties.is_active) {
|
||||
decrement_queue_count(dqm, q->properties.type);
|
||||
if (q->properties.is_gws) {
|
||||
dqm->gws_queue_count--;
|
||||
qpd->mapped_gws_queue = false;
|
||||
}
|
||||
}
|
||||
|
||||
dqm->total_queue_count--;
|
||||
}
|
||||
|
|
|
@ -182,6 +182,7 @@ struct device_queue_manager {
|
|||
unsigned int processes_count;
|
||||
unsigned int active_queue_count;
|
||||
unsigned int active_cp_queue_count;
|
||||
unsigned int gws_queue_count;
|
||||
unsigned int total_queue_count;
|
||||
unsigned int next_pipe_to_allocate;
|
||||
unsigned int *allocated_queues;
|
||||
|
|
|
@ -126,6 +126,7 @@ static bool kq_initialize(struct kernel_queue *kq, struct kfd_dev *dev,
|
|||
|
||||
prop.queue_size = queue_size;
|
||||
prop.is_interop = false;
|
||||
prop.is_gws = false;
|
||||
prop.priority = 1;
|
||||
prop.queue_percent = 100;
|
||||
prop.type = type;
|
||||
|
|
|
@ -41,7 +41,7 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
|
|||
unsigned int *rlib_size,
|
||||
bool *over_subscription)
|
||||
{
|
||||
unsigned int process_count, queue_count, compute_queue_count;
|
||||
unsigned int process_count, queue_count, compute_queue_count, gws_queue_count;
|
||||
unsigned int map_queue_size;
|
||||
unsigned int max_proc_per_quantum = 1;
|
||||
struct kfd_dev *dev = pm->dqm->dev;
|
||||
|
@ -49,6 +49,7 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
|
|||
process_count = pm->dqm->processes_count;
|
||||
queue_count = pm->dqm->active_queue_count;
|
||||
compute_queue_count = pm->dqm->active_cp_queue_count;
|
||||
gws_queue_count = pm->dqm->gws_queue_count;
|
||||
|
||||
/* check if there is over subscription
|
||||
* Note: the arbitration between the number of VMIDs and
|
||||
|
@ -61,7 +62,8 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
|
|||
max_proc_per_quantum = dev->max_proc_per_quantum;
|
||||
|
||||
if ((process_count > max_proc_per_quantum) ||
|
||||
compute_queue_count > get_cp_queues_num(pm->dqm)) {
|
||||
compute_queue_count > get_cp_queues_num(pm->dqm) ||
|
||||
gws_queue_count > 1) {
|
||||
*over_subscription = true;
|
||||
pr_debug("Over subscribed runlist\n");
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ static int pm_map_process_v9(struct packet_manager *pm,
|
|||
packet->bitfields2.pasid = qpd->pqm->process->pasid;
|
||||
packet->bitfields14.gds_size = qpd->gds_size & 0x3F;
|
||||
packet->bitfields14.gds_size_hi = (qpd->gds_size >> 6) & 0xF;
|
||||
packet->bitfields14.num_gws = qpd->num_gws;
|
||||
packet->bitfields14.num_gws = (qpd->mapped_gws_queue) ? qpd->num_gws : 0;
|
||||
packet->bitfields14.num_oac = qpd->num_oac;
|
||||
packet->bitfields14.sdma_enable = 1;
|
||||
packet->bitfields14.num_queues = (qpd->is_debug) ? 0 : qpd->queue_count;
|
||||
|
|
|
@ -282,6 +282,7 @@ struct kfd_dev {
|
|||
|
||||
/* Firmware versions */
|
||||
uint16_t mec_fw_version;
|
||||
uint16_t mec2_fw_version;
|
||||
uint16_t sdma_fw_version;
|
||||
|
||||
/* Maximum process number mapped to HW scheduler */
|
||||
|
@ -410,6 +411,10 @@ enum KFD_QUEUE_PRIORITY {
|
|||
* @is_active: Defines if the queue is active or not. @is_active and
|
||||
* @is_evicted are protected by the DQM lock.
|
||||
*
|
||||
* @is_gws: Defines if the queue has been updated to be GWS-capable or not.
|
||||
* @is_gws should be protected by the DQM lock, since changing it can yield the
|
||||
* possibility of updating DQM state on number of GWS queues.
|
||||
*
|
||||
* @vmid: If the scheduling mode is no cp scheduling the field defines the vmid
|
||||
* of the queue.
|
||||
*
|
||||
|
@ -432,6 +437,7 @@ struct queue_properties {
|
|||
bool is_interop;
|
||||
bool is_evicted;
|
||||
bool is_active;
|
||||
bool is_gws;
|
||||
/* Not relevant for user mode queues in cp scheduling */
|
||||
unsigned int vmid;
|
||||
/* Relevant only for sdma queues*/
|
||||
|
@ -563,6 +569,14 @@ struct qcm_process_device {
|
|||
*/
|
||||
bool reset_wavefronts;
|
||||
|
||||
/* This flag tells us if this process has a GWS-capable
|
||||
* queue that will be mapped into the runlist. It's
|
||||
* possible to request a GWS BO, but not have the queue
|
||||
* currently mapped, and this changes how the MAP_PROCESS
|
||||
* PM4 packet is configured.
|
||||
*/
|
||||
bool mapped_gws_queue;
|
||||
|
||||
/*
|
||||
* All the memory management data should be here too
|
||||
*/
|
||||
|
@ -923,6 +937,8 @@ int pqm_set_gws(struct process_queue_manager *pqm, unsigned int qid,
|
|||
void *gws);
|
||||
struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm,
|
||||
unsigned int qid);
|
||||
struct queue *pqm_get_user_queue(struct process_queue_manager *pqm,
|
||||
unsigned int qid);
|
||||
int pqm_get_wave_state(struct process_queue_manager *pqm,
|
||||
unsigned int qid,
|
||||
void __user *ctl_stack,
|
||||
|
|
|
@ -858,6 +858,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
|
|||
pdd->qpd.dqm = dev->dqm;
|
||||
pdd->qpd.pqm = &p->pqm;
|
||||
pdd->qpd.evicted = 0;
|
||||
pdd->qpd.mapped_gws_queue = false;
|
||||
pdd->process = p;
|
||||
pdd->bound = PDD_UNBOUND;
|
||||
pdd->already_dequeued = false;
|
||||
|
|
|
@ -476,6 +476,15 @@ struct kernel_queue *pqm_get_kernel_queue(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct queue *pqm_get_user_queue(struct process_queue_manager *pqm,
|
||||
unsigned int qid)
|
||||
{
|
||||
struct process_queue_node *pqn;
|
||||
|
||||
pqn = get_queue_by_qid(pqm, qid);
|
||||
return pqn ? pqn->q : NULL;
|
||||
}
|
||||
|
||||
int pqm_get_wave_state(struct process_queue_manager *pqm,
|
||||
unsigned int qid,
|
||||
void __user *ctl_stack,
|
||||
|
|
|
@ -1301,6 +1301,10 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
|
|||
|
||||
dev->node_props.vendor_id = gpu->pdev->vendor;
|
||||
dev->node_props.device_id = gpu->pdev->device;
|
||||
dev->node_props.capability |=
|
||||
((amdgpu_amdkfd_get_asic_rev_id(dev->gpu->kgd) <<
|
||||
HSA_CAP_ASIC_REVISION_SHIFT) &
|
||||
HSA_CAP_ASIC_REVISION_MASK);
|
||||
dev->node_props.location_id = pci_dev_id(gpu->pdev);
|
||||
dev->node_props.max_engine_clk_fcompute =
|
||||
amdgpu_amdkfd_get_max_engine_clock_in_mhz(dev->gpu->kgd);
|
||||
|
@ -1315,7 +1319,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
|
|||
gpu->device_info->num_xgmi_sdma_engines;
|
||||
dev->node_props.num_sdma_queues_per_engine =
|
||||
gpu->device_info->num_sdma_queues_per_engine;
|
||||
dev->node_props.num_gws = (hws_gws_support &&
|
||||
dev->node_props.num_gws = (dev->gpu->gws &&
|
||||
dev->gpu->dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS) ?
|
||||
amdgpu_amdkfd_get_num_gws(dev->gpu->kgd) : 0;
|
||||
dev->node_props.num_cp_queues = get_cp_queues_num(dev->gpu->dqm);
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#define HSA_CAP_WATCH_POINTS_TOTALBITS_SHIFT 8
|
||||
#define HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK 0x00003000
|
||||
#define HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT 12
|
||||
#define HSA_CAP_RESERVED 0xffffc000
|
||||
|
||||
#define HSA_CAP_DOORBELL_TYPE_PRE_1_0 0x0
|
||||
#define HSA_CAP_DOORBELL_TYPE_1_0 0x1
|
||||
|
@ -51,6 +50,10 @@
|
|||
#define HSA_CAP_SRAM_EDCSUPPORTED 0x00080000
|
||||
#define HSA_CAP_MEM_EDCSUPPORTED 0x00100000
|
||||
#define HSA_CAP_RASEVENTNOTIFY 0x00200000
|
||||
#define HSA_CAP_ASIC_REVISION_MASK 0x03c00000
|
||||
#define HSA_CAP_ASIC_REVISION_SHIFT 22
|
||||
|
||||
#define HSA_CAP_RESERVED 0xfc078000
|
||||
|
||||
struct kfd_node_properties {
|
||||
uint64_t hive_id;
|
||||
|
|
|
@ -3309,7 +3309,7 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state,
|
|||
}
|
||||
|
||||
static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
|
||||
uint64_t *tiling_flags)
|
||||
uint64_t *tiling_flags, bool *tmz_surface)
|
||||
{
|
||||
struct amdgpu_bo *rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
|
||||
int r = amdgpu_bo_reserve(rbo, false);
|
||||
|
@ -3324,6 +3324,9 @@ static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
|
|||
if (tiling_flags)
|
||||
amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
|
||||
|
||||
if (tmz_surface)
|
||||
*tmz_surface = amdgpu_bo_encrypted(rbo);
|
||||
|
||||
amdgpu_bo_unreserve(rbo);
|
||||
|
||||
return r;
|
||||
|
@ -3411,6 +3414,7 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
|
|||
struct plane_size *plane_size,
|
||||
struct dc_plane_dcc_param *dcc,
|
||||
struct dc_plane_address *address,
|
||||
bool tmz_surface,
|
||||
bool force_disable_dcc)
|
||||
{
|
||||
const struct drm_framebuffer *fb = &afb->base;
|
||||
|
@ -3421,6 +3425,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
|
|||
memset(dcc, 0, sizeof(*dcc));
|
||||
memset(address, 0, sizeof(*address));
|
||||
|
||||
address->tmz_surface = tmz_surface;
|
||||
|
||||
if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
|
||||
plane_size->surface_size.x = 0;
|
||||
plane_size->surface_size.y = 0;
|
||||
|
@ -3611,6 +3617,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
|
|||
const uint64_t tiling_flags,
|
||||
struct dc_plane_info *plane_info,
|
||||
struct dc_plane_address *address,
|
||||
bool tmz_surface,
|
||||
bool force_disable_dcc)
|
||||
{
|
||||
const struct drm_framebuffer *fb = plane_state->fb;
|
||||
|
@ -3693,7 +3700,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
|
|||
plane_info->rotation, tiling_flags,
|
||||
&plane_info->tiling_info,
|
||||
&plane_info->plane_size,
|
||||
&plane_info->dcc, address,
|
||||
&plane_info->dcc, address, tmz_surface,
|
||||
force_disable_dcc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -3717,6 +3724,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
|
|||
struct dc_plane_info plane_info;
|
||||
uint64_t tiling_flags;
|
||||
int ret;
|
||||
bool tmz_surface = false;
|
||||
bool force_disable_dcc = false;
|
||||
|
||||
ret = fill_dc_scaling_info(plane_state, &scaling_info);
|
||||
|
@ -3728,7 +3736,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
|
|||
dc_plane_state->clip_rect = scaling_info.clip_rect;
|
||||
dc_plane_state->scaling_quality = scaling_info.scaling_quality;
|
||||
|
||||
ret = get_fb_info(amdgpu_fb, &tiling_flags);
|
||||
ret = get_fb_info(amdgpu_fb, &tiling_flags, &tmz_surface);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -3736,6 +3744,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
|
|||
ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags,
|
||||
&plane_info,
|
||||
&dc_plane_state->address,
|
||||
tmz_surface,
|
||||
force_disable_dcc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -5354,6 +5363,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
|
|||
uint64_t tiling_flags;
|
||||
uint32_t domain;
|
||||
int r;
|
||||
bool tmz_surface = false;
|
||||
bool force_disable_dcc = false;
|
||||
|
||||
dm_plane_state_old = to_dm_plane_state(plane->state);
|
||||
|
@ -5403,6 +5413,8 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
|
|||
|
||||
amdgpu_bo_get_tiling_flags(rbo, &tiling_flags);
|
||||
|
||||
tmz_surface = amdgpu_bo_encrypted(rbo);
|
||||
|
||||
ttm_eu_backoff_reservation(&ticket, &list);
|
||||
|
||||
afb->address = amdgpu_bo_gpu_offset(rbo);
|
||||
|
@ -5418,7 +5430,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
|
|||
adev, afb, plane_state->format, plane_state->rotation,
|
||||
tiling_flags, &plane_state->tiling_info,
|
||||
&plane_state->plane_size, &plane_state->dcc,
|
||||
&plane_state->address,
|
||||
&plane_state->address, tmz_surface,
|
||||
force_disable_dcc);
|
||||
}
|
||||
|
||||
|
@ -6592,6 +6604,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||
unsigned long flags;
|
||||
struct amdgpu_bo *abo;
|
||||
uint64_t tiling_flags;
|
||||
bool tmz_surface = false;
|
||||
uint32_t target_vblank, last_flip_vblank;
|
||||
bool vrr_active = amdgpu_dm_vrr_active(acrtc_state);
|
||||
bool pflip_present = false;
|
||||
|
@ -6687,12 +6700,15 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||
|
||||
amdgpu_bo_get_tiling_flags(abo, &tiling_flags);
|
||||
|
||||
tmz_surface = amdgpu_bo_encrypted(abo);
|
||||
|
||||
amdgpu_bo_unreserve(abo);
|
||||
|
||||
fill_dc_plane_info_and_addr(
|
||||
dm->adev, new_plane_state, tiling_flags,
|
||||
&bundle->plane_infos[planes_count],
|
||||
&bundle->flip_addrs[planes_count].address,
|
||||
tmz_surface,
|
||||
false);
|
||||
|
||||
DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n",
|
||||
|
@ -8065,6 +8081,7 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
|
|||
struct dc_flip_addrs *flip_addr = &bundle->flip_addrs[num_plane];
|
||||
struct dc_scaling_info *scaling_info = &bundle->scaling_infos[num_plane];
|
||||
uint64_t tiling_flags;
|
||||
bool tmz_surface = false;
|
||||
|
||||
new_plane_crtc = new_plane_state->crtc;
|
||||
new_dm_plane_state = to_dm_plane_state(new_plane_state);
|
||||
|
@ -8112,14 +8129,14 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
|
|||
bundle->surface_updates[num_plane].scaling_info = scaling_info;
|
||||
|
||||
if (amdgpu_fb) {
|
||||
ret = get_fb_info(amdgpu_fb, &tiling_flags);
|
||||
ret = get_fb_info(amdgpu_fb, &tiling_flags, &tmz_surface);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
|
||||
ret = fill_dc_plane_info_and_addr(
|
||||
dm->adev, new_plane_state, tiling_flags,
|
||||
plane_info,
|
||||
&flip_addr->address,
|
||||
&flip_addr->address, tmz_surface,
|
||||
false);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
|
|
|
@ -239,7 +239,8 @@ static int __set_output_tf(struct dc_transfer_func *func,
|
|||
* instead to simulate this.
|
||||
*/
|
||||
gamma->type = GAMMA_CUSTOM;
|
||||
res = mod_color_calculate_degamma_params(func, gamma, true);
|
||||
res = mod_color_calculate_degamma_params(NULL, func,
|
||||
gamma, true);
|
||||
} else {
|
||||
/*
|
||||
* Assume sRGB. The actual mapping will depend on whether the
|
||||
|
@ -271,7 +272,7 @@ static int __set_input_tf(struct dc_transfer_func *func,
|
|||
|
||||
__drm_lut_to_dc_gamma(lut, gamma, false);
|
||||
|
||||
res = mod_color_calculate_degamma_params(func, gamma, true);
|
||||
res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
|
||||
dc_gamma_release(&gamma);
|
||||
|
||||
return res ? 0 : -ENOMEM;
|
||||
|
@ -485,7 +486,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
|
|||
dc_plane_state->in_transfer_func->tf = tf;
|
||||
|
||||
if (tf != TRANSFER_FUNCTION_SRGB &&
|
||||
!mod_color_calculate_degamma_params(
|
||||
!mod_color_calculate_degamma_params(NULL,
|
||||
dc_plane_state->in_transfer_func, NULL, false))
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
|
|
|
@ -113,13 +113,19 @@ static void encoder_control_dmcub(
|
|||
struct dc_dmub_srv *dmcub,
|
||||
struct dig_encoder_stream_setup_parameters_v1_5 *dig)
|
||||
{
|
||||
struct dmub_rb_cmd_digx_encoder_control encoder_control = { 0 };
|
||||
union dmub_rb_cmd cmd;
|
||||
|
||||
encoder_control.header.type = DMUB_CMD__VBIOS;
|
||||
encoder_control.header.sub_type = DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL;
|
||||
encoder_control.encoder_control.dig.stream_param = *dig;
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
dc_dmub_srv_cmd_queue(dmcub, &encoder_control.header);
|
||||
cmd.digx_encoder_control.header.type = DMUB_CMD__VBIOS;
|
||||
cmd.digx_encoder_control.header.sub_type =
|
||||
DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL;
|
||||
cmd.digx_encoder_control.header.payload_bytes =
|
||||
sizeof(cmd.digx_encoder_control) -
|
||||
sizeof(cmd.digx_encoder_control.header);
|
||||
cmd.digx_encoder_control.encoder_control.dig.stream_param = *dig;
|
||||
|
||||
dc_dmub_srv_cmd_queue(dmcub, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dmcub);
|
||||
dc_dmub_srv_wait_idle(dmcub);
|
||||
}
|
||||
|
@ -238,14 +244,19 @@ static void transmitter_control_dmcub(
|
|||
struct dc_dmub_srv *dmcub,
|
||||
struct dig_transmitter_control_parameters_v1_6 *dig)
|
||||
{
|
||||
struct dmub_rb_cmd_dig1_transmitter_control transmitter_control;
|
||||
union dmub_rb_cmd cmd;
|
||||
|
||||
transmitter_control.header.type = DMUB_CMD__VBIOS;
|
||||
transmitter_control.header.sub_type =
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.dig1_transmitter_control.header.type = DMUB_CMD__VBIOS;
|
||||
cmd.dig1_transmitter_control.header.sub_type =
|
||||
DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL;
|
||||
transmitter_control.transmitter_control.dig = *dig;
|
||||
cmd.dig1_transmitter_control.header.payload_bytes =
|
||||
sizeof(cmd.dig1_transmitter_control) -
|
||||
sizeof(cmd.dig1_transmitter_control.header);
|
||||
cmd.dig1_transmitter_control.transmitter_control.dig = *dig;
|
||||
|
||||
dc_dmub_srv_cmd_queue(dmcub, &transmitter_control.header);
|
||||
dc_dmub_srv_cmd_queue(dmcub, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dmcub);
|
||||
dc_dmub_srv_wait_idle(dmcub);
|
||||
}
|
||||
|
@ -339,13 +350,18 @@ static void set_pixel_clock_dmcub(
|
|||
struct dc_dmub_srv *dmcub,
|
||||
struct set_pixel_clock_parameter_v1_7 *clk)
|
||||
{
|
||||
struct dmub_rb_cmd_set_pixel_clock pixel_clock = { 0 };
|
||||
union dmub_rb_cmd cmd;
|
||||
|
||||
pixel_clock.header.type = DMUB_CMD__VBIOS;
|
||||
pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK;
|
||||
pixel_clock.pixel_clock.clk = *clk;
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
dc_dmub_srv_cmd_queue(dmcub, &pixel_clock.header);
|
||||
cmd.set_pixel_clock.header.type = DMUB_CMD__VBIOS;
|
||||
cmd.set_pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK;
|
||||
cmd.set_pixel_clock.header.payload_bytes =
|
||||
sizeof(cmd.set_pixel_clock) -
|
||||
sizeof(cmd.set_pixel_clock.header);
|
||||
cmd.set_pixel_clock.pixel_clock.clk = *clk;
|
||||
|
||||
dc_dmub_srv_cmd_queue(dmcub, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dmcub);
|
||||
dc_dmub_srv_wait_idle(dmcub);
|
||||
}
|
||||
|
@ -705,13 +721,19 @@ static void enable_disp_power_gating_dmcub(
|
|||
struct dc_dmub_srv *dmcub,
|
||||
struct enable_disp_power_gating_parameters_v2_1 *pwr)
|
||||
{
|
||||
struct dmub_rb_cmd_enable_disp_power_gating power_gating;
|
||||
union dmub_rb_cmd cmd;
|
||||
|
||||
power_gating.header.type = DMUB_CMD__VBIOS;
|
||||
power_gating.header.sub_type = DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING;
|
||||
power_gating.power_gating.pwr = *pwr;
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
dc_dmub_srv_cmd_queue(dmcub, &power_gating.header);
|
||||
cmd.enable_disp_power_gating.header.type = DMUB_CMD__VBIOS;
|
||||
cmd.enable_disp_power_gating.header.sub_type =
|
||||
DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING;
|
||||
cmd.enable_disp_power_gating.header.payload_bytes =
|
||||
sizeof(cmd.enable_disp_power_gating) -
|
||||
sizeof(cmd.enable_disp_power_gating.header);
|
||||
cmd.enable_disp_power_gating.power_gating.pwr = *pwr;
|
||||
|
||||
dc_dmub_srv_cmd_queue(dmcub, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dmcub);
|
||||
dc_dmub_srv_wait_idle(dmcub);
|
||||
}
|
||||
|
|
|
@ -2210,7 +2210,9 @@ static void commit_planes_do_stream_update(struct dc *dc,
|
|||
|
||||
if (should_program_abm) {
|
||||
if (*stream_update->abm_level == ABM_LEVEL_IMMEDIATE_DISABLE) {
|
||||
pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm);
|
||||
pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(
|
||||
pipe_ctx->stream_res.abm,
|
||||
pipe_ctx->stream->link->panel_cntl->inst);
|
||||
} else {
|
||||
pipe_ctx->stream_res.abm->funcs->set_abm_level(
|
||||
pipe_ctx->stream_res.abm, stream->abm_level);
|
||||
|
|
|
@ -2509,35 +2509,21 @@ bool dc_link_set_backlight_level(const struct dc_link *link,
|
|||
uint32_t frame_ramp)
|
||||
{
|
||||
struct dc *dc = link->ctx->dc;
|
||||
struct abm *abm = get_abm_from_stream_res(link);
|
||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||
unsigned int controller_id = 0;
|
||||
bool fw_set_brightness = true;
|
||||
int i;
|
||||
|
||||
DC_LOGGER_INIT(link->ctx->logger);
|
||||
|
||||
if (abm == NULL || (abm->funcs->set_backlight_level_pwm == NULL))
|
||||
return false;
|
||||
|
||||
if (dmcu)
|
||||
fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
|
||||
|
||||
DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
|
||||
backlight_pwm_u16_16, backlight_pwm_u16_16);
|
||||
|
||||
if (dc_is_embedded_signal(link->connector_signal)) {
|
||||
struct pipe_ctx *pipe_ctx = NULL;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
if (dc->current_state->res_ctx.pipe_ctx[i].stream) {
|
||||
if (dc->current_state->res_ctx.
|
||||
pipe_ctx[i].stream->link
|
||||
== link) {
|
||||
/* DMCU -1 for all controller id values,
|
||||
* therefore +1 here
|
||||
*/
|
||||
controller_id =
|
||||
dc->current_state->
|
||||
res_ctx.pipe_ctx[i].stream_res.tg->inst +
|
||||
1;
|
||||
pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
|
||||
/* Disable brightness ramping when the display is blanked
|
||||
* as it can hang the DMCU
|
||||
|
@ -2547,12 +2533,14 @@ bool dc_link_set_backlight_level(const struct dc_link *link,
|
|||
}
|
||||
}
|
||||
}
|
||||
abm->funcs->set_backlight_level_pwm(
|
||||
abm,
|
||||
|
||||
if (pipe_ctx == NULL)
|
||||
ASSERT(false);
|
||||
|
||||
dc->hwss.set_backlight_level(
|
||||
pipe_ctx,
|
||||
backlight_pwm_u16_16,
|
||||
frame_ramp,
|
||||
controller_id,
|
||||
fw_set_brightness);
|
||||
frame_ramp);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -2564,7 +2552,7 @@ bool dc_link_set_abm_disable(const struct dc_link *link)
|
|||
bool success = false;
|
||||
|
||||
if (abm)
|
||||
success = abm->funcs->set_abm_immediate_disable(abm);
|
||||
success = abm->funcs->set_abm_immediate_disable(abm, link->panel_cntl->inst);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
|
|
@ -599,7 +599,7 @@ bool dal_ddc_submit_aux_command(struct ddc_service *ddc,
|
|||
do {
|
||||
struct aux_payload current_payload;
|
||||
bool is_end_of_payload = (retrieved + DEFAULT_AUX_MAX_DATA_SIZE) >
|
||||
payload->length ? true : false;
|
||||
payload->length;
|
||||
|
||||
current_payload.address = payload->address;
|
||||
current_payload.data = &payload->data[retrieved];
|
||||
|
|
|
@ -4231,7 +4231,7 @@ void dpcd_set_source_specific_data(struct dc_link *link)
|
|||
{
|
||||
const uint32_t post_oui_delay = 30; // 30ms
|
||||
uint8_t dspc = 0;
|
||||
enum dc_status ret = DC_ERROR_UNEXPECTED;
|
||||
enum dc_status ret;
|
||||
|
||||
ret = core_link_read_dpcd(link, DP_DOWN_STREAM_PORT_COUNT, &dspc,
|
||||
sizeof(dspc));
|
||||
|
|
|
@ -1064,8 +1064,8 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
|||
|
||||
calculate_viewport(pipe_ctx);
|
||||
|
||||
if (pipe_ctx->plane_res.scl_data.viewport.height < 16 ||
|
||||
pipe_ctx->plane_res.scl_data.viewport.width < 16) {
|
||||
if (pipe_ctx->plane_res.scl_data.viewport.height < 12 ||
|
||||
pipe_ctx->plane_res.scl_data.viewport.width < 12) {
|
||||
if (store_h_border_left) {
|
||||
restore_border_left_from_dst(pipe_ctx,
|
||||
store_h_border_left);
|
||||
|
|
|
@ -231,34 +231,6 @@ struct dc_stream_status *dc_stream_get_status(
|
|||
return dc_stream_get_status_from_state(dc->current_state, stream);
|
||||
}
|
||||
|
||||
static void delay_cursor_until_vupdate(struct pipe_ctx *pipe_ctx, struct dc *dc)
|
||||
{
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
unsigned int vupdate_line;
|
||||
unsigned int lines_to_vupdate, us_to_vupdate, vpos, nvpos;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
unsigned int us_per_line;
|
||||
|
||||
if (stream->ctx->asic_id.chip_family == FAMILY_RV &&
|
||||
ASICREV_IS_RAVEN(stream->ctx->asic_id.hw_internal_rev)) {
|
||||
|
||||
vupdate_line = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
|
||||
if (!dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos))
|
||||
return;
|
||||
|
||||
if (vpos >= vupdate_line)
|
||||
return;
|
||||
|
||||
us_per_line = stream->timing.h_total * 10000 / stream->timing.pix_clk_100hz;
|
||||
lines_to_vupdate = vupdate_line - vpos;
|
||||
us_to_vupdate = lines_to_vupdate * us_per_line;
|
||||
|
||||
/* 70 us is a conservative estimate of cursor update time*/
|
||||
if (us_to_vupdate < 70)
|
||||
udelay(us_to_vupdate);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address
|
||||
|
@ -298,9 +270,7 @@ bool dc_stream_set_cursor_attributes(
|
|||
|
||||
if (!pipe_to_program) {
|
||||
pipe_to_program = pipe_ctx;
|
||||
|
||||
delay_cursor_until_vupdate(pipe_ctx, dc);
|
||||
dc->hwss.pipe_control_lock(dc, pipe_to_program, true);
|
||||
dc->hwss.cursor_lock(dc, pipe_to_program, true);
|
||||
}
|
||||
|
||||
dc->hwss.set_cursor_attribute(pipe_ctx);
|
||||
|
@ -309,7 +279,7 @@ bool dc_stream_set_cursor_attributes(
|
|||
}
|
||||
|
||||
if (pipe_to_program)
|
||||
dc->hwss.pipe_control_lock(dc, pipe_to_program, false);
|
||||
dc->hwss.cursor_lock(dc, pipe_to_program, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -349,16 +319,14 @@ bool dc_stream_set_cursor_position(
|
|||
|
||||
if (!pipe_to_program) {
|
||||
pipe_to_program = pipe_ctx;
|
||||
|
||||
delay_cursor_until_vupdate(pipe_ctx, dc);
|
||||
dc->hwss.pipe_control_lock(dc, pipe_to_program, true);
|
||||
dc->hwss.cursor_lock(dc, pipe_to_program, true);
|
||||
}
|
||||
|
||||
dc->hwss.set_cursor_position(pipe_ctx);
|
||||
}
|
||||
|
||||
if (pipe_to_program)
|
||||
dc->hwss.pipe_control_lock(dc, pipe_to_program, false);
|
||||
dc->hwss.cursor_lock(dc, pipe_to_program, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "inc/hw/dmcu.h"
|
||||
#include "dml/display_mode_lib.h"
|
||||
|
||||
#define DC_VER "3.2.81"
|
||||
#define DC_VER "3.2.83.1"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
|
@ -98,6 +98,49 @@ struct dc_plane_cap {
|
|||
} max_downscale_factor;
|
||||
};
|
||||
|
||||
// Color management caps (DPP and MPC)
|
||||
struct rom_curve_caps {
|
||||
uint16_t srgb : 1;
|
||||
uint16_t bt2020 : 1;
|
||||
uint16_t gamma2_2 : 1;
|
||||
uint16_t pq : 1;
|
||||
uint16_t hlg : 1;
|
||||
};
|
||||
|
||||
struct dpp_color_caps {
|
||||
uint16_t dcn_arch : 1; // all DCE generations treated the same
|
||||
// input lut is different than most LUTs, just plain 256-entry lookup
|
||||
uint16_t input_lut_shared : 1; // shared with DGAM
|
||||
uint16_t icsc : 1;
|
||||
uint16_t dgam_ram : 1;
|
||||
uint16_t post_csc : 1; // before gamut remap
|
||||
uint16_t gamma_corr : 1;
|
||||
|
||||
// hdr_mult and gamut remap always available in DPP (in that order)
|
||||
// 3d lut implies shaper LUT,
|
||||
// it may be shared with MPC - check MPC:shared_3d_lut flag
|
||||
uint16_t hw_3d_lut : 1;
|
||||
uint16_t ogam_ram : 1; // blnd gam
|
||||
uint16_t ocsc : 1;
|
||||
struct rom_curve_caps dgam_rom_caps;
|
||||
struct rom_curve_caps ogam_rom_caps;
|
||||
};
|
||||
|
||||
struct mpc_color_caps {
|
||||
uint16_t gamut_remap : 1;
|
||||
uint16_t ogam_ram : 1;
|
||||
uint16_t ocsc : 1;
|
||||
uint16_t num_3dluts : 3; //3d lut always assumes a preceding shaper LUT
|
||||
uint16_t shared_3d_lut:1; //can be in either DPP or MPC, but single instance
|
||||
|
||||
struct rom_curve_caps ogam_rom_caps;
|
||||
};
|
||||
|
||||
struct dc_color_caps {
|
||||
struct dpp_color_caps dpp;
|
||||
struct mpc_color_caps mpc;
|
||||
};
|
||||
|
||||
struct dc_caps {
|
||||
uint32_t max_streams;
|
||||
uint32_t max_links;
|
||||
|
@ -120,9 +163,9 @@ struct dc_caps {
|
|||
bool psp_setup_panel_mode;
|
||||
bool extended_aux_timeout_support;
|
||||
bool dmcub_support;
|
||||
bool hw_3d_lut;
|
||||
enum dp_protocol_version max_dp_protocol_version;
|
||||
struct dc_plane_cap planes[MAX_PLANES];
|
||||
struct dc_color_caps color;
|
||||
};
|
||||
|
||||
struct dc_bug_wa {
|
||||
|
@ -478,6 +521,7 @@ struct dc_bounding_box_overrides {
|
|||
int urgent_latency_ns;
|
||||
int percent_of_ideal_drambw;
|
||||
int dram_clock_change_latency_ns;
|
||||
int dummy_clock_change_latency_ns;
|
||||
/* This forces a hard min on the DCFCLK we use
|
||||
* for DML. Unlike the debug option for forcing
|
||||
* DCFCLK, this override affects watermark calculations
|
||||
|
|
|
@ -58,7 +58,7 @@ void dc_dmub_srv_destroy(struct dc_dmub_srv **dmub_srv)
|
|||
}
|
||||
|
||||
void dc_dmub_srv_cmd_queue(struct dc_dmub_srv *dc_dmub_srv,
|
||||
struct dmub_cmd_header *cmd)
|
||||
union dmub_rb_cmd *cmd)
|
||||
{
|
||||
struct dmub_srv *dmub = dc_dmub_srv->dmub;
|
||||
struct dc_context *dc_ctx = dc_dmub_srv->ctx;
|
||||
|
|
|
@ -27,10 +27,9 @@
|
|||
#define _DMUB_DC_SRV_H_
|
||||
|
||||
#include "os_types.h"
|
||||
#include "../dmub/inc/dmub_cmd.h"
|
||||
#include "dmub/inc/dmub_cmd.h"
|
||||
|
||||
struct dmub_srv;
|
||||
struct dmub_cmd_header;
|
||||
|
||||
struct dc_reg_helper_state {
|
||||
bool gather_in_progress;
|
||||
|
@ -49,7 +48,7 @@ struct dc_dmub_srv {
|
|||
};
|
||||
|
||||
void dc_dmub_srv_cmd_queue(struct dc_dmub_srv *dc_dmub_srv,
|
||||
struct dmub_cmd_header *cmd);
|
||||
union dmub_rb_cmd *cmd);
|
||||
|
||||
void dc_dmub_srv_cmd_execute(struct dc_dmub_srv *dc_dmub_srv);
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ static inline void submit_dmub_read_modify_write(
|
|||
gather = ctx->dmub_srv->reg_helper_offload.gather_in_progress;
|
||||
ctx->dmub_srv->reg_helper_offload.gather_in_progress = false;
|
||||
|
||||
dc_dmub_srv_cmd_queue(ctx->dmub_srv, &cmd_buf->header);
|
||||
dc_dmub_srv_cmd_queue(ctx->dmub_srv, &offload->cmd_data);
|
||||
|
||||
ctx->dmub_srv->reg_helper_offload.gather_in_progress = gather;
|
||||
|
||||
|
@ -73,7 +73,7 @@ static inline void submit_dmub_burst_write(
|
|||
gather = ctx->dmub_srv->reg_helper_offload.gather_in_progress;
|
||||
ctx->dmub_srv->reg_helper_offload.gather_in_progress = false;
|
||||
|
||||
dc_dmub_srv_cmd_queue(ctx->dmub_srv, &cmd_buf->header);
|
||||
dc_dmub_srv_cmd_queue(ctx->dmub_srv, &offload->cmd_data);
|
||||
|
||||
ctx->dmub_srv->reg_helper_offload.gather_in_progress = gather;
|
||||
|
||||
|
@ -92,7 +92,7 @@ static inline void submit_dmub_reg_wait(
|
|||
gather = ctx->dmub_srv->reg_helper_offload.gather_in_progress;
|
||||
ctx->dmub_srv->reg_helper_offload.gather_in_progress = false;
|
||||
|
||||
dc_dmub_srv_cmd_queue(ctx->dmub_srv, &cmd_buf->header);
|
||||
dc_dmub_srv_cmd_queue(ctx->dmub_srv, &offload->cmd_data);
|
||||
|
||||
memset(cmd_buf, 0, sizeof(*cmd_buf));
|
||||
offload->reg_seq_count = 0;
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
|
||||
#define MCP_DISABLE_ABM_IMMEDIATELY 255
|
||||
|
||||
static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id)
|
||||
static bool dce_abm_set_pipe(struct abm *abm, uint32_t controller_id, uint32_t panel_inst)
|
||||
{
|
||||
struct dce_abm *abm_dce = TO_DCE_ABM(abm);
|
||||
uint32_t rampingBoundary = 0xFFFF;
|
||||
|
@ -201,7 +201,8 @@ static void dmcu_set_backlight_level(
|
|||
struct dce_abm *abm_dce,
|
||||
uint32_t backlight_pwm_u16_16,
|
||||
uint32_t frame_ramp,
|
||||
uint32_t controller_id)
|
||||
uint32_t controller_id,
|
||||
uint32_t panel_id)
|
||||
{
|
||||
unsigned int backlight_8_bit = 0;
|
||||
uint32_t s2;
|
||||
|
@ -213,7 +214,7 @@ static void dmcu_set_backlight_level(
|
|||
// Take MSB of fractional part since backlight is not max
|
||||
backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF;
|
||||
|
||||
dce_abm_set_pipe(&abm_dce->base, controller_id);
|
||||
dce_abm_set_pipe(&abm_dce->base, controller_id, panel_id);
|
||||
|
||||
/* waitDMCUReadyForCmd */
|
||||
REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT,
|
||||
|
@ -331,14 +332,14 @@ static bool dce_abm_set_level(struct abm *abm, uint32_t level)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool dce_abm_immediate_disable(struct abm *abm)
|
||||
static bool dce_abm_immediate_disable(struct abm *abm, uint32_t panel_inst)
|
||||
{
|
||||
struct dce_abm *abm_dce = TO_DCE_ABM(abm);
|
||||
|
||||
if (abm->dmcu_is_running == false)
|
||||
return true;
|
||||
|
||||
dce_abm_set_pipe(abm, MCP_DISABLE_ABM_IMMEDIATELY);
|
||||
dce_abm_set_pipe(abm, MCP_DISABLE_ABM_IMMEDIATELY, panel_inst);
|
||||
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL =
|
||||
REG_READ(BL_PWM_CNTL);
|
||||
|
@ -420,6 +421,7 @@ static bool dce_abm_set_backlight_level_pwm(
|
|||
unsigned int backlight_pwm_u16_16,
|
||||
unsigned int frame_ramp,
|
||||
unsigned int controller_id,
|
||||
unsigned int panel_inst,
|
||||
bool fw_set_brightness)
|
||||
{
|
||||
struct dce_abm *abm_dce = TO_DCE_ABM(abm);
|
||||
|
@ -432,7 +434,8 @@ static bool dce_abm_set_backlight_level_pwm(
|
|||
dmcu_set_backlight_level(abm_dce,
|
||||
backlight_pwm_u16_16,
|
||||
frame_ramp,
|
||||
controller_id);
|
||||
controller_id,
|
||||
panel_inst);
|
||||
else
|
||||
driver_set_backlight_level(abm_dce, backlight_pwm_u16_16);
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "dce_abm.h"
|
||||
#include "dc.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "../../dmub/inc/dmub_srv.h"
|
||||
#include "dmub/inc/dmub_srv.h"
|
||||
#include "core_types.h"
|
||||
#include "dm_services.h"
|
||||
#include "reg_helper.h"
|
||||
|
@ -50,7 +50,7 @@
|
|||
|
||||
#define DISABLE_ABM_IMMEDIATELY 255
|
||||
|
||||
static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst)
|
||||
static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst, uint32_t panel_inst)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = abm->ctx;
|
||||
|
@ -59,10 +59,11 @@ static bool dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst)
|
|||
cmd.abm_set_pipe.header.type = DMUB_CMD__ABM;
|
||||
cmd.abm_set_pipe.header.sub_type = DMUB_CMD__ABM_SET_PIPE;
|
||||
cmd.abm_set_pipe.abm_set_pipe_data.otg_inst = otg_inst;
|
||||
cmd.abm_set_pipe.abm_set_pipe_data.panel_inst = panel_inst;
|
||||
cmd.abm_set_pipe.abm_set_pipe_data.ramping_boundary = ramping_boundary;
|
||||
cmd.abm_set_pipe.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pipe_data);
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_set_pipe.header);
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dc->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||
|
||||
|
@ -120,7 +121,8 @@ static void dmcub_set_backlight_level(
|
|||
struct dce_abm *dce_abm,
|
||||
uint32_t backlight_pwm_u16_16,
|
||||
uint32_t frame_ramp,
|
||||
uint32_t otg_inst)
|
||||
uint32_t otg_inst,
|
||||
uint32_t panel_inst)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = dce_abm->base.ctx;
|
||||
|
@ -134,7 +136,7 @@ static void dmcub_set_backlight_level(
|
|||
// Take MSB of fractional part since backlight is not max
|
||||
backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF;
|
||||
|
||||
dmub_abm_set_pipe(&dce_abm->base, otg_inst);
|
||||
dmub_abm_set_pipe(&dce_abm->base, otg_inst, panel_inst);
|
||||
|
||||
REG_UPDATE(BL1_PWM_USER_LEVEL, BL1_PWM_USER_LEVEL, backlight_pwm_u16_16);
|
||||
|
||||
|
@ -146,7 +148,7 @@ static void dmcub_set_backlight_level(
|
|||
cmd.abm_set_backlight.abm_set_backlight_data.frame_ramp = frame_ramp;
|
||||
cmd.abm_set_backlight.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_backlight_data);
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_set_backlight.header);
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dc->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||
|
||||
|
@ -171,7 +173,7 @@ static void dmub_abm_enable_fractional_pwm(struct dc_context *dc)
|
|||
cmd.abm_set_pwm_frac.abm_set_pwm_frac_data.fractional_pwm = fractional_pwm;
|
||||
cmd.abm_set_pwm_frac.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pwm_frac_data);
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_set_pwm_frac.header);
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dc->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||
}
|
||||
|
@ -250,18 +252,18 @@ static bool dmub_abm_set_level(struct abm *abm, uint32_t level)
|
|||
cmd.abm_set_level.abm_set_level_data.level = level;
|
||||
cmd.abm_set_level.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_level_data);
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_set_level.header);
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dc->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool dmub_abm_immediate_disable(struct abm *abm)
|
||||
static bool dmub_abm_immediate_disable(struct abm *abm, uint32_t panel_inst)
|
||||
{
|
||||
struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
|
||||
|
||||
dmub_abm_set_pipe(abm, DISABLE_ABM_IMMEDIATELY);
|
||||
dmub_abm_set_pipe(abm, DISABLE_ABM_IMMEDIATELY, panel_inst);
|
||||
|
||||
abm->stored_backlight_registers.BL_PWM_CNTL =
|
||||
REG_READ(BL_PWM_CNTL);
|
||||
|
@ -338,6 +340,7 @@ static bool dmub_abm_set_backlight_level_pwm(
|
|||
unsigned int backlight_pwm_u16_16,
|
||||
unsigned int frame_ramp,
|
||||
unsigned int otg_inst,
|
||||
uint32_t panel_inst,
|
||||
bool fw_set_brightness)
|
||||
{
|
||||
struct dce_abm *dce_abm = TO_DMUB_ABM(abm);
|
||||
|
@ -345,7 +348,8 @@ static bool dmub_abm_set_backlight_level_pwm(
|
|||
dmcub_set_backlight_level(dce_abm,
|
||||
backlight_pwm_u16_16,
|
||||
frame_ramp,
|
||||
otg_inst);
|
||||
otg_inst,
|
||||
panel_inst);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -370,7 +374,7 @@ static bool dmub_abm_init_config(struct abm *abm,
|
|||
cmd.abm_init_config.abm_init_config_data.bytes = bytes;
|
||||
cmd.abm_init_config.header.payload_bytes = sizeof(struct dmub_cmd_abm_init_config_data);
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.abm_init_config.header);
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dc->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
#include "dmub_psr.h"
|
||||
#include "dc.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "../../dmub/inc/dmub_srv.h"
|
||||
#include "../../dmub/inc/dmub_gpint_cmd.h"
|
||||
#include "dmub/inc/dmub_srv.h"
|
||||
#include "dmub/inc/dmub_gpint_cmd.h"
|
||||
#include "core_types.h"
|
||||
|
||||
#define MAX_PIPES 6
|
||||
|
@ -102,7 +102,7 @@ static bool dmub_psr_set_version(struct dmub_psr *dmub, struct dc_stream_state *
|
|||
cmd.psr_set_version.psr_set_version_data.version = stream->link->psr_settings.psr_version;
|
||||
cmd.psr_set_version.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_version_data);
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.psr_set_version.header);
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dc->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||
|
||||
|
@ -126,7 +126,7 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable)
|
|||
|
||||
cmd.psr_enable.header.payload_bytes = 0; // Send header only
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.psr_enable.header);
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dc->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level)
|
|||
cmd.psr_set_level.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_level_data);
|
||||
cmd.psr_set_level.psr_set_level_data.psr_level = psr_level;
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.psr_set_level.header);
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dc->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
|
|||
copy_settings_data->debug.visual_confirm = dc->dc->debug.visual_confirm == VISUAL_CONFIRM_PSR ?
|
||||
true : false;
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.psr_copy_settings.header);
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dc->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||
|
||||
|
|
|
@ -2714,6 +2714,37 @@ void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
|
|||
pipe_ctx->plane_res.xfm, attributes);
|
||||
}
|
||||
|
||||
bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
|
||||
uint32_t backlight_pwm_u16_16,
|
||||
uint32_t frame_ramp)
|
||||
{
|
||||
struct dc_link *link = pipe_ctx->stream->link;
|
||||
struct dc *dc = link->ctx->dc;
|
||||
struct abm *abm = pipe_ctx->stream_res.abm;
|
||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||
bool fw_set_brightness = true;
|
||||
/* DMCU -1 for all controller id values,
|
||||
* therefore +1 here
|
||||
*/
|
||||
uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1;
|
||||
|
||||
if (abm == NULL || (abm->funcs->set_backlight_level_pwm == NULL))
|
||||
return false;
|
||||
|
||||
if (dmcu)
|
||||
fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu);
|
||||
|
||||
abm->funcs->set_backlight_level_pwm(
|
||||
abm,
|
||||
backlight_pwm_u16_16,
|
||||
frame_ramp,
|
||||
controller_id,
|
||||
link->panel_cntl->inst,
|
||||
fw_set_brightness);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct hw_sequencer_funcs dce110_funcs = {
|
||||
.program_gamut_remap = program_gamut_remap,
|
||||
.program_output_csc = program_output_csc,
|
||||
|
@ -2736,6 +2767,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
|
|||
.disable_plane = dce110_power_down_fe,
|
||||
.pipe_control_lock = dce_pipe_control_lock,
|
||||
.interdependent_update_lock = NULL,
|
||||
.cursor_lock = dce_pipe_control_lock,
|
||||
.prepare_bandwidth = dce110_prepare_bandwidth,
|
||||
.optimize_bandwidth = dce110_optimize_bandwidth,
|
||||
.set_drr = set_drr,
|
||||
|
@ -2747,7 +2779,8 @@ static const struct hw_sequencer_funcs dce110_funcs = {
|
|||
.edp_power_control = dce110_edp_power_control,
|
||||
.edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
|
||||
.set_cursor_position = dce110_set_cursor_position,
|
||||
.set_cursor_attribute = dce110_set_cursor_attribute
|
||||
.set_cursor_attribute = dce110_set_cursor_attribute,
|
||||
.set_backlight_level = dce110_set_backlight_level,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dce110_private_funcs = {
|
||||
|
|
|
@ -85,5 +85,9 @@ void dce110_edp_wait_for_hpd_ready(
|
|||
struct dc_link *link,
|
||||
bool power_up);
|
||||
|
||||
bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx,
|
||||
uint32_t backlight_pwm_u16_16,
|
||||
uint32_t frame_ramp);
|
||||
|
||||
#endif /* __DC_HWSS_DCE110_H__ */
|
||||
|
||||
|
|
|
@ -679,8 +679,7 @@ void dce110_opp_v_set_csc_default(
|
|||
if (default_adjust->force_hw_default == false) {
|
||||
const struct out_csc_color_matrix *elm;
|
||||
/* currently parameter not in use */
|
||||
enum grph_color_adjust_option option =
|
||||
GRPH_COLOR_MATRIX_HW_DEFAULT;
|
||||
enum grph_color_adjust_option option;
|
||||
uint32_t i;
|
||||
/*
|
||||
* HW default false we program locally defined matrix
|
||||
|
|
|
@ -903,7 +903,8 @@ static void dcn10_reset_back_end_for_pipe(
|
|||
if (pipe_ctx->top_pipe == NULL) {
|
||||
|
||||
if (pipe_ctx->stream_res.abm)
|
||||
pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm);
|
||||
pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm,
|
||||
pipe_ctx->stream->link->panel_cntl->inst);
|
||||
|
||||
pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
|
||||
|
||||
|
@ -1668,6 +1669,16 @@ void dcn10_pipe_control_lock(
|
|||
hws->funcs.verify_allow_pstate_change_high(dc);
|
||||
}
|
||||
|
||||
void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock)
|
||||
{
|
||||
/* cursor lock is per MPCC tree, so only need to lock one pipe per stream */
|
||||
if (!pipe || pipe->top_pipe)
|
||||
return;
|
||||
|
||||
dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc,
|
||||
pipe->stream_res.opp->inst, lock);
|
||||
}
|
||||
|
||||
static bool wait_for_reset_trigger_to_occur(
|
||||
struct dc_context *dc_ctx,
|
||||
struct timing_generator *tg)
|
||||
|
@ -2474,12 +2485,14 @@ void dcn10_blank_pixel_data(
|
|||
if (stream_res->tg->funcs->set_blank)
|
||||
stream_res->tg->funcs->set_blank(stream_res->tg, blank);
|
||||
if (stream_res->abm) {
|
||||
stream_res->abm->funcs->set_pipe(stream_res->abm, stream_res->tg->inst + 1);
|
||||
stream_res->abm->funcs->set_pipe(stream_res->abm, stream_res->tg->inst + 1,
|
||||
stream->link->panel_cntl->inst);
|
||||
stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level);
|
||||
}
|
||||
} else if (blank) {
|
||||
if (stream_res->abm)
|
||||
stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm);
|
||||
stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm,
|
||||
stream->link->panel_cntl->inst);
|
||||
if (stream_res->tg->funcs->set_blank)
|
||||
stream_res->tg->funcs->set_blank(stream_res->tg, blank);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ void dcn10_pipe_control_lock(
|
|||
struct dc *dc,
|
||||
struct pipe_ctx *pipe,
|
||||
bool lock);
|
||||
void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock);
|
||||
void dcn10_blank_pixel_data(
|
||||
struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
|
|
|
@ -50,6 +50,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
|
|||
.disable_audio_stream = dce110_disable_audio_stream,
|
||||
.disable_plane = dcn10_disable_plane,
|
||||
.pipe_control_lock = dcn10_pipe_control_lock,
|
||||
.cursor_lock = dcn10_cursor_lock,
|
||||
.interdependent_update_lock = dcn10_lock_all_pipes,
|
||||
.prepare_bandwidth = dcn10_prepare_bandwidth,
|
||||
.optimize_bandwidth = dcn10_optimize_bandwidth,
|
||||
|
@ -71,6 +72,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
|
|||
.set_clock = dcn10_set_clock,
|
||||
.get_clock = dcn10_get_clock,
|
||||
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
|
||||
.set_backlight_level = dce110_set_backlight_level,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn10_private_funcs = {
|
||||
|
|
|
@ -223,6 +223,9 @@ struct mpcc *mpc1_insert_plane(
|
|||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_id);
|
||||
|
||||
/* Configure VUPDATE lock set for this MPCC to map to the OPP */
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, tree->opp_id);
|
||||
|
||||
/* update mpc tree mux setting */
|
||||
if (tree->opp_list == insert_above_mpcc) {
|
||||
/* insert the toppest mpcc */
|
||||
|
@ -318,6 +321,7 @@ void mpc1_remove_mpcc(
|
|||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
|
||||
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
|
||||
|
||||
/* mark this mpcc as not in use */
|
||||
mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id);
|
||||
|
@ -328,6 +332,7 @@ void mpc1_remove_mpcc(
|
|||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
|
||||
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -361,6 +366,7 @@ void mpc1_mpc_init(struct mpc *mpc)
|
|||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
|
||||
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
|
||||
|
||||
mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id);
|
||||
}
|
||||
|
@ -381,6 +387,7 @@ void mpc1_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id)
|
|||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
|
||||
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
|
||||
|
||||
mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id);
|
||||
|
||||
|
@ -453,6 +460,13 @@ void mpc1_read_mpcc_state(
|
|||
MPCC_BUSY, &s->busy);
|
||||
}
|
||||
|
||||
void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock)
|
||||
{
|
||||
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
|
||||
|
||||
REG_SET(CUR[opp_id], 0, CUR_VUPDATE_LOCK_SET, lock ? 1 : 0);
|
||||
}
|
||||
|
||||
static const struct mpc_funcs dcn10_mpc_funcs = {
|
||||
.read_mpcc_state = mpc1_read_mpcc_state,
|
||||
.insert_plane = mpc1_insert_plane,
|
||||
|
@ -464,6 +478,7 @@ static const struct mpc_funcs dcn10_mpc_funcs = {
|
|||
.assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect,
|
||||
.init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
|
||||
.update_blending = mpc1_update_blending,
|
||||
.cursor_lock = mpc1_cursor_lock,
|
||||
.set_denorm = NULL,
|
||||
.set_denorm_clamp = NULL,
|
||||
.set_output_csc = NULL,
|
||||
|
|
|
@ -39,11 +39,12 @@
|
|||
SRII(MPCC_BG_G_Y, MPCC, inst),\
|
||||
SRII(MPCC_BG_R_CR, MPCC, inst),\
|
||||
SRII(MPCC_BG_B_CB, MPCC, inst),\
|
||||
SRII(MPCC_BG_B_CB, MPCC, inst),\
|
||||
SRII(MPCC_SM_CONTROL, MPCC, inst)
|
||||
SRII(MPCC_SM_CONTROL, MPCC, inst),\
|
||||
SRII(MPCC_UPDATE_LOCK_SEL, MPCC, inst)
|
||||
|
||||
#define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \
|
||||
SRII(MUX, MPC_OUT, inst)
|
||||
SRII(MUX, MPC_OUT, inst),\
|
||||
VUPDATE_SRII(CUR, VUPDATE_LOCK_SET, inst)
|
||||
|
||||
#define MPC_COMMON_REG_VARIABLE_LIST \
|
||||
uint32_t MPCC_TOP_SEL[MAX_MPCC]; \
|
||||
|
@ -55,7 +56,9 @@
|
|||
uint32_t MPCC_BG_R_CR[MAX_MPCC]; \
|
||||
uint32_t MPCC_BG_B_CB[MAX_MPCC]; \
|
||||
uint32_t MPCC_SM_CONTROL[MAX_MPCC]; \
|
||||
uint32_t MUX[MAX_OPP];
|
||||
uint32_t MUX[MAX_OPP]; \
|
||||
uint32_t MPCC_UPDATE_LOCK_SEL[MAX_MPCC]; \
|
||||
uint32_t CUR[MAX_OPP];
|
||||
|
||||
#define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\
|
||||
SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\
|
||||
|
@ -78,7 +81,8 @@
|
|||
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FIELD_ALT, mask_sh),\
|
||||
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_FRAME_POL, mask_sh),\
|
||||
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_TOP_POL, mask_sh),\
|
||||
SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh)
|
||||
SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh),\
|
||||
SF(MPCC0_MPCC_UPDATE_LOCK_SEL, MPCC_UPDATE_LOCK_SEL, mask_sh)
|
||||
|
||||
#define MPC_REG_FIELD_LIST(type) \
|
||||
type MPCC_TOP_SEL;\
|
||||
|
@ -101,7 +105,9 @@
|
|||
type MPCC_SM_FIELD_ALT;\
|
||||
type MPCC_SM_FORCE_NEXT_FRAME_POL;\
|
||||
type MPCC_SM_FORCE_NEXT_TOP_POL;\
|
||||
type MPC_OUT_MUX;
|
||||
type MPC_OUT_MUX;\
|
||||
type MPCC_UPDATE_LOCK_SEL;\
|
||||
type CUR_VUPDATE_LOCK_SET;
|
||||
|
||||
struct dcn_mpc_registers {
|
||||
MPC_COMMON_REG_VARIABLE_LIST
|
||||
|
@ -192,4 +198,6 @@ void mpc1_read_mpcc_state(
|
|||
int mpcc_inst,
|
||||
struct mpcc_state *s);
|
||||
|
||||
void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -182,6 +182,14 @@ enum dcn10_clk_src_array_id {
|
|||
.reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
|
||||
mm ## block ## id ## _ ## reg_name
|
||||
|
||||
#define VUPDATE_SRII(reg_name, block, id)\
|
||||
.reg_name[id] = BASE(mm ## reg_name ## 0 ## _ ## block ## id ## _BASE_IDX) + \
|
||||
mm ## reg_name ## 0 ## _ ## block ## id
|
||||
|
||||
/* set field/register/bitfield name */
|
||||
#define SFRB(field_name, reg_name, bitfield, post_fix)\
|
||||
.field_name = reg_name ## __ ## bitfield ## post_fix
|
||||
|
||||
/* NBIO */
|
||||
#define NBIO_BASE_INNER(seg) \
|
||||
NBIF_BASE__INST0_SEG ## seg
|
||||
|
@ -432,11 +440,13 @@ static const struct dcn_mpc_registers mpc_regs = {
|
|||
};
|
||||
|
||||
static const struct dcn_mpc_shift mpc_shift = {
|
||||
MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT)
|
||||
MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT),\
|
||||
SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, __SHIFT)
|
||||
};
|
||||
|
||||
static const struct dcn_mpc_mask mpc_mask = {
|
||||
MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK),
|
||||
MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK),\
|
||||
SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, _MASK)
|
||||
};
|
||||
|
||||
#define tg_regs(id)\
|
||||
|
@ -1384,6 +1394,40 @@ static bool dcn10_resource_construct(
|
|||
/* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */
|
||||
dc->caps.force_dp_tps4_for_cp2520 = true;
|
||||
|
||||
/* Color pipeline capabilities */
|
||||
dc->caps.color.dpp.dcn_arch = 1;
|
||||
dc->caps.color.dpp.input_lut_shared = 1;
|
||||
dc->caps.color.dpp.icsc = 1;
|
||||
dc->caps.color.dpp.dgam_ram = 1;
|
||||
dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
|
||||
dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
|
||||
dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 0;
|
||||
dc->caps.color.dpp.dgam_rom_caps.pq = 0;
|
||||
dc->caps.color.dpp.dgam_rom_caps.hlg = 0;
|
||||
dc->caps.color.dpp.post_csc = 0;
|
||||
dc->caps.color.dpp.gamma_corr = 0;
|
||||
|
||||
dc->caps.color.dpp.hw_3d_lut = 0;
|
||||
dc->caps.color.dpp.ogam_ram = 1; // RGAM on DCN1
|
||||
dc->caps.color.dpp.ogam_rom_caps.srgb = 1;
|
||||
dc->caps.color.dpp.ogam_rom_caps.bt2020 = 1;
|
||||
dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
|
||||
dc->caps.color.dpp.ogam_rom_caps.pq = 0;
|
||||
dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
|
||||
dc->caps.color.dpp.ocsc = 1;
|
||||
|
||||
/* no post-blend color operations */
|
||||
dc->caps.color.mpc.gamut_remap = 0;
|
||||
dc->caps.color.mpc.num_3dluts = 0;
|
||||
dc->caps.color.mpc.shared_3d_lut = 0;
|
||||
dc->caps.color.mpc.ogam_ram = 0;
|
||||
dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
|
||||
dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
|
||||
dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
|
||||
dc->caps.color.mpc.ogam_rom_caps.pq = 0;
|
||||
dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
|
||||
dc->caps.color.mpc.ocsc = 0;
|
||||
|
||||
if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
|
||||
dc->debug = debug_defaults_drv;
|
||||
else
|
||||
|
|
|
@ -962,7 +962,8 @@ void dcn20_blank_pixel_data(
|
|||
|
||||
if (blank) {
|
||||
if (stream_res->abm)
|
||||
stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm);
|
||||
stream_res->abm->funcs->set_abm_immediate_disable(stream_res->abm,
|
||||
stream->link->panel_cntl->inst);
|
||||
|
||||
if (dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) {
|
||||
test_pattern = CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
|
||||
|
@ -997,7 +998,8 @@ void dcn20_blank_pixel_data(
|
|||
|
||||
if (!blank)
|
||||
if (stream_res->abm) {
|
||||
stream_res->abm->funcs->set_pipe(stream_res->abm, stream_res->tg->inst + 1);
|
||||
stream_res->abm->funcs->set_pipe(stream_res->abm, stream_res->tg->inst + 1,
|
||||
stream->link->panel_cntl->inst);
|
||||
stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level);
|
||||
}
|
||||
}
|
||||
|
@ -2041,7 +2043,8 @@ static void dcn20_reset_back_end_for_pipe(
|
|||
if (pipe_ctx->top_pipe == NULL) {
|
||||
|
||||
if (pipe_ctx->stream_res.abm)
|
||||
pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm);
|
||||
pipe_ctx->stream_res.abm->funcs->set_abm_immediate_disable(pipe_ctx->stream_res.abm,
|
||||
pipe_ctx->stream->link->panel_cntl->inst);
|
||||
|
||||
pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);
|
||||
|
||||
|
@ -2304,7 +2307,8 @@ void dcn20_fpga_init_hw(struct dc *dc)
|
|||
|
||||
REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2);
|
||||
REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
|
||||
REG_WRITE(REFCLK_CNTL, 0);
|
||||
if (REG(REFCLK_CNTL))
|
||||
REG_WRITE(REFCLK_CNTL, 0);
|
||||
//
|
||||
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
|
|||
.disable_plane = dcn20_disable_plane,
|
||||
.pipe_control_lock = dcn20_pipe_control_lock,
|
||||
.interdependent_update_lock = dcn10_lock_all_pipes,
|
||||
.cursor_lock = dcn10_cursor_lock,
|
||||
.prepare_bandwidth = dcn20_prepare_bandwidth,
|
||||
.optimize_bandwidth = dcn20_optimize_bandwidth,
|
||||
.update_bandwidth = dcn20_update_bandwidth,
|
||||
|
@ -82,6 +83,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
|
|||
.init_vm_ctx = dcn20_init_vm_ctx,
|
||||
.set_flip_control_gsl = dcn20_set_flip_control_gsl,
|
||||
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
|
||||
.set_backlight_level = dce110_set_backlight_level,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn20_private_funcs = {
|
||||
|
|
|
@ -452,7 +452,7 @@ void mpc2_set_output_gamma(
|
|||
next_mode = LUT_RAM_A;
|
||||
|
||||
mpc20_power_on_ogam_lut(mpc, mpcc_id, true);
|
||||
mpc20_configure_ogam_lut(mpc, mpcc_id, next_mode == LUT_RAM_A ? true:false);
|
||||
mpc20_configure_ogam_lut(mpc, mpcc_id, next_mode == LUT_RAM_A);
|
||||
|
||||
if (next_mode == LUT_RAM_A)
|
||||
mpc2_program_luta(mpc, mpcc_id, params);
|
||||
|
@ -545,6 +545,7 @@ const struct mpc_funcs dcn20_mpc_funcs = {
|
|||
.mpc_init = mpc1_mpc_init,
|
||||
.mpc_init_single_inst = mpc1_mpc_init_single_inst,
|
||||
.update_blending = mpc2_update_blending,
|
||||
.cursor_lock = mpc1_cursor_lock,
|
||||
.get_mpcc_for_dpp = mpc2_get_mpcc_for_dpp,
|
||||
.wait_for_idle = mpc2_assert_idle_mpcc,
|
||||
.assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect,
|
||||
|
|
|
@ -179,7 +179,8 @@
|
|||
SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MAX_G_Y, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MIN_G_Y, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MAX_B_CB, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh)
|
||||
SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh),\
|
||||
SF(CUR_VUPDATE_LOCK_SET0, CUR_VUPDATE_LOCK_SET, mask_sh)
|
||||
|
||||
/*
|
||||
* DCN2 MPC_OCSC debug status register:
|
||||
|
|
|
@ -509,6 +509,10 @@ enum dcn20_clk_src_array_id {
|
|||
.block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
|
||||
mm ## block ## id ## _ ## reg_name
|
||||
|
||||
#define VUPDATE_SRII(reg_name, block, id)\
|
||||
.reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
|
||||
mm ## reg_name ## _ ## block ## id
|
||||
|
||||
/* NBIO */
|
||||
#define NBIO_BASE_INNER(seg) \
|
||||
NBIO_BASE__INST0_SEG ## seg
|
||||
|
@ -1936,7 +1940,7 @@ bool dcn20_split_stream_for_odm(
|
|||
return true;
|
||||
}
|
||||
|
||||
void dcn20_split_stream_for_mpc(
|
||||
bool dcn20_split_stream_for_mpc(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
struct pipe_ctx *primary_pipe,
|
||||
|
@ -1965,8 +1969,11 @@ void dcn20_split_stream_for_mpc(
|
|||
secondary_pipe->top_pipe = primary_pipe;
|
||||
|
||||
ASSERT(primary_pipe->plane_state);
|
||||
resource_build_scaling_params(primary_pipe);
|
||||
resource_build_scaling_params(secondary_pipe);
|
||||
if (!resource_build_scaling_params(primary_pipe) ||
|
||||
!resource_build_scaling_params(secondary_pipe))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dcn20_populate_dml_writeback_from_context(
|
||||
|
@ -2623,19 +2630,24 @@ int dcn20_validate_apply_pipe_split_flags(
|
|||
|
||||
/* Avoid split loop looks for lowest voltage level that allows most unsplit pipes possible */
|
||||
if (avoid_split) {
|
||||
int max_mpc_comb = context->bw_ctx.dml.vba.maxMpcComb;
|
||||
|
||||
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
if (!context->res_ctx.pipe_ctx[i].stream)
|
||||
continue;
|
||||
|
||||
for (vlevel_split = vlevel; vlevel <= context->bw_ctx.dml.soc.num_states; vlevel++)
|
||||
if (context->bw_ctx.dml.vba.NoOfDPP[vlevel][0][pipe_idx] == 1)
|
||||
if (context->bw_ctx.dml.vba.NoOfDPP[vlevel][0][pipe_idx] == 1 &&
|
||||
context->bw_ctx.dml.vba.ModeSupport[vlevel][0])
|
||||
break;
|
||||
/* Impossible to not split this pipe */
|
||||
if (vlevel > context->bw_ctx.dml.soc.num_states)
|
||||
vlevel = vlevel_split;
|
||||
else
|
||||
max_mpc_comb = 0;
|
||||
pipe_idx++;
|
||||
}
|
||||
context->bw_ctx.dml.vba.maxMpcComb = 0;
|
||||
context->bw_ctx.dml.vba.maxMpcComb = max_mpc_comb;
|
||||
}
|
||||
|
||||
/* Split loop sets which pipe should be split based on dml outputs and dc flags */
|
||||
|
@ -2791,9 +2803,10 @@ bool dcn20_fast_validate_bw(
|
|||
goto validate_fail;
|
||||
dcn20_build_mapped_resource(dc, context, pipe->stream);
|
||||
} else
|
||||
dcn20_split_stream_for_mpc(
|
||||
&context->res_ctx, dc->res_pool,
|
||||
pipe, hsplit_pipe);
|
||||
if (!dcn20_split_stream_for_mpc(
|
||||
&context->res_ctx, dc->res_pool,
|
||||
pipe, hsplit_pipe))
|
||||
goto validate_fail;
|
||||
pipe_split_from[hsplit_pipe->pipe_idx] = pipe_idx;
|
||||
}
|
||||
} else if (hsplit_pipe && hsplit_pipe->plane_state == pipe->plane_state) {
|
||||
|
@ -3458,6 +3471,13 @@ void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st
|
|||
bb->dram_clock_change_latency_us =
|
||||
dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
|
||||
}
|
||||
|
||||
if ((int)(bb->dummy_pstate_latency_us * 1000)
|
||||
!= dc->bb_overrides.dummy_clock_change_latency_ns
|
||||
&& dc->bb_overrides.dummy_clock_change_latency_ns) {
|
||||
bb->dummy_pstate_latency_us =
|
||||
dc->bb_overrides.dummy_clock_change_latency_ns / 1000.0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct _vcs_dpi_soc_bounding_box_st *get_asic_rev_soc_bb(
|
||||
|
@ -3693,9 +3713,42 @@ static bool dcn20_resource_construct(
|
|||
dc->caps.max_slave_planes = 1;
|
||||
dc->caps.post_blend_color_processing = true;
|
||||
dc->caps.force_dp_tps4_for_cp2520 = true;
|
||||
dc->caps.hw_3d_lut = true;
|
||||
dc->caps.extended_aux_timeout_support = true;
|
||||
|
||||
/* Color pipeline capabilities */
|
||||
dc->caps.color.dpp.dcn_arch = 1;
|
||||
dc->caps.color.dpp.input_lut_shared = 0;
|
||||
dc->caps.color.dpp.icsc = 1;
|
||||
dc->caps.color.dpp.dgam_ram = 1;
|
||||
dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
|
||||
dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
|
||||
dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 0;
|
||||
dc->caps.color.dpp.dgam_rom_caps.pq = 0;
|
||||
dc->caps.color.dpp.dgam_rom_caps.hlg = 0;
|
||||
dc->caps.color.dpp.post_csc = 0;
|
||||
dc->caps.color.dpp.gamma_corr = 0;
|
||||
|
||||
dc->caps.color.dpp.hw_3d_lut = 1;
|
||||
dc->caps.color.dpp.ogam_ram = 1;
|
||||
// no OGAM ROM on DCN2, only MPC ROM
|
||||
dc->caps.color.dpp.ogam_rom_caps.srgb = 0;
|
||||
dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;
|
||||
dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
|
||||
dc->caps.color.dpp.ogam_rom_caps.pq = 0;
|
||||
dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
|
||||
dc->caps.color.dpp.ocsc = 0;
|
||||
|
||||
dc->caps.color.mpc.gamut_remap = 0;
|
||||
dc->caps.color.mpc.num_3dluts = 0;
|
||||
dc->caps.color.mpc.shared_3d_lut = 0;
|
||||
dc->caps.color.mpc.ogam_ram = 1;
|
||||
dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
|
||||
dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
|
||||
dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
|
||||
dc->caps.color.mpc.ogam_rom_caps.pq = 0;
|
||||
dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
|
||||
dc->caps.color.mpc.ocsc = 1;
|
||||
|
||||
if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) {
|
||||
dc->debug = debug_defaults_drv;
|
||||
} else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
|
||||
|
|
|
@ -129,7 +129,7 @@ void dcn20_release_dsc(struct resource_context *res_ctx,
|
|||
const struct resource_pool *pool,
|
||||
struct display_stream_compressor **dsc);
|
||||
bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx);
|
||||
void dcn20_split_stream_for_mpc(
|
||||
bool dcn20_split_stream_for_mpc(
|
||||
struct resource_context *res_ctx,
|
||||
const struct resource_pool *pool,
|
||||
struct pipe_ctx *primary_pipe,
|
||||
|
|
|
@ -778,21 +778,28 @@ void dmcub_PLAT_54186_wa(struct hubp *hubp, struct surface_flip_registers *flip_
|
|||
{
|
||||
struct dc_dmub_srv *dmcub = hubp->ctx->dmub_srv;
|
||||
struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
|
||||
struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa = { 0 };
|
||||
union dmub_rb_cmd cmd;
|
||||
|
||||
PLAT_54186_wa.header.type = DMUB_CMD__PLAT_54186_WA;
|
||||
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS;
|
||||
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_C;
|
||||
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH;
|
||||
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C;
|
||||
PLAT_54186_wa.flip.flip_params.grph_stereo = flip_regs->grph_stereo;
|
||||
PLAT_54186_wa.flip.flip_params.hubp_inst = hubp->inst;
|
||||
PLAT_54186_wa.flip.flip_params.immediate = flip_regs->immediate;
|
||||
PLAT_54186_wa.flip.flip_params.tmz_surface = flip_regs->tmz_surface;
|
||||
PLAT_54186_wa.flip.flip_params.vmid = flip_regs->vmid;
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.PLAT_54186_wa.header.type = DMUB_CMD__PLAT_54186_WA;
|
||||
cmd.PLAT_54186_wa.header.payload_bytes = sizeof(cmd.PLAT_54186_wa.flip);
|
||||
cmd.PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS =
|
||||
flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS;
|
||||
cmd.PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C =
|
||||
flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_C;
|
||||
cmd.PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
|
||||
flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH;
|
||||
cmd.PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C =
|
||||
flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C;
|
||||
cmd.PLAT_54186_wa.flip.flip_params.grph_stereo = flip_regs->grph_stereo;
|
||||
cmd.PLAT_54186_wa.flip.flip_params.hubp_inst = hubp->inst;
|
||||
cmd.PLAT_54186_wa.flip.flip_params.immediate = flip_regs->immediate;
|
||||
cmd.PLAT_54186_wa.flip.flip_params.tmz_surface = flip_regs->tmz_surface;
|
||||
cmd.PLAT_54186_wa.flip.flip_params.vmid = flip_regs->vmid;
|
||||
|
||||
PERF_TRACE(); // TODO: remove after performance is stable.
|
||||
dc_dmub_srv_cmd_queue(dmcub, &PLAT_54186_wa.header);
|
||||
dc_dmub_srv_cmd_queue(dmcub, &cmd);
|
||||
PERF_TRACE(); // TODO: remove after performance is stable.
|
||||
dc_dmub_srv_cmd_execute(dmcub);
|
||||
PERF_TRACE(); // TODO: remove after performance is stable.
|
||||
|
|
|
@ -53,6 +53,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
|
|||
.disable_plane = dcn20_disable_plane,
|
||||
.pipe_control_lock = dcn20_pipe_control_lock,
|
||||
.interdependent_update_lock = dcn10_lock_all_pipes,
|
||||
.cursor_lock = dcn10_cursor_lock,
|
||||
.prepare_bandwidth = dcn20_prepare_bandwidth,
|
||||
.optimize_bandwidth = dcn20_optimize_bandwidth,
|
||||
.update_bandwidth = dcn20_update_bandwidth,
|
||||
|
@ -91,6 +92,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
|
|||
.optimize_pwr_state = dcn21_optimize_pwr_state,
|
||||
.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
|
||||
.power_down = dce110_power_down,
|
||||
.set_backlight_level = dce110_set_backlight_level,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn21_private_funcs = {
|
||||
|
|
|
@ -286,7 +286,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
|
|||
.dram_channel_width_bytes = 4,
|
||||
.fabric_datapath_to_dcn_data_return_bytes = 32,
|
||||
.dcn_downspread_percent = 0.5,
|
||||
.downspread_percent = 0.5,
|
||||
.downspread_percent = 0.38,
|
||||
.dram_page_open_time_ns = 50.0,
|
||||
.dram_rw_turnaround_time_ns = 17.5,
|
||||
.dram_return_buffer_per_channel_bytes = 8192,
|
||||
|
@ -342,6 +342,10 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
|
|||
.block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
|
||||
mm ## block ## id ## _ ## reg_name
|
||||
|
||||
#define VUPDATE_SRII(reg_name, block, id)\
|
||||
.reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
|
||||
mm ## reg_name ## _ ## block ## id
|
||||
|
||||
/* NBIO */
|
||||
#define NBIO_BASE_INNER(seg) \
|
||||
NBIF0_BASE__INST0_SEG ## seg
|
||||
|
@ -1379,64 +1383,49 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
|
|||
{
|
||||
struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
|
||||
struct clk_limit_table *clk_table = &bw_params->clk_table;
|
||||
unsigned int i, j, k;
|
||||
int closest_clk_lvl;
|
||||
struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
|
||||
unsigned int i, j, closest_clk_lvl;
|
||||
|
||||
// Default clock levels are used for diags, which may lead to overclocking.
|
||||
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) && !IS_DIAG_DC(dc->ctx->dce_environment)) {
|
||||
if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
|
||||
dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
|
||||
dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
|
||||
dcn2_1_soc.num_chans = bw_params->num_channels;
|
||||
|
||||
/* Vmin: leave lowest DCN clocks, override with dcfclk, fclk, memclk from fuse */
|
||||
dcn2_1_soc.clock_limits[0].state = 0;
|
||||
dcn2_1_soc.clock_limits[0].dcfclk_mhz = clk_table->entries[0].dcfclk_mhz;
|
||||
dcn2_1_soc.clock_limits[0].fabricclk_mhz = clk_table->entries[0].fclk_mhz;
|
||||
dcn2_1_soc.clock_limits[0].socclk_mhz = clk_table->entries[0].socclk_mhz;
|
||||
dcn2_1_soc.clock_limits[0].dram_speed_mts = clk_table->entries[0].memclk_mhz * 2;
|
||||
|
||||
/*
|
||||
* Other levels: find closest DCN clocks that fit the given clock limit using dcfclk
|
||||
* as indicator
|
||||
*/
|
||||
|
||||
closest_clk_lvl = -1;
|
||||
/* index currently being filled */
|
||||
k = 1;
|
||||
for (i = 1; i < clk_table->num_entries; i++) {
|
||||
/* loop backwards, skip duplicate state*/
|
||||
for (j = dcn2_1_soc.num_states - 1; j >= k; j--) {
|
||||
ASSERT(clk_table->num_entries);
|
||||
for (i = 0; i < clk_table->num_entries; i++) {
|
||||
/* loop backwards*/
|
||||
for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) {
|
||||
if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
|
||||
closest_clk_lvl = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if found a lvl that fits, use the DCN clks from it, if not, go to next clk limit*/
|
||||
if (closest_clk_lvl != -1) {
|
||||
dcn2_1_soc.clock_limits[k].state = i;
|
||||
dcn2_1_soc.clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].socclk_mhz = clk_table->entries[i].socclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
|
||||
clock_limits[i].state = i;
|
||||
clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
|
||||
clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
|
||||
clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
|
||||
clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
|
||||
|
||||
dcn2_1_soc.clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
|
||||
dcn2_1_soc.clock_limits[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
|
||||
dcn2_1_soc.clock_limits[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
|
||||
k++;
|
||||
}
|
||||
clock_limits[i].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
|
||||
clock_limits[i].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
|
||||
clock_limits[i].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
|
||||
clock_limits[i].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
|
||||
clock_limits[i].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
|
||||
clock_limits[i].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
|
||||
clock_limits[i].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
|
||||
}
|
||||
for (i = 0; i < clk_table->num_entries; i++)
|
||||
dcn2_1_soc.clock_limits[i] = clock_limits[i];
|
||||
if (clk_table->num_entries) {
|
||||
dcn2_1_soc.num_states = clk_table->num_entries;
|
||||
/* duplicate last level */
|
||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];
|
||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;
|
||||
}
|
||||
dcn2_1_soc.num_states = k;
|
||||
}
|
||||
|
||||
/* duplicate last level */
|
||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];
|
||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;
|
||||
|
||||
dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
|
||||
}
|
||||
|
||||
|
@ -1813,7 +1802,6 @@ static bool dcn21_resource_construct(
|
|||
dc->caps.i2c_speed_in_khz = 100;
|
||||
dc->caps.max_cursor_size = 256;
|
||||
dc->caps.dmdata_alloc_size = 2048;
|
||||
dc->caps.hw_3d_lut = true;
|
||||
|
||||
dc->caps.max_slave_planes = 1;
|
||||
dc->caps.post_blend_color_processing = true;
|
||||
|
@ -1822,6 +1810,40 @@ static bool dcn21_resource_construct(
|
|||
dc->caps.dmcub_support = true;
|
||||
dc->caps.is_apu = true;
|
||||
|
||||
/* Color pipeline capabilities */
|
||||
dc->caps.color.dpp.dcn_arch = 1;
|
||||
dc->caps.color.dpp.input_lut_shared = 0;
|
||||
dc->caps.color.dpp.icsc = 1;
|
||||
dc->caps.color.dpp.dgam_ram = 1;
|
||||
dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
|
||||
dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
|
||||
dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 0;
|
||||
dc->caps.color.dpp.dgam_rom_caps.pq = 0;
|
||||
dc->caps.color.dpp.dgam_rom_caps.hlg = 0;
|
||||
dc->caps.color.dpp.post_csc = 0;
|
||||
dc->caps.color.dpp.gamma_corr = 0;
|
||||
|
||||
dc->caps.color.dpp.hw_3d_lut = 1;
|
||||
dc->caps.color.dpp.ogam_ram = 1;
|
||||
// no OGAM ROM on DCN2
|
||||
dc->caps.color.dpp.ogam_rom_caps.srgb = 0;
|
||||
dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;
|
||||
dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
|
||||
dc->caps.color.dpp.ogam_rom_caps.pq = 0;
|
||||
dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
|
||||
dc->caps.color.dpp.ocsc = 0;
|
||||
|
||||
dc->caps.color.mpc.gamut_remap = 0;
|
||||
dc->caps.color.mpc.num_3dluts = 0;
|
||||
dc->caps.color.mpc.shared_3d_lut = 0;
|
||||
dc->caps.color.mpc.ogam_ram = 1;
|
||||
dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
|
||||
dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
|
||||
dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
|
||||
dc->caps.color.mpc.ogam_rom_caps.pq = 0;
|
||||
dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
|
||||
dc->caps.color.mpc.ocsc = 1;
|
||||
|
||||
if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
|
||||
dc->debug = debug_defaults_drv;
|
||||
else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
|
||||
|
|
|
@ -121,6 +121,7 @@ struct _vcs_dpi_soc_bounding_box_st {
|
|||
};
|
||||
|
||||
struct _vcs_dpi_ip_params_st {
|
||||
bool use_min_dcfclk;
|
||||
bool gpuvm_enable;
|
||||
bool hostvm_enable;
|
||||
unsigned int gpuvm_max_page_table_levels;
|
||||
|
|
|
@ -280,6 +280,7 @@ static void fetch_ip_params(struct display_mode_lib *mode_lib)
|
|||
ip_params_st *ip = &mode_lib->vba.ip;
|
||||
|
||||
// IP Parameters
|
||||
mode_lib->vba.UseMinimumRequiredDCFCLK = ip->use_min_dcfclk;
|
||||
mode_lib->vba.MaxNumDPP = ip->max_num_dpp;
|
||||
mode_lib->vba.MaxNumOTG = ip->max_num_otg;
|
||||
mode_lib->vba.MaxNumHDMIFRLOutputs = ip->max_num_hdmi_frl_outputs;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue