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:
Dave Airlie 2020-05-08 13:31:06 +10:00
commit 370fb6b0aa
117 changed files with 1536 additions and 636 deletions

View File

@ -189,6 +189,8 @@ extern int sched_policy;
static const int sched_policy = KFD_SCHED_POLICY_HWS; static const int sched_policy = KFD_SCHED_POLICY_HWS;
#endif #endif
extern int amdgpu_tmz;
#ifdef CONFIG_DRM_AMDGPU_SI #ifdef CONFIG_DRM_AMDGPU_SI
extern int amdgpu_si_support; extern int amdgpu_si_support;
#endif #endif
@ -202,8 +204,6 @@ extern int amdgpu_cik_support;
#define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000
#define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */ #define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */
#define AMDGPU_FENCE_JIFFIES_TIMEOUT (HZ / 2) #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 AMDGPU_DEBUGFS_MAX_COMPONENTS 32
#define AMDGPUFB_CONN_LIMIT 4 #define AMDGPUFB_CONN_LIMIT 4
#define AMDGPU_BIOS_NUM_SCRATCH 16 #define AMDGPU_BIOS_NUM_SCRATCH 16
@ -400,13 +400,6 @@ struct amdgpu_sa_bo {
int amdgpu_fence_slab_init(void); int amdgpu_fence_slab_init(void);
void amdgpu_fence_slab_fini(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. * IRQS.
*/ */
@ -864,7 +857,7 @@ struct amdgpu_device {
unsigned num_rings; unsigned num_rings;
struct amdgpu_ring *rings[AMDGPU_MAX_RINGS]; struct amdgpu_ring *rings[AMDGPU_MAX_RINGS];
bool ib_pool_ready; 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]; struct amdgpu_sched gpu_sched[AMDGPU_HW_IP_NUM][AMDGPU_RING_PRIO_MAX];
/* interrupts */ /* interrupts */
@ -945,7 +938,7 @@ struct amdgpu_device {
atomic64_t gart_pin_size; atomic64_t gart_pin_size;
/* soc15 register offset based on ip, instance and segment */ /* 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 */ /* delayed work_func for deferring clockgating during resume */
struct delayed_work delayed_init_work; 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) 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

View File

@ -564,6 +564,13 @@ uint32_t amdgpu_amdkfd_get_num_gws(struct kgd_dev *kgd)
return adev->gds.gws_size; 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, int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine,
uint32_t vmid, uint64_t gpu_addr, uint32_t vmid, uint64_t gpu_addr,
uint32_t *ib_cmd, uint32_t ib_len) uint32_t *ib_cmd, uint32_t ib_len)

View File

@ -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_unique_id(struct kgd_dev *kgd);
uint64_t amdgpu_amdkfd_get_mmio_remap_phys_addr(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_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); 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 /* Read user wptr from a specified user address space with page fault

View File

@ -40,7 +40,7 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size,
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
r = amdgpu_copy_buffer(ring, saddr, daddr, size, NULL, &fence, r = amdgpu_copy_buffer(ring, saddr, daddr, size, NULL, &fence,
false, false); false, false, false);
if (r) if (r)
goto exit_do_move; goto exit_do_move;
r = dma_fence_wait(fence, false); r = dma_fence_wait(fence, false);

View File

@ -924,7 +924,8 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
ring = to_amdgpu_ring(entity->rq->sched); ring = to_amdgpu_ring(entity->rq->sched);
r = amdgpu_ib_get(adev, vm, ring->funcs->parse_cs ? 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) { if (r) {
DRM_ERROR("Failed to get ib !\n"); DRM_ERROR("Failed to get ib !\n");
return r; return r;

View File

@ -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); adev->firmware.load_type = amdgpu_ucode_get_load_type(adev, amdgpu_fw_load_type);
amdgpu_gmc_tmz_set(adev);
return 0; 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); INIT_WORK(&adev->xgmi_reset_work, amdgpu_device_xgmi_reset_func);
adev->gfx.gfx_off_req_count = 1; 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 */ /* Registers mapping */
/* TODO: block userspace mapping of io register */ /* 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); amdgpu_ras_suspend(adev);
r = amdgpu_device_ip_suspend_phase1(adev); r = amdgpu_device_ip_suspend_phase1(adev);
amdgpu_amdkfd_suspend(adev, !fbcon);
/* evict vram memory */ /* evict vram memory */
amdgpu_bo_evict_vram(adev); amdgpu_bo_evict_vram(adev);

View File

@ -85,9 +85,10 @@
* - 3.34.0 - Non-DC can flip correctly between buffers with different pitches * - 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.35.0 - Add drm_amdgpu_info_device::tcc_disabled_mask
* - 3.36.0 - Allow reading more status registers on si/cik * - 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_MAJOR 3
#define KMS_DRIVER_MINOR 36 #define KMS_DRIVER_MINOR 37
#define KMS_DRIVER_PATCHLEVEL 0 #define KMS_DRIVER_PATCHLEVEL 0
int amdgpu_vram_limit = 0; int amdgpu_vram_limit = 0;
@ -144,6 +145,7 @@ int amdgpu_discovery = -1;
int amdgpu_mes = 0; int amdgpu_mes = 0;
int amdgpu_noretry; int amdgpu_noretry;
int amdgpu_force_asic_type = -1; int amdgpu_force_asic_type = -1;
int amdgpu_tmz = 0;
struct amdgpu_mgpu_info mgpu_info = { struct amdgpu_mgpu_info mgpu_info = {
.mutex = __MUTEX_INITIALIZER(mgpu_info.mutex), .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) * DOC: hws_gws_support(bool)
* Whether HWS support gws barriers. Default value: false (not supported) * Assume that HWS supports GWS barriers regardless of what firmware version
* This will be replaced with a MEC firmware version check once firmware * check says. Default value: false (rely on MEC2 firmware version check).
* is ready
*/ */
bool hws_gws_support; bool hws_gws_support;
module_param(hws_gws_support, bool, 0444); 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) * 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_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) ");
module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444); 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[] = { static const struct pci_device_id pciidlist[] = {
#ifdef CONFIG_DRM_AMDGPU_SI #ifdef CONFIG_DRM_AMDGPU_SI
{0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI}, {0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI},

View File

@ -192,14 +192,22 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f,
* Used For polling fence. * Used For polling fence.
* Returns 0 on success, -ENOMEM on failure. * 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; uint32_t seq;
signed long r;
if (!s) if (!s)
return -EINVAL; return -EINVAL;
seq = ++ring->fence_drv.sync_seq; 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, amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,
seq, 0); seq, 0);

View File

@ -234,7 +234,8 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
AMDGPU_GEM_CREATE_CPU_GTT_USWC | AMDGPU_GEM_CREATE_CPU_GTT_USWC |
AMDGPU_GEM_CREATE_VRAM_CLEARED | AMDGPU_GEM_CREATE_VRAM_CLEARED |
AMDGPU_GEM_CREATE_VM_ALWAYS_VALID | AMDGPU_GEM_CREATE_VM_ALWAYS_VALID |
AMDGPU_GEM_CREATE_EXPLICIT_SYNC)) AMDGPU_GEM_CREATE_EXPLICIT_SYNC |
AMDGPU_GEM_CREATE_ENCRYPTED))
return -EINVAL; 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) if (args->in.domains & ~AMDGPU_GEM_DOMAIN_MASK)
return -EINVAL; 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 */ /* create a gem object to contain this object in */
if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS | if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS |
AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) { AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {

View File

@ -675,13 +675,15 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg)
spin_lock_irqsave(&kiq->ring_lock, flags); spin_lock_irqsave(&kiq->ring_lock, flags);
if (amdgpu_device_wb_get(adev, &reg_val_offs)) { if (amdgpu_device_wb_get(adev, &reg_val_offs)) {
spin_unlock_irqrestore(&kiq->ring_lock, flags);
pr_err("critical bug! too many kiq readers\n"); pr_err("critical bug! too many kiq readers\n");
goto failed_kiq_read; goto failed_unlock;
} }
amdgpu_ring_alloc(ring, 32); amdgpu_ring_alloc(ring, 32);
amdgpu_ring_emit_rreg(ring, reg, reg_val_offs); 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); amdgpu_ring_commit(ring);
spin_unlock_irqrestore(&kiq->ring_lock, flags); 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); amdgpu_device_wb_free(adev, reg_val_offs);
return value; return value;
failed_undo:
amdgpu_ring_undo(ring);
failed_unlock:
spin_unlock_irqrestore(&kiq->ring_lock, flags);
failed_kiq_read: failed_kiq_read:
if (reg_val_offs)
amdgpu_device_wb_free(adev, reg_val_offs);
pr_err("failed to read reg:%x\n", reg); pr_err("failed to read reg:%x\n", reg);
return ~0; 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); spin_lock_irqsave(&kiq->ring_lock, flags);
amdgpu_ring_alloc(ring, 32); amdgpu_ring_alloc(ring, 32);
amdgpu_ring_emit_wreg(ring, reg, v); 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); amdgpu_ring_commit(ring);
spin_unlock_irqrestore(&kiq->ring_lock, flags); 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; return;
failed_undo:
amdgpu_ring_undo(ring);
spin_unlock_irqrestore(&kiq->ring_lock, flags);
failed_kiq_write: failed_kiq_write:
pr_err("failed to write reg:%x\n", reg); pr_err("failed to write reg:%x\n", reg);
} }

View File

@ -373,3 +373,38 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
return 0; 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;
}
}

View File

@ -213,6 +213,8 @@ struct amdgpu_gmc {
} fault_hash[AMDGPU_GMC_FAULT_HASH_SIZE]; } fault_hash[AMDGPU_GMC_FAULT_HASH_SIZE];
uint64_t last_fault:AMDGPU_GMC_FAULT_RING_ORDER; uint64_t last_fault:AMDGPU_GMC_FAULT_RING_ORDER;
bool tmz_enabled;
const struct amdgpu_gmc_funcs *gmc_funcs; const struct amdgpu_gmc_funcs *gmc_funcs;
struct amdgpu_xgmi xgmi; 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); void amdgpu_gmc_ras_fini(struct amdgpu_device *adev);
int amdgpu_gmc_allocate_vm_inv_eng(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 #endif

View File

@ -61,14 +61,13 @@
* Returns 0 on success, error on failure. * Returns 0 on success, error on failure.
*/ */
int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
unsigned size, unsigned size, enum amdgpu_ib_pool_type pool_type,
enum amdgpu_ib_pool_type pool_type, struct amdgpu_ib *ib)
struct amdgpu_ib *ib)
{ {
int r; int r;
if (size) { 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); &ib->sa_bo, size, 256);
if (r) { if (r) {
dev_err(adev->dev, "failed to get a new IB (%d)\n", 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; uint64_t fence_ctx;
uint32_t status = 0, alloc_size; uint32_t status = 0, alloc_size;
unsigned fence_flags = 0; unsigned fence_flags = 0;
bool secure;
unsigned i; unsigned i;
int r = 0; int r = 0;
@ -161,6 +161,12 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
return -EINVAL; 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 * alloc_size = ring->funcs->emit_frame_size + num_ibs *
ring->funcs->emit_ib_size; 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); 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) { for (i = 0; i < num_ibs; ++i) {
ib = &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 */ !amdgpu_sriov_vf(adev)) /* for SRIOV preemption, Preamble CE ib must be inserted anyway */
continue; 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); amdgpu_ring_emit_ib(ring, job, ib, status);
status &= ~AMDGPU_HAVE_CTX_SWITCH; status &= ~AMDGPU_HAVE_CTX_SWITCH;
} }
if (ring->funcs->emit_tmz) if (job && ring->funcs->emit_frame_cntl)
amdgpu_ring_emit_tmz(ring, false); amdgpu_ring_emit_frame_cntl(ring, false, secure);
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
if (!(adev->flags & AMD_IS_APU)) 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 amdgpu_ib_pool_init(struct amdgpu_device *adev)
{ {
int r, i;
unsigned size; unsigned size;
int r, i;
if (adev->ib_pool_ready) { if (adev->ib_pool_ready)
return 0; return 0;
}
for (i = 0; i < AMDGPU_IB_POOL_MAX; i++) { for (i = 0; i < AMDGPU_IB_POOL_MAX; i++) {
if (i == AMDGPU_IB_POOL_DIRECT) if (i == AMDGPU_IB_POOL_DIRECT)
size = PAGE_SIZE * 2; size = PAGE_SIZE * 2;
else else
size = AMDGPU_IB_POOL_SIZE*64*1024; size = AMDGPU_IB_POOL_SIZE;
r = amdgpu_sa_bo_manager_init(adev, &adev->ring_tmp_bo[i],
size, r = amdgpu_sa_bo_manager_init(adev, &adev->ib_pools[i],
AMDGPU_GPU_PAGE_SIZE, size, AMDGPU_GPU_PAGE_SIZE,
AMDGPU_GEM_DOMAIN_GTT); AMDGPU_GEM_DOMAIN_GTT);
if (r) { if (r)
for (i--; i >= 0; i--) goto error;
amdgpu_sa_bo_manager_fini(adev, &adev->ring_tmp_bo[i]);
return r;
}
} }
adev->ib_pool_ready = true; adev->ib_pool_ready = true;
return 0; 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; int i;
if (adev->ib_pool_ready) { if (!adev->ib_pool_ready)
for (i = 0; i < AMDGPU_IB_POOL_MAX; i++) return;
amdgpu_sa_bo_manager_fini(adev, &adev->ring_tmp_bo[i]);
adev->ib_pool_ready = false; 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) int amdgpu_ib_ring_tests(struct amdgpu_device *adev)
{ {
unsigned i;
int r, ret = 0;
long tmo_gfx, tmo_mm; long tmo_gfx, tmo_mm;
int r, ret = 0;
unsigned i;
tmo_mm = tmo_gfx = AMDGPU_IB_TEST_TIMEOUT; tmo_mm = tmo_gfx = AMDGPU_IB_TEST_TIMEOUT;
if (amdgpu_sriov_vf(adev)) { 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 drm_device *dev = node->minor->dev;
struct amdgpu_device *adev = dev->dev_private; struct amdgpu_device *adev = dev->dev_private;
seq_printf(m, "-------------------- NORMAL -------------------- \n"); seq_printf(m, "--------------------- DELAYED --------------------- \n");
amdgpu_sa_bo_dump_debug_info(&adev->ring_tmp_bo[AMDGPU_IB_POOL_NORMAL], m); amdgpu_sa_bo_dump_debug_info(&adev->ib_pools[AMDGPU_IB_POOL_DELAYED],
seq_printf(m, "---------------------- VM ---------------------- \n"); m);
amdgpu_sa_bo_dump_debug_info(&adev->ring_tmp_bo[AMDGPU_IB_POOL_VM], m); seq_printf(m, "-------------------- IMMEDIATE -------------------- \n");
seq_printf(m, "-------------------- DIRECT--------------------- \n"); amdgpu_sa_bo_dump_debug_info(&adev->ib_pools[AMDGPU_IB_POOL_IMMEDIATE],
amdgpu_sa_bo_dump_debug_info(&adev->ring_tmp_bo[AMDGPU_IB_POOL_DIRECT], m); m);
seq_printf(m, "--------------------- DIRECT ---------------------- \n");
amdgpu_sa_bo_dump_debug_info(&adev->ib_pools[AMDGPU_IB_POOL_DIRECT], m);
return 0; return 0;
} }
static const struct drm_info_list amdgpu_debugfs_sa_list[] = { static const struct drm_info_list amdgpu_debugfs_sa_list[] = {

View File

@ -282,7 +282,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
!dma_fence_is_later(updates, (*id)->flushed_updates)) !dma_fence_is_later(updates, (*id)->flushed_updates))
updates = NULL; updates = NULL;
if ((*id)->owner != vm->direct.fence_context || if ((*id)->owner != vm->immediate.fence_context ||
job->vm_pd_addr != (*id)->pd_gpu_addr || job->vm_pd_addr != (*id)->pd_gpu_addr ||
updates || !(*id)->last_flush || updates || !(*id)->last_flush ||
((*id)->last_flush->context != fence_context && ((*id)->last_flush->context != fence_context &&
@ -349,7 +349,7 @@ static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
struct dma_fence *flushed; struct dma_fence *flushed;
/* Check all the prerequisites to using this VMID */ /* Check all the prerequisites to using this VMID */
if ((*id)->owner != vm->direct.fence_context) if ((*id)->owner != vm->immediate.fence_context)
continue; continue;
if ((*id)->pd_gpu_addr != job->vm_pd_addr) 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->pd_gpu_addr = job->vm_pd_addr;
id->owner = vm->direct.fence_context; id->owner = vm->immediate.fence_context;
if (job->vm_needs_flush) { if (job->vm_needs_flush) {
dma_fence_put(id->last_flush); dma_fence_put(id->last_flush);

View File

@ -62,7 +62,6 @@ struct amdgpu_job {
/* user fence handling */ /* user fence handling */
uint64_t uf_addr; uint64_t uf_addr;
uint64_t uf_sequence; uint64_t uf_sequence;
}; };
int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,

View File

@ -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, return amdgpu_copy_buffer(ring, shadow_addr, parent_addr,
amdgpu_bo_size(shadow), NULL, fence, amdgpu_bo_size(shadow), NULL, fence,
true, false); true, false, false);
} }
/** /**

View File

@ -229,6 +229,17 @@ static inline bool amdgpu_bo_explicit_sync(struct amdgpu_bo *bo)
return bo->flags & AMDGPU_GEM_CREATE_EXPLICIT_SYNC; 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); bool amdgpu_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);
void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain); void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain);

View File

@ -3271,26 +3271,27 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
return ret; return ret;
} }
if (!amdgpu_sriov_vf(adev)) {
ret = device_create_file(adev->dev, &dev_attr_pp_num_states); ret = device_create_file(adev->dev, &dev_attr_pp_num_states);
if (ret) { if (ret) {
DRM_ERROR("failed to create device file pp_num_states\n"); DRM_ERROR("failed to create device file pp_num_states\n");
return ret; return ret;
} }
ret = device_create_file(adev->dev, &dev_attr_pp_cur_state); ret = device_create_file(adev->dev, &dev_attr_pp_cur_state);
if (ret) { if (ret) {
DRM_ERROR("failed to create device file pp_cur_state\n"); DRM_ERROR("failed to create device file pp_cur_state\n");
return ret; return ret;
} }
ret = device_create_file(adev->dev, &dev_attr_pp_force_state); ret = device_create_file(adev->dev, &dev_attr_pp_force_state);
if (ret) { if (ret) {
DRM_ERROR("failed to create device file pp_force_state\n"); DRM_ERROR("failed to create device file pp_force_state\n");
return ret; return ret;
} }
ret = device_create_file(adev->dev, &dev_attr_pp_table); ret = device_create_file(adev->dev, &dev_attr_pp_table);
if (ret) { if (ret) {
DRM_ERROR("failed to create device file pp_table\n"); DRM_ERROR("failed to create device file pp_table\n");
return ret; return ret;
}
} }
ret = device_create_file(adev->dev, &dev_attr_pp_dpm_sclk); 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; 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) { if (adev->asic_type != CHIP_ARCTURUS) {
ret = device_create_file(adev->dev, &dev_attr_pp_dpm_pcie); ret = device_create_file(adev->dev, &dev_attr_pp_dpm_pcie);
if (ret) { if (ret) {

View File

@ -50,6 +50,8 @@
#define to_amdgpu_ring(s) container_of((s), struct amdgpu_ring, sched) #define to_amdgpu_ring(s) container_of((s), struct amdgpu_ring, sched)
#define AMDGPU_IB_POOL_SIZE (1024 * 1024)
enum amdgpu_ring_type { enum amdgpu_ring_type {
AMDGPU_RING_TYPE_GFX = AMDGPU_HW_IP_GFX, AMDGPU_RING_TYPE_GFX = AMDGPU_HW_IP_GFX,
AMDGPU_RING_TYPE_COMPUTE = AMDGPU_HW_IP_COMPUTE, AMDGPU_RING_TYPE_COMPUTE = AMDGPU_HW_IP_COMPUTE,
@ -63,6 +65,17 @@ enum amdgpu_ring_type {
AMDGPU_RING_TYPE_KIQ 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_device;
struct amdgpu_ring; struct amdgpu_ring;
struct amdgpu_ib; 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); void amdgpu_fence_driver_resume(struct amdgpu_device *adev);
int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **fence, int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **fence,
unsigned flags); 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); bool amdgpu_fence_process(struct amdgpu_ring *ring);
int amdgpu_fence_wait_empty(struct amdgpu_ring *ring); int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);
signed long amdgpu_fence_wait_polling(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, void (*emit_reg_write_reg_wait)(struct amdgpu_ring *ring,
uint32_t reg0, uint32_t reg1, uint32_t reg0, uint32_t reg1,
uint32_t ref, uint32_t mask); 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 */ /* Try to soft recover the ring to make the fence signal */
void (*soft_recovery)(struct amdgpu_ring *ring, unsigned vmid); void (*soft_recovery)(struct amdgpu_ring *ring, unsigned vmid);
int (*preempt_ib)(struct amdgpu_ring *ring); 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_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_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_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_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_init_cond_exec(r) (r)->funcs->init_cond_exec((r))
#define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o)) #define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o))

View File

@ -89,7 +89,8 @@ struct amdgpu_buffer_funcs {
/* dst addr in bytes */ /* dst addr in bytes */
uint64_t dst_offset, uint64_t dst_offset,
/* number of byte to transfer */ /* number of byte to transfer */
uint32_t byte_count); uint32_t byte_count,
bool tmz);
/* maximum bytes in a single operation */ /* maximum bytes in a single operation */
uint32_t fill_max_bytes; uint32_t fill_max_bytes;
@ -107,7 +108,7 @@ struct amdgpu_buffer_funcs {
uint32_t byte_count); 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)) #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 * struct amdgpu_sdma_instance *

View File

@ -249,6 +249,11 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync,
owner != AMDGPU_FENCE_OWNER_UNDEFINED) owner != AMDGPU_FENCE_OWNER_UNDEFINED)
continue; 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 */ /* Ignore fences depending on the sync mode */
switch (mode) { switch (mode) {
case AMDGPU_SYNC_ALWAYS: case AMDGPU_SYNC_ALWAYS:

View File

@ -44,7 +44,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
/* Number of tests = /* Number of tests =
* (Total GTT - IB pool - writeback page - ring buffers) / test size * (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) for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
if (adev->rings[i]) if (adev->rings[i])
n -= adev->rings[i]->ring_size; 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]); amdgpu_bo_kunmap(gtt_obj[i]);
r = amdgpu_copy_buffer(ring, gart_addr, vram_addr, r = amdgpu_copy_buffer(ring, gart_addr, vram_addr,
size, NULL, &fence, false, false); size, NULL, &fence, false, false, false);
if (r) { if (r) {
DRM_ERROR("Failed GTT->VRAM copy %d\n", i); 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); amdgpu_bo_kunmap(vram_obj);
r = amdgpu_copy_buffer(ring, vram_addr, gart_addr, r = amdgpu_copy_buffer(ring, vram_addr, gart_addr,
size, NULL, &fence, false, false); size, NULL, &fence, false, false, false);
if (r) { if (r) {
DRM_ERROR("Failed VRAM->GTT copy %d\n", i); DRM_ERROR("Failed VRAM->GTT copy %d\n", i);

View File

@ -62,11 +62,6 @@
#define AMDGPU_TTM_VRAM_MAX_DW_READ (size_t)128 #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 * 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, 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; 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; 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 * 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 * 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 * {dst->mem + dst->offset}. src->bo and dst->bo could be same BO for a
* move and different for a BO to BO copy. * 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, int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
struct amdgpu_copy_mem *src, const struct amdgpu_copy_mem *src,
struct amdgpu_copy_mem *dst, const struct amdgpu_copy_mem *dst,
uint64_t size, uint64_t size, bool tmz,
struct dma_resv *resv, struct dma_resv *resv,
struct dma_fence **f) 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 amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
struct drm_mm_node *src_mm, *dst_mm; 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; struct dma_fence *fence = NULL;
int r = 0; int r = 0;
const uint64_t GTT_MAX_BYTES = (AMDGPU_GTT_MAX_TRANSFER_SIZE *
AMDGPU_GPU_PAGE_SIZE);
if (!adev->mman.buffer_funcs_enabled) { if (!adev->mman.buffer_funcs_enabled) {
DRM_ERROR("Trying to move memory with ring turned off.\n"); DRM_ERROR("Trying to move memory with ring turned off.\n");
return -EINVAL; return -EINVAL;
} }
src_mm = amdgpu_find_mm_node(src->mem, &src->offset); src_offset = src->offset;
src_node_start = amdgpu_mm_node_addr(src->bo, src_mm, src->mem) + src_mm = amdgpu_find_mm_node(src->mem, &src_offset);
src->offset; src_node_size = (src_mm->size << PAGE_SHIFT) - src_offset;
src_node_size = (src_mm->size << PAGE_SHIFT) - src->offset;
src_page_offset = src_node_start & (PAGE_SIZE - 1);
dst_mm = amdgpu_find_mm_node(dst->mem, &dst->offset); dst_offset = dst->offset;
dst_node_start = amdgpu_mm_node_addr(dst->bo, dst_mm, dst->mem) + dst_mm = amdgpu_find_mm_node(dst->mem, &dst_offset);
dst->offset; dst_node_size = (dst_mm->size << PAGE_SHIFT) - dst_offset;
dst_node_size = (dst_mm->size << PAGE_SHIFT) - dst->offset;
dst_page_offset = dst_node_start & (PAGE_SIZE - 1);
mutex_lock(&adev->mman.gtt_window_lock); mutex_lock(&adev->mman.gtt_window_lock);
while (size) { while (size) {
unsigned long cur_size; uint32_t src_page_offset = src_offset & ~PAGE_MASK;
uint64_t from = src_node_start, to = dst_node_start; uint32_t dst_page_offset = dst_offset & ~PAGE_MASK;
struct dma_fence *next; struct dma_fence *next;
uint32_t cur_size;
uint64_t from, to;
/* Copy size cannot exceed GTT_MAX_BYTES. So if src or dst /* Copy size cannot exceed GTT_MAX_BYTES. So if src or dst
* begins at an offset, then adjust the size accordingly * begins at an offset, then adjust the size accordingly
*/ */
cur_size = min3(min(src_node_size, dst_node_size), size, cur_size = max(src_page_offset, dst_page_offset);
GTT_MAX_BYTES); cur_size = min(min3(src_node_size, dst_node_size, size),
if (cur_size + src_page_offset > GTT_MAX_BYTES || (uint64_t)(GTT_MAX_BYTES - cur_size));
cur_size + dst_page_offset > GTT_MAX_BYTES)
cur_size -= max(src_page_offset, dst_page_offset);
/* Map only what needs to be accessed. Map src to window 0 and /* Map src to window 0 and dst to window 1. */
* dst to window 1 r = amdgpu_ttm_map_buffer(src->bo, src->mem, src_mm,
*/ PFN_UP(cur_size + src_page_offset),
if (src->mem->start == AMDGPU_BO_INVALID_OFFSET) { src_offset, 0, ring, tmz, &from);
r = amdgpu_map_buffer(src->bo, src->mem, if (r)
PFN_UP(cur_size + src_page_offset), goto error;
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;
}
if (dst->mem->start == AMDGPU_BO_INVALID_OFFSET) { r = amdgpu_ttm_map_buffer(dst->bo, dst->mem, dst_mm,
r = amdgpu_map_buffer(dst->bo, dst->mem, PFN_UP(cur_size + dst_page_offset),
PFN_UP(cur_size + dst_page_offset), dst_offset, 1, ring, tmz, &to);
dst_node_start, 1, ring, if (r)
&to); goto error;
if (r)
goto error;
to += dst_page_offset;
}
r = amdgpu_copy_buffer(ring, from, to, cur_size, r = amdgpu_copy_buffer(ring, from, to, cur_size,
resv, &next, false, true); resv, &next, false, true, tmz);
if (r) if (r)
goto error; goto error;
@ -386,23 +481,20 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
src_node_size -= cur_size; src_node_size -= cur_size;
if (!src_node_size) { if (!src_node_size) {
src_node_start = amdgpu_mm_node_addr(src->bo, ++src_mm, ++src_mm;
src->mem); src_node_size = src_mm->size << PAGE_SHIFT;
src_node_size = (src_mm->size << PAGE_SHIFT); src_offset = 0;
src_page_offset = 0;
} else { } else {
src_node_start += cur_size; src_offset += cur_size;
src_page_offset = src_node_start & (PAGE_SIZE - 1);
} }
dst_node_size -= cur_size; dst_node_size -= cur_size;
if (!dst_node_size) { if (!dst_node_size) {
dst_node_start = amdgpu_mm_node_addr(dst->bo, ++dst_mm, ++dst_mm;
dst->mem); dst_node_size = dst_mm->size << PAGE_SHIFT;
dst_node_size = (dst_mm->size << PAGE_SHIFT); dst_offset = 0;
dst_page_offset = 0;
} else { } else {
dst_node_start += cur_size; dst_offset += cur_size;
dst_page_offset = dst_node_start & (PAGE_SIZE - 1);
} }
} }
error: error:
@ -425,6 +517,7 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
struct ttm_mem_reg *old_mem) struct ttm_mem_reg *old_mem)
{ {
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); 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 amdgpu_copy_mem src, dst;
struct dma_fence *fence = NULL; struct dma_fence *fence = NULL;
int r; 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, r = amdgpu_ttm_copy_mem_to_mem(adev, &src, &dst,
new_mem->num_pages << PAGE_SHIFT, new_mem->num_pages << PAGE_SHIFT,
amdgpu_bo_encrypted(abo),
bo->base.resv, &fence); bo->base.resv, &fence);
if (r) if (r)
goto error; goto error;
/* clear the space being freed */ /* clear the space being freed */
if (old_mem->mem_type == TTM_PL_VRAM && if (old_mem->mem_type == TTM_PL_VRAM &&
(ttm_to_amdgpu_bo(bo)->flags & (abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
struct dma_fence *wipe_fence = NULL; struct dma_fence *wipe_fence = NULL;
r = amdgpu_fill_buffer(ttm_to_amdgpu_bo(bo), AMDGPU_POISON, 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, static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
unsigned long page_offset) unsigned long page_offset)
{ {
uint64_t offset = (page_offset << PAGE_SHIFT);
struct drm_mm_node *mm; struct drm_mm_node *mm;
unsigned long offset = (page_offset << PAGE_SHIFT);
mm = amdgpu_find_mm_node(&bo->mem, &offset); mm = amdgpu_find_mm_node(&bo->mem, &offset);
return (bo->mem.bus.base >> PAGE_SHIFT) + mm->start + 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; struct amdgpu_ttm_tt *gtt = (void *)ttm;
int r; int r;
if (amdgpu_bo_encrypted(abo))
flags |= AMDGPU_PTE_TMZ;
if (abo->flags & AMDGPU_GEM_CREATE_CP_MQD_GFX9) { if (abo->flags & AMDGPU_GEM_CREATE_CP_MQD_GFX9) {
uint64_t page_idx = 1; 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) { switch (bo->mem.mem_type) {
case TTM_PL_TT: case TTM_PL_TT:
if (amdgpu_bo_is_amdgpu_bo(bo) &&
amdgpu_bo_encrypted(ttm_to_amdgpu_bo(bo)))
return false;
return true; return true;
case TTM_PL_VRAM: 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) if (bo->mem.mem_type != TTM_PL_VRAM)
return -EIO; return -EIO;
nodes = amdgpu_find_mm_node(&abo->tbo.mem, &offset); pos = offset;
pos = (nodes->start << PAGE_SHIFT) + offset; nodes = amdgpu_find_mm_node(&abo->tbo.mem, &pos);
pos += (nodes->start << PAGE_SHIFT);
while (len && pos < adev->gmc.mc_vram_size) { while (len && pos < adev->gmc.mc_vram_size) {
uint64_t aligned_pos = pos & ~(uint64_t)3; 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); 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 = &gtt->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, int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
uint64_t dst_offset, uint32_t byte_count, uint64_t dst_offset, uint32_t byte_count,
struct dma_resv *resv, struct dma_resv *resv,
struct dma_fence **fence, bool direct_submit, 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_device *adev = ring->adev;
struct amdgpu_job *job; 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_loops = DIV_ROUND_UP(byte_count, max_bytes);
num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->copy_num_dw, 8); num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->copy_num_dw, 8);
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, pool, &job);
direct_submit ? AMDGPU_IB_POOL_DIRECT : AMDGPU_IB_POOL_NORMAL, &job);
if (r) if (r)
return 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); uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_offset, 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; src_offset += cur_size_in_bytes;
dst_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 */ /* for IB padding */
num_dw += 64; 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) if (r)
return r; return r;

View File

@ -97,11 +97,11 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
uint64_t dst_offset, uint32_t byte_count, uint64_t dst_offset, uint32_t byte_count,
struct dma_resv *resv, struct dma_resv *resv,
struct dma_fence **fence, bool direct_submit, 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, int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
struct amdgpu_copy_mem *src, const struct amdgpu_copy_mem *src,
struct amdgpu_copy_mem *dst, const struct amdgpu_copy_mem *dst,
uint64_t size, uint64_t size, bool tmz,
struct dma_resv *resv, struct dma_resv *resv,
struct dma_fence **f); struct dma_fence **f);
int amdgpu_fill_buffer(struct amdgpu_bo *bo, int amdgpu_fill_buffer(struct amdgpu_bo *bo,

View File

@ -1056,8 +1056,8 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
goto err; goto err;
} }
r = amdgpu_job_alloc_with_ib(adev, 64, r = amdgpu_job_alloc_with_ib(adev, 64, direct ? AMDGPU_IB_POOL_DIRECT :
direct ? AMDGPU_IB_POOL_DIRECT : AMDGPU_IB_POOL_NORMAL, &job); AMDGPU_IB_POOL_DELAYED, &job);
if (r) if (r)
goto err; goto err;

View File

@ -447,7 +447,7 @@ static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
int i, r; int i, r;
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
AMDGPU_IB_POOL_DIRECT, &job); AMDGPU_IB_POOL_DIRECT, &job);
if (r) if (r)
return r; return r;
@ -526,7 +526,8 @@ static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
int i, r; int i, r;
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, 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) if (r)
return r; return r;

View File

@ -60,7 +60,10 @@ void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
amdgpu_ring_alloc(ring, 32); amdgpu_ring_alloc(ring, 32);
amdgpu_ring_emit_reg_write_reg_wait(ring, reg0, reg1, amdgpu_ring_emit_reg_write_reg_wait(ring, reg0, reg1,
ref, mask); 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); amdgpu_ring_commit(ring);
spin_unlock_irqrestore(&kiq->ring_lock, flags); spin_unlock_irqrestore(&kiq->ring_lock, flags);
@ -82,6 +85,9 @@ void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
return; return;
failed_undo:
amdgpu_ring_undo(ring);
spin_unlock_irqrestore(&kiq->ring_lock, flags);
failed_kiq: failed_kiq:
pr_err("failed to write reg %x wait reg %x\n", reg0, reg1); pr_err("failed to write reg %x wait reg %x\n", reg0, reg1);
} }

View File

@ -726,7 +726,7 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
* @adev: amdgpu_device pointer * @adev: amdgpu_device pointer
* @vm: VM to clear BO from * @vm: VM to clear BO from
* @bo: BO to clear * @bo: BO to clear
* @direct: use a direct update * @immediate: use an immediate update
* *
* Root PD needs to be reserved when calling this. * 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, static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
struct amdgpu_vm *vm, struct amdgpu_vm *vm,
struct amdgpu_bo *bo, struct amdgpu_bo *bo,
bool direct) bool immediate)
{ {
struct ttm_operation_ctx ctx = { true, false }; struct ttm_operation_ctx ctx = { true, false };
unsigned level = adev->vm_manager.root_level; unsigned level = adev->vm_manager.root_level;
@ -795,7 +795,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
params.adev = adev; params.adev = adev;
params.vm = vm; params.vm = vm;
params.direct = direct; params.immediate = immediate;
r = vm->update_funcs->prepare(&params, NULL, AMDGPU_SYNC_EXPLICIT); r = vm->update_funcs->prepare(&params, NULL, AMDGPU_SYNC_EXPLICIT);
if (r) if (r)
@ -850,11 +850,11 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
* @adev: amdgpu_device pointer * @adev: amdgpu_device pointer
* @vm: requesting vm * @vm: requesting vm
* @level: the page table level * @level: the page table level
* @direct: use a direct update * @immediate: use a immediate update
* @bp: resulting BO allocation parameters * @bp: resulting BO allocation parameters
*/ */
static void amdgpu_vm_bo_param(struct amdgpu_device *adev, struct amdgpu_vm *vm, 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) struct amdgpu_bo_param *bp)
{ {
memset(bp, 0, sizeof(*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) else if (!vm->root.base.bo || vm->root.base.bo->shadow)
bp->flags |= AMDGPU_GEM_CREATE_SHADOW; bp->flags |= AMDGPU_GEM_CREATE_SHADOW;
bp->type = ttm_bo_type_kernel; bp->type = ttm_bo_type_kernel;
bp->no_wait_gpu = direct; bp->no_wait_gpu = immediate;
if (vm->root.base.bo) if (vm->root.base.bo)
bp->resv = vm->root.base.bo->tbo.base.resv; 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 * @adev: amdgpu_device pointer
* @vm: VM to allocate page tables for * @vm: VM to allocate page tables for
* @cursor: Which page table to allocate * @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. * 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, static int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
struct amdgpu_vm *vm, struct amdgpu_vm *vm,
struct amdgpu_vm_pt_cursor *cursor, struct amdgpu_vm_pt_cursor *cursor,
bool direct) bool immediate)
{ {
struct amdgpu_vm_pt *entry = cursor->entry; struct amdgpu_vm_pt *entry = cursor->entry;
struct amdgpu_bo_param bp; struct amdgpu_bo_param bp;
@ -913,7 +913,7 @@ static int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
if (entry->base.bo) if (entry->base.bo)
return 0; 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); r = amdgpu_bo_create(adev, &bp, &pt);
if (r) 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); pt->parent = amdgpu_bo_ref(cursor->parent->base.bo);
amdgpu_vm_bo_base_init(&entry->base, vm, pt); 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) if (r)
goto error_free_pt; goto error_free_pt;
@ -1276,7 +1276,7 @@ static void amdgpu_vm_invalidate_pds(struct amdgpu_device *adev,
* *
* @adev: amdgpu_device pointer * @adev: amdgpu_device pointer
* @vm: requested vm * @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. * 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. * 0 for success, error for failure.
*/ */
int amdgpu_vm_update_pdes(struct amdgpu_device *adev, 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; struct amdgpu_vm_update_params params;
int r; int r;
@ -1295,7 +1295,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
params.adev = adev; params.adev = adev;
params.vm = vm; params.vm = vm;
params.direct = direct; params.immediate = immediate;
r = vm->update_funcs->prepare(&params, NULL, AMDGPU_SYNC_EXPLICIT); r = vm->update_funcs->prepare(&params, NULL, AMDGPU_SYNC_EXPLICIT);
if (r) 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; uint64_t incr, entry_end, pe_start;
struct amdgpu_bo *pt; struct amdgpu_bo *pt;
if (flags & (AMDGPU_PTE_VALID | AMDGPU_PTE_PRT)) { if (!params->unlocked) {
/* make sure that the page tables covering the /* make sure that the page tables covering the
* address range are actually allocated * address range are actually allocated
*/ */
r = amdgpu_vm_alloc_pts(params->adev, params->vm, r = amdgpu_vm_alloc_pts(params->adev, params->vm,
&cursor, params->direct); &cursor, params->immediate);
if (r) if (r)
return r; return r;
} }
shift = amdgpu_vm_level_shift(adev, cursor.level); shift = amdgpu_vm_level_shift(adev, cursor.level);
parent_shift = amdgpu_vm_level_shift(adev, cursor.level - 1); parent_shift = amdgpu_vm_level_shift(adev, cursor.level - 1);
if (adev->asic_type < CHIP_VEGA10 && if (params->unlocked) {
(flags & AMDGPU_PTE_VALID)) { /* 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 */ /* No huge page support before GMC v9 */
if (cursor.level != AMDGPU_VM_PTB) { if (cursor.level != AMDGPU_VM_PTB) {
if (!amdgpu_vm_pt_descendant(adev, &cursor)) 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 * @adev: amdgpu_device pointer
* @vm: requested vm * @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 * @resv: fences we need to sync to
* @start: start of mapped range * @start: start of mapped range
* @last: last mapped entry * @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. * 0 for success, -EINVAL for failure.
*/ */
static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
struct amdgpu_vm *vm, bool direct, struct amdgpu_vm *vm, bool immediate,
struct dma_resv *resv, bool unlocked, struct dma_resv *resv,
uint64_t start, uint64_t last, uint64_t start, uint64_t last,
uint64_t flags, uint64_t addr, uint64_t flags, uint64_t addr,
dma_addr_t *pages_addr, dma_addr_t *pages_addr,
@ -1586,8 +1591,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
params.adev = adev; params.adev = adev;
params.vm = vm; params.vm = vm;
params.direct = direct; params.immediate = immediate;
params.pages_addr = pages_addr; params.pages_addr = pages_addr;
params.unlocked = unlocked;
/* Implicitly sync to command submissions in the same VM before /* Implicitly sync to command submissions in the same VM before
* unmapping. Sync to moving fences before mapping. * 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; goto error_unlock;
} }
if (flags & (AMDGPU_PTE_VALID | AMDGPU_PTE_PRT)) { if (!unlocked && !dma_fence_is_signaled(vm->last_unlocked)) {
struct amdgpu_bo *root = vm->root.base.bo; struct dma_fence *tmp = dma_fence_get_stub();
if (!dma_fence_is_signaled(vm->last_direct)) amdgpu_bo_fence(vm->root.base.bo, vm->last_unlocked, true);
amdgpu_bo_fence(root, vm->last_direct, true); swap(vm->last_unlocked, tmp);
dma_fence_put(tmp);
} }
r = vm->update_funcs->prepare(&params, resv, sync_mode); r = vm->update_funcs->prepare(&params, 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); 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, start, last, flags, addr,
dma_addr, fence); dma_addr, fence);
if (r) if (r)
@ -1784,6 +1791,10 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
if (bo) { if (bo) {
flags = amdgpu_ttm_tt_pte_flags(adev, bo->tbo.ttm, mem); 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); bo_adev = amdgpu_ttm_adev(bo->tbo.bdev);
} else { } else {
flags = 0x0; flags = 0x0;
@ -2014,7 +2025,7 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
mapping->start < AMDGPU_GMC_HOLE_START) mapping->start < AMDGPU_GMC_HOLE_START)
init_pte_value = AMDGPU_PTE_DEFAULT_ATC; 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, mapping->start, mapping->last,
init_pte_value, 0, NULL, &f); init_pte_value, 0, NULL, &f);
amdgpu_vm_free_mapping(adev, vm, mapping, f); amdgpu_vm_free_mapping(adev, vm, mapping, f);
@ -2578,7 +2589,7 @@ bool amdgpu_vm_evictable(struct amdgpu_bo *bo)
return false; return false;
/* Don't evict VM page tables while they are updated */ /* 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); amdgpu_vm_eviction_unlock(bo_base->vm);
return false; return false;
} }
@ -2755,7 +2766,7 @@ long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout)
if (timeout <= 0) if (timeout <= 0)
return timeout; 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 */ /* 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_scheds,
adev->vm_manager.vm_pte_num_scheds, NULL); adev->vm_manager.vm_pte_num_scheds, NULL);
if (r) 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_scheds,
adev->vm_manager.vm_pte_num_scheds, NULL); adev->vm_manager.vm_pte_num_scheds, NULL);
if (r) if (r)
goto error_free_direct; goto error_free_immediate;
vm->pte_support_ats = false; vm->pte_support_ats = false;
vm->is_compute_context = false; vm->is_compute_context = false;
@ -2827,7 +2838,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
else else
vm->update_funcs = &amdgpu_vm_sdma_funcs; vm->update_funcs = &amdgpu_vm_sdma_funcs;
vm->last_update = NULL; vm->last_update = NULL;
vm->last_direct = dma_fence_get_stub(); vm->last_unlocked = dma_fence_get_stub();
mutex_init(&vm->eviction_lock); mutex_init(&vm->eviction_lock);
vm->evicting = false; vm->evicting = false;
@ -2881,11 +2892,11 @@ error_free_root:
vm->root.base.bo = NULL; vm->root.base.bo = NULL;
error_free_delayed: error_free_delayed:
dma_fence_put(vm->last_direct); dma_fence_put(vm->last_unlocked);
drm_sched_entity_destroy(&vm->delayed); drm_sched_entity_destroy(&vm->delayed);
error_free_direct: error_free_immediate:
drm_sched_entity_destroy(&vm->direct); drm_sched_entity_destroy(&vm->immediate);
return r; return r;
} }
@ -3082,8 +3093,8 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
vm->pasid = 0; vm->pasid = 0;
} }
dma_fence_wait(vm->last_direct, false); dma_fence_wait(vm->last_unlocked, false);
dma_fence_put(vm->last_direct); dma_fence_put(vm->last_unlocked);
list_for_each_entry_safe(mapping, tmp, &vm->freed, list) { list_for_each_entry_safe(mapping, tmp, &vm->freed, list) {
if (mapping->flags & AMDGPU_PTE_PRT && prt_fini_needed) { 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); amdgpu_bo_unref(&root);
WARN_ON(vm->root.base.bo); WARN_ON(vm->root.base.bo);
drm_sched_entity_destroy(&vm->direct); drm_sched_entity_destroy(&vm->immediate);
drm_sched_entity_destroy(&vm->delayed); drm_sched_entity_destroy(&vm->delayed);
if (!RB_EMPTY_ROOT(&vm->va.rb_root)) { 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; value = 0;
} }
r = amdgpu_vm_bo_update_mapping(adev, vm, true, NULL, addr, addr + 1, r = amdgpu_vm_bo_update_mapping(adev, vm, true, false, NULL, addr,
flags, value, NULL, NULL); addr + 1, flags, value, NULL, NULL);
if (r) if (r)
goto error_unlock; goto error_unlock;

View File

@ -54,6 +54,9 @@ struct amdgpu_bo_list_entry;
#define AMDGPU_PTE_SYSTEM (1ULL << 1) #define AMDGPU_PTE_SYSTEM (1ULL << 1)
#define AMDGPU_PTE_SNOOPED (1ULL << 2) #define AMDGPU_PTE_SNOOPED (1ULL << 2)
/* RV+ */
#define AMDGPU_PTE_TMZ (1ULL << 3)
/* VI only */ /* VI only */
#define AMDGPU_PTE_EXECUTABLE (1ULL << 4) #define AMDGPU_PTE_EXECUTABLE (1ULL << 4)
@ -203,9 +206,14 @@ struct amdgpu_vm_update_params {
struct amdgpu_vm *vm; 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: * @pages_addr:
@ -271,11 +279,11 @@ struct amdgpu_vm {
struct dma_fence *last_update; struct dma_fence *last_update;
/* Scheduler entities for page table updates */ /* Scheduler entities for page table updates */
struct drm_sched_entity direct; struct drm_sched_entity immediate;
struct drm_sched_entity delayed; struct drm_sched_entity delayed;
/* Last submission to the scheduler entities */ /* Last unlocked submission to the scheduler entities */
struct dma_fence *last_direct; struct dma_fence *last_unlocked;
unsigned int pasid; unsigned int pasid;
/* dedicated to vm */ /* dedicated to vm */
@ -376,7 +384,7 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
void *param); void *param);
int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync); 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, 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, int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
struct amdgpu_vm *vm, struct amdgpu_vm *vm,
struct dma_fence **fence); struct dma_fence **fence);

View File

@ -84,7 +84,7 @@ static int amdgpu_vm_cpu_update(struct amdgpu_vm_update_params *p,
pe += (unsigned long)amdgpu_bo_kptr(bo); 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++) { for (i = 0; i < count; i++) {
value = p->pages_addr ? value = p->pages_addr ?

View File

@ -61,11 +61,12 @@ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
struct dma_resv *resv, struct dma_resv *resv,
enum amdgpu_sync_mode sync_mode) 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; unsigned int ndw = AMDGPU_VM_SDMA_MIN_NUM_DW;
int r; int r;
r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4, r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4, pool, &p->job);
p->direct ? AMDGPU_IB_POOL_VM : AMDGPU_IB_POOL_NORMAL, &p->job);
if (r) if (r)
return 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 amdgpu_ib *ib = p->job->ibs;
struct drm_sched_entity *entity; struct drm_sched_entity *entity;
struct dma_fence *f, *tmp;
struct amdgpu_ring *ring; struct amdgpu_ring *ring;
struct dma_fence *f;
int r; 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); ring = container_of(entity->rq->sched, struct amdgpu_ring, sched);
WARN_ON(ib->length_dw == 0); WARN_ON(ib->length_dw == 0);
@ -105,15 +106,16 @@ static int amdgpu_vm_sdma_commit(struct amdgpu_vm_update_params *p,
if (r) if (r)
goto error; goto error;
if (p->direct) { if (p->unlocked) {
tmp = dma_fence_get(f); struct dma_fence *tmp = dma_fence_get(f);
swap(p->vm->last_direct, tmp);
swap(p->vm->last_unlocked, f);
dma_fence_put(tmp); dma_fence_put(tmp);
} else { } 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); swap(*fence, f);
dma_fence_put(f); dma_fence_put(f);
return 0; 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; src += p->num_dw_left * 4;
pe += amdgpu_gmc_sign_extend(bo->tbo.offset); 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); 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; struct amdgpu_ib *ib = p->job->ibs;
pe += amdgpu_gmc_sign_extend(bo->tbo.offset); 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) { if (count < 3) {
amdgpu_vm_write_pte(p->adev, ib, pe, addr | flags, amdgpu_vm_write_pte(p->adev, ib, pe, addr | flags,
count, incr); 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 addr, unsigned count, uint32_t incr,
uint64_t flags) uint64_t flags)
{ {
enum amdgpu_ib_pool_type pool = p->immediate ? AMDGPU_IB_POOL_IMMEDIATE
: AMDGPU_IB_POOL_DELAYED;
unsigned int i, ndw, nptes; unsigned int i, ndw, nptes;
uint64_t *pte; uint64_t *pte;
int r; 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 = max(ndw, AMDGPU_VM_SDMA_MIN_NUM_DW);
ndw = min(ndw, AMDGPU_VM_SDMA_MAX_NUM_DW); ndw = min(ndw, AMDGPU_VM_SDMA_MAX_NUM_DW);
r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4, r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4, pool,
p->direct ? AMDGPU_IB_POOL_VM : AMDGPU_IB_POOL_NORMAL, &p->job); &p->job);
if (r) if (r)
return r; return r;

View File

@ -395,7 +395,9 @@ int amdgpu_xgmi_set_pstate(struct amdgpu_device *adev, int pstate)
bool init_low = hive->pstate == AMDGPU_XGMI_PSTATE_UNKNOWN; bool init_low = hive->pstate == AMDGPU_XGMI_PSTATE_UNKNOWN;
/* fw bug so temporarily disable pstate switching */ /* 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; return 0;
mutex_lock(&hive->hive_lock); mutex_lock(&hive->hive_lock);

View File

@ -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, static void cik_sdma_emit_copy_buffer(struct amdgpu_ib *ib,
uint64_t src_offset, uint64_t src_offset,
uint64_t dst_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++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0);
ib->ptr[ib->length_dw++] = byte_count; ib->ptr[ib->length_dw++] = byte_count;

View File

@ -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 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_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_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) 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; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
bool enable = (state == AMD_PG_STATE_GATE); bool enable = (state == AMD_PG_STATE_GATE);
if (amdgpu_sriov_vf(adev))
return 0;
switch (adev->asic_type) { switch (adev->asic_type) {
case CHIP_NAVI10: case CHIP_NAVI10:
case CHIP_NAVI14: 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; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (amdgpu_sriov_vf(adev))
return 0;
switch (adev->asic_type) { switch (adev->asic_type) {
case CHIP_NAVI10: case CHIP_NAVI10:
case CHIP_NAVI14: case CHIP_NAVI14:
@ -7427,7 +7434,8 @@ static void gfx_v10_0_ring_emit_sb(struct amdgpu_ring *ring)
amdgpu_ring_write(ring, 0); 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; 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, gfx_v10_0_ring_emit_ce_meta(ring,
(!amdgpu_sriov_vf(ring->adev) && flags & AMDGPU_IB_PREEMPTED) ? true : false); (!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 */ dw2 |= 0x80000000; /* set load_enable otherwise this package is just NOPs */
if (flags & AMDGPU_HAVE_CTX_SWITCH) { if (flags & AMDGPU_HAVE_CTX_SWITCH) {
/* set load_global_config & load_global_uconfig */ /* 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); 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, 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, 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, .init_cond_exec = gfx_v10_0_ring_emit_init_cond_exec,
.patch_cond_exec = gfx_v10_0_ring_emit_patch_cond_exec, .patch_cond_exec = gfx_v10_0_ring_emit_patch_cond_exec,
.preempt_ib = gfx_v10_0_ring_preempt_ib, .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_wreg = gfx_v10_0_ring_emit_wreg,
.emit_reg_wait = gfx_v10_0_ring_emit_reg_wait, .emit_reg_wait = gfx_v10_0_ring_emit_reg_wait,
.emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait, .emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait,

View File

@ -2531,7 +2531,7 @@ static void gfx_v9_0_init_sq_config(struct amdgpu_device *adev)
break; break;
default: default:
break; break;
}; }
} }
static void gfx_v9_0_constants_init(struct amdgpu_device *adev) 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); spin_lock_irqsave(&kiq->ring_lock, flags);
if (amdgpu_device_wb_get(adev, &reg_val_offs)) { if (amdgpu_device_wb_get(adev, &reg_val_offs)) {
spin_unlock_irqrestore(&kiq->ring_lock, flags);
pr_err("critical bug! too many kiq readers\n"); pr_err("critical bug! too many kiq readers\n");
goto failed_kiq_read; goto failed_unlock;
} }
amdgpu_ring_alloc(ring, 32); amdgpu_ring_alloc(ring, 32);
amdgpu_ring_write(ring, PACKET3(PACKET3_COPY_DATA, 4)); 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)); reg_val_offs * 4));
amdgpu_ring_write(ring, upper_32_bits(adev->wb.gpu_addr + amdgpu_ring_write(ring, upper_32_bits(adev->wb.gpu_addr +
reg_val_offs * 4)); 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); amdgpu_ring_commit(ring);
spin_unlock_irqrestore(&kiq->ring_lock, flags); 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); amdgpu_device_wb_free(adev, reg_val_offs);
return value; return value;
failed_undo:
amdgpu_ring_undo(ring);
failed_unlock:
spin_unlock_irqrestore(&kiq->ring_lock, flags);
failed_kiq_read: failed_kiq_read:
if (reg_val_offs)
amdgpu_device_wb_free(adev, reg_val_offs);
pr_err("failed to read gpu clock\n"); pr_err("failed to read gpu clock\n");
return ~0; 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); 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, 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) 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)) if (amdgpu_sriov_vf(ring->adev))
gfx_v9_0_ring_emit_ce_meta(ring); 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 */ dw2 |= 0x80000000; /* set load_enable otherwise this package is just NOPs */
if (flags & AMDGPU_HAVE_CTX_SWITCH) { if (flags & AMDGPU_HAVE_CTX_SWITCH) {
/* set load_global_config & load_global_uconfig */ /* 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, .emit_cntxcntl = gfx_v9_ring_emit_cntxcntl,
.init_cond_exec = gfx_v9_0_ring_emit_init_cond_exec, .init_cond_exec = gfx_v9_0_ring_emit_init_cond_exec,
.patch_cond_exec = gfx_v9_0_ring_emit_patch_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_wreg = gfx_v9_0_ring_emit_wreg,
.emit_reg_wait = gfx_v9_0_ring_emit_reg_wait, .emit_reg_wait = gfx_v9_0_ring_emit_reg_wait,
.emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait, .emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait,

View File

@ -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 * translation. Avoid this by doing the invalidation from the SDMA
* itself. * 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) if (r)
goto error_alloc; 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); amdgpu_ring_alloc(ring, kiq->pmf->invalidate_tlbs_size + 8);
kiq->pmf->kiq_invalidate_tlbs(ring, kiq->pmf->kiq_invalidate_tlbs(ring,
pasid, flush_type, all_hub); 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); amdgpu_ring_commit(ring);
spin_unlock(&adev->gfx.kiq.ring_lock); spin_unlock(&adev->gfx.kiq.ring_lock);
r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout); r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);

View File

@ -621,7 +621,13 @@ static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
pasid, 2, all_hub); pasid, 2, all_hub);
kiq->pmf->kiq_invalidate_tlbs(ring, kiq->pmf->kiq_invalidate_tlbs(ring,
pasid, flush_type, all_hub); 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); amdgpu_ring_commit(ring);
spin_unlock(&adev->gfx.kiq.ring_lock); spin_unlock(&adev->gfx.kiq.ring_lock);
r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout); r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);

View File

@ -26,7 +26,7 @@
#define AI_MAILBOX_POLL_ACK_TIMEDOUT 500 #define AI_MAILBOX_POLL_ACK_TIMEDOUT 500
#define AI_MAILBOX_POLL_MSG_TIMEDOUT 12000 #define AI_MAILBOX_POLL_MSG_TIMEDOUT 12000
#define AI_MAILBOX_POLL_FLR_TIMEDOUT 500 #define AI_MAILBOX_POLL_FLR_TIMEDOUT 5000
enum idh_request { enum idh_request {
IDH_REQ_GPU_INIT_ACCESS = 1, IDH_REQ_GPU_INIT_ACCESS = 1,

View File

@ -26,7 +26,7 @@
#define NV_MAILBOX_POLL_ACK_TIMEDOUT 500 #define NV_MAILBOX_POLL_ACK_TIMEDOUT 500
#define NV_MAILBOX_POLL_MSG_TIMEDOUT 6000 #define NV_MAILBOX_POLL_MSG_TIMEDOUT 6000
#define NV_MAILBOX_POLL_FLR_TIMEDOUT 500 #define NV_MAILBOX_POLL_FLR_TIMEDOUT 5000
enum idh_request { enum idh_request {
IDH_REQ_GPU_INIT_ACCESS = 1, IDH_REQ_GPU_INIT_ACCESS = 1,

View File

@ -73,6 +73,22 @@
#define SDMA_OP_AQL_COPY 0 #define SDMA_OP_AQL_COPY 0
#define SDMA_OP_AQL_BARRIER_OR 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 for op field*/
#define SDMA_PKT_HEADER_op_offset 0 #define SDMA_PKT_HEADER_op_offset 0
#define SDMA_PKT_HEADER_op_mask 0x000000FF #define SDMA_PKT_HEADER_op_mask 0x000000FF

View File

@ -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, &gmc_v10_0_ip_block);
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP && if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)
!amdgpu_sriov_vf(adev))
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);

View File

@ -306,6 +306,7 @@
#define PACKET3_GET_LOD_STATS 0x8E #define PACKET3_GET_LOD_STATS 0x8E
#define PACKET3_DRAW_MULTI_PREAMBLE 0x8F #define PACKET3_DRAW_MULTI_PREAMBLE 0x8F
#define PACKET3_FRAME_CONTROL 0x90 #define PACKET3_FRAME_CONTROL 0x90
# define FRAME_TMZ (1 << 0)
# define FRAME_CMD(x) ((x) << 28) # define FRAME_CMD(x) ((x) << 28)
/* /*
* x=0: tmz_begin * x=0: tmz_begin

View File

@ -137,6 +137,8 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
case CHIP_NAVI10: case CHIP_NAVI10:
case CHIP_NAVI14: case CHIP_NAVI14:
case CHIP_NAVI12: case CHIP_NAVI12:
if (amdgpu_sriov_vf(adev))
break;
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev); err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
if (err) { if (err) {

View File

@ -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, static void sdma_v2_4_emit_copy_buffer(struct amdgpu_ib *ib,
uint64_t src_offset, uint64_t src_offset,
uint64_t dst_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) | 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);

View File

@ -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, static void sdma_v3_0_emit_copy_buffer(struct amdgpu_ib *ib,
uint64_t src_offset, uint64_t src_offset,
uint64_t dst_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) | 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);

View File

@ -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, static void sdma_v4_0_emit_copy_buffer(struct amdgpu_ib *ib,
uint64_t src_offset, uint64_t src_offset,
uint64_t dst_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) | 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++] = byte_count - 1;
ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */ ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
ib->ptr[ib->length_dw++] = lower_32_bits(src_offset); ib->ptr[ib->length_dw++] = lower_32_bits(src_offset);

View File

@ -410,6 +410,18 @@ static void sdma_v5_0_ring_emit_ib(struct amdgpu_ring *ring,
unsigned vmid = AMDGPU_JOB_GET_VMID(job); unsigned vmid = AMDGPU_JOB_GET_VMID(job);
uint64_t csa_mc_addr = amdgpu_sdma_get_csa_mc_addr(ring, vmid); 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 /* 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 * must be on a 8-dword boundary. Our IB packet below is 6
* dwords long, thus add x number of NOPs, such that, in * 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_WREG * 3 +
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 * 2 + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 * 2 +
10 + 10 + 10, /* sdma_v5_0_ring_emit_fence x3 for user fence, vm fence */ 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_ib = sdma_v5_0_ring_emit_ib,
.emit_fence = sdma_v5_0_ring_emit_fence, .emit_fence = sdma_v5_0_ring_emit_fence,
.emit_pipeline_sync = sdma_v5_0_ring_emit_pipeline_sync, .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, static void sdma_v5_0_emit_copy_buffer(struct amdgpu_ib *ib,
uint64_t src_offset, uint64_t src_offset,
uint64_t dst_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) | 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++] = byte_count - 1;
ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */ ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
ib->ptr[ib->length_dw++] = lower_32_bits(src_offset); ib->ptr[ib->length_dw++] = lower_32_bits(src_offset);

View File

@ -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, static void si_dma_emit_copy_buffer(struct amdgpu_ib *ib,
uint64_t src_offset, uint64_t src_offset,
uint64_t dst_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, ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_COPY,
1, 0, 0, byte_count); 1, 0, 0, byte_count);

View File

@ -35,6 +35,9 @@
#define RREG32_SOC15(ip, inst, reg) \ #define RREG32_SOC15(ip, inst, reg) \
RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + 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) \ #define RREG32_SOC15_OFFSET(ip, inst, reg, offset) \
RREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset) RREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset)

View File

@ -286,6 +286,7 @@
#define PACKET3_WAIT_ON_DE_COUNTER_DIFF 0x88 #define PACKET3_WAIT_ON_DE_COUNTER_DIFF 0x88
#define PACKET3_SWITCH_BUFFER 0x8B #define PACKET3_SWITCH_BUFFER 0x8B
#define PACKET3_FRAME_CONTROL 0x90 #define PACKET3_FRAME_CONTROL 0x90
# define FRAME_TMZ (1 << 0)
# define FRAME_CMD(x) ((x) << 28) # define FRAME_CMD(x) ((x) << 28)
/* /*
* x=0: tmz_begin * x=0: tmz_begin

View File

@ -56,24 +56,43 @@ const uint32_t
static void umc_v6_1_enable_umc_index_mode(struct amdgpu_device *adev) 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); 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) 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); 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) 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); 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_REGISTER_NBIF_VG20_GPU,
RSMU_UMC_INDEX_MODE_EN); 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; 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, static void umc_v6_1_query_correctable_error_count(struct amdgpu_device *adev,
uint32_t umc_reg_offset, uint32_t umc_reg_offset,
unsigned long *error_count) 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, ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel, UMCCH0_0_EccErrCntSel,
EccErrCntCsSel, 0); EccErrCntCsSel, 0);
WREG32_PCIE((ecc_err_cnt_sel_addr + umc_reg_offset) * 4, ecc_err_cnt_sel); 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); ecc_err_cnt = RREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4);
*error_count += *error_count +=
(REG_GET_FIELD(ecc_err_cnt, UMCCH0_0_EccErrCnt, EccErrCnt) - (REG_GET_FIELD(ecc_err_cnt, UMCCH0_0_EccErrCnt, EccErrCnt) -
UMC_V6_1_CE_CNT_INIT); 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 */ /* select the higher chip and check the err counter */
ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel, UMCCH0_0_EccErrCntSel, ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel, UMCCH0_0_EccErrCntSel,
EccErrCntCsSel, 1); EccErrCntCsSel, 1);
WREG32_PCIE((ecc_err_cnt_sel_addr + umc_reg_offset) * 4, ecc_err_cnt_sel); 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); ecc_err_cnt = RREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4);
*error_count += *error_count +=
(REG_GET_FIELD(ecc_err_cnt, UMCCH0_0_EccErrCnt, EccErrCnt) - (REG_GET_FIELD(ecc_err_cnt, UMCCH0_0_EccErrCnt, EccErrCnt) -
UMC_V6_1_CE_CNT_INIT); 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 /* check for SRAM correctable error
MCUMC_STATUS is a 64 bit register */ 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) if (rsmu_umc_index_state)
umc_v6_1_enable_umc_index_mode(adev); 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, static void umc_v6_1_query_error_address(struct amdgpu_device *adev,

View File

@ -1404,7 +1404,7 @@ static int vcn_v2_5_pause_dpg_mode(struct amdgpu_device *adev,
{ {
struct amdgpu_ring *ring; struct amdgpu_ring *ring;
uint32_t reg_data = 0; uint32_t reg_data = 0;
int ret_code; int ret_code = 0;
/* pause/unpause if state is changed */ /* pause/unpause if state is changed */
if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) { 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); (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
if (new_state->fw_based == VCN_DPG_STATE__PAUSE) { if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
ret_code = 0;
SOC15_WAIT_ON_RREG(UVD, inst_idx, mmUVD_POWER_STATUS, 0x1, SOC15_WAIT_ON_RREG(UVD, inst_idx, mmUVD_POWER_STATUS, 0x1,
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); 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); UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
} }
} else { } else {
/* unpause dpg, no need to wait */
reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
WREG32_SOC15(UVD, inst_idx, mmUVD_DPG_PAUSE, reg_data); 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; adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based;
} }

View File

@ -215,6 +215,7 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
} }
q_properties->is_interop = false; q_properties->is_interop = false;
q_properties->is_gws = false;
q_properties->queue_percent = args->queue_percentage; q_properties->queue_percent = args->queue_percentage;
q_properties->priority = args->queue_priority; q_properties->priority = args->queue_priority;
q_properties->queue_address = args->ring_base_address; q_properties->queue_address = args->ring_base_address;
@ -1584,6 +1585,45 @@ copy_from_user_failed:
return err; 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, static int kfd_ioctl_get_dmabuf_info(struct file *filep,
struct kfd_process *p, void *data) 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, AMDKFD_IOCTL_DEF(AMDKFD_IOC_IMPORT_DMABUF,
kfd_ioctl_import_dmabuf, 0), 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) #define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls)

View File

@ -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, bool kgd2kfd_device_init(struct kfd_dev *kfd,
struct drm_device *ddev, struct drm_device *ddev,
const struct kgd2kfd_shared_resources *gpu_resources) const struct kgd2kfd_shared_resources *gpu_resources)
@ -578,6 +595,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
kfd->ddev = ddev; kfd->ddev = ddev;
kfd->mec_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd, kfd->mec_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd,
KGD_ENGINE_MEC1); 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, kfd->sdma_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd,
KGD_ENGINE_SDMA1); KGD_ENGINE_SDMA1);
kfd->shared_resources = *gpu_resources; kfd->shared_resources = *gpu_resources;
@ -598,13 +617,6 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
} else } else
kfd->max_proc_per_quantum = hws_max_conc_proc; 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 */ /* calculate max size of mqds needed for queues */
size = max_num_of_queues_per_device * size = max_num_of_queues_per_device *
kfd->device_info->mqd_size_aligned; kfd->device_info->mqd_size_aligned;
@ -662,6 +674,15 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
goto device_queue_manager_error; 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)) { if (kfd_iommu_device_init(kfd)) {
dev_err(kfd_device, "Error initializing iommuv2\n"); dev_err(kfd_device, "Error initializing iommuv2\n");
goto device_iommu_error; goto device_iommu_error;
@ -691,6 +712,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
kfd_topology_add_device_error: kfd_topology_add_device_error:
kfd_resume_error: kfd_resume_error:
device_iommu_error: device_iommu_error:
gws_error:
device_queue_manager_uninit(kfd->dqm); device_queue_manager_uninit(kfd->dqm);
device_queue_manager_error: device_queue_manager_error:
kfd_interrupt_exit(kfd); kfd_interrupt_exit(kfd);
@ -701,7 +723,7 @@ kfd_doorbell_error:
kfd_gtt_sa_init_error: kfd_gtt_sa_init_error:
amdgpu_amdkfd_free_gtt_mem(kfd->kgd, kfd->gtt_mem); amdgpu_amdkfd_free_gtt_mem(kfd->kgd, kfd->gtt_mem);
alloc_gtt_mem_failure: alloc_gtt_mem_failure:
if (hws_gws_support) if (kfd->gws)
amdgpu_amdkfd_free_gws(kfd->kgd, kfd->gws); amdgpu_amdkfd_free_gws(kfd->kgd, kfd->gws);
dev_err(kfd_device, dev_err(kfd_device,
"device %x:%x NOT added due to errors\n", "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_doorbell_fini(kfd);
kfd_gtt_sa_fini(kfd); kfd_gtt_sa_fini(kfd);
amdgpu_amdkfd_free_gtt_mem(kfd->kgd, kfd->gtt_mem); 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); amdgpu_amdkfd_free_gws(kfd->kgd, kfd->gws);
} }

View File

@ -505,8 +505,13 @@ static int destroy_queue_nocpsch_locked(struct device_queue_manager *dqm,
deallocate_vmid(dqm, qpd, q); deallocate_vmid(dqm, qpd, q);
} }
qpd->queue_count--; qpd->queue_count--;
if (q->properties.is_active) if (q->properties.is_active) {
decrement_queue_count(dqm, q->properties.type); decrement_queue_count(dqm, q->properties.type);
if (q->properties.is_gws) {
dqm->gws_queue_count--;
qpd->mapped_gws_queue = false;
}
}
return retval; 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) else if (!q->properties.is_active && prev_active)
decrement_queue_count(dqm, q->properties.type); 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) if (dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS)
retval = map_queues_cpsch(dqm); retval = map_queues_cpsch(dqm);
else if (q->properties.is_active && 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.type)];
q->properties.is_active = false; q->properties.is_active = false;
decrement_queue_count(dqm, q->properties.type); 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")) if (WARN_ONCE(!dqm->sched_running, "Evict when stopped\n"))
continue; continue;
@ -744,6 +767,10 @@ static int restore_process_queues_nocpsch(struct device_queue_manager *dqm,
q->properties.type)]; q->properties.type)];
q->properties.is_active = true; q->properties.is_active = true;
increment_queue_count(dqm, q->properties.type); 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")) if (WARN_ONCE(!dqm->sched_running, "Restore when stopped\n"))
continue; continue;
@ -913,6 +940,7 @@ static int initialize_nocpsch(struct device_queue_manager *dqm)
INIT_LIST_HEAD(&dqm->queues); INIT_LIST_HEAD(&dqm->queues);
dqm->active_queue_count = dqm->next_pipe_to_allocate = 0; dqm->active_queue_count = dqm->next_pipe_to_allocate = 0;
dqm->active_cp_queue_count = 0; dqm->active_cp_queue_count = 0;
dqm->gws_queue_count = 0;
for (pipe = 0; pipe < get_pipes_per_mec(dqm); pipe++) { for (pipe = 0; pipe < get_pipes_per_mec(dqm); pipe++) {
int pipe_offset = pipe * get_queues_per_pipe(dqm); 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); INIT_LIST_HEAD(&dqm->queues);
dqm->active_queue_count = dqm->processes_count = 0; dqm->active_queue_count = dqm->processes_count = 0;
dqm->active_cp_queue_count = 0; dqm->active_cp_queue_count = 0;
dqm->gws_queue_count = 0;
dqm->active_runlist = false; dqm->active_runlist = false;
dqm->sdma_bitmap = ~0ULL >> (64 - get_num_sdma_queues(dqm)); dqm->sdma_bitmap = ~0ULL >> (64 - get_num_sdma_queues(dqm));
dqm->xgmi_sdma_bitmap = ~0ULL >> (64 - get_num_xgmi_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); KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
if (retval == -ETIME) if (retval == -ETIME)
qpd->reset_wavefronts = true; 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) else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
deallocate_sdma_queue(dqm, q); deallocate_sdma_queue(dqm, q);
if (q->properties.is_active) if (q->properties.is_active) {
decrement_queue_count(dqm, q->properties.type); 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--; dqm->total_queue_count--;
} }

View File

@ -182,6 +182,7 @@ struct device_queue_manager {
unsigned int processes_count; unsigned int processes_count;
unsigned int active_queue_count; unsigned int active_queue_count;
unsigned int active_cp_queue_count; unsigned int active_cp_queue_count;
unsigned int gws_queue_count;
unsigned int total_queue_count; unsigned int total_queue_count;
unsigned int next_pipe_to_allocate; unsigned int next_pipe_to_allocate;
unsigned int *allocated_queues; unsigned int *allocated_queues;

View File

@ -126,6 +126,7 @@ static bool kq_initialize(struct kernel_queue *kq, struct kfd_dev *dev,
prop.queue_size = queue_size; prop.queue_size = queue_size;
prop.is_interop = false; prop.is_interop = false;
prop.is_gws = false;
prop.priority = 1; prop.priority = 1;
prop.queue_percent = 100; prop.queue_percent = 100;
prop.type = type; prop.type = type;

View File

@ -41,7 +41,7 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
unsigned int *rlib_size, unsigned int *rlib_size,
bool *over_subscription) 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 map_queue_size;
unsigned int max_proc_per_quantum = 1; unsigned int max_proc_per_quantum = 1;
struct kfd_dev *dev = pm->dqm->dev; 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; process_count = pm->dqm->processes_count;
queue_count = pm->dqm->active_queue_count; queue_count = pm->dqm->active_queue_count;
compute_queue_count = pm->dqm->active_cp_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 /* check if there is over subscription
* Note: the arbitration between the number of VMIDs and * 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; max_proc_per_quantum = dev->max_proc_per_quantum;
if ((process_count > 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; *over_subscription = true;
pr_debug("Over subscribed runlist\n"); pr_debug("Over subscribed runlist\n");
} }

View File

@ -43,7 +43,7 @@ static int pm_map_process_v9(struct packet_manager *pm,
packet->bitfields2.pasid = qpd->pqm->process->pasid; packet->bitfields2.pasid = qpd->pqm->process->pasid;
packet->bitfields14.gds_size = qpd->gds_size & 0x3F; packet->bitfields14.gds_size = qpd->gds_size & 0x3F;
packet->bitfields14.gds_size_hi = (qpd->gds_size >> 6) & 0xF; 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.num_oac = qpd->num_oac;
packet->bitfields14.sdma_enable = 1; packet->bitfields14.sdma_enable = 1;
packet->bitfields14.num_queues = (qpd->is_debug) ? 0 : qpd->queue_count; packet->bitfields14.num_queues = (qpd->is_debug) ? 0 : qpd->queue_count;

View File

@ -282,6 +282,7 @@ struct kfd_dev {
/* Firmware versions */ /* Firmware versions */
uint16_t mec_fw_version; uint16_t mec_fw_version;
uint16_t mec2_fw_version;
uint16_t sdma_fw_version; uint16_t sdma_fw_version;
/* Maximum process number mapped to HW scheduler */ /* 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_active: Defines if the queue is active or not. @is_active and
* @is_evicted are protected by the DQM lock. * @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 * @vmid: If the scheduling mode is no cp scheduling the field defines the vmid
* of the queue. * of the queue.
* *
@ -432,6 +437,7 @@ struct queue_properties {
bool is_interop; bool is_interop;
bool is_evicted; bool is_evicted;
bool is_active; bool is_active;
bool is_gws;
/* Not relevant for user mode queues in cp scheduling */ /* Not relevant for user mode queues in cp scheduling */
unsigned int vmid; unsigned int vmid;
/* Relevant only for sdma queues*/ /* Relevant only for sdma queues*/
@ -563,6 +569,14 @@ struct qcm_process_device {
*/ */
bool reset_wavefronts; 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 * 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); void *gws);
struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm, struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm,
unsigned int qid); 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, int pqm_get_wave_state(struct process_queue_manager *pqm,
unsigned int qid, unsigned int qid,
void __user *ctl_stack, void __user *ctl_stack,

View File

@ -858,6 +858,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
pdd->qpd.dqm = dev->dqm; pdd->qpd.dqm = dev->dqm;
pdd->qpd.pqm = &p->pqm; pdd->qpd.pqm = &p->pqm;
pdd->qpd.evicted = 0; pdd->qpd.evicted = 0;
pdd->qpd.mapped_gws_queue = false;
pdd->process = p; pdd->process = p;
pdd->bound = PDD_UNBOUND; pdd->bound = PDD_UNBOUND;
pdd->already_dequeued = false; pdd->already_dequeued = false;

View File

@ -476,6 +476,15 @@ struct kernel_queue *pqm_get_kernel_queue(
return NULL; 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, int pqm_get_wave_state(struct process_queue_manager *pqm,
unsigned int qid, unsigned int qid,
void __user *ctl_stack, void __user *ctl_stack,

View File

@ -1301,6 +1301,10 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
dev->node_props.vendor_id = gpu->pdev->vendor; dev->node_props.vendor_id = gpu->pdev->vendor;
dev->node_props.device_id = gpu->pdev->device; 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.location_id = pci_dev_id(gpu->pdev);
dev->node_props.max_engine_clk_fcompute = dev->node_props.max_engine_clk_fcompute =
amdgpu_amdkfd_get_max_engine_clock_in_mhz(dev->gpu->kgd); 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; gpu->device_info->num_xgmi_sdma_engines;
dev->node_props.num_sdma_queues_per_engine = dev->node_props.num_sdma_queues_per_engine =
gpu->device_info->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) ? dev->gpu->dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS) ?
amdgpu_amdkfd_get_num_gws(dev->gpu->kgd) : 0; amdgpu_amdkfd_get_num_gws(dev->gpu->kgd) : 0;
dev->node_props.num_cp_queues = get_cp_queues_num(dev->gpu->dqm); dev->node_props.num_cp_queues = get_cp_queues_num(dev->gpu->dqm);

View File

@ -41,7 +41,6 @@
#define HSA_CAP_WATCH_POINTS_TOTALBITS_SHIFT 8 #define HSA_CAP_WATCH_POINTS_TOTALBITS_SHIFT 8
#define HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK 0x00003000 #define HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK 0x00003000
#define HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT 12 #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_PRE_1_0 0x0
#define HSA_CAP_DOORBELL_TYPE_1_0 0x1 #define HSA_CAP_DOORBELL_TYPE_1_0 0x1
@ -51,6 +50,10 @@
#define HSA_CAP_SRAM_EDCSUPPORTED 0x00080000 #define HSA_CAP_SRAM_EDCSUPPORTED 0x00080000
#define HSA_CAP_MEM_EDCSUPPORTED 0x00100000 #define HSA_CAP_MEM_EDCSUPPORTED 0x00100000
#define HSA_CAP_RASEVENTNOTIFY 0x00200000 #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 { struct kfd_node_properties {
uint64_t hive_id; uint64_t hive_id;

View File

@ -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, 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]); struct amdgpu_bo *rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
int r = amdgpu_bo_reserve(rbo, false); 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) if (tiling_flags)
amdgpu_bo_get_tiling_flags(rbo, tiling_flags); amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
if (tmz_surface)
*tmz_surface = amdgpu_bo_encrypted(rbo);
amdgpu_bo_unreserve(rbo); amdgpu_bo_unreserve(rbo);
return r; return r;
@ -3411,6 +3414,7 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
struct plane_size *plane_size, struct plane_size *plane_size,
struct dc_plane_dcc_param *dcc, struct dc_plane_dcc_param *dcc,
struct dc_plane_address *address, struct dc_plane_address *address,
bool tmz_surface,
bool force_disable_dcc) bool force_disable_dcc)
{ {
const struct drm_framebuffer *fb = &afb->base; 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(dcc, 0, sizeof(*dcc));
memset(address, 0, sizeof(*address)); memset(address, 0, sizeof(*address));
address->tmz_surface = tmz_surface;
if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
plane_size->surface_size.x = 0; plane_size->surface_size.x = 0;
plane_size->surface_size.y = 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, const uint64_t tiling_flags,
struct dc_plane_info *plane_info, struct dc_plane_info *plane_info,
struct dc_plane_address *address, struct dc_plane_address *address,
bool tmz_surface,
bool force_disable_dcc) bool force_disable_dcc)
{ {
const struct drm_framebuffer *fb = plane_state->fb; 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->rotation, tiling_flags,
&plane_info->tiling_info, &plane_info->tiling_info,
&plane_info->plane_size, &plane_info->plane_size,
&plane_info->dcc, address, &plane_info->dcc, address, tmz_surface,
force_disable_dcc); force_disable_dcc);
if (ret) if (ret)
return ret; return ret;
@ -3717,6 +3724,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
struct dc_plane_info plane_info; struct dc_plane_info plane_info;
uint64_t tiling_flags; uint64_t tiling_flags;
int ret; int ret;
bool tmz_surface = false;
bool force_disable_dcc = false; bool force_disable_dcc = false;
ret = fill_dc_scaling_info(plane_state, &scaling_info); 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->clip_rect = scaling_info.clip_rect;
dc_plane_state->scaling_quality = scaling_info.scaling_quality; 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) if (ret)
return 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, ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags,
&plane_info, &plane_info,
&dc_plane_state->address, &dc_plane_state->address,
tmz_surface,
force_disable_dcc); force_disable_dcc);
if (ret) if (ret)
return ret; return ret;
@ -5354,6 +5363,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
uint64_t tiling_flags; uint64_t tiling_flags;
uint32_t domain; uint32_t domain;
int r; int r;
bool tmz_surface = false;
bool force_disable_dcc = false; bool force_disable_dcc = false;
dm_plane_state_old = to_dm_plane_state(plane->state); 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); amdgpu_bo_get_tiling_flags(rbo, &tiling_flags);
tmz_surface = amdgpu_bo_encrypted(rbo);
ttm_eu_backoff_reservation(&ticket, &list); ttm_eu_backoff_reservation(&ticket, &list);
afb->address = amdgpu_bo_gpu_offset(rbo); 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, adev, afb, plane_state->format, plane_state->rotation,
tiling_flags, &plane_state->tiling_info, tiling_flags, &plane_state->tiling_info,
&plane_state->plane_size, &plane_state->dcc, &plane_state->plane_size, &plane_state->dcc,
&plane_state->address, &plane_state->address, tmz_surface,
force_disable_dcc); force_disable_dcc);
} }
@ -6592,6 +6604,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
unsigned long flags; unsigned long flags;
struct amdgpu_bo *abo; struct amdgpu_bo *abo;
uint64_t tiling_flags; uint64_t tiling_flags;
bool tmz_surface = false;
uint32_t target_vblank, last_flip_vblank; uint32_t target_vblank, last_flip_vblank;
bool vrr_active = amdgpu_dm_vrr_active(acrtc_state); bool vrr_active = amdgpu_dm_vrr_active(acrtc_state);
bool pflip_present = false; 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); amdgpu_bo_get_tiling_flags(abo, &tiling_flags);
tmz_surface = amdgpu_bo_encrypted(abo);
amdgpu_bo_unreserve(abo); amdgpu_bo_unreserve(abo);
fill_dc_plane_info_and_addr( fill_dc_plane_info_and_addr(
dm->adev, new_plane_state, tiling_flags, dm->adev, new_plane_state, tiling_flags,
&bundle->plane_infos[planes_count], &bundle->plane_infos[planes_count],
&bundle->flip_addrs[planes_count].address, &bundle->flip_addrs[planes_count].address,
tmz_surface,
false); false);
DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n", 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_flip_addrs *flip_addr = &bundle->flip_addrs[num_plane];
struct dc_scaling_info *scaling_info = &bundle->scaling_infos[num_plane]; struct dc_scaling_info *scaling_info = &bundle->scaling_infos[num_plane];
uint64_t tiling_flags; uint64_t tiling_flags;
bool tmz_surface = false;
new_plane_crtc = new_plane_state->crtc; new_plane_crtc = new_plane_state->crtc;
new_dm_plane_state = to_dm_plane_state(new_plane_state); 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; bundle->surface_updates[num_plane].scaling_info = scaling_info;
if (amdgpu_fb) { if (amdgpu_fb) {
ret = get_fb_info(amdgpu_fb, &tiling_flags); ret = get_fb_info(amdgpu_fb, &tiling_flags, &tmz_surface);
if (ret) if (ret)
goto cleanup; goto cleanup;
ret = fill_dc_plane_info_and_addr( ret = fill_dc_plane_info_and_addr(
dm->adev, new_plane_state, tiling_flags, dm->adev, new_plane_state, tiling_flags,
plane_info, plane_info,
&flip_addr->address, &flip_addr->address, tmz_surface,
false); false);
if (ret) if (ret)
goto cleanup; goto cleanup;

View File

@ -239,7 +239,8 @@ static int __set_output_tf(struct dc_transfer_func *func,
* instead to simulate this. * instead to simulate this.
*/ */
gamma->type = GAMMA_CUSTOM; gamma->type = GAMMA_CUSTOM;
res = mod_color_calculate_degamma_params(func, gamma, true); res = mod_color_calculate_degamma_params(NULL, func,
gamma, true);
} else { } else {
/* /*
* Assume sRGB. The actual mapping will depend on whether the * 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); __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); dc_gamma_release(&gamma);
return res ? 0 : -ENOMEM; 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; dc_plane_state->in_transfer_func->tf = tf;
if (tf != TRANSFER_FUNCTION_SRGB && if (tf != TRANSFER_FUNCTION_SRGB &&
!mod_color_calculate_degamma_params( !mod_color_calculate_degamma_params(NULL,
dc_plane_state->in_transfer_func, NULL, false)) dc_plane_state->in_transfer_func, NULL, false))
return -ENOMEM; return -ENOMEM;
} else { } else {

View File

@ -113,13 +113,19 @@ static void encoder_control_dmcub(
struct dc_dmub_srv *dmcub, struct dc_dmub_srv *dmcub,
struct dig_encoder_stream_setup_parameters_v1_5 *dig) 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; memset(&cmd, 0, sizeof(cmd));
encoder_control.header.sub_type = DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL;
encoder_control.encoder_control.dig.stream_param = *dig;
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_cmd_execute(dmcub);
dc_dmub_srv_wait_idle(dmcub); dc_dmub_srv_wait_idle(dmcub);
} }
@ -238,14 +244,19 @@ static void transmitter_control_dmcub(
struct dc_dmub_srv *dmcub, struct dc_dmub_srv *dmcub,
struct dig_transmitter_control_parameters_v1_6 *dig) 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; memset(&cmd, 0, sizeof(cmd));
transmitter_control.header.sub_type =
cmd.dig1_transmitter_control.header.type = DMUB_CMD__VBIOS;
cmd.dig1_transmitter_control.header.sub_type =
DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL; 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_cmd_execute(dmcub);
dc_dmub_srv_wait_idle(dmcub); dc_dmub_srv_wait_idle(dmcub);
} }
@ -339,13 +350,18 @@ static void set_pixel_clock_dmcub(
struct dc_dmub_srv *dmcub, struct dc_dmub_srv *dmcub,
struct set_pixel_clock_parameter_v1_7 *clk) 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; memset(&cmd, 0, sizeof(cmd));
pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK;
pixel_clock.pixel_clock.clk = *clk;
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_cmd_execute(dmcub);
dc_dmub_srv_wait_idle(dmcub); dc_dmub_srv_wait_idle(dmcub);
} }
@ -705,13 +721,19 @@ static void enable_disp_power_gating_dmcub(
struct dc_dmub_srv *dmcub, struct dc_dmub_srv *dmcub,
struct enable_disp_power_gating_parameters_v2_1 *pwr) 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; memset(&cmd, 0, sizeof(cmd));
power_gating.header.sub_type = DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING;
power_gating.power_gating.pwr = *pwr;
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_cmd_execute(dmcub);
dc_dmub_srv_wait_idle(dmcub); dc_dmub_srv_wait_idle(dmcub);
} }

View File

@ -2210,7 +2210,9 @@ static void commit_planes_do_stream_update(struct dc *dc,
if (should_program_abm) { if (should_program_abm) {
if (*stream_update->abm_level == ABM_LEVEL_IMMEDIATE_DISABLE) { 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 { } else {
pipe_ctx->stream_res.abm->funcs->set_abm_level( pipe_ctx->stream_res.abm->funcs->set_abm_level(
pipe_ctx->stream_res.abm, stream->abm_level); pipe_ctx->stream_res.abm, stream->abm_level);

View File

@ -2509,35 +2509,21 @@ bool dc_link_set_backlight_level(const struct dc_link *link,
uint32_t frame_ramp) uint32_t frame_ramp)
{ {
struct dc *dc = link->ctx->dc; 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; int i;
DC_LOGGER_INIT(link->ctx->logger); 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", DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
backlight_pwm_u16_16, backlight_pwm_u16_16); backlight_pwm_u16_16, backlight_pwm_u16_16);
if (dc_is_embedded_signal(link->connector_signal)) { if (dc_is_embedded_signal(link->connector_signal)) {
struct pipe_ctx *pipe_ctx = NULL;
for (i = 0; i < MAX_PIPES; i++) { 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) {
if (dc->current_state->res_ctx. if (dc->current_state->res_ctx.
pipe_ctx[i].stream->link pipe_ctx[i].stream->link
== link) { == link) {
/* DMCU -1 for all controller id values, pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
* therefore +1 here
*/
controller_id =
dc->current_state->
res_ctx.pipe_ctx[i].stream_res.tg->inst +
1;
/* Disable brightness ramping when the display is blanked /* Disable brightness ramping when the display is blanked
* as it can hang the DMCU * 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, backlight_pwm_u16_16,
frame_ramp, frame_ramp);
controller_id,
fw_set_brightness);
} }
return true; return true;
@ -2564,7 +2552,7 @@ bool dc_link_set_abm_disable(const struct dc_link *link)
bool success = false; bool success = false;
if (abm) if (abm)
success = abm->funcs->set_abm_immediate_disable(abm); success = abm->funcs->set_abm_immediate_disable(abm, link->panel_cntl->inst);
return success; return success;
} }

View File

@ -599,7 +599,7 @@ bool dal_ddc_submit_aux_command(struct ddc_service *ddc,
do { do {
struct aux_payload current_payload; struct aux_payload current_payload;
bool is_end_of_payload = (retrieved + DEFAULT_AUX_MAX_DATA_SIZE) > bool is_end_of_payload = (retrieved + DEFAULT_AUX_MAX_DATA_SIZE) >
payload->length ? true : false; payload->length;
current_payload.address = payload->address; current_payload.address = payload->address;
current_payload.data = &payload->data[retrieved]; current_payload.data = &payload->data[retrieved];

View File

@ -4231,7 +4231,7 @@ void dpcd_set_source_specific_data(struct dc_link *link)
{ {
const uint32_t post_oui_delay = 30; // 30ms const uint32_t post_oui_delay = 30; // 30ms
uint8_t dspc = 0; 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, ret = core_link_read_dpcd(link, DP_DOWN_STREAM_PORT_COUNT, &dspc,
sizeof(dspc)); sizeof(dspc));

View File

@ -1064,8 +1064,8 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
calculate_viewport(pipe_ctx); calculate_viewport(pipe_ctx);
if (pipe_ctx->plane_res.scl_data.viewport.height < 16 || if (pipe_ctx->plane_res.scl_data.viewport.height < 12 ||
pipe_ctx->plane_res.scl_data.viewport.width < 16) { pipe_ctx->plane_res.scl_data.viewport.width < 12) {
if (store_h_border_left) { if (store_h_border_left) {
restore_border_left_from_dst(pipe_ctx, restore_border_left_from_dst(pipe_ctx,
store_h_border_left); store_h_border_left);

View File

@ -231,34 +231,6 @@ struct dc_stream_status *dc_stream_get_status(
return dc_stream_get_status_from_state(dc->current_state, stream); 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 * 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) { if (!pipe_to_program) {
pipe_to_program = pipe_ctx; pipe_to_program = pipe_ctx;
dc->hwss.cursor_lock(dc, pipe_to_program, true);
delay_cursor_until_vupdate(pipe_ctx, dc);
dc->hwss.pipe_control_lock(dc, pipe_to_program, true);
} }
dc->hwss.set_cursor_attribute(pipe_ctx); dc->hwss.set_cursor_attribute(pipe_ctx);
@ -309,7 +279,7 @@ bool dc_stream_set_cursor_attributes(
} }
if (pipe_to_program) 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; return true;
} }
@ -349,16 +319,14 @@ bool dc_stream_set_cursor_position(
if (!pipe_to_program) { if (!pipe_to_program) {
pipe_to_program = pipe_ctx; pipe_to_program = pipe_ctx;
dc->hwss.cursor_lock(dc, pipe_to_program, true);
delay_cursor_until_vupdate(pipe_ctx, dc);
dc->hwss.pipe_control_lock(dc, pipe_to_program, true);
} }
dc->hwss.set_cursor_position(pipe_ctx); dc->hwss.set_cursor_position(pipe_ctx);
} }
if (pipe_to_program) 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; return true;
} }

View File

@ -42,7 +42,7 @@
#include "inc/hw/dmcu.h" #include "inc/hw/dmcu.h"
#include "dml/display_mode_lib.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_SURFACES 3
#define MAX_PLANES 6 #define MAX_PLANES 6
@ -98,6 +98,49 @@ struct dc_plane_cap {
} max_downscale_factor; } 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 { struct dc_caps {
uint32_t max_streams; uint32_t max_streams;
uint32_t max_links; uint32_t max_links;
@ -120,9 +163,9 @@ struct dc_caps {
bool psp_setup_panel_mode; bool psp_setup_panel_mode;
bool extended_aux_timeout_support; bool extended_aux_timeout_support;
bool dmcub_support; bool dmcub_support;
bool hw_3d_lut;
enum dp_protocol_version max_dp_protocol_version; enum dp_protocol_version max_dp_protocol_version;
struct dc_plane_cap planes[MAX_PLANES]; struct dc_plane_cap planes[MAX_PLANES];
struct dc_color_caps color;
}; };
struct dc_bug_wa { struct dc_bug_wa {
@ -478,6 +521,7 @@ struct dc_bounding_box_overrides {
int urgent_latency_ns; int urgent_latency_ns;
int percent_of_ideal_drambw; int percent_of_ideal_drambw;
int dram_clock_change_latency_ns; int dram_clock_change_latency_ns;
int dummy_clock_change_latency_ns;
/* This forces a hard min on the DCFCLK we use /* This forces a hard min on the DCFCLK we use
* for DML. Unlike the debug option for forcing * for DML. Unlike the debug option for forcing
* DCFCLK, this override affects watermark calculations * DCFCLK, this override affects watermark calculations

View File

@ -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, 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 dmub_srv *dmub = dc_dmub_srv->dmub;
struct dc_context *dc_ctx = dc_dmub_srv->ctx; struct dc_context *dc_ctx = dc_dmub_srv->ctx;

View File

@ -27,10 +27,9 @@
#define _DMUB_DC_SRV_H_ #define _DMUB_DC_SRV_H_
#include "os_types.h" #include "os_types.h"
#include "../dmub/inc/dmub_cmd.h" #include "dmub/inc/dmub_cmd.h"
struct dmub_srv; struct dmub_srv;
struct dmub_cmd_header;
struct dc_reg_helper_state { struct dc_reg_helper_state {
bool gather_in_progress; 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, 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); void dc_dmub_srv_cmd_execute(struct dc_dmub_srv *dc_dmub_srv);

View File

@ -50,7 +50,7 @@ static inline void submit_dmub_read_modify_write(
gather = ctx->dmub_srv->reg_helper_offload.gather_in_progress; gather = ctx->dmub_srv->reg_helper_offload.gather_in_progress;
ctx->dmub_srv->reg_helper_offload.gather_in_progress = false; 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; 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; gather = ctx->dmub_srv->reg_helper_offload.gather_in_progress;
ctx->dmub_srv->reg_helper_offload.gather_in_progress = false; 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; 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; gather = ctx->dmub_srv->reg_helper_offload.gather_in_progress;
ctx->dmub_srv->reg_helper_offload.gather_in_progress = false; 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)); memset(cmd_buf, 0, sizeof(*cmd_buf));
offload->reg_seq_count = 0; offload->reg_seq_count = 0;

View File

@ -55,7 +55,7 @@
#define MCP_DISABLE_ABM_IMMEDIATELY 255 #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); struct dce_abm *abm_dce = TO_DCE_ABM(abm);
uint32_t rampingBoundary = 0xFFFF; uint32_t rampingBoundary = 0xFFFF;
@ -201,7 +201,8 @@ static void dmcu_set_backlight_level(
struct dce_abm *abm_dce, struct dce_abm *abm_dce,
uint32_t backlight_pwm_u16_16, uint32_t backlight_pwm_u16_16,
uint32_t frame_ramp, uint32_t frame_ramp,
uint32_t controller_id) uint32_t controller_id,
uint32_t panel_id)
{ {
unsigned int backlight_8_bit = 0; unsigned int backlight_8_bit = 0;
uint32_t s2; uint32_t s2;
@ -213,7 +214,7 @@ static void dmcu_set_backlight_level(
// Take MSB of fractional part since backlight is not max // Take MSB of fractional part since backlight is not max
backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF; 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 */ /* waitDMCUReadyForCmd */
REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 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; 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); struct dce_abm *abm_dce = TO_DCE_ABM(abm);
if (abm->dmcu_is_running == false) if (abm->dmcu_is_running == false)
return true; 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 = abm->stored_backlight_registers.BL_PWM_CNTL =
REG_READ(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 backlight_pwm_u16_16,
unsigned int frame_ramp, unsigned int frame_ramp,
unsigned int controller_id, unsigned int controller_id,
unsigned int panel_inst,
bool fw_set_brightness) bool fw_set_brightness)
{ {
struct dce_abm *abm_dce = TO_DCE_ABM(abm); 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, dmcu_set_backlight_level(abm_dce,
backlight_pwm_u16_16, backlight_pwm_u16_16,
frame_ramp, frame_ramp,
controller_id); controller_id,
panel_inst);
else else
driver_set_backlight_level(abm_dce, backlight_pwm_u16_16); driver_set_backlight_level(abm_dce, backlight_pwm_u16_16);

View File

@ -27,7 +27,7 @@
#include "dce_abm.h" #include "dce_abm.h"
#include "dc.h" #include "dc.h"
#include "dc_dmub_srv.h" #include "dc_dmub_srv.h"
#include "../../dmub/inc/dmub_srv.h" #include "dmub/inc/dmub_srv.h"
#include "core_types.h" #include "core_types.h"
#include "dm_services.h" #include "dm_services.h"
#include "reg_helper.h" #include "reg_helper.h"
@ -50,7 +50,7 @@
#define DISABLE_ABM_IMMEDIATELY 255 #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; union dmub_rb_cmd cmd;
struct dc_context *dc = abm->ctx; 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.type = DMUB_CMD__ABM;
cmd.abm_set_pipe.header.sub_type = DMUB_CMD__ABM_SET_PIPE; 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.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.abm_set_pipe_data.ramping_boundary = ramping_boundary;
cmd.abm_set_pipe.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_pipe_data); 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_cmd_execute(dc->dmub_srv);
dc_dmub_srv_wait_idle(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, struct dce_abm *dce_abm,
uint32_t backlight_pwm_u16_16, uint32_t backlight_pwm_u16_16,
uint32_t frame_ramp, uint32_t frame_ramp,
uint32_t otg_inst) uint32_t otg_inst,
uint32_t panel_inst)
{ {
union dmub_rb_cmd cmd; union dmub_rb_cmd cmd;
struct dc_context *dc = dce_abm->base.ctx; 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 // Take MSB of fractional part since backlight is not max
backlight_8_bit = (backlight_pwm_u16_16 >> 8) & 0xFF; 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); 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.abm_set_backlight_data.frame_ramp = frame_ramp;
cmd.abm_set_backlight.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_backlight_data); 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_cmd_execute(dc->dmub_srv);
dc_dmub_srv_wait_idle(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.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); 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_cmd_execute(dc->dmub_srv);
dc_dmub_srv_wait_idle(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.abm_set_level_data.level = level;
cmd.abm_set_level.header.payload_bytes = sizeof(struct dmub_cmd_abm_set_level_data); 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_cmd_execute(dc->dmub_srv);
dc_dmub_srv_wait_idle(dc->dmub_srv); dc_dmub_srv_wait_idle(dc->dmub_srv);
return true; 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); 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 = abm->stored_backlight_registers.BL_PWM_CNTL =
REG_READ(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 backlight_pwm_u16_16,
unsigned int frame_ramp, unsigned int frame_ramp,
unsigned int otg_inst, unsigned int otg_inst,
uint32_t panel_inst,
bool fw_set_brightness) bool fw_set_brightness)
{ {
struct dce_abm *dce_abm = TO_DMUB_ABM(abm); 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, dmcub_set_backlight_level(dce_abm,
backlight_pwm_u16_16, backlight_pwm_u16_16,
frame_ramp, frame_ramp,
otg_inst); otg_inst,
panel_inst);
return true; 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.abm_init_config_data.bytes = bytes;
cmd.abm_init_config.header.payload_bytes = sizeof(struct dmub_cmd_abm_init_config_data); 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_cmd_execute(dc->dmub_srv);
dc_dmub_srv_wait_idle(dc->dmub_srv); dc_dmub_srv_wait_idle(dc->dmub_srv);

View File

@ -26,8 +26,8 @@
#include "dmub_psr.h" #include "dmub_psr.h"
#include "dc.h" #include "dc.h"
#include "dc_dmub_srv.h" #include "dc_dmub_srv.h"
#include "../../dmub/inc/dmub_srv.h" #include "dmub/inc/dmub_srv.h"
#include "../../dmub/inc/dmub_gpint_cmd.h" #include "dmub/inc/dmub_gpint_cmd.h"
#include "core_types.h" #include "core_types.h"
#define MAX_PIPES 6 #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.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); 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_cmd_execute(dc->dmub_srv);
dc_dmub_srv_wait_idle(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 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_cmd_execute(dc->dmub_srv);
dc_dmub_srv_wait_idle(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.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_level_data);
cmd.psr_set_level.psr_set_level_data.psr_level = psr_level; 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_cmd_execute(dc->dmub_srv);
dc_dmub_srv_wait_idle(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 ? copy_settings_data->debug.visual_confirm = dc->dc->debug.visual_confirm == VISUAL_CONFIRM_PSR ?
true : false; 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_cmd_execute(dc->dmub_srv);
dc_dmub_srv_wait_idle(dc->dmub_srv); dc_dmub_srv_wait_idle(dc->dmub_srv);

View File

@ -2714,6 +2714,37 @@ void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
pipe_ctx->plane_res.xfm, attributes); 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 = { static const struct hw_sequencer_funcs dce110_funcs = {
.program_gamut_remap = program_gamut_remap, .program_gamut_remap = program_gamut_remap,
.program_output_csc = program_output_csc, .program_output_csc = program_output_csc,
@ -2736,6 +2767,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
.disable_plane = dce110_power_down_fe, .disable_plane = dce110_power_down_fe,
.pipe_control_lock = dce_pipe_control_lock, .pipe_control_lock = dce_pipe_control_lock,
.interdependent_update_lock = NULL, .interdependent_update_lock = NULL,
.cursor_lock = dce_pipe_control_lock,
.prepare_bandwidth = dce110_prepare_bandwidth, .prepare_bandwidth = dce110_prepare_bandwidth,
.optimize_bandwidth = dce110_optimize_bandwidth, .optimize_bandwidth = dce110_optimize_bandwidth,
.set_drr = set_drr, .set_drr = set_drr,
@ -2747,7 +2779,8 @@ static const struct hw_sequencer_funcs dce110_funcs = {
.edp_power_control = dce110_edp_power_control, .edp_power_control = dce110_edp_power_control,
.edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready, .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready,
.set_cursor_position = dce110_set_cursor_position, .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 = { static const struct hwseq_private_funcs dce110_private_funcs = {

View File

@ -85,5 +85,9 @@ void dce110_edp_wait_for_hpd_ready(
struct dc_link *link, struct dc_link *link,
bool power_up); 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__ */ #endif /* __DC_HWSS_DCE110_H__ */

View File

@ -679,8 +679,7 @@ void dce110_opp_v_set_csc_default(
if (default_adjust->force_hw_default == false) { if (default_adjust->force_hw_default == false) {
const struct out_csc_color_matrix *elm; const struct out_csc_color_matrix *elm;
/* currently parameter not in use */ /* currently parameter not in use */
enum grph_color_adjust_option option = enum grph_color_adjust_option option;
GRPH_COLOR_MATRIX_HW_DEFAULT;
uint32_t i; uint32_t i;
/* /*
* HW default false we program locally defined matrix * HW default false we program locally defined matrix

View File

@ -903,7 +903,8 @@ static void dcn10_reset_back_end_for_pipe(
if (pipe_ctx->top_pipe == NULL) { if (pipe_ctx->top_pipe == NULL) {
if (pipe_ctx->stream_res.abm) 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); 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); 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( static bool wait_for_reset_trigger_to_occur(
struct dc_context *dc_ctx, struct dc_context *dc_ctx,
struct timing_generator *tg) struct timing_generator *tg)
@ -2474,12 +2485,14 @@ void dcn10_blank_pixel_data(
if (stream_res->tg->funcs->set_blank) if (stream_res->tg->funcs->set_blank)
stream_res->tg->funcs->set_blank(stream_res->tg, blank); stream_res->tg->funcs->set_blank(stream_res->tg, blank);
if (stream_res->abm) { 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); stream_res->abm->funcs->set_abm_level(stream_res->abm, stream->abm_level);
} }
} else if (blank) { } else if (blank) {
if (stream_res->abm) 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) if (stream_res->tg->funcs->set_blank)
stream_res->tg->funcs->set_blank(stream_res->tg, blank); stream_res->tg->funcs->set_blank(stream_res->tg, blank);
} }

View File

@ -49,6 +49,7 @@ void dcn10_pipe_control_lock(
struct dc *dc, struct dc *dc,
struct pipe_ctx *pipe, struct pipe_ctx *pipe,
bool lock); bool lock);
void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock);
void dcn10_blank_pixel_data( void dcn10_blank_pixel_data(
struct dc *dc, struct dc *dc,
struct pipe_ctx *pipe_ctx, struct pipe_ctx *pipe_ctx,

View File

@ -50,6 +50,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.disable_audio_stream = dce110_disable_audio_stream, .disable_audio_stream = dce110_disable_audio_stream,
.disable_plane = dcn10_disable_plane, .disable_plane = dcn10_disable_plane,
.pipe_control_lock = dcn10_pipe_control_lock, .pipe_control_lock = dcn10_pipe_control_lock,
.cursor_lock = dcn10_cursor_lock,
.interdependent_update_lock = dcn10_lock_all_pipes, .interdependent_update_lock = dcn10_lock_all_pipes,
.prepare_bandwidth = dcn10_prepare_bandwidth, .prepare_bandwidth = dcn10_prepare_bandwidth,
.optimize_bandwidth = dcn10_optimize_bandwidth, .optimize_bandwidth = dcn10_optimize_bandwidth,
@ -71,6 +72,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
.set_clock = dcn10_set_clock, .set_clock = dcn10_set_clock,
.get_clock = dcn10_get_clock, .get_clock = dcn10_get_clock,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, .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 = { static const struct hwseq_private_funcs dcn10_private_funcs = {

View File

@ -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_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id);
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_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 */ /* update mpc tree mux setting */
if (tree->opp_list == insert_above_mpcc) { if (tree->opp_list == insert_above_mpcc) {
/* insert the toppest 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_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_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_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 */ /* mark this mpcc as not in use */
mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id); 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_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_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_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_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_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_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); 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_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_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_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); mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id);
@ -453,6 +460,13 @@ void mpc1_read_mpcc_state(
MPCC_BUSY, &s->busy); 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 = { static const struct mpc_funcs dcn10_mpc_funcs = {
.read_mpcc_state = mpc1_read_mpcc_state, .read_mpcc_state = mpc1_read_mpcc_state,
.insert_plane = mpc1_insert_plane, .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, .assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect,
.init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw, .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
.update_blending = mpc1_update_blending, .update_blending = mpc1_update_blending,
.cursor_lock = mpc1_cursor_lock,
.set_denorm = NULL, .set_denorm = NULL,
.set_denorm_clamp = NULL, .set_denorm_clamp = NULL,
.set_output_csc = NULL, .set_output_csc = NULL,

View File

@ -39,11 +39,12 @@
SRII(MPCC_BG_G_Y, MPCC, inst),\ SRII(MPCC_BG_G_Y, MPCC, inst),\
SRII(MPCC_BG_R_CR, 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_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) \ #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 \ #define MPC_COMMON_REG_VARIABLE_LIST \
uint32_t MPCC_TOP_SEL[MAX_MPCC]; \ uint32_t MPCC_TOP_SEL[MAX_MPCC]; \
@ -55,7 +56,9 @@
uint32_t MPCC_BG_R_CR[MAX_MPCC]; \ uint32_t MPCC_BG_R_CR[MAX_MPCC]; \
uint32_t MPCC_BG_B_CB[MAX_MPCC]; \ uint32_t MPCC_BG_B_CB[MAX_MPCC]; \
uint32_t MPCC_SM_CONTROL[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)\ #define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\
SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, 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_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_FRAME_POL, mask_sh),\
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_TOP_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) \ #define MPC_REG_FIELD_LIST(type) \
type MPCC_TOP_SEL;\ type MPCC_TOP_SEL;\
@ -101,7 +105,9 @@
type MPCC_SM_FIELD_ALT;\ type MPCC_SM_FIELD_ALT;\
type MPCC_SM_FORCE_NEXT_FRAME_POL;\ type MPCC_SM_FORCE_NEXT_FRAME_POL;\
type MPCC_SM_FORCE_NEXT_TOP_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 { struct dcn_mpc_registers {
MPC_COMMON_REG_VARIABLE_LIST MPC_COMMON_REG_VARIABLE_LIST
@ -192,4 +198,6 @@ void mpc1_read_mpcc_state(
int mpcc_inst, int mpcc_inst,
struct mpcc_state *s); struct mpcc_state *s);
void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock);
#endif #endif

View File

@ -182,6 +182,14 @@ enum dcn10_clk_src_array_id {
.reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
mm ## block ## id ## _ ## reg_name 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 */ /* NBIO */
#define NBIO_BASE_INNER(seg) \ #define NBIO_BASE_INNER(seg) \
NBIF_BASE__INST0_SEG ## 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 = { 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 = { 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)\ #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 */ /* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */
dc->caps.force_dp_tps4_for_cp2520 = true; 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) if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
dc->debug = debug_defaults_drv; dc->debug = debug_defaults_drv;
else else

View File

@ -962,7 +962,8 @@ void dcn20_blank_pixel_data(
if (blank) { if (blank) {
if (stream_res->abm) 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) { if (dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) {
test_pattern = CONTROLLER_DP_TEST_PATTERN_COLORSQUARES; test_pattern = CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
@ -997,7 +998,8 @@ void dcn20_blank_pixel_data(
if (!blank) if (!blank)
if (stream_res->abm) { 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); 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->top_pipe == NULL) {
if (pipe_ctx->stream_res.abm) 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); 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_REFDIV, 2);
REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1); 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);
// //

View File

@ -52,6 +52,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
.disable_plane = dcn20_disable_plane, .disable_plane = dcn20_disable_plane,
.pipe_control_lock = dcn20_pipe_control_lock, .pipe_control_lock = dcn20_pipe_control_lock,
.interdependent_update_lock = dcn10_lock_all_pipes, .interdependent_update_lock = dcn10_lock_all_pipes,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn20_prepare_bandwidth, .prepare_bandwidth = dcn20_prepare_bandwidth,
.optimize_bandwidth = dcn20_optimize_bandwidth, .optimize_bandwidth = dcn20_optimize_bandwidth,
.update_bandwidth = dcn20_update_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, .init_vm_ctx = dcn20_init_vm_ctx,
.set_flip_control_gsl = dcn20_set_flip_control_gsl, .set_flip_control_gsl = dcn20_set_flip_control_gsl,
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, .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 = { static const struct hwseq_private_funcs dcn20_private_funcs = {

View File

@ -452,7 +452,7 @@ void mpc2_set_output_gamma(
next_mode = LUT_RAM_A; next_mode = LUT_RAM_A;
mpc20_power_on_ogam_lut(mpc, mpcc_id, true); 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) if (next_mode == LUT_RAM_A)
mpc2_program_luta(mpc, mpcc_id, params); 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 = mpc1_mpc_init,
.mpc_init_single_inst = mpc1_mpc_init_single_inst, .mpc_init_single_inst = mpc1_mpc_init_single_inst,
.update_blending = mpc2_update_blending, .update_blending = mpc2_update_blending,
.cursor_lock = mpc1_cursor_lock,
.get_mpcc_for_dpp = mpc2_get_mpcc_for_dpp, .get_mpcc_for_dpp = mpc2_get_mpcc_for_dpp,
.wait_for_idle = mpc2_assert_idle_mpcc, .wait_for_idle = mpc2_assert_idle_mpcc,
.assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect, .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect,

View File

@ -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_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_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_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: * DCN2 MPC_OCSC debug status register:

View File

@ -509,6 +509,10 @@ enum dcn20_clk_src_array_id {
.block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
mm ## block ## id ## _ ## reg_name 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 */ /* NBIO */
#define NBIO_BASE_INNER(seg) \ #define NBIO_BASE_INNER(seg) \
NBIO_BASE__INST0_SEG ## seg NBIO_BASE__INST0_SEG ## seg
@ -1936,7 +1940,7 @@ bool dcn20_split_stream_for_odm(
return true; return true;
} }
void dcn20_split_stream_for_mpc( bool dcn20_split_stream_for_mpc(
struct resource_context *res_ctx, struct resource_context *res_ctx,
const struct resource_pool *pool, const struct resource_pool *pool,
struct pipe_ctx *primary_pipe, struct pipe_ctx *primary_pipe,
@ -1965,8 +1969,11 @@ void dcn20_split_stream_for_mpc(
secondary_pipe->top_pipe = primary_pipe; secondary_pipe->top_pipe = primary_pipe;
ASSERT(primary_pipe->plane_state); ASSERT(primary_pipe->plane_state);
resource_build_scaling_params(primary_pipe); if (!resource_build_scaling_params(primary_pipe) ||
resource_build_scaling_params(secondary_pipe); !resource_build_scaling_params(secondary_pipe))
return false;
return true;
} }
void dcn20_populate_dml_writeback_from_context( 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 */ /* Avoid split loop looks for lowest voltage level that allows most unsplit pipes possible */
if (avoid_split) { 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++) { for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
if (!context->res_ctx.pipe_ctx[i].stream) if (!context->res_ctx.pipe_ctx[i].stream)
continue; continue;
for (vlevel_split = vlevel; vlevel <= context->bw_ctx.dml.soc.num_states; vlevel++) 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; break;
/* Impossible to not split this pipe */ /* Impossible to not split this pipe */
if (vlevel > context->bw_ctx.dml.soc.num_states) if (vlevel > context->bw_ctx.dml.soc.num_states)
vlevel = vlevel_split; vlevel = vlevel_split;
else
max_mpc_comb = 0;
pipe_idx++; 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 */ /* 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; goto validate_fail;
dcn20_build_mapped_resource(dc, context, pipe->stream); dcn20_build_mapped_resource(dc, context, pipe->stream);
} else } else
dcn20_split_stream_for_mpc( if (!dcn20_split_stream_for_mpc(
&context->res_ctx, dc->res_pool, &context->res_ctx, dc->res_pool,
pipe, hsplit_pipe); pipe, hsplit_pipe))
goto validate_fail;
pipe_split_from[hsplit_pipe->pipe_idx] = pipe_idx; pipe_split_from[hsplit_pipe->pipe_idx] = pipe_idx;
} }
} else if (hsplit_pipe && hsplit_pipe->plane_state == pipe->plane_state) { } 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 = bb->dram_clock_change_latency_us =
dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; 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( 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.max_slave_planes = 1;
dc->caps.post_blend_color_processing = true; dc->caps.post_blend_color_processing = true;
dc->caps.force_dp_tps4_for_cp2520 = true; dc->caps.force_dp_tps4_for_cp2520 = true;
dc->caps.hw_3d_lut = true;
dc->caps.extended_aux_timeout_support = 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) { if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) {
dc->debug = debug_defaults_drv; dc->debug = debug_defaults_drv;
} else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) { } else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {

View File

@ -129,7 +129,7 @@ void dcn20_release_dsc(struct resource_context *res_ctx,
const struct resource_pool *pool, const struct resource_pool *pool,
struct display_stream_compressor **dsc); struct display_stream_compressor **dsc);
bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx); 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, struct resource_context *res_ctx,
const struct resource_pool *pool, const struct resource_pool *pool,
struct pipe_ctx *primary_pipe, struct pipe_ctx *primary_pipe,

View File

@ -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 dc_dmub_srv *dmcub = hubp->ctx->dmub_srv;
struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); 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; memset(&cmd, 0, sizeof(cmd));
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; cmd.PLAT_54186_wa.header.type = DMUB_CMD__PLAT_54186_WA;
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH; cmd.PLAT_54186_wa.header.payload_bytes = sizeof(cmd.PLAT_54186_wa.flip);
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C; cmd.PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS =
PLAT_54186_wa.flip.flip_params.grph_stereo = flip_regs->grph_stereo; flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS;
PLAT_54186_wa.flip.flip_params.hubp_inst = hubp->inst; cmd.PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C =
PLAT_54186_wa.flip.flip_params.immediate = flip_regs->immediate; flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_C;
PLAT_54186_wa.flip.flip_params.tmz_surface = flip_regs->tmz_surface; cmd.PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
PLAT_54186_wa.flip.flip_params.vmid = flip_regs->vmid; 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. 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. PERF_TRACE(); // TODO: remove after performance is stable.
dc_dmub_srv_cmd_execute(dmcub); dc_dmub_srv_cmd_execute(dmcub);
PERF_TRACE(); // TODO: remove after performance is stable. PERF_TRACE(); // TODO: remove after performance is stable.

View File

@ -53,6 +53,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
.disable_plane = dcn20_disable_plane, .disable_plane = dcn20_disable_plane,
.pipe_control_lock = dcn20_pipe_control_lock, .pipe_control_lock = dcn20_pipe_control_lock,
.interdependent_update_lock = dcn10_lock_all_pipes, .interdependent_update_lock = dcn10_lock_all_pipes,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn20_prepare_bandwidth, .prepare_bandwidth = dcn20_prepare_bandwidth,
.optimize_bandwidth = dcn20_optimize_bandwidth, .optimize_bandwidth = dcn20_optimize_bandwidth,
.update_bandwidth = dcn20_update_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, .optimize_pwr_state = dcn21_optimize_pwr_state,
.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state, .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
.power_down = dce110_power_down, .power_down = dce110_power_down,
.set_backlight_level = dce110_set_backlight_level,
}; };
static const struct hwseq_private_funcs dcn21_private_funcs = { static const struct hwseq_private_funcs dcn21_private_funcs = {

View File

@ -286,7 +286,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
.dram_channel_width_bytes = 4, .dram_channel_width_bytes = 4,
.fabric_datapath_to_dcn_data_return_bytes = 32, .fabric_datapath_to_dcn_data_return_bytes = 32,
.dcn_downspread_percent = 0.5, .dcn_downspread_percent = 0.5,
.downspread_percent = 0.5, .downspread_percent = 0.38,
.dram_page_open_time_ns = 50.0, .dram_page_open_time_ns = 50.0,
.dram_rw_turnaround_time_ns = 17.5, .dram_rw_turnaround_time_ns = 17.5,
.dram_return_buffer_per_channel_bytes = 8192, .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) + \ .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
mm ## block ## id ## _ ## reg_name 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 */ /* NBIO */
#define NBIO_BASE_INNER(seg) \ #define NBIO_BASE_INNER(seg) \
NBIF0_BASE__INST0_SEG ## 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 dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
struct clk_limit_table *clk_table = &bw_params->clk_table; struct clk_limit_table *clk_table = &bw_params->clk_table;
unsigned int i, j, k; struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
int closest_clk_lvl; unsigned int i, j, closest_clk_lvl;
// Default clock levels are used for diags, which may lead to overclocking. // 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_otg = pool->base.res_cap->num_timing_generator;
dcn2_1_ip.max_num_dpp = pool->base.pipe_count; dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
dcn2_1_soc.num_chans = bw_params->num_channels; dcn2_1_soc.num_chans = bw_params->num_channels;
/* Vmin: leave lowest DCN clocks, override with dcfclk, fclk, memclk from fuse */ ASSERT(clk_table->num_entries);
dcn2_1_soc.clock_limits[0].state = 0; for (i = 0; i < clk_table->num_entries; i++) {
dcn2_1_soc.clock_limits[0].dcfclk_mhz = clk_table->entries[0].dcfclk_mhz; /* loop backwards*/
dcn2_1_soc.clock_limits[0].fabricclk_mhz = clk_table->entries[0].fclk_mhz; for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) {
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--) {
if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
closest_clk_lvl = j; closest_clk_lvl = j;
break; break;
} }
} }
/* if found a lvl that fits, use the DCN clks from it, if not, go to next clk limit*/ clock_limits[i].state = i;
if (closest_clk_lvl != -1) { clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
dcn2_1_soc.clock_limits[k].state = i; clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
dcn2_1_soc.clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
dcn2_1_soc.clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz; clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
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;
dcn2_1_soc.clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; clock_limits[i].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; clock_limits[i].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; clock_limits[i].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; clock_limits[i].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; clock_limits[i].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; clock_limits[i].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; clock_limits[i].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
k++; }
} 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); 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.i2c_speed_in_khz = 100;
dc->caps.max_cursor_size = 256; dc->caps.max_cursor_size = 256;
dc->caps.dmdata_alloc_size = 2048; dc->caps.dmdata_alloc_size = 2048;
dc->caps.hw_3d_lut = true;
dc->caps.max_slave_planes = 1; dc->caps.max_slave_planes = 1;
dc->caps.post_blend_color_processing = true; dc->caps.post_blend_color_processing = true;
@ -1822,6 +1810,40 @@ static bool dcn21_resource_construct(
dc->caps.dmcub_support = true; dc->caps.dmcub_support = true;
dc->caps.is_apu = 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) if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
dc->debug = debug_defaults_drv; dc->debug = debug_defaults_drv;
else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) { else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {

View File

@ -121,6 +121,7 @@ struct _vcs_dpi_soc_bounding_box_st {
}; };
struct _vcs_dpi_ip_params_st { struct _vcs_dpi_ip_params_st {
bool use_min_dcfclk;
bool gpuvm_enable; bool gpuvm_enable;
bool hostvm_enable; bool hostvm_enable;
unsigned int gpuvm_max_page_table_levels; unsigned int gpuvm_max_page_table_levels;

View File

@ -280,6 +280,7 @@ static void fetch_ip_params(struct display_mode_lib *mode_lib)
ip_params_st *ip = &mode_lib->vba.ip; ip_params_st *ip = &mode_lib->vba.ip;
// IP Parameters // IP Parameters
mode_lib->vba.UseMinimumRequiredDCFCLK = ip->use_min_dcfclk;
mode_lib->vba.MaxNumDPP = ip->max_num_dpp; mode_lib->vba.MaxNumDPP = ip->max_num_dpp;
mode_lib->vba.MaxNumOTG = ip->max_num_otg; mode_lib->vba.MaxNumOTG = ip->max_num_otg;
mode_lib->vba.MaxNumHDMIFRLOutputs = ip->max_num_hdmi_frl_outputs; 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