Merge tag 'amd-drm-next-5.6-2020-01-17' of git://people.freedesktop.org/~agd5f/linux into drm-next
amd-drm-next-5.6-2020-01-17: amdgpu: - Fix 32 bit harder - Powerplay cleanups - VCN fixes for Arcturus - RAS fixes - eDP/DP fixes - SR-IOV fixes - Re-enable S/G display for PCO/RV2 - Free stolen memory after init on gmc10 - DF hashing optimizations for Arcturus - Properly handle runtime pm in sysfs and debugfs - Unify more GC programming between amdgpu and amdkfd - Golden settings updates for gfx10 - GDDR6 training fixes - Freesync fixes - DSC fixes - TMDS fixes - Renoir USB-C fixes - DC dml updates from hw team - Pollock support - Mutex init regresson fix amdkfd: - Unify more GC programming between amdgpu and amdkfd - Use KIQ to setup HIQ rather than using MMIO scheduler: - Documentation fixes - Improve job distribution with load sharing drm: - DP MST fix Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200117213625.4722-1-alexander.deucher@amd.com
This commit is contained in:
commit
df95968ff7
@ -90,6 +90,7 @@
|
||||
#include "amdgpu_mes.h"
|
||||
#include "amdgpu_umc.h"
|
||||
#include "amdgpu_mmhub.h"
|
||||
#include "amdgpu_df.h"
|
||||
|
||||
#define MAX_GPU_INSTANCE 16
|
||||
|
||||
@ -664,29 +665,6 @@ struct amdgpu_mmio_remap {
|
||||
resource_size_t bus_addr;
|
||||
};
|
||||
|
||||
struct amdgpu_df_funcs {
|
||||
void (*sw_init)(struct amdgpu_device *adev);
|
||||
void (*sw_fini)(struct amdgpu_device *adev);
|
||||
void (*enable_broadcast_mode)(struct amdgpu_device *adev,
|
||||
bool enable);
|
||||
u32 (*get_fb_channel_number)(struct amdgpu_device *adev);
|
||||
u32 (*get_hbm_channel_number)(struct amdgpu_device *adev);
|
||||
void (*update_medium_grain_clock_gating)(struct amdgpu_device *adev,
|
||||
bool enable);
|
||||
void (*get_clockgating_state)(struct amdgpu_device *adev,
|
||||
u32 *flags);
|
||||
void (*enable_ecc_force_par_wr_rmw)(struct amdgpu_device *adev,
|
||||
bool enable);
|
||||
int (*pmc_start)(struct amdgpu_device *adev, uint64_t config,
|
||||
int is_enable);
|
||||
int (*pmc_stop)(struct amdgpu_device *adev, uint64_t config,
|
||||
int is_disable);
|
||||
void (*pmc_get_count)(struct amdgpu_device *adev, uint64_t config,
|
||||
uint64_t *count);
|
||||
uint64_t (*get_fica)(struct amdgpu_device *adev, uint32_t ficaa_val);
|
||||
void (*set_fica)(struct amdgpu_device *adev, uint32_t ficaa_val,
|
||||
uint32_t ficadl_val, uint32_t ficadh_val);
|
||||
};
|
||||
/* Define the HW IP blocks will be used in driver , add more if necessary */
|
||||
enum amd_hw_ip_block_type {
|
||||
GC_HWIP = 1,
|
||||
@ -930,6 +908,9 @@ struct amdgpu_device {
|
||||
bool enable_mes;
|
||||
struct amdgpu_mes mes;
|
||||
|
||||
/* df */
|
||||
struct amdgpu_df df;
|
||||
|
||||
struct amdgpu_ip_block ip_blocks[AMDGPU_MAX_IP_NUM];
|
||||
int num_ip_blocks;
|
||||
struct mutex mn_lock;
|
||||
@ -943,8 +924,6 @@ struct amdgpu_device {
|
||||
/* soc15 register offset based on ip, instance and segment */
|
||||
uint32_t *reg_offset[MAX_HWIP][HWIP_MAX_INSTANCE];
|
||||
|
||||
const struct amdgpu_df_funcs *df_funcs;
|
||||
|
||||
/* delayed work_func for deferring clockgating during resume */
|
||||
struct delayed_work delayed_init_work;
|
||||
|
||||
|
@ -613,15 +613,9 @@ void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
|
||||
|
||||
if (is_support_sw_smu(adev))
|
||||
smu_switch_power_profile(&adev->smu,
|
||||
PP_SMC_POWER_PROFILE_COMPUTE,
|
||||
!idle);
|
||||
else if (adev->powerplay.pp_funcs &&
|
||||
adev->powerplay.pp_funcs->switch_power_profile)
|
||||
amdgpu_dpm_switch_power_profile(adev,
|
||||
PP_SMC_POWER_PROFILE_COMPUTE,
|
||||
!idle);
|
||||
amdgpu_dpm_switch_power_profile(adev,
|
||||
PP_SMC_POWER_PROFILE_COMPUTE,
|
||||
!idle);
|
||||
}
|
||||
|
||||
bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid)
|
||||
@ -634,6 +628,38 @@ bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid)
|
||||
return false;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct kgd_dev *kgd, uint16_t vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
|
||||
|
||||
if (adev->family == AMDGPU_FAMILY_AI) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adev->num_vmhubs; i++)
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid, i, 0);
|
||||
} else {
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid, AMDGPU_GFXHUB_0, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct kgd_dev *kgd, uint16_t pasid)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
|
||||
uint32_t flush_type = 0;
|
||||
bool all_hub = false;
|
||||
|
||||
if (adev->gmc.xgmi.num_physical_nodes &&
|
||||
adev->asic_type == CHIP_VEGA20)
|
||||
flush_type = 2;
|
||||
|
||||
if (adev->family == AMDGPU_FAMILY_AI)
|
||||
all_hub = true;
|
||||
|
||||
return amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, flush_type, all_hub);
|
||||
}
|
||||
|
||||
bool amdgpu_amdkfd_have_atomics_support(struct kgd_dev *kgd)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
|
||||
|
@ -136,6 +136,8 @@ int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine,
|
||||
uint32_t *ib_cmd, uint32_t ib_len);
|
||||
void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle);
|
||||
bool amdgpu_amdkfd_have_atomics_support(struct kgd_dev *kgd);
|
||||
int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct kgd_dev *kgd, uint16_t vmid);
|
||||
int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct kgd_dev *kgd, uint16_t pasid);
|
||||
|
||||
bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid);
|
||||
|
||||
|
@ -71,32 +71,56 @@ static uint32_t get_sdma_rlc_reg_offset(struct amdgpu_device *adev,
|
||||
unsigned int engine_id,
|
||||
unsigned int queue_id)
|
||||
{
|
||||
uint32_t sdma_engine_reg_base[8] = {
|
||||
SOC15_REG_OFFSET(SDMA0, 0,
|
||||
mmSDMA0_RLC0_RB_CNTL) - mmSDMA0_RLC0_RB_CNTL,
|
||||
SOC15_REG_OFFSET(SDMA1, 0,
|
||||
mmSDMA1_RLC0_RB_CNTL) - mmSDMA1_RLC0_RB_CNTL,
|
||||
SOC15_REG_OFFSET(SDMA2, 0,
|
||||
mmSDMA2_RLC0_RB_CNTL) - mmSDMA2_RLC0_RB_CNTL,
|
||||
SOC15_REG_OFFSET(SDMA3, 0,
|
||||
mmSDMA3_RLC0_RB_CNTL) - mmSDMA3_RLC0_RB_CNTL,
|
||||
SOC15_REG_OFFSET(SDMA4, 0,
|
||||
mmSDMA4_RLC0_RB_CNTL) - mmSDMA4_RLC0_RB_CNTL,
|
||||
SOC15_REG_OFFSET(SDMA5, 0,
|
||||
mmSDMA5_RLC0_RB_CNTL) - mmSDMA5_RLC0_RB_CNTL,
|
||||
SOC15_REG_OFFSET(SDMA6, 0,
|
||||
mmSDMA6_RLC0_RB_CNTL) - mmSDMA6_RLC0_RB_CNTL,
|
||||
SOC15_REG_OFFSET(SDMA7, 0,
|
||||
mmSDMA7_RLC0_RB_CNTL) - mmSDMA7_RLC0_RB_CNTL
|
||||
};
|
||||
uint32_t sdma_engine_reg_base = 0;
|
||||
uint32_t sdma_rlc_reg_offset;
|
||||
|
||||
uint32_t retval = sdma_engine_reg_base[engine_id]
|
||||
switch (engine_id) {
|
||||
default:
|
||||
dev_warn(adev->dev,
|
||||
"Invalid sdma engine id (%d), using engine id 0\n",
|
||||
engine_id);
|
||||
/* fall through */
|
||||
case 0:
|
||||
sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA0, 0,
|
||||
mmSDMA0_RLC0_RB_CNTL) - mmSDMA0_RLC0_RB_CNTL;
|
||||
break;
|
||||
case 1:
|
||||
sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA1, 0,
|
||||
mmSDMA1_RLC0_RB_CNTL) - mmSDMA1_RLC0_RB_CNTL;
|
||||
break;
|
||||
case 2:
|
||||
sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA2, 0,
|
||||
mmSDMA2_RLC0_RB_CNTL) - mmSDMA2_RLC0_RB_CNTL;
|
||||
break;
|
||||
case 3:
|
||||
sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA3, 0,
|
||||
mmSDMA3_RLC0_RB_CNTL) - mmSDMA3_RLC0_RB_CNTL;
|
||||
break;
|
||||
case 4:
|
||||
sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA4, 0,
|
||||
mmSDMA4_RLC0_RB_CNTL) - mmSDMA4_RLC0_RB_CNTL;
|
||||
break;
|
||||
case 5:
|
||||
sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA5, 0,
|
||||
mmSDMA5_RLC0_RB_CNTL) - mmSDMA5_RLC0_RB_CNTL;
|
||||
break;
|
||||
case 6:
|
||||
sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA6, 0,
|
||||
mmSDMA6_RLC0_RB_CNTL) - mmSDMA6_RLC0_RB_CNTL;
|
||||
break;
|
||||
case 7:
|
||||
sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA7, 0,
|
||||
mmSDMA7_RLC0_RB_CNTL) - mmSDMA7_RLC0_RB_CNTL;
|
||||
break;
|
||||
}
|
||||
|
||||
sdma_rlc_reg_offset = sdma_engine_reg_base
|
||||
+ queue_id * (mmSDMA0_RLC1_RB_CNTL - mmSDMA0_RLC0_RB_CNTL);
|
||||
|
||||
pr_debug("RLC register offset for SDMA%d RLC%d: 0x%x\n", engine_id,
|
||||
queue_id, retval);
|
||||
queue_id, sdma_rlc_reg_offset);
|
||||
|
||||
return retval;
|
||||
return sdma_rlc_reg_offset;
|
||||
}
|
||||
|
||||
static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd,
|
||||
@ -281,6 +305,7 @@ const struct kfd2kgd_calls arcturus_kfd2kgd = {
|
||||
.set_pasid_vmid_mapping = kgd_gfx_v9_set_pasid_vmid_mapping,
|
||||
.init_interrupts = kgd_gfx_v9_init_interrupts,
|
||||
.hqd_load = kgd_gfx_v9_hqd_load,
|
||||
.hiq_mqd_load = kgd_gfx_v9_hiq_mqd_load,
|
||||
.hqd_sdma_load = kgd_hqd_sdma_load,
|
||||
.hqd_dump = kgd_gfx_v9_hqd_dump,
|
||||
.hqd_sdma_dump = kgd_hqd_sdma_dump,
|
||||
@ -296,7 +321,5 @@ const struct kfd2kgd_calls arcturus_kfd2kgd = {
|
||||
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
|
||||
.get_tile_config = kgd_gfx_v9_get_tile_config,
|
||||
.set_vm_context_page_table_base = kgd_set_vm_context_page_table_base,
|
||||
.invalidate_tlbs = kgd_gfx_v9_invalidate_tlbs,
|
||||
.invalidate_tlbs_vmid = kgd_gfx_v9_invalidate_tlbs_vmid,
|
||||
.get_hive_id = amdgpu_amdkfd_get_hive_id,
|
||||
};
|
||||
|
@ -107,13 +107,13 @@ static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id,
|
||||
lock_srbm(kgd, mec, pipe, queue_id, 0);
|
||||
}
|
||||
|
||||
static uint32_t get_queue_mask(struct amdgpu_device *adev,
|
||||
static uint64_t get_queue_mask(struct amdgpu_device *adev,
|
||||
uint32_t pipe_id, uint32_t queue_id)
|
||||
{
|
||||
unsigned int bit = (pipe_id * adev->gfx.mec.num_queue_per_pipe +
|
||||
queue_id) & 31;
|
||||
unsigned int bit = pipe_id * adev->gfx.mec.num_queue_per_pipe +
|
||||
queue_id;
|
||||
|
||||
return ((uint32_t)1) << bit;
|
||||
return 1ull << bit;
|
||||
}
|
||||
|
||||
static void release_queue(struct kgd_dev *kgd)
|
||||
@ -268,21 +268,6 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
|
||||
pr_debug("Load hqd of pipe %d queue %d\n", pipe_id, queue_id);
|
||||
acquire_queue(kgd, pipe_id, queue_id);
|
||||
|
||||
/* HIQ is set during driver init period with vmid set to 0*/
|
||||
if (m->cp_hqd_vmid == 0) {
|
||||
uint32_t value, mec, pipe;
|
||||
|
||||
mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
|
||||
pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
|
||||
|
||||
pr_debug("kfd: set HIQ, mec:%d, pipe:%d, queue:%d.\n",
|
||||
mec, pipe, queue_id);
|
||||
value = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_CP_SCHEDULERS));
|
||||
value = REG_SET_FIELD(value, RLC_CP_SCHEDULERS, scheduler1,
|
||||
((mec << 5) | (pipe << 3) | queue_id | 0x80));
|
||||
WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_CP_SCHEDULERS), value);
|
||||
}
|
||||
|
||||
/* HQD registers extend from CP_MQD_BASE_ADDR to CP_HQD_EOP_WPTR_MEM. */
|
||||
mqd_hqd = &m->cp_mqd_base_addr_lo;
|
||||
hqd_base = SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR);
|
||||
@ -332,9 +317,10 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
|
||||
lower_32_bits((uint64_t)wptr));
|
||||
WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI),
|
||||
upper_32_bits((uint64_t)wptr));
|
||||
pr_debug("%s setting CP_PQ_WPTR_POLL_CNTL1 to %x\n", __func__, get_queue_mask(adev, pipe_id, queue_id));
|
||||
pr_debug("%s setting CP_PQ_WPTR_POLL_CNTL1 to %x\n", __func__,
|
||||
(uint32_t)get_queue_mask(adev, pipe_id, queue_id));
|
||||
WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_PQ_WPTR_POLL_CNTL1),
|
||||
get_queue_mask(adev, pipe_id, queue_id));
|
||||
(uint32_t)get_queue_mask(adev, pipe_id, queue_id));
|
||||
}
|
||||
|
||||
/* Start the EOP fetcher */
|
||||
@ -350,6 +336,59 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kgd_hiq_mqd_load(struct kgd_dev *kgd, void *mqd,
|
||||
uint32_t pipe_id, uint32_t queue_id,
|
||||
uint32_t doorbell_off)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring;
|
||||
struct v10_compute_mqd *m;
|
||||
uint32_t mec, pipe;
|
||||
int r;
|
||||
|
||||
m = get_mqd(mqd);
|
||||
|
||||
acquire_queue(kgd, pipe_id, queue_id);
|
||||
|
||||
mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
|
||||
pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
|
||||
|
||||
pr_debug("kfd: set HIQ, mec:%d, pipe:%d, queue:%d.\n",
|
||||
mec, pipe, queue_id);
|
||||
|
||||
spin_lock(&adev->gfx.kiq.ring_lock);
|
||||
r = amdgpu_ring_alloc(kiq_ring, 7);
|
||||
if (r) {
|
||||
pr_err("Failed to alloc KIQ (%d).\n", r);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_MAP_QUEUES, 5));
|
||||
amdgpu_ring_write(kiq_ring,
|
||||
PACKET3_MAP_QUEUES_QUEUE_SEL(0) | /* Queue_Sel */
|
||||
PACKET3_MAP_QUEUES_VMID(m->cp_hqd_vmid) | /* VMID */
|
||||
PACKET3_MAP_QUEUES_QUEUE(queue_id) |
|
||||
PACKET3_MAP_QUEUES_PIPE(pipe) |
|
||||
PACKET3_MAP_QUEUES_ME((mec - 1)) |
|
||||
PACKET3_MAP_QUEUES_QUEUE_TYPE(0) | /*queue_type: normal compute queue */
|
||||
PACKET3_MAP_QUEUES_ALLOC_FORMAT(0) | /* alloc format: all_on_one_pipe */
|
||||
PACKET3_MAP_QUEUES_ENGINE_SEL(1) | /* engine_sel: hiq */
|
||||
PACKET3_MAP_QUEUES_NUM_QUEUES(1)); /* num_queues: must be 1 */
|
||||
amdgpu_ring_write(kiq_ring,
|
||||
PACKET3_MAP_QUEUES_DOORBELL_OFFSET(doorbell_off));
|
||||
amdgpu_ring_write(kiq_ring, m->cp_mqd_base_addr_lo);
|
||||
amdgpu_ring_write(kiq_ring, m->cp_mqd_base_addr_hi);
|
||||
amdgpu_ring_write(kiq_ring, m->cp_hqd_pq_wptr_poll_addr_lo);
|
||||
amdgpu_ring_write(kiq_ring, m->cp_hqd_pq_wptr_poll_addr_hi);
|
||||
amdgpu_ring_commit(kiq_ring);
|
||||
|
||||
out_unlock:
|
||||
spin_unlock(&adev->gfx.kiq.ring_lock);
|
||||
release_queue(kgd);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int kgd_hqd_dump(struct kgd_dev *kgd,
|
||||
uint32_t pipe_id, uint32_t queue_id,
|
||||
uint32_t (**dump)[2], uint32_t *n_regs)
|
||||
@ -686,71 +725,6 @@ static bool get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd,
|
||||
return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
|
||||
}
|
||||
|
||||
static int invalidate_tlbs_with_kiq(struct amdgpu_device *adev, uint16_t pasid)
|
||||
{
|
||||
signed long r;
|
||||
uint32_t seq;
|
||||
struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
|
||||
|
||||
spin_lock(&adev->gfx.kiq.ring_lock);
|
||||
amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
|
||||
amdgpu_ring_write(ring,
|
||||
PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
|
||||
PACKET3_INVALIDATE_TLBS_PASID(pasid));
|
||||
amdgpu_fence_emit_polling(ring, &seq);
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock(&adev->gfx.kiq.ring_lock);
|
||||
|
||||
r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
|
||||
if (r < 1) {
|
||||
DRM_ERROR("wait for kiq fence error: %ld.\n", r);
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
|
||||
int vmid;
|
||||
uint16_t queried_pasid;
|
||||
bool ret;
|
||||
struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
|
||||
|
||||
if (amdgpu_emu_mode == 0 && ring->sched.ready)
|
||||
return invalidate_tlbs_with_kiq(adev, pasid);
|
||||
|
||||
for (vmid = 0; vmid < 16; vmid++) {
|
||||
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid))
|
||||
continue;
|
||||
|
||||
ret = get_atc_vmid_pasid_mapping_info(kgd, vmid,
|
||||
&queried_pasid);
|
||||
if (ret && queried_pasid == pasid) {
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid,
|
||||
AMDGPU_GFXHUB_0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
|
||||
|
||||
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
|
||||
pr_err("non kfd vmid %d\n", vmid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid, AMDGPU_GFXHUB_0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kgd_address_watch_disable(struct kgd_dev *kgd)
|
||||
{
|
||||
return 0;
|
||||
@ -817,6 +791,7 @@ const struct kfd2kgd_calls gfx_v10_kfd2kgd = {
|
||||
.set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping,
|
||||
.init_interrupts = kgd_init_interrupts,
|
||||
.hqd_load = kgd_hqd_load,
|
||||
.hiq_mqd_load = kgd_hiq_mqd_load,
|
||||
.hqd_sdma_load = kgd_hqd_sdma_load,
|
||||
.hqd_dump = kgd_hqd_dump,
|
||||
.hqd_sdma_dump = kgd_hqd_sdma_dump,
|
||||
@ -832,7 +807,5 @@ const struct kfd2kgd_calls gfx_v10_kfd2kgd = {
|
||||
get_atc_vmid_pasid_mapping_info,
|
||||
.get_tile_config = amdgpu_amdkfd_get_tile_config,
|
||||
.set_vm_context_page_table_base = set_vm_context_page_table_base,
|
||||
.invalidate_tlbs = invalidate_tlbs,
|
||||
.invalidate_tlbs_vmid = invalidate_tlbs_vmid,
|
||||
.get_hive_id = amdgpu_amdkfd_get_hive_id,
|
||||
};
|
||||
|
@ -696,45 +696,6 @@ static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
|
||||
lower_32_bits(page_table_base));
|
||||
}
|
||||
|
||||
static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
|
||||
int vmid;
|
||||
unsigned int tmp;
|
||||
|
||||
if (adev->in_gpu_reset)
|
||||
return -EIO;
|
||||
|
||||
for (vmid = 0; vmid < 16; vmid++) {
|
||||
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid))
|
||||
continue;
|
||||
|
||||
tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
|
||||
if ((tmp & ATC_VMID0_PASID_MAPPING__VALID_MASK) &&
|
||||
(tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid) {
|
||||
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
|
||||
RREG32(mmVM_INVALIDATE_RESPONSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
|
||||
|
||||
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
|
||||
pr_err("non kfd vmid\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
|
||||
RREG32(mmVM_INVALIDATE_RESPONSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* read_vmid_from_vmfault_reg - read vmid from register
|
||||
*
|
||||
@ -771,7 +732,5 @@ const struct kfd2kgd_calls gfx_v7_kfd2kgd = {
|
||||
.set_scratch_backing_va = set_scratch_backing_va,
|
||||
.get_tile_config = get_tile_config,
|
||||
.set_vm_context_page_table_base = set_vm_context_page_table_base,
|
||||
.invalidate_tlbs = invalidate_tlbs,
|
||||
.invalidate_tlbs_vmid = invalidate_tlbs_vmid,
|
||||
.read_vmid_from_vmfault_reg = read_vmid_from_vmfault_reg,
|
||||
};
|
||||
|
@ -657,45 +657,6 @@ static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
|
||||
lower_32_bits(page_table_base));
|
||||
}
|
||||
|
||||
static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
|
||||
int vmid;
|
||||
unsigned int tmp;
|
||||
|
||||
if (adev->in_gpu_reset)
|
||||
return -EIO;
|
||||
|
||||
for (vmid = 0; vmid < 16; vmid++) {
|
||||
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid))
|
||||
continue;
|
||||
|
||||
tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
|
||||
if ((tmp & ATC_VMID0_PASID_MAPPING__VALID_MASK) &&
|
||||
(tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid) {
|
||||
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
|
||||
RREG32(mmVM_INVALIDATE_RESPONSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
|
||||
|
||||
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
|
||||
pr_err("non kfd vmid %d\n", vmid);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
|
||||
RREG32(mmVM_INVALIDATE_RESPONSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct kfd2kgd_calls gfx_v8_kfd2kgd = {
|
||||
.program_sh_mem_settings = kgd_program_sh_mem_settings,
|
||||
.set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping,
|
||||
@ -717,6 +678,4 @@ const struct kfd2kgd_calls gfx_v8_kfd2kgd = {
|
||||
.set_scratch_backing_va = set_scratch_backing_va,
|
||||
.get_tile_config = get_tile_config,
|
||||
.set_vm_context_page_table_base = set_vm_context_page_table_base,
|
||||
.invalidate_tlbs = invalidate_tlbs,
|
||||
.invalidate_tlbs_vmid = invalidate_tlbs_vmid,
|
||||
};
|
||||
|
@ -103,13 +103,13 @@ static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id,
|
||||
lock_srbm(kgd, mec, pipe, queue_id, 0);
|
||||
}
|
||||
|
||||
static uint32_t get_queue_mask(struct amdgpu_device *adev,
|
||||
static uint64_t get_queue_mask(struct amdgpu_device *adev,
|
||||
uint32_t pipe_id, uint32_t queue_id)
|
||||
{
|
||||
unsigned int bit = (pipe_id * adev->gfx.mec.num_queue_per_pipe +
|
||||
queue_id) & 31;
|
||||
unsigned int bit = pipe_id * adev->gfx.mec.num_queue_per_pipe +
|
||||
queue_id;
|
||||
|
||||
return ((uint32_t)1) << bit;
|
||||
return 1ull << bit;
|
||||
}
|
||||
|
||||
static void release_queue(struct kgd_dev *kgd)
|
||||
@ -258,21 +258,6 @@ int kgd_gfx_v9_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
|
||||
|
||||
acquire_queue(kgd, pipe_id, queue_id);
|
||||
|
||||
/* HIQ is set during driver init period with vmid set to 0*/
|
||||
if (m->cp_hqd_vmid == 0) {
|
||||
uint32_t value, mec, pipe;
|
||||
|
||||
mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
|
||||
pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
|
||||
|
||||
pr_debug("kfd: set HIQ, mec:%d, pipe:%d, queue:%d.\n",
|
||||
mec, pipe, queue_id);
|
||||
value = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_CP_SCHEDULERS));
|
||||
value = REG_SET_FIELD(value, RLC_CP_SCHEDULERS, scheduler1,
|
||||
((mec << 5) | (pipe << 3) | queue_id | 0x80));
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmRLC_CP_SCHEDULERS), value);
|
||||
}
|
||||
|
||||
/* HQD registers extend from CP_MQD_BASE_ADDR to CP_HQD_EOP_WPTR_MEM. */
|
||||
mqd_hqd = &m->cp_mqd_base_addr_lo;
|
||||
hqd_base = SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR);
|
||||
@ -323,7 +308,7 @@ int kgd_gfx_v9_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI),
|
||||
upper_32_bits((uintptr_t)wptr));
|
||||
WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_PQ_WPTR_POLL_CNTL1),
|
||||
get_queue_mask(adev, pipe_id, queue_id));
|
||||
(uint32_t)get_queue_mask(adev, pipe_id, queue_id));
|
||||
}
|
||||
|
||||
/* Start the EOP fetcher */
|
||||
@ -339,6 +324,59 @@ int kgd_gfx_v9_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kgd_gfx_v9_hiq_mqd_load(struct kgd_dev *kgd, void *mqd,
|
||||
uint32_t pipe_id, uint32_t queue_id,
|
||||
uint32_t doorbell_off)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring;
|
||||
struct v9_mqd *m;
|
||||
uint32_t mec, pipe;
|
||||
int r;
|
||||
|
||||
m = get_mqd(mqd);
|
||||
|
||||
acquire_queue(kgd, pipe_id, queue_id);
|
||||
|
||||
mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
|
||||
pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
|
||||
|
||||
pr_debug("kfd: set HIQ, mec:%d, pipe:%d, queue:%d.\n",
|
||||
mec, pipe, queue_id);
|
||||
|
||||
spin_lock(&adev->gfx.kiq.ring_lock);
|
||||
r = amdgpu_ring_alloc(kiq_ring, 7);
|
||||
if (r) {
|
||||
pr_err("Failed to alloc KIQ (%d).\n", r);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_MAP_QUEUES, 5));
|
||||
amdgpu_ring_write(kiq_ring,
|
||||
PACKET3_MAP_QUEUES_QUEUE_SEL(0) | /* Queue_Sel */
|
||||
PACKET3_MAP_QUEUES_VMID(m->cp_hqd_vmid) | /* VMID */
|
||||
PACKET3_MAP_QUEUES_QUEUE(queue_id) |
|
||||
PACKET3_MAP_QUEUES_PIPE(pipe) |
|
||||
PACKET3_MAP_QUEUES_ME((mec - 1)) |
|
||||
PACKET3_MAP_QUEUES_QUEUE_TYPE(0) | /*queue_type: normal compute queue */
|
||||
PACKET3_MAP_QUEUES_ALLOC_FORMAT(0) | /* alloc format: all_on_one_pipe */
|
||||
PACKET3_MAP_QUEUES_ENGINE_SEL(1) | /* engine_sel: hiq */
|
||||
PACKET3_MAP_QUEUES_NUM_QUEUES(1)); /* num_queues: must be 1 */
|
||||
amdgpu_ring_write(kiq_ring,
|
||||
PACKET3_MAP_QUEUES_DOORBELL_OFFSET(doorbell_off));
|
||||
amdgpu_ring_write(kiq_ring, m->cp_mqd_base_addr_lo);
|
||||
amdgpu_ring_write(kiq_ring, m->cp_mqd_base_addr_hi);
|
||||
amdgpu_ring_write(kiq_ring, m->cp_hqd_pq_wptr_poll_addr_lo);
|
||||
amdgpu_ring_write(kiq_ring, m->cp_hqd_pq_wptr_poll_addr_hi);
|
||||
amdgpu_ring_commit(kiq_ring);
|
||||
|
||||
out_unlock:
|
||||
spin_unlock(&adev->gfx.kiq.ring_lock);
|
||||
release_queue(kgd);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int kgd_gfx_v9_hqd_dump(struct kgd_dev *kgd,
|
||||
uint32_t pipe_id, uint32_t queue_id,
|
||||
uint32_t (**dump)[2], uint32_t *n_regs)
|
||||
@ -617,100 +655,6 @@ bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd,
|
||||
return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
|
||||
}
|
||||
|
||||
static int invalidate_tlbs_with_kiq(struct amdgpu_device *adev, uint16_t pasid,
|
||||
uint32_t flush_type)
|
||||
{
|
||||
signed long r;
|
||||
uint32_t seq;
|
||||
struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
|
||||
|
||||
spin_lock(&adev->gfx.kiq.ring_lock);
|
||||
amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
|
||||
amdgpu_ring_write(ring,
|
||||
PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
|
||||
PACKET3_INVALIDATE_TLBS_ALL_HUB(1) |
|
||||
PACKET3_INVALIDATE_TLBS_PASID(pasid) |
|
||||
PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type));
|
||||
amdgpu_fence_emit_polling(ring, &seq);
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock(&adev->gfx.kiq.ring_lock);
|
||||
|
||||
r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
|
||||
if (r < 1) {
|
||||
DRM_ERROR("wait for kiq fence error: %ld.\n", r);
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kgd_gfx_v9_invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
|
||||
int vmid, i;
|
||||
uint16_t queried_pasid;
|
||||
bool ret;
|
||||
struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
|
||||
uint32_t flush_type = 0;
|
||||
|
||||
if (adev->in_gpu_reset)
|
||||
return -EIO;
|
||||
if (adev->gmc.xgmi.num_physical_nodes &&
|
||||
adev->asic_type == CHIP_VEGA20)
|
||||
flush_type = 2;
|
||||
|
||||
if (ring->sched.ready)
|
||||
return invalidate_tlbs_with_kiq(adev, pasid, flush_type);
|
||||
|
||||
for (vmid = 0; vmid < 16; vmid++) {
|
||||
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid))
|
||||
continue;
|
||||
|
||||
ret = kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(kgd, vmid,
|
||||
&queried_pasid);
|
||||
if (ret && queried_pasid == pasid) {
|
||||
for (i = 0; i < adev->num_vmhubs; i++)
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid,
|
||||
i, flush_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kgd_gfx_v9_invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
|
||||
int i;
|
||||
|
||||
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
|
||||
pr_err("non kfd vmid %d\n", vmid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use legacy mode tlb invalidation.
|
||||
*
|
||||
* Currently on Raven the code below is broken for anything but
|
||||
* legacy mode due to a MMHUB power gating problem. A workaround
|
||||
* is for MMHUB to wait until the condition PER_VMID_INVALIDATE_REQ
|
||||
* == PER_VMID_INVALIDATE_ACK instead of simply waiting for the ack
|
||||
* bit.
|
||||
*
|
||||
* TODO 1: agree on the right set of invalidation registers for
|
||||
* KFD use. Use the last one for now. Invalidate both GC and
|
||||
* MMHUB.
|
||||
*
|
||||
* TODO 2: support range-based invalidation, requires kfg2kgd
|
||||
* interface change
|
||||
*/
|
||||
for (i = 0; i < adev->num_vmhubs; i++)
|
||||
amdgpu_gmc_flush_gpu_tlb(adev, vmid, i, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kgd_gfx_v9_address_watch_disable(struct kgd_dev *kgd)
|
||||
{
|
||||
return 0;
|
||||
@ -778,6 +722,7 @@ const struct kfd2kgd_calls gfx_v9_kfd2kgd = {
|
||||
.set_pasid_vmid_mapping = kgd_gfx_v9_set_pasid_vmid_mapping,
|
||||
.init_interrupts = kgd_gfx_v9_init_interrupts,
|
||||
.hqd_load = kgd_gfx_v9_hqd_load,
|
||||
.hiq_mqd_load = kgd_gfx_v9_hiq_mqd_load,
|
||||
.hqd_sdma_load = kgd_hqd_sdma_load,
|
||||
.hqd_dump = kgd_gfx_v9_hqd_dump,
|
||||
.hqd_sdma_dump = kgd_hqd_sdma_dump,
|
||||
@ -793,7 +738,5 @@ const struct kfd2kgd_calls gfx_v9_kfd2kgd = {
|
||||
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
|
||||
.get_tile_config = kgd_gfx_v9_get_tile_config,
|
||||
.set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base,
|
||||
.invalidate_tlbs = kgd_gfx_v9_invalidate_tlbs,
|
||||
.invalidate_tlbs_vmid = kgd_gfx_v9_invalidate_tlbs_vmid,
|
||||
.get_hive_id = amdgpu_amdkfd_get_hive_id,
|
||||
};
|
||||
|
@ -33,6 +33,9 @@ int kgd_gfx_v9_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
|
||||
uint32_t queue_id, uint32_t __user *wptr,
|
||||
uint32_t wptr_shift, uint32_t wptr_mask,
|
||||
struct mm_struct *mm);
|
||||
int kgd_gfx_v9_hiq_mqd_load(struct kgd_dev *kgd, void *mqd,
|
||||
uint32_t pipe_id, uint32_t queue_id,
|
||||
uint32_t doorbell_off);
|
||||
int kgd_gfx_v9_hqd_dump(struct kgd_dev *kgd,
|
||||
uint32_t pipe_id, uint32_t queue_id,
|
||||
uint32_t (**dump)[2], uint32_t *n_regs);
|
||||
@ -57,7 +60,5 @@ uint32_t kgd_gfx_v9_address_watch_get_offset(struct kgd_dev *kgd,
|
||||
|
||||
bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd,
|
||||
uint8_t vmid, uint16_t *p_pasid);
|
||||
int kgd_gfx_v9_invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid);
|
||||
int kgd_gfx_v9_invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid);
|
||||
int kgd_gfx_v9_get_tile_config(struct kgd_dev *kgd,
|
||||
struct tile_config *config);
|
||||
|
@ -909,6 +909,11 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
|
||||
if (parser->entity && parser->entity != entity)
|
||||
return -EINVAL;
|
||||
|
||||
/* Return if there is no run queue associated with this entity.
|
||||
* Possibly because of disabled HW IP*/
|
||||
if (entity->rq == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
parser->entity = entity;
|
||||
|
||||
ring = to_amdgpu_ring(entity->rq->sched);
|
||||
@ -1229,7 +1234,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
|
||||
goto error_abort;
|
||||
}
|
||||
|
||||
job->owner = p->filp;
|
||||
p->fence = dma_fence_get(&job->base.s_fence->finished);
|
||||
|
||||
amdgpu_ctx_add_fence(p->ctx, entity, p->fence, &seq);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <drm/drm_debugfs.h>
|
||||
|
||||
@ -144,10 +145,17 @@ static int amdgpu_debugfs_process_reg_op(bool read, struct file *f,
|
||||
|
||||
*pos &= (1UL << 22) - 1;
|
||||
|
||||
r = pm_runtime_get_sync(adev->ddev->dev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (use_bank) {
|
||||
if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||
|
||||
(se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines))
|
||||
(se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines)) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
amdgpu_gfx_select_se_sh(adev, se_bank,
|
||||
sh_bank, instance_bank);
|
||||
@ -193,6 +201,9 @@ end:
|
||||
if (pm_pg_lock)
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -237,13 +248,20 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
|
||||
if (size & 0x3 || *pos & 0x3)
|
||||
return -EINVAL;
|
||||
|
||||
r = pm_runtime_get_sync(adev->ddev->dev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
value = RREG32_PCIE(*pos >> 2);
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r)
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
result += 4;
|
||||
buf += 4;
|
||||
@ -251,6 +269,9 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -276,12 +297,19 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user
|
||||
if (size & 0x3 || *pos & 0x3)
|
||||
return -EINVAL;
|
||||
|
||||
r = pm_runtime_get_sync(adev->ddev->dev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
r = get_user(value, (uint32_t *)buf);
|
||||
if (r)
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
WREG32_PCIE(*pos >> 2, value);
|
||||
|
||||
@ -291,6 +319,9 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -316,13 +347,20 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
|
||||
if (size & 0x3 || *pos & 0x3)
|
||||
return -EINVAL;
|
||||
|
||||
r = pm_runtime_get_sync(adev->ddev->dev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
value = RREG32_DIDT(*pos >> 2);
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r)
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
result += 4;
|
||||
buf += 4;
|
||||
@ -330,6 +368,9 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -355,12 +396,19 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user
|
||||
if (size & 0x3 || *pos & 0x3)
|
||||
return -EINVAL;
|
||||
|
||||
r = pm_runtime_get_sync(adev->ddev->dev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
r = get_user(value, (uint32_t *)buf);
|
||||
if (r)
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
WREG32_DIDT(*pos >> 2, value);
|
||||
|
||||
@ -370,6 +418,9 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -395,13 +446,20 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
|
||||
if (size & 0x3 || *pos & 0x3)
|
||||
return -EINVAL;
|
||||
|
||||
r = pm_runtime_get_sync(adev->ddev->dev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
value = RREG32_SMC(*pos);
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r)
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
result += 4;
|
||||
buf += 4;
|
||||
@ -409,6 +467,9 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -434,12 +495,19 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
|
||||
if (size & 0x3 || *pos & 0x3)
|
||||
return -EINVAL;
|
||||
|
||||
r = pm_runtime_get_sync(adev->ddev->dev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
r = get_user(value, (uint32_t *)buf);
|
||||
if (r)
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
WREG32_SMC(*pos, value);
|
||||
|
||||
@ -449,6 +517,9 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -572,7 +643,16 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
|
||||
idx = *pos >> 2;
|
||||
|
||||
valuesize = sizeof(values);
|
||||
|
||||
r = pm_runtime_get_sync(adev->ddev->dev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize);
|
||||
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@ -633,6 +713,10 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
|
||||
wave = (*pos & GENMASK_ULL(36, 31)) >> 31;
|
||||
simd = (*pos & GENMASK_ULL(44, 37)) >> 37;
|
||||
|
||||
r = pm_runtime_get_sync(adev->ddev->dev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* switch to the specific se/sh/cu */
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
amdgpu_gfx_select_se_sh(adev, se, sh, cu);
|
||||
@ -644,6 +728,9 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
|
||||
amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
if (!x)
|
||||
return -EINVAL;
|
||||
|
||||
@ -711,6 +798,10 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
r = pm_runtime_get_sync(adev->ddev->dev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* switch to the specific se/sh/cu */
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
amdgpu_gfx_select_se_sh(adev, se, sh, cu);
|
||||
@ -726,6 +817,9 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
|
||||
amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
@ -859,6 +953,10 @@ static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data)
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
int r = 0, i;
|
||||
|
||||
r = pm_runtime_get_sync(dev->dev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Avoid accidently unparking the sched thread during GPU reset */
|
||||
mutex_lock(&adev->lock_reset);
|
||||
|
||||
@ -889,6 +987,9 @@ static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data)
|
||||
|
||||
mutex_unlock(&adev->lock_reset);
|
||||
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -907,8 +1008,17 @@ static int amdgpu_debugfs_evict_vram(struct seq_file *m, void *data)
|
||||
struct drm_info_node *node = (struct drm_info_node *)m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
int r;
|
||||
|
||||
r = pm_runtime_get_sync(dev->dev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
seq_printf(m, "(%d)\n", amdgpu_bo_evict_vram(adev));
|
||||
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -917,8 +1027,17 @@ static int amdgpu_debugfs_evict_gtt(struct seq_file *m, void *data)
|
||||
struct drm_info_node *node = (struct drm_info_node *)m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
int r;
|
||||
|
||||
r = pm_runtime_get_sync(dev->dev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
seq_printf(m, "(%d)\n", ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_TT));
|
||||
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2345,14 +2345,7 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
|
||||
adev->ip_blocks[i].status.hw = false;
|
||||
/* handle putting the SMC in the appropriate state */
|
||||
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) {
|
||||
if (is_support_sw_smu(adev)) {
|
||||
r = smu_set_mp1_state(&adev->smu, adev->mp1_state);
|
||||
} else if (adev->powerplay.pp_funcs &&
|
||||
adev->powerplay.pp_funcs->set_mp1_state) {
|
||||
r = adev->powerplay.pp_funcs->set_mp1_state(
|
||||
adev->powerplay.pp_handle,
|
||||
adev->mp1_state);
|
||||
}
|
||||
r = amdgpu_dpm_set_mp1_state(adev, adev->mp1_state);
|
||||
if (r) {
|
||||
DRM_ERROR("SMC failed to set mp1 state %d, %d\n",
|
||||
adev->mp1_state, r);
|
||||
@ -2855,6 +2848,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||
hash_init(adev->mn_hash);
|
||||
mutex_init(&adev->lock_reset);
|
||||
mutex_init(&adev->psp.mutex);
|
||||
mutex_init(&adev->notifier_lock);
|
||||
|
||||
r = amdgpu_device_check_arguments(adev);
|
||||
if (r)
|
||||
@ -3765,6 +3759,7 @@ bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev)
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_ARCTURUS:
|
||||
break;
|
||||
default:
|
||||
goto disabled;
|
||||
@ -4359,55 +4354,21 @@ int amdgpu_device_baco_enter(struct drm_device *dev)
|
||||
if (ras && ras->supported)
|
||||
adev->nbio.funcs->enable_doorbell_interrupt(adev, false);
|
||||
|
||||
if (is_support_sw_smu(adev)) {
|
||||
struct smu_context *smu = &adev->smu;
|
||||
int ret;
|
||||
|
||||
ret = smu_baco_enter(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
void *pp_handle = adev->powerplay.pp_handle;
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
|
||||
if (!pp_funcs ||!pp_funcs->get_asic_baco_state ||!pp_funcs->set_asic_baco_state)
|
||||
return -ENOENT;
|
||||
|
||||
/* enter BACO state */
|
||||
if (pp_funcs->set_asic_baco_state(pp_handle, 1))
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return amdgpu_dpm_baco_enter(adev);
|
||||
}
|
||||
|
||||
int amdgpu_device_baco_exit(struct drm_device *dev)
|
||||
{
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
|
||||
int ret = 0;
|
||||
|
||||
if (!amdgpu_device_supports_baco(adev->ddev))
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (is_support_sw_smu(adev)) {
|
||||
struct smu_context *smu = &adev->smu;
|
||||
int ret;
|
||||
|
||||
ret = smu_baco_exit(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
} else {
|
||||
void *pp_handle = adev->powerplay.pp_handle;
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
|
||||
if (!pp_funcs ||!pp_funcs->get_asic_baco_state ||!pp_funcs->set_asic_baco_state)
|
||||
return -ENOENT;
|
||||
|
||||
/* exit BACO state */
|
||||
if (pp_funcs->set_asic_baco_state(pp_handle, 0))
|
||||
return -EIO;
|
||||
}
|
||||
ret = amdgpu_dpm_baco_exit(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (ras && ras->supported)
|
||||
adev->nbio.funcs->enable_doorbell_interrupt(adev, true);
|
||||
|
62
drivers/gpu/drm/amd/amdgpu/amdgpu_df.h
Normal file
62
drivers/gpu/drm/amd/amdgpu/amdgpu_df.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2020 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __AMDGPU_DF_H__
|
||||
#define __AMDGPU_DF_H__
|
||||
|
||||
struct amdgpu_df_hash_status {
|
||||
bool hash_64k;
|
||||
bool hash_2m;
|
||||
bool hash_1g;
|
||||
};
|
||||
|
||||
struct amdgpu_df_funcs {
|
||||
void (*sw_init)(struct amdgpu_device *adev);
|
||||
void (*sw_fini)(struct amdgpu_device *adev);
|
||||
void (*enable_broadcast_mode)(struct amdgpu_device *adev,
|
||||
bool enable);
|
||||
u32 (*get_fb_channel_number)(struct amdgpu_device *adev);
|
||||
u32 (*get_hbm_channel_number)(struct amdgpu_device *adev);
|
||||
void (*update_medium_grain_clock_gating)(struct amdgpu_device *adev,
|
||||
bool enable);
|
||||
void (*get_clockgating_state)(struct amdgpu_device *adev,
|
||||
u32 *flags);
|
||||
void (*enable_ecc_force_par_wr_rmw)(struct amdgpu_device *adev,
|
||||
bool enable);
|
||||
int (*pmc_start)(struct amdgpu_device *adev, uint64_t config,
|
||||
int is_enable);
|
||||
int (*pmc_stop)(struct amdgpu_device *adev, uint64_t config,
|
||||
int is_disable);
|
||||
void (*pmc_get_count)(struct amdgpu_device *adev, uint64_t config,
|
||||
uint64_t *count);
|
||||
uint64_t (*get_fica)(struct amdgpu_device *adev, uint32_t ficaa_val);
|
||||
void (*set_fica)(struct amdgpu_device *adev, uint32_t ficaa_val,
|
||||
uint32_t ficadl_val, uint32_t ficadh_val);
|
||||
};
|
||||
|
||||
struct amdgpu_df {
|
||||
struct amdgpu_df_hash_status hash_status;
|
||||
const struct amdgpu_df_funcs *funcs;
|
||||
};
|
||||
|
||||
#endif /* __AMDGPU_DF_H__ */
|
@ -513,13 +513,23 @@ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
|
||||
* will not allow USWC mappings.
|
||||
* Also, don't allow GTT domain if the BO doens't have USWC falg set.
|
||||
*/
|
||||
if (adev->asic_type >= CHIP_CARRIZO &&
|
||||
adev->asic_type < CHIP_RAVEN &&
|
||||
(adev->flags & AMD_IS_APU) &&
|
||||
(bo_flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC) &&
|
||||
if ((bo_flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC) &&
|
||||
amdgpu_bo_support_uswc(bo_flags) &&
|
||||
amdgpu_device_asic_has_dc_support(adev->asic_type))
|
||||
domain |= AMDGPU_GEM_DOMAIN_GTT;
|
||||
amdgpu_device_asic_has_dc_support(adev->asic_type)) {
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
domain |= AMDGPU_GEM_DOMAIN_GTT;
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
/* enable S/G on PCO and RV2 */
|
||||
if (adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8)
|
||||
domain |= AMDGPU_GEM_DOMAIN_GTT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return domain;
|
||||
|
@ -946,23 +946,54 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block
|
||||
bool swsmu = is_support_sw_smu(adev);
|
||||
|
||||
switch (block_type) {
|
||||
case AMD_IP_BLOCK_TYPE_GFX:
|
||||
case AMD_IP_BLOCK_TYPE_UVD:
|
||||
case AMD_IP_BLOCK_TYPE_VCN:
|
||||
case AMD_IP_BLOCK_TYPE_VCE:
|
||||
case AMD_IP_BLOCK_TYPE_SDMA:
|
||||
if (swsmu) {
|
||||
ret = smu_dpm_set_power_gate(&adev->smu, block_type, gate);
|
||||
} else {
|
||||
if (adev->powerplay.pp_funcs &&
|
||||
adev->powerplay.pp_funcs->set_powergating_by_smu) {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
ret = ((adev)->powerplay.pp_funcs->set_powergating_by_smu(
|
||||
(adev)->powerplay.pp_handle, block_type, gate));
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
}
|
||||
} else if (adev->powerplay.pp_funcs &&
|
||||
adev->powerplay.pp_funcs->set_powergating_by_smu) {
|
||||
/*
|
||||
* TODO: need a better lock mechanism
|
||||
*
|
||||
* Here adev->pm.mutex lock protection is enforced on
|
||||
* UVD and VCE cases only. Since for other cases, there
|
||||
* may be already lock protection in amdgpu_pm.c.
|
||||
* This is a quick fix for the deadlock issue below.
|
||||
* NFO: task ocltst:2028 blocked for more than 120 seconds.
|
||||
* Tainted: G OE 5.0.0-37-generic #40~18.04.1-Ubuntu
|
||||
* echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
|
||||
* cltst D 0 2028 2026 0x00000000
|
||||
* all Trace:
|
||||
* __schedule+0x2c0/0x870
|
||||
* schedule+0x2c/0x70
|
||||
* schedule_preempt_disabled+0xe/0x10
|
||||
* __mutex_lock.isra.9+0x26d/0x4e0
|
||||
* __mutex_lock_slowpath+0x13/0x20
|
||||
* ? __mutex_lock_slowpath+0x13/0x20
|
||||
* mutex_lock+0x2f/0x40
|
||||
* amdgpu_dpm_set_powergating_by_smu+0x64/0xe0 [amdgpu]
|
||||
* gfx_v8_0_enable_gfx_static_mg_power_gating+0x3c/0x70 [amdgpu]
|
||||
* gfx_v8_0_set_powergating_state+0x66/0x260 [amdgpu]
|
||||
* amdgpu_device_ip_set_powergating_state+0x62/0xb0 [amdgpu]
|
||||
* pp_dpm_force_performance_level+0xe7/0x100 [amdgpu]
|
||||
* amdgpu_set_dpm_forced_performance_level+0x129/0x330 [amdgpu]
|
||||
*/
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
ret = ((adev)->powerplay.pp_funcs->set_powergating_by_smu(
|
||||
(adev)->powerplay.pp_handle, block_type, gate));
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
}
|
||||
break;
|
||||
case AMD_IP_BLOCK_TYPE_GFX:
|
||||
case AMD_IP_BLOCK_TYPE_VCN:
|
||||
case AMD_IP_BLOCK_TYPE_SDMA:
|
||||
if (swsmu)
|
||||
ret = smu_dpm_set_power_gate(&adev->smu, block_type, gate);
|
||||
else if (adev->powerplay.pp_funcs &&
|
||||
adev->powerplay.pp_funcs->set_powergating_by_smu)
|
||||
ret = ((adev)->powerplay.pp_funcs->set_powergating_by_smu(
|
||||
(adev)->powerplay.pp_handle, block_type, gate));
|
||||
break;
|
||||
case AMD_IP_BLOCK_TYPE_JPEG:
|
||||
if (swsmu)
|
||||
ret = smu_dpm_set_power_gate(&adev->smu, block_type, gate);
|
||||
@ -970,12 +1001,9 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block
|
||||
case AMD_IP_BLOCK_TYPE_GMC:
|
||||
case AMD_IP_BLOCK_TYPE_ACP:
|
||||
if (adev->powerplay.pp_funcs &&
|
||||
adev->powerplay.pp_funcs->set_powergating_by_smu) {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
adev->powerplay.pp_funcs->set_powergating_by_smu)
|
||||
ret = ((adev)->powerplay.pp_funcs->set_powergating_by_smu(
|
||||
(adev)->powerplay.pp_handle, block_type, gate));
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -983,3 +1011,163 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_dpm_baco_enter(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
void *pp_handle = adev->powerplay.pp_handle;
|
||||
struct smu_context *smu = &adev->smu;
|
||||
int ret = 0;
|
||||
|
||||
if (is_support_sw_smu(adev)) {
|
||||
ret = smu_baco_enter(smu);
|
||||
} else {
|
||||
if (!pp_funcs || !pp_funcs->set_asic_baco_state)
|
||||
return -ENOENT;
|
||||
|
||||
/* enter BACO state */
|
||||
ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_dpm_baco_exit(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
void *pp_handle = adev->powerplay.pp_handle;
|
||||
struct smu_context *smu = &adev->smu;
|
||||
int ret = 0;
|
||||
|
||||
if (is_support_sw_smu(adev)) {
|
||||
ret = smu_baco_exit(smu);
|
||||
} else {
|
||||
if (!pp_funcs || !pp_funcs->set_asic_baco_state)
|
||||
return -ENOENT;
|
||||
|
||||
/* exit BACO state */
|
||||
ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
|
||||
enum pp_mp1_state mp1_state)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (is_support_sw_smu(adev)) {
|
||||
ret = smu_set_mp1_state(&adev->smu, mp1_state);
|
||||
} else if (adev->powerplay.pp_funcs &&
|
||||
adev->powerplay.pp_funcs->set_mp1_state) {
|
||||
ret = adev->powerplay.pp_funcs->set_mp1_state(
|
||||
adev->powerplay.pp_handle,
|
||||
mp1_state);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
void *pp_handle = adev->powerplay.pp_handle;
|
||||
struct smu_context *smu = &adev->smu;
|
||||
bool baco_cap;
|
||||
|
||||
if (is_support_sw_smu(adev)) {
|
||||
return smu_baco_is_support(smu);
|
||||
} else {
|
||||
if (!pp_funcs || !pp_funcs->get_asic_baco_capability)
|
||||
return false;
|
||||
|
||||
if (pp_funcs->get_asic_baco_capability(pp_handle, &baco_cap))
|
||||
return false;
|
||||
|
||||
return baco_cap ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
void *pp_handle = adev->powerplay.pp_handle;
|
||||
struct smu_context *smu = &adev->smu;
|
||||
|
||||
if (is_support_sw_smu(adev)) {
|
||||
return smu_mode2_reset(smu);
|
||||
} else {
|
||||
if (!pp_funcs || !pp_funcs->asic_reset_mode_2)
|
||||
return -ENOENT;
|
||||
|
||||
return pp_funcs->asic_reset_mode_2(pp_handle);
|
||||
}
|
||||
}
|
||||
|
||||
int amdgpu_dpm_baco_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
void *pp_handle = adev->powerplay.pp_handle;
|
||||
struct smu_context *smu = &adev->smu;
|
||||
int ret = 0;
|
||||
|
||||
dev_info(adev->dev, "GPU BACO reset\n");
|
||||
|
||||
if (is_support_sw_smu(adev)) {
|
||||
ret = smu_baco_enter(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = smu_baco_exit(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
if (!pp_funcs
|
||||
|| !pp_funcs->set_asic_baco_state)
|
||||
return -ENOENT;
|
||||
|
||||
/* enter BACO state */
|
||||
ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* exit BACO state */
|
||||
ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
|
||||
enum PP_SMC_POWER_PROFILE type,
|
||||
bool en)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (is_support_sw_smu(adev))
|
||||
ret = smu_switch_power_profile(&adev->smu, type, en);
|
||||
else if (adev->powerplay.pp_funcs &&
|
||||
adev->powerplay.pp_funcs->switch_power_profile)
|
||||
ret = adev->powerplay.pp_funcs->switch_power_profile(
|
||||
adev->powerplay.pp_handle, type, en);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device *adev,
|
||||
uint32_t pstate)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (is_support_sw_smu_xgmi(adev))
|
||||
ret = smu_set_xgmi_pstate(&adev->smu, pstate);
|
||||
else if (adev->powerplay.pp_funcs &&
|
||||
adev->powerplay.pp_funcs->set_xgmi_pstate)
|
||||
ret = adev->powerplay.pp_funcs->set_xgmi_pstate(adev->powerplay.pp_handle,
|
||||
pstate);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -341,10 +341,6 @@ enum amdgpu_pcie_gen {
|
||||
((adev)->powerplay.pp_funcs->reset_power_profile_state(\
|
||||
(adev)->powerplay.pp_handle, request))
|
||||
|
||||
#define amdgpu_dpm_switch_power_profile(adev, type, en) \
|
||||
((adev)->powerplay.pp_funcs->switch_power_profile(\
|
||||
(adev)->powerplay.pp_handle, type, en))
|
||||
|
||||
#define amdgpu_dpm_set_clockgating_by_smu(adev, msg_id) \
|
||||
((adev)->powerplay.pp_funcs->set_clockgating_by_smu(\
|
||||
(adev)->powerplay.pp_handle, msg_id))
|
||||
@ -517,4 +513,24 @@ extern int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low);
|
||||
|
||||
extern int amdgpu_dpm_get_mclk(struct amdgpu_device *adev, bool low);
|
||||
|
||||
int amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device *adev,
|
||||
uint32_t pstate);
|
||||
|
||||
int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
|
||||
enum PP_SMC_POWER_PROFILE type,
|
||||
bool en);
|
||||
|
||||
int amdgpu_dpm_baco_reset(struct amdgpu_device *adev);
|
||||
|
||||
int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev);
|
||||
|
||||
bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev);
|
||||
|
||||
int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
|
||||
enum pp_mp1_state mp1_state);
|
||||
|
||||
int amdgpu_dpm_baco_exit(struct amdgpu_device *adev);
|
||||
|
||||
int amdgpu_dpm_baco_enter(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
@ -741,10 +741,18 @@ static int amdgpu_debugfs_gpu_recover(struct seq_file *m, void *data)
|
||||
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
int r;
|
||||
|
||||
r = pm_runtime_get_sync(dev->dev);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
seq_printf(m, "gpu recover\n");
|
||||
amdgpu_device_gpu_recover(adev, NULL);
|
||||
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -543,12 +543,6 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
|
||||
if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
|
||||
return;
|
||||
|
||||
if (!is_support_sw_smu(adev) &&
|
||||
(!adev->powerplay.pp_funcs ||
|
||||
!adev->powerplay.pp_funcs->set_powergating_by_smu))
|
||||
return;
|
||||
|
||||
|
||||
mutex_lock(&adev->gfx.gfx_off_mutex);
|
||||
|
||||
if (!enable)
|
||||
|
@ -76,11 +76,15 @@ struct kiq_pm4_funcs {
|
||||
struct amdgpu_ring *ring,
|
||||
u64 addr,
|
||||
u64 seq);
|
||||
void (*kiq_invalidate_tlbs)(struct amdgpu_ring *kiq_ring,
|
||||
uint16_t pasid, uint32_t flush_type,
|
||||
bool all_hub);
|
||||
/* Packet sizes */
|
||||
int set_resources_size;
|
||||
int map_queues_size;
|
||||
int unmap_queues_size;
|
||||
int query_status_size;
|
||||
int invalidate_tlbs_size;
|
||||
};
|
||||
|
||||
struct amdgpu_kiq {
|
||||
|
@ -60,6 +60,11 @@
|
||||
*/
|
||||
#define AMDGPU_GMC_FAULT_TIMEOUT 5000ULL
|
||||
|
||||
/*
|
||||
* Default stolen memory size, 1024 * 768 * 4
|
||||
*/
|
||||
#define AMDGPU_STOLEN_BIST_TRAINING_DEFAULT_SIZE 0x300000ULL
|
||||
|
||||
struct firmware;
|
||||
|
||||
/*
|
||||
@ -92,6 +97,9 @@ struct amdgpu_gmc_funcs {
|
||||
/* flush the vm tlb via mmio */
|
||||
void (*flush_gpu_tlb)(struct amdgpu_device *adev, uint32_t vmid,
|
||||
uint32_t vmhub, uint32_t flush_type);
|
||||
/* flush the vm tlb via pasid */
|
||||
int (*flush_gpu_tlb_pasid)(struct amdgpu_device *adev, uint16_t pasid,
|
||||
uint32_t flush_type, bool all_hub);
|
||||
/* flush the vm tlb via ring */
|
||||
uint64_t (*emit_flush_gpu_tlb)(struct amdgpu_ring *ring, unsigned vmid,
|
||||
uint64_t pd_addr);
|
||||
@ -216,6 +224,9 @@ struct amdgpu_gmc {
|
||||
};
|
||||
|
||||
#define amdgpu_gmc_flush_gpu_tlb(adev, vmid, vmhub, type) ((adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid), (vmhub), (type)))
|
||||
#define amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, type, allhub) \
|
||||
((adev)->gmc.gmc_funcs->flush_gpu_tlb_pasid \
|
||||
((adev), (pasid), (type), (allhub)))
|
||||
#define amdgpu_gmc_emit_flush_gpu_tlb(r, vmid, addr) (r)->adev->gmc.gmc_funcs->emit_flush_gpu_tlb((r), (vmid), (addr))
|
||||
#define amdgpu_gmc_emit_pasid_mapping(r, vmid, pasid) (r)->adev->gmc.gmc_funcs->emit_pasid_mapping((r), (vmid), (pasid))
|
||||
#define amdgpu_gmc_map_mtype(adev, flags) (adev)->gmc.gmc_funcs->map_mtype((adev),(flags))
|
||||
|
@ -153,7 +153,6 @@ int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
job->owner = owner;
|
||||
*f = dma_fence_get(&job->base.s_fence->finished);
|
||||
amdgpu_job_free_resources(job);
|
||||
priority = job->base.s_priority;
|
||||
|
@ -49,7 +49,6 @@ struct amdgpu_job {
|
||||
uint32_t preamble_status;
|
||||
uint32_t preemption_status;
|
||||
uint32_t num_ibs;
|
||||
void *owner;
|
||||
bool vm_needs_flush;
|
||||
uint64_t vm_pd_addr;
|
||||
unsigned vmid;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -74,9 +74,9 @@ static void amdgpu_perf_start(struct perf_event *event, int flags)
|
||||
switch (pe->pmu_perf_type) {
|
||||
case PERF_TYPE_AMDGPU_DF:
|
||||
if (!(flags & PERF_EF_RELOAD))
|
||||
pe->adev->df_funcs->pmc_start(pe->adev, hwc->conf, 1);
|
||||
pe->adev->df.funcs->pmc_start(pe->adev, hwc->conf, 1);
|
||||
|
||||
pe->adev->df_funcs->pmc_start(pe->adev, hwc->conf, 0);
|
||||
pe->adev->df.funcs->pmc_start(pe->adev, hwc->conf, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -101,7 +101,7 @@ static void amdgpu_perf_read(struct perf_event *event)
|
||||
|
||||
switch (pe->pmu_perf_type) {
|
||||
case PERF_TYPE_AMDGPU_DF:
|
||||
pe->adev->df_funcs->pmc_get_count(pe->adev, hwc->conf,
|
||||
pe->adev->df.funcs->pmc_get_count(pe->adev, hwc->conf,
|
||||
&count);
|
||||
break;
|
||||
default:
|
||||
@ -126,7 +126,7 @@ static void amdgpu_perf_stop(struct perf_event *event, int flags)
|
||||
|
||||
switch (pe->pmu_perf_type) {
|
||||
case PERF_TYPE_AMDGPU_DF:
|
||||
pe->adev->df_funcs->pmc_stop(pe->adev, hwc->conf, 0);
|
||||
pe->adev->df.funcs->pmc_stop(pe->adev, hwc->conf, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -156,7 +156,7 @@ static int amdgpu_perf_add(struct perf_event *event, int flags)
|
||||
|
||||
switch (pe->pmu_perf_type) {
|
||||
case PERF_TYPE_AMDGPU_DF:
|
||||
retval = pe->adev->df_funcs->pmc_start(pe->adev, hwc->conf, 1);
|
||||
retval = pe->adev->df.funcs->pmc_start(pe->adev, hwc->conf, 1);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
@ -184,7 +184,7 @@ static void amdgpu_perf_del(struct perf_event *event, int flags)
|
||||
|
||||
switch (pe->pmu_perf_type) {
|
||||
case PERF_TYPE_AMDGPU_DF:
|
||||
pe->adev->df_funcs->pmc_stop(pe->adev, hwc->conf, 1);
|
||||
pe->adev->df.funcs->pmc_stop(pe->adev, hwc->conf, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -529,6 +529,11 @@ static int psp_xgmi_unload(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
/* XGMI TA unload currently is not supported on Arcturus */
|
||||
if (adev->asic_type == CHIP_ARCTURUS)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* TODO: bypass the unloading in sriov for now
|
||||
|
@ -686,6 +686,7 @@ int amdgpu_ras_error_query(struct amdgpu_device *adev,
|
||||
{
|
||||
struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head);
|
||||
struct ras_err_data err_data = {0, 0, 0, NULL};
|
||||
int i;
|
||||
|
||||
if (!obj)
|
||||
return -EINVAL;
|
||||
@ -700,6 +701,13 @@ int amdgpu_ras_error_query(struct amdgpu_device *adev,
|
||||
if (adev->umc.funcs->query_ras_error_address)
|
||||
adev->umc.funcs->query_ras_error_address(adev, &err_data);
|
||||
break;
|
||||
case AMDGPU_RAS_BLOCK__SDMA:
|
||||
if (adev->sdma.funcs->query_ras_error_count) {
|
||||
for (i = 0; i < adev->sdma.num_instances; i++)
|
||||
adev->sdma.funcs->query_ras_error_count(adev, i,
|
||||
&err_data);
|
||||
}
|
||||
break;
|
||||
case AMDGPU_RAS_BLOCK__GFX:
|
||||
if (adev->gfx.funcs->query_ras_error_count)
|
||||
adev->gfx.funcs->query_ras_error_count(adev, &err_data);
|
||||
@ -1345,7 +1353,8 @@ static void amdgpu_ras_do_recovery(struct work_struct *work)
|
||||
struct amdgpu_ras *ras =
|
||||
container_of(work, struct amdgpu_ras, recovery_work);
|
||||
|
||||
amdgpu_device_gpu_recover(ras->adev, 0);
|
||||
if (amdgpu_device_should_recover_gpu(ras->adev))
|
||||
amdgpu_device_gpu_recover(ras->adev, 0);
|
||||
atomic_set(&ras->in_recovery, 0);
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,14 @@ struct amdgpu_sdma_instance {
|
||||
bool burst_nop;
|
||||
};
|
||||
|
||||
struct amdgpu_sdma_ras_funcs {
|
||||
int (*ras_late_init)(struct amdgpu_device *adev,
|
||||
void *ras_ih_info);
|
||||
void (*ras_fini)(struct amdgpu_device *adev);
|
||||
int (*query_ras_error_count)(struct amdgpu_device *adev,
|
||||
uint32_t instance, void *ras_error_status);
|
||||
};
|
||||
|
||||
struct amdgpu_sdma {
|
||||
struct amdgpu_sdma_instance instance[AMDGPU_MAX_SDMA_INSTANCES];
|
||||
struct drm_gpu_scheduler *sdma_sched[AMDGPU_MAX_SDMA_INSTANCES];
|
||||
@ -61,6 +69,7 @@ struct amdgpu_sdma {
|
||||
uint32_t srbm_soft_reset;
|
||||
bool has_page_queue;
|
||||
struct ras_common_if *ras_if;
|
||||
const struct amdgpu_sdma_ras_funcs *funcs;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <linux/swap.h>
|
||||
#include <linux/swiotlb.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/sizes.h>
|
||||
|
||||
#include <drm/ttm/ttm_bo_api.h>
|
||||
#include <drm/ttm/ttm_bo_driver.h>
|
||||
|
@ -75,6 +75,9 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
||||
break;
|
||||
case CHIP_ARCTURUS:
|
||||
fw_name = FIRMWARE_ARCTURUS;
|
||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||
adev->vcn.indirect_sram = true;
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
fw_name = FIRMWARE_RENOIR;
|
||||
@ -165,15 +168,15 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
||||
dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (adev->vcn.indirect_sram) {
|
||||
r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.dpg_sram_bo,
|
||||
&adev->vcn.dpg_sram_gpu_addr, &adev->vcn.dpg_sram_cpu_addr);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "(%d) failed to allocate DPG bo\n", r);
|
||||
return r;
|
||||
if (adev->vcn.indirect_sram) {
|
||||
r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].dpg_sram_bo,
|
||||
&adev->vcn.inst[i].dpg_sram_gpu_addr, &adev->vcn.inst[i].dpg_sram_cpu_addr);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "VCN %d (%d) failed to allocate DPG bo\n", i, r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,15 +189,14 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
|
||||
|
||||
cancel_delayed_work_sync(&adev->vcn.idle_work);
|
||||
|
||||
if (adev->vcn.indirect_sram) {
|
||||
amdgpu_bo_free_kernel(&adev->vcn.dpg_sram_bo,
|
||||
&adev->vcn.dpg_sram_gpu_addr,
|
||||
(void **)&adev->vcn.dpg_sram_cpu_addr);
|
||||
}
|
||||
|
||||
for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
|
||||
if (adev->vcn.harvest_config & (1 << j))
|
||||
continue;
|
||||
if (adev->vcn.indirect_sram) {
|
||||
amdgpu_bo_free_kernel(&adev->vcn.inst[j].dpg_sram_bo,
|
||||
&adev->vcn.inst[j].dpg_sram_gpu_addr,
|
||||
(void **)&adev->vcn.inst[j].dpg_sram_cpu_addr);
|
||||
}
|
||||
kvfree(adev->vcn.inst[j].saved_bo);
|
||||
|
||||
amdgpu_bo_free_kernel(&adev->vcn.inst[j].vcpu_bo,
|
||||
@ -298,7 +300,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
|
||||
else
|
||||
new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
|
||||
|
||||
adev->vcn.pause_dpg_mode(adev, &new_state);
|
||||
adev->vcn.pause_dpg_mode(adev, j, &new_state);
|
||||
}
|
||||
|
||||
fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_dec);
|
||||
@ -341,7 +343,7 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
|
||||
new_state.fw_based = VCN_DPG_STATE__PAUSE;
|
||||
|
||||
adev->vcn.pause_dpg_mode(adev, &new_state);
|
||||
adev->vcn.pause_dpg_mode(adev, ring->me, &new_state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,11 @@
|
||||
#define VCN_VID_IP_ADDRESS_2_0 0x0
|
||||
#define VCN_AON_IP_ADDRESS_2_0 0x30000
|
||||
|
||||
#define mmUVD_RBC_XX_IB_REG_CHECK 0x026b
|
||||
#define mmUVD_RBC_XX_IB_REG_CHECK_BASE_IDX 1
|
||||
#define mmUVD_REG_XX_MASK 0x026c
|
||||
#define mmUVD_REG_XX_MASK_BASE_IDX 1
|
||||
|
||||
/* 1 second timeout */
|
||||
#define VCN_IDLE_TIMEOUT msecs_to_jiffies(1000)
|
||||
|
||||
@ -104,27 +109,27 @@
|
||||
internal_reg_offset >>= 2; \
|
||||
})
|
||||
|
||||
#define RREG32_SOC15_DPG_MODE_2_0(offset, mask_en) \
|
||||
({ \
|
||||
WREG32_SOC15(VCN, 0, mmUVD_DPG_LMA_CTL, \
|
||||
(0x0 << UVD_DPG_LMA_CTL__READ_WRITE__SHIFT | \
|
||||
mask_en << UVD_DPG_LMA_CTL__MASK_EN__SHIFT | \
|
||||
offset << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT)); \
|
||||
RREG32_SOC15(VCN, 0, mmUVD_DPG_LMA_DATA); \
|
||||
#define RREG32_SOC15_DPG_MODE_2_0(inst_idx, offset, mask_en) \
|
||||
({ \
|
||||
WREG32_SOC15(VCN, inst, mmUVD_DPG_LMA_CTL, \
|
||||
(0x0 << UVD_DPG_LMA_CTL__READ_WRITE__SHIFT | \
|
||||
mask_en << UVD_DPG_LMA_CTL__MASK_EN__SHIFT | \
|
||||
offset << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT)); \
|
||||
RREG32_SOC15(VCN, inst_idx, mmUVD_DPG_LMA_DATA); \
|
||||
})
|
||||
|
||||
#define WREG32_SOC15_DPG_MODE_2_0(offset, value, mask_en, indirect) \
|
||||
do { \
|
||||
if (!indirect) { \
|
||||
WREG32_SOC15(VCN, 0, mmUVD_DPG_LMA_DATA, value); \
|
||||
WREG32_SOC15(VCN, 0, mmUVD_DPG_LMA_CTL, \
|
||||
(0x1 << UVD_DPG_LMA_CTL__READ_WRITE__SHIFT | \
|
||||
mask_en << UVD_DPG_LMA_CTL__MASK_EN__SHIFT | \
|
||||
offset << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT)); \
|
||||
} else { \
|
||||
*adev->vcn.dpg_sram_curr_addr++ = offset; \
|
||||
*adev->vcn.dpg_sram_curr_addr++ = value; \
|
||||
} \
|
||||
#define WREG32_SOC15_DPG_MODE_2_0(inst_idx, offset, value, mask_en, indirect) \
|
||||
do { \
|
||||
if (!indirect) { \
|
||||
WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_LMA_DATA, value); \
|
||||
WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_LMA_CTL, \
|
||||
(0x1 << UVD_DPG_LMA_CTL__READ_WRITE__SHIFT | \
|
||||
mask_en << UVD_DPG_LMA_CTL__MASK_EN__SHIFT | \
|
||||
offset << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT)); \
|
||||
} else { \
|
||||
*adev->vcn.inst[inst_idx].dpg_sram_curr_addr++ = offset; \
|
||||
*adev->vcn.inst[inst_idx].dpg_sram_curr_addr++ = value; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
enum engine_status_constants {
|
||||
@ -173,6 +178,10 @@ struct amdgpu_vcn_inst {
|
||||
struct amdgpu_ring ring_enc[AMDGPU_VCN_MAX_ENC_RINGS];
|
||||
struct amdgpu_irq_src irq;
|
||||
struct amdgpu_vcn_reg external;
|
||||
struct amdgpu_bo *dpg_sram_bo;
|
||||
void *dpg_sram_cpu_addr;
|
||||
uint64_t dpg_sram_gpu_addr;
|
||||
uint32_t *dpg_sram_curr_addr;
|
||||
};
|
||||
|
||||
struct amdgpu_vcn {
|
||||
@ -184,10 +193,6 @@ struct amdgpu_vcn {
|
||||
struct dpg_pause_state pause_state;
|
||||
|
||||
bool indirect_sram;
|
||||
struct amdgpu_bo *dpg_sram_bo;
|
||||
void *dpg_sram_cpu_addr;
|
||||
uint64_t dpg_sram_gpu_addr;
|
||||
uint32_t *dpg_sram_curr_addr;
|
||||
|
||||
uint8_t num_vcn_inst;
|
||||
struct amdgpu_vcn_inst inst[AMDGPU_MAX_VCN_INSTANCES];
|
||||
@ -199,7 +204,7 @@ struct amdgpu_vcn {
|
||||
|
||||
unsigned harvest_config;
|
||||
int (*pause_dpg_mode)(struct amdgpu_device *adev,
|
||||
struct dpg_pause_state *new_state);
|
||||
int inst_idx, struct dpg_pause_state *new_state);
|
||||
};
|
||||
|
||||
int amdgpu_vcn_sw_init(struct amdgpu_device *adev);
|
||||
|
@ -82,6 +82,32 @@ struct amdgpu_prt_cb {
|
||||
struct dma_fence_cb cb;
|
||||
};
|
||||
|
||||
/**
|
||||
* vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS
|
||||
* happens while holding this lock anywhere to prevent deadlocks when
|
||||
* an MMU notifier runs in reclaim-FS context.
|
||||
*/
|
||||
static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm)
|
||||
{
|
||||
mutex_lock(&vm->eviction_lock);
|
||||
vm->saved_flags = memalloc_nofs_save();
|
||||
}
|
||||
|
||||
static inline int amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm)
|
||||
{
|
||||
if (mutex_trylock(&vm->eviction_lock)) {
|
||||
vm->saved_flags = memalloc_nofs_save();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm)
|
||||
{
|
||||
memalloc_nofs_restore(vm->saved_flags);
|
||||
mutex_unlock(&vm->eviction_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_level_shift - return the addr shift for each level
|
||||
*
|
||||
@ -678,9 +704,9 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&vm->eviction_lock);
|
||||
amdgpu_vm_eviction_lock(vm);
|
||||
vm->evicting = false;
|
||||
mutex_unlock(&vm->eviction_lock);
|
||||
amdgpu_vm_eviction_unlock(vm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1559,7 +1585,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
||||
if (!(flags & AMDGPU_PTE_VALID))
|
||||
owner = AMDGPU_FENCE_OWNER_KFD;
|
||||
|
||||
mutex_lock(&vm->eviction_lock);
|
||||
amdgpu_vm_eviction_lock(vm);
|
||||
if (vm->evicting) {
|
||||
r = -EBUSY;
|
||||
goto error_unlock;
|
||||
@ -1576,7 +1602,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
||||
r = vm->update_funcs->commit(¶ms, fence);
|
||||
|
||||
error_unlock:
|
||||
mutex_unlock(&vm->eviction_lock);
|
||||
amdgpu_vm_eviction_unlock(vm);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -2533,18 +2559,18 @@ bool amdgpu_vm_evictable(struct amdgpu_bo *bo)
|
||||
return false;
|
||||
|
||||
/* Try to block ongoing updates */
|
||||
if (!mutex_trylock(&bo_base->vm->eviction_lock))
|
||||
if (!amdgpu_vm_eviction_trylock(bo_base->vm))
|
||||
return false;
|
||||
|
||||
/* Don't evict VM page tables while they are updated */
|
||||
if (!dma_fence_is_signaled(bo_base->vm->last_direct) ||
|
||||
!dma_fence_is_signaled(bo_base->vm->last_delayed)) {
|
||||
mutex_unlock(&bo_base->vm->eviction_lock);
|
||||
amdgpu_vm_eviction_unlock(bo_base->vm);
|
||||
return false;
|
||||
}
|
||||
|
||||
bo_base->vm->evicting = true;
|
||||
mutex_unlock(&bo_base->vm->eviction_lock);
|
||||
amdgpu_vm_eviction_unlock(bo_base->vm);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <drm/gpu_scheduler.h>
|
||||
#include <drm/drm_file.h>
|
||||
#include <drm/ttm/ttm_bo_driver.h>
|
||||
#include <linux/sched/mm.h>
|
||||
|
||||
#include "amdgpu_sync.h"
|
||||
#include "amdgpu_ring.h"
|
||||
@ -239,9 +240,12 @@ struct amdgpu_vm {
|
||||
/* tree of virtual addresses mapped */
|
||||
struct rb_root_cached va;
|
||||
|
||||
/* Lock to prevent eviction while we are updating page tables */
|
||||
/* Lock to prevent eviction while we are updating page tables
|
||||
* use vm_eviction_lock/unlock(vm)
|
||||
*/
|
||||
struct mutex eviction_lock;
|
||||
bool evicting;
|
||||
unsigned int saved_flags;
|
||||
|
||||
/* BOs who needs a validation */
|
||||
struct list_head evicted;
|
||||
|
@ -146,16 +146,16 @@ static ssize_t amdgpu_xgmi_show_error(struct device *dev,
|
||||
ficaa_pie_ctl_in = AMDGPU_XGMI_SET_FICAA(0x200);
|
||||
ficaa_pie_status_in = AMDGPU_XGMI_SET_FICAA(0x208);
|
||||
|
||||
fica_out = adev->df_funcs->get_fica(adev, ficaa_pie_ctl_in);
|
||||
fica_out = adev->df.funcs->get_fica(adev, ficaa_pie_ctl_in);
|
||||
if (fica_out != 0x1f)
|
||||
pr_err("xGMI error counters not enabled!\n");
|
||||
|
||||
fica_out = adev->df_funcs->get_fica(adev, ficaa_pie_status_in);
|
||||
fica_out = adev->df.funcs->get_fica(adev, ficaa_pie_status_in);
|
||||
|
||||
if ((fica_out & 0xffff) == 2)
|
||||
error_count = ((fica_out >> 62) & 0x1) + (fica_out >> 63);
|
||||
|
||||
adev->df_funcs->set_fica(adev, ficaa_pie_status_in, 0, 0);
|
||||
adev->df.funcs->set_fica(adev, ficaa_pie_status_in, 0, 0);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", error_count);
|
||||
}
|
||||
@ -291,13 +291,7 @@ int amdgpu_xgmi_set_pstate(struct amdgpu_device *adev, int pstate)
|
||||
|
||||
dev_dbg(adev->dev, "Set xgmi pstate %d.\n", pstate);
|
||||
|
||||
if (is_support_sw_smu_xgmi(adev))
|
||||
ret = smu_set_xgmi_pstate(&adev->smu, pstate);
|
||||
else if (adev->powerplay.pp_funcs &&
|
||||
adev->powerplay.pp_funcs->set_xgmi_pstate)
|
||||
ret = adev->powerplay.pp_funcs->set_xgmi_pstate(adev->powerplay.pp_handle,
|
||||
pstate);
|
||||
|
||||
ret = amdgpu_dpm_set_xgmi_pstate(adev, pstate);
|
||||
if (ret) {
|
||||
dev_err(adev->dev,
|
||||
"XGMI: Set pstate failure on device %llx, hive %llx, ret %d",
|
||||
|
@ -1312,19 +1312,13 @@ static int cik_asic_pci_config_reset(struct amdgpu_device *adev)
|
||||
|
||||
static bool cik_asic_supports_baco(struct amdgpu_device *adev)
|
||||
{
|
||||
bool baco_support;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_BONAIRE:
|
||||
case CHIP_HAWAII:
|
||||
smu7_asic_get_baco_capability(adev, &baco_support);
|
||||
break;
|
||||
return amdgpu_dpm_is_baco_supported(adev);
|
||||
default:
|
||||
baco_support = false;
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
return baco_support;
|
||||
}
|
||||
|
||||
static enum amd_reset_method
|
||||
@ -1366,7 +1360,7 @@ static int cik_asic_reset(struct amdgpu_device *adev)
|
||||
if (cik_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
|
||||
if (!adev->in_suspend)
|
||||
amdgpu_inc_vram_lost(adev);
|
||||
r = smu7_asic_baco_reset(adev);
|
||||
r = amdgpu_dpm_baco_reset(adev);
|
||||
} else {
|
||||
r = cik_asic_pci_config_reset(adev);
|
||||
}
|
||||
|
@ -31,7 +31,5 @@ void cik_srbm_select(struct amdgpu_device *adev,
|
||||
int cik_set_ip_blocks(struct amdgpu_device *adev);
|
||||
|
||||
void legacy_doorbell_index_init(struct amdgpu_device *adev);
|
||||
int smu7_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap);
|
||||
int smu7_asic_baco_reset(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
@ -31,6 +31,9 @@ static u32 df_v1_7_channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2};
|
||||
|
||||
static void df_v1_7_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->df.hash_status.hash_64k = false;
|
||||
adev->df.hash_status.hash_2m = false;
|
||||
adev->df.hash_status.hash_1g = false;
|
||||
}
|
||||
|
||||
static void df_v1_7_sw_fini(struct amdgpu_device *adev)
|
||||
@ -66,7 +69,7 @@ static u32 df_v1_7_get_hbm_channel_number(struct amdgpu_device *adev)
|
||||
{
|
||||
int fb_channel_number;
|
||||
|
||||
fb_channel_number = adev->df_funcs->get_fb_channel_number(adev);
|
||||
fb_channel_number = adev->df.funcs->get_fb_channel_number(adev);
|
||||
|
||||
return df_v1_7_channel_number[fb_channel_number];
|
||||
}
|
||||
@ -77,7 +80,7 @@ static void df_v1_7_update_medium_grain_clock_gating(struct amdgpu_device *adev,
|
||||
u32 tmp;
|
||||
|
||||
/* Put DF on broadcast mode */
|
||||
adev->df_funcs->enable_broadcast_mode(adev, true);
|
||||
adev->df.funcs->enable_broadcast_mode(adev, true);
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DF_MGCG)) {
|
||||
tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater);
|
||||
@ -92,7 +95,7 @@ static void df_v1_7_update_medium_grain_clock_gating(struct amdgpu_device *adev,
|
||||
}
|
||||
|
||||
/* Exit boradcast mode */
|
||||
adev->df_funcs->enable_broadcast_mode(adev, false);
|
||||
adev->df.funcs->enable_broadcast_mode(adev, false);
|
||||
}
|
||||
|
||||
static void df_v1_7_get_clockgating_state(struct amdgpu_device *adev,
|
||||
|
@ -262,6 +262,32 @@ static ssize_t df_v3_6_get_df_cntr_avail(struct device *dev,
|
||||
/* device attr for available perfmon counters */
|
||||
static DEVICE_ATTR(df_cntr_avail, S_IRUGO, df_v3_6_get_df_cntr_avail, NULL);
|
||||
|
||||
static void df_v3_6_query_hashes(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
adev->df.hash_status.hash_64k = false;
|
||||
adev->df.hash_status.hash_2m = false;
|
||||
adev->df.hash_status.hash_1g = false;
|
||||
|
||||
if (adev->asic_type != CHIP_ARCTURUS)
|
||||
return;
|
||||
|
||||
/* encoding for hash-enabled on Arcturus */
|
||||
if (adev->df.funcs->get_fb_channel_number(adev) == 0xe) {
|
||||
tmp = RREG32_SOC15(DF, 0, mmDF_CS_UMC_AON0_DfGlobalCtrl);
|
||||
adev->df.hash_status.hash_64k = REG_GET_FIELD(tmp,
|
||||
DF_CS_UMC_AON0_DfGlobalCtrl,
|
||||
GlbHashIntlvCtl64K);
|
||||
adev->df.hash_status.hash_2m = REG_GET_FIELD(tmp,
|
||||
DF_CS_UMC_AON0_DfGlobalCtrl,
|
||||
GlbHashIntlvCtl2M);
|
||||
adev->df.hash_status.hash_1g = REG_GET_FIELD(tmp,
|
||||
DF_CS_UMC_AON0_DfGlobalCtrl,
|
||||
GlbHashIntlvCtl1G);
|
||||
}
|
||||
}
|
||||
|
||||
/* init perfmons */
|
||||
static void df_v3_6_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
@ -273,6 +299,8 @@ static void df_v3_6_sw_init(struct amdgpu_device *adev)
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_DF_PERFMONS; i++)
|
||||
adev->df_perfmon_config_assign_mask[i] = 0;
|
||||
|
||||
df_v3_6_query_hashes(adev);
|
||||
}
|
||||
|
||||
static void df_v3_6_sw_fini(struct amdgpu_device *adev)
|
||||
@ -311,7 +339,7 @@ static u32 df_v3_6_get_hbm_channel_number(struct amdgpu_device *adev)
|
||||
{
|
||||
int fb_channel_number;
|
||||
|
||||
fb_channel_number = adev->df_funcs->get_fb_channel_number(adev);
|
||||
fb_channel_number = adev->df.funcs->get_fb_channel_number(adev);
|
||||
if (fb_channel_number >= ARRAY_SIZE(df_v3_6_channel_number))
|
||||
fb_channel_number = 0;
|
||||
|
||||
@ -325,7 +353,7 @@ static void df_v3_6_update_medium_grain_clock_gating(struct amdgpu_device *adev,
|
||||
|
||||
if (adev->cg_flags & AMD_CG_SUPPORT_DF_MGCG) {
|
||||
/* Put DF on broadcast mode */
|
||||
adev->df_funcs->enable_broadcast_mode(adev, true);
|
||||
adev->df.funcs->enable_broadcast_mode(adev, true);
|
||||
|
||||
if (enable) {
|
||||
tmp = RREG32_SOC15(DF, 0,
|
||||
@ -344,7 +372,7 @@ static void df_v3_6_update_medium_grain_clock_gating(struct amdgpu_device *adev,
|
||||
}
|
||||
|
||||
/* Exit broadcast mode */
|
||||
adev->df_funcs->enable_broadcast_mode(adev, false);
|
||||
adev->df.funcs->enable_broadcast_mode(adev, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "ivsrcid/gfx/irqsrcs_gfx_10_1.h"
|
||||
|
||||
#include "soc15.h"
|
||||
#include "soc15d.h"
|
||||
#include "soc15_common.h"
|
||||
#include "clearstate_gfx10.h"
|
||||
#include "v10_structs.h"
|
||||
@ -120,7 +121,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_1[] =
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0x00000800, 0x00000820),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_SPARE, 0xffffffff, 0xffff3101),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL, 0x001f0000, 0x00070104),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0x001f0000, 0x00070104),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_ALU_CLK_CTRL, 0xffffffff, 0xffffffff),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_ARB_CONFIG, 0x00000100, 0x00000130),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_LDS_CLK_CTRL, 0xffffffff, 0xffffffff),
|
||||
@ -168,7 +169,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_1_1[] =
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0x00000800, 0x00000820),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_SPARE, 0xffffffff, 0xffff3101),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL, 0x001f0000, 0x00070105),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0x001f0000, 0x00070105),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_ALU_CLK_CTRL, 0xffffffff, 0xffffffff),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_ARB_CONFIG, 0x00000133, 0x00000130),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_LDS_CLK_CTRL, 0xffffffff, 0xffffffff),
|
||||
@ -345,15 +346,29 @@ static void gfx10_kiq_query_status(struct amdgpu_ring *kiq_ring,
|
||||
amdgpu_ring_write(kiq_ring, upper_32_bits(seq));
|
||||
}
|
||||
|
||||
static void gfx10_kiq_invalidate_tlbs(struct amdgpu_ring *kiq_ring,
|
||||
uint16_t pasid, uint32_t flush_type,
|
||||
bool all_hub)
|
||||
{
|
||||
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
|
||||
amdgpu_ring_write(kiq_ring,
|
||||
PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
|
||||
PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) |
|
||||
PACKET3_INVALIDATE_TLBS_PASID(pasid) |
|
||||
PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type));
|
||||
}
|
||||
|
||||
static const struct kiq_pm4_funcs gfx_v10_0_kiq_pm4_funcs = {
|
||||
.kiq_set_resources = gfx10_kiq_set_resources,
|
||||
.kiq_map_queues = gfx10_kiq_map_queues,
|
||||
.kiq_unmap_queues = gfx10_kiq_unmap_queues,
|
||||
.kiq_query_status = gfx10_kiq_query_status,
|
||||
.kiq_invalidate_tlbs = gfx10_kiq_invalidate_tlbs,
|
||||
.set_resources_size = 8,
|
||||
.map_queues_size = 7,
|
||||
.unmap_queues_size = 6,
|
||||
.query_status_size = 7,
|
||||
.invalidate_tlbs_size = 12,
|
||||
};
|
||||
|
||||
static void gfx_v10_0_set_kiq_pm4_funcs(struct amdgpu_device *adev)
|
||||
@ -807,10 +822,11 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
||||
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_G];
|
||||
info->ucode_id = AMDGPU_UCODE_ID_RLC_G;
|
||||
info->fw = adev->gfx.rlc_fw;
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
if (info->fw) {
|
||||
header = (const struct common_firmware_header *)info->fw->data;
|
||||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
|
||||
}
|
||||
if (adev->gfx.rlc.is_rlc_v2_1 &&
|
||||
adev->gfx.rlc.save_restore_list_cntl_size_bytes &&
|
||||
adev->gfx.rlc.save_restore_list_gpm_size_bytes &&
|
||||
@ -3321,8 +3337,11 @@ static int gfx_v10_0_compute_mqd_init(struct amdgpu_ring *ring)
|
||||
tmp = REG_SET_FIELD(tmp, CP_HQD_IB_CONTROL, MIN_IB_AVAIL_SIZE, 3);
|
||||
mqd->cp_hqd_ib_control = tmp;
|
||||
|
||||
/* activate the queue */
|
||||
mqd->cp_hqd_active = 1;
|
||||
/* map_queues packet doesn't need activate the queue,
|
||||
* so only kiq need set this field.
|
||||
*/
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_KIQ)
|
||||
mqd->cp_hqd_active = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -4558,8 +4558,11 @@ static int gfx_v8_0_mqd_init(struct amdgpu_ring *ring)
|
||||
mqd->cp_hqd_eop_wptr_mem = RREG32(mmCP_HQD_EOP_WPTR_MEM);
|
||||
mqd->cp_hqd_eop_dones = RREG32(mmCP_HQD_EOP_DONES);
|
||||
|
||||
/* activate the queue */
|
||||
mqd->cp_hqd_active = 1;
|
||||
/* map_queues packet doesn't need activate the queue,
|
||||
* so only kiq need set this field.
|
||||
*/
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_KIQ)
|
||||
mqd->cp_hqd_active = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -48,15 +48,6 @@
|
||||
|
||||
#include "amdgpu_ras.h"
|
||||
|
||||
#include "sdma0/sdma0_4_2_offset.h"
|
||||
#include "sdma1/sdma1_4_2_offset.h"
|
||||
#include "sdma2/sdma2_4_2_2_offset.h"
|
||||
#include "sdma3/sdma3_4_2_2_offset.h"
|
||||
#include "sdma4/sdma4_4_2_2_offset.h"
|
||||
#include "sdma5/sdma5_4_2_2_offset.h"
|
||||
#include "sdma6/sdma6_4_2_2_offset.h"
|
||||
#include "sdma7/sdma7_4_2_2_offset.h"
|
||||
|
||||
#define GFX9_NUM_GFX_RINGS 1
|
||||
#define GFX9_MEC_HPD_SIZE 4096
|
||||
#define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L
|
||||
@ -748,6 +739,134 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
|
||||
static int gfx_v9_0_ras_error_inject(struct amdgpu_device *adev,
|
||||
void *inject_if);
|
||||
|
||||
static void gfx_v9_0_kiq_set_resources(struct amdgpu_ring *kiq_ring,
|
||||
uint64_t queue_mask)
|
||||
{
|
||||
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_SET_RESOURCES, 6));
|
||||
amdgpu_ring_write(kiq_ring,
|
||||
PACKET3_SET_RESOURCES_VMID_MASK(0) |
|
||||
/* vmid_mask:0* queue_type:0 (KIQ) */
|
||||
PACKET3_SET_RESOURCES_QUEUE_TYPE(0));
|
||||
amdgpu_ring_write(kiq_ring,
|
||||
lower_32_bits(queue_mask)); /* queue mask lo */
|
||||
amdgpu_ring_write(kiq_ring,
|
||||
upper_32_bits(queue_mask)); /* queue mask hi */
|
||||
amdgpu_ring_write(kiq_ring, 0); /* gws mask lo */
|
||||
amdgpu_ring_write(kiq_ring, 0); /* gws mask hi */
|
||||
amdgpu_ring_write(kiq_ring, 0); /* oac mask */
|
||||
amdgpu_ring_write(kiq_ring, 0); /* gds heap base:0, gds heap size:0 */
|
||||
}
|
||||
|
||||
static void gfx_v9_0_kiq_map_queues(struct amdgpu_ring *kiq_ring,
|
||||
struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = kiq_ring->adev;
|
||||
uint64_t mqd_addr = amdgpu_bo_gpu_offset(ring->mqd_obj);
|
||||
uint64_t wptr_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4);
|
||||
uint32_t eng_sel = ring->funcs->type == AMDGPU_RING_TYPE_GFX ? 4 : 0;
|
||||
|
||||
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_MAP_QUEUES, 5));
|
||||
/* Q_sel:0, vmid:0, vidmem: 1, engine:0, num_Q:1*/
|
||||
amdgpu_ring_write(kiq_ring, /* Q_sel: 0, vmid: 0, engine: 0, num_Q: 1 */
|
||||
PACKET3_MAP_QUEUES_QUEUE_SEL(0) | /* Queue_Sel */
|
||||
PACKET3_MAP_QUEUES_VMID(0) | /* VMID */
|
||||
PACKET3_MAP_QUEUES_QUEUE(ring->queue) |
|
||||
PACKET3_MAP_QUEUES_PIPE(ring->pipe) |
|
||||
PACKET3_MAP_QUEUES_ME((ring->me == 1 ? 0 : 1)) |
|
||||
/*queue_type: normal compute queue */
|
||||
PACKET3_MAP_QUEUES_QUEUE_TYPE(0) |
|
||||
/* alloc format: all_on_one_pipe */
|
||||
PACKET3_MAP_QUEUES_ALLOC_FORMAT(0) |
|
||||
PACKET3_MAP_QUEUES_ENGINE_SEL(eng_sel) |
|
||||
/* num_queues: must be 1 */
|
||||
PACKET3_MAP_QUEUES_NUM_QUEUES(1));
|
||||
amdgpu_ring_write(kiq_ring,
|
||||
PACKET3_MAP_QUEUES_DOORBELL_OFFSET(ring->doorbell_index));
|
||||
amdgpu_ring_write(kiq_ring, lower_32_bits(mqd_addr));
|
||||
amdgpu_ring_write(kiq_ring, upper_32_bits(mqd_addr));
|
||||
amdgpu_ring_write(kiq_ring, lower_32_bits(wptr_addr));
|
||||
amdgpu_ring_write(kiq_ring, upper_32_bits(wptr_addr));
|
||||
}
|
||||
|
||||
static void gfx_v9_0_kiq_unmap_queues(struct amdgpu_ring *kiq_ring,
|
||||
struct amdgpu_ring *ring,
|
||||
enum amdgpu_unmap_queues_action action,
|
||||
u64 gpu_addr, u64 seq)
|
||||
{
|
||||
uint32_t eng_sel = ring->funcs->type == AMDGPU_RING_TYPE_GFX ? 4 : 0;
|
||||
|
||||
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_UNMAP_QUEUES, 4));
|
||||
amdgpu_ring_write(kiq_ring, /* Q_sel: 0, vmid: 0, engine: 0, num_Q: 1 */
|
||||
PACKET3_UNMAP_QUEUES_ACTION(action) |
|
||||
PACKET3_UNMAP_QUEUES_QUEUE_SEL(0) |
|
||||
PACKET3_UNMAP_QUEUES_ENGINE_SEL(eng_sel) |
|
||||
PACKET3_UNMAP_QUEUES_NUM_QUEUES(1));
|
||||
amdgpu_ring_write(kiq_ring,
|
||||
PACKET3_UNMAP_QUEUES_DOORBELL_OFFSET0(ring->doorbell_index));
|
||||
|
||||
if (action == PREEMPT_QUEUES_NO_UNMAP) {
|
||||
amdgpu_ring_write(kiq_ring, lower_32_bits(gpu_addr));
|
||||
amdgpu_ring_write(kiq_ring, upper_32_bits(gpu_addr));
|
||||
amdgpu_ring_write(kiq_ring, seq);
|
||||
} else {
|
||||
amdgpu_ring_write(kiq_ring, 0);
|
||||
amdgpu_ring_write(kiq_ring, 0);
|
||||
amdgpu_ring_write(kiq_ring, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_v9_0_kiq_query_status(struct amdgpu_ring *kiq_ring,
|
||||
struct amdgpu_ring *ring,
|
||||
u64 addr,
|
||||
u64 seq)
|
||||
{
|
||||
uint32_t eng_sel = ring->funcs->type == AMDGPU_RING_TYPE_GFX ? 4 : 0;
|
||||
|
||||
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_QUERY_STATUS, 5));
|
||||
amdgpu_ring_write(kiq_ring,
|
||||
PACKET3_QUERY_STATUS_CONTEXT_ID(0) |
|
||||
PACKET3_QUERY_STATUS_INTERRUPT_SEL(0) |
|
||||
PACKET3_QUERY_STATUS_COMMAND(2));
|
||||
/* Q_sel: 0, vmid: 0, engine: 0, num_Q: 1 */
|
||||
amdgpu_ring_write(kiq_ring,
|
||||
PACKET3_QUERY_STATUS_DOORBELL_OFFSET(ring->doorbell_index) |
|
||||
PACKET3_QUERY_STATUS_ENG_SEL(eng_sel));
|
||||
amdgpu_ring_write(kiq_ring, lower_32_bits(addr));
|
||||
amdgpu_ring_write(kiq_ring, upper_32_bits(addr));
|
||||
amdgpu_ring_write(kiq_ring, lower_32_bits(seq));
|
||||
amdgpu_ring_write(kiq_ring, upper_32_bits(seq));
|
||||
}
|
||||
|
||||
static void gfx_v9_0_kiq_invalidate_tlbs(struct amdgpu_ring *kiq_ring,
|
||||
uint16_t pasid, uint32_t flush_type,
|
||||
bool all_hub)
|
||||
{
|
||||
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
|
||||
amdgpu_ring_write(kiq_ring,
|
||||
PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
|
||||
PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) |
|
||||
PACKET3_INVALIDATE_TLBS_PASID(pasid) |
|
||||
PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type));
|
||||
}
|
||||
|
||||
static const struct kiq_pm4_funcs gfx_v9_0_kiq_pm4_funcs = {
|
||||
.kiq_set_resources = gfx_v9_0_kiq_set_resources,
|
||||
.kiq_map_queues = gfx_v9_0_kiq_map_queues,
|
||||
.kiq_unmap_queues = gfx_v9_0_kiq_unmap_queues,
|
||||
.kiq_query_status = gfx_v9_0_kiq_query_status,
|
||||
.kiq_invalidate_tlbs = gfx_v9_0_kiq_invalidate_tlbs,
|
||||
.set_resources_size = 8,
|
||||
.map_queues_size = 7,
|
||||
.unmap_queues_size = 6,
|
||||
.query_status_size = 7,
|
||||
.invalidate_tlbs_size = 12,
|
||||
};
|
||||
|
||||
static void gfx_v9_0_set_kiq_pm4_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->gfx.kiq.pmf = &gfx_v9_0_kiq_pm4_funcs;
|
||||
}
|
||||
|
||||
static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
switch (adev->asic_type) {
|
||||
@ -3115,74 +3234,6 @@ static void gfx_v9_0_kiq_setting(struct amdgpu_ring *ring)
|
||||
WREG32_SOC15_RLC(GC, 0, mmRLC_CP_SCHEDULERS, tmp);
|
||||
}
|
||||
|
||||
static int gfx_v9_0_kiq_kcq_enable(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring;
|
||||
uint64_t queue_mask = 0;
|
||||
int r, i;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_COMPUTE_QUEUES; ++i) {
|
||||
if (!test_bit(i, adev->gfx.mec.queue_bitmap))
|
||||
continue;
|
||||
|
||||
/* This situation may be hit in the future if a new HW
|
||||
* generation exposes more than 64 queues. If so, the
|
||||
* definition of queue_mask needs updating */
|
||||
if (WARN_ON(i >= (sizeof(queue_mask)*8))) {
|
||||
DRM_ERROR("Invalid KCQ enabled: %d\n", i);
|
||||
break;
|
||||
}
|
||||
|
||||
queue_mask |= (1ull << i);
|
||||
}
|
||||
|
||||
r = amdgpu_ring_alloc(kiq_ring, (7 * adev->gfx.num_compute_rings) + 8);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to lock KIQ (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* set resources */
|
||||
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_SET_RESOURCES, 6));
|
||||
amdgpu_ring_write(kiq_ring, PACKET3_SET_RESOURCES_VMID_MASK(0) |
|
||||
PACKET3_SET_RESOURCES_QUEUE_TYPE(0)); /* vmid_mask:0 queue_type:0 (KIQ) */
|
||||
amdgpu_ring_write(kiq_ring, lower_32_bits(queue_mask)); /* queue mask lo */
|
||||
amdgpu_ring_write(kiq_ring, upper_32_bits(queue_mask)); /* queue mask hi */
|
||||
amdgpu_ring_write(kiq_ring, 0); /* gws mask lo */
|
||||
amdgpu_ring_write(kiq_ring, 0); /* gws mask hi */
|
||||
amdgpu_ring_write(kiq_ring, 0); /* oac mask */
|
||||
amdgpu_ring_write(kiq_ring, 0); /* gds heap base:0, gds heap size:0 */
|
||||
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
|
||||
struct amdgpu_ring *ring = &adev->gfx.compute_ring[i];
|
||||
uint64_t mqd_addr = amdgpu_bo_gpu_offset(ring->mqd_obj);
|
||||
uint64_t wptr_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4);
|
||||
|
||||
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_MAP_QUEUES, 5));
|
||||
/* Q_sel:0, vmid:0, vidmem: 1, engine:0, num_Q:1*/
|
||||
amdgpu_ring_write(kiq_ring, /* Q_sel: 0, vmid: 0, engine: 0, num_Q: 1 */
|
||||
PACKET3_MAP_QUEUES_QUEUE_SEL(0) | /* Queue_Sel */
|
||||
PACKET3_MAP_QUEUES_VMID(0) | /* VMID */
|
||||
PACKET3_MAP_QUEUES_QUEUE(ring->queue) |
|
||||
PACKET3_MAP_QUEUES_PIPE(ring->pipe) |
|
||||
PACKET3_MAP_QUEUES_ME((ring->me == 1 ? 0 : 1)) |
|
||||
PACKET3_MAP_QUEUES_QUEUE_TYPE(0) | /*queue_type: normal compute queue */
|
||||
PACKET3_MAP_QUEUES_ALLOC_FORMAT(0) | /* alloc format: all_on_one_pipe */
|
||||
PACKET3_MAP_QUEUES_ENGINE_SEL(0) | /* engine_sel: compute */
|
||||
PACKET3_MAP_QUEUES_NUM_QUEUES(1)); /* num_queues: must be 1 */
|
||||
amdgpu_ring_write(kiq_ring, PACKET3_MAP_QUEUES_DOORBELL_OFFSET(ring->doorbell_index));
|
||||
amdgpu_ring_write(kiq_ring, lower_32_bits(mqd_addr));
|
||||
amdgpu_ring_write(kiq_ring, upper_32_bits(mqd_addr));
|
||||
amdgpu_ring_write(kiq_ring, lower_32_bits(wptr_addr));
|
||||
amdgpu_ring_write(kiq_ring, upper_32_bits(wptr_addr));
|
||||
}
|
||||
|
||||
r = amdgpu_ring_test_helper(kiq_ring);
|
||||
if (r)
|
||||
DRM_ERROR("KCQ enable failed\n");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int gfx_v9_0_mqd_init(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
@ -3319,8 +3370,11 @@ static int gfx_v9_0_mqd_init(struct amdgpu_ring *ring)
|
||||
tmp = REG_SET_FIELD(tmp, CP_HQD_IB_CONTROL, MIN_IB_AVAIL_SIZE, 3);
|
||||
mqd->cp_hqd_ib_control = tmp;
|
||||
|
||||
/* activate the queue */
|
||||
mqd->cp_hqd_active = 1;
|
||||
/* map_queues packet doesn't need activate the queue,
|
||||
* so only kiq need set this field.
|
||||
*/
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_KIQ)
|
||||
mqd->cp_hqd_active = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -3589,7 +3643,7 @@ static int gfx_v9_0_kcq_resume(struct amdgpu_device *adev)
|
||||
goto done;
|
||||
}
|
||||
|
||||
r = gfx_v9_0_kiq_kcq_enable(adev);
|
||||
r = amdgpu_gfx_enable_kcq(adev);
|
||||
done:
|
||||
return r;
|
||||
}
|
||||
@ -3646,6 +3700,23 @@ static int gfx_v9_0_cp_resume(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_v9_0_init_tcp_config(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
if (adev->asic_type != CHIP_ARCTURUS)
|
||||
return;
|
||||
|
||||
tmp = RREG32_SOC15(GC, 0, mmTCP_ADDR_CONFIG);
|
||||
tmp = REG_SET_FIELD(tmp, TCP_ADDR_CONFIG, ENABLE64KHASH,
|
||||
adev->df.hash_status.hash_64k);
|
||||
tmp = REG_SET_FIELD(tmp, TCP_ADDR_CONFIG, ENABLE2MHASH,
|
||||
adev->df.hash_status.hash_2m);
|
||||
tmp = REG_SET_FIELD(tmp, TCP_ADDR_CONFIG, ENABLE1GHASH,
|
||||
adev->df.hash_status.hash_1g);
|
||||
WREG32_SOC15(GC, 0, mmTCP_ADDR_CONFIG, tmp);
|
||||
}
|
||||
|
||||
static void gfx_v9_0_cp_enable(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
if (adev->asic_type != CHIP_ARCTURUS)
|
||||
@ -3663,6 +3734,8 @@ static int gfx_v9_0_hw_init(void *handle)
|
||||
|
||||
gfx_v9_0_constants_init(adev);
|
||||
|
||||
gfx_v9_0_init_tcp_config(adev);
|
||||
|
||||
r = adev->gfx.rlc.funcs->resume(adev);
|
||||
if (r)
|
||||
return r;
|
||||
@ -3674,36 +3747,6 @@ static int gfx_v9_0_hw_init(void *handle)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int gfx_v9_0_kcq_disable(struct amdgpu_device *adev)
|
||||
{
|
||||
int r, i;
|
||||
struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring;
|
||||
|
||||
r = amdgpu_ring_alloc(kiq_ring, 6 * adev->gfx.num_compute_rings);
|
||||
if (r)
|
||||
DRM_ERROR("Failed to lock KIQ (%d).\n", r);
|
||||
|
||||
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
|
||||
struct amdgpu_ring *ring = &adev->gfx.compute_ring[i];
|
||||
|
||||
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_UNMAP_QUEUES, 4));
|
||||
amdgpu_ring_write(kiq_ring, /* Q_sel: 0, vmid: 0, engine: 0, num_Q: 1 */
|
||||
PACKET3_UNMAP_QUEUES_ACTION(1) | /* RESET_QUEUES */
|
||||
PACKET3_UNMAP_QUEUES_QUEUE_SEL(0) |
|
||||
PACKET3_UNMAP_QUEUES_ENGINE_SEL(0) |
|
||||
PACKET3_UNMAP_QUEUES_NUM_QUEUES(1));
|
||||
amdgpu_ring_write(kiq_ring, PACKET3_UNMAP_QUEUES_DOORBELL_OFFSET0(ring->doorbell_index));
|
||||
amdgpu_ring_write(kiq_ring, 0);
|
||||
amdgpu_ring_write(kiq_ring, 0);
|
||||
amdgpu_ring_write(kiq_ring, 0);
|
||||
}
|
||||
r = amdgpu_ring_test_helper(kiq_ring);
|
||||
if (r)
|
||||
DRM_ERROR("KCQ disable failed\n");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int gfx_v9_0_hw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
@ -3715,7 +3758,7 @@ static int gfx_v9_0_hw_fini(void *handle)
|
||||
/* DF freeze and kcq disable will fail */
|
||||
if (!amdgpu_ras_intr_triggered())
|
||||
/* disable KCQ to avoid CPC touch memory not valid anymore */
|
||||
gfx_v9_0_kcq_disable(adev);
|
||||
amdgpu_gfx_disable_kcq(adev);
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
gfx_v9_0_cp_gfx_enable(adev, false);
|
||||
@ -4021,14 +4064,6 @@ static const struct soc15_reg_entry sec_ded_counter_registers[] = {
|
||||
{ SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), 0, 1, 2},
|
||||
{ SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 0, 4, 6},
|
||||
{ SOC15_REG_ENTRY(HDP, 0, mmHDP_EDC_CNT), 0, 1, 1},
|
||||
{ SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER), 0, 1, 1},
|
||||
{ SOC15_REG_ENTRY(SDMA1, 0, mmSDMA1_EDC_COUNTER), 0, 1, 1},
|
||||
{ SOC15_REG_ENTRY(SDMA2, 0, mmSDMA2_EDC_COUNTER), 0, 1, 1},
|
||||
{ SOC15_REG_ENTRY(SDMA3, 0, mmSDMA3_EDC_COUNTER), 0, 1, 1},
|
||||
{ SOC15_REG_ENTRY(SDMA4, 0, mmSDMA4_EDC_COUNTER), 0, 1, 1},
|
||||
{ SOC15_REG_ENTRY(SDMA5, 0, mmSDMA5_EDC_COUNTER), 0, 1, 1},
|
||||
{ SOC15_REG_ENTRY(SDMA6, 0, mmSDMA6_EDC_COUNTER), 0, 1, 1},
|
||||
{ SOC15_REG_ENTRY(SDMA7, 0, mmSDMA7_EDC_COUNTER), 0, 1, 1},
|
||||
};
|
||||
|
||||
static int gfx_v9_0_do_edc_gds_workarounds(struct amdgpu_device *adev)
|
||||
@ -4092,7 +4127,6 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
|
||||
adev->gfx.config.max_sh_per_se;
|
||||
int sgpr_work_group_size = 5;
|
||||
int gpr_reg_size = compute_dim_x / 16 + 6;
|
||||
int sec_ded_counter_reg_size = adev->sdma.num_instances + 34;
|
||||
|
||||
/* only support when RAS is enabled */
|
||||
if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
|
||||
@ -4232,7 +4266,7 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
|
||||
|
||||
/* read back registers to clear the counters */
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
for (i = 0; i < sec_ded_counter_reg_size; i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(sec_ded_counter_registers); i++) {
|
||||
for (j = 0; j < sec_ded_counter_registers[i].se_num; j++) {
|
||||
for (k = 0; k < sec_ded_counter_registers[i].instance; k++) {
|
||||
gfx_v9_0_select_se_sh(adev, j, 0x0, k);
|
||||
@ -4259,6 +4293,7 @@ static int gfx_v9_0_early_init(void *handle)
|
||||
else
|
||||
adev->gfx.num_gfx_rings = GFX9_NUM_GFX_RINGS;
|
||||
adev->gfx.num_compute_rings = AMDGPU_MAX_COMPUTE_RINGS;
|
||||
gfx_v9_0_set_kiq_pm4_funcs(adev);
|
||||
gfx_v9_0_set_ring_funcs(adev);
|
||||
gfx_v9_0_set_irq_funcs(adev);
|
||||
gfx_v9_0_set_gds_init(adev);
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "hdp/hdp_5_0_0_sh_mask.h"
|
||||
#include "gc/gc_10_1_0_sh_mask.h"
|
||||
#include "mmhub/mmhub_2_0_0_sh_mask.h"
|
||||
#include "athub/athub_2_0_0_sh_mask.h"
|
||||
#include "athub/athub_2_0_0_offset.h"
|
||||
#include "dcn/dcn_2_0_0_offset.h"
|
||||
#include "dcn/dcn_2_0_0_sh_mask.h"
|
||||
#include "oss/osssys_5_0_0_offset.h"
|
||||
@ -37,6 +39,7 @@
|
||||
#include "navi10_enum.h"
|
||||
|
||||
#include "soc15.h"
|
||||
#include "soc15d.h"
|
||||
#include "soc15_common.h"
|
||||
|
||||
#include "nbio_v2_3.h"
|
||||
@ -234,6 +237,19 @@ static bool gmc_v10_0_use_invalidate_semaphore(struct amdgpu_device *adev,
|
||||
(!amdgpu_sriov_vf(adev)));
|
||||
}
|
||||
|
||||
static bool gmc_v10_0_get_atc_vmid_pasid_mapping_info(
|
||||
struct amdgpu_device *adev,
|
||||
uint8_t vmid, uint16_t *p_pasid)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING)
|
||||
+ vmid);
|
||||
*p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
|
||||
|
||||
return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* GART
|
||||
* VMID 0 is the physical GPU addresses as used by the kernel.
|
||||
@ -380,6 +396,63 @@ error_alloc:
|
||||
DRM_ERROR("Error flushing GPU TLB using the SDMA (%d)!\n", r);
|
||||
}
|
||||
|
||||
/**
|
||||
* gmc_v10_0_flush_gpu_tlb_pasid - tlb flush via pasid
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @pasid: pasid to be flush
|
||||
*
|
||||
* Flush the TLB for the requested pasid.
|
||||
*/
|
||||
static int gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
|
||||
uint16_t pasid, uint32_t flush_type,
|
||||
bool all_hub)
|
||||
{
|
||||
int vmid, i;
|
||||
signed long r;
|
||||
uint32_t seq;
|
||||
uint16_t queried_pasid;
|
||||
bool ret;
|
||||
struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq;
|
||||
|
||||
if (amdgpu_emu_mode == 0 && ring->sched.ready) {
|
||||
spin_lock(&adev->gfx.kiq.ring_lock);
|
||||
amdgpu_ring_alloc(ring, kiq->pmf->invalidate_tlbs_size);
|
||||
kiq->pmf->kiq_invalidate_tlbs(ring,
|
||||
pasid, flush_type, all_hub);
|
||||
amdgpu_fence_emit_polling(ring, &seq);
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock(&adev->gfx.kiq.ring_lock);
|
||||
r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
|
||||
if (r < 1) {
|
||||
DRM_ERROR("wait for kiq fence error: %ld.\n", r);
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (vmid = 1; vmid < 16; vmid++) {
|
||||
|
||||
ret = gmc_v10_0_get_atc_vmid_pasid_mapping_info(adev, vmid,
|
||||
&queried_pasid);
|
||||
if (ret && queried_pasid == pasid) {
|
||||
if (all_hub) {
|
||||
for (i = 0; i < adev->num_vmhubs; i++)
|
||||
gmc_v10_0_flush_gpu_tlb(adev, vmid,
|
||||
i, 0);
|
||||
} else {
|
||||
gmc_v10_0_flush_gpu_tlb(adev, vmid,
|
||||
AMDGPU_GFXHUB_0, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
@ -531,6 +604,7 @@ static void gmc_v10_0_get_vm_pte(struct amdgpu_device *adev,
|
||||
|
||||
static const struct amdgpu_gmc_funcs gmc_v10_0_gmc_funcs = {
|
||||
.flush_gpu_tlb = gmc_v10_0_flush_gpu_tlb,
|
||||
.flush_gpu_tlb_pasid = gmc_v10_0_flush_gpu_tlb_pasid,
|
||||
.emit_flush_gpu_tlb = gmc_v10_0_emit_flush_gpu_tlb,
|
||||
.emit_pasid_mapping = gmc_v10_0_emit_pasid_mapping,
|
||||
.map_mtype = gmc_v10_0_map_mtype,
|
||||
@ -566,6 +640,13 @@ static int gmc_v10_0_late_init(void *handle)
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
/*
|
||||
* Can't free the stolen VGA memory when it might be used for memory
|
||||
* training again.
|
||||
*/
|
||||
if (!adev->fw_vram_usage.mem_train_support)
|
||||
amdgpu_bo_late_init(adev);
|
||||
|
||||
r = amdgpu_gmc_allocate_vm_inv_eng(adev);
|
||||
if (r)
|
||||
return r;
|
||||
@ -720,6 +801,10 @@ static int gmc_v10_0_sw_init(void *handle)
|
||||
r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VMC,
|
||||
VMC_1_0__SRCID__VM_FAULT,
|
||||
&adev->gmc.vm_fault);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UTCL2,
|
||||
UTCL2_1_0__SRCID__FAULT,
|
||||
&adev->gmc.vm_fault);
|
||||
@ -732,15 +817,6 @@ static int gmc_v10_0_sw_init(void *handle)
|
||||
*/
|
||||
adev->gmc.mc_mask = 0xffffffffffffULL; /* 48 bit MC */
|
||||
|
||||
/*
|
||||
* Reserve 8M stolen memory for navi10 like vega10
|
||||
* TODO: will check if it's really needed on asic.
|
||||
*/
|
||||
if (amdgpu_emu_mode == 1)
|
||||
adev->gmc.stolen_size = 0;
|
||||
else
|
||||
adev->gmc.stolen_size = 9 * 1024 *1024;
|
||||
|
||||
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44));
|
||||
if (r) {
|
||||
printk(KERN_WARNING "amdgpu: No suitable DMA available.\n");
|
||||
@ -753,6 +829,19 @@ static int gmc_v10_0_sw_init(void *handle)
|
||||
|
||||
adev->gmc.stolen_size = gmc_v10_0_get_vbios_fb_size(adev);
|
||||
|
||||
/*
|
||||
* In dual GPUs scenario, stolen_size is assigned to zero on the
|
||||
* secondary GPU, since there is no pre-OS console using that memory.
|
||||
* Then the bottom region of VRAM was allocated as GTT, unfortunately a
|
||||
* small region of bottom VRAM was encroached by UMC firmware during
|
||||
* GDDR6 BIST training, this cause page fault.
|
||||
* The page fault can be fixed by forcing stolen_size to 3MB, then the
|
||||
* bottom region of VRAM was allocated as stolen memory, GTT corruption
|
||||
* avoid.
|
||||
*/
|
||||
adev->gmc.stolen_size = max(adev->gmc.stolen_size,
|
||||
AMDGPU_STOLEN_BIST_TRAINING_DEFAULT_SIZE);
|
||||
|
||||
/* Memory manager */
|
||||
r = amdgpu_bo_init(adev);
|
||||
if (r)
|
||||
@ -792,6 +881,13 @@ static void gmc_v10_0_gart_fini(struct amdgpu_device *adev)
|
||||
static int gmc_v10_0_sw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
void *stolen_vga_buf;
|
||||
|
||||
/*
|
||||
* Free the stolen memory if it wasn't already freed in late_init
|
||||
* because of memory training.
|
||||
*/
|
||||
amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, &stolen_vga_buf);
|
||||
|
||||
amdgpu_vm_manager_fini(adev);
|
||||
gmc_v10_0_gart_fini(adev);
|
||||
|
@ -418,6 +418,38 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gmc_v7_0_flush_gpu_tlb_pasid - tlb flush via pasid
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @pasid: pasid to be flush
|
||||
*
|
||||
* Flush the TLB for the requested pasid.
|
||||
*/
|
||||
static int gmc_v7_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
|
||||
uint16_t pasid, uint32_t flush_type,
|
||||
bool all_hub)
|
||||
{
|
||||
int vmid;
|
||||
unsigned int tmp;
|
||||
|
||||
if (adev->in_gpu_reset)
|
||||
return -EIO;
|
||||
|
||||
for (vmid = 1; vmid < 16; vmid++) {
|
||||
|
||||
tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
|
||||
if ((tmp & ATC_VMID0_PASID_MAPPING__VALID_MASK) &&
|
||||
(tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid) {
|
||||
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
|
||||
RREG32(mmVM_INVALIDATE_RESPONSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* GART
|
||||
* VMID 0 is the physical GPU addresses as used by the kernel.
|
||||
@ -1333,6 +1365,7 @@ static const struct amd_ip_funcs gmc_v7_0_ip_funcs = {
|
||||
|
||||
static const struct amdgpu_gmc_funcs gmc_v7_0_gmc_funcs = {
|
||||
.flush_gpu_tlb = gmc_v7_0_flush_gpu_tlb,
|
||||
.flush_gpu_tlb_pasid = gmc_v7_0_flush_gpu_tlb_pasid,
|
||||
.emit_flush_gpu_tlb = gmc_v7_0_emit_flush_gpu_tlb,
|
||||
.emit_pasid_mapping = gmc_v7_0_emit_pasid_mapping,
|
||||
.set_prt = gmc_v7_0_set_prt,
|
||||
|
@ -620,6 +620,39 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gmc_v8_0_flush_gpu_tlb_pasid - tlb flush via pasid
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @pasid: pasid to be flush
|
||||
*
|
||||
* Flush the TLB for the requested pasid.
|
||||
*/
|
||||
static int gmc_v8_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
|
||||
uint16_t pasid, uint32_t flush_type,
|
||||
bool all_hub)
|
||||
{
|
||||
int vmid;
|
||||
unsigned int tmp;
|
||||
|
||||
if (adev->in_gpu_reset)
|
||||
return -EIO;
|
||||
|
||||
for (vmid = 1; vmid < 16; vmid++) {
|
||||
|
||||
tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
|
||||
if ((tmp & ATC_VMID0_PASID_MAPPING__VALID_MASK) &&
|
||||
(tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid) {
|
||||
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
|
||||
RREG32(mmVM_INVALIDATE_RESPONSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* GART
|
||||
* VMID 0 is the physical GPU addresses as used by the kernel.
|
||||
@ -1700,6 +1733,7 @@ static const struct amd_ip_funcs gmc_v8_0_ip_funcs = {
|
||||
|
||||
static const struct amdgpu_gmc_funcs gmc_v8_0_gmc_funcs = {
|
||||
.flush_gpu_tlb = gmc_v8_0_flush_gpu_tlb,
|
||||
.flush_gpu_tlb_pasid = gmc_v8_0_flush_gpu_tlb_pasid,
|
||||
.emit_flush_gpu_tlb = gmc_v8_0_emit_flush_gpu_tlb,
|
||||
.emit_pasid_mapping = gmc_v8_0_emit_pasid_mapping,
|
||||
.set_prt = gmc_v8_0_set_prt,
|
||||
|
@ -38,10 +38,12 @@
|
||||
#include "dce/dce_12_0_sh_mask.h"
|
||||
#include "vega10_enum.h"
|
||||
#include "mmhub/mmhub_1_0_offset.h"
|
||||
#include "athub/athub_1_0_sh_mask.h"
|
||||
#include "athub/athub_1_0_offset.h"
|
||||
#include "oss/osssys_4_0_offset.h"
|
||||
|
||||
#include "soc15.h"
|
||||
#include "soc15d.h"
|
||||
#include "soc15_common.h"
|
||||
#include "umc/umc_6_0_sh_mask.h"
|
||||
|
||||
@ -441,6 +443,18 @@ static bool gmc_v9_0_use_invalidate_semaphore(struct amdgpu_device *adev,
|
||||
adev->pdev->device == 0x15d8)));
|
||||
}
|
||||
|
||||
static bool gmc_v9_0_get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
|
||||
uint8_t vmid, uint16_t *p_pasid)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING)
|
||||
+ vmid);
|
||||
*p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
|
||||
|
||||
return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* GART
|
||||
* VMID 0 is the physical GPU addresses as used by the kernel.
|
||||
@ -539,6 +553,67 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
DRM_ERROR("Timeout waiting for VM flush ACK!\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* gmc_v9_0_flush_gpu_tlb_pasid - tlb flush via pasid
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @pasid: pasid to be flush
|
||||
*
|
||||
* Flush the TLB for the requested pasid.
|
||||
*/
|
||||
static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
|
||||
uint16_t pasid, uint32_t flush_type,
|
||||
bool all_hub)
|
||||
{
|
||||
int vmid, i;
|
||||
signed long r;
|
||||
uint32_t seq;
|
||||
uint16_t queried_pasid;
|
||||
bool ret;
|
||||
struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq;
|
||||
|
||||
if (adev->in_gpu_reset)
|
||||
return -EIO;
|
||||
|
||||
if (ring->sched.ready) {
|
||||
spin_lock(&adev->gfx.kiq.ring_lock);
|
||||
amdgpu_ring_alloc(ring, kiq->pmf->invalidate_tlbs_size);
|
||||
kiq->pmf->kiq_invalidate_tlbs(ring,
|
||||
pasid, flush_type, all_hub);
|
||||
amdgpu_fence_emit_polling(ring, &seq);
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock(&adev->gfx.kiq.ring_lock);
|
||||
r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
|
||||
if (r < 1) {
|
||||
DRM_ERROR("wait for kiq fence error: %ld.\n", r);
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (vmid = 1; vmid < 16; vmid++) {
|
||||
|
||||
ret = gmc_v9_0_get_atc_vmid_pasid_mapping_info(adev, vmid,
|
||||
&queried_pasid);
|
||||
if (ret && queried_pasid == pasid) {
|
||||
if (all_hub) {
|
||||
for (i = 0; i < adev->num_vmhubs; i++)
|
||||
gmc_v9_0_flush_gpu_tlb(adev, vmid,
|
||||
i, 0);
|
||||
} else {
|
||||
gmc_v9_0_flush_gpu_tlb(adev, vmid,
|
||||
AMDGPU_GFXHUB_0, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
@ -700,6 +775,7 @@ static void gmc_v9_0_get_vm_pte(struct amdgpu_device *adev,
|
||||
|
||||
static const struct amdgpu_gmc_funcs gmc_v9_0_gmc_funcs = {
|
||||
.flush_gpu_tlb = gmc_v9_0_flush_gpu_tlb,
|
||||
.flush_gpu_tlb_pasid = gmc_v9_0_flush_gpu_tlb_pasid,
|
||||
.emit_flush_gpu_tlb = gmc_v9_0_emit_flush_gpu_tlb,
|
||||
.emit_pasid_mapping = gmc_v9_0_emit_pasid_mapping,
|
||||
.map_mtype = gmc_v9_0_map_mtype,
|
||||
@ -817,8 +893,8 @@ static int gmc_v9_0_late_init(void *handle)
|
||||
r = amdgpu_atomfirmware_mem_ecc_supported(adev);
|
||||
if (!r) {
|
||||
DRM_INFO("ECC is not present.\n");
|
||||
if (adev->df_funcs->enable_ecc_force_par_wr_rmw)
|
||||
adev->df_funcs->enable_ecc_force_par_wr_rmw(adev, false);
|
||||
if (adev->df.funcs->enable_ecc_force_par_wr_rmw)
|
||||
adev->df.funcs->enable_ecc_force_par_wr_rmw(adev, false);
|
||||
} else {
|
||||
DRM_INFO("ECC is active.\n");
|
||||
}
|
||||
@ -1023,7 +1099,7 @@ static int gmc_v9_0_sw_init(void *handle)
|
||||
else
|
||||
chansize = 128;
|
||||
|
||||
numchan = adev->df_funcs->get_hbm_channel_number(adev);
|
||||
numchan = adev->df.funcs->get_hbm_channel_number(adev);
|
||||
adev->gmc.vram_width = numchan * chansize;
|
||||
}
|
||||
|
||||
|
@ -478,7 +478,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP &&
|
||||
is_support_sw_smu(adev) && !amdgpu_sriov_vf(adev))
|
||||
!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
@ -489,7 +489,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block);
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT &&
|
||||
is_support_sw_smu(adev) && !amdgpu_sriov_vf(adev))
|
||||
!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block);
|
||||
@ -502,7 +502,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP &&
|
||||
is_support_sw_smu(adev) && !amdgpu_sriov_vf(adev))
|
||||
!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
@ -513,7 +513,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block);
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT &&
|
||||
is_support_sw_smu(adev) && !amdgpu_sriov_vf(adev))
|
||||
!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block);
|
||||
@ -726,6 +726,12 @@ static int nv_common_early_init(void *handle)
|
||||
AMD_PG_SUPPORT_VCN_DPG |
|
||||
AMD_PG_SUPPORT_JPEG |
|
||||
AMD_PG_SUPPORT_ATHUB;
|
||||
/* guest vm gets 0xffffffff when reading RCC_DEV0_EPF0_STRAP0,
|
||||
* as a consequence, the rev_id and external_rev_id are wrong.
|
||||
* workaround it by hardcoding rev_id to 0 (default value).
|
||||
*/
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
adev->rev_id = 0;
|
||||
adev->external_rev_id = adev->rev_id + 0xa;
|
||||
break;
|
||||
default:
|
||||
|
@ -43,10 +43,13 @@ MODULE_FIRMWARE("amdgpu/vega20_asd.bin");
|
||||
MODULE_FIRMWARE("amdgpu/vega20_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi10_sos.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi10_asd.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi10_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi14_sos.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi14_asd.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi14_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi12_sos.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi12_asd.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi12_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/arcturus_sos.bin");
|
||||
MODULE_FIRMWARE("amdgpu/arcturus_asd.bin");
|
||||
MODULE_FIRMWARE("amdgpu/arcturus_ta.bin");
|
||||
|
@ -82,6 +82,7 @@ static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev);
|
||||
static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev);
|
||||
static void sdma_v4_0_set_vm_pte_funcs(struct amdgpu_device *adev);
|
||||
static void sdma_v4_0_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static void sdma_v4_0_set_ras_funcs(struct amdgpu_device *adev);
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma_4[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_CHICKEN_BITS, 0xfe931f07, 0x02831d07),
|
||||
@ -254,7 +255,106 @@ static const struct soc15_reg_golden golden_settings_sdma_4_3[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x00000000)
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x03fbe1fe)
|
||||
};
|
||||
|
||||
static const struct soc15_ras_field_entry sdma_v4_0_ras_fields[] = {
|
||||
{ "SDMA_UCODE_BUF_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_UCODE_BUF_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_RB_CMD_BUF_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_RB_CMD_BUF_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_IB_CMD_BUF_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_IB_CMD_BUF_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_UTCL1_RD_FIFO_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_UTCL1_RD_FIFO_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_UTCL1_RDBST_FIFO_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_UTCL1_RDBST_FIFO_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_DATA_LUT_FIFO_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_DATA_LUT_FIFO_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF0_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF0_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF1_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF1_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF2_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF2_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF3_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF3_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF4_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF4_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF5_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF5_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF6_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF6_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF7_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF7_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF8_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF8_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF9_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF9_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF10_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF10_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF11_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF11_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF12_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF12_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF13_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF13_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF14_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF14_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MBANK_DATA_BUF15_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MBANK_DATA_BUF15_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_SPLIT_DAT_BUF_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_SPLIT_DAT_BUF_SED),
|
||||
0, 0,
|
||||
},
|
||||
{ "SDMA_MC_WR_ADDR_FIFO_SED", SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_EDC_COUNTER),
|
||||
SOC15_REG_FIELD(SDMA0_EDC_COUNTER, SDMA_MC_WR_ADDR_FIFO_SED),
|
||||
0, 0,
|
||||
},
|
||||
};
|
||||
|
||||
static u32 sdma_v4_0_get_reg_offset(struct amdgpu_device *adev,
|
||||
@ -1686,6 +1786,7 @@ static int sdma_v4_0_early_init(void *handle)
|
||||
sdma_v4_0_set_buffer_funcs(adev);
|
||||
sdma_v4_0_set_vm_pte_funcs(adev);
|
||||
sdma_v4_0_set_irq_funcs(adev);
|
||||
sdma_v4_0_set_ras_funcs(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1700,8 +1801,18 @@ static int sdma_v4_0_late_init(void *handle)
|
||||
struct ras_ih_if ih_info = {
|
||||
.cb = sdma_v4_0_process_ras_data_cb,
|
||||
};
|
||||
int i;
|
||||
|
||||
return amdgpu_sdma_ras_late_init(adev, &ih_info);
|
||||
/* read back edc counter registers to clear the counters */
|
||||
if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__SDMA)) {
|
||||
for (i = 0; i < adev->sdma.num_instances; i++)
|
||||
RREG32_SDMA(i, mmSDMA0_EDC_COUNTER);
|
||||
}
|
||||
|
||||
if (adev->sdma.funcs && adev->sdma.funcs->ras_late_init)
|
||||
return adev->sdma.funcs->ras_late_init(adev, &ih_info);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdma_v4_0_sw_init(void *handle)
|
||||
@ -1773,7 +1884,8 @@ static int sdma_v4_0_sw_fini(void *handle)
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int i;
|
||||
|
||||
amdgpu_sdma_ras_fini(adev);
|
||||
if (adev->sdma.funcs && adev->sdma.funcs->ras_fini)
|
||||
adev->sdma.funcs->ras_fini(adev);
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
amdgpu_ring_fini(&adev->sdma.instance[i].ring);
|
||||
@ -2414,6 +2526,70 @@ static void sdma_v4_0_set_vm_pte_funcs(struct amdgpu_device *adev)
|
||||
adev->vm_manager.vm_pte_num_scheds = adev->sdma.num_instances;
|
||||
}
|
||||
|
||||
static void sdma_v4_0_get_ras_error_count(uint32_t value,
|
||||
uint32_t instance,
|
||||
uint32_t *sec_count)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t sec_cnt;
|
||||
|
||||
/* double bits error (multiple bits) error detection is not supported */
|
||||
for (i = 0; i < ARRAY_SIZE(sdma_v4_0_ras_fields); i++) {
|
||||
/* the SDMA_EDC_COUNTER register in each sdma instance
|
||||
* shares the same sed shift_mask
|
||||
* */
|
||||
sec_cnt = (value &
|
||||
sdma_v4_0_ras_fields[i].sec_count_mask) >>
|
||||
sdma_v4_0_ras_fields[i].sec_count_shift;
|
||||
if (sec_cnt) {
|
||||
DRM_INFO("Detected %s in SDMA%d, SED %d\n",
|
||||
sdma_v4_0_ras_fields[i].name,
|
||||
instance, sec_cnt);
|
||||
*sec_count += sec_cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int sdma_v4_0_query_ras_error_count(struct amdgpu_device *adev,
|
||||
uint32_t instance, void *ras_error_status)
|
||||
{
|
||||
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
|
||||
uint32_t sec_count = 0;
|
||||
uint32_t reg_value = 0;
|
||||
|
||||
reg_value = RREG32_SDMA(instance, mmSDMA0_EDC_COUNTER);
|
||||
/* double bit error is not supported */
|
||||
if (reg_value)
|
||||
sdma_v4_0_get_ras_error_count(reg_value,
|
||||
instance, &sec_count);
|
||||
/* err_data->ce_count should be initialized to 0
|
||||
* before calling into this function */
|
||||
err_data->ce_count += sec_count;
|
||||
/* double bit error is not supported
|
||||
* set ue count to 0 */
|
||||
err_data->ue_count = 0;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static const struct amdgpu_sdma_ras_funcs sdma_v4_0_ras_funcs = {
|
||||
.ras_late_init = amdgpu_sdma_ras_late_init,
|
||||
.ras_fini = amdgpu_sdma_ras_fini,
|
||||
.query_ras_error_count = sdma_v4_0_query_ras_error_count,
|
||||
};
|
||||
|
||||
static void sdma_v4_0_set_ras_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_ARCTURUS:
|
||||
adev->sdma.funcs = &sdma_v4_0_ras_funcs;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version sdma_v4_0_ip_block = {
|
||||
.type = AMD_IP_BLOCK_TYPE_SDMA,
|
||||
.major = 4,
|
||||
|
@ -479,62 +479,18 @@ static int soc15_asic_mode1_reset(struct amdgpu_device *adev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int soc15_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap)
|
||||
{
|
||||
if (is_support_sw_smu(adev)) {
|
||||
struct smu_context *smu = &adev->smu;
|
||||
|
||||
*cap = smu_baco_is_support(smu);
|
||||
return 0;
|
||||
} else {
|
||||
void *pp_handle = adev->powerplay.pp_handle;
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
|
||||
if (!pp_funcs || !pp_funcs->get_asic_baco_capability) {
|
||||
*cap = false;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
return pp_funcs->get_asic_baco_capability(pp_handle, cap);
|
||||
}
|
||||
}
|
||||
|
||||
static int soc15_asic_baco_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
|
||||
int ret = 0;
|
||||
|
||||
/* avoid NBIF got stuck when do RAS recovery in BACO reset */
|
||||
if (ras && ras->supported)
|
||||
adev->nbio.funcs->enable_doorbell_interrupt(adev, false);
|
||||
|
||||
dev_info(adev->dev, "GPU BACO reset\n");
|
||||
|
||||
if (is_support_sw_smu(adev)) {
|
||||
struct smu_context *smu = &adev->smu;
|
||||
int ret;
|
||||
|
||||
ret = smu_baco_enter(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = smu_baco_exit(smu);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
void *pp_handle = adev->powerplay.pp_handle;
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
|
||||
if (!pp_funcs ||!pp_funcs->get_asic_baco_state ||!pp_funcs->set_asic_baco_state)
|
||||
return -ENOENT;
|
||||
|
||||
/* enter BACO state */
|
||||
if (pp_funcs->set_asic_baco_state(pp_handle, 1))
|
||||
return -EIO;
|
||||
|
||||
/* exit BACO state */
|
||||
if (pp_funcs->set_asic_baco_state(pp_handle, 0))
|
||||
return -EIO;
|
||||
}
|
||||
ret = amdgpu_dpm_baco_reset(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* re-enable doorbell interrupt after BACO exit */
|
||||
if (ras && ras->supported)
|
||||
@ -543,17 +499,6 @@ static int soc15_asic_baco_reset(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int soc15_mode2_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
if (is_support_sw_smu(adev))
|
||||
return smu_mode2_reset(&adev->smu);
|
||||
if (!adev->powerplay.pp_funcs ||
|
||||
!adev->powerplay.pp_funcs->asic_reset_mode_2)
|
||||
return -ENOENT;
|
||||
|
||||
return adev->powerplay.pp_funcs->asic_reset_mode_2(adev->powerplay.pp_handle);
|
||||
}
|
||||
|
||||
static enum amd_reset_method
|
||||
soc15_asic_reset_method(struct amdgpu_device *adev)
|
||||
{
|
||||
@ -567,11 +512,11 @@ soc15_asic_reset_method(struct amdgpu_device *adev)
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_ARCTURUS:
|
||||
soc15_asic_get_baco_capability(adev, &baco_reset);
|
||||
baco_reset = amdgpu_dpm_is_baco_supported(adev);
|
||||
break;
|
||||
case CHIP_VEGA20:
|
||||
if (adev->psp.sos_fw_version >= 0x80067)
|
||||
soc15_asic_get_baco_capability(adev, &baco_reset);
|
||||
baco_reset = amdgpu_dpm_is_baco_supported(adev);
|
||||
|
||||
/*
|
||||
* 1. PMFW version > 0x284300: all cases use baco
|
||||
@ -598,7 +543,7 @@ static int soc15_asic_reset(struct amdgpu_device *adev)
|
||||
amdgpu_inc_vram_lost(adev);
|
||||
return soc15_asic_baco_reset(adev);
|
||||
case AMD_RESET_METHOD_MODE2:
|
||||
return soc15_mode2_reset(adev);
|
||||
return amdgpu_dpm_mode2_reset(adev);
|
||||
default:
|
||||
if (!adev->in_suspend)
|
||||
amdgpu_inc_vram_lost(adev);
|
||||
@ -608,25 +553,18 @@ static int soc15_asic_reset(struct amdgpu_device *adev)
|
||||
|
||||
static bool soc15_supports_baco(struct amdgpu_device *adev)
|
||||
{
|
||||
bool baco_support;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_ARCTURUS:
|
||||
soc15_asic_get_baco_capability(adev, &baco_support);
|
||||
break;
|
||||
return amdgpu_dpm_is_baco_supported(adev);
|
||||
case CHIP_VEGA20:
|
||||
if (adev->psp.sos_fw_version >= 0x80067)
|
||||
soc15_asic_get_baco_capability(adev, &baco_support);
|
||||
else
|
||||
baco_support = false;
|
||||
break;
|
||||
return amdgpu_dpm_is_baco_supported(adev);
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return baco_support;
|
||||
}
|
||||
|
||||
/*static int soc15_set_uvd_clock(struct amdgpu_device *adev, u32 clock,
|
||||
@ -739,9 +677,9 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
||||
}
|
||||
|
||||
if (adev->asic_type == CHIP_VEGA20 || adev->asic_type == CHIP_ARCTURUS)
|
||||
adev->df_funcs = &df_v3_6_funcs;
|
||||
adev->df.funcs = &df_v3_6_funcs;
|
||||
else
|
||||
adev->df_funcs = &df_v1_7_funcs;
|
||||
adev->df.funcs = &df_v1_7_funcs;
|
||||
|
||||
adev->rev_id = soc15_get_rev_id(adev);
|
||||
adev->nbio.funcs->detect_hw_virt(adev);
|
||||
@ -834,8 +772,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block);
|
||||
} else {
|
||||
if (unlikely(adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT))
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block);
|
||||
}
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v2_5_ip_block);
|
||||
@ -846,8 +783,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
|
||||
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
amdgpu_device_ip_block_add(adev, &psp_v12_0_ip_block);
|
||||
if (is_support_sw_smu(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v12_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &smu_v12_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
@ -1311,7 +1247,7 @@ static int soc15_common_sw_init(void *handle)
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
xgpu_ai_mailbox_add_irq_id(adev);
|
||||
|
||||
adev->df_funcs->sw_init(adev);
|
||||
adev->df.funcs->sw_init(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1321,7 +1257,7 @@ static int soc15_common_sw_fini(void *handle)
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
amdgpu_nbio_ras_fini(adev);
|
||||
adev->df_funcs->sw_fini(adev);
|
||||
adev->df.funcs->sw_fini(adev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1542,7 +1478,7 @@ static int soc15_common_set_clockgating_state(void *handle,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
soc15_update_rom_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
adev->df_funcs->update_medium_grain_clock_gating(adev,
|
||||
adev->df.funcs->update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
@ -1600,7 +1536,7 @@ static void soc15_common_get_clockgating_state(void *handle, u32 *flags)
|
||||
if (!(data & CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK))
|
||||
*flags |= AMD_CG_SUPPORT_ROM_MGCG;
|
||||
|
||||
adev->df_funcs->get_clockgating_state(adev, flags);
|
||||
adev->df.funcs->get_clockgating_state(adev, flags);
|
||||
}
|
||||
|
||||
static int soc15_common_set_powergating_state(void *handle,
|
||||
|
@ -30,8 +30,6 @@
|
||||
#include "umc/umc_6_1_1_sh_mask.h"
|
||||
#include "umc/umc_6_1_2_offset.h"
|
||||
|
||||
#define smnMCA_UMC0_MCUMC_ADDRT0 0x50f10
|
||||
|
||||
#define UMC_6_INST_DIST 0x40000
|
||||
|
||||
/*
|
||||
@ -56,12 +54,30 @@ const uint32_t
|
||||
{9, 25, 0, 16}, {15, 31, 6, 22}
|
||||
};
|
||||
|
||||
static void umc_v6_1_enable_umc_index_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
WREG32_FIELD15(RSMU, 0, RSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU,
|
||||
RSMU_UMC_INDEX_MODE_EN, 1);
|
||||
}
|
||||
|
||||
static void umc_v6_1_disable_umc_index_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
WREG32_FIELD15(RSMU, 0, RSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU,
|
||||
RSMU_UMC_INDEX_MODE_EN, 0);
|
||||
}
|
||||
|
||||
static uint32_t umc_v6_1_get_umc_index_mode_state(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t rsmu_umc_index;
|
||||
|
||||
rsmu_umc_index = RREG32_SOC15(RSMU, 0,
|
||||
mmRSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU);
|
||||
|
||||
return REG_GET_FIELD(rsmu_umc_index,
|
||||
RSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU,
|
||||
RSMU_UMC_INDEX_MODE_EN);
|
||||
}
|
||||
|
||||
static inline uint32_t get_umc_6_reg_offset(struct amdgpu_device *adev,
|
||||
uint32_t umc_inst,
|
||||
uint32_t ch_inst)
|
||||
@ -165,6 +181,11 @@ static void umc_v6_1_query_ras_error_count(struct amdgpu_device *adev,
|
||||
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,
|
||||
@ -177,6 +198,9 @@ static void umc_v6_1_query_ras_error_count(struct amdgpu_device *adev,
|
||||
umc_reg_offset,
|
||||
&(err_data->ue_count));
|
||||
}
|
||||
|
||||
if (rsmu_umc_index_state)
|
||||
umc_v6_1_enable_umc_index_mode(adev);
|
||||
}
|
||||
|
||||
static void umc_v6_1_query_error_address(struct amdgpu_device *adev,
|
||||
@ -186,7 +210,7 @@ static void umc_v6_1_query_error_address(struct amdgpu_device *adev,
|
||||
uint32_t umc_inst)
|
||||
{
|
||||
uint32_t lsb, mc_umc_status_addr;
|
||||
uint64_t mc_umc_status, err_addr, retired_page;
|
||||
uint64_t mc_umc_status, err_addr, retired_page, mc_umc_addrt0;
|
||||
struct eeprom_table_record *err_rec;
|
||||
uint32_t channel_index = adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
|
||||
|
||||
@ -194,10 +218,14 @@ static void umc_v6_1_query_error_address(struct amdgpu_device *adev,
|
||||
/* UMC 6_1_2 registers */
|
||||
mc_umc_status_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_STATUST0_ARCT);
|
||||
mc_umc_addrt0 =
|
||||
SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_ADDRT0_ARCT);
|
||||
} else {
|
||||
/* UMC 6_1_1 registers */
|
||||
mc_umc_status_addr =
|
||||
SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_STATUST0);
|
||||
mc_umc_addrt0 =
|
||||
SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_ADDRT0);
|
||||
}
|
||||
|
||||
/* skip error address process if -ENOMEM */
|
||||
@ -214,8 +242,8 @@ static void umc_v6_1_query_error_address(struct amdgpu_device *adev,
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) {
|
||||
err_addr = RREG64_PCIE(smnMCA_UMC0_MCUMC_ADDRT0 + umc_reg_offset * 4);
|
||||
|
||||
err_addr = RREG64_PCIE((mc_umc_addrt0 + umc_reg_offset) * 4);
|
||||
/* the lowest lsb bits should be ignored */
|
||||
lsb = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, LSB);
|
||||
err_addr = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
|
||||
@ -255,6 +283,11 @@ static void umc_v6_1_query_ras_error_address(struct amdgpu_device *adev,
|
||||
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,
|
||||
@ -267,6 +300,8 @@ static void umc_v6_1_query_ras_error_address(struct amdgpu_device *adev,
|
||||
umc_inst);
|
||||
}
|
||||
|
||||
if (rsmu_umc_index_state)
|
||||
umc_v6_1_enable_umc_index_mode(adev);
|
||||
}
|
||||
|
||||
static void umc_v6_1_err_cnt_init_per_channel(struct amdgpu_device *adev,
|
||||
@ -313,7 +348,10 @@ static void umc_v6_1_err_cnt_init(struct amdgpu_device *adev)
|
||||
uint32_t ch_inst = 0;
|
||||
uint32_t umc_reg_offset = 0;
|
||||
|
||||
umc_v6_1_disable_umc_index_mode(adev);
|
||||
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,
|
||||
@ -322,6 +360,9 @@ static void umc_v6_1_err_cnt_init(struct amdgpu_device *adev)
|
||||
|
||||
umc_v6_1_err_cnt_init_per_channel(adev, umc_reg_offset);
|
||||
}
|
||||
|
||||
if (rsmu_umc_index_state)
|
||||
umc_v6_1_enable_umc_index_mode(adev);
|
||||
}
|
||||
|
||||
const struct amdgpu_umc_funcs umc_v6_1_funcs = {
|
||||
|
@ -39,10 +39,10 @@
|
||||
#include "ivsrcid/vcn/irqsrcs_vcn_1_0.h"
|
||||
#include "jpeg_v1_0.h"
|
||||
|
||||
#define mmUVD_RBC_XX_IB_REG_CHECK 0x05ab
|
||||
#define mmUVD_RBC_XX_IB_REG_CHECK_BASE_IDX 1
|
||||
#define mmUVD_REG_XX_MASK 0x05ac
|
||||
#define mmUVD_REG_XX_MASK_BASE_IDX 1
|
||||
#define mmUVD_RBC_XX_IB_REG_CHECK_1_0 0x05ab
|
||||
#define mmUVD_RBC_XX_IB_REG_CHECK_1_0_BASE_IDX 1
|
||||
#define mmUVD_REG_XX_MASK_1_0 0x05ac
|
||||
#define mmUVD_REG_XX_MASK_1_0_BASE_IDX 1
|
||||
|
||||
static int vcn_v1_0_stop(struct amdgpu_device *adev);
|
||||
static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
|
||||
@ -50,7 +50,7 @@ static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev);
|
||||
static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static int vcn_v1_0_set_powergating_state(void *handle, enum amd_powergating_state state);
|
||||
static int vcn_v1_0_pause_dpg_mode(struct amdgpu_device *adev,
|
||||
struct dpg_pause_state *new_state);
|
||||
int inst_idx, struct dpg_pause_state *new_state);
|
||||
|
||||
static void vcn_v1_0_idle_work_handler(struct work_struct *work);
|
||||
|
||||
@ -835,9 +835,9 @@ static int vcn_v1_0_start_spg_mode(struct amdgpu_device *adev)
|
||||
|
||||
vcn_v1_0_mc_resume_spg_mode(adev);
|
||||
|
||||
WREG32_SOC15(UVD, 0, mmUVD_REG_XX_MASK, 0x10);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK,
|
||||
RREG32_SOC15(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK) | 0x3);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_REG_XX_MASK_1_0, 0x10);
|
||||
WREG32_SOC15(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK_1_0,
|
||||
RREG32_SOC15(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK_1_0) | 0x3);
|
||||
|
||||
/* enable VCPU clock */
|
||||
WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, UVD_VCPU_CNTL__CLK_EN_MASK);
|
||||
@ -1199,7 +1199,7 @@ static int vcn_v1_0_stop(struct amdgpu_device *adev)
|
||||
}
|
||||
|
||||
static int vcn_v1_0_pause_dpg_mode(struct amdgpu_device *adev,
|
||||
struct dpg_pause_state *new_state)
|
||||
int inst_idx, struct dpg_pause_state *new_state)
|
||||
{
|
||||
int ret_code;
|
||||
uint32_t reg_data = 0;
|
||||
@ -1786,7 +1786,7 @@ static void vcn_v1_0_idle_work_handler(struct work_struct *work)
|
||||
else
|
||||
new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
|
||||
|
||||
adev->vcn.pause_dpg_mode(adev, &new_state);
|
||||
adev->vcn.pause_dpg_mode(adev, 0, &new_state);
|
||||
}
|
||||
|
||||
fences += amdgpu_fence_count_emitted(&adev->jpeg.inst->ring_dec);
|
||||
@ -1840,7 +1840,7 @@ void vcn_v1_0_ring_begin_use(struct amdgpu_ring *ring)
|
||||
else if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG)
|
||||
new_state.jpeg = VCN_DPG_STATE__PAUSE;
|
||||
|
||||
adev->vcn.pause_dpg_mode(adev, &new_state);
|
||||
adev->vcn.pause_dpg_mode(adev, 0, &new_state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,18 +47,13 @@
|
||||
#define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x5a7
|
||||
#define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x1e2
|
||||
|
||||
#define mmUVD_RBC_XX_IB_REG_CHECK 0x026b
|
||||
#define mmUVD_RBC_XX_IB_REG_CHECK_BASE_IDX 1
|
||||
#define mmUVD_REG_XX_MASK 0x026c
|
||||
#define mmUVD_REG_XX_MASK_BASE_IDX 1
|
||||
|
||||
static void vcn_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev);
|
||||
static void vcn_v2_0_set_enc_ring_funcs(struct amdgpu_device *adev);
|
||||
static void vcn_v2_0_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static int vcn_v2_0_set_powergating_state(void *handle,
|
||||
enum amd_powergating_state state);
|
||||
static int vcn_v2_0_pause_dpg_mode(struct amdgpu_device *adev,
|
||||
struct dpg_pause_state *new_state);
|
||||
int inst_idx, struct dpg_pause_state *new_state);
|
||||
|
||||
/**
|
||||
* vcn_v2_0_early_init - set function pointers
|
||||
@ -356,88 +351,88 @@ static void vcn_v2_0_mc_resume_dpg_mode(struct amdgpu_device *adev, bool indirec
|
||||
/* cache window 0: fw */
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
if (!indirect) {
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
|
||||
(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
|
||||
(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
|
||||
} else {
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
|
||||
}
|
||||
offset = 0;
|
||||
} else {
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
|
||||
lower_32_bits(adev->vcn.inst->gpu_addr), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
|
||||
upper_32_bits(adev->vcn.inst->gpu_addr), 0, indirect);
|
||||
offset = size;
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_VCPU_CACHE_OFFSET0),
|
||||
AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect);
|
||||
}
|
||||
|
||||
if (!indirect)
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_VCPU_CACHE_SIZE0), size, 0, indirect);
|
||||
else
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_VCPU_CACHE_SIZE0), 0, 0, indirect);
|
||||
|
||||
/* cache window 1: stack */
|
||||
if (!indirect) {
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
|
||||
lower_32_bits(adev->vcn.inst->gpu_addr + offset), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
|
||||
upper_32_bits(adev->vcn.inst->gpu_addr + offset), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
|
||||
} else {
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
|
||||
}
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect);
|
||||
|
||||
/* cache window 2: context */
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
|
||||
lower_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
|
||||
upper_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect);
|
||||
|
||||
/* non-cache window */
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_VCPU_NONCACHE_SIZE0), 0, 0, indirect);
|
||||
|
||||
/* VCN global tiling registers */
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_GFX10_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
|
||||
}
|
||||
|
||||
@ -583,19 +578,19 @@ static void vcn_v2_0_clock_gating_dpg_mode(struct amdgpu_device *adev,
|
||||
UVD_CGC_CTRL__WCB_MODE_MASK |
|
||||
UVD_CGC_CTRL__VCPU_MODE_MASK |
|
||||
UVD_CGC_CTRL__SCPU_MODE_MASK);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_CGC_CTRL), reg_data, sram_sel, indirect);
|
||||
|
||||
/* turn off clock gating */
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_CGC_GATE), 0, sram_sel, indirect);
|
||||
|
||||
/* turn on SUVD clock gating */
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_SUVD_CGC_GATE), 1, sram_sel, indirect);
|
||||
|
||||
/* turn on sw mode in UVD_SUVD_CGC_CTRL */
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect);
|
||||
}
|
||||
|
||||
@ -759,7 +754,7 @@ static int vcn_v2_0_start_dpg_mode(struct amdgpu_device *adev, bool indirect)
|
||||
WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, tmp);
|
||||
|
||||
if (indirect)
|
||||
adev->vcn.dpg_sram_curr_addr = (uint32_t*)adev->vcn.dpg_sram_cpu_addr;
|
||||
adev->vcn.inst->dpg_sram_curr_addr = (uint32_t*)adev->vcn.inst->dpg_sram_cpu_addr;
|
||||
|
||||
/* enable clock gating */
|
||||
vcn_v2_0_clock_gating_dpg_mode(adev, 0, indirect);
|
||||
@ -768,11 +763,11 @@ static int vcn_v2_0_start_dpg_mode(struct amdgpu_device *adev, bool indirect)
|
||||
tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
|
||||
tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
|
||||
tmp |= UVD_VCPU_CNTL__MIF_WR_LOW_THRESHOLD_BP_MASK;
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_VCPU_CNTL), tmp, 0, indirect);
|
||||
|
||||
/* disable master interupt */
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_MASTINT_EN), 0, 0, indirect);
|
||||
|
||||
/* setup mmUVD_LMI_CTRL */
|
||||
@ -784,28 +779,28 @@ static int vcn_v2_0_start_dpg_mode(struct amdgpu_device *adev, bool indirect)
|
||||
UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
|
||||
(8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
|
||||
0x00100000L);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_CTRL), tmp, 0, indirect);
|
||||
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_MPC_CNTL),
|
||||
0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect);
|
||||
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_MPC_SET_MUXA0),
|
||||
((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
|
||||
(0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
|
||||
(0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
|
||||
(0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect);
|
||||
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_MPC_SET_MUXB0),
|
||||
((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
|
||||
(0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
|
||||
(0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
|
||||
(0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect);
|
||||
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_MPC_SET_MUX),
|
||||
((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
|
||||
(0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
|
||||
@ -813,29 +808,29 @@ static int vcn_v2_0_start_dpg_mode(struct amdgpu_device *adev, bool indirect)
|
||||
|
||||
vcn_v2_0_mc_resume_dpg_mode(adev, indirect);
|
||||
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_REG_XX_MASK), 0x10, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK), 0x3, 0, indirect);
|
||||
|
||||
/* release VCPU reset to boot */
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_SOFT_RESET), 0, 0, indirect);
|
||||
|
||||
/* enable LMI MC and UMC channels */
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_LMI_CTRL2),
|
||||
0x1F << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT, 0, indirect);
|
||||
|
||||
/* enable master interrupt */
|
||||
WREG32_SOC15_DPG_MODE_2_0(SOC15_DPG_MODE_OFFSET_2_0(
|
||||
WREG32_SOC15_DPG_MODE_2_0(0, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, 0, mmUVD_MASTINT_EN),
|
||||
UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect);
|
||||
|
||||
if (indirect)
|
||||
psp_update_vcn_sram(adev, 0, adev->vcn.dpg_sram_gpu_addr,
|
||||
(uint32_t)((uintptr_t)adev->vcn.dpg_sram_curr_addr -
|
||||
(uintptr_t)adev->vcn.dpg_sram_cpu_addr));
|
||||
psp_update_vcn_sram(adev, 0, adev->vcn.inst->dpg_sram_gpu_addr,
|
||||
(uint32_t)((uintptr_t)adev->vcn.inst->dpg_sram_curr_addr -
|
||||
(uintptr_t)adev->vcn.inst->dpg_sram_cpu_addr));
|
||||
|
||||
/* force RBC into idle state */
|
||||
rb_bufsz = order_base_2(ring->ring_size);
|
||||
@ -1135,7 +1130,7 @@ power_off:
|
||||
}
|
||||
|
||||
static int vcn_v2_0_pause_dpg_mode(struct amdgpu_device *adev,
|
||||
struct dpg_pause_state *new_state)
|
||||
int inst_idx, struct dpg_pause_state *new_state)
|
||||
{
|
||||
struct amdgpu_ring *ring;
|
||||
uint32_t reg_data = 0;
|
||||
|
@ -55,6 +55,8 @@ static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev);
|
||||
static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static int vcn_v2_5_set_powergating_state(void *handle,
|
||||
enum amd_powergating_state state);
|
||||
static int vcn_v2_5_pause_dpg_mode(struct amdgpu_device *adev,
|
||||
int inst_idx, struct dpg_pause_state *new_state);
|
||||
static int vcn_v2_5_sriov_start(struct amdgpu_device *adev);
|
||||
|
||||
static int amdgpu_ih_clientid_vcns[] = {
|
||||
@ -212,6 +214,9 @@ static int vcn_v2_5_sw_init(void *handle)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
|
||||
adev->vcn.pause_dpg_mode = vcn_v2_5_pause_dpg_mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -286,7 +291,8 @@ static int vcn_v2_5_hw_init(void *handle)
|
||||
|
||||
done:
|
||||
if (!r)
|
||||
DRM_INFO("VCN decode and encode initialized successfully.\n");
|
||||
DRM_INFO("VCN decode and encode initialized successfully(under %s).\n",
|
||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)?"DPG Mode":"SPG Mode");
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -309,7 +315,9 @@ static int vcn_v2_5_hw_fini(void *handle)
|
||||
continue;
|
||||
ring = &adev->vcn.inst[i].ring_dec;
|
||||
|
||||
if (RREG32_SOC15(VCN, i, mmUVD_STATUS))
|
||||
if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
|
||||
(adev->vcn.cur_state != AMD_PG_STATE_GATE &&
|
||||
RREG32_SOC15(VCN, i, mmUVD_STATUS)))
|
||||
vcn_v2_5_set_powergating_state(adev, AMD_PG_STATE_GATE);
|
||||
|
||||
ring->sched.ready = false;
|
||||
@ -384,9 +392,9 @@ static void vcn_v2_5_mc_resume(struct amdgpu_device *adev)
|
||||
/* cache window 0: fw */
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
|
||||
(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo));
|
||||
(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo));
|
||||
WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
|
||||
(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi));
|
||||
(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi));
|
||||
WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET0, 0);
|
||||
offset = 0;
|
||||
} else {
|
||||
@ -418,6 +426,99 @@ static void vcn_v2_5_mc_resume(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
static void vcn_v2_5_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
|
||||
{
|
||||
uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
|
||||
uint32_t offset;
|
||||
|
||||
/* cache window 0: fw */
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
if (!indirect) {
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
|
||||
(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_lo), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
|
||||
(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_hi), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
|
||||
} else {
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
|
||||
}
|
||||
offset = 0;
|
||||
} else {
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
|
||||
lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
|
||||
upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
|
||||
offset = size;
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_CACHE_OFFSET0),
|
||||
AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect);
|
||||
}
|
||||
|
||||
if (!indirect)
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_CACHE_SIZE0), size, 0, indirect);
|
||||
else
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_CACHE_SIZE0), 0, 0, indirect);
|
||||
|
||||
/* cache window 1: stack */
|
||||
if (!indirect) {
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
|
||||
lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
|
||||
upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
|
||||
} else {
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
|
||||
}
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect);
|
||||
|
||||
/* cache window 2: context */
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
|
||||
lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
|
||||
upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect);
|
||||
|
||||
/* non-cache window */
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_NONCACHE_SIZE0), 0, 0, indirect);
|
||||
|
||||
/* VCN global tiling registers */
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_GFX8_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
|
||||
}
|
||||
|
||||
/**
|
||||
* vcn_v2_5_disable_clock_gating - disable VCN clock gating
|
||||
*
|
||||
@ -536,6 +637,54 @@ static void vcn_v2_5_disable_clock_gating(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
static void vcn_v2_5_clock_gating_dpg_mode(struct amdgpu_device *adev,
|
||||
uint8_t sram_sel, int inst_idx, uint8_t indirect)
|
||||
{
|
||||
uint32_t reg_data = 0;
|
||||
|
||||
/* enable sw clock gating control */
|
||||
if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
|
||||
reg_data = 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
|
||||
else
|
||||
reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
|
||||
reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
|
||||
reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
|
||||
reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |
|
||||
UVD_CGC_CTRL__UDEC_CM_MODE_MASK |
|
||||
UVD_CGC_CTRL__UDEC_IT_MODE_MASK |
|
||||
UVD_CGC_CTRL__UDEC_DB_MODE_MASK |
|
||||
UVD_CGC_CTRL__UDEC_MP_MODE_MASK |
|
||||
UVD_CGC_CTRL__SYS_MODE_MASK |
|
||||
UVD_CGC_CTRL__UDEC_MODE_MASK |
|
||||
UVD_CGC_CTRL__MPEG2_MODE_MASK |
|
||||
UVD_CGC_CTRL__REGS_MODE_MASK |
|
||||
UVD_CGC_CTRL__RBC_MODE_MASK |
|
||||
UVD_CGC_CTRL__LMI_MC_MODE_MASK |
|
||||
UVD_CGC_CTRL__LMI_UMC_MODE_MASK |
|
||||
UVD_CGC_CTRL__IDCT_MODE_MASK |
|
||||
UVD_CGC_CTRL__MPRD_MODE_MASK |
|
||||
UVD_CGC_CTRL__MPC_MODE_MASK |
|
||||
UVD_CGC_CTRL__LBSI_MODE_MASK |
|
||||
UVD_CGC_CTRL__LRBBM_MODE_MASK |
|
||||
UVD_CGC_CTRL__WCB_MODE_MASK |
|
||||
UVD_CGC_CTRL__VCPU_MODE_MASK |
|
||||
UVD_CGC_CTRL__MMSCH_MODE_MASK);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_CGC_CTRL), reg_data, sram_sel, indirect);
|
||||
|
||||
/* turn off clock gating */
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_CGC_GATE), 0, sram_sel, indirect);
|
||||
|
||||
/* turn on SUVD clock gating */
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_SUVD_CGC_GATE), 1, sram_sel, indirect);
|
||||
|
||||
/* turn on sw mode in UVD_SUVD_CGC_CTRL */
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect);
|
||||
}
|
||||
|
||||
/**
|
||||
* vcn_v2_5_enable_clock_gating - enable VCN clock gating
|
||||
*
|
||||
@ -598,6 +747,138 @@ static void vcn_v2_5_enable_clock_gating(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
static int vcn_v2_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
|
||||
{
|
||||
struct amdgpu_ring *ring;
|
||||
uint32_t rb_bufsz, tmp;
|
||||
|
||||
/* disable register anti-hang mechanism */
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, inst_idx, mmUVD_POWER_STATUS), 1,
|
||||
~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
|
||||
/* enable dynamic power gating mode */
|
||||
tmp = RREG32_SOC15(UVD, inst_idx, mmUVD_POWER_STATUS);
|
||||
tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;
|
||||
tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK;
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_POWER_STATUS, tmp);
|
||||
|
||||
if (indirect)
|
||||
adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t*)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr;
|
||||
|
||||
/* enable clock gating */
|
||||
vcn_v2_5_clock_gating_dpg_mode(adev, 0, inst_idx, indirect);
|
||||
|
||||
/* enable VCPU clock */
|
||||
tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
|
||||
tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
|
||||
tmp |= UVD_VCPU_CNTL__BLK_RST_MASK;
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_CNTL), tmp, 0, indirect);
|
||||
|
||||
/* disable master interupt */
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_MASTINT_EN), 0, 0, indirect);
|
||||
|
||||
/* setup mmUVD_LMI_CTRL */
|
||||
tmp = (0x8 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
|
||||
UVD_LMI_CTRL__REQ_MODE_MASK |
|
||||
UVD_LMI_CTRL__CRC_RESET_MASK |
|
||||
UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
|
||||
UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
|
||||
UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
|
||||
(8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
|
||||
0x00100000L);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_CTRL), tmp, 0, indirect);
|
||||
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_MPC_CNTL),
|
||||
0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect);
|
||||
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_MPC_SET_MUXA0),
|
||||
((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
|
||||
(0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
|
||||
(0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
|
||||
(0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect);
|
||||
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_MPC_SET_MUXB0),
|
||||
((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
|
||||
(0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
|
||||
(0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
|
||||
(0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect);
|
||||
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_MPC_SET_MUX),
|
||||
((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
|
||||
(0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
|
||||
(0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect);
|
||||
|
||||
vcn_v2_5_mc_resume_dpg_mode(adev, inst_idx, indirect);
|
||||
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_REG_XX_MASK), 0x10, 0, indirect);
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_RBC_XX_IB_REG_CHECK), 0x3, 0, indirect);
|
||||
|
||||
/* enable LMI MC and UMC channels */
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_LMI_CTRL2), 0, 0, indirect);
|
||||
|
||||
/* unblock VCPU register access */
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_RB_ARB_CTRL), 0, 0, indirect);
|
||||
|
||||
tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
|
||||
tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_VCPU_CNTL), tmp, 0, indirect);
|
||||
|
||||
/* enable master interrupt */
|
||||
WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
|
||||
UVD, inst_idx, mmUVD_MASTINT_EN),
|
||||
UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect);
|
||||
|
||||
if (indirect)
|
||||
psp_update_vcn_sram(adev, inst_idx, adev->vcn.inst[inst_idx].dpg_sram_gpu_addr,
|
||||
(uint32_t)((uintptr_t)adev->vcn.inst[inst_idx].dpg_sram_curr_addr -
|
||||
(uintptr_t)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr));
|
||||
|
||||
ring = &adev->vcn.inst[inst_idx].ring_dec;
|
||||
/* force RBC into idle state */
|
||||
rb_bufsz = order_base_2(ring->ring_size);
|
||||
tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
|
||||
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
|
||||
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
|
||||
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
|
||||
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RBC_RB_CNTL, tmp);
|
||||
|
||||
/* set the write pointer delay */
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RBC_RB_WPTR_CNTL, 0);
|
||||
|
||||
/* set the wb address */
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RBC_RB_RPTR_ADDR,
|
||||
(upper_32_bits(ring->gpu_addr) >> 2));
|
||||
|
||||
/* programm the RB_BASE for ring buffer */
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
|
||||
lower_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
|
||||
upper_32_bits(ring->gpu_addr));
|
||||
|
||||
/* Initialize the ring buffer's read and write pointers */
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RBC_RB_RPTR, 0);
|
||||
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_SCRATCH2, 0);
|
||||
|
||||
ring->wptr = RREG32_SOC15(UVD, inst_idx, mmUVD_RBC_RB_RPTR);
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RBC_RB_WPTR,
|
||||
lower_32_bits(ring->wptr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vcn_v2_5_start(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *ring;
|
||||
@ -610,6 +891,9 @@ static int vcn_v2_5_start(struct amdgpu_device *adev)
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
|
||||
return vcn_v2_5_start_dpg_mode(adev, i, adev->vcn.indirect_sram);
|
||||
|
||||
/* disable register anti-hang mechanism */
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_POWER_STATUS), 0,
|
||||
~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
|
||||
@ -973,6 +1257,35 @@ static int vcn_v2_5_sriov_start(struct amdgpu_device *adev)
|
||||
return vcn_v2_5_mmsch_start(adev, &adev->virt.mm_table);
|
||||
}
|
||||
|
||||
static int vcn_v2_5_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
|
||||
{
|
||||
int ret_code = 0;
|
||||
uint32_t tmp;
|
||||
|
||||
/* Wait for power status to be 1 */
|
||||
SOC15_WAIT_ON_RREG(UVD, inst_idx, mmUVD_POWER_STATUS, 1,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
|
||||
|
||||
/* wait for read ptr to be equal to write ptr */
|
||||
tmp = RREG32_SOC15(UVD, inst_idx, mmUVD_RB_WPTR);
|
||||
SOC15_WAIT_ON_RREG(UVD, inst_idx, mmUVD_RB_RPTR, tmp, 0xFFFFFFFF, ret_code);
|
||||
|
||||
tmp = RREG32_SOC15(UVD, inst_idx, mmUVD_RB_WPTR2);
|
||||
SOC15_WAIT_ON_RREG(UVD, inst_idx, mmUVD_RB_RPTR2, tmp, 0xFFFFFFFF, ret_code);
|
||||
|
||||
tmp = RREG32_SOC15(UVD, inst_idx, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF;
|
||||
SOC15_WAIT_ON_RREG(UVD, inst_idx, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF, ret_code);
|
||||
|
||||
SOC15_WAIT_ON_RREG(UVD, inst_idx, mmUVD_POWER_STATUS, 1,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
|
||||
|
||||
/* disable dynamic power gating mode */
|
||||
WREG32_P(SOC15_REG_OFFSET(UVD, inst_idx, mmUVD_POWER_STATUS), 0,
|
||||
~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vcn_v2_5_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
@ -981,6 +1294,12 @@ static int vcn_v2_5_stop(struct amdgpu_device *adev)
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
|
||||
r = vcn_v2_5_stop_dpg_mode(adev, i);
|
||||
goto power_off;
|
||||
}
|
||||
|
||||
/* wait for vcn idle */
|
||||
SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7, r);
|
||||
if (r)
|
||||
@ -1030,12 +1349,74 @@ static int vcn_v2_5_stop(struct amdgpu_device *adev)
|
||||
~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
|
||||
}
|
||||
|
||||
power_off:
|
||||
if (adev->pm.dpm_enabled)
|
||||
amdgpu_dpm_enable_uvd(adev, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vcn_v2_5_pause_dpg_mode(struct amdgpu_device *adev,
|
||||
int inst_idx, struct dpg_pause_state *new_state)
|
||||
{
|
||||
struct amdgpu_ring *ring;
|
||||
uint32_t reg_data = 0;
|
||||
int ret_code;
|
||||
|
||||
/* pause/unpause if state is changed */
|
||||
if (adev->vcn.pause_state.fw_based != new_state->fw_based) {
|
||||
DRM_DEBUG("dpg pause state changed %d -> %d",
|
||||
adev->vcn.pause_state.fw_based, new_state->fw_based);
|
||||
reg_data = RREG32_SOC15(UVD, inst_idx, mmUVD_DPG_PAUSE) &
|
||||
(~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
|
||||
|
||||
if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
|
||||
ret_code = 0;
|
||||
SOC15_WAIT_ON_RREG(UVD, inst_idx, mmUVD_POWER_STATUS, 0x1,
|
||||
UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
|
||||
|
||||
if (!ret_code) {
|
||||
/* pause DPG */
|
||||
reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_DPG_PAUSE, reg_data);
|
||||
|
||||
/* wait for ACK */
|
||||
SOC15_WAIT_ON_RREG(UVD, inst_idx, mmUVD_DPG_PAUSE,
|
||||
UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
|
||||
UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, ret_code);
|
||||
|
||||
/* Restore */
|
||||
ring = &adev->vcn.inst[inst_idx].ring_enc[0];
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RB_BASE_LO, ring->gpu_addr);
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RB_SIZE, ring->ring_size / 4);
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
|
||||
|
||||
ring = &adev->vcn.inst[inst_idx].ring_enc[1];
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RB_BASE_LO2, ring->gpu_addr);
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RB_SIZE2, ring->ring_size / 4);
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
|
||||
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_RBC_RB_WPTR,
|
||||
RREG32_SOC15(UVD, inst_idx, mmUVD_SCRATCH2) & 0x7FFFFFFF);
|
||||
|
||||
SOC15_WAIT_ON_RREG(UVD, inst_idx, mmUVD_POWER_STATUS,
|
||||
0x0, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
|
||||
}
|
||||
} else {
|
||||
/* unpause dpg, no need to wait */
|
||||
reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
|
||||
WREG32_SOC15(UVD, inst_idx, mmUVD_DPG_PAUSE, reg_data);
|
||||
}
|
||||
adev->vcn.pause_state.fw_based = new_state->fw_based;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vcn_v2_5_dec_ring_get_rptr - get read pointer
|
||||
*
|
||||
@ -1078,6 +1459,10 @@ static void vcn_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
|
||||
WREG32_SOC15(UVD, ring->me, mmUVD_SCRATCH2,
|
||||
lower_32_bits(ring->wptr) | 0x80000000);
|
||||
|
||||
if (ring->use_doorbell) {
|
||||
adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
|
||||
WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
|
||||
|
@ -689,40 +689,6 @@ static int vi_gpu_pci_config_reset(struct amdgpu_device *adev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int smu7_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap)
|
||||
{
|
||||
void *pp_handle = adev->powerplay.pp_handle;
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
|
||||
if (!pp_funcs || !pp_funcs->get_asic_baco_capability) {
|
||||
*cap = false;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
return pp_funcs->get_asic_baco_capability(pp_handle, cap);
|
||||
}
|
||||
|
||||
int smu7_asic_baco_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
void *pp_handle = adev->powerplay.pp_handle;
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
|
||||
if (!pp_funcs ||!pp_funcs->get_asic_baco_state ||!pp_funcs->set_asic_baco_state)
|
||||
return -ENOENT;
|
||||
|
||||
/* enter BACO state */
|
||||
if (pp_funcs->set_asic_baco_state(pp_handle, 1))
|
||||
return -EIO;
|
||||
|
||||
/* exit BACO state */
|
||||
if (pp_funcs->set_asic_baco_state(pp_handle, 0))
|
||||
return -EIO;
|
||||
|
||||
dev_info(adev->dev, "GPU BACO reset\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vi_asic_pci_config_reset - soft reset GPU
|
||||
*
|
||||
@ -747,8 +713,6 @@ static int vi_asic_pci_config_reset(struct amdgpu_device *adev)
|
||||
|
||||
static bool vi_asic_supports_baco(struct amdgpu_device *adev)
|
||||
{
|
||||
bool baco_support;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_FIJI:
|
||||
case CHIP_TONGA:
|
||||
@ -756,14 +720,10 @@ static bool vi_asic_supports_baco(struct amdgpu_device *adev)
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS12:
|
||||
case CHIP_TOPAZ:
|
||||
smu7_asic_get_baco_capability(adev, &baco_support);
|
||||
break;
|
||||
return amdgpu_dpm_is_baco_supported(adev);
|
||||
default:
|
||||
baco_support = false;
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
return baco_support;
|
||||
}
|
||||
|
||||
static enum amd_reset_method
|
||||
@ -778,7 +738,7 @@ vi_asic_reset_method(struct amdgpu_device *adev)
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS12:
|
||||
case CHIP_TOPAZ:
|
||||
smu7_asic_get_baco_capability(adev, &baco_reset);
|
||||
baco_reset = amdgpu_dpm_is_baco_supported(adev);
|
||||
break;
|
||||
default:
|
||||
baco_reset = false;
|
||||
@ -807,7 +767,7 @@ static int vi_asic_reset(struct amdgpu_device *adev)
|
||||
if (vi_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
|
||||
if (!adev->in_suspend)
|
||||
amdgpu_inc_vram_lost(adev);
|
||||
r = smu7_asic_baco_reset(adev);
|
||||
r = amdgpu_dpm_baco_reset(adev);
|
||||
} else {
|
||||
r = vi_asic_pci_config_reset(adev);
|
||||
}
|
||||
|
@ -31,7 +31,5 @@ void vi_srbm_select(struct amdgpu_device *adev,
|
||||
int vi_set_ip_blocks(struct amdgpu_device *adev);
|
||||
|
||||
void legacy_doorbell_index_init(struct amdgpu_device *adev);
|
||||
int smu7_asic_get_baco_capability(struct amdgpu_device *adev, bool *cap);
|
||||
int smu7_asic_baco_reset(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
@ -934,6 +934,7 @@ static void uninitialize(struct device_queue_manager *dqm)
|
||||
|
||||
static int start_nocpsch(struct device_queue_manager *dqm)
|
||||
{
|
||||
pr_info("SW scheduler is used");
|
||||
init_interrupts(dqm);
|
||||
|
||||
if (dqm->dev->device_info->asic_family == CHIP_HAWAII)
|
||||
|
@ -153,6 +153,14 @@ static int load_mqd(struct mqd_manager *mm, void *mqd,
|
||||
return r;
|
||||
}
|
||||
|
||||
static int hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd,
|
||||
uint32_t pipe_id, uint32_t queue_id,
|
||||
struct queue_properties *p, struct mm_struct *mms)
|
||||
{
|
||||
return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->kgd, mqd, pipe_id,
|
||||
queue_id, p->doorbell_off);
|
||||
}
|
||||
|
||||
static void update_mqd(struct mqd_manager *mm, void *mqd,
|
||||
struct queue_properties *q)
|
||||
{
|
||||
@ -409,7 +417,7 @@ struct mqd_manager *mqd_manager_init_v10(enum KFD_MQD_TYPE type,
|
||||
mqd->allocate_mqd = allocate_hiq_mqd;
|
||||
mqd->init_mqd = init_mqd_hiq;
|
||||
mqd->free_mqd = free_mqd_hiq_sdma;
|
||||
mqd->load_mqd = load_mqd;
|
||||
mqd->load_mqd = hiq_load_mqd_kiq;
|
||||
mqd->update_mqd = update_mqd;
|
||||
mqd->destroy_mqd = destroy_mqd;
|
||||
mqd->is_occupied = is_occupied;
|
||||
|
@ -191,6 +191,14 @@ static int load_mqd(struct mqd_manager *mm, void *mqd,
|
||||
wptr_shift, 0, mms);
|
||||
}
|
||||
|
||||
static int hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd,
|
||||
uint32_t pipe_id, uint32_t queue_id,
|
||||
struct queue_properties *p, struct mm_struct *mms)
|
||||
{
|
||||
return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->kgd, mqd, pipe_id,
|
||||
queue_id, p->doorbell_off);
|
||||
}
|
||||
|
||||
static void update_mqd(struct mqd_manager *mm, void *mqd,
|
||||
struct queue_properties *q)
|
||||
{
|
||||
@ -449,7 +457,7 @@ struct mqd_manager *mqd_manager_init_v9(enum KFD_MQD_TYPE type,
|
||||
mqd->allocate_mqd = allocate_hiq_mqd;
|
||||
mqd->init_mqd = init_mqd_hiq;
|
||||
mqd->free_mqd = free_mqd_hiq_sdma;
|
||||
mqd->load_mqd = load_mqd;
|
||||
mqd->load_mqd = hiq_load_mqd_kiq;
|
||||
mqd->update_mqd = update_mqd;
|
||||
mqd->destroy_mqd = destroy_mqd;
|
||||
mqd->is_occupied = is_occupied;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <linux/mman.h>
|
||||
#include <linux/file.h>
|
||||
#include "amdgpu_amdkfd.h"
|
||||
#include "amdgpu.h"
|
||||
|
||||
struct mm_struct;
|
||||
|
||||
@ -1152,16 +1153,17 @@ int kfd_reserved_mem_mmap(struct kfd_dev *dev, struct kfd_process *process,
|
||||
void kfd_flush_tlb(struct kfd_process_device *pdd)
|
||||
{
|
||||
struct kfd_dev *dev = pdd->dev;
|
||||
const struct kfd2kgd_calls *f2g = dev->kfd2kgd;
|
||||
|
||||
if (dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS) {
|
||||
/* Nothing to flush until a VMID is assigned, which
|
||||
* only happens when the first queue is created.
|
||||
*/
|
||||
if (pdd->qpd.vmid)
|
||||
f2g->invalidate_tlbs_vmid(dev->kgd, pdd->qpd.vmid);
|
||||
amdgpu_amdkfd_flush_gpu_tlb_vmid(dev->kgd,
|
||||
pdd->qpd.vmid);
|
||||
} else {
|
||||
f2g->invalidate_tlbs(dev->kgd, pdd->process->pasid);
|
||||
amdgpu_amdkfd_flush_gpu_tlb_pasid(dev->kgd,
|
||||
pdd->process->pasid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -906,13 +906,16 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
||||
|
||||
init_data.dce_environment = DCE_ENV_PRODUCTION_DRV;
|
||||
|
||||
/*
|
||||
* TODO debug why this doesn't work on Raven
|
||||
*/
|
||||
if (adev->flags & AMD_IS_APU &&
|
||||
adev->asic_type >= CHIP_CARRIZO &&
|
||||
adev->asic_type < CHIP_RAVEN)
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_RENOIR:
|
||||
init_data.flags.gpu_vm_support = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (amdgpu_dc_feature_mask & DC_FBC_MASK)
|
||||
init_data.flags.fbc_support = true;
|
||||
@ -8390,17 +8393,37 @@ static bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream)
|
||||
bool amdgpu_dm_psr_enable(struct dc_stream_state *stream)
|
||||
{
|
||||
struct dc_link *link = stream->link;
|
||||
struct dc_static_screen_events triggers = {0};
|
||||
unsigned int vsync_rate_hz = 0;
|
||||
struct dc_static_screen_params params = {0};
|
||||
/* Calculate number of static frames before generating interrupt to
|
||||
* enter PSR.
|
||||
*/
|
||||
unsigned int frame_time_microsec = 1000000 / vsync_rate_hz;
|
||||
// Init fail safe of 2 frames static
|
||||
unsigned int num_frames_static = 2;
|
||||
|
||||
DRM_DEBUG_DRIVER("Enabling psr...\n");
|
||||
|
||||
triggers.cursor_update = true;
|
||||
triggers.overlay_update = true;
|
||||
triggers.surface_update = true;
|
||||
vsync_rate_hz = div64_u64(div64_u64((
|
||||
stream->timing.pix_clk_100hz * 100),
|
||||
stream->timing.v_total),
|
||||
stream->timing.h_total);
|
||||
|
||||
dc_stream_set_static_screen_events(link->ctx->dc,
|
||||
/* Round up
|
||||
* Calculate number of frames such that at least 30 ms of time has
|
||||
* passed.
|
||||
*/
|
||||
if (vsync_rate_hz != 0)
|
||||
num_frames_static = (30000 / frame_time_microsec) + 1;
|
||||
|
||||
params.triggers.cursor_update = true;
|
||||
params.triggers.overlay_update = true;
|
||||
params.triggers.surface_update = true;
|
||||
params.num_frames = num_frames_static;
|
||||
|
||||
dc_stream_set_static_screen_params(link->ctx->dc,
|
||||
&stream, 1,
|
||||
&triggers);
|
||||
¶ms);
|
||||
|
||||
return dc_link_set_psr_allow_active(link, true, false);
|
||||
}
|
||||
|
@ -534,7 +534,7 @@ static int kbps_to_peak_pbn(int kbps)
|
||||
|
||||
peak_kbps *= 1006;
|
||||
peak_kbps = div_u64(peak_kbps, 1000);
|
||||
return (int) DIV_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000));
|
||||
return (int) DIV64_U64_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000));
|
||||
}
|
||||
|
||||
static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *params,
|
||||
|
@ -705,8 +705,8 @@ static void hack_bounding_box(struct dcn_bw_internal_vars *v,
|
||||
|
||||
unsigned int get_highest_allowed_voltage_level(uint32_t hw_internal_rev)
|
||||
{
|
||||
/* for dali, the highest voltage level we want is 0 */
|
||||
if (ASICREV_IS_DALI(hw_internal_rev))
|
||||
/* for dali & pollock, the highest voltage level we want is 0 */
|
||||
if (ASICREV_IS_POLLOCK(hw_internal_rev) || ASICREV_IS_DALI(hw_internal_rev))
|
||||
return 0;
|
||||
|
||||
/* we are ok with all levels */
|
||||
|
@ -134,13 +134,13 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
case FAMILY_RV:
|
||||
if (ASICREV_IS_DALI(asic_id.hw_internal_rev)) {
|
||||
if (ASICREV_IS_DALI(asic_id.hw_internal_rev) ||
|
||||
ASICREV_IS_POLLOCK(asic_id.hw_internal_rev)) {
|
||||
/* TEMP: this check has to come before ASICREV_IS_RENOIR */
|
||||
/* which also incorrectly returns true for Dali */
|
||||
/* which also incorrectly returns true for Dali/Pollock*/
|
||||
rv2_clk_mgr_construct(ctx, clk_mgr, pp_smu);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ASICREV_IS_RENOIR(asic_id.hw_internal_rev)) {
|
||||
rn_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
|
||||
break;
|
||||
|
@ -59,14 +59,16 @@ int rn_get_active_display_cnt_wa(
|
||||
struct dc_state *context)
|
||||
{
|
||||
int i, display_count;
|
||||
bool hdmi_present = false;
|
||||
bool tmds_present = false;
|
||||
|
||||
display_count = 0;
|
||||
for (i = 0; i < context->stream_count; i++) {
|
||||
const struct dc_stream_state *stream = context->streams[i];
|
||||
|
||||
if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
|
||||
hdmi_present = true;
|
||||
if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A ||
|
||||
stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
|
||||
stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK)
|
||||
tmds_present = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
@ -85,7 +87,7 @@ int rn_get_active_display_cnt_wa(
|
||||
}
|
||||
|
||||
/* WA for hang on HDMI after display off back back on*/
|
||||
if (display_count == 0 && hdmi_present)
|
||||
if (display_count == 0 && tmds_present)
|
||||
display_count = 1;
|
||||
|
||||
return display_count;
|
||||
|
@ -287,7 +287,6 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
||||
struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (pipe->stream == stream && pipe->stream_res.tg) {
|
||||
pipe->stream->adjust = *adjust;
|
||||
dc->hwss.set_drr(&pipe,
|
||||
1,
|
||||
adjust->v_total_min,
|
||||
@ -511,10 +510,10 @@ bool dc_stream_program_csc_matrix(struct dc *dc, struct dc_stream_state *stream)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dc_stream_set_static_screen_events(struct dc *dc,
|
||||
void dc_stream_set_static_screen_params(struct dc *dc,
|
||||
struct dc_stream_state **streams,
|
||||
int num_streams,
|
||||
const struct dc_static_screen_events *events)
|
||||
const struct dc_static_screen_params *params)
|
||||
{
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
@ -533,7 +532,7 @@ void dc_stream_set_static_screen_events(struct dc *dc,
|
||||
}
|
||||
}
|
||||
|
||||
dc->hwss.set_static_screen_control(pipes_affected, num_pipes_affected, events);
|
||||
dc->hwss.set_static_screen_control(pipes_affected, num_pipes_affected, params);
|
||||
}
|
||||
|
||||
static void dc_destruct(struct dc *dc)
|
||||
@ -1319,6 +1318,12 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context)
|
||||
return (result == DC_OK);
|
||||
}
|
||||
|
||||
bool dc_is_hw_initialized(struct dc *dc)
|
||||
{
|
||||
struct dc_bios *dcb = dc->ctx->dc_bios;
|
||||
return dcb->funcs->is_accelerated_mode(dcb);
|
||||
}
|
||||
|
||||
bool dc_post_update_surfaces_to_stream(struct dc *dc)
|
||||
{
|
||||
int i;
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "dpcd_defs.h"
|
||||
#include "dmcu.h"
|
||||
#include "hw/clk_mgr.h"
|
||||
#include "../dce/dmub_psr.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
||||
@ -817,8 +818,8 @@ static bool dc_link_detect_helper(struct dc_link *link,
|
||||
}
|
||||
|
||||
case SIGNAL_TYPE_EDP: {
|
||||
read_current_link_settings_on_detect(link);
|
||||
detect_edp_sink_caps(link);
|
||||
read_current_link_settings_on_detect(link);
|
||||
sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
|
||||
sink_caps.signal = SIGNAL_TYPE_EDP;
|
||||
break;
|
||||
@ -2404,10 +2405,11 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool
|
||||
{
|
||||
struct dc *dc = link->ctx->dc;
|
||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||
struct dmub_psr *psr = dc->res_pool->psr;
|
||||
|
||||
|
||||
|
||||
if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_feature_enabled)
|
||||
if ((psr != NULL) && link->psr_feature_enabled)
|
||||
psr->funcs->set_psr_enable(psr, allow_active);
|
||||
else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_feature_enabled)
|
||||
dmcu->funcs->set_psr_enable(dmcu, allow_active, wait);
|
||||
|
||||
link->psr_allow_active = allow_active;
|
||||
@ -2419,8 +2421,11 @@ bool dc_link_get_psr_state(const struct dc_link *link, uint32_t *psr_state)
|
||||
{
|
||||
struct dc *dc = link->ctx->dc;
|
||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||
struct dmub_psr *psr = dc->res_pool->psr;
|
||||
|
||||
if (dmcu != NULL && link->psr_feature_enabled)
|
||||
if (psr != NULL && link->psr_feature_enabled)
|
||||
psr->funcs->get_psr_state(psr_state);
|
||||
else if (dmcu != NULL && link->psr_feature_enabled)
|
||||
dmcu->funcs->get_psr_state(dmcu, psr_state);
|
||||
|
||||
return true;
|
||||
@ -2467,6 +2472,7 @@ bool dc_link_setup_psr(struct dc_link *link,
|
||||
{
|
||||
struct dc *dc;
|
||||
struct dmcu *dmcu;
|
||||
struct dmub_psr *psr;
|
||||
int i;
|
||||
/* updateSinkPsrDpcdConfig*/
|
||||
union dpcd_psr_configuration psr_configuration;
|
||||
@ -2478,8 +2484,9 @@ bool dc_link_setup_psr(struct dc_link *link,
|
||||
|
||||
dc = link->ctx->dc;
|
||||
dmcu = dc->res_pool->dmcu;
|
||||
psr = dc->res_pool->psr;
|
||||
|
||||
if (!dmcu)
|
||||
if (!dmcu && !psr)
|
||||
return false;
|
||||
|
||||
|
||||
@ -2535,7 +2542,7 @@ bool dc_link_setup_psr(struct dc_link *link,
|
||||
transmitter_to_phy_id(link->link_enc->transmitter);
|
||||
|
||||
psr_context->crtcTimingVerticalTotal = stream->timing.v_total;
|
||||
psr_context->vsyncRateHz = div64_u64(div64_u64((stream->
|
||||
psr_context->vsync_rate_hz = div64_u64(div64_u64((stream->
|
||||
timing.pix_clk_100hz * 100),
|
||||
stream->timing.v_total),
|
||||
stream->timing.h_total);
|
||||
@ -2588,7 +2595,10 @@ bool dc_link_setup_psr(struct dc_link *link,
|
||||
*/
|
||||
psr_context->frame_delay = 0;
|
||||
|
||||
link->psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, psr_context);
|
||||
if (psr)
|
||||
link->psr_feature_enabled = psr->funcs->setup_psr(psr, link, psr_context);
|
||||
else
|
||||
link->psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, psr_context);
|
||||
|
||||
/* psr_enabled == 0 indicates setup_psr did not succeed, but this
|
||||
* should not happen since firmware should be running at this point
|
||||
@ -2863,6 +2873,39 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx)
|
||||
|
||||
return DC_OK;
|
||||
}
|
||||
|
||||
enum dc_status dc_link_reallocate_mst_payload(struct dc_link *link)
|
||||
{
|
||||
int i;
|
||||
struct pipe_ctx *pipe_ctx;
|
||||
|
||||
// Clear all of MST payload then reallocate
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link &&
|
||||
pipe_ctx->stream->dpms_off == false &&
|
||||
pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
|
||||
deallocate_mst_payload(pipe_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link &&
|
||||
pipe_ctx->stream->dpms_off == false &&
|
||||
pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
|
||||
/* enable/disable PHY will clear connection between BE and FE
|
||||
* need to restore it.
|
||||
*/
|
||||
link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
|
||||
pipe_ctx->stream_res.stream_enc->id, true);
|
||||
dc_link_allocate_mst_payload(pipe_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
return DC_OK;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_HDCP)
|
||||
static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off)
|
||||
{
|
||||
@ -3361,3 +3404,10 @@ const struct dc_link_settings *dc_link_get_link_cap(
|
||||
return &link->preferred_link_setting;
|
||||
return &link->verified_link_cap;
|
||||
}
|
||||
|
||||
void dc_link_overwrite_extended_receiver_cap(
|
||||
struct dc_link *link)
|
||||
{
|
||||
dp_overwrite_extended_receiver_cap(link);
|
||||
}
|
||||
|
||||
|
@ -1217,24 +1217,33 @@ static void configure_lttpr_mode(struct dc_link *link)
|
||||
uint8_t repeater_cnt;
|
||||
uint32_t aux_interval_address;
|
||||
uint8_t repeater_id;
|
||||
enum dc_status result = DC_ERROR_UNEXPECTED;
|
||||
uint8_t repeater_mode = DP_PHY_REPEATER_MODE_TRANSPARENT;
|
||||
|
||||
DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Transparent Mode\n", __func__);
|
||||
core_link_write_dpcd(link,
|
||||
result = core_link_write_dpcd(link,
|
||||
DP_PHY_REPEATER_MODE,
|
||||
(uint8_t *)&repeater_mode,
|
||||
sizeof(repeater_mode));
|
||||
|
||||
if (result == DC_OK) {
|
||||
link->dpcd_caps.lttpr_caps.mode = repeater_mode;
|
||||
}
|
||||
|
||||
if (!link->is_lttpr_mode_transparent) {
|
||||
|
||||
DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Non Transparent Mode\n", __func__);
|
||||
|
||||
repeater_mode = DP_PHY_REPEATER_MODE_NON_TRANSPARENT;
|
||||
core_link_write_dpcd(link,
|
||||
result = core_link_write_dpcd(link,
|
||||
DP_PHY_REPEATER_MODE,
|
||||
(uint8_t *)&repeater_mode,
|
||||
sizeof(repeater_mode));
|
||||
|
||||
if (result == DC_OK) {
|
||||
link->dpcd_caps.lttpr_caps.mode = repeater_mode;
|
||||
}
|
||||
|
||||
repeater_cnt = convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
|
||||
for (repeater_id = repeater_cnt; repeater_id > 0; repeater_id--) {
|
||||
aux_interval_address = DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 +
|
||||
@ -1883,6 +1892,16 @@ bool dp_verify_link_cap(
|
||||
/* disable PHY done possible by BIOS, will be done by driver itself */
|
||||
dp_disable_link_phy(link, link->connector_signal);
|
||||
|
||||
/* Temporary Renoir-specific workaround for SWDEV-215184;
|
||||
* PHY will sometimes be in bad state on hotplugging display from certain USB-C dongle,
|
||||
* so add extra cycle of enabling and disabling the PHY before first link training.
|
||||
*/
|
||||
if (link->link_enc->features.flags.bits.DP_IS_USB_C &&
|
||||
link->dc->debug.usbc_combo_phy_reset_wa) {
|
||||
dp_enable_link_phy(link, link->connector_signal, dp_cs_id, cur);
|
||||
dp_disable_link_phy(link, link->connector_signal);
|
||||
}
|
||||
|
||||
dp_cs_id = get_clock_source_id(link);
|
||||
|
||||
/* link training starts with the maximum common settings
|
||||
@ -2876,18 +2895,14 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
|
||||
return false;
|
||||
|
||||
previous_link_settings = link->cur_link_settings;
|
||||
dp_disable_link_phy(link, pipe_ctx->stream->signal);
|
||||
|
||||
perform_link_training_with_retries(&previous_link_settings,
|
||||
true, LINK_TRAINING_ATTEMPTS,
|
||||
pipe_ctx,
|
||||
pipe_ctx->stream->signal);
|
||||
|
||||
if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link &&
|
||||
pipe_ctx->stream->dpms_off == false &&
|
||||
pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
|
||||
dc_link_allocate_mst_payload(pipe_ctx);
|
||||
}
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
dc_link_reallocate_mst_payload(link);
|
||||
|
||||
status = false;
|
||||
if (out_link_loss)
|
||||
@ -3269,7 +3284,7 @@ static bool retrieve_link_cap(struct dc_link *link)
|
||||
dpcd_data[DP_TRAINING_AUX_RD_INTERVAL];
|
||||
|
||||
link->dpcd_caps.ext_receiver_cap_field_present =
|
||||
aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1 ? true:false;
|
||||
aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1;
|
||||
|
||||
if (aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1) {
|
||||
uint8_t ext_cap_data[16];
|
||||
@ -3428,6 +3443,68 @@ static bool retrieve_link_cap(struct dc_link *link)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dp_overwrite_extended_receiver_cap(struct dc_link *link)
|
||||
{
|
||||
uint8_t dpcd_data[16];
|
||||
uint32_t read_dpcd_retry_cnt = 3;
|
||||
enum dc_status status = DC_ERROR_UNEXPECTED;
|
||||
union dp_downstream_port_present ds_port = { 0 };
|
||||
union down_stream_port_count down_strm_port_count;
|
||||
union edp_configuration_cap edp_config_cap;
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < read_dpcd_retry_cnt; i++) {
|
||||
status = core_link_read_dpcd(
|
||||
link,
|
||||
DP_DPCD_REV,
|
||||
dpcd_data,
|
||||
sizeof(dpcd_data));
|
||||
if (status == DC_OK)
|
||||
break;
|
||||
}
|
||||
|
||||
link->dpcd_caps.dpcd_rev.raw =
|
||||
dpcd_data[DP_DPCD_REV - DP_DPCD_REV];
|
||||
|
||||
if (dpcd_data[DP_MAX_LANE_COUNT - DP_DPCD_REV] == 0)
|
||||
return false;
|
||||
|
||||
ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
|
||||
DP_DPCD_REV];
|
||||
|
||||
get_active_converter_info(ds_port.byte, link);
|
||||
|
||||
down_strm_port_count.raw = dpcd_data[DP_DOWN_STREAM_PORT_COUNT -
|
||||
DP_DPCD_REV];
|
||||
|
||||
link->dpcd_caps.allow_invalid_MSA_timing_param =
|
||||
down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
|
||||
|
||||
link->dpcd_caps.max_ln_count.raw = dpcd_data[
|
||||
DP_MAX_LANE_COUNT - DP_DPCD_REV];
|
||||
|
||||
link->dpcd_caps.max_down_spread.raw = dpcd_data[
|
||||
DP_MAX_DOWNSPREAD - DP_DPCD_REV];
|
||||
|
||||
link->reported_link_cap.lane_count =
|
||||
link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
|
||||
link->reported_link_cap.link_rate = dpcd_data[
|
||||
DP_MAX_LINK_RATE - DP_DPCD_REV];
|
||||
link->reported_link_cap.link_spread =
|
||||
link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ?
|
||||
LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
|
||||
|
||||
edp_config_cap.raw = dpcd_data[
|
||||
DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV];
|
||||
link->dpcd_caps.panel_mode_edp =
|
||||
edp_config_cap.bits.ALT_SCRAMBLER_RESET;
|
||||
link->dpcd_caps.dpcd_display_control_capable =
|
||||
edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool detect_dp_sink_caps(struct dc_link *link)
|
||||
{
|
||||
return retrieve_link_cap(link);
|
||||
@ -3603,6 +3680,7 @@ static void set_crtc_test_pattern(struct dc_link *link,
|
||||
struct pipe_ctx *odm_pipe;
|
||||
enum controller_dp_color_space controller_color_space;
|
||||
int opp_cnt = 1;
|
||||
uint8_t count = 0;
|
||||
|
||||
switch (test_pattern_color_space) {
|
||||
case DP_TEST_PATTERN_COLOR_SPACE_RGB:
|
||||
@ -3646,6 +3724,12 @@ static void set_crtc_test_pattern(struct dc_link *link,
|
||||
NULL,
|
||||
width,
|
||||
height);
|
||||
/* wait for dpg to blank pixel data with test pattern */
|
||||
for (count = 0; count < 1000; count++)
|
||||
if (opp->funcs->dpg_is_blanked(opp))
|
||||
break;
|
||||
else
|
||||
udelay(100);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2066,6 +2066,13 @@ void dc_resource_state_construct(
|
||||
dst_ctx->clk_mgr = dc->clk_mgr;
|
||||
}
|
||||
|
||||
|
||||
bool dc_resource_is_dsc_encoding_supported(const struct dc *dc)
|
||||
{
|
||||
return dc->res_pool->res_cap->num_dsc > 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* dc_validate_global_state() - Determine if HW can support a given state
|
||||
* Checks HW resource availability and bandwidth requirement.
|
||||
@ -2897,6 +2904,3 @@ void get_audio_check(struct audio_info *aud_modes,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include "inc/hw/dmcu.h"
|
||||
#include "dml/display_mode_lib.h"
|
||||
|
||||
#define DC_VER "3.2.64"
|
||||
#define DC_VER "3.2.68"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
@ -157,11 +157,14 @@ struct dc_surface_dcc_cap {
|
||||
bool const_color_support;
|
||||
};
|
||||
|
||||
struct dc_static_screen_events {
|
||||
bool force_trigger;
|
||||
bool cursor_update;
|
||||
bool surface_update;
|
||||
bool overlay_update;
|
||||
struct dc_static_screen_params {
|
||||
struct {
|
||||
bool force_trigger;
|
||||
bool cursor_update;
|
||||
bool surface_update;
|
||||
bool overlay_update;
|
||||
} triggers;
|
||||
unsigned int num_frames;
|
||||
};
|
||||
|
||||
|
||||
@ -420,6 +423,8 @@ struct dc_debug_options {
|
||||
bool nv12_iflip_vm_wa;
|
||||
bool disable_dram_clock_change_vactive_support;
|
||||
bool validate_dml_output;
|
||||
bool enable_dmcub_surface_flip;
|
||||
bool usbc_combo_phy_reset_wa;
|
||||
};
|
||||
|
||||
struct dc_debug_data {
|
||||
@ -910,6 +915,8 @@ void dc_resource_state_copy_construct_current(
|
||||
|
||||
void dc_resource_state_destruct(struct dc_state *context);
|
||||
|
||||
bool dc_resource_is_dsc_encoding_supported(const struct dc *dc);
|
||||
|
||||
/*
|
||||
* TODO update to make it about validation sets
|
||||
* Set up streams and links associated to drive sinks
|
||||
@ -1067,6 +1074,7 @@ unsigned int dc_get_current_backlight_pwm(struct dc *dc);
|
||||
unsigned int dc_get_target_backlight_pwm(struct dc *dc);
|
||||
|
||||
bool dc_is_dmcu_initialized(struct dc *dc);
|
||||
bool dc_is_hw_initialized(struct dc *dc);
|
||||
|
||||
enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping);
|
||||
void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg);
|
||||
|
@ -552,6 +552,36 @@ uint32_t generic_read_indirect_reg(const struct dc_context *ctx,
|
||||
return value;
|
||||
}
|
||||
|
||||
uint32_t generic_indirect_reg_get(const struct dc_context *ctx,
|
||||
uint32_t addr_index, uint32_t addr_data,
|
||||
uint32_t index, int n,
|
||||
uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
|
||||
...)
|
||||
{
|
||||
uint32_t shift, mask, *field_value;
|
||||
uint32_t value = 0;
|
||||
int i = 1;
|
||||
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, field_value1);
|
||||
|
||||
value = generic_read_indirect_reg(ctx, addr_index, addr_data, index);
|
||||
*field_value1 = get_reg_field_value_ex(value, mask1, shift1);
|
||||
|
||||
while (i < n) {
|
||||
shift = va_arg(ap, uint32_t);
|
||||
mask = va_arg(ap, uint32_t);
|
||||
field_value = va_arg(ap, uint32_t *);
|
||||
|
||||
*field_value = get_reg_field_value_ex(value, mask, shift);
|
||||
i++;
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
uint32_t generic_indirect_reg_update_ex(const struct dc_context *ctx,
|
||||
uint32_t addr_index, uint32_t addr_data,
|
||||
|
@ -205,6 +205,7 @@ enum dc_detect_reason {
|
||||
bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
|
||||
bool dc_link_get_hpd_state(struct dc_link *dc_link);
|
||||
enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx);
|
||||
enum dc_status dc_link_reallocate_mst_payload(struct dc_link *link);
|
||||
|
||||
/* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
|
||||
* Return:
|
||||
@ -301,6 +302,9 @@ uint32_t dc_link_bandwidth_kbps(
|
||||
const struct dc_link_settings *dc_link_get_link_cap(
|
||||
const struct dc_link *link);
|
||||
|
||||
void dc_link_overwrite_extended_receiver_cap(
|
||||
struct dc_link *link);
|
||||
|
||||
bool dc_submit_i2c(
|
||||
struct dc *dc,
|
||||
uint32_t link_index,
|
||||
|
@ -439,10 +439,10 @@ bool dc_stream_get_crc(struct dc *dc,
|
||||
uint32_t *g_y,
|
||||
uint32_t *b_cb);
|
||||
|
||||
void dc_stream_set_static_screen_events(struct dc *dc,
|
||||
void dc_stream_set_static_screen_params(struct dc *dc,
|
||||
struct dc_stream_state **stream,
|
||||
int num_streams,
|
||||
const struct dc_static_screen_events *events);
|
||||
const struct dc_static_screen_params *params);
|
||||
|
||||
void dc_stream_set_dyn_expansion(struct dc *dc, struct dc_stream_state *stream,
|
||||
enum dc_dynamic_expansion option);
|
||||
|
@ -229,6 +229,7 @@ struct dc_panel_patch {
|
||||
unsigned int extra_t12_ms;
|
||||
unsigned int extra_delay_backlight_off;
|
||||
unsigned int extra_t7_ms;
|
||||
unsigned int manage_secondary_link;
|
||||
};
|
||||
|
||||
struct dc_edid_caps {
|
||||
@ -728,7 +729,7 @@ struct psr_context {
|
||||
/* The VSync rate in Hz used to calculate the
|
||||
* step size for smooth brightness feature
|
||||
*/
|
||||
unsigned int vsyncRateHz;
|
||||
unsigned int vsync_rate_hz;
|
||||
unsigned int skipPsrWaitForPllLock;
|
||||
unsigned int numberOfControllers;
|
||||
/* Unused, for future use. To indicate that first changed frame from
|
||||
|
@ -537,9 +537,6 @@ static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
|
||||
if (dmcu->dmcu_state != DMCU_RUNNING)
|
||||
return;
|
||||
|
||||
dcn10_get_dmcu_psr_state(dmcu, &psr_state);
|
||||
if (psr_state == 0 && !enable)
|
||||
return;
|
||||
/* waitDMCUReadyForCmd */
|
||||
REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0,
|
||||
dmcu_wait_reg_ready_interval,
|
||||
|
220
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
Normal file
220
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright 2019 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dmub_psr.h"
|
||||
#include "dc.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "../../dmub/inc/dmub_srv.h"
|
||||
#include "dmub_fw_state.h"
|
||||
#include "core_types.h"
|
||||
#include "ipp.h"
|
||||
|
||||
#define MAX_PIPES 6
|
||||
|
||||
/**
|
||||
* Get PSR state from firmware.
|
||||
*/
|
||||
static void dmub_get_psr_state(uint32_t *psr_state)
|
||||
{
|
||||
// Not yet implemented
|
||||
// Trigger GPINT interrupt from firmware
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable PSR.
|
||||
*/
|
||||
static void dmub_set_psr_enable(struct dmub_psr *dmub, bool enable)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = dmub->ctx;
|
||||
|
||||
cmd.psr_enable.header.type = DMUB_CMD__PSR;
|
||||
|
||||
if (enable)
|
||||
cmd.psr_enable.header.sub_type = DMUB_CMD__PSR_ENABLE;
|
||||
else
|
||||
cmd.psr_enable.header.sub_type = DMUB_CMD__PSR_DISABLE;
|
||||
|
||||
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_execute(dc->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set PSR level.
|
||||
*/
|
||||
static void dmub_set_psr_level(struct dmub_psr *dmub, uint16_t psr_level)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
uint32_t psr_state = 0;
|
||||
struct dc_context *dc = dmub->ctx;
|
||||
|
||||
dmub_get_psr_state(&psr_state);
|
||||
|
||||
if (psr_state == 0)
|
||||
return;
|
||||
|
||||
cmd.psr_set_level.header.type = DMUB_CMD__PSR;
|
||||
cmd.psr_set_level.header.sub_type = DMUB_CMD__PSR_SET_LEVEL;
|
||||
cmd.psr_set_level.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_level_data);
|
||||
cmd.psr_set_level.psr_set_level_data.psr_level = psr_level;
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.psr_set_level.header);
|
||||
dc_dmub_srv_cmd_execute(dc->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup PSR by programming phy registers and sending psr hw context values to firmware.
|
||||
*/
|
||||
static bool dmub_setup_psr(struct dmub_psr *dmub,
|
||||
struct dc_link *link,
|
||||
struct psr_context *psr_context)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = dmub->ctx;
|
||||
struct dmub_cmd_psr_copy_settings_data *copy_settings_data
|
||||
= &cmd.psr_copy_settings.psr_copy_settings_data;
|
||||
struct pipe_ctx *pipe_ctx = NULL;
|
||||
struct resource_context *res_ctx = &link->ctx->dc->current_state->res_ctx;
|
||||
|
||||
for (int i = 0; i < MAX_PIPES; i++) {
|
||||
if (res_ctx &&
|
||||
res_ctx->pipe_ctx[i].stream &&
|
||||
res_ctx->pipe_ctx[i].stream->link &&
|
||||
res_ctx->pipe_ctx[i].stream->link == link &&
|
||||
res_ctx->pipe_ctx[i].stream->link->connector_signal == SIGNAL_TYPE_EDP) {
|
||||
pipe_ctx = &res_ctx->pipe_ctx[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pipe_ctx ||
|
||||
!&pipe_ctx->plane_res ||
|
||||
!&pipe_ctx->stream_res)
|
||||
return false;
|
||||
|
||||
// Program DP DPHY fast training registers
|
||||
link->link_enc->funcs->psr_program_dp_dphy_fast_training(link->link_enc,
|
||||
psr_context->psrExitLinkTrainingRequired);
|
||||
|
||||
// Program DP_SEC_CNTL1 register to set transmission GPS0 line num and priority to high
|
||||
link->link_enc->funcs->psr_program_secondary_packet(link->link_enc,
|
||||
psr_context->sdpTransmitLineNumDeadline);
|
||||
|
||||
cmd.psr_copy_settings.header.type = DMUB_CMD__PSR;
|
||||
cmd.psr_copy_settings.header.sub_type = DMUB_CMD__PSR_COPY_SETTINGS;
|
||||
cmd.psr_copy_settings.header.payload_bytes = sizeof(struct dmub_cmd_psr_copy_settings_data);
|
||||
|
||||
// Hw insts
|
||||
copy_settings_data->dpphy_inst = psr_context->phyType;
|
||||
copy_settings_data->aux_inst = psr_context->channel;
|
||||
copy_settings_data->digfe_inst = psr_context->engineId;
|
||||
copy_settings_data->digbe_inst = psr_context->transmitterId;
|
||||
|
||||
copy_settings_data->mpcc_inst = pipe_ctx->plane_res.mpcc_inst;
|
||||
|
||||
if (pipe_ctx->plane_res.hubp)
|
||||
copy_settings_data->hubp_inst = pipe_ctx->plane_res.hubp->inst;
|
||||
else
|
||||
copy_settings_data->hubp_inst = 0;
|
||||
if (pipe_ctx->plane_res.dpp)
|
||||
copy_settings_data->dpp_inst = pipe_ctx->plane_res.dpp->inst;
|
||||
else
|
||||
copy_settings_data->dpp_inst = 0;
|
||||
if (pipe_ctx->stream_res.opp)
|
||||
copy_settings_data->opp_inst = pipe_ctx->stream_res.opp->inst;
|
||||
else
|
||||
copy_settings_data->opp_inst = 0;
|
||||
if (pipe_ctx->stream_res.tg)
|
||||
copy_settings_data->otg_inst = pipe_ctx->stream_res.tg->inst;
|
||||
else
|
||||
copy_settings_data->otg_inst = 0;
|
||||
|
||||
// Misc
|
||||
copy_settings_data->psr_level = psr_context->psr_level.u32all;
|
||||
copy_settings_data->hyst_frames = psr_context->timehyst_frames;
|
||||
copy_settings_data->hyst_lines = psr_context->hyst_lines;
|
||||
copy_settings_data->phy_type = psr_context->phyType;
|
||||
copy_settings_data->aux_repeat = psr_context->aux_repeats;
|
||||
copy_settings_data->smu_optimizations_en = psr_context->allow_smu_optimizations;
|
||||
copy_settings_data->skip_wait_for_pll_lock = psr_context->skipPsrWaitForPllLock;
|
||||
copy_settings_data->frame_delay = psr_context->frame_delay;
|
||||
copy_settings_data->smu_phy_id = psr_context->smuPhyId;
|
||||
copy_settings_data->num_of_controllers = psr_context->numberOfControllers;
|
||||
copy_settings_data->frame_cap_ind = psr_context->psrFrameCaptureIndicationReq;
|
||||
copy_settings_data->phy_num = psr_context->frame_delay & 0x7;
|
||||
copy_settings_data->link_rate = psr_context->frame_delay & 0xF;
|
||||
|
||||
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd.psr_copy_settings.header);
|
||||
dc_dmub_srv_cmd_execute(dc->dmub_srv);
|
||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct dmub_psr_funcs psr_funcs = {
|
||||
.set_psr_enable = dmub_set_psr_enable,
|
||||
.setup_psr = dmub_setup_psr,
|
||||
.get_psr_state = dmub_get_psr_state,
|
||||
.set_psr_level = dmub_set_psr_level,
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct PSR object.
|
||||
*/
|
||||
static void dmub_psr_construct(struct dmub_psr *psr, struct dc_context *ctx)
|
||||
{
|
||||
psr->ctx = ctx;
|
||||
psr->funcs = &psr_funcs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate and initialize PSR object.
|
||||
*/
|
||||
struct dmub_psr *dmub_psr_create(struct dc_context *ctx)
|
||||
{
|
||||
struct dmub_psr *psr = kzalloc(sizeof(struct dmub_psr), GFP_KERNEL);
|
||||
|
||||
if (psr == NULL) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dmub_psr_construct(psr, ctx);
|
||||
|
||||
return psr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deallocate PSR object.
|
||||
*/
|
||||
void dmub_psr_destroy(struct dmub_psr **dmub)
|
||||
{
|
||||
kfree(dmub);
|
||||
*dmub = NULL;
|
||||
}
|
47
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
Normal file
47
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-16 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DMUB_PSR_H_
|
||||
#define _DMUB_PSR_H_
|
||||
|
||||
#include "os_types.h"
|
||||
|
||||
struct dmub_psr {
|
||||
struct dc_context *ctx;
|
||||
const struct dmub_psr_funcs *funcs;
|
||||
};
|
||||
|
||||
struct dmub_psr_funcs {
|
||||
void (*set_psr_enable)(struct dmub_psr *dmub, bool enable);
|
||||
bool (*setup_psr)(struct dmub_psr *dmub, struct dc_link *link, struct psr_context *psr_context);
|
||||
void (*get_psr_state)(uint32_t *psr_state);
|
||||
void (*set_psr_level)(struct dmub_psr *dmub, uint16_t psr_level);
|
||||
};
|
||||
|
||||
struct dmub_psr *dmub_psr_create(struct dc_context *ctx);
|
||||
void dmub_psr_destroy(struct dmub_psr **dmub);
|
||||
|
||||
|
||||
#endif /* _DCE_DMUB_H_ */
|
@ -1373,9 +1373,13 @@ static enum dc_status apply_single_controller_ctx_to_hw(
|
||||
// DRR should set trigger event to monitor surface update event
|
||||
if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
|
||||
event_triggers = 0x80;
|
||||
/* Event triggers and num frames initialized for DRR, but can be
|
||||
* later updated for PSR use. Note DRR trigger events are generated
|
||||
* regardless of whether num frames met.
|
||||
*/
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
|
||||
pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
|
||||
pipe_ctx->stream_res.tg, event_triggers);
|
||||
pipe_ctx->stream_res.tg, event_triggers, 2);
|
||||
|
||||
if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg(
|
||||
@ -1706,6 +1710,8 @@ static void set_drr(struct pipe_ctx **pipe_ctx,
|
||||
struct drr_params params = {0};
|
||||
// DRR should set trigger event to monitor surface update event
|
||||
unsigned int event_triggers = 0x80;
|
||||
// Note DRR trigger events are generated regardless of whether num frames met.
|
||||
unsigned int num_frames = 2;
|
||||
|
||||
params.vertical_total_max = vmax;
|
||||
params.vertical_total_min = vmin;
|
||||
@ -1721,7 +1727,7 @@ static void set_drr(struct pipe_ctx **pipe_ctx,
|
||||
if (vmax != 0 && vmin != 0)
|
||||
pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
|
||||
pipe_ctx[i]->stream_res.tg,
|
||||
event_triggers);
|
||||
event_triggers, num_frames);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1738,30 +1744,31 @@ static void get_position(struct pipe_ctx **pipe_ctx,
|
||||
}
|
||||
|
||||
static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
|
||||
int num_pipes, const struct dc_static_screen_events *events)
|
||||
int num_pipes, const struct dc_static_screen_params *params)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int value = 0;
|
||||
unsigned int triggers = 0;
|
||||
|
||||
if (events->overlay_update)
|
||||
value |= 0x100;
|
||||
if (events->surface_update)
|
||||
value |= 0x80;
|
||||
if (events->cursor_update)
|
||||
value |= 0x2;
|
||||
if (events->force_trigger)
|
||||
value |= 0x1;
|
||||
if (params->triggers.overlay_update)
|
||||
triggers |= 0x100;
|
||||
if (params->triggers.surface_update)
|
||||
triggers |= 0x80;
|
||||
if (params->triggers.cursor_update)
|
||||
triggers |= 0x2;
|
||||
if (params->triggers.force_trigger)
|
||||
triggers |= 0x1;
|
||||
|
||||
if (num_pipes) {
|
||||
struct dc *dc = pipe_ctx[0]->stream->ctx->dc;
|
||||
|
||||
if (dc->fbc_compressor)
|
||||
value |= 0x84;
|
||||
triggers |= 0x84;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_pipes; i++)
|
||||
pipe_ctx[i]->stream_res.tg->funcs->
|
||||
set_static_screen_control(pipe_ctx[i]->stream_res.tg, value);
|
||||
set_static_screen_control(pipe_ctx[i]->stream_res.tg,
|
||||
triggers, params->num_frames);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -469,22 +469,27 @@ void dce110_timing_generator_set_drr(
|
||||
|
||||
void dce110_timing_generator_set_static_screen_control(
|
||||
struct timing_generator *tg,
|
||||
uint32_t value)
|
||||
uint32_t event_triggers,
|
||||
uint32_t num_frames)
|
||||
{
|
||||
struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
|
||||
uint32_t static_screen_cntl = 0;
|
||||
uint32_t addr = 0;
|
||||
|
||||
// By register spec, it only takes 8 bit value
|
||||
if (num_frames > 0xFF)
|
||||
num_frames = 0xFF;
|
||||
|
||||
addr = CRTC_REG(mmCRTC_STATIC_SCREEN_CONTROL);
|
||||
static_screen_cntl = dm_read_reg(tg->ctx, addr);
|
||||
|
||||
set_reg_field_value(static_screen_cntl,
|
||||
value,
|
||||
event_triggers,
|
||||
CRTC_STATIC_SCREEN_CONTROL,
|
||||
CRTC_STATIC_SCREEN_EVENT_MASK);
|
||||
|
||||
set_reg_field_value(static_screen_cntl,
|
||||
2,
|
||||
num_frames,
|
||||
CRTC_STATIC_SCREEN_CONTROL,
|
||||
CRTC_STATIC_SCREEN_FRAME_COUNT);
|
||||
|
||||
|
@ -231,7 +231,8 @@ void dce110_timing_generator_set_drr(
|
||||
|
||||
void dce110_timing_generator_set_static_screen_control(
|
||||
struct timing_generator *tg,
|
||||
uint32_t value);
|
||||
uint32_t event_triggers,
|
||||
uint32_t num_frames);
|
||||
|
||||
void dce110_timing_generator_get_crtc_scanoutpos(
|
||||
struct timing_generator *tg,
|
||||
|
@ -819,13 +819,18 @@ void dce120_tg_set_colors(struct timing_generator *tg,
|
||||
|
||||
static void dce120_timing_generator_set_static_screen_control(
|
||||
struct timing_generator *tg,
|
||||
uint32_t value)
|
||||
uint32_t event_triggers,
|
||||
uint32_t num_frames)
|
||||
{
|
||||
struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
|
||||
|
||||
// By register spec, it only takes 8 bit value
|
||||
if (num_frames > 0xFF)
|
||||
num_frames = 0xFF;
|
||||
|
||||
CRTC_REG_UPDATE_2(CRTC0_CRTC_STATIC_SCREEN_CONTROL,
|
||||
CRTC_STATIC_SCREEN_EVENT_MASK, value,
|
||||
CRTC_STATIC_SCREEN_FRAME_COUNT, 2);
|
||||
CRTC_STATIC_SCREEN_EVENT_MASK, event_triggers,
|
||||
CRTC_STATIC_SCREEN_FRAME_COUNT, num_frames);
|
||||
}
|
||||
|
||||
void dce120_timing_generator_set_test_pattern(
|
||||
|
@ -88,26 +88,6 @@ enum dscl_mode_sel {
|
||||
DSCL_MODE_DSCL_BYPASS = 6
|
||||
};
|
||||
|
||||
static const struct dpp_input_csc_matrix dpp_input_csc_matrix[] = {
|
||||
{COLOR_SPACE_SRGB,
|
||||
{0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
|
||||
{COLOR_SPACE_SRGB_LIMITED,
|
||||
{0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
|
||||
{COLOR_SPACE_YCBCR601,
|
||||
{0x2cdd, 0x2000, 0, 0xe991, 0xe926, 0x2000, 0xf4fd, 0x10ef,
|
||||
0, 0x2000, 0x38b4, 0xe3a6} },
|
||||
{COLOR_SPACE_YCBCR601_LIMITED,
|
||||
{0x3353, 0x2568, 0, 0xe400, 0xe5dc, 0x2568, 0xf367, 0x1108,
|
||||
0, 0x2568, 0x40de, 0xdd3a} },
|
||||
{COLOR_SPACE_YCBCR709,
|
||||
{0x3265, 0x2000, 0, 0xe6ce, 0xf105, 0x2000, 0xfa01, 0xa7d, 0,
|
||||
0x2000, 0x3b61, 0xe24f} },
|
||||
|
||||
{COLOR_SPACE_YCBCR709_LIMITED,
|
||||
{0x39a6, 0x2568, 0, 0xe0d6, 0xeedd, 0x2568, 0xf925, 0x9a8, 0,
|
||||
0x2568, 0x43ee, 0xdbb2} }
|
||||
};
|
||||
|
||||
static void program_gamut_remap(
|
||||
struct dcn10_dpp *dpp,
|
||||
const uint16_t *regval,
|
||||
|
@ -930,6 +930,9 @@ static bool hubbub1_get_dcc_compression_cap(struct hubbub *hubbub,
|
||||
output->grph.rgb.max_compressed_blk_size = 64;
|
||||
output->grph.rgb.independent_64b_blks = true;
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
output->capable = true;
|
||||
|
@ -1188,8 +1188,14 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
|
||||
if (can_apply_seamless_boot &&
|
||||
pipe_ctx->stream != NULL &&
|
||||
pipe_ctx->stream_res.tg->funcs->is_tg_enabled(
|
||||
pipe_ctx->stream_res.tg))
|
||||
pipe_ctx->stream_res.tg)) {
|
||||
// Enable double buffering for OTG_BLANK no matter if
|
||||
// seamless boot is enabled or not to suppress global sync
|
||||
// signals when OTG blanked. This is to prevent pipe from
|
||||
// requesting data while in PSR.
|
||||
tg->funcs->tg_init(tg);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Disable on the current state so the new one isn't cleared. */
|
||||
pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
@ -2704,6 +2710,8 @@ void dcn10_set_drr(struct pipe_ctx **pipe_ctx,
|
||||
struct drr_params params = {0};
|
||||
// DRR set trigger event mapped to OTG_TRIG_A (bit 11) for manual control flow
|
||||
unsigned int event_triggers = 0x800;
|
||||
// Note DRR trigger events are generated regardless of whether num frames met.
|
||||
unsigned int num_frames = 2;
|
||||
|
||||
params.vertical_total_max = vmax;
|
||||
params.vertical_total_min = vmin;
|
||||
@ -2720,7 +2728,7 @@ void dcn10_set_drr(struct pipe_ctx **pipe_ctx,
|
||||
if (vmax != 0 && vmin != 0)
|
||||
pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
|
||||
pipe_ctx[i]->stream_res.tg,
|
||||
event_triggers);
|
||||
event_triggers, num_frames);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2737,21 +2745,22 @@ void dcn10_get_position(struct pipe_ctx **pipe_ctx,
|
||||
}
|
||||
|
||||
void dcn10_set_static_screen_control(struct pipe_ctx **pipe_ctx,
|
||||
int num_pipes, const struct dc_static_screen_events *events)
|
||||
int num_pipes, const struct dc_static_screen_params *params)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int value = 0;
|
||||
unsigned int triggers = 0;
|
||||
|
||||
if (events->surface_update)
|
||||
value |= 0x80;
|
||||
if (events->cursor_update)
|
||||
value |= 0x2;
|
||||
if (events->force_trigger)
|
||||
value |= 0x1;
|
||||
if (params->triggers.surface_update)
|
||||
triggers |= 0x80;
|
||||
if (params->triggers.cursor_update)
|
||||
triggers |= 0x2;
|
||||
if (params->triggers.force_trigger)
|
||||
triggers |= 0x1;
|
||||
|
||||
for (i = 0; i < num_pipes; i++)
|
||||
pipe_ctx[i]->stream_res.tg->funcs->
|
||||
set_static_screen_control(pipe_ctx[i]->stream_res.tg, value);
|
||||
set_static_screen_control(pipe_ctx[i]->stream_res.tg,
|
||||
triggers, params->num_frames);
|
||||
}
|
||||
|
||||
static void dcn10_config_stereo_parameters(
|
||||
|
@ -132,7 +132,7 @@ void dcn10_get_position(struct pipe_ctx **pipe_ctx,
|
||||
int num_pipes,
|
||||
struct crtc_position *position);
|
||||
void dcn10_set_static_screen_control(struct pipe_ctx **pipe_ctx,
|
||||
int num_pipes, const struct dc_static_screen_events *events);
|
||||
int num_pipes, const struct dc_static_screen_params *params);
|
||||
void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc);
|
||||
void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
void dcn10_log_hw_state(struct dc *dc,
|
||||
|
@ -789,21 +789,26 @@ void optc1_set_early_control(
|
||||
|
||||
void optc1_set_static_screen_control(
|
||||
struct timing_generator *optc,
|
||||
uint32_t value)
|
||||
uint32_t event_triggers,
|
||||
uint32_t num_frames)
|
||||
{
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
|
||||
// By register spec, it only takes 8 bit value
|
||||
if (num_frames > 0xFF)
|
||||
num_frames = 0xFF;
|
||||
|
||||
/* Bit 8 is no longer applicable in RV for PSR case,
|
||||
* set bit 8 to 0 if given
|
||||
*/
|
||||
if ((value & STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN)
|
||||
if ((event_triggers & STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN)
|
||||
!= 0)
|
||||
value = value &
|
||||
event_triggers = event_triggers &
|
||||
~STATIC_SCREEN_EVENT_MASK_RANGETIMING_DOUBLE_BUFFER_UPDATE_EN;
|
||||
|
||||
REG_SET_2(OTG_STATIC_SCREEN_CONTROL, 0,
|
||||
OTG_STATIC_SCREEN_EVENT_MASK, value,
|
||||
OTG_STATIC_SCREEN_FRAME_COUNT, 2);
|
||||
OTG_STATIC_SCREEN_EVENT_MASK, event_triggers,
|
||||
OTG_STATIC_SCREEN_FRAME_COUNT, num_frames);
|
||||
}
|
||||
|
||||
void optc1_setup_manual_trigger(struct timing_generator *optc)
|
||||
|
@ -625,7 +625,8 @@ void optc1_set_drr(
|
||||
|
||||
void optc1_set_static_screen_control(
|
||||
struct timing_generator *optc,
|
||||
uint32_t value);
|
||||
uint32_t event_triggers,
|
||||
uint32_t num_frames);
|
||||
|
||||
void optc1_program_stereo(struct timing_generator *optc,
|
||||
const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags);
|
||||
|
@ -104,7 +104,7 @@ static void dpp2_cnv_setup (
|
||||
uint32_t pixel_format = 0;
|
||||
uint32_t alpha_en = 1;
|
||||
enum dc_color_space color_space = COLOR_SPACE_SRGB;
|
||||
enum dcn10_input_csc_select select = INPUT_CSC_SELECT_BYPASS;
|
||||
enum dcn20_input_csc_select select = DCN2_ICSC_SELECT_BYPASS;
|
||||
bool force_disable_cursor = false;
|
||||
struct out_csc_color_matrix tbl_entry;
|
||||
uint32_t is_2bit = 0;
|
||||
@ -145,25 +145,25 @@ static void dpp2_cnv_setup (
|
||||
force_disable_cursor = false;
|
||||
pixel_format = 65;
|
||||
color_space = COLOR_SPACE_YCBCR709;
|
||||
select = INPUT_CSC_SELECT_ICSC;
|
||||
select = DCN2_ICSC_SELECT_ICSC_A;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
|
||||
force_disable_cursor = true;
|
||||
pixel_format = 64;
|
||||
color_space = COLOR_SPACE_YCBCR709;
|
||||
select = INPUT_CSC_SELECT_ICSC;
|
||||
select = DCN2_ICSC_SELECT_ICSC_A;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
|
||||
force_disable_cursor = true;
|
||||
pixel_format = 67;
|
||||
color_space = COLOR_SPACE_YCBCR709;
|
||||
select = INPUT_CSC_SELECT_ICSC;
|
||||
select = DCN2_ICSC_SELECT_ICSC_A;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
|
||||
force_disable_cursor = true;
|
||||
pixel_format = 66;
|
||||
color_space = COLOR_SPACE_YCBCR709;
|
||||
select = INPUT_CSC_SELECT_ICSC;
|
||||
select = DCN2_ICSC_SELECT_ICSC_A;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
|
||||
pixel_format = 22;
|
||||
@ -177,7 +177,7 @@ static void dpp2_cnv_setup (
|
||||
case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
|
||||
pixel_format = 12;
|
||||
color_space = COLOR_SPACE_YCBCR709;
|
||||
select = INPUT_CSC_SELECT_ICSC;
|
||||
select = DCN2_ICSC_SELECT_ICSC_A;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
|
||||
pixel_format = 112;
|
||||
@ -188,13 +188,13 @@ static void dpp2_cnv_setup (
|
||||
case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
|
||||
pixel_format = 114;
|
||||
color_space = COLOR_SPACE_YCBCR709;
|
||||
select = INPUT_CSC_SELECT_ICSC;
|
||||
select = DCN2_ICSC_SELECT_ICSC_A;
|
||||
is_2bit = 1;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
|
||||
pixel_format = 115;
|
||||
color_space = COLOR_SPACE_YCBCR709;
|
||||
select = INPUT_CSC_SELECT_ICSC;
|
||||
select = DCN2_ICSC_SELECT_ICSC_A;
|
||||
is_2bit = 1;
|
||||
break;
|
||||
case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
|
||||
@ -227,13 +227,13 @@ static void dpp2_cnv_setup (
|
||||
tbl_entry.color_space = input_color_space;
|
||||
|
||||
if (color_space >= COLOR_SPACE_YCBCR601)
|
||||
select = INPUT_CSC_SELECT_ICSC;
|
||||
select = DCN2_ICSC_SELECT_ICSC_A;
|
||||
else
|
||||
select = INPUT_CSC_SELECT_BYPASS;
|
||||
select = DCN2_ICSC_SELECT_BYPASS;
|
||||
|
||||
dpp1_program_input_csc(dpp_base, color_space, select, &tbl_entry);
|
||||
dpp2_program_input_csc(dpp_base, color_space, select, &tbl_entry);
|
||||
} else
|
||||
dpp1_program_input_csc(dpp_base, color_space, select, NULL);
|
||||
dpp2_program_input_csc(dpp_base, color_space, select, NULL);
|
||||
|
||||
if (force_disable_cursor) {
|
||||
REG_UPDATE(CURSOR_CONTROL,
|
||||
@ -458,7 +458,7 @@ static struct dpp_funcs dcn20_dpp_funcs = {
|
||||
.dpp_reset = dpp_reset,
|
||||
.dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale,
|
||||
.dpp_get_optimal_number_of_taps = dpp1_get_optimal_number_of_taps,
|
||||
.dpp_set_gamut_remap = dpp1_cm_set_gamut_remap,
|
||||
.dpp_set_gamut_remap = dpp2_cm_set_gamut_remap,
|
||||
.dpp_set_csc_adjustment = NULL,
|
||||
.dpp_set_csc_default = NULL,
|
||||
.dpp_program_regamma_pwl = oppn20_dummy_program_regamma_pwl,
|
||||
|
@ -150,6 +150,16 @@
|
||||
SRI(CM_SHAPER_RAMA_REGION_32_33, CM, id), \
|
||||
SRI(CM_SHAPER_LUT_INDEX, CM, id)
|
||||
|
||||
#define TF_REG_LIST_DCN20_COMMON_APPEND(id) \
|
||||
SRI(CM_GAMUT_REMAP_B_C11_C12, CM, id),\
|
||||
SRI(CM_GAMUT_REMAP_B_C13_C14, CM, id),\
|
||||
SRI(CM_GAMUT_REMAP_B_C21_C22, CM, id),\
|
||||
SRI(CM_GAMUT_REMAP_B_C23_C24, CM, id),\
|
||||
SRI(CM_GAMUT_REMAP_B_C31_C32, CM, id),\
|
||||
SRI(CM_GAMUT_REMAP_B_C33_C34, CM, id),\
|
||||
SRI(CM_ICSC_B_C11_C12, CM, id), \
|
||||
SRI(CM_ICSC_B_C33_C34, CM, id)
|
||||
|
||||
#define TF_REG_LIST_DCN20(id) \
|
||||
TF_REG_LIST_DCN(id), \
|
||||
TF_REG_LIST_DCN20_COMMON(id), \
|
||||
@ -572,10 +582,29 @@
|
||||
TF_SF(DSCL0_OBUF_MEM_PWR_CTRL, OBUF_MEM_PWR_FORCE, mask_sh),\
|
||||
TF_SF(DSCL0_DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, mask_sh)
|
||||
|
||||
/* DPP CM debug status register:
|
||||
*
|
||||
* Status index including current ICSC, Gamut Remap Mode is 9
|
||||
* ICSC Mode: [4..3]
|
||||
* Gamut Remap Mode: [10..9]
|
||||
*/
|
||||
#define CM_TEST_DEBUG_DATA_STATUS_IDX 9
|
||||
|
||||
#define TF_DEBUG_REG_LIST_SH_DCN20 \
|
||||
TF_DEBUG_REG_LIST_SH_DCN10, \
|
||||
.CM_TEST_DEBUG_DATA_ICSC_MODE = 3, \
|
||||
.CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE = 9
|
||||
|
||||
#define TF_DEBUG_REG_LIST_MASK_DCN20 \
|
||||
TF_DEBUG_REG_LIST_MASK_DCN10, \
|
||||
.CM_TEST_DEBUG_DATA_ICSC_MODE = 0x18, \
|
||||
.CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE = 0x600
|
||||
|
||||
#define TF_REG_FIELD_LIST_DCN2_0(type) \
|
||||
TF_REG_FIELD_LIST(type) \
|
||||
type CM_BLNDGAM_LUT_DATA; \
|
||||
type CM_TEST_DEBUG_DATA_ICSC_MODE; \
|
||||
type CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE; \
|
||||
type FORMAT_CNV16; \
|
||||
type CNVC_BYPASS_MSB_ALIGN; \
|
||||
type CLAMP_POSITIVE; \
|
||||
@ -630,11 +659,22 @@ struct dcn2_dpp_mask {
|
||||
uint32_t COLOR_KEYER_RED; \
|
||||
uint32_t COLOR_KEYER_GREEN; \
|
||||
uint32_t COLOR_KEYER_BLUE; \
|
||||
uint32_t OBUF_MEM_PWR_CTRL;\
|
||||
uint32_t OBUF_MEM_PWR_CTRL; \
|
||||
uint32_t DSCL_MEM_PWR_CTRL
|
||||
|
||||
#define DPP_DCN2_REG_VARIABLE_LIST_CM_APPEND \
|
||||
uint32_t CM_GAMUT_REMAP_B_C11_C12; \
|
||||
uint32_t CM_GAMUT_REMAP_B_C13_C14; \
|
||||
uint32_t CM_GAMUT_REMAP_B_C21_C22; \
|
||||
uint32_t CM_GAMUT_REMAP_B_C23_C24; \
|
||||
uint32_t CM_GAMUT_REMAP_B_C31_C32; \
|
||||
uint32_t CM_GAMUT_REMAP_B_C33_C34; \
|
||||
uint32_t CM_ICSC_B_C11_C12; \
|
||||
uint32_t CM_ICSC_B_C33_C34
|
||||
|
||||
struct dcn2_dpp_registers {
|
||||
DPP_DCN2_REG_VARIABLE_LIST;
|
||||
DPP_DCN2_REG_VARIABLE_LIST_CM_APPEND;
|
||||
};
|
||||
|
||||
struct dcn20_dpp {
|
||||
@ -656,6 +696,18 @@ struct dcn20_dpp {
|
||||
struct pwl_params pwl_data;
|
||||
};
|
||||
|
||||
enum dcn20_input_csc_select {
|
||||
DCN2_ICSC_SELECT_BYPASS = 0,
|
||||
DCN2_ICSC_SELECT_ICSC_A = 1,
|
||||
DCN2_ICSC_SELECT_ICSC_B = 2
|
||||
};
|
||||
|
||||
enum dcn20_gamut_remap_select {
|
||||
DCN2_GAMUT_REMAP_BYPASS = 0,
|
||||
DCN2_GAMUT_REMAP_COEF_A = 1,
|
||||
DCN2_GAMUT_REMAP_COEF_B = 2
|
||||
};
|
||||
|
||||
void dpp20_read_state(struct dpp *dpp_base,
|
||||
struct dcn_dpp_state *s);
|
||||
|
||||
@ -667,6 +719,16 @@ void dpp2_set_degamma(
|
||||
struct dpp *dpp_base,
|
||||
enum ipp_degamma_mode mode);
|
||||
|
||||
void dpp2_cm_set_gamut_remap(
|
||||
struct dpp *dpp_base,
|
||||
const struct dpp_grph_csc_adjustment *adjust);
|
||||
|
||||
void dpp2_program_input_csc(
|
||||
struct dpp *dpp_base,
|
||||
enum dc_color_space color_space,
|
||||
enum dcn20_input_csc_select input_select,
|
||||
const struct out_csc_color_matrix *tbl_entry);
|
||||
|
||||
bool dpp20_program_blnd_lut(
|
||||
struct dpp *dpp_base, const struct pwl_params *params);
|
||||
|
||||
|
@ -36,6 +36,9 @@
|
||||
#define REG(reg)\
|
||||
dpp->tf_regs->reg
|
||||
|
||||
#define IND_REG(index) \
|
||||
(index)
|
||||
|
||||
#define CTX \
|
||||
dpp->base.ctx
|
||||
|
||||
@ -44,9 +47,6 @@
|
||||
dpp->tf_shift->field_name, dpp->tf_mask->field_name
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void dpp2_enable_cm_block(
|
||||
struct dpp *dpp_base)
|
||||
{
|
||||
@ -158,6 +158,155 @@ void dpp2_set_degamma(
|
||||
}
|
||||
}
|
||||
|
||||
static void program_gamut_remap(
|
||||
struct dcn20_dpp *dpp,
|
||||
const uint16_t *regval,
|
||||
enum dcn20_gamut_remap_select select)
|
||||
{
|
||||
uint32_t cur_select = 0;
|
||||
struct color_matrices_reg gam_regs;
|
||||
|
||||
if (regval == NULL || select == DCN2_GAMUT_REMAP_BYPASS) {
|
||||
REG_SET(CM_GAMUT_REMAP_CONTROL, 0,
|
||||
CM_GAMUT_REMAP_MODE, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* determine which gamut_remap coefficients (A or B) we are using
|
||||
* currently. select the alternate set to double buffer
|
||||
* the update so gamut_remap is updated on frame boundary
|
||||
*/
|
||||
IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
|
||||
CM_TEST_DEBUG_DATA_STATUS_IDX,
|
||||
CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE, &cur_select);
|
||||
|
||||
/* value stored in dbg reg will be 1 greater than mode we want */
|
||||
if (cur_select != DCN2_GAMUT_REMAP_COEF_A)
|
||||
select = DCN2_GAMUT_REMAP_COEF_A;
|
||||
else
|
||||
select = DCN2_GAMUT_REMAP_COEF_B;
|
||||
|
||||
gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11;
|
||||
gam_regs.masks.csc_c11 = dpp->tf_mask->CM_GAMUT_REMAP_C11;
|
||||
gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12;
|
||||
gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12;
|
||||
|
||||
if (select == DCN2_GAMUT_REMAP_COEF_A) {
|
||||
gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_C11_C12);
|
||||
gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34);
|
||||
} else {
|
||||
gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_B_C11_C12);
|
||||
gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_B_C33_C34);
|
||||
}
|
||||
|
||||
cm_helper_program_color_matrices(
|
||||
dpp->base.ctx,
|
||||
regval,
|
||||
&gam_regs);
|
||||
|
||||
REG_SET(
|
||||
CM_GAMUT_REMAP_CONTROL, 0,
|
||||
CM_GAMUT_REMAP_MODE, select);
|
||||
|
||||
}
|
||||
|
||||
void dpp2_cm_set_gamut_remap(
|
||||
struct dpp *dpp_base,
|
||||
const struct dpp_grph_csc_adjustment *adjust)
|
||||
{
|
||||
struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
|
||||
int i = 0;
|
||||
|
||||
if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
|
||||
/* Bypass if type is bypass or hw */
|
||||
program_gamut_remap(dpp, NULL, DCN2_GAMUT_REMAP_BYPASS);
|
||||
else {
|
||||
struct fixed31_32 arr_matrix[12];
|
||||
uint16_t arr_reg_val[12];
|
||||
|
||||
for (i = 0; i < 12; i++)
|
||||
arr_matrix[i] = adjust->temperature_matrix[i];
|
||||
|
||||
convert_float_matrix(
|
||||
arr_reg_val, arr_matrix, 12);
|
||||
|
||||
program_gamut_remap(dpp, arr_reg_val, DCN2_GAMUT_REMAP_COEF_A);
|
||||
}
|
||||
}
|
||||
|
||||
void dpp2_program_input_csc(
|
||||
struct dpp *dpp_base,
|
||||
enum dc_color_space color_space,
|
||||
enum dcn20_input_csc_select input_select,
|
||||
const struct out_csc_color_matrix *tbl_entry)
|
||||
{
|
||||
struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
|
||||
int i;
|
||||
int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix);
|
||||
const uint16_t *regval = NULL;
|
||||
uint32_t cur_select = 0;
|
||||
enum dcn20_input_csc_select select;
|
||||
struct color_matrices_reg icsc_regs;
|
||||
|
||||
if (input_select == DCN2_ICSC_SELECT_BYPASS) {
|
||||
REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tbl_entry == NULL) {
|
||||
for (i = 0; i < arr_size; i++)
|
||||
if (dpp_input_csc_matrix[i].color_space == color_space) {
|
||||
regval = dpp_input_csc_matrix[i].regval;
|
||||
break;
|
||||
}
|
||||
|
||||
if (regval == NULL) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
regval = tbl_entry->regval;
|
||||
}
|
||||
|
||||
/* determine which CSC coefficients (A or B) we are using
|
||||
* currently. select the alternate set to double buffer
|
||||
* the CSC update so CSC is updated on frame boundary
|
||||
*/
|
||||
IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
|
||||
CM_TEST_DEBUG_DATA_STATUS_IDX,
|
||||
CM_TEST_DEBUG_DATA_ICSC_MODE, &cur_select);
|
||||
|
||||
if (cur_select != DCN2_ICSC_SELECT_ICSC_A)
|
||||
select = DCN2_ICSC_SELECT_ICSC_A;
|
||||
else
|
||||
select = DCN2_ICSC_SELECT_ICSC_B;
|
||||
|
||||
icsc_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11;
|
||||
icsc_regs.masks.csc_c11 = dpp->tf_mask->CM_ICSC_C11;
|
||||
icsc_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12;
|
||||
icsc_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12;
|
||||
|
||||
if (select == DCN2_ICSC_SELECT_ICSC_A) {
|
||||
|
||||
icsc_regs.csc_c11_c12 = REG(CM_ICSC_C11_C12);
|
||||
icsc_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34);
|
||||
|
||||
} else {
|
||||
|
||||
icsc_regs.csc_c11_c12 = REG(CM_ICSC_B_C11_C12);
|
||||
icsc_regs.csc_c33_c34 = REG(CM_ICSC_B_C33_C34);
|
||||
|
||||
}
|
||||
|
||||
cm_helper_program_color_matrices(
|
||||
dpp->base.ctx,
|
||||
regval,
|
||||
&icsc_regs);
|
||||
|
||||
REG_SET(CM_ICSC_CONTROL, 0,
|
||||
CM_ICSC_MODE, select);
|
||||
}
|
||||
|
||||
static void dpp20_power_on_blnd_lut(
|
||||
struct dpp *dpp_base,
|
||||
bool power_on)
|
||||
|
@ -293,6 +293,9 @@ bool hubbub2_get_dcc_compression_cap(struct hubbub *hubbub,
|
||||
output->grph.rgb.max_compressed_blk_size = 64;
|
||||
output->grph.rgb.independent_64b_blks = true;
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
break;
|
||||
}
|
||||
output->capable = true;
|
||||
output->const_color_support = true;
|
||||
@ -601,7 +604,8 @@ static const struct hubbub_funcs hubbub2_funcs = {
|
||||
.wm_read_state = hubbub2_wm_read_state,
|
||||
.get_dchub_ref_freq = hubbub2_get_dchub_ref_freq,
|
||||
.program_watermarks = hubbub2_program_watermarks,
|
||||
.allow_self_refresh_control = hubbub1_allow_self_refresh_control
|
||||
.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
|
||||
.allow_self_refresh_control = hubbub1_allow_self_refresh_control,
|
||||
};
|
||||
|
||||
void hubbub2_construct(struct dcn20_hubbub *hubbub,
|
||||
|
@ -686,9 +686,13 @@ enum dc_status dcn20_enable_stream_timing(
|
||||
// DRR should set trigger event to monitor surface update event
|
||||
if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0)
|
||||
event_triggers = 0x80;
|
||||
/* Event triggers and num frames initialized for DRR, but can be
|
||||
* later updated for PSR use. Note DRR trigger events are generated
|
||||
* regardless of whether num frames met.
|
||||
*/
|
||||
if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control)
|
||||
pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
|
||||
pipe_ctx->stream_res.tg, event_triggers);
|
||||
pipe_ctx->stream_res.tg, event_triggers, 2);
|
||||
|
||||
/* TODO program crtc source select for non-virtual signal*/
|
||||
/* TODO program FMT */
|
||||
@ -941,6 +945,9 @@ void dcn20_blank_pixel_data(
|
||||
int width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
|
||||
int height = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
|
||||
|
||||
if (stream->link->test_pattern_enabled)
|
||||
return;
|
||||
|
||||
/* get opp dpg blank color */
|
||||
color_space_to_black_color(dc, color_space, &black_color);
|
||||
|
||||
@ -1638,9 +1645,9 @@ void dcn20_program_front_end_for_ctx(
|
||||
struct hubp *hubp = pipe->plane_res.hubp;
|
||||
int j = 0;
|
||||
|
||||
for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS
|
||||
for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS*1000
|
||||
&& hubp->funcs->hubp_is_flip_pending(hubp); j++)
|
||||
msleep(1);
|
||||
mdelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,9 @@
|
||||
#define REG(reg)\
|
||||
mpc20->mpc_regs->reg
|
||||
|
||||
#define IND_REG(index) \
|
||||
(index)
|
||||
|
||||
#define CTX \
|
||||
mpc20->base.ctx
|
||||
|
||||
@ -132,19 +135,33 @@ void mpc2_set_output_csc(
|
||||
const uint16_t *regval,
|
||||
enum mpc_output_csc_mode ocsc_mode)
|
||||
{
|
||||
uint32_t cur_mode;
|
||||
struct dcn20_mpc *mpc20 = TO_DCN20_MPC(mpc);
|
||||
struct color_matrices_reg ocsc_regs;
|
||||
|
||||
REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
|
||||
|
||||
if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE)
|
||||
if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE) {
|
||||
REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
|
||||
return;
|
||||
}
|
||||
|
||||
if (regval == NULL) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
|
||||
/* determine which CSC coefficients (A or B) we are using
|
||||
* currently. select the alternate set to double buffer
|
||||
* the CSC update so CSC is updated on frame boundary
|
||||
*/
|
||||
IX_REG_GET(MPC_OCSC_TEST_DEBUG_INDEX, MPC_OCSC_TEST_DEBUG_DATA,
|
||||
MPC_OCSC_TEST_DEBUG_DATA_STATUS_IDX,
|
||||
MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE, &cur_mode);
|
||||
|
||||
if (cur_mode != MPC_OUTPUT_CSC_COEF_A)
|
||||
ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
|
||||
else
|
||||
ocsc_mode = MPC_OUTPUT_CSC_COEF_B;
|
||||
|
||||
ocsc_regs.shifts.csc_c11 = mpc20->mpc_shift->MPC_OCSC_C11_A;
|
||||
ocsc_regs.masks.csc_c11 = mpc20->mpc_mask->MPC_OCSC_C11_A;
|
||||
ocsc_regs.shifts.csc_c12 = mpc20->mpc_shift->MPC_OCSC_C12_A;
|
||||
@ -157,10 +174,13 @@ void mpc2_set_output_csc(
|
||||
ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_B[opp_id]);
|
||||
ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_B[opp_id]);
|
||||
}
|
||||
|
||||
cm_helper_program_color_matrices(
|
||||
mpc20->base.ctx,
|
||||
regval,
|
||||
&ocsc_regs);
|
||||
|
||||
REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
|
||||
}
|
||||
|
||||
void mpc2_set_ocsc_default(
|
||||
@ -169,14 +189,16 @@ void mpc2_set_ocsc_default(
|
||||
enum dc_color_space color_space,
|
||||
enum mpc_output_csc_mode ocsc_mode)
|
||||
{
|
||||
uint32_t cur_mode;
|
||||
struct dcn20_mpc *mpc20 = TO_DCN20_MPC(mpc);
|
||||
uint32_t arr_size;
|
||||
struct color_matrices_reg ocsc_regs;
|
||||
const uint16_t *regval = NULL;
|
||||
|
||||
REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
|
||||
if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE)
|
||||
if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE) {
|
||||
REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
|
||||
return;
|
||||
}
|
||||
|
||||
regval = find_color_matrix(color_space, &arr_size);
|
||||
|
||||
@ -185,6 +207,19 @@ void mpc2_set_ocsc_default(
|
||||
return;
|
||||
}
|
||||
|
||||
/* determine which CSC coefficients (A or B) we are using
|
||||
* currently. select the alternate set to double buffer
|
||||
* the CSC update so CSC is updated on frame boundary
|
||||
*/
|
||||
IX_REG_GET(MPC_OCSC_TEST_DEBUG_INDEX, MPC_OCSC_TEST_DEBUG_DATA,
|
||||
MPC_OCSC_TEST_DEBUG_DATA_STATUS_IDX,
|
||||
MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE, &cur_mode);
|
||||
|
||||
if (cur_mode != MPC_OUTPUT_CSC_COEF_A)
|
||||
ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
|
||||
else
|
||||
ocsc_mode = MPC_OUTPUT_CSC_COEF_B;
|
||||
|
||||
ocsc_regs.shifts.csc_c11 = mpc20->mpc_shift->MPC_OCSC_C11_A;
|
||||
ocsc_regs.masks.csc_c11 = mpc20->mpc_mask->MPC_OCSC_C11_A;
|
||||
ocsc_regs.shifts.csc_c12 = mpc20->mpc_shift->MPC_OCSC_C12_A;
|
||||
@ -203,6 +238,8 @@ void mpc2_set_ocsc_default(
|
||||
mpc20->base.ctx,
|
||||
regval,
|
||||
&ocsc_regs);
|
||||
|
||||
REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
|
||||
}
|
||||
|
||||
static void mpc2_ogam_get_reg_field(
|
||||
|
@ -80,6 +80,10 @@
|
||||
SRII(DENORM_CLAMP_G_Y, MPC_OUT, inst),\
|
||||
SRII(DENORM_CLAMP_B_CB, MPC_OUT, inst)
|
||||
|
||||
#define MPC_DBG_REG_LIST_DCN2_0() \
|
||||
SR(MPC_OCSC_TEST_DEBUG_DATA),\
|
||||
SR(MPC_OCSC_TEST_DEBUG_INDEX)
|
||||
|
||||
#define MPC_REG_VARIABLE_LIST_DCN2_0 \
|
||||
MPC_COMMON_REG_VARIABLE_LIST \
|
||||
uint32_t MPCC_TOP_GAIN[MAX_MPCC]; \
|
||||
@ -118,6 +122,8 @@
|
||||
uint32_t MPCC_OGAM_LUT_RAM_CONTROL[MAX_MPCC];\
|
||||
uint32_t MPCC_OGAM_LUT_DATA[MAX_MPCC];\
|
||||
uint32_t MPCC_OGAM_MODE[MAX_MPCC];\
|
||||
uint32_t MPC_OCSC_TEST_DEBUG_DATA;\
|
||||
uint32_t MPC_OCSC_TEST_DEBUG_INDEX;\
|
||||
uint32_t CSC_MODE[MAX_OPP]; \
|
||||
uint32_t CSC_C11_C12_A[MAX_OPP]; \
|
||||
uint32_t CSC_C33_C34_A[MAX_OPP]; \
|
||||
@ -134,6 +140,7 @@
|
||||
SF(MPCC0_MPCC_TOP_GAIN, MPCC_TOP_GAIN, mask_sh),\
|
||||
SF(MPCC0_MPCC_BOT_GAIN_INSIDE, MPCC_BOT_GAIN_INSIDE, mask_sh),\
|
||||
SF(MPCC0_MPCC_BOT_GAIN_OUTSIDE, MPCC_BOT_GAIN_OUTSIDE, mask_sh),\
|
||||
SF(MPC_OCSC_TEST_DEBUG_INDEX, MPC_OCSC_TEST_DEBUG_INDEX, mask_sh),\
|
||||
SF(MPC_OUT0_CSC_MODE, MPC_OCSC_MODE, mask_sh),\
|
||||
SF(MPC_OUT0_CSC_C11_C12_A, MPC_OCSC_C11_A, mask_sh),\
|
||||
SF(MPC_OUT0_CSC_C11_C12_A, MPC_OCSC_C12_A, mask_sh),\
|
||||
@ -174,6 +181,19 @@
|
||||
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)
|
||||
|
||||
/*
|
||||
* DCN2 MPC_OCSC debug status register:
|
||||
*
|
||||
* Status index including current OCSC Mode is 1
|
||||
* OCSC Mode: [1..0]
|
||||
*/
|
||||
#define MPC_OCSC_TEST_DEBUG_DATA_STATUS_IDX 1
|
||||
|
||||
#define MPC_DEBUG_REG_LIST_SH_DCN20 \
|
||||
.MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE = 0
|
||||
|
||||
#define MPC_DEBUG_REG_LIST_MASK_DCN20 \
|
||||
.MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE = 0x3
|
||||
|
||||
#define MPC_REG_FIELD_LIST_DCN2_0(type) \
|
||||
MPC_REG_FIELD_LIST(type)\
|
||||
@ -182,6 +202,8 @@
|
||||
type MPCC_TOP_GAIN;\
|
||||
type MPCC_BOT_GAIN_INSIDE;\
|
||||
type MPCC_BOT_GAIN_OUTSIDE;\
|
||||
type MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE;\
|
||||
type MPC_OCSC_TEST_DEBUG_INDEX;\
|
||||
type MPC_OCSC_MODE;\
|
||||
type MPC_OCSC_C11_A;\
|
||||
type MPC_OCSC_C12_A;\
|
||||
|
@ -638,6 +638,7 @@ static const struct dce110_aux_registers aux_engine_regs[] = {
|
||||
#define tf_regs(id)\
|
||||
[id] = {\
|
||||
TF_REG_LIST_DCN20(id),\
|
||||
TF_REG_LIST_DCN20_COMMON_APPEND(id),\
|
||||
}
|
||||
|
||||
static const struct dcn2_dpp_registers tf_regs[] = {
|
||||
@ -651,12 +652,12 @@ static const struct dcn2_dpp_registers tf_regs[] = {
|
||||
|
||||
static const struct dcn2_dpp_shift tf_shift = {
|
||||
TF_REG_LIST_SH_MASK_DCN20(__SHIFT),
|
||||
TF_DEBUG_REG_LIST_SH_DCN10
|
||||
TF_DEBUG_REG_LIST_SH_DCN20
|
||||
};
|
||||
|
||||
static const struct dcn2_dpp_mask tf_mask = {
|
||||
TF_REG_LIST_SH_MASK_DCN20(_MASK),
|
||||
TF_DEBUG_REG_LIST_MASK_DCN10
|
||||
TF_DEBUG_REG_LIST_MASK_DCN20
|
||||
};
|
||||
|
||||
#define dwbc_regs_dcn2(id)\
|
||||
@ -706,14 +707,17 @@ static const struct dcn20_mpc_registers mpc_regs = {
|
||||
MPC_OUT_MUX_REG_LIST_DCN2_0(3),
|
||||
MPC_OUT_MUX_REG_LIST_DCN2_0(4),
|
||||
MPC_OUT_MUX_REG_LIST_DCN2_0(5),
|
||||
MPC_DBG_REG_LIST_DCN2_0()
|
||||
};
|
||||
|
||||
static const struct dcn20_mpc_shift mpc_shift = {
|
||||
MPC_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
|
||||
MPC_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT),
|
||||
MPC_DEBUG_REG_LIST_SH_DCN20
|
||||
};
|
||||
|
||||
static const struct dcn20_mpc_mask mpc_mask = {
|
||||
MPC_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
|
||||
MPC_COMMON_MASK_SH_LIST_DCN2_0(_MASK),
|
||||
MPC_DEBUG_REG_LIST_MASK_DCN20
|
||||
};
|
||||
|
||||
#define tg_regs(id)\
|
||||
@ -1857,6 +1861,22 @@ void dcn20_populate_dml_writeback_from_context(
|
||||
|
||||
}
|
||||
|
||||
static int get_num_odm_heads(struct pipe_ctx *pipe)
|
||||
{
|
||||
int odm_head_count = 0;
|
||||
struct pipe_ctx *next_pipe = pipe->next_odm_pipe;
|
||||
while (next_pipe) {
|
||||
odm_head_count++;
|
||||
next_pipe = next_pipe->next_odm_pipe;
|
||||
}
|
||||
pipe = pipe->prev_odm_pipe;
|
||||
while (pipe) {
|
||||
odm_head_count++;
|
||||
pipe = pipe->prev_odm_pipe;
|
||||
}
|
||||
return odm_head_count ? odm_head_count + 1 : 0;
|
||||
}
|
||||
|
||||
int dcn20_populate_dml_pipes_from_context(
|
||||
struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes)
|
||||
{
|
||||
@ -1883,17 +1903,21 @@ int dcn20_populate_dml_pipes_from_context(
|
||||
for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct dc_crtc_timing *timing = &res_ctx->pipe_ctx[i].stream->timing;
|
||||
unsigned int v_total;
|
||||
unsigned int front_porch;
|
||||
int output_bpc;
|
||||
|
||||
if (!res_ctx->pipe_ctx[i].stream)
|
||||
continue;
|
||||
|
||||
v_total = timing->v_total;
|
||||
front_porch = timing->v_front_porch;
|
||||
/* todo:
|
||||
pipes[pipe_cnt].pipe.src.dynamic_metadata_enable = 0;
|
||||
pipes[pipe_cnt].pipe.src.dcc = 0;
|
||||
pipes[pipe_cnt].pipe.src.vm = 0;*/
|
||||
|
||||
pipes[pipe_cnt].clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0;
|
||||
|
||||
pipes[pipe_cnt].dout.dsc_enable = res_ctx->pipe_ctx[i].stream->timing.flags.DSC;
|
||||
/* todo: rotation?*/
|
||||
pipes[pipe_cnt].dout.dsc_slices = res_ctx->pipe_ctx[i].stream->timing.dsc_cfg.num_slices_h;
|
||||
@ -1915,7 +1939,7 @@ int dcn20_populate_dml_pipes_from_context(
|
||||
- timing->h_addressable
|
||||
- timing->h_border_left
|
||||
- timing->h_border_right;
|
||||
pipes[pipe_cnt].pipe.dest.vblank_start = v_total - timing->v_front_porch;
|
||||
pipes[pipe_cnt].pipe.dest.vblank_start = v_total - front_porch;
|
||||
pipes[pipe_cnt].pipe.dest.vblank_end = pipes[pipe_cnt].pipe.dest.vblank_start
|
||||
- timing->v_addressable
|
||||
- timing->v_border_top
|
||||
@ -1932,8 +1956,13 @@ int dcn20_populate_dml_pipes_from_context(
|
||||
pipes[pipe_cnt].dout.dp_lanes = 4;
|
||||
pipes[pipe_cnt].pipe.dest.vtotal_min = res_ctx->pipe_ctx[i].stream->adjust.v_total_min;
|
||||
pipes[pipe_cnt].pipe.dest.vtotal_max = res_ctx->pipe_ctx[i].stream->adjust.v_total_max;
|
||||
pipes[pipe_cnt].pipe.dest.odm_combine = res_ctx->pipe_ctx[i].prev_odm_pipe
|
||||
|| res_ctx->pipe_ctx[i].next_odm_pipe;
|
||||
switch (get_num_odm_heads(&res_ctx->pipe_ctx[i])) {
|
||||
case 2:
|
||||
pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_2to1;
|
||||
break;
|
||||
default:
|
||||
pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_disabled;
|
||||
}
|
||||
pipes[pipe_cnt].pipe.src.hsplit_grp = res_ctx->pipe_ctx[i].pipe_idx;
|
||||
if (res_ctx->pipe_ctx[i].top_pipe && res_ctx->pipe_ctx[i].top_pipe->plane_state
|
||||
== res_ctx->pipe_ctx[i].plane_state)
|
||||
@ -2043,6 +2072,9 @@ int dcn20_populate_dml_pipes_from_context(
|
||||
if (pipes[pipe_cnt].pipe.src.viewport_height > 1080)
|
||||
pipes[pipe_cnt].pipe.src.viewport_height = 1080;
|
||||
pipes[pipe_cnt].pipe.src.surface_height_y = pipes[pipe_cnt].pipe.src.viewport_height;
|
||||
pipes[pipe_cnt].pipe.src.surface_width_y = pipes[pipe_cnt].pipe.src.viewport_width;
|
||||
pipes[pipe_cnt].pipe.src.surface_height_c = pipes[pipe_cnt].pipe.src.viewport_height;
|
||||
pipes[pipe_cnt].pipe.src.surface_width_c = pipes[pipe_cnt].pipe.src.viewport_width;
|
||||
pipes[pipe_cnt].pipe.src.data_pitch = ((pipes[pipe_cnt].pipe.src.viewport_width + 63) / 64) * 64; /* linear sw only */
|
||||
pipes[pipe_cnt].pipe.src.source_format = dm_444_32;
|
||||
pipes[pipe_cnt].pipe.dest.recout_width = pipes[pipe_cnt].pipe.src.viewport_width; /*vp_width/hratio*/
|
||||
@ -2076,7 +2108,10 @@ int dcn20_populate_dml_pipes_from_context(
|
||||
pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c.width;
|
||||
pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport.height;
|
||||
pipes[pipe_cnt].pipe.src.viewport_height_c = scl->viewport_c.height;
|
||||
pipes[pipe_cnt].pipe.src.surface_width_y = pln->plane_size.surface_size.width;
|
||||
pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height;
|
||||
pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width;
|
||||
pipes[pipe_cnt].pipe.src.surface_height_c = pln->plane_size.chroma_size.height;
|
||||
if (pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
|
||||
pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch;
|
||||
pipes[pipe_cnt].pipe.src.data_pitch_c = pln->plane_size.chroma_pitch;
|
||||
@ -2490,7 +2525,7 @@ int dcn20_validate_apply_pipe_split_flags(
|
||||
split[i] = true;
|
||||
if (dc->debug.force_odm_combine & (1 << pipe->stream_res.tg->inst)) {
|
||||
split[i] = true;
|
||||
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx] = true;
|
||||
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx] = dm_odm_combine_mode_2to1;
|
||||
}
|
||||
context->bw_ctx.dml.vba.ODMCombineEnabled[pipe_idx] =
|
||||
context->bw_ctx.dml.vba.ODMCombineEnablePerState[vlevel][pipe_idx];
|
||||
@ -2915,7 +2950,7 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
|
||||
|
||||
if (context->bw_ctx.dml.soc.dummy_pstate_latency_us == 0 ||
|
||||
(voltage_supported && full_pstate_supported)) {
|
||||
context->bw_ctx.bw.dcn.clk.p_state_change_support = true;
|
||||
context->bw_ctx.bw.dcn.clk.p_state_change_support = full_pstate_supported;
|
||||
goto restore_dml_state;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include "dm_services.h"
|
||||
#include "reg_helper.h"
|
||||
|
||||
#include "dc_dmub_srv.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
||||
#define REG(reg)\
|
||||
@ -251,10 +253,20 @@ static void hubp21_apply_PLAT_54186_wa(
|
||||
ROTATION_ANGLE, &rotation_angle,
|
||||
H_MIRROR_EN, &h_mirror_en);
|
||||
|
||||
/* apply wa only for NV12 surface with scatter gather enabled with view port > 512 */
|
||||
/* reset persistent cached data */
|
||||
hubp21->PLAT_54186_wa_chroma_addr_offset = 0;
|
||||
/* apply wa only for NV12 surface with scatter gather enabled with viewport > 512 along
|
||||
* the vertical direction*/
|
||||
if (address->type != PLN_ADDR_TYPE_VIDEO_PROGRESSIVE ||
|
||||
address->video_progressive.luma_addr.high_part == 0xf4
|
||||
|| viewport_c_height <= 512)
|
||||
address->video_progressive.luma_addr.high_part == 0xf4)
|
||||
return;
|
||||
|
||||
if ((rotation_angle == 0 || rotation_angle == 180)
|
||||
&& viewport_c_height <= 512)
|
||||
return;
|
||||
|
||||
if ((rotation_angle == 90 || rotation_angle == 270)
|
||||
&& viewport_c_width <= 512)
|
||||
return;
|
||||
|
||||
switch (rotation_angle) {
|
||||
@ -678,123 +690,167 @@ void hubp21_validate_dml_output(struct hubp *hubp,
|
||||
dml_dlg_attr->refcyc_per_meta_chunk_flip_l, dlg_attr.refcyc_per_meta_chunk_flip_l);
|
||||
}
|
||||
|
||||
bool hubp21_program_surface_flip_and_addr(
|
||||
struct hubp *hubp,
|
||||
const struct dc_plane_address *address,
|
||||
bool flip_immediate)
|
||||
static void program_surface_flip_and_addr(struct hubp *hubp, struct surface_flip_registers *flip_regs)
|
||||
{
|
||||
struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
|
||||
struct dc_debug_options *debug = &hubp->ctx->dc->debug;
|
||||
|
||||
//program flip type
|
||||
REG_UPDATE(DCSURF_FLIP_CONTROL,
|
||||
SURFACE_FLIP_TYPE, flip_immediate);
|
||||
REG_UPDATE_3(DCSURF_FLIP_CONTROL,
|
||||
SURFACE_FLIP_TYPE, flip_regs->immediate,
|
||||
SURFACE_FLIP_MODE_FOR_STEREOSYNC, flip_regs->grph_stereo,
|
||||
SURFACE_FLIP_IN_STEREOSYNC, flip_regs->grph_stereo);
|
||||
|
||||
// Program VMID reg
|
||||
REG_UPDATE(VMID_SETTINGS_0,
|
||||
VMID, address->vmid);
|
||||
VMID, flip_regs->vmid);
|
||||
|
||||
if (address->type == PLN_ADDR_TYPE_GRPH_STEREO) {
|
||||
REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x1);
|
||||
REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x1);
|
||||
REG_UPDATE_8(DCSURF_SURFACE_CONTROL,
|
||||
PRIMARY_SURFACE_TMZ, flip_regs->tmz_surface,
|
||||
PRIMARY_SURFACE_TMZ_C, flip_regs->tmz_surface,
|
||||
PRIMARY_META_SURFACE_TMZ, flip_regs->tmz_surface,
|
||||
PRIMARY_META_SURFACE_TMZ_C, flip_regs->tmz_surface,
|
||||
SECONDARY_SURFACE_TMZ, flip_regs->tmz_surface,
|
||||
SECONDARY_SURFACE_TMZ_C, flip_regs->tmz_surface,
|
||||
SECONDARY_META_SURFACE_TMZ, flip_regs->tmz_surface,
|
||||
SECONDARY_META_SURFACE_TMZ_C, flip_regs->tmz_surface);
|
||||
|
||||
} else {
|
||||
// turn off stereo if not in stereo
|
||||
REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x0);
|
||||
REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x0);
|
||||
}
|
||||
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
|
||||
PRIMARY_META_SURFACE_ADDRESS_HIGH_C,
|
||||
flip_regs->DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C);
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0,
|
||||
PRIMARY_META_SURFACE_ADDRESS_C,
|
||||
flip_regs->DCSURF_PRIMARY_META_SURFACE_ADDRESS_C);
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
|
||||
PRIMARY_META_SURFACE_ADDRESS_HIGH,
|
||||
flip_regs->DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH);
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
|
||||
PRIMARY_META_SURFACE_ADDRESS,
|
||||
flip_regs->DCSURF_PRIMARY_META_SURFACE_ADDRESS);
|
||||
|
||||
REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 0,
|
||||
SECONDARY_META_SURFACE_ADDRESS_HIGH,
|
||||
flip_regs->DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH);
|
||||
|
||||
REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 0,
|
||||
SECONDARY_META_SURFACE_ADDRESS,
|
||||
flip_regs->DCSURF_SECONDARY_META_SURFACE_ADDRESS);
|
||||
|
||||
|
||||
REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
|
||||
SECONDARY_SURFACE_ADDRESS_HIGH,
|
||||
flip_regs->DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH);
|
||||
|
||||
REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0,
|
||||
SECONDARY_SURFACE_ADDRESS,
|
||||
flip_regs->DCSURF_SECONDARY_SURFACE_ADDRESS);
|
||||
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
|
||||
PRIMARY_SURFACE_ADDRESS_HIGH_C,
|
||||
flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C);
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
|
||||
PRIMARY_SURFACE_ADDRESS_C,
|
||||
flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_C);
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
|
||||
PRIMARY_SURFACE_ADDRESS_HIGH,
|
||||
flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH);
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
|
||||
PRIMARY_SURFACE_ADDRESS,
|
||||
flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS);
|
||||
}
|
||||
|
||||
void dmcub_PLAT_54186_wa(struct hubp *hubp, struct surface_flip_registers *flip_regs)
|
||||
{
|
||||
struct dc_dmub_srv *dmcub = hubp->ctx->dmub_srv;
|
||||
struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
|
||||
struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa = { 0 };
|
||||
|
||||
PLAT_54186_wa.header.type = DMUB_CMD__PLAT_54186_WA;
|
||||
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS;
|
||||
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_C;
|
||||
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH;
|
||||
PLAT_54186_wa.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C = flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C;
|
||||
PLAT_54186_wa.flip.flip_params.grph_stereo = flip_regs->grph_stereo;
|
||||
PLAT_54186_wa.flip.flip_params.hubp_inst = hubp->inst;
|
||||
PLAT_54186_wa.flip.flip_params.immediate = flip_regs->immediate;
|
||||
PLAT_54186_wa.flip.flip_params.tmz_surface = flip_regs->tmz_surface;
|
||||
PLAT_54186_wa.flip.flip_params.vmid = flip_regs->vmid;
|
||||
|
||||
PERF_TRACE(); // TODO: remove after performance is stable.
|
||||
dc_dmub_srv_cmd_queue(dmcub, &PLAT_54186_wa.header);
|
||||
PERF_TRACE(); // TODO: remove after performance is stable.
|
||||
dc_dmub_srv_cmd_execute(dmcub);
|
||||
PERF_TRACE(); // TODO: remove after performance is stable.
|
||||
dc_dmub_srv_wait_idle(dmcub);
|
||||
PERF_TRACE(); // TODO: remove after performance is stable.
|
||||
}
|
||||
|
||||
bool hubp21_program_surface_flip_and_addr(
|
||||
struct hubp *hubp,
|
||||
const struct dc_plane_address *address,
|
||||
bool flip_immediate)
|
||||
{
|
||||
struct dc_debug_options *debug = &hubp->ctx->dc->debug;
|
||||
struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
|
||||
struct surface_flip_registers flip_regs = { 0 };
|
||||
|
||||
flip_regs.vmid = address->vmid;
|
||||
|
||||
/* HW automatically latch rest of address register on write to
|
||||
* DCSURF_PRIMARY_SURFACE_ADDRESS if SURFACE_UPDATE_LOCK is not used
|
||||
*
|
||||
* program high first and then the low addr, order matters!
|
||||
*/
|
||||
switch (address->type) {
|
||||
case PLN_ADDR_TYPE_GRAPHICS:
|
||||
/* DCN1.0 does not support const color
|
||||
* TODO: program DCHUBBUB_RET_PATH_DCC_CFGx_0/1
|
||||
* base on address->grph.dcc_const_color
|
||||
* x = 0, 2, 4, 6 for pipe 0, 1, 2, 3 for rgb and luma
|
||||
* x = 1, 3, 5, 7 for pipe 0, 1, 2, 3 for chroma
|
||||
*/
|
||||
|
||||
if (address->grph.addr.quad_part == 0)
|
||||
if (address->grph.addr.quad_part == 0) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
break;
|
||||
|
||||
REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
|
||||
PRIMARY_SURFACE_TMZ, address->tmz_surface,
|
||||
PRIMARY_META_SURFACE_TMZ, address->tmz_surface);
|
||||
|
||||
if (address->grph.meta_addr.quad_part != 0) {
|
||||
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
|
||||
PRIMARY_META_SURFACE_ADDRESS_HIGH,
|
||||
address->grph.meta_addr.high_part);
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
|
||||
PRIMARY_META_SURFACE_ADDRESS,
|
||||
address->grph.meta_addr.low_part);
|
||||
}
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
|
||||
PRIMARY_SURFACE_ADDRESS_HIGH,
|
||||
address->grph.addr.high_part);
|
||||
if (address->grph.meta_addr.quad_part != 0) {
|
||||
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS =
|
||||
address->grph.meta_addr.low_part;
|
||||
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH =
|
||||
address->grph.meta_addr.high_part;
|
||||
}
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
|
||||
PRIMARY_SURFACE_ADDRESS,
|
||||
address->grph.addr.low_part);
|
||||
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS =
|
||||
address->grph.addr.low_part;
|
||||
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
|
||||
address->grph.addr.high_part;
|
||||
break;
|
||||
case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
|
||||
if (address->video_progressive.luma_addr.quad_part == 0
|
||||
|| address->video_progressive.chroma_addr.quad_part == 0)
|
||||
break;
|
||||
|
||||
REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
|
||||
PRIMARY_SURFACE_TMZ, address->tmz_surface,
|
||||
PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
|
||||
PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
|
||||
PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
|
||||
|
||||
if (address->video_progressive.luma_meta_addr.quad_part != 0) {
|
||||
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
|
||||
PRIMARY_META_SURFACE_ADDRESS_HIGH_C,
|
||||
address->video_progressive.chroma_meta_addr.high_part);
|
||||
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS =
|
||||
address->video_progressive.luma_meta_addr.low_part;
|
||||
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH =
|
||||
address->video_progressive.luma_meta_addr.high_part;
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0,
|
||||
PRIMARY_META_SURFACE_ADDRESS_C,
|
||||
address->video_progressive.chroma_meta_addr.low_part);
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
|
||||
PRIMARY_META_SURFACE_ADDRESS_HIGH,
|
||||
address->video_progressive.luma_meta_addr.high_part);
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
|
||||
PRIMARY_META_SURFACE_ADDRESS,
|
||||
address->video_progressive.luma_meta_addr.low_part);
|
||||
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS_C =
|
||||
address->video_progressive.chroma_meta_addr.low_part;
|
||||
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C =
|
||||
address->video_progressive.chroma_meta_addr.high_part;
|
||||
}
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
|
||||
PRIMARY_SURFACE_ADDRESS_HIGH_C,
|
||||
address->video_progressive.chroma_addr.high_part);
|
||||
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS =
|
||||
address->video_progressive.luma_addr.low_part;
|
||||
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
|
||||
address->video_progressive.luma_addr.high_part;
|
||||
|
||||
if (debug->nv12_iflip_vm_wa) {
|
||||
REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
|
||||
PRIMARY_SURFACE_ADDRESS_C,
|
||||
address->video_progressive.chroma_addr.low_part + hubp21->PLAT_54186_wa_chroma_addr_offset);
|
||||
} else {
|
||||
REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
|
||||
PRIMARY_SURFACE_ADDRESS_C,
|
||||
address->video_progressive.chroma_addr.low_part);
|
||||
}
|
||||
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS_C =
|
||||
address->video_progressive.chroma_addr.low_part + hubp21->PLAT_54186_wa_chroma_addr_offset;
|
||||
} else
|
||||
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS_C =
|
||||
address->video_progressive.chroma_addr.low_part;
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
|
||||
PRIMARY_SURFACE_ADDRESS_HIGH,
|
||||
address->video_progressive.luma_addr.high_part);
|
||||
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C =
|
||||
address->video_progressive.chroma_addr.high_part;
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
|
||||
PRIMARY_SURFACE_ADDRESS,
|
||||
address->video_progressive.luma_addr.low_part);
|
||||
break;
|
||||
case PLN_ADDR_TYPE_GRPH_STEREO:
|
||||
if (address->grph_stereo.left_addr.quad_part == 0)
|
||||
@ -802,58 +858,46 @@ bool hubp21_program_surface_flip_and_addr(
|
||||
if (address->grph_stereo.right_addr.quad_part == 0)
|
||||
break;
|
||||
|
||||
REG_UPDATE_8(DCSURF_SURFACE_CONTROL,
|
||||
PRIMARY_SURFACE_TMZ, address->tmz_surface,
|
||||
PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
|
||||
PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
|
||||
PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface,
|
||||
SECONDARY_SURFACE_TMZ, address->tmz_surface,
|
||||
SECONDARY_SURFACE_TMZ_C, address->tmz_surface,
|
||||
SECONDARY_META_SURFACE_TMZ, address->tmz_surface,
|
||||
SECONDARY_META_SURFACE_TMZ_C, address->tmz_surface);
|
||||
flip_regs.grph_stereo = true;
|
||||
|
||||
if (address->grph_stereo.right_meta_addr.quad_part != 0) {
|
||||
|
||||
REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 0,
|
||||
SECONDARY_META_SURFACE_ADDRESS_HIGH,
|
||||
address->grph_stereo.right_meta_addr.high_part);
|
||||
|
||||
REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 0,
|
||||
SECONDARY_META_SURFACE_ADDRESS,
|
||||
address->grph_stereo.right_meta_addr.low_part);
|
||||
flip_regs.DCSURF_SECONDARY_META_SURFACE_ADDRESS =
|
||||
address->grph_stereo.right_meta_addr.low_part;
|
||||
flip_regs.DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH =
|
||||
address->grph_stereo.right_meta_addr.high_part;
|
||||
}
|
||||
|
||||
if (address->grph_stereo.left_meta_addr.quad_part != 0) {
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
|
||||
PRIMARY_META_SURFACE_ADDRESS_HIGH,
|
||||
address->grph_stereo.left_meta_addr.high_part);
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
|
||||
PRIMARY_META_SURFACE_ADDRESS,
|
||||
address->grph_stereo.left_meta_addr.low_part);
|
||||
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS =
|
||||
address->grph_stereo.left_meta_addr.low_part;
|
||||
flip_regs.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH =
|
||||
address->grph_stereo.left_meta_addr.high_part;
|
||||
}
|
||||
|
||||
REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
|
||||
SECONDARY_SURFACE_ADDRESS_HIGH,
|
||||
address->grph_stereo.right_addr.high_part);
|
||||
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS =
|
||||
address->grph_stereo.left_addr.low_part;
|
||||
flip_regs.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
|
||||
address->grph_stereo.left_addr.high_part;
|
||||
|
||||
REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0,
|
||||
SECONDARY_SURFACE_ADDRESS,
|
||||
address->grph_stereo.right_addr.low_part);
|
||||
flip_regs.DCSURF_SECONDARY_SURFACE_ADDRESS =
|
||||
address->grph_stereo.right_addr.low_part;
|
||||
flip_regs.DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH =
|
||||
address->grph_stereo.right_addr.high_part;
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
|
||||
PRIMARY_SURFACE_ADDRESS_HIGH,
|
||||
address->grph_stereo.left_addr.high_part);
|
||||
|
||||
REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
|
||||
PRIMARY_SURFACE_ADDRESS,
|
||||
address->grph_stereo.left_addr.low_part);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
break;
|
||||
}
|
||||
|
||||
flip_regs.tmz_surface = address->tmz_surface;
|
||||
flip_regs.immediate = flip_immediate;
|
||||
|
||||
if (hubp->ctx->dc->debug.enable_dmcub_surface_flip && address->type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
|
||||
dmcub_PLAT_54186_wa(hubp, &flip_regs);
|
||||
else
|
||||
program_surface_flip_and_addr(hubp, &flip_regs);
|
||||
|
||||
hubp->request_address = *address;
|
||||
|
||||
return true;
|
||||
|
@ -83,6 +83,7 @@
|
||||
#include "dcn21_resource.h"
|
||||
#include "vm_helper.h"
|
||||
#include "dcn20/dcn20_vmid.h"
|
||||
#include "../dce/dmub_psr.h"
|
||||
|
||||
#define SOC_BOUNDING_BOX_VALID false
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
@ -465,15 +466,18 @@ static const struct dcn20_mpc_registers mpc_regs = {
|
||||
MPC_OUT_MUX_REG_LIST_DCN2_0(0),
|
||||
MPC_OUT_MUX_REG_LIST_DCN2_0(1),
|
||||
MPC_OUT_MUX_REG_LIST_DCN2_0(2),
|
||||
MPC_OUT_MUX_REG_LIST_DCN2_0(3)
|
||||
MPC_OUT_MUX_REG_LIST_DCN2_0(3),
|
||||
MPC_DBG_REG_LIST_DCN2_0()
|
||||
};
|
||||
|
||||
static const struct dcn20_mpc_shift mpc_shift = {
|
||||
MPC_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT)
|
||||
MPC_COMMON_MASK_SH_LIST_DCN2_0(__SHIFT),
|
||||
MPC_DEBUG_REG_LIST_SH_DCN20
|
||||
};
|
||||
|
||||
static const struct dcn20_mpc_mask mpc_mask = {
|
||||
MPC_COMMON_MASK_SH_LIST_DCN2_0(_MASK)
|
||||
MPC_COMMON_MASK_SH_LIST_DCN2_0(_MASK),
|
||||
MPC_DEBUG_REG_LIST_MASK_DCN20
|
||||
};
|
||||
|
||||
#define hubp_regs(id)\
|
||||
@ -608,6 +612,7 @@ static const struct dce110_aux_registers aux_engine_regs[] = {
|
||||
#define tf_regs(id)\
|
||||
[id] = {\
|
||||
TF_REG_LIST_DCN20(id),\
|
||||
TF_REG_LIST_DCN20_COMMON_APPEND(id),\
|
||||
}
|
||||
|
||||
static const struct dcn2_dpp_registers tf_regs[] = {
|
||||
@ -618,11 +623,13 @@ static const struct dcn2_dpp_registers tf_regs[] = {
|
||||
};
|
||||
|
||||
static const struct dcn2_dpp_shift tf_shift = {
|
||||
TF_REG_LIST_SH_MASK_DCN20(__SHIFT)
|
||||
TF_REG_LIST_SH_MASK_DCN20(__SHIFT),
|
||||
TF_DEBUG_REG_LIST_SH_DCN20
|
||||
};
|
||||
|
||||
static const struct dcn2_dpp_mask tf_mask = {
|
||||
TF_REG_LIST_SH_MASK_DCN20(_MASK)
|
||||
TF_REG_LIST_SH_MASK_DCN20(_MASK),
|
||||
TF_DEBUG_REG_LIST_MASK_DCN20
|
||||
};
|
||||
|
||||
#define stream_enc_regs(id)\
|
||||
@ -828,7 +835,8 @@ static const struct dc_debug_options debug_defaults_drv = {
|
||||
.scl_reset_length10 = true,
|
||||
.sanity_checks = true,
|
||||
.disable_48mhz_pwrdwn = false,
|
||||
.nv12_iflip_vm_wa = true
|
||||
.nv12_iflip_vm_wa = true,
|
||||
.usbc_combo_phy_reset_wa = true
|
||||
};
|
||||
|
||||
static const struct dc_debug_options debug_defaults_diags = {
|
||||
@ -1341,6 +1349,10 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
|
||||
}
|
||||
dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - 1];
|
||||
dcn2_1_soc.num_states = i;
|
||||
|
||||
// diags does not retrieve proper values from SMU, do not update DML instance for diags
|
||||
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) && !IS_DIAG_DC(dc->ctx->dce_environment))
|
||||
dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
|
||||
}
|
||||
|
||||
/* Temporary Place holder until we can get them from fuse */
|
||||
@ -1740,6 +1752,10 @@ static bool dcn21_resource_construct(
|
||||
goto create_fail;
|
||||
}
|
||||
|
||||
// Leave as NULL to not affect current dmcu psr programming sequence
|
||||
// Will be uncommented when functionality is confirmed to be working
|
||||
pool->base.psr = NULL;
|
||||
|
||||
pool->base.abm = dce_abm_create(ctx,
|
||||
&abm_regs,
|
||||
&abm_shift,
|
||||
|
@ -937,7 +937,7 @@ static unsigned int CalculateVMAndRowBytes(
|
||||
*MetaRowByte = 0;
|
||||
}
|
||||
|
||||
if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_lvp) {
|
||||
if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_l_vp) {
|
||||
MacroTileSizeBytes = 256;
|
||||
MacroTileHeight = BlockHeight256Bytes;
|
||||
} else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x
|
||||
@ -1335,11 +1335,11 @@ static void dml20_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPer
|
||||
else
|
||||
mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportHeight[k];
|
||||
|
||||
if (mode_lib->vba.ODMCombineEnabled[k] == true)
|
||||
if (mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
|
||||
MainPlaneDoesODMCombine = true;
|
||||
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == j
|
||||
&& mode_lib->vba.ODMCombineEnabled[j] == true)
|
||||
&& mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
|
||||
MainPlaneDoesODMCombine = true;
|
||||
|
||||
if (MainPlaneDoesODMCombine == true)
|
||||
@ -2848,12 +2848,12 @@ static void dml20_DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
|
||||
SwathWidth = mode_lib->vba.ViewportHeight[k];
|
||||
}
|
||||
|
||||
if (mode_lib->vba.ODMCombineEnabled[k] == true) {
|
||||
if (mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
|
||||
MainPlaneDoesODMCombine = true;
|
||||
}
|
||||
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == j
|
||||
&& mode_lib->vba.ODMCombineEnabled[j] == true) {
|
||||
&& mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
|
||||
MainPlaneDoesODMCombine = true;
|
||||
}
|
||||
}
|
||||
@ -3348,7 +3348,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
== dm_420_10))
|
||||
|| (((mode_lib->vba.SurfaceTiling[k] == dm_sw_gfx7_2d_thin_gl
|
||||
|| mode_lib->vba.SurfaceTiling[k]
|
||||
== dm_sw_gfx7_2d_thin_lvp)
|
||||
== dm_sw_gfx7_2d_thin_l_vp)
|
||||
&& !((mode_lib->vba.SourcePixelFormat[k]
|
||||
== dm_444_64
|
||||
|| mode_lib->vba.SourcePixelFormat[k]
|
||||
@ -3446,10 +3446,10 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
locals->FabricAndDRAMBandwidthPerState[i] * 1000)
|
||||
* locals->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100;
|
||||
|
||||
locals->ReturnBWPerState[i] = locals->ReturnBWToDCNPerState;
|
||||
locals->ReturnBWPerState[i][0] = locals->ReturnBWToDCNPerState;
|
||||
|
||||
if (locals->DCCEnabledInAnyPlane == true && locals->ReturnBWToDCNPerState > locals->DCFCLKPerState[i] * locals->ReturnBusWidth / 4) {
|
||||
locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
|
||||
locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
|
||||
locals->ReturnBWToDCNPerState * 4 * (1 - locals->UrgentLatency /
|
||||
((locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
|
||||
/ (locals->ReturnBWToDCNPerState - locals->DCFCLKPerState[i]
|
||||
@ -3460,7 +3460,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024);
|
||||
|
||||
if (locals->DCCEnabledInAnyPlane && locals->CriticalPoint > 1 && locals->CriticalPoint < 4) {
|
||||
locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
|
||||
locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
|
||||
4 * locals->ReturnBWToDCNPerState *
|
||||
(locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
|
||||
* locals->ReturnBusWidth * locals->DCFCLKPerState[i] * locals->UrgentLatency /
|
||||
@ -3472,7 +3472,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
locals->DCFCLKPerState[i], locals->FabricAndDRAMBandwidthPerState[i] * 1000);
|
||||
|
||||
if (locals->DCCEnabledInAnyPlane == true && locals->ReturnBWToDCNPerState > locals->DCFCLKPerState[i] * locals->ReturnBusWidth / 4) {
|
||||
locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
|
||||
locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
|
||||
locals->ReturnBWToDCNPerState * 4 * (1 - locals->UrgentLatency /
|
||||
((locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
|
||||
/ (locals->ReturnBWToDCNPerState - locals->DCFCLKPerState[i]
|
||||
@ -3483,7 +3483,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024);
|
||||
|
||||
if (locals->DCCEnabledInAnyPlane && locals->CriticalPoint > 1 && locals->CriticalPoint < 4) {
|
||||
locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
|
||||
locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
|
||||
4 * locals->ReturnBWToDCNPerState *
|
||||
(locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
|
||||
* locals->ReturnBusWidth * locals->DCFCLKPerState[i] * locals->UrgentLatency /
|
||||
@ -3521,12 +3521,12 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
|
||||
locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i] =
|
||||
(mode_lib->vba.RoundTripPingLatencyCycles + 32.0) / mode_lib->vba.DCFCLKPerState[i]
|
||||
+ locals->UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels / locals->ReturnBWPerState[i];
|
||||
if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024.0 / locals->ReturnBWPerState[i]
|
||||
+ locals->UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels / locals->ReturnBWPerState[i][0];
|
||||
if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024.0 / locals->ReturnBWPerState[i][0]
|
||||
> locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
|
||||
locals->ROBSupport[i] = true;
|
||||
locals->ROBSupport[i][0] = true;
|
||||
} else {
|
||||
locals->ROBSupport[i] = false;
|
||||
locals->ROBSupport[i][0] = false;
|
||||
}
|
||||
}
|
||||
/*Writeback Mode Support Check*/
|
||||
@ -3903,7 +3903,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
}
|
||||
if (locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
|
||||
&& locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]
|
||||
&& locals->ODMCombineEnablePerState[i][k] == false) {
|
||||
&& locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
|
||||
locals->NoOfDPP[i][j][k] = 1;
|
||||
locals->RequiredDPPCLK[i][j][k] =
|
||||
locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
|
||||
@ -3992,16 +3992,16 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
/*Viewport Size Check*/
|
||||
|
||||
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
|
||||
locals->ViewportSizeSupport[i] = true;
|
||||
locals->ViewportSizeSupport[i][0] = true;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
|
||||
if (dml_min(locals->SwathWidthYSingleDPP[k], dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]))
|
||||
> locals->MaximumSwathWidth[k]) {
|
||||
locals->ViewportSizeSupport[i] = false;
|
||||
locals->ViewportSizeSupport[i][0] = false;
|
||||
}
|
||||
} else {
|
||||
if (locals->SwathWidthYSingleDPP[k] / 2.0 > locals->MaximumSwathWidth[k]) {
|
||||
locals->ViewportSizeSupport[i] = false;
|
||||
locals->ViewportSizeSupport[i][0] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4183,8 +4183,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.DSCFormatFactor = 1;
|
||||
}
|
||||
if (locals->RequiresDSC[i][k] == true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k]
|
||||
== true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
|
||||
if (mode_lib->vba.PixelClockBackEnd[k] / 6.0 / mode_lib->vba.DSCFormatFactor
|
||||
> (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
|
||||
locals->DSCCLKRequiredMoreThanSupported[i] =
|
||||
@ -4207,7 +4206,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.TotalDSCUnitsRequired = 0.0;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (locals->RequiresDSC[i][k] == true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
|
||||
mode_lib->vba.TotalDSCUnitsRequired =
|
||||
mode_lib->vba.TotalDSCUnitsRequired + 2.0;
|
||||
} else {
|
||||
@ -4249,7 +4248,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.bpp = locals->OutputBppPerState[i][k];
|
||||
}
|
||||
if (locals->RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == false) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
|
||||
locals->DSCDelayPerState[i][k] =
|
||||
dscceComputeDelay(
|
||||
mode_lib->vba.DSCInputBitPerComponent[k],
|
||||
@ -4292,7 +4291,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == true)
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1)
|
||||
locals->SwathWidthYPerState[i][j][k] = dml_min(locals->SwathWidthYSingleDPP[k], dml_round(locals->HActive[k] / 2 * locals->HRatio[k]));
|
||||
else
|
||||
locals->SwathWidthYPerState[i][j][k] = locals->SwathWidthYSingleDPP[k] / locals->NoOfDPP[i][j][k];
|
||||
@ -4345,28 +4344,28 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
|
||||
locals->EffectiveDETLBLinesLuma = dml_floor(locals->LinesInDETLuma + dml_min(
|
||||
locals->LinesInDETLuma * locals->RequiredDISPCLK[i][j] * locals->BytePerPixelInDETY[k] *
|
||||
locals->PSCL_FACTOR[k] / locals->ReturnBWPerState[i],
|
||||
locals->PSCL_FACTOR[k] / locals->ReturnBWPerState[i][0],
|
||||
locals->EffectiveLBLatencyHidingSourceLinesLuma),
|
||||
locals->SwathHeightYPerState[i][j][k]);
|
||||
|
||||
locals->EffectiveDETLBLinesChroma = dml_floor(locals->LinesInDETChroma + dml_min(
|
||||
locals->LinesInDETChroma * locals->RequiredDISPCLK[i][j] * locals->BytePerPixelInDETC[k] *
|
||||
locals->PSCL_FACTOR_CHROMA[k] / locals->ReturnBWPerState[i],
|
||||
locals->PSCL_FACTOR_CHROMA[k] / locals->ReturnBWPerState[i][0],
|
||||
locals->EffectiveLBLatencyHidingSourceLinesChroma),
|
||||
locals->SwathHeightCPerState[i][j][k]);
|
||||
|
||||
if (locals->BytePerPixelInDETC[k] == 0) {
|
||||
locals->UrgentLatencySupportUsPerState[i][j][k] = locals->EffectiveDETLBLinesLuma * (locals->HTotal[k] / locals->PixelClock[k])
|
||||
/ locals->VRatio[k] - locals->EffectiveDETLBLinesLuma * locals->SwathWidthYPerState[i][j][k] *
|
||||
dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i] / locals->NoOfDPP[i][j][k]);
|
||||
dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i][0] / locals->NoOfDPP[i][j][k]);
|
||||
} else {
|
||||
locals->UrgentLatencySupportUsPerState[i][j][k] = dml_min(
|
||||
locals->EffectiveDETLBLinesLuma * (locals->HTotal[k] / locals->PixelClock[k])
|
||||
/ locals->VRatio[k] - locals->EffectiveDETLBLinesLuma * locals->SwathWidthYPerState[i][j][k] *
|
||||
dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i] / locals->NoOfDPP[i][j][k]),
|
||||
dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i][0] / locals->NoOfDPP[i][j][k]),
|
||||
locals->EffectiveDETLBLinesChroma * (locals->HTotal[k] / locals->PixelClock[k]) / (locals->VRatio[k] / 2) -
|
||||
locals->EffectiveDETLBLinesChroma * locals->SwathWidthYPerState[i][j][k] / 2 *
|
||||
dml_ceil(locals->BytePerPixelInDETC[k], 2) / (locals->ReturnBWPerState[i] / locals->NoOfDPP[i][j][k]));
|
||||
dml_ceil(locals->BytePerPixelInDETC[k], 2) / (locals->ReturnBWPerState[i][0] / locals->NoOfDPP[i][j][k]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4406,14 +4405,14 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
locals->SwathHeightYThisState[k] = locals->SwathHeightYPerState[i][j][k];
|
||||
locals->SwathHeightCThisState[k] = locals->SwathHeightCPerState[i][j][k];
|
||||
locals->SwathWidthYThisState[k] = locals->SwathWidthYPerState[i][j][k];
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep = dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] = dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
mode_lib->vba.PixelClock[k] / 16.0);
|
||||
if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
|
||||
if (mode_lib->vba.VRatio[k] <= 1.0) {
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep =
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
|
||||
dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
1.1
|
||||
* dml_ceil(
|
||||
mode_lib->vba.BytePerPixelInDETY[k],
|
||||
@ -4423,9 +4422,9 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
* mode_lib->vba.PixelClock[k]
|
||||
/ mode_lib->vba.NoOfDPP[i][j][k]);
|
||||
} else {
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep =
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
|
||||
dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
1.1
|
||||
* dml_ceil(
|
||||
mode_lib->vba.BytePerPixelInDETY[k],
|
||||
@ -4436,9 +4435,9 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
}
|
||||
} else {
|
||||
if (mode_lib->vba.VRatio[k] <= 1.0) {
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep =
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
|
||||
dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
1.1
|
||||
* dml_ceil(
|
||||
mode_lib->vba.BytePerPixelInDETY[k],
|
||||
@ -4448,9 +4447,9 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
* mode_lib->vba.PixelClock[k]
|
||||
/ mode_lib->vba.NoOfDPP[i][j][k]);
|
||||
} else {
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep =
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
|
||||
dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
1.1
|
||||
* dml_ceil(
|
||||
mode_lib->vba.BytePerPixelInDETY[k],
|
||||
@ -4460,9 +4459,9 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
* mode_lib->vba.RequiredDPPCLK[i][j][k]);
|
||||
}
|
||||
if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) {
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep =
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
|
||||
dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
1.1
|
||||
* dml_ceil(
|
||||
mode_lib->vba.BytePerPixelInDETC[k],
|
||||
@ -4473,9 +4472,9 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
* mode_lib->vba.PixelClock[k]
|
||||
/ mode_lib->vba.NoOfDPP[i][j][k]);
|
||||
} else {
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep =
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
|
||||
dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
1.1
|
||||
* dml_ceil(
|
||||
mode_lib->vba.BytePerPixelInDETC[k],
|
||||
@ -4511,7 +4510,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
&mode_lib->vba.PTEBufferSizeNotExceededY[i][j][k],
|
||||
&mode_lib->vba.dpte_row_height[k],
|
||||
&mode_lib->vba.meta_row_height[k]);
|
||||
mode_lib->vba.PrefetchLinesY[k] = CalculatePrefetchSourceLines(
|
||||
mode_lib->vba.PrefetchLinesY[0][0][k] = CalculatePrefetchSourceLines(
|
||||
mode_lib,
|
||||
mode_lib->vba.VRatio[k],
|
||||
mode_lib->vba.vtaps[k],
|
||||
@ -4550,7 +4549,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
&mode_lib->vba.PTEBufferSizeNotExceededC[i][j][k],
|
||||
&mode_lib->vba.dpte_row_height_chroma[k],
|
||||
&mode_lib->vba.meta_row_height_chroma[k]);
|
||||
mode_lib->vba.PrefetchLinesC[k] = CalculatePrefetchSourceLines(
|
||||
mode_lib->vba.PrefetchLinesC[0][0][k] = CalculatePrefetchSourceLines(
|
||||
mode_lib,
|
||||
mode_lib->vba.VRatio[k] / 2.0,
|
||||
mode_lib->vba.VTAPsChroma[k],
|
||||
@ -4564,14 +4563,14 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = 0.0;
|
||||
mode_lib->vba.MetaRowBytesC = 0.0;
|
||||
mode_lib->vba.DPTEBytesPerRowC = 0.0;
|
||||
locals->PrefetchLinesC[k] = 0.0;
|
||||
locals->PrefetchLinesC[0][0][k] = 0.0;
|
||||
locals->PTEBufferSizeNotExceededC[i][j][k] = true;
|
||||
locals->PTEBufferSizeInRequestsForLuma = mode_lib->vba.PTEBufferSizeInRequestsLuma + mode_lib->vba.PTEBufferSizeInRequestsChroma;
|
||||
}
|
||||
locals->PDEAndMetaPTEBytesPerFrame[k] =
|
||||
locals->PDEAndMetaPTEBytesPerFrame[0][0][k] =
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrameY + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
|
||||
locals->MetaRowBytes[k] = mode_lib->vba.MetaRowBytesY + mode_lib->vba.MetaRowBytesC;
|
||||
locals->DPTEBytesPerRow[k] = mode_lib->vba.DPTEBytesPerRowY + mode_lib->vba.DPTEBytesPerRowC;
|
||||
locals->MetaRowBytes[0][0][k] = mode_lib->vba.MetaRowBytesY + mode_lib->vba.MetaRowBytesC;
|
||||
locals->DPTEBytesPerRow[0][0][k] = mode_lib->vba.DPTEBytesPerRowY + mode_lib->vba.DPTEBytesPerRowC;
|
||||
|
||||
CalculateActiveRowBandwidth(
|
||||
mode_lib->vba.GPUVMEnable,
|
||||
@ -4598,14 +4597,14 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
+ mode_lib->vba.TotalNumberOfDCCActiveDPP[i][j]
|
||||
* mode_lib->vba.MetaChunkSize)
|
||||
* 1024.0
|
||||
/ mode_lib->vba.ReturnBWPerState[i];
|
||||
/ mode_lib->vba.ReturnBWPerState[i][0];
|
||||
if (mode_lib->vba.GPUVMEnable == true) {
|
||||
mode_lib->vba.ExtraLatency = mode_lib->vba.ExtraLatency
|
||||
+ mode_lib->vba.TotalNumberOfActiveDPP[i][j]
|
||||
* mode_lib->vba.PTEGroupSize
|
||||
/ mode_lib->vba.ReturnBWPerState[i];
|
||||
/ mode_lib->vba.ReturnBWPerState[i][0];
|
||||
}
|
||||
mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep;
|
||||
mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0];
|
||||
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == k) {
|
||||
@ -4655,7 +4654,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
}
|
||||
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
locals->MaximumVStartup[k] = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
|
||||
locals->MaximumVStartup[0][0][k] = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
|
||||
- dml_max(1.0, dml_ceil(locals->WritebackDelay[i][k] / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), 1.0));
|
||||
}
|
||||
|
||||
@ -4700,7 +4699,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.RequiredDPPCLK[i][j][k],
|
||||
mode_lib->vba.RequiredDISPCLK[i][j],
|
||||
mode_lib->vba.PixelClock[k],
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
mode_lib->vba.DSCDelayPerState[i][k],
|
||||
mode_lib->vba.NoOfDPP[i][j][k],
|
||||
mode_lib->vba.ScalerEnabled[k],
|
||||
@ -4718,7 +4717,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
- mode_lib->vba.VActive[k],
|
||||
mode_lib->vba.HTotal[k],
|
||||
mode_lib->vba.MaxInterDCNTileRepeaters,
|
||||
mode_lib->vba.MaximumVStartup[k],
|
||||
mode_lib->vba.MaximumVStartup[0][0][k],
|
||||
mode_lib->vba.GPUVMMaxPageTableLevels,
|
||||
mode_lib->vba.GPUVMEnable,
|
||||
mode_lib->vba.DynamicMetadataEnable[k],
|
||||
@ -4728,15 +4727,15 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.UrgentLatencyPixelDataOnly,
|
||||
mode_lib->vba.ExtraLatency,
|
||||
mode_lib->vba.TimeCalc,
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
|
||||
mode_lib->vba.MetaRowBytes[k],
|
||||
mode_lib->vba.DPTEBytesPerRow[k],
|
||||
mode_lib->vba.PrefetchLinesY[k],
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[0][0][k],
|
||||
mode_lib->vba.MetaRowBytes[0][0][k],
|
||||
mode_lib->vba.DPTEBytesPerRow[0][0][k],
|
||||
mode_lib->vba.PrefetchLinesY[0][0][k],
|
||||
mode_lib->vba.SwathWidthYPerState[i][j][k],
|
||||
mode_lib->vba.BytePerPixelInDETY[k],
|
||||
mode_lib->vba.PrefillY[k],
|
||||
mode_lib->vba.MaxNumSwY[k],
|
||||
mode_lib->vba.PrefetchLinesC[k],
|
||||
mode_lib->vba.PrefetchLinesC[0][0][k],
|
||||
mode_lib->vba.BytePerPixelInDETC[k],
|
||||
mode_lib->vba.PrefillC[k],
|
||||
mode_lib->vba.MaxNumSwC[k],
|
||||
@ -4767,19 +4766,19 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
locals->prefetch_vm_bw_valid = true;
|
||||
locals->prefetch_row_bw_valid = true;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (locals->PDEAndMetaPTEBytesPerFrame[k] == 0)
|
||||
if (locals->PDEAndMetaPTEBytesPerFrame[0][0][k] == 0)
|
||||
locals->prefetch_vm_bw[k] = 0;
|
||||
else if (locals->LinesForMetaPTE[k] > 0)
|
||||
locals->prefetch_vm_bw[k] = locals->PDEAndMetaPTEBytesPerFrame[k]
|
||||
locals->prefetch_vm_bw[k] = locals->PDEAndMetaPTEBytesPerFrame[0][0][k]
|
||||
/ (locals->LinesForMetaPTE[k] * locals->HTotal[k] / locals->PixelClock[k]);
|
||||
else {
|
||||
locals->prefetch_vm_bw[k] = 0;
|
||||
locals->prefetch_vm_bw_valid = false;
|
||||
}
|
||||
if (locals->MetaRowBytes[k] + locals->DPTEBytesPerRow[k] == 0)
|
||||
if (locals->MetaRowBytes[0][0][k] + locals->DPTEBytesPerRow[0][0][k] == 0)
|
||||
locals->prefetch_row_bw[k] = 0;
|
||||
else if (locals->LinesForMetaAndDPTERow[k] > 0)
|
||||
locals->prefetch_row_bw[k] = (locals->MetaRowBytes[k] + locals->DPTEBytesPerRow[k])
|
||||
locals->prefetch_row_bw[k] = (locals->MetaRowBytes[0][0][k] + locals->DPTEBytesPerRow[0][0][k])
|
||||
/ (locals->LinesForMetaAndDPTERow[k] * locals->HTotal[k] / locals->PixelClock[k]);
|
||||
else {
|
||||
locals->prefetch_row_bw[k] = 0;
|
||||
@ -4798,13 +4797,13 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k])
|
||||
+ mode_lib->vba.meta_row_bw[k] + mode_lib->vba.dpte_row_bw[k]);
|
||||
}
|
||||
locals->BandwidthWithoutPrefetchSupported[i] = true;
|
||||
if (mode_lib->vba.MaximumReadBandwidthWithoutPrefetch > locals->ReturnBWPerState[i]) {
|
||||
locals->BandwidthWithoutPrefetchSupported[i] = false;
|
||||
locals->BandwidthWithoutPrefetchSupported[i][0] = true;
|
||||
if (mode_lib->vba.MaximumReadBandwidthWithoutPrefetch > locals->ReturnBWPerState[i][0]) {
|
||||
locals->BandwidthWithoutPrefetchSupported[i][0] = false;
|
||||
}
|
||||
|
||||
locals->PrefetchSupported[i][j] = true;
|
||||
if (mode_lib->vba.MaximumReadBandwidthWithPrefetch > locals->ReturnBWPerState[i]) {
|
||||
if (mode_lib->vba.MaximumReadBandwidthWithPrefetch > locals->ReturnBWPerState[i][0]) {
|
||||
locals->PrefetchSupported[i][j] = false;
|
||||
}
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
@ -4829,7 +4828,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
if (mode_lib->vba.PrefetchSupported[i][j] == true
|
||||
&& mode_lib->vba.VRatioInPrefetchSupported[i][j] == true) {
|
||||
mode_lib->vba.BandwidthAvailableForImmediateFlip =
|
||||
mode_lib->vba.ReturnBWPerState[i];
|
||||
mode_lib->vba.ReturnBWPerState[i][0];
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
mode_lib->vba.BandwidthAvailableForImmediateFlip =
|
||||
mode_lib->vba.BandwidthAvailableForImmediateFlip
|
||||
@ -4843,9 +4842,9 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
|
||||
&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
|
||||
mode_lib->vba.ImmediateFlipBytes[k] =
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k]
|
||||
+ mode_lib->vba.MetaRowBytes[k]
|
||||
+ mode_lib->vba.DPTEBytesPerRow[k];
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[0][0][k]
|
||||
+ mode_lib->vba.MetaRowBytes[0][0][k]
|
||||
+ mode_lib->vba.DPTEBytesPerRow[0][0][k];
|
||||
}
|
||||
}
|
||||
mode_lib->vba.TotImmediateFlipBytes = 0.0;
|
||||
@ -4873,9 +4872,9 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
/ mode_lib->vba.PixelClock[k],
|
||||
mode_lib->vba.VRatio[k],
|
||||
mode_lib->vba.Tno_bw[k],
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
|
||||
mode_lib->vba.MetaRowBytes[k],
|
||||
mode_lib->vba.DPTEBytesPerRow[k],
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[0][0][k],
|
||||
mode_lib->vba.MetaRowBytes[0][0][k],
|
||||
mode_lib->vba.DPTEBytesPerRow[0][0][k],
|
||||
mode_lib->vba.DCCEnable[k],
|
||||
mode_lib->vba.dpte_row_height[k],
|
||||
mode_lib->vba.meta_row_height[k],
|
||||
@ -4900,7 +4899,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
}
|
||||
mode_lib->vba.ImmediateFlipSupportedForState[i][j] = true;
|
||||
if (mode_lib->vba.total_dcn_read_bw_with_flip
|
||||
> mode_lib->vba.ReturnBWPerState[i]) {
|
||||
> mode_lib->vba.ReturnBWPerState[i][0]) {
|
||||
mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
|
||||
}
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
@ -4919,13 +4918,13 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; k++)
|
||||
mode_lib->vba.MaxTotalVActiveRDBandwidth = mode_lib->vba.MaxTotalVActiveRDBandwidth + mode_lib->vba.ReadBandwidth[k];
|
||||
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
|
||||
mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i] = dml_min(mode_lib->vba.ReturnBusWidth *
|
||||
mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i][0] = dml_min(mode_lib->vba.ReturnBusWidth *
|
||||
mode_lib->vba.DCFCLKPerState[i], mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000) *
|
||||
mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation / 100;
|
||||
if (mode_lib->vba.MaxTotalVActiveRDBandwidth <= mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i])
|
||||
mode_lib->vba.TotalVerticalActiveBandwidthSupport[i] = true;
|
||||
if (mode_lib->vba.MaxTotalVActiveRDBandwidth <= mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i][0])
|
||||
mode_lib->vba.TotalVerticalActiveBandwidthSupport[i][0] = true;
|
||||
else
|
||||
mode_lib->vba.TotalVerticalActiveBandwidthSupport[i] = false;
|
||||
mode_lib->vba.TotalVerticalActiveBandwidthSupport[i][0] = false;
|
||||
}
|
||||
|
||||
/*PTE Buffer Size Check*/
|
||||
@ -5013,7 +5012,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
status = DML_FAIL_SCALE_RATIO_TAP;
|
||||
} else if (mode_lib->vba.SourceFormatPixelAndScanSupport != true) {
|
||||
status = DML_FAIL_SOURCE_PIXEL_FORMAT;
|
||||
} else if (locals->ViewportSizeSupport[i] != true) {
|
||||
} else if (locals->ViewportSizeSupport[i][0] != true) {
|
||||
status = DML_FAIL_VIEWPORT_SIZE;
|
||||
} else if (locals->DIOSupport[i] != true) {
|
||||
status = DML_FAIL_DIO_SUPPORT;
|
||||
@ -5023,7 +5022,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
status = DML_FAIL_DSC_CLK_REQUIRED;
|
||||
} else if (locals->UrgentLatencySupport[i][j] != true) {
|
||||
status = DML_FAIL_URGENT_LATENCY;
|
||||
} else if (locals->ROBSupport[i] != true) {
|
||||
} else if (locals->ROBSupport[i][0] != true) {
|
||||
status = DML_FAIL_REORDERING_BUFFER;
|
||||
} else if (locals->DISPCLK_DPPCLK_Support[i][j] != true) {
|
||||
status = DML_FAIL_DISPCLK_DPPCLK;
|
||||
@ -5043,7 +5042,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
status = DML_FAIL_PITCH_SUPPORT;
|
||||
} else if (locals->PrefetchSupported[i][j] != true) {
|
||||
status = DML_FAIL_PREFETCH_SUPPORT;
|
||||
} else if (locals->TotalVerticalActiveBandwidthSupport[i] != true) {
|
||||
} else if (locals->TotalVerticalActiveBandwidthSupport[i][0] != true) {
|
||||
status = DML_FAIL_TOTAL_V_ACTIVE_BW;
|
||||
} else if (locals->VRatioInPrefetchSupported[i][j] != true) {
|
||||
status = DML_FAIL_V_RATIO_PREFETCH;
|
||||
@ -5089,7 +5088,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.DRAMSpeed = mode_lib->vba.DRAMSpeedPerState[mode_lib->vba.VoltageLevel];
|
||||
mode_lib->vba.FabricClock = mode_lib->vba.FabricClockPerState[mode_lib->vba.VoltageLevel];
|
||||
mode_lib->vba.SOCCLK = mode_lib->vba.SOCCLKPerState[mode_lib->vba.VoltageLevel];
|
||||
mode_lib->vba.ReturnBW = locals->ReturnBWPerState[mode_lib->vba.VoltageLevel];
|
||||
mode_lib->vba.ReturnBW = locals->ReturnBWPerState[mode_lib->vba.VoltageLevel][0];
|
||||
mode_lib->vba.FabricAndDRAMBandwidth = locals->FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == k) {
|
||||
|
@ -997,7 +997,7 @@ static unsigned int CalculateVMAndRowBytes(
|
||||
*MetaRowByte = 0;
|
||||
}
|
||||
|
||||
if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_lvp) {
|
||||
if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_l_vp) {
|
||||
MacroTileSizeBytes = 256;
|
||||
MacroTileHeight = BlockHeight256Bytes;
|
||||
} else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x
|
||||
@ -1395,11 +1395,11 @@ static void dml20v2_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndP
|
||||
else
|
||||
mode_lib->vba.SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportHeight[k];
|
||||
|
||||
if (mode_lib->vba.ODMCombineEnabled[k] == true)
|
||||
if (mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
|
||||
MainPlaneDoesODMCombine = true;
|
||||
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == j
|
||||
&& mode_lib->vba.ODMCombineEnabled[j] == true)
|
||||
&& mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
|
||||
MainPlaneDoesODMCombine = true;
|
||||
|
||||
if (MainPlaneDoesODMCombine == true)
|
||||
@ -2885,12 +2885,12 @@ static void dml20v2_DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
|
||||
SwathWidth = mode_lib->vba.ViewportHeight[k];
|
||||
}
|
||||
|
||||
if (mode_lib->vba.ODMCombineEnabled[k] == true) {
|
||||
if (mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
|
||||
MainPlaneDoesODMCombine = true;
|
||||
}
|
||||
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == j
|
||||
&& mode_lib->vba.ODMCombineEnabled[j] == true) {
|
||||
&& mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
|
||||
MainPlaneDoesODMCombine = true;
|
||||
}
|
||||
}
|
||||
@ -3385,7 +3385,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
== dm_420_10))
|
||||
|| (((mode_lib->vba.SurfaceTiling[k] == dm_sw_gfx7_2d_thin_gl
|
||||
|| mode_lib->vba.SurfaceTiling[k]
|
||||
== dm_sw_gfx7_2d_thin_lvp)
|
||||
== dm_sw_gfx7_2d_thin_l_vp)
|
||||
&& !((mode_lib->vba.SourcePixelFormat[k]
|
||||
== dm_444_64
|
||||
|| mode_lib->vba.SourcePixelFormat[k]
|
||||
@ -3483,10 +3483,10 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
locals->FabricAndDRAMBandwidthPerState[i] * 1000)
|
||||
* locals->PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100;
|
||||
|
||||
locals->ReturnBWPerState[i] = locals->ReturnBWToDCNPerState;
|
||||
locals->ReturnBWPerState[i][0] = locals->ReturnBWToDCNPerState;
|
||||
|
||||
if (locals->DCCEnabledInAnyPlane == true && locals->ReturnBWToDCNPerState > locals->DCFCLKPerState[i] * locals->ReturnBusWidth / 4) {
|
||||
locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
|
||||
locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
|
||||
locals->ReturnBWToDCNPerState * 4 * (1 - locals->UrgentLatency /
|
||||
((locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
|
||||
/ (locals->ReturnBWToDCNPerState - locals->DCFCLKPerState[i]
|
||||
@ -3497,7 +3497,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024);
|
||||
|
||||
if (locals->DCCEnabledInAnyPlane && locals->CriticalPoint > 1 && locals->CriticalPoint < 4) {
|
||||
locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
|
||||
locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
|
||||
4 * locals->ReturnBWToDCNPerState *
|
||||
(locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
|
||||
* locals->ReturnBusWidth * locals->DCFCLKPerState[i] * locals->UrgentLatency /
|
||||
@ -3509,7 +3509,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
locals->DCFCLKPerState[i], locals->FabricAndDRAMBandwidthPerState[i] * 1000);
|
||||
|
||||
if (locals->DCCEnabledInAnyPlane == true && locals->ReturnBWToDCNPerState > locals->DCFCLKPerState[i] * locals->ReturnBusWidth / 4) {
|
||||
locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
|
||||
locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
|
||||
locals->ReturnBWToDCNPerState * 4 * (1 - locals->UrgentLatency /
|
||||
((locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
|
||||
/ (locals->ReturnBWToDCNPerState - locals->DCFCLKPerState[i]
|
||||
@ -3520,7 +3520,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
+ (locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024);
|
||||
|
||||
if (locals->DCCEnabledInAnyPlane && locals->CriticalPoint > 1 && locals->CriticalPoint < 4) {
|
||||
locals->ReturnBWPerState[i] = dml_min(locals->ReturnBWPerState[i],
|
||||
locals->ReturnBWPerState[i][0] = dml_min(locals->ReturnBWPerState[i][0],
|
||||
4 * locals->ReturnBWToDCNPerState *
|
||||
(locals->ROBBufferSizeInKByte - locals->PixelChunkSizeInKByte) * 1024
|
||||
* locals->ReturnBusWidth * locals->DCFCLKPerState[i] * locals->UrgentLatency /
|
||||
@ -3558,12 +3558,12 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
|
||||
locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i] =
|
||||
(mode_lib->vba.RoundTripPingLatencyCycles + 32.0) / mode_lib->vba.DCFCLKPerState[i]
|
||||
+ locals->UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels / locals->ReturnBWPerState[i];
|
||||
if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024.0 / locals->ReturnBWPerState[i]
|
||||
+ locals->UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels / locals->ReturnBWPerState[i][0];
|
||||
if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024.0 / locals->ReturnBWPerState[i][0]
|
||||
> locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
|
||||
locals->ROBSupport[i] = true;
|
||||
locals->ROBSupport[i][0] = true;
|
||||
} else {
|
||||
locals->ROBSupport[i] = false;
|
||||
locals->ROBSupport[i][0] = false;
|
||||
}
|
||||
}
|
||||
/*Writeback Mode Support Check*/
|
||||
@ -3946,7 +3946,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
}
|
||||
if (locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
|
||||
&& locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]
|
||||
&& locals->ODMCombineEnablePerState[i][k] == false) {
|
||||
&& locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
|
||||
locals->NoOfDPP[i][j][k] = 1;
|
||||
locals->RequiredDPPCLK[i][j][k] =
|
||||
locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
|
||||
@ -4035,16 +4035,16 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
/*Viewport Size Check*/
|
||||
|
||||
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
|
||||
locals->ViewportSizeSupport[i] = true;
|
||||
locals->ViewportSizeSupport[i][0] = true;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
|
||||
if (dml_min(locals->SwathWidthYSingleDPP[k], dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]))
|
||||
> locals->MaximumSwathWidth[k]) {
|
||||
locals->ViewportSizeSupport[i] = false;
|
||||
locals->ViewportSizeSupport[i][0] = false;
|
||||
}
|
||||
} else {
|
||||
if (locals->SwathWidthYSingleDPP[k] / 2.0 > locals->MaximumSwathWidth[k]) {
|
||||
locals->ViewportSizeSupport[i] = false;
|
||||
locals->ViewportSizeSupport[i][0] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4226,8 +4226,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
mode_lib->vba.DSCFormatFactor = 1;
|
||||
}
|
||||
if (locals->RequiresDSC[i][k] == true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k]
|
||||
== true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
|
||||
if (mode_lib->vba.PixelClockBackEnd[k] / 6.0 / mode_lib->vba.DSCFormatFactor
|
||||
> (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
|
||||
locals->DSCCLKRequiredMoreThanSupported[i] =
|
||||
@ -4250,7 +4249,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
mode_lib->vba.TotalDSCUnitsRequired = 0.0;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (locals->RequiresDSC[i][k] == true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
|
||||
mode_lib->vba.TotalDSCUnitsRequired =
|
||||
mode_lib->vba.TotalDSCUnitsRequired + 2.0;
|
||||
} else {
|
||||
@ -4292,7 +4291,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
mode_lib->vba.bpp = locals->OutputBppPerState[i][k];
|
||||
}
|
||||
if (locals->RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == false) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
|
||||
locals->DSCDelayPerState[i][k] =
|
||||
dscceComputeDelay(
|
||||
mode_lib->vba.DSCInputBitPerComponent[k],
|
||||
@ -4335,7 +4334,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == true)
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1)
|
||||
locals->SwathWidthYPerState[i][j][k] = dml_min(locals->SwathWidthYSingleDPP[k], dml_round(locals->HActive[k] / 2 * locals->HRatio[k]));
|
||||
else
|
||||
locals->SwathWidthYPerState[i][j][k] = locals->SwathWidthYSingleDPP[k] / locals->NoOfDPP[i][j][k];
|
||||
@ -4388,28 +4387,28 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
|
||||
locals->EffectiveDETLBLinesLuma = dml_floor(locals->LinesInDETLuma + dml_min(
|
||||
locals->LinesInDETLuma * locals->RequiredDISPCLK[i][j] * locals->BytePerPixelInDETY[k] *
|
||||
locals->PSCL_FACTOR[k] / locals->ReturnBWPerState[i],
|
||||
locals->PSCL_FACTOR[k] / locals->ReturnBWPerState[i][0],
|
||||
locals->EffectiveLBLatencyHidingSourceLinesLuma),
|
||||
locals->SwathHeightYPerState[i][j][k]);
|
||||
|
||||
locals->EffectiveDETLBLinesChroma = dml_floor(locals->LinesInDETChroma + dml_min(
|
||||
locals->LinesInDETChroma * locals->RequiredDISPCLK[i][j] * locals->BytePerPixelInDETC[k] *
|
||||
locals->PSCL_FACTOR_CHROMA[k] / locals->ReturnBWPerState[i],
|
||||
locals->PSCL_FACTOR_CHROMA[k] / locals->ReturnBWPerState[i][0],
|
||||
locals->EffectiveLBLatencyHidingSourceLinesChroma),
|
||||
locals->SwathHeightCPerState[i][j][k]);
|
||||
|
||||
if (locals->BytePerPixelInDETC[k] == 0) {
|
||||
locals->UrgentLatencySupportUsPerState[i][j][k] = locals->EffectiveDETLBLinesLuma * (locals->HTotal[k] / locals->PixelClock[k])
|
||||
/ locals->VRatio[k] - locals->EffectiveDETLBLinesLuma * locals->SwathWidthYPerState[i][j][k] *
|
||||
dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i] / locals->NoOfDPP[i][j][k]);
|
||||
dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i][0] / locals->NoOfDPP[i][j][k]);
|
||||
} else {
|
||||
locals->UrgentLatencySupportUsPerState[i][j][k] = dml_min(
|
||||
locals->EffectiveDETLBLinesLuma * (locals->HTotal[k] / locals->PixelClock[k])
|
||||
/ locals->VRatio[k] - locals->EffectiveDETLBLinesLuma * locals->SwathWidthYPerState[i][j][k] *
|
||||
dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i] / locals->NoOfDPP[i][j][k]),
|
||||
dml_ceil(locals->BytePerPixelInDETY[k], 1) / (locals->ReturnBWPerState[i][0] / locals->NoOfDPP[i][j][k]),
|
||||
locals->EffectiveDETLBLinesChroma * (locals->HTotal[k] / locals->PixelClock[k]) / (locals->VRatio[k] / 2) -
|
||||
locals->EffectiveDETLBLinesChroma * locals->SwathWidthYPerState[i][j][k] / 2 *
|
||||
dml_ceil(locals->BytePerPixelInDETC[k], 2) / (locals->ReturnBWPerState[i] / locals->NoOfDPP[i][j][k]));
|
||||
dml_ceil(locals->BytePerPixelInDETC[k], 2) / (locals->ReturnBWPerState[i][0] / locals->NoOfDPP[i][j][k]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4454,14 +4453,14 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
locals->SwathHeightYThisState[k] = locals->SwathHeightYPerState[i][j][k];
|
||||
locals->SwathHeightCThisState[k] = locals->SwathHeightCPerState[i][j][k];
|
||||
locals->SwathWidthYThisState[k] = locals->SwathWidthYPerState[i][j][k];
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep = dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] = dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
mode_lib->vba.PixelClock[k] / 16.0);
|
||||
if (mode_lib->vba.BytePerPixelInDETC[k] == 0.0) {
|
||||
if (mode_lib->vba.VRatio[k] <= 1.0) {
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep =
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
|
||||
dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
1.1
|
||||
* dml_ceil(
|
||||
mode_lib->vba.BytePerPixelInDETY[k],
|
||||
@ -4471,9 +4470,9 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
* mode_lib->vba.PixelClock[k]
|
||||
/ mode_lib->vba.NoOfDPP[i][j][k]);
|
||||
} else {
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep =
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
|
||||
dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
1.1
|
||||
* dml_ceil(
|
||||
mode_lib->vba.BytePerPixelInDETY[k],
|
||||
@ -4484,9 +4483,9 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
}
|
||||
} else {
|
||||
if (mode_lib->vba.VRatio[k] <= 1.0) {
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep =
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
|
||||
dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
1.1
|
||||
* dml_ceil(
|
||||
mode_lib->vba.BytePerPixelInDETY[k],
|
||||
@ -4496,9 +4495,9 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
* mode_lib->vba.PixelClock[k]
|
||||
/ mode_lib->vba.NoOfDPP[i][j][k]);
|
||||
} else {
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep =
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
|
||||
dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
1.1
|
||||
* dml_ceil(
|
||||
mode_lib->vba.BytePerPixelInDETY[k],
|
||||
@ -4508,9 +4507,9 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
* mode_lib->vba.RequiredDPPCLK[i][j][k]);
|
||||
}
|
||||
if (mode_lib->vba.VRatio[k] / 2.0 <= 1.0) {
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep =
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
|
||||
dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
1.1
|
||||
* dml_ceil(
|
||||
mode_lib->vba.BytePerPixelInDETC[k],
|
||||
@ -4521,9 +4520,9 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
* mode_lib->vba.PixelClock[k]
|
||||
/ mode_lib->vba.NoOfDPP[i][j][k]);
|
||||
} else {
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep =
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0] =
|
||||
dml_max(
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
1.1
|
||||
* dml_ceil(
|
||||
mode_lib->vba.BytePerPixelInDETC[k],
|
||||
@ -4559,7 +4558,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
&mode_lib->vba.PTEBufferSizeNotExceededY[i][j][k],
|
||||
&mode_lib->vba.dpte_row_height[k],
|
||||
&mode_lib->vba.meta_row_height[k]);
|
||||
mode_lib->vba.PrefetchLinesY[k] = CalculatePrefetchSourceLines(
|
||||
mode_lib->vba.PrefetchLinesY[0][0][k] = CalculatePrefetchSourceLines(
|
||||
mode_lib,
|
||||
mode_lib->vba.VRatio[k],
|
||||
mode_lib->vba.vtaps[k],
|
||||
@ -4598,7 +4597,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
&mode_lib->vba.PTEBufferSizeNotExceededC[i][j][k],
|
||||
&mode_lib->vba.dpte_row_height_chroma[k],
|
||||
&mode_lib->vba.meta_row_height_chroma[k]);
|
||||
mode_lib->vba.PrefetchLinesC[k] = CalculatePrefetchSourceLines(
|
||||
mode_lib->vba.PrefetchLinesC[0][0][k] = CalculatePrefetchSourceLines(
|
||||
mode_lib,
|
||||
mode_lib->vba.VRatio[k] / 2.0,
|
||||
mode_lib->vba.VTAPsChroma[k],
|
||||
@ -4612,14 +4611,14 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = 0.0;
|
||||
mode_lib->vba.MetaRowBytesC = 0.0;
|
||||
mode_lib->vba.DPTEBytesPerRowC = 0.0;
|
||||
locals->PrefetchLinesC[k] = 0.0;
|
||||
locals->PrefetchLinesC[0][0][k] = 0.0;
|
||||
locals->PTEBufferSizeNotExceededC[i][j][k] = true;
|
||||
locals->PTEBufferSizeInRequestsForLuma = mode_lib->vba.PTEBufferSizeInRequestsLuma + mode_lib->vba.PTEBufferSizeInRequestsChroma;
|
||||
}
|
||||
locals->PDEAndMetaPTEBytesPerFrame[k] =
|
||||
locals->PDEAndMetaPTEBytesPerFrame[0][0][k] =
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrameY + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
|
||||
locals->MetaRowBytes[k] = mode_lib->vba.MetaRowBytesY + mode_lib->vba.MetaRowBytesC;
|
||||
locals->DPTEBytesPerRow[k] = mode_lib->vba.DPTEBytesPerRowY + mode_lib->vba.DPTEBytesPerRowC;
|
||||
locals->MetaRowBytes[0][0][k] = mode_lib->vba.MetaRowBytesY + mode_lib->vba.MetaRowBytesC;
|
||||
locals->DPTEBytesPerRow[0][0][k] = mode_lib->vba.DPTEBytesPerRowY + mode_lib->vba.DPTEBytesPerRowC;
|
||||
|
||||
CalculateActiveRowBandwidth(
|
||||
mode_lib->vba.GPUVMEnable,
|
||||
@ -4646,14 +4645,14 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
+ mode_lib->vba.TotalNumberOfDCCActiveDPP[i][j]
|
||||
* mode_lib->vba.MetaChunkSize)
|
||||
* 1024.0
|
||||
/ mode_lib->vba.ReturnBWPerState[i];
|
||||
/ mode_lib->vba.ReturnBWPerState[i][0];
|
||||
if (mode_lib->vba.GPUVMEnable == true) {
|
||||
mode_lib->vba.ExtraLatency = mode_lib->vba.ExtraLatency
|
||||
+ mode_lib->vba.TotalNumberOfActiveDPP[i][j]
|
||||
* mode_lib->vba.PTEGroupSize
|
||||
/ mode_lib->vba.ReturnBWPerState[i];
|
||||
/ mode_lib->vba.ReturnBWPerState[i][0];
|
||||
}
|
||||
mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep;
|
||||
mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0];
|
||||
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == k) {
|
||||
@ -4703,7 +4702,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
}
|
||||
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
locals->MaximumVStartup[k] = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
|
||||
locals->MaximumVStartup[0][0][k] = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
|
||||
- dml_max(1.0, dml_ceil(locals->WritebackDelay[i][k] / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), 1.0));
|
||||
}
|
||||
|
||||
@ -4743,7 +4742,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0.0;
|
||||
}
|
||||
|
||||
CalculateDelayAfterScaler(mode_lib, mode_lib->vba.ReturnBWPerState[i], mode_lib->vba.ReadBandwidthLuma[k], mode_lib->vba.ReadBandwidthChroma[k], mode_lib->vba.MaxTotalVActiveRDBandwidth,
|
||||
CalculateDelayAfterScaler(mode_lib, mode_lib->vba.ReturnBWPerState[i][0], mode_lib->vba.ReadBandwidthLuma[k], mode_lib->vba.ReadBandwidthChroma[k], mode_lib->vba.MaxTotalVActiveRDBandwidth,
|
||||
mode_lib->vba.DisplayPipeLineDeliveryTimeLuma[k], mode_lib->vba.DisplayPipeLineDeliveryTimeChroma[k],
|
||||
mode_lib->vba.RequiredDPPCLK[i][j][k], mode_lib->vba.RequiredDISPCLK[i][j], mode_lib->vba.PixelClock[k], mode_lib->vba.DSCDelayPerState[i][k], mode_lib->vba.NoOfDPP[i][j][k], mode_lib->vba.ScalerEnabled[k], mode_lib->vba.NumberOfCursors[k],
|
||||
mode_lib->vba.DPPCLKDelaySubtotal, mode_lib->vba.DPPCLKDelaySCL, mode_lib->vba.DPPCLKDelaySCLLBOnly, mode_lib->vba.DPPCLKDelayCNVCFormater, mode_lib->vba.DPPCLKDelayCNVCCursor, mode_lib->vba.DISPCLKDelaySubtotal,
|
||||
@ -4757,14 +4756,14 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
mode_lib->vba.RequiredDPPCLK[i][j][k],
|
||||
mode_lib->vba.RequiredDISPCLK[i][j],
|
||||
mode_lib->vba.PixelClock[k],
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
mode_lib->vba.NoOfDPP[i][j][k],
|
||||
mode_lib->vba.NumberOfCursors[k],
|
||||
mode_lib->vba.VTotal[k]
|
||||
- mode_lib->vba.VActive[k],
|
||||
mode_lib->vba.HTotal[k],
|
||||
mode_lib->vba.MaxInterDCNTileRepeaters,
|
||||
mode_lib->vba.MaximumVStartup[k],
|
||||
mode_lib->vba.MaximumVStartup[0][0][k],
|
||||
mode_lib->vba.GPUVMMaxPageTableLevels,
|
||||
mode_lib->vba.GPUVMEnable,
|
||||
mode_lib->vba.DynamicMetadataEnable[k],
|
||||
@ -4774,15 +4773,15 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
mode_lib->vba.UrgentLatencyPixelDataOnly,
|
||||
mode_lib->vba.ExtraLatency,
|
||||
mode_lib->vba.TimeCalc,
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
|
||||
mode_lib->vba.MetaRowBytes[k],
|
||||
mode_lib->vba.DPTEBytesPerRow[k],
|
||||
mode_lib->vba.PrefetchLinesY[k],
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[0][0][k],
|
||||
mode_lib->vba.MetaRowBytes[0][0][k],
|
||||
mode_lib->vba.DPTEBytesPerRow[0][0][k],
|
||||
mode_lib->vba.PrefetchLinesY[0][0][k],
|
||||
mode_lib->vba.SwathWidthYPerState[i][j][k],
|
||||
mode_lib->vba.BytePerPixelInDETY[k],
|
||||
mode_lib->vba.PrefillY[k],
|
||||
mode_lib->vba.MaxNumSwY[k],
|
||||
mode_lib->vba.PrefetchLinesC[k],
|
||||
mode_lib->vba.PrefetchLinesC[0][0][k],
|
||||
mode_lib->vba.BytePerPixelInDETC[k],
|
||||
mode_lib->vba.PrefillC[k],
|
||||
mode_lib->vba.MaxNumSwC[k],
|
||||
@ -4812,19 +4811,19 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
locals->prefetch_vm_bw_valid = true;
|
||||
locals->prefetch_row_bw_valid = true;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (locals->PDEAndMetaPTEBytesPerFrame[k] == 0)
|
||||
if (locals->PDEAndMetaPTEBytesPerFrame[0][0][k] == 0)
|
||||
locals->prefetch_vm_bw[k] = 0;
|
||||
else if (locals->LinesForMetaPTE[k] > 0)
|
||||
locals->prefetch_vm_bw[k] = locals->PDEAndMetaPTEBytesPerFrame[k]
|
||||
locals->prefetch_vm_bw[k] = locals->PDEAndMetaPTEBytesPerFrame[0][0][k]
|
||||
/ (locals->LinesForMetaPTE[k] * locals->HTotal[k] / locals->PixelClock[k]);
|
||||
else {
|
||||
locals->prefetch_vm_bw[k] = 0;
|
||||
locals->prefetch_vm_bw_valid = false;
|
||||
}
|
||||
if (locals->MetaRowBytes[k] + locals->DPTEBytesPerRow[k] == 0)
|
||||
if (locals->MetaRowBytes[0][0][k] + locals->DPTEBytesPerRow[0][0][k] == 0)
|
||||
locals->prefetch_row_bw[k] = 0;
|
||||
else if (locals->LinesForMetaAndDPTERow[k] > 0)
|
||||
locals->prefetch_row_bw[k] = (locals->MetaRowBytes[k] + locals->DPTEBytesPerRow[k])
|
||||
locals->prefetch_row_bw[k] = (locals->MetaRowBytes[0][0][k] + locals->DPTEBytesPerRow[0][0][k])
|
||||
/ (locals->LinesForMetaAndDPTERow[k] * locals->HTotal[k] / locals->PixelClock[k]);
|
||||
else {
|
||||
locals->prefetch_row_bw[k] = 0;
|
||||
@ -4843,13 +4842,13 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
mode_lib->vba.RequiredPrefetchPixelDataBWLuma[i][j][k])
|
||||
+ mode_lib->vba.meta_row_bw[k] + mode_lib->vba.dpte_row_bw[k]);
|
||||
}
|
||||
locals->BandwidthWithoutPrefetchSupported[i] = true;
|
||||
if (mode_lib->vba.MaximumReadBandwidthWithoutPrefetch > locals->ReturnBWPerState[i]) {
|
||||
locals->BandwidthWithoutPrefetchSupported[i] = false;
|
||||
locals->BandwidthWithoutPrefetchSupported[i][0] = true;
|
||||
if (mode_lib->vba.MaximumReadBandwidthWithoutPrefetch > locals->ReturnBWPerState[i][0]) {
|
||||
locals->BandwidthWithoutPrefetchSupported[i][0] = false;
|
||||
}
|
||||
|
||||
locals->PrefetchSupported[i][j] = true;
|
||||
if (mode_lib->vba.MaximumReadBandwidthWithPrefetch > locals->ReturnBWPerState[i]) {
|
||||
if (mode_lib->vba.MaximumReadBandwidthWithPrefetch > locals->ReturnBWPerState[i][0]) {
|
||||
locals->PrefetchSupported[i][j] = false;
|
||||
}
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
@ -4874,7 +4873,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
if (mode_lib->vba.PrefetchSupported[i][j] == true
|
||||
&& mode_lib->vba.VRatioInPrefetchSupported[i][j] == true) {
|
||||
mode_lib->vba.BandwidthAvailableForImmediateFlip =
|
||||
mode_lib->vba.ReturnBWPerState[i];
|
||||
mode_lib->vba.ReturnBWPerState[i][0];
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
mode_lib->vba.BandwidthAvailableForImmediateFlip =
|
||||
mode_lib->vba.BandwidthAvailableForImmediateFlip
|
||||
@ -4888,9 +4887,9 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
if ((mode_lib->vba.SourcePixelFormat[k] != dm_420_8
|
||||
&& mode_lib->vba.SourcePixelFormat[k] != dm_420_10)) {
|
||||
mode_lib->vba.ImmediateFlipBytes[k] =
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k]
|
||||
+ mode_lib->vba.MetaRowBytes[k]
|
||||
+ mode_lib->vba.DPTEBytesPerRow[k];
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[0][0][k]
|
||||
+ mode_lib->vba.MetaRowBytes[0][0][k]
|
||||
+ mode_lib->vba.DPTEBytesPerRow[0][0][k];
|
||||
}
|
||||
}
|
||||
mode_lib->vba.TotImmediateFlipBytes = 0.0;
|
||||
@ -4918,9 +4917,9 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
/ mode_lib->vba.PixelClock[k],
|
||||
mode_lib->vba.VRatio[k],
|
||||
mode_lib->vba.Tno_bw[k],
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[k],
|
||||
mode_lib->vba.MetaRowBytes[k],
|
||||
mode_lib->vba.DPTEBytesPerRow[k],
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrame[0][0][k],
|
||||
mode_lib->vba.MetaRowBytes[0][0][k],
|
||||
mode_lib->vba.DPTEBytesPerRow[0][0][k],
|
||||
mode_lib->vba.DCCEnable[k],
|
||||
mode_lib->vba.dpte_row_height[k],
|
||||
mode_lib->vba.meta_row_height[k],
|
||||
@ -4945,7 +4944,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
}
|
||||
mode_lib->vba.ImmediateFlipSupportedForState[i][j] = true;
|
||||
if (mode_lib->vba.total_dcn_read_bw_with_flip
|
||||
> mode_lib->vba.ReturnBWPerState[i]) {
|
||||
> mode_lib->vba.ReturnBWPerState[i][0]) {
|
||||
mode_lib->vba.ImmediateFlipSupportedForState[i][j] = false;
|
||||
}
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
@ -4961,13 +4960,13 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
|
||||
/*Vertical Active BW support*/
|
||||
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
|
||||
mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i] = dml_min(mode_lib->vba.ReturnBusWidth *
|
||||
mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i][0] = dml_min(mode_lib->vba.ReturnBusWidth *
|
||||
mode_lib->vba.DCFCLKPerState[i], mode_lib->vba.FabricAndDRAMBandwidthPerState[i] * 1000) *
|
||||
mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation / 100;
|
||||
if (mode_lib->vba.MaxTotalVActiveRDBandwidth <= mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i])
|
||||
mode_lib->vba.TotalVerticalActiveBandwidthSupport[i] = true;
|
||||
if (mode_lib->vba.MaxTotalVActiveRDBandwidth <= mode_lib->vba.MaxTotalVerticalActiveAvailableBandwidth[i][0])
|
||||
mode_lib->vba.TotalVerticalActiveBandwidthSupport[i][0] = true;
|
||||
else
|
||||
mode_lib->vba.TotalVerticalActiveBandwidthSupport[i] = false;
|
||||
mode_lib->vba.TotalVerticalActiveBandwidthSupport[i][0] = false;
|
||||
}
|
||||
|
||||
/*PTE Buffer Size Check*/
|
||||
@ -5055,7 +5054,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
status = DML_FAIL_SCALE_RATIO_TAP;
|
||||
} else if (mode_lib->vba.SourceFormatPixelAndScanSupport != true) {
|
||||
status = DML_FAIL_SOURCE_PIXEL_FORMAT;
|
||||
} else if (locals->ViewportSizeSupport[i] != true) {
|
||||
} else if (locals->ViewportSizeSupport[i][0] != true) {
|
||||
status = DML_FAIL_VIEWPORT_SIZE;
|
||||
} else if (locals->DIOSupport[i] != true) {
|
||||
status = DML_FAIL_DIO_SUPPORT;
|
||||
@ -5065,7 +5064,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
status = DML_FAIL_DSC_CLK_REQUIRED;
|
||||
} else if (locals->UrgentLatencySupport[i][j] != true) {
|
||||
status = DML_FAIL_URGENT_LATENCY;
|
||||
} else if (locals->ROBSupport[i] != true) {
|
||||
} else if (locals->ROBSupport[i][0] != true) {
|
||||
status = DML_FAIL_REORDERING_BUFFER;
|
||||
} else if (locals->DISPCLK_DPPCLK_Support[i][j] != true) {
|
||||
status = DML_FAIL_DISPCLK_DPPCLK;
|
||||
@ -5085,7 +5084,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
status = DML_FAIL_PITCH_SUPPORT;
|
||||
} else if (locals->PrefetchSupported[i][j] != true) {
|
||||
status = DML_FAIL_PREFETCH_SUPPORT;
|
||||
} else if (locals->TotalVerticalActiveBandwidthSupport[i] != true) {
|
||||
} else if (locals->TotalVerticalActiveBandwidthSupport[i][0] != true) {
|
||||
status = DML_FAIL_TOTAL_V_ACTIVE_BW;
|
||||
} else if (locals->VRatioInPrefetchSupported[i][j] != true) {
|
||||
status = DML_FAIL_V_RATIO_PREFETCH;
|
||||
@ -5131,7 +5130,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
|
||||
mode_lib->vba.DRAMSpeed = mode_lib->vba.DRAMSpeedPerState[mode_lib->vba.VoltageLevel];
|
||||
mode_lib->vba.FabricClock = mode_lib->vba.FabricClockPerState[mode_lib->vba.VoltageLevel];
|
||||
mode_lib->vba.SOCCLK = mode_lib->vba.SOCCLKPerState[mode_lib->vba.VoltageLevel];
|
||||
mode_lib->vba.ReturnBW = locals->ReturnBWPerState[mode_lib->vba.VoltageLevel];
|
||||
mode_lib->vba.ReturnBW = locals->ReturnBWPerState[mode_lib->vba.VoltageLevel][0];
|
||||
mode_lib->vba.FabricAndDRAMBandwidth = locals->FabricAndDRAMBandwidthPerState[mode_lib->vba.VoltageLevel];
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == k) {
|
||||
|
@ -197,7 +197,7 @@ static unsigned int CalculateVMAndRowBytes(
|
||||
unsigned int *meta_row_width,
|
||||
unsigned int *meta_row_height,
|
||||
unsigned int *vm_group_bytes,
|
||||
long *dpte_group_bytes,
|
||||
unsigned int *dpte_group_bytes,
|
||||
unsigned int *PixelPTEReqWidth,
|
||||
unsigned int *PixelPTEReqHeight,
|
||||
unsigned int *PTERequestSize,
|
||||
@ -295,7 +295,7 @@ static void CalculateWatermarksAndDRAMSpeedChangeSupport(
|
||||
double UrgentOutOfOrderReturn,
|
||||
double ReturnBW,
|
||||
bool GPUVMEnable,
|
||||
long dpte_group_bytes[],
|
||||
int dpte_group_bytes[],
|
||||
unsigned int MetaChunkSize,
|
||||
double UrgentLatency,
|
||||
double ExtraLatency,
|
||||
@ -309,13 +309,13 @@ static void CalculateWatermarksAndDRAMSpeedChangeSupport(
|
||||
int DPPPerPlane[],
|
||||
bool DCCEnable[],
|
||||
double DPPCLK[],
|
||||
unsigned int SwathWidthSingleDPPY[],
|
||||
double SwathWidthSingleDPPY[],
|
||||
unsigned int SwathHeightY[],
|
||||
double ReadBandwidthPlaneLuma[],
|
||||
unsigned int SwathHeightC[],
|
||||
double ReadBandwidthPlaneChroma[],
|
||||
unsigned int LBBitPerPixel[],
|
||||
unsigned int SwathWidthY[],
|
||||
double SwathWidthY[],
|
||||
double HRatio[],
|
||||
unsigned int vtaps[],
|
||||
unsigned int VTAPsChroma[],
|
||||
@ -344,7 +344,7 @@ static void CalculateDCFCLKDeepSleep(
|
||||
double BytePerPixelDETY[],
|
||||
double BytePerPixelDETC[],
|
||||
double VRatio[],
|
||||
unsigned int SwathWidthY[],
|
||||
double SwathWidthY[],
|
||||
int DPPPerPlane[],
|
||||
double HRatio[],
|
||||
double PixelClock[],
|
||||
@ -435,7 +435,7 @@ static void CalculateMetaAndPTETimes(
|
||||
unsigned int meta_row_height[],
|
||||
unsigned int meta_req_width[],
|
||||
unsigned int meta_req_height[],
|
||||
long dpte_group_bytes[],
|
||||
int dpte_group_bytes[],
|
||||
unsigned int PTERequestSizeY[],
|
||||
unsigned int PTERequestSizeC[],
|
||||
unsigned int PixelPTEReqWidthY[],
|
||||
@ -477,7 +477,7 @@ static double CalculateExtraLatency(
|
||||
bool HostVMEnable,
|
||||
int NumberOfActivePlanes,
|
||||
int NumberOfDPP[],
|
||||
long dpte_group_bytes[],
|
||||
int dpte_group_bytes[],
|
||||
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
||||
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
||||
int HostVMMaxPageTableLevels,
|
||||
@ -1280,7 +1280,7 @@ static unsigned int CalculateVMAndRowBytes(
|
||||
unsigned int *meta_row_width,
|
||||
unsigned int *meta_row_height,
|
||||
unsigned int *vm_group_bytes,
|
||||
long *dpte_group_bytes,
|
||||
unsigned int *dpte_group_bytes,
|
||||
unsigned int *PixelPTEReqWidth,
|
||||
unsigned int *PixelPTEReqHeight,
|
||||
unsigned int *PTERequestSize,
|
||||
@ -1338,7 +1338,7 @@ static unsigned int CalculateVMAndRowBytes(
|
||||
*MetaRowByte = 0;
|
||||
}
|
||||
|
||||
if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_lvp) {
|
||||
if (SurfaceTiling == dm_sw_linear || SurfaceTiling == dm_sw_gfx7_2d_thin_gl || SurfaceTiling == dm_sw_gfx7_2d_thin_l_vp) {
|
||||
MacroTileSizeBytes = 256;
|
||||
MacroTileHeight = BlockHeight256Bytes;
|
||||
} else if (SurfaceTiling == dm_sw_4kb_s || SurfaceTiling == dm_sw_4kb_s_x
|
||||
@ -1683,11 +1683,11 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
|
||||
else
|
||||
locals->SwathWidthSingleDPPY[k] = mode_lib->vba.ViewportHeight[k];
|
||||
|
||||
if (mode_lib->vba.ODMCombineEnabled[k] == true)
|
||||
if (mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
|
||||
MainPlaneDoesODMCombine = true;
|
||||
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j)
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == j
|
||||
&& mode_lib->vba.ODMCombineEnabled[j] == true)
|
||||
&& mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1)
|
||||
MainPlaneDoesODMCombine = true;
|
||||
|
||||
if (MainPlaneDoesODMCombine == true)
|
||||
@ -2940,12 +2940,12 @@ static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib)
|
||||
SwathWidth = mode_lib->vba.ViewportHeight[k];
|
||||
}
|
||||
|
||||
if (mode_lib->vba.ODMCombineEnabled[k] == true) {
|
||||
if (mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
|
||||
MainPlaneDoesODMCombine = true;
|
||||
}
|
||||
for (j = 0; j < mode_lib->vba.NumberOfActivePlanes; ++j) {
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == j
|
||||
&& mode_lib->vba.ODMCombineEnabled[j] == true) {
|
||||
&& mode_lib->vba.ODMCombineEnabled[k] == dm_odm_combine_mode_2to1) {
|
||||
MainPlaneDoesODMCombine = true;
|
||||
}
|
||||
}
|
||||
@ -3453,7 +3453,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
== dm_420_10))
|
||||
|| (((mode_lib->vba.SurfaceTiling[k] == dm_sw_gfx7_2d_thin_gl
|
||||
|| mode_lib->vba.SurfaceTiling[k]
|
||||
== dm_sw_gfx7_2d_thin_lvp)
|
||||
== dm_sw_gfx7_2d_thin_l_vp)
|
||||
&& !((mode_lib->vba.SourcePixelFormat[k]
|
||||
== dm_444_64
|
||||
|| mode_lib->vba.SourcePixelFormat[k]
|
||||
@ -3542,17 +3542,17 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
}
|
||||
}
|
||||
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
|
||||
locals->IdealSDPPortBandwidthPerState[i] = dml_min3(
|
||||
locals->IdealSDPPortBandwidthPerState[i][0] = dml_min3(
|
||||
mode_lib->vba.ReturnBusWidth * mode_lib->vba.DCFCLKPerState[i],
|
||||
mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
|
||||
* mode_lib->vba.DRAMChannelWidth,
|
||||
mode_lib->vba.FabricClockPerState[i]
|
||||
* mode_lib->vba.FabricDatapathToDCNDataReturn);
|
||||
if (mode_lib->vba.HostVMEnable == false) {
|
||||
locals->ReturnBWPerState[i] = locals->IdealSDPPortBandwidthPerState[i]
|
||||
locals->ReturnBWPerState[i][0] = locals->IdealSDPPortBandwidthPerState[i][0]
|
||||
* mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelDataOnly / 100.0;
|
||||
} else {
|
||||
locals->ReturnBWPerState[i] = locals->IdealSDPPortBandwidthPerState[i]
|
||||
locals->ReturnBWPerState[i][0] = locals->IdealSDPPortBandwidthPerState[i][0]
|
||||
* mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData / 100.0;
|
||||
}
|
||||
}
|
||||
@ -3589,12 +3589,12 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
+ dml_max3(mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelDataOnly,
|
||||
mode_lib->vba.UrgentOutOfOrderReturnPerChannelPixelMixedWithVMData,
|
||||
mode_lib->vba.UrgentOutOfOrderReturnPerChannelVMDataOnly)
|
||||
* mode_lib->vba.NumberOfChannels / locals->ReturnBWPerState[i];
|
||||
if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024.0 / locals->ReturnBWPerState[i]
|
||||
* mode_lib->vba.NumberOfChannels / locals->ReturnBWPerState[i][0];
|
||||
if ((mode_lib->vba.ROBBufferSizeInKByte - mode_lib->vba.PixelChunkSizeInKByte) * 1024.0 / locals->ReturnBWPerState[i][0]
|
||||
> locals->UrgentRoundTripAndOutOfOrderLatencyPerState[i]) {
|
||||
locals->ROBSupport[i] = true;
|
||||
locals->ROBSupport[i][0] = true;
|
||||
} else {
|
||||
locals->ROBSupport[i] = false;
|
||||
locals->ROBSupport[i][0] = false;
|
||||
}
|
||||
}
|
||||
/*Writeback Mode Support Check*/
|
||||
@ -3982,7 +3982,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
}
|
||||
if (locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
|
||||
&& locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]
|
||||
&& locals->ODMCombineEnablePerState[i][k] == false) {
|
||||
&& locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
|
||||
locals->NoOfDPP[i][j][k] = 1;
|
||||
locals->RequiredDPPCLK[i][j][k] =
|
||||
locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
|
||||
@ -4071,16 +4071,16 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
/*Viewport Size Check*/
|
||||
|
||||
for (i = 0; i <= mode_lib->vba.soc.num_states; i++) {
|
||||
locals->ViewportSizeSupport[i] = true;
|
||||
locals->ViewportSizeSupport[i][0] = true;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
|
||||
if (dml_min(locals->SwathWidthYSingleDPP[k], dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]))
|
||||
> locals->MaximumSwathWidth[k]) {
|
||||
locals->ViewportSizeSupport[i] = false;
|
||||
locals->ViewportSizeSupport[i][0] = false;
|
||||
}
|
||||
} else {
|
||||
if (locals->SwathWidthYSingleDPP[k] / 2.0 > locals->MaximumSwathWidth[k]) {
|
||||
locals->ViewportSizeSupport[i] = false;
|
||||
locals->ViewportSizeSupport[i][0] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4269,8 +4269,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.DSCFormatFactor = 1;
|
||||
}
|
||||
if (locals->RequiresDSC[i][k] == true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k]
|
||||
== true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
|
||||
if (mode_lib->vba.PixelClockBackEnd[k] / 6.0 / mode_lib->vba.DSCFormatFactor
|
||||
> (1.0 - mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * mode_lib->vba.MaxDSCCLK[i]) {
|
||||
locals->DSCCLKRequiredMoreThanSupported[i] =
|
||||
@ -4293,7 +4292,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.TotalDSCUnitsRequired = 0.0;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (locals->RequiresDSC[i][k] == true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
|
||||
mode_lib->vba.TotalDSCUnitsRequired =
|
||||
mode_lib->vba.TotalDSCUnitsRequired + 2.0;
|
||||
} else {
|
||||
@ -4335,7 +4334,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.bpp = locals->OutputBppPerState[i][k];
|
||||
}
|
||||
if (locals->RequiresDSC[i][k] == true && mode_lib->vba.bpp != 0.0) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == false) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
|
||||
locals->DSCDelayPerState[i][k] =
|
||||
dscceComputeDelay(
|
||||
mode_lib->vba.DSCInputBitPerComponent[k],
|
||||
@ -4399,7 +4398,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
locals->RequiredDPPCLKThisState[k] = locals->RequiredDPPCLK[i][j][k];
|
||||
locals->NoOfDPPThisState[k] = locals->NoOfDPP[i][j][k];
|
||||
if (locals->ODMCombineEnablePerState[i][k] == true) {
|
||||
if (locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) {
|
||||
locals->SwathWidthYThisState[k] =
|
||||
dml_min(locals->SwathWidthYSingleDPP[k], dml_round(mode_lib->vba.HActive[k] / 2.0 * mode_lib->vba.HRatio[k]));
|
||||
} else {
|
||||
@ -4451,7 +4450,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
locals->PSCL_FACTOR,
|
||||
locals->PSCL_FACTOR_CHROMA,
|
||||
locals->RequiredDPPCLKThisState,
|
||||
&mode_lib->vba.ProjectedDCFCLKDeepSleep);
|
||||
&mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0]);
|
||||
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if ((mode_lib->vba.SourcePixelFormat[k] != dm_444_64
|
||||
@ -4496,7 +4495,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
locals->PTERequestSizeC,
|
||||
locals->dpde0_bytes_per_frame_ub_c,
|
||||
locals->meta_pte_bytes_per_frame_ub_c);
|
||||
locals->PrefetchLinesC[k] = CalculatePrefetchSourceLines(
|
||||
locals->PrefetchLinesC[0][0][k] = CalculatePrefetchSourceLines(
|
||||
mode_lib,
|
||||
mode_lib->vba.VRatio[k]/2,
|
||||
mode_lib->vba.VTAPsChroma[k],
|
||||
@ -4511,7 +4510,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrameC = 0.0;
|
||||
mode_lib->vba.MetaRowBytesC = 0.0;
|
||||
mode_lib->vba.DPTEBytesPerRowC = 0.0;
|
||||
locals->PrefetchLinesC[k] = 0.0;
|
||||
locals->PrefetchLinesC[0][0][k] = 0.0;
|
||||
locals->PTEBufferSizeNotExceededC[i][j][k] = true;
|
||||
locals->PTEBufferSizeInRequestsForLuma = mode_lib->vba.PTEBufferSizeInRequestsLuma + mode_lib->vba.PTEBufferSizeInRequestsChroma;
|
||||
}
|
||||
@ -4552,7 +4551,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
locals->PTERequestSizeY,
|
||||
locals->dpde0_bytes_per_frame_ub_l,
|
||||
locals->meta_pte_bytes_per_frame_ub_l);
|
||||
locals->PrefetchLinesY[k] = CalculatePrefetchSourceLines(
|
||||
locals->PrefetchLinesY[0][0][k] = CalculatePrefetchSourceLines(
|
||||
mode_lib,
|
||||
mode_lib->vba.VRatio[k],
|
||||
mode_lib->vba.vtaps[k],
|
||||
@ -4562,10 +4561,10 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.ViewportYStartY[k],
|
||||
&locals->PrefillY[k],
|
||||
&locals->MaxNumSwY[k]);
|
||||
locals->PDEAndMetaPTEBytesPerFrame[k] =
|
||||
locals->PDEAndMetaPTEBytesPerFrame[0][0][k] =
|
||||
mode_lib->vba.PDEAndMetaPTEBytesPerFrameY + mode_lib->vba.PDEAndMetaPTEBytesPerFrameC;
|
||||
locals->MetaRowBytes[k] = mode_lib->vba.MetaRowBytesY + mode_lib->vba.MetaRowBytesC;
|
||||
locals->DPTEBytesPerRow[k] = mode_lib->vba.DPTEBytesPerRowY + mode_lib->vba.DPTEBytesPerRowC;
|
||||
locals->MetaRowBytes[0][0][k] = mode_lib->vba.MetaRowBytesY + mode_lib->vba.MetaRowBytesC;
|
||||
locals->DPTEBytesPerRow[0][0][k] = mode_lib->vba.DPTEBytesPerRowY + mode_lib->vba.DPTEBytesPerRowC;
|
||||
|
||||
CalculateActiveRowBandwidth(
|
||||
mode_lib->vba.GPUVMEnable,
|
||||
@ -4591,7 +4590,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.PixelChunkSizeInKByte,
|
||||
locals->TotalNumberOfDCCActiveDPP[i][j],
|
||||
mode_lib->vba.MetaChunkSize,
|
||||
locals->ReturnBWPerState[i],
|
||||
locals->ReturnBWPerState[i][0],
|
||||
mode_lib->vba.GPUVMEnable,
|
||||
mode_lib->vba.HostVMEnable,
|
||||
mode_lib->vba.NumberOfActivePlanes,
|
||||
@ -4602,7 +4601,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.HostVMMaxPageTableLevels,
|
||||
mode_lib->vba.HostVMCachedPageTableLevels);
|
||||
|
||||
mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep;
|
||||
mode_lib->vba.TimeCalc = 24.0 / mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0];
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == k) {
|
||||
if (mode_lib->vba.WritebackEnable[k] == true) {
|
||||
@ -4644,15 +4643,15 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
}
|
||||
}
|
||||
}
|
||||
mode_lib->vba.MaxMaxVStartup = 0;
|
||||
mode_lib->vba.MaxMaxVStartup[0][0] = 0;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
locals->MaximumVStartup[k] = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
|
||||
locals->MaximumVStartup[0][0][k] = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]
|
||||
- dml_max(1.0, dml_ceil(locals->WritebackDelay[i][k] / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]), 1.0));
|
||||
mode_lib->vba.MaxMaxVStartup = dml_max(mode_lib->vba.MaxMaxVStartup, locals->MaximumVStartup[k]);
|
||||
mode_lib->vba.MaxMaxVStartup[0][0] = dml_max(mode_lib->vba.MaxMaxVStartup[0][0], locals->MaximumVStartup[0][0][k]);
|
||||
}
|
||||
|
||||
mode_lib->vba.NextPrefetchMode = mode_lib->vba.MinPrefetchMode;
|
||||
mode_lib->vba.NextMaxVStartup = mode_lib->vba.MaxMaxVStartup;
|
||||
mode_lib->vba.NextMaxVStartup = mode_lib->vba.MaxMaxVStartup[0][0];
|
||||
do {
|
||||
mode_lib->vba.PrefetchMode[i][j] = mode_lib->vba.NextPrefetchMode;
|
||||
mode_lib->vba.MaxVStartup = mode_lib->vba.NextMaxVStartup;
|
||||
@ -4693,7 +4692,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
myPipe.DPPCLK = locals->RequiredDPPCLK[i][j][k];
|
||||
myPipe.DISPCLK = locals->RequiredDISPCLK[i][j];
|
||||
myPipe.PixelClock = mode_lib->vba.PixelClock[k];
|
||||
myPipe.DCFCLKDeepSleep = mode_lib->vba.ProjectedDCFCLKDeepSleep;
|
||||
myPipe.DCFCLKDeepSleep = mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0];
|
||||
myPipe.DPPPerPlane = locals->NoOfDPP[i][j][k];
|
||||
myPipe.ScalerEnabled = mode_lib->vba.ScalerEnabled[k];
|
||||
myPipe.SourceScan = mode_lib->vba.SourceScan[k];
|
||||
@ -4727,8 +4726,8 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
locals->SwathWidthYThisState[k] / mode_lib->vba.HRatio[k],
|
||||
mode_lib->vba.OutputFormat[k],
|
||||
mode_lib->vba.MaxInterDCNTileRepeaters,
|
||||
dml_min(mode_lib->vba.MaxVStartup, locals->MaximumVStartup[k]),
|
||||
locals->MaximumVStartup[k],
|
||||
dml_min(mode_lib->vba.MaxVStartup, locals->MaximumVStartup[0][0][k]),
|
||||
locals->MaximumVStartup[0][0][k],
|
||||
mode_lib->vba.GPUVMMaxPageTableLevels,
|
||||
mode_lib->vba.GPUVMEnable,
|
||||
&myHostVM,
|
||||
@ -4739,15 +4738,15 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.UrgentLatency,
|
||||
mode_lib->vba.ExtraLatency,
|
||||
mode_lib->vba.TimeCalc,
|
||||
locals->PDEAndMetaPTEBytesPerFrame[k],
|
||||
locals->MetaRowBytes[k],
|
||||
locals->DPTEBytesPerRow[k],
|
||||
locals->PrefetchLinesY[k],
|
||||
locals->PDEAndMetaPTEBytesPerFrame[0][0][k],
|
||||
locals->MetaRowBytes[0][0][k],
|
||||
locals->DPTEBytesPerRow[0][0][k],
|
||||
locals->PrefetchLinesY[0][0][k],
|
||||
locals->SwathWidthYThisState[k],
|
||||
locals->BytePerPixelInDETY[k],
|
||||
locals->PrefillY[k],
|
||||
locals->MaxNumSwY[k],
|
||||
locals->PrefetchLinesC[k],
|
||||
locals->PrefetchLinesC[0][0][k],
|
||||
locals->BytePerPixelInDETC[k],
|
||||
locals->PrefillC[k],
|
||||
locals->MaxNumSwC[k],
|
||||
@ -4836,14 +4835,14 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
+ locals->RequiredPrefetchPixelDataBWChroma[i][j][k] * locals->UrgentBurstFactorChromaPre[k]
|
||||
+ locals->cursor_bw_pre[k] * locals->UrgentBurstFactorCursorPre[k]);
|
||||
}
|
||||
locals->BandwidthWithoutPrefetchSupported[i] = true;
|
||||
if (mode_lib->vba.MaximumReadBandwidthWithoutPrefetch > locals->ReturnBWPerState[i]
|
||||
locals->BandwidthWithoutPrefetchSupported[i][0] = true;
|
||||
if (mode_lib->vba.MaximumReadBandwidthWithoutPrefetch > locals->ReturnBWPerState[i][0]
|
||||
|| locals->NotEnoughUrgentLatencyHiding == 1) {
|
||||
locals->BandwidthWithoutPrefetchSupported[i] = false;
|
||||
locals->BandwidthWithoutPrefetchSupported[i][0] = false;
|
||||
}
|
||||
|
||||
locals->PrefetchSupported[i][j] = true;
|
||||
if (mode_lib->vba.MaximumReadBandwidthWithPrefetch > locals->ReturnBWPerState[i]
|
||||
if (mode_lib->vba.MaximumReadBandwidthWithPrefetch > locals->ReturnBWPerState[i][0]
|
||||
|| locals->NotEnoughUrgentLatencyHiding == 1
|
||||
|| locals->NotEnoughUrgentLatencyHidingPre == 1) {
|
||||
locals->PrefetchSupported[i][j] = false;
|
||||
@ -4872,17 +4871,17 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
}
|
||||
|
||||
if (mode_lib->vba.MaxVStartup <= 13 || mode_lib->vba.AnyLinesForVMOrRowTooLarge == false) {
|
||||
mode_lib->vba.NextMaxVStartup = mode_lib->vba.MaxMaxVStartup;
|
||||
mode_lib->vba.NextMaxVStartup = mode_lib->vba.MaxMaxVStartup[0][0];
|
||||
mode_lib->vba.NextPrefetchMode = mode_lib->vba.NextPrefetchMode + 1;
|
||||
} else {
|
||||
mode_lib->vba.NextMaxVStartup = mode_lib->vba.NextMaxVStartup - 1;
|
||||
}
|
||||
} while ((locals->PrefetchSupported[i][j] != true || locals->VRatioInPrefetchSupported[i][j] != true)
|
||||
&& (mode_lib->vba.NextMaxVStartup != mode_lib->vba.MaxMaxVStartup
|
||||
&& (mode_lib->vba.NextMaxVStartup != mode_lib->vba.MaxMaxVStartup[0][0]
|
||||
|| mode_lib->vba.NextPrefetchMode < mode_lib->vba.MaxPrefetchMode));
|
||||
|
||||
if (locals->PrefetchSupported[i][j] == true && locals->VRatioInPrefetchSupported[i][j] == true) {
|
||||
mode_lib->vba.BandwidthAvailableForImmediateFlip = locals->ReturnBWPerState[i];
|
||||
mode_lib->vba.BandwidthAvailableForImmediateFlip = locals->ReturnBWPerState[i][0];
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
mode_lib->vba.BandwidthAvailableForImmediateFlip = mode_lib->vba.BandwidthAvailableForImmediateFlip
|
||||
- dml_max(locals->ReadBandwidthLuma[k] * locals->UrgentBurstFactorLuma[k]
|
||||
@ -4895,7 +4894,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.TotImmediateFlipBytes = 0.0;
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
mode_lib->vba.TotImmediateFlipBytes = mode_lib->vba.TotImmediateFlipBytes
|
||||
+ locals->PDEAndMetaPTEBytesPerFrame[k] + locals->MetaRowBytes[k] + locals->DPTEBytesPerRow[k];
|
||||
+ locals->PDEAndMetaPTEBytesPerFrame[0][0][k] + locals->MetaRowBytes[0][0][k] + locals->DPTEBytesPerRow[0][0][k];
|
||||
}
|
||||
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
@ -4910,9 +4909,9 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.HostVMMaxPageTableLevels,
|
||||
mode_lib->vba.HostVMCachedPageTableLevels,
|
||||
mode_lib->vba.GPUVMEnable,
|
||||
locals->PDEAndMetaPTEBytesPerFrame[k],
|
||||
locals->MetaRowBytes[k],
|
||||
locals->DPTEBytesPerRow[k],
|
||||
locals->PDEAndMetaPTEBytesPerFrame[0][0][k],
|
||||
locals->MetaRowBytes[0][0][k],
|
||||
locals->DPTEBytesPerRow[0][0][k],
|
||||
mode_lib->vba.BandwidthAvailableForImmediateFlip,
|
||||
mode_lib->vba.TotImmediateFlipBytes,
|
||||
mode_lib->vba.SourcePixelFormat[k],
|
||||
@ -4943,7 +4942,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
}
|
||||
locals->ImmediateFlipSupportedForState[i][j] = true;
|
||||
if (mode_lib->vba.total_dcn_read_bw_with_flip
|
||||
> locals->ReturnBWPerState[i]) {
|
||||
> locals->ReturnBWPerState[i][0]) {
|
||||
locals->ImmediateFlipSupportedForState[i][j] = false;
|
||||
}
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
@ -4970,7 +4969,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.WritebackInterfaceChromaBufferSize,
|
||||
mode_lib->vba.DCFCLKPerState[i],
|
||||
mode_lib->vba.UrgentOutOfOrderReturnPerChannel * mode_lib->vba.NumberOfChannels,
|
||||
locals->ReturnBWPerState[i],
|
||||
locals->ReturnBWPerState[i][0],
|
||||
mode_lib->vba.GPUVMEnable,
|
||||
locals->dpte_group_bytes,
|
||||
mode_lib->vba.MetaChunkSize,
|
||||
@ -4982,7 +4981,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.DRAMClockChangeLatency,
|
||||
mode_lib->vba.SRExitTime,
|
||||
mode_lib->vba.SREnterPlusExitTime,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep,
|
||||
mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0],
|
||||
locals->NoOfDPPThisState,
|
||||
mode_lib->vba.DCCEnable,
|
||||
locals->RequiredDPPCLKThisState,
|
||||
@ -5025,8 +5024,8 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
MaxTotalVActiveRDBandwidth = MaxTotalVActiveRDBandwidth + locals->ReadBandwidth[k];
|
||||
}
|
||||
for (i = 0; i <= mode_lib->vba.soc.num_states; ++i) {
|
||||
locals->MaxTotalVerticalActiveAvailableBandwidth[i] = dml_min(
|
||||
locals->IdealSDPPortBandwidthPerState[i] *
|
||||
locals->MaxTotalVerticalActiveAvailableBandwidth[i][0] = dml_min(
|
||||
locals->IdealSDPPortBandwidthPerState[i][0] *
|
||||
mode_lib->vba.MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation
|
||||
/ 100.0, mode_lib->vba.DRAMSpeedPerState[i] *
|
||||
mode_lib->vba.NumberOfChannels *
|
||||
@ -5034,10 +5033,10 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.MaxAveragePercentOfIdealDRAMBWDisplayCanUseInNormalSystemOperation
|
||||
/ 100.0);
|
||||
|
||||
if (MaxTotalVActiveRDBandwidth <= locals->MaxTotalVerticalActiveAvailableBandwidth[i]) {
|
||||
locals->TotalVerticalActiveBandwidthSupport[i] = true;
|
||||
if (MaxTotalVActiveRDBandwidth <= locals->MaxTotalVerticalActiveAvailableBandwidth[i][0]) {
|
||||
locals->TotalVerticalActiveBandwidthSupport[i][0] = true;
|
||||
} else {
|
||||
locals->TotalVerticalActiveBandwidthSupport[i] = false;
|
||||
locals->TotalVerticalActiveBandwidthSupport[i][0] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5116,7 +5115,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
status = DML_FAIL_SCALE_RATIO_TAP;
|
||||
} else if (mode_lib->vba.SourceFormatPixelAndScanSupport != true) {
|
||||
status = DML_FAIL_SOURCE_PIXEL_FORMAT;
|
||||
} else if (locals->ViewportSizeSupport[i] != true) {
|
||||
} else if (locals->ViewportSizeSupport[i][0] != true) {
|
||||
status = DML_FAIL_VIEWPORT_SIZE;
|
||||
} else if (locals->DIOSupport[i] != true) {
|
||||
status = DML_FAIL_DIO_SUPPORT;
|
||||
@ -5124,7 +5123,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
status = DML_FAIL_NOT_ENOUGH_DSC;
|
||||
} else if (locals->DSCCLKRequiredMoreThanSupported[i] != false) {
|
||||
status = DML_FAIL_DSC_CLK_REQUIRED;
|
||||
} else if (locals->ROBSupport[i] != true) {
|
||||
} else if (locals->ROBSupport[i][0] != true) {
|
||||
status = DML_FAIL_REORDERING_BUFFER;
|
||||
} else if (locals->DISPCLK_DPPCLK_Support[i][j] != true) {
|
||||
status = DML_FAIL_DISPCLK_DPPCLK;
|
||||
@ -5142,7 +5141,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
status = DML_FAIL_CURSOR_SUPPORT;
|
||||
} else if (mode_lib->vba.PitchSupport != true) {
|
||||
status = DML_FAIL_PITCH_SUPPORT;
|
||||
} else if (locals->TotalVerticalActiveBandwidthSupport[i] != true) {
|
||||
} else if (locals->TotalVerticalActiveBandwidthSupport[i][0] != true) {
|
||||
status = DML_FAIL_TOTAL_V_ACTIVE_BW;
|
||||
} else if (locals->PTEBufferSizeNotExceeded[i][j] != true) {
|
||||
status = DML_FAIL_PTE_BUFFER_SIZE;
|
||||
@ -5198,7 +5197,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.DRAMSpeed = mode_lib->vba.DRAMSpeedPerState[mode_lib->vba.VoltageLevel];
|
||||
mode_lib->vba.FabricClock = mode_lib->vba.FabricClockPerState[mode_lib->vba.VoltageLevel];
|
||||
mode_lib->vba.SOCCLK = mode_lib->vba.SOCCLKPerState[mode_lib->vba.VoltageLevel];
|
||||
mode_lib->vba.ReturnBW = locals->ReturnBWPerState[mode_lib->vba.VoltageLevel];
|
||||
mode_lib->vba.ReturnBW = locals->ReturnBWPerState[mode_lib->vba.VoltageLevel][0];
|
||||
for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) {
|
||||
if (mode_lib->vba.BlendingAndTiming[k] == k) {
|
||||
mode_lib->vba.ODMCombineEnabled[k] =
|
||||
@ -5227,7 +5226,7 @@ static void CalculateWatermarksAndDRAMSpeedChangeSupport(
|
||||
double UrgentOutOfOrderReturn,
|
||||
double ReturnBW,
|
||||
bool GPUVMEnable,
|
||||
long dpte_group_bytes[],
|
||||
int dpte_group_bytes[],
|
||||
unsigned int MetaChunkSize,
|
||||
double UrgentLatency,
|
||||
double ExtraLatency,
|
||||
@ -5241,13 +5240,13 @@ static void CalculateWatermarksAndDRAMSpeedChangeSupport(
|
||||
int DPPPerPlane[],
|
||||
bool DCCEnable[],
|
||||
double DPPCLK[],
|
||||
unsigned int SwathWidthSingleDPPY[],
|
||||
double SwathWidthSingleDPPY[],
|
||||
unsigned int SwathHeightY[],
|
||||
double ReadBandwidthPlaneLuma[],
|
||||
unsigned int SwathHeightC[],
|
||||
double ReadBandwidthPlaneChroma[],
|
||||
unsigned int LBBitPerPixel[],
|
||||
unsigned int SwathWidthY[],
|
||||
double SwathWidthY[],
|
||||
double HRatio[],
|
||||
unsigned int vtaps[],
|
||||
unsigned int VTAPsChroma[],
|
||||
@ -5503,7 +5502,7 @@ static void CalculateDCFCLKDeepSleep(
|
||||
double BytePerPixelDETY[],
|
||||
double BytePerPixelDETC[],
|
||||
double VRatio[],
|
||||
unsigned int SwathWidthY[],
|
||||
double SwathWidthY[],
|
||||
int DPPPerPlane[],
|
||||
double HRatio[],
|
||||
double PixelClock[],
|
||||
@ -5831,7 +5830,7 @@ static void CalculateMetaAndPTETimes(
|
||||
unsigned int meta_row_height[],
|
||||
unsigned int meta_req_width[],
|
||||
unsigned int meta_req_height[],
|
||||
long dpte_group_bytes[],
|
||||
int dpte_group_bytes[],
|
||||
unsigned int PTERequestSizeY[],
|
||||
unsigned int PTERequestSizeC[],
|
||||
unsigned int PixelPTEReqWidthY[],
|
||||
@ -6087,7 +6086,7 @@ static double CalculateExtraLatency(
|
||||
bool HostVMEnable,
|
||||
int NumberOfActivePlanes,
|
||||
int NumberOfDPP[],
|
||||
long dpte_group_bytes[],
|
||||
int dpte_group_bytes[],
|
||||
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData,
|
||||
double PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly,
|
||||
int HostVMMaxPageTableLevels,
|
||||
|
@ -85,7 +85,7 @@ enum dm_swizzle_mode {
|
||||
dm_sw_var_s_x = 29,
|
||||
dm_sw_var_d_x = 30,
|
||||
dm_sw_64kb_r_x,
|
||||
dm_sw_gfx7_2d_thin_lvp,
|
||||
dm_sw_gfx7_2d_thin_l_vp,
|
||||
dm_sw_gfx7_2d_thin_gl,
|
||||
};
|
||||
enum lb_depth {
|
||||
@ -119,6 +119,10 @@ enum mpc_combine_affinity {
|
||||
dm_mpc_never
|
||||
};
|
||||
|
||||
enum RequestType {
|
||||
REQ_256Bytes, REQ_128BytesNonContiguous, REQ_128BytesContiguous, REQ_NA
|
||||
};
|
||||
|
||||
enum self_refresh_affinity {
|
||||
dm_try_to_allow_self_refresh_and_mclk_switch,
|
||||
dm_allow_self_refresh_and_mclk_switch,
|
||||
@ -165,4 +169,16 @@ enum odm_combine_mode {
|
||||
dm_odm_combine_mode_4to1,
|
||||
};
|
||||
|
||||
enum odm_combine_policy {
|
||||
dm_odm_combine_policy_dal,
|
||||
dm_odm_combine_policy_none,
|
||||
dm_odm_combine_policy_2to1,
|
||||
dm_odm_combine_policy_4to1,
|
||||
};
|
||||
|
||||
enum immediate_flip_requirement {
|
||||
dm_immediate_flip_not_required,
|
||||
dm_immediate_flip_required,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -63,6 +63,7 @@ struct _vcs_dpi_voltage_scaling_st {
|
||||
double dispclk_mhz;
|
||||
double phyclk_mhz;
|
||||
double dppclk_mhz;
|
||||
double dtbclk_mhz;
|
||||
};
|
||||
|
||||
struct _vcs_dpi_soc_bounding_box_st {
|
||||
@ -214,6 +215,7 @@ struct _vcs_dpi_display_pipe_source_params_st {
|
||||
int source_format;
|
||||
unsigned char dcc;
|
||||
unsigned int dcc_rate;
|
||||
unsigned int dcc_rate_chroma;
|
||||
unsigned char dcc_use_global;
|
||||
unsigned char vm;
|
||||
bool gpuvm; // gpuvm enabled
|
||||
@ -225,7 +227,10 @@ struct _vcs_dpi_display_pipe_source_params_st {
|
||||
int source_scan;
|
||||
int sw_mode;
|
||||
int macro_tile_size;
|
||||
unsigned int surface_width_y;
|
||||
unsigned int surface_height_y;
|
||||
unsigned int surface_width_c;
|
||||
unsigned int surface_height_c;
|
||||
unsigned int viewport_width;
|
||||
unsigned int viewport_height;
|
||||
unsigned int viewport_y_y;
|
||||
@ -324,7 +329,7 @@ struct _vcs_dpi_display_pipe_dest_params_st {
|
||||
double pixel_rate_mhz;
|
||||
unsigned char synchronized_vblank_all_planes;
|
||||
unsigned char otg_inst;
|
||||
unsigned char odm_combine;
|
||||
unsigned int odm_combine;
|
||||
unsigned char use_maximum_vstartup;
|
||||
unsigned int vtotal_max;
|
||||
unsigned int vtotal_min;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user