mirror of
https://github.com/torvalds/linux
synced 2024-10-05 02:44:13 +00:00
Merge tag 'amd-drm-next-6.2-2022-11-04' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-6.2-2022-11-04: amdgpu: - Add TMZ support for GC 11.0.1 - More IP version check conversions - Mode2 reset fixes for sienna cichlid - SMU 13.x fixes - RAS enablement on MP 13.x - Replace kmap with kmap_local_page() - Misc Clang warning fixes - SR-IOV fixes for GC 11.x - PCI AER fix - DCN 3.2.x commit sequence rework - SDMA 4.x doorbell fix - Expose additional new GC 11.x firmware versions - Misc code cleanups - S0i3 fixes - More DC FPU cleanup - Add more DC kerneldoc - Misc spelling and grammer fixes - DCN 3.1.x fixes - Plane modifier fix - MCA RAS enablement - Secure display locking fix - RAS TA rework - RAS EEPROM fixes - Fail suspend if eviction fails - Drop AMD specific DSC workarounds in favor of drm EDID quirks - SR-IOV suspend/resume fixes - Enable DCN support for ARM - Enable secure display on DCN 2.1 amdkfd: - Cache size fixes for GC 10.3.x - kfd_dev struct cleanup - GC11.x CWSR trap handler fix - Userptr fixes - Warning fixes radeon: - Replace kmap with kmap_local_page() UAPI: - Expose additional new GC 11.x firmware versions via the existing INFO query drm: - Add some new EDID DSC quirks Signed-off-by: Dave Airlie <airlied@redhat.com> # Conflicts: # drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20221104205827.6008-1-alexander.deucher@amd.com
This commit is contained in:
commit
49e8e6343d
|
@ -219,10 +219,12 @@ extern int amdgpu_use_xgmi_p2p;
|
|||
extern int sched_policy;
|
||||
extern bool debug_evictions;
|
||||
extern bool no_system_mem_limit;
|
||||
extern int halt_if_hws_hang;
|
||||
#else
|
||||
static const int __maybe_unused sched_policy = KFD_SCHED_POLICY_HWS;
|
||||
static const bool __maybe_unused debug_evictions; /* = false */
|
||||
static const bool __maybe_unused no_system_mem_limit;
|
||||
static const int __maybe_unused halt_if_hws_hang;
|
||||
#endif
|
||||
#ifdef CONFIG_HSA_AMD_P2P
|
||||
extern bool pcie_p2p;
|
||||
|
@ -675,7 +677,7 @@ enum amd_hw_ip_block_type {
|
|||
MAX_HWIP
|
||||
};
|
||||
|
||||
#define HWIP_MAX_INSTANCE 11
|
||||
#define HWIP_MAX_INSTANCE 28
|
||||
|
||||
#define HW_ID_MAX 300
|
||||
#define IP_VERSION(mj, mn, rv) (((mj) << 16) | ((mn) << 8) | (rv))
|
||||
|
|
|
@ -195,7 +195,7 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
adev->kfd.init_complete = kgd2kfd_device_init(adev->kfd.dev,
|
||||
adev_to_drm(adev), &gpu_resources);
|
||||
&gpu_resources);
|
||||
|
||||
amdgpu_amdkfd_total_mem_size += adev->gmc.real_vram_size;
|
||||
|
||||
|
@ -706,6 +706,13 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
|
|||
|
||||
void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle)
|
||||
{
|
||||
/* Temporary workaround to fix issues observed in some
|
||||
* compute applications when GFXOFF is enabled on GFX11.
|
||||
*/
|
||||
if (IP_VERSION_MAJ(adev->ip_versions[GC_HWIP][0]) == 11) {
|
||||
pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled");
|
||||
amdgpu_gfx_off_ctrl(adev, idle);
|
||||
}
|
||||
amdgpu_dpm_switch_power_profile(adev,
|
||||
PP_SMC_POWER_PROFILE_COMPUTE,
|
||||
!idle);
|
||||
|
@ -753,9 +760,7 @@ bool amdgpu_amdkfd_have_atomics_support(struct amdgpu_device *adev)
|
|||
|
||||
void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev, bool reset)
|
||||
{
|
||||
struct ras_err_data err_data = {0, 0, 0, NULL};
|
||||
|
||||
amdgpu_umc_poison_handler(adev, &err_data, reset);
|
||||
amdgpu_umc_poison_handler(adev, reset);
|
||||
}
|
||||
|
||||
bool amdgpu_amdkfd_ras_query_utcl2_poison_status(struct amdgpu_device *adev)
|
||||
|
|
|
@ -353,7 +353,6 @@ int kgd2kfd_init(void);
|
|||
void kgd2kfd_exit(void);
|
||||
struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf);
|
||||
bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
||||
struct drm_device *ddev,
|
||||
const struct kgd2kfd_shared_resources *gpu_resources);
|
||||
void kgd2kfd_device_exit(struct kfd_dev *kfd);
|
||||
void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm);
|
||||
|
@ -381,7 +380,7 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
|
|||
}
|
||||
|
||||
static inline
|
||||
bool kgd2kfd_device_init(struct kfd_dev *kfd, struct drm_device *ddev,
|
||||
bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
||||
const struct kgd2kfd_shared_resources *gpu_resources)
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -787,7 +787,7 @@ void kgd_gfx_v9_get_cu_occupancy(struct amdgpu_device *adev, int pasid,
|
|||
for (se_idx = 0; se_idx < se_cnt; se_idx++) {
|
||||
for (sh_idx = 0; sh_idx < sh_cnt; sh_idx++) {
|
||||
|
||||
gfx_v9_0_select_se_sh(adev, se_idx, sh_idx, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, se_idx, sh_idx, 0xffffffff);
|
||||
queue_map = RREG32_SOC15(GC, 0, mmSPI_CSQ_WF_ACTIVE_STATUS);
|
||||
|
||||
/*
|
||||
|
@ -820,7 +820,7 @@ void kgd_gfx_v9_get_cu_occupancy(struct amdgpu_device *adev, int pasid,
|
|||
}
|
||||
}
|
||||
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
soc15_grbm_select(adev, 0, 0, 0, 0);
|
||||
unlock_spi_csq_mutexes(adev);
|
||||
|
||||
|
|
|
@ -418,9 +418,9 @@ static uint64_t get_pte_flags(struct amdgpu_device *adev, struct kgd_mem *mem)
|
|||
if (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE)
|
||||
mapping_flags |= AMDGPU_VM_PAGE_EXECUTABLE;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_ARCTURUS:
|
||||
case CHIP_ALDEBARAN:
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(9, 4, 1):
|
||||
case IP_VERSION(9, 4, 2):
|
||||
if (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
|
||||
if (bo_adev == adev) {
|
||||
if (uncached)
|
||||
|
@ -429,7 +429,7 @@ static uint64_t get_pte_flags(struct amdgpu_device *adev, struct kgd_mem *mem)
|
|||
mapping_flags |= AMDGPU_VM_MTYPE_CC;
|
||||
else
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_RW;
|
||||
if (adev->asic_type == CHIP_ALDEBARAN &&
|
||||
if ((adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2)) &&
|
||||
adev->gmc.xgmi.connected_to_cpu)
|
||||
snoop = true;
|
||||
} else {
|
||||
|
@ -510,13 +510,13 @@ kfd_mem_dmamap_userptr(struct kgd_mem *mem,
|
|||
struct ttm_tt *ttm = bo->tbo.ttm;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(ttm->num_pages != src_ttm->num_pages))
|
||||
return -EINVAL;
|
||||
|
||||
ttm->sg = kmalloc(sizeof(*ttm->sg), GFP_KERNEL);
|
||||
if (unlikely(!ttm->sg))
|
||||
return -ENOMEM;
|
||||
|
||||
if (WARN_ON(ttm->num_pages != src_ttm->num_pages))
|
||||
return -EINVAL;
|
||||
|
||||
/* Same sequence as in amdgpu_ttm_tt_pin_userptr */
|
||||
ret = sg_alloc_table_from_pages(ttm->sg, src_ttm->pages,
|
||||
ttm->num_pages, 0,
|
||||
|
@ -1907,16 +1907,6 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
|
|||
*/
|
||||
mutex_lock(&mem->process_info->lock);
|
||||
|
||||
/* Lock mmap-sem. If we find an invalid userptr BO, we can be
|
||||
* sure that the MMU notifier is no longer running
|
||||
* concurrently and the queues are actually stopped
|
||||
*/
|
||||
if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) {
|
||||
mmap_write_lock(current->mm);
|
||||
is_invalid_userptr = atomic_read(&mem->invalid);
|
||||
mmap_write_unlock(current->mm);
|
||||
}
|
||||
|
||||
mutex_lock(&mem->lock);
|
||||
|
||||
domain = mem->domain;
|
||||
|
|
|
@ -326,7 +326,10 @@ static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
ctx->stable_pstate = current_stable_pstate;
|
||||
if (mgr->adev->pm.stable_pstate_ctx)
|
||||
ctx->stable_pstate = mgr->adev->pm.stable_pstate_ctx->stable_pstate;
|
||||
else
|
||||
ctx->stable_pstate = current_stable_pstate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1568,7 +1568,7 @@ static int amdgpu_device_check_arguments(struct amdgpu_device *adev)
|
|||
* @pdev: pci dev pointer
|
||||
* @state: vga_switcheroo state
|
||||
*
|
||||
* Callback for the switcheroo driver. Suspends or resumes the
|
||||
* Callback for the switcheroo driver. Suspends or resumes
|
||||
* the asics before or after it is powered up using ACPI methods.
|
||||
*/
|
||||
static void amdgpu_switcheroo_set_state(struct pci_dev *pdev,
|
||||
|
@ -2397,7 +2397,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
|||
adev->ip_blocks[i].status.hw = true;
|
||||
|
||||
/* right after GMC hw init, we create CSA */
|
||||
if (amdgpu_mcbp || amdgpu_sriov_vf(adev)) {
|
||||
if (amdgpu_mcbp) {
|
||||
r = amdgpu_allocate_static_csa(adev, &adev->virt.csa_obj,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
AMDGPU_CSA_SIZE);
|
||||
|
@ -3210,6 +3210,15 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
|
|||
return r;
|
||||
}
|
||||
adev->ip_blocks[i].status.hw = true;
|
||||
|
||||
if (adev->in_s0ix && adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) {
|
||||
/* disable gfxoff for IP resume. The gfxoff will be re-enabled in
|
||||
* amdgpu_device_resume() after IP resume.
|
||||
*/
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
DRM_DEBUG("will disable gfxoff for re-initializing other blocks\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -4051,15 +4060,18 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
|
|||
* at suspend time.
|
||||
*
|
||||
*/
|
||||
static void amdgpu_device_evict_resources(struct amdgpu_device *adev)
|
||||
static int amdgpu_device_evict_resources(struct amdgpu_device *adev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* No need to evict vram on APUs for suspend to ram or s2idle */
|
||||
if ((adev->in_s3 || adev->in_s0ix) && (adev->flags & AMD_IS_APU))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM))
|
||||
ret = amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM);
|
||||
if (ret)
|
||||
DRM_WARN("evicting device resources failed\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4109,7 +4121,9 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
|
|||
if (!adev->in_s0ix)
|
||||
amdgpu_amdkfd_suspend(adev, adev->in_runpm);
|
||||
|
||||
amdgpu_device_evict_resources(adev);
|
||||
r = amdgpu_device_evict_resources(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_fence_driver_hw_fini(adev);
|
||||
|
||||
|
@ -4183,8 +4197,17 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
|||
}
|
||||
|
||||
/* Make sure IB tests flushed */
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
amdgpu_irq_gpu_reset_resume_helper(adev);
|
||||
flush_delayed_work(&adev->delayed_init_work);
|
||||
|
||||
if (adev->in_s0ix) {
|
||||
/* re-enable gfxoff after IP resume. This re-enables gfxoff after
|
||||
* it was disabled for IP resume in amdgpu_device_ip_resume_phase2().
|
||||
*/
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
DRM_DEBUG("will enable gfxoff for the mission mode\n");
|
||||
}
|
||||
if (fbcon)
|
||||
drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false);
|
||||
|
||||
|
@ -5381,7 +5404,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res);
|
||||
}
|
||||
|
||||
if (adev->enable_mes)
|
||||
if (adev->enable_mes && adev->ip_versions[GC_HWIP][0] != IP_VERSION(11, 0, 3))
|
||||
amdgpu_mes_self_test(tmp_adev);
|
||||
|
||||
if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled) {
|
||||
|
|
|
@ -2201,7 +2201,8 @@ amdgpu_pci_remove(struct pci_dev *pdev)
|
|||
pm_runtime_forbid(dev->dev);
|
||||
}
|
||||
|
||||
if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2)) {
|
||||
if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2) &&
|
||||
!amdgpu_sriov_vf(adev)) {
|
||||
bool need_to_reset_gpu = false;
|
||||
|
||||
if (adev->gmc.xgmi.num_physical_nodes > 1) {
|
||||
|
|
|
@ -542,6 +542,7 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
|
|||
case IP_VERSION(10, 3, 1):
|
||||
/* YELLOW_CARP*/
|
||||
case IP_VERSION(10, 3, 3):
|
||||
case IP_VERSION(11, 0, 1):
|
||||
/* Don't enable it by default yet.
|
||||
*/
|
||||
if (amdgpu_tmz < 1) {
|
||||
|
|
|
@ -337,11 +337,17 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
|
|||
fw_info->feature = adev->psp.cap_feature_version;
|
||||
break;
|
||||
case AMDGPU_INFO_FW_MES_KIQ:
|
||||
fw_info->ver = adev->mes.ucode_fw_version[0];
|
||||
fw_info->feature = 0;
|
||||
fw_info->ver = adev->mes.kiq_version & AMDGPU_MES_VERSION_MASK;
|
||||
fw_info->feature = (adev->mes.kiq_version & AMDGPU_MES_FEAT_VERSION_MASK)
|
||||
>> AMDGPU_MES_FEAT_VERSION_SHIFT;
|
||||
break;
|
||||
case AMDGPU_INFO_FW_MES:
|
||||
fw_info->ver = adev->mes.ucode_fw_version[1];
|
||||
fw_info->ver = adev->mes.sched_version & AMDGPU_MES_VERSION_MASK;
|
||||
fw_info->feature = (adev->mes.sched_version & AMDGPU_MES_FEAT_VERSION_MASK)
|
||||
>> AMDGPU_MES_FEAT_VERSION_SHIFT;
|
||||
break;
|
||||
case AMDGPU_INFO_FW_IMU:
|
||||
fw_info->ver = adev->gfx.imu_fw_version;
|
||||
fw_info->feature = 0;
|
||||
break;
|
||||
default:
|
||||
|
@ -790,7 +796,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|||
dev_info->ids_flags = 0;
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
dev_info->ids_flags |= AMDGPU_IDS_FLAGS_FUSION;
|
||||
if (amdgpu_mcbp || amdgpu_sriov_vf(adev))
|
||||
if (amdgpu_mcbp)
|
||||
dev_info->ids_flags |= AMDGPU_IDS_FLAGS_PREEMPTION;
|
||||
if (amdgpu_is_tmz(adev))
|
||||
dev_info->ids_flags |= AMDGPU_IDS_FLAGS_TMZ;
|
||||
|
@ -1166,7 +1172,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
|
|||
goto error_vm;
|
||||
}
|
||||
|
||||
if (amdgpu_mcbp || amdgpu_sriov_vf(adev)) {
|
||||
if (amdgpu_mcbp) {
|
||||
uint64_t csa_addr = amdgpu_csa_vaddr(adev) & AMDGPU_GMC_HOLE_MASK;
|
||||
|
||||
r = amdgpu_map_static_csa(adev, &fpriv->vm, adev->virt.csa_obj,
|
||||
|
@ -1230,7 +1236,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
|
|||
if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_VCE) != NULL)
|
||||
amdgpu_vce_free_handles(adev, file_priv);
|
||||
|
||||
if (amdgpu_mcbp || amdgpu_sriov_vf(adev)) {
|
||||
if (amdgpu_mcbp) {
|
||||
/* TODO: how to handle reserve failure */
|
||||
BUG_ON(amdgpu_bo_reserve(adev->virt.csa_obj, true));
|
||||
amdgpu_vm_bo_del(adev, fpriv->csa_va);
|
||||
|
@ -1520,6 +1526,15 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
|
|||
fw_info.feature, fw_info.ver);
|
||||
}
|
||||
|
||||
/* IMU */
|
||||
query_fw.fw_type = AMDGPU_INFO_FW_IMU;
|
||||
query_fw.index = 0;
|
||||
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
seq_printf(m, "IMU feature version: %u, firmware version: 0x%08x\n",
|
||||
fw_info.feature, fw_info.ver);
|
||||
|
||||
/* PSP SOS */
|
||||
query_fw.fw_type = AMDGPU_INFO_FW_SOS;
|
||||
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
|
||||
|
|
|
@ -91,14 +91,12 @@ struct amdgpu_mes {
|
|||
struct amdgpu_bo *ucode_fw_obj[AMDGPU_MAX_MES_PIPES];
|
||||
uint64_t ucode_fw_gpu_addr[AMDGPU_MAX_MES_PIPES];
|
||||
uint32_t *ucode_fw_ptr[AMDGPU_MAX_MES_PIPES];
|
||||
uint32_t ucode_fw_version[AMDGPU_MAX_MES_PIPES];
|
||||
uint64_t uc_start_addr[AMDGPU_MAX_MES_PIPES];
|
||||
|
||||
/* mes ucode data */
|
||||
struct amdgpu_bo *data_fw_obj[AMDGPU_MAX_MES_PIPES];
|
||||
uint64_t data_fw_gpu_addr[AMDGPU_MAX_MES_PIPES];
|
||||
uint32_t *data_fw_ptr[AMDGPU_MAX_MES_PIPES];
|
||||
uint32_t data_fw_version[AMDGPU_MAX_MES_PIPES];
|
||||
uint64_t data_start_addr[AMDGPU_MAX_MES_PIPES];
|
||||
|
||||
/* eop gpu obj */
|
||||
|
|
|
@ -988,6 +988,8 @@ int psp_ta_unload(struct psp_context *psp, struct ta_context *context)
|
|||
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
|
||||
|
||||
context->resp_status = cmd->resp.status;
|
||||
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
|
@ -1069,42 +1071,6 @@ int psp_ta_init_shared_buf(struct psp_context *psp,
|
|||
&mem_ctx->shared_buf);
|
||||
}
|
||||
|
||||
static void psp_prep_ta_invoke_indirect_cmd_buf(struct psp_gfx_cmd_resp *cmd,
|
||||
uint32_t ta_cmd_id,
|
||||
struct ta_context *context)
|
||||
{
|
||||
cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD;
|
||||
cmd->cmd.cmd_invoke_cmd.session_id = context->session_id;
|
||||
cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id;
|
||||
|
||||
cmd->cmd.cmd_invoke_cmd.buf.num_desc = 1;
|
||||
cmd->cmd.cmd_invoke_cmd.buf.total_size = context->mem_context.shared_mem_size;
|
||||
cmd->cmd.cmd_invoke_cmd.buf.buf_desc[0].buf_size = context->mem_context.shared_mem_size;
|
||||
cmd->cmd.cmd_invoke_cmd.buf.buf_desc[0].buf_phy_addr_lo =
|
||||
lower_32_bits(context->mem_context.shared_mc_addr);
|
||||
cmd->cmd.cmd_invoke_cmd.buf.buf_desc[0].buf_phy_addr_hi =
|
||||
upper_32_bits(context->mem_context.shared_mc_addr);
|
||||
}
|
||||
|
||||
int psp_ta_invoke_indirect(struct psp_context *psp,
|
||||
uint32_t ta_cmd_id,
|
||||
struct ta_context *context)
|
||||
{
|
||||
int ret;
|
||||
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_ta_invoke_indirect_cmd_buf(cmd, ta_cmd_id, context);
|
||||
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd,
|
||||
psp->fence_buf_mc_addr);
|
||||
|
||||
context->resp_status = cmd->resp.status;
|
||||
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void psp_prep_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd,
|
||||
uint32_t ta_cmd_id,
|
||||
uint32_t session_id)
|
||||
|
@ -1547,7 +1513,7 @@ int psp_ras_terminate(struct psp_context *psp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int psp_ras_initialize(struct psp_context *psp)
|
||||
int psp_ras_initialize(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
uint32_t boot_cfg = 0xFF;
|
||||
|
@ -1560,6 +1526,11 @@ static int psp_ras_initialize(struct psp_context *psp)
|
|||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
if (psp->ras_context.context.initialized) {
|
||||
dev_warn(adev->dev, "RAS WARN: TA has already been loaded\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!adev->psp.ras_context.context.bin_desc.size_bytes ||
|
||||
!adev->psp.ras_context.context.bin_desc.start_addr) {
|
||||
dev_info(adev->dev, "RAS: optional ras ta ucode is not available\n");
|
||||
|
@ -1610,7 +1581,7 @@ static int psp_ras_initialize(struct psp_context *psp)
|
|||
psp->ras_context.context.mem_context.shared_mem_size = PSP_RAS_SHARED_MEM_SIZE;
|
||||
psp->ras_context.context.ta_load_type = GFX_CMD_ID_LOAD_TA;
|
||||
|
||||
if (!psp->ras_context.context.initialized) {
|
||||
if (!psp->ras_context.context.mem_context.shared_buf) {
|
||||
ret = psp_ta_init_shared_buf(psp, &psp->ras_context.context.mem_context);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -1631,7 +1602,6 @@ static int psp_ras_initialize(struct psp_context *psp)
|
|||
else {
|
||||
if (ras_cmd->ras_status)
|
||||
dev_warn(psp->adev->dev, "RAS Init Status: 0x%X\n", ras_cmd->ras_status);
|
||||
amdgpu_ras_fini(psp->adev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -1938,10 +1908,15 @@ static int psp_securedisplay_initialize(struct psp_context *psp)
|
|||
} else
|
||||
return ret;
|
||||
|
||||
mutex_lock(&psp->securedisplay_context.mutex);
|
||||
|
||||
psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,
|
||||
TA_SECUREDISPLAY_COMMAND__QUERY_TA);
|
||||
|
||||
ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__QUERY_TA);
|
||||
|
||||
mutex_unlock(&psp->securedisplay_context.mutex);
|
||||
|
||||
if (ret) {
|
||||
psp_securedisplay_terminate(psp);
|
||||
/* free securedisplay shared memory */
|
||||
|
@ -1990,12 +1965,8 @@ int psp_securedisplay_invoke(struct psp_context *psp, uint32_t ta_cmd_id)
|
|||
ta_cmd_id != TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&psp->securedisplay_context.mutex);
|
||||
|
||||
ret = psp_ta_invoke(psp, ta_cmd_id, &psp->securedisplay_context.context);
|
||||
|
||||
mutex_unlock(&psp->securedisplay_context.mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* SECUREDISPLAY end */
|
||||
|
|
|
@ -136,6 +136,12 @@ struct psp_funcs
|
|||
int (*vbflash_stat)(struct psp_context *psp);
|
||||
};
|
||||
|
||||
struct ta_funcs {
|
||||
int (*fn_ta_initialize)(struct psp_context *psp);
|
||||
int (*fn_ta_invoke)(struct psp_context *psp, uint32_t ta_cmd_id);
|
||||
int (*fn_ta_terminate)(struct psp_context *psp);
|
||||
};
|
||||
|
||||
#define AMDGPU_XGMI_MAX_CONNECTED_NODES 64
|
||||
struct psp_xgmi_node_info {
|
||||
uint64_t node_id;
|
||||
|
@ -309,6 +315,7 @@ struct psp_context
|
|||
struct psp_gfx_cmd_resp *cmd;
|
||||
|
||||
const struct psp_funcs *funcs;
|
||||
const struct ta_funcs *ta_funcs;
|
||||
|
||||
/* firmware buffer */
|
||||
struct amdgpu_bo *fw_pri_bo;
|
||||
|
@ -463,9 +470,6 @@ int psp_ta_load(struct psp_context *psp, struct ta_context *context);
|
|||
int psp_ta_invoke(struct psp_context *psp,
|
||||
uint32_t ta_cmd_id,
|
||||
struct ta_context *context);
|
||||
int psp_ta_invoke_indirect(struct psp_context *psp,
|
||||
uint32_t ta_cmd_id,
|
||||
struct ta_context *context);
|
||||
|
||||
int psp_xgmi_initialize(struct psp_context *psp, bool set_extended_data, bool load_ta);
|
||||
int psp_xgmi_terminate(struct psp_context *psp);
|
||||
|
@ -479,7 +483,7 @@ int psp_xgmi_get_topology_info(struct psp_context *psp,
|
|||
int psp_xgmi_set_topology_info(struct psp_context *psp,
|
||||
int number_devices,
|
||||
struct psp_xgmi_topology_info *topology);
|
||||
|
||||
int psp_ras_initialize(struct psp_context *psp);
|
||||
int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id);
|
||||
int psp_ras_enable_features(struct psp_context *psp,
|
||||
union ta_ras_cmd_input *info, bool enable);
|
||||
|
|
|
@ -41,30 +41,46 @@ static uint32_t get_bin_version(const uint8_t *bin)
|
|||
return hdr->ucode_version;
|
||||
}
|
||||
|
||||
static void prep_ta_mem_context(struct psp_context *psp,
|
||||
struct ta_context *context,
|
||||
static int prep_ta_mem_context(struct ta_mem_context *mem_context,
|
||||
uint8_t *shared_buf,
|
||||
uint32_t shared_buf_len)
|
||||
{
|
||||
context->mem_context.shared_mem_size = PAGE_ALIGN(shared_buf_len);
|
||||
psp_ta_init_shared_buf(psp, &context->mem_context);
|
||||
if (mem_context->shared_mem_size < shared_buf_len)
|
||||
return -EINVAL;
|
||||
memset(mem_context->shared_buf, 0, mem_context->shared_mem_size);
|
||||
memcpy((void *)mem_context->shared_buf, shared_buf, shared_buf_len);
|
||||
|
||||
memcpy((void *)context->mem_context.shared_buf, shared_buf, shared_buf_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_ta_type_valid(enum ta_type_id ta_type)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
switch (ta_type) {
|
||||
case TA_TYPE_RAS:
|
||||
ret = true;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct ta_funcs ras_ta_funcs = {
|
||||
.fn_ta_initialize = psp_ras_initialize,
|
||||
.fn_ta_invoke = psp_ras_invoke,
|
||||
.fn_ta_terminate = psp_ras_terminate
|
||||
};
|
||||
|
||||
static void set_ta_context_funcs(struct psp_context *psp,
|
||||
enum ta_type_id ta_type,
|
||||
struct ta_context **pcontext)
|
||||
{
|
||||
switch (ta_type) {
|
||||
case TA_TYPE_RAS:
|
||||
*pcontext = &psp->ras_context.context;
|
||||
psp->ta_funcs = &ras_ta_funcs;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations ta_load_debugfs_fops = {
|
||||
|
@ -85,8 +101,7 @@ static const struct file_operations ta_invoke_debugfs_fops = {
|
|||
.owner = THIS_MODULE
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* DOC: AMDGPU TA debugfs interfaces
|
||||
*
|
||||
* Three debugfs interfaces can be opened by a program to
|
||||
|
@ -111,15 +126,18 @@ static const struct file_operations ta_invoke_debugfs_fops = {
|
|||
*
|
||||
* - For TA invoke debugfs interface:
|
||||
* Transmit buffer:
|
||||
* - TA type (4bytes)
|
||||
* - TA ID (4bytes)
|
||||
* - TA CMD ID (4bytes)
|
||||
* - TA shard buf length (4bytes)
|
||||
* - TA shard buf length
|
||||
* (4bytes, value not beyond TA shared memory size)
|
||||
* - TA shared buf
|
||||
* Receive buffer:
|
||||
* - TA shared buf
|
||||
*
|
||||
* - For TA unload debugfs interface:
|
||||
* Transmit buffer:
|
||||
* - TA type (4bytes)
|
||||
* - TA ID (4bytes)
|
||||
*/
|
||||
|
||||
|
@ -131,59 +149,92 @@ static ssize_t ta_if_load_debugfs_write(struct file *fp, const char *buf, size_t
|
|||
uint32_t copy_pos = 0;
|
||||
int ret = 0;
|
||||
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(fp)->i_private;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
struct ta_context context = {0};
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(fp)->i_private;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
struct ta_context *context = NULL;
|
||||
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
|
||||
ret = copy_from_user((void *)&ta_type, &buf[copy_pos], sizeof(uint32_t));
|
||||
if (ret || (!is_ta_type_valid(ta_type)))
|
||||
return -EINVAL;
|
||||
return -EFAULT;
|
||||
|
||||
copy_pos += sizeof(uint32_t);
|
||||
|
||||
ret = copy_from_user((void *)&ta_bin_len, &buf[copy_pos], sizeof(uint32_t));
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
return -EFAULT;
|
||||
|
||||
copy_pos += sizeof(uint32_t);
|
||||
|
||||
ta_bin = kzalloc(ta_bin_len, GFP_KERNEL);
|
||||
if (!ta_bin)
|
||||
ret = -ENOMEM;
|
||||
return -ENOMEM;
|
||||
if (copy_from_user((void *)ta_bin, &buf[copy_pos], ta_bin_len)) {
|
||||
ret = -EFAULT;
|
||||
goto err_free_bin;
|
||||
}
|
||||
|
||||
ret = psp_ras_terminate(psp);
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "Failed to unload embedded RAS TA\n");
|
||||
/* Set TA context and functions */
|
||||
set_ta_context_funcs(psp, ta_type, &context);
|
||||
|
||||
if (!psp->ta_funcs || !psp->ta_funcs->fn_ta_terminate) {
|
||||
dev_err(adev->dev, "Unsupported function to terminate TA\n");
|
||||
ret = -EOPNOTSUPP;
|
||||
goto err_free_bin;
|
||||
}
|
||||
|
||||
context.ta_type = ta_type;
|
||||
context.ta_load_type = GFX_CMD_ID_LOAD_TA;
|
||||
context.bin_desc.fw_version = get_bin_version(ta_bin);
|
||||
context.bin_desc.size_bytes = ta_bin_len;
|
||||
context.bin_desc.start_addr = ta_bin;
|
||||
/*
|
||||
* Allocate TA shared buf in case shared buf was freed
|
||||
* due to loading TA failed before.
|
||||
*/
|
||||
if (!context->mem_context.shared_buf) {
|
||||
ret = psp_ta_init_shared_buf(psp, &context->mem_context);
|
||||
if (ret) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_bin;
|
||||
}
|
||||
}
|
||||
|
||||
ret = psp_ta_load(psp, &context);
|
||||
|
||||
if (ret || context.resp_status) {
|
||||
dev_err(adev->dev, "TA load via debugfs failed (%d) status %d\n",
|
||||
ret, context.resp_status);
|
||||
ret = psp_fn_ta_terminate(psp);
|
||||
if (ret || context->resp_status) {
|
||||
dev_err(adev->dev,
|
||||
"Failed to unload embedded TA (%d) and status (0x%X)\n",
|
||||
ret, context->resp_status);
|
||||
if (!ret)
|
||||
ret = -EINVAL;
|
||||
goto err_free_bin;
|
||||
goto err_free_ta_shared_buf;
|
||||
}
|
||||
|
||||
context.initialized = true;
|
||||
if (copy_to_user((char *)buf, (void *)&context.session_id, sizeof(uint32_t)))
|
||||
/* Prepare TA context for TA initialization */
|
||||
context->ta_type = ta_type;
|
||||
context->bin_desc.fw_version = get_bin_version(ta_bin);
|
||||
context->bin_desc.size_bytes = ta_bin_len;
|
||||
context->bin_desc.start_addr = ta_bin;
|
||||
|
||||
if (!psp->ta_funcs->fn_ta_initialize) {
|
||||
dev_err(adev->dev, "Unsupported function to initialize TA\n");
|
||||
ret = -EOPNOTSUPP;
|
||||
goto err_free_ta_shared_buf;
|
||||
}
|
||||
|
||||
ret = psp_fn_ta_initialize(psp);
|
||||
if (ret || context->resp_status) {
|
||||
dev_err(adev->dev, "Failed to load TA via debugfs (%d) and status (0x%X)\n",
|
||||
ret, context->resp_status);
|
||||
if (!ret)
|
||||
ret = -EINVAL;
|
||||
goto err_free_ta_shared_buf;
|
||||
}
|
||||
|
||||
if (copy_to_user((char *)buf, (void *)&context->session_id, sizeof(uint32_t)))
|
||||
ret = -EFAULT;
|
||||
|
||||
err_free_ta_shared_buf:
|
||||
/* Only free TA shared buf when returns error code */
|
||||
if (ret && context->mem_context.shared_buf)
|
||||
psp_ta_free_shared_buf(&context->mem_context);
|
||||
err_free_bin:
|
||||
kfree(ta_bin);
|
||||
|
||||
|
@ -192,58 +243,85 @@ static ssize_t ta_if_load_debugfs_write(struct file *fp, const char *buf, size_t
|
|||
|
||||
static ssize_t ta_if_unload_debugfs_write(struct file *fp, const char *buf, size_t len, loff_t *off)
|
||||
{
|
||||
uint32_t ta_id = 0;
|
||||
int ret = 0;
|
||||
uint32_t ta_type = 0;
|
||||
uint32_t ta_id = 0;
|
||||
uint32_t copy_pos = 0;
|
||||
int ret = 0;
|
||||
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(fp)->i_private;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
struct ta_context context = {0};
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(fp)->i_private;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
struct ta_context *context = NULL;
|
||||
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
|
||||
ret = copy_from_user((void *)&ta_id, buf, sizeof(uint32_t));
|
||||
ret = copy_from_user((void *)&ta_type, &buf[copy_pos], sizeof(uint32_t));
|
||||
if (ret || (!is_ta_type_valid(ta_type)))
|
||||
return -EFAULT;
|
||||
|
||||
copy_pos += sizeof(uint32_t);
|
||||
|
||||
ret = copy_from_user((void *)&ta_id, &buf[copy_pos], sizeof(uint32_t));
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
return -EFAULT;
|
||||
|
||||
context.session_id = ta_id;
|
||||
set_ta_context_funcs(psp, ta_type, &context);
|
||||
context->session_id = ta_id;
|
||||
|
||||
ret = psp_ta_unload(psp, &context);
|
||||
if (!ret)
|
||||
context.initialized = false;
|
||||
if (!psp->ta_funcs || !psp->ta_funcs->fn_ta_terminate) {
|
||||
dev_err(adev->dev, "Unsupported function to terminate TA\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
ret = psp_fn_ta_terminate(psp);
|
||||
if (ret || context->resp_status) {
|
||||
dev_err(adev->dev, "Failed to unload TA via debugfs (%d) and status (0x%X)\n",
|
||||
ret, context->resp_status);
|
||||
if (!ret)
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
if (context->mem_context.shared_buf)
|
||||
psp_ta_free_shared_buf(&context->mem_context);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size_t len, loff_t *off)
|
||||
{
|
||||
uint32_t ta_type = 0;
|
||||
uint32_t ta_id = 0;
|
||||
uint32_t cmd_id = 0;
|
||||
uint32_t shared_buf_len = 0;
|
||||
uint8_t *shared_buf = NULL;
|
||||
uint8_t *shared_buf = NULL;
|
||||
uint32_t copy_pos = 0;
|
||||
int ret = 0;
|
||||
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(fp)->i_private;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
struct ta_context context = {0};
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(fp)->i_private;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
struct ta_context *context = NULL;
|
||||
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
|
||||
ret = copy_from_user((void *)&ta_type, &buf[copy_pos], sizeof(uint32_t));
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
copy_pos += sizeof(uint32_t);
|
||||
|
||||
ret = copy_from_user((void *)&ta_id, &buf[copy_pos], sizeof(uint32_t));
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
return -EFAULT;
|
||||
copy_pos += sizeof(uint32_t);
|
||||
|
||||
ret = copy_from_user((void *)&cmd_id, &buf[copy_pos], sizeof(uint32_t));
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
return -EFAULT;
|
||||
copy_pos += sizeof(uint32_t);
|
||||
|
||||
ret = copy_from_user((void *)&shared_buf_len, &buf[copy_pos], sizeof(uint32_t));
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
return -EFAULT;
|
||||
copy_pos += sizeof(uint32_t);
|
||||
|
||||
shared_buf = kzalloc(shared_buf_len, GFP_KERNEL);
|
||||
|
@ -254,25 +332,38 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size
|
|||
goto err_free_shared_buf;
|
||||
}
|
||||
|
||||
context.session_id = ta_id;
|
||||
set_ta_context_funcs(psp, ta_type, &context);
|
||||
|
||||
prep_ta_mem_context(psp, &context, shared_buf, shared_buf_len);
|
||||
|
||||
ret = psp_ta_invoke_indirect(psp, cmd_id, &context);
|
||||
|
||||
if (ret || context.resp_status) {
|
||||
dev_err(adev->dev, "TA invoke via debugfs failed (%d) status %d\n",
|
||||
ret, context.resp_status);
|
||||
if (!ret)
|
||||
ret = -EINVAL;
|
||||
goto err_free_ta_shared_buf;
|
||||
if (!context->initialized) {
|
||||
dev_err(adev->dev, "TA is not initialized\n");
|
||||
ret = -EINVAL;
|
||||
goto err_free_shared_buf;
|
||||
}
|
||||
|
||||
if (copy_to_user((char *)buf, context.mem_context.shared_buf, shared_buf_len))
|
||||
ret = -EFAULT;
|
||||
if (!psp->ta_funcs || !psp->ta_funcs->fn_ta_invoke) {
|
||||
dev_err(adev->dev, "Unsupported function to invoke TA\n");
|
||||
ret = -EOPNOTSUPP;
|
||||
goto err_free_shared_buf;
|
||||
}
|
||||
|
||||
err_free_ta_shared_buf:
|
||||
psp_ta_free_shared_buf(&context.mem_context);
|
||||
context->session_id = ta_id;
|
||||
|
||||
ret = prep_ta_mem_context(&context->mem_context, shared_buf, shared_buf_len);
|
||||
if (ret)
|
||||
goto err_free_shared_buf;
|
||||
|
||||
ret = psp_fn_ta_invoke(psp, cmd_id);
|
||||
if (ret || context->resp_status) {
|
||||
dev_err(adev->dev, "Failed to invoke TA via debugfs (%d) and status (0x%X)\n",
|
||||
ret, context->resp_status);
|
||||
if (!ret) {
|
||||
ret = -EINVAL;
|
||||
goto err_free_shared_buf;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy_to_user((char *)buf, context->mem_context.shared_buf, shared_buf_len))
|
||||
ret = -EFAULT;
|
||||
|
||||
err_free_shared_buf:
|
||||
kfree(shared_buf);
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
#ifndef __AMDGPU_PSP_TA_H__
|
||||
#define __AMDGPU_PSP_TA_H__
|
||||
|
||||
/* Calling set_ta_context_funcs is required before using the following macros */
|
||||
#define psp_fn_ta_initialize(psp) ((psp)->ta_funcs->fn_ta_initialize((psp)))
|
||||
#define psp_fn_ta_invoke(psp, ta_cmd_id) ((psp)->ta_funcs->fn_ta_invoke((psp), (ta_cmd_id)))
|
||||
#define psp_fn_ta_terminate(psp) ((psp)->ta_funcs->fn_ta_terminate((psp)))
|
||||
|
||||
void amdgpu_ta_if_debugfs_init(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1561,7 +1561,6 @@ static void amdgpu_ras_interrupt_poison_consumption_handler(struct ras_manager *
|
|||
{
|
||||
bool poison_stat = false;
|
||||
struct amdgpu_device *adev = obj->adev;
|
||||
struct ras_err_data err_data = {0, 0, 0, NULL};
|
||||
struct amdgpu_ras_block_object *block_obj =
|
||||
amdgpu_ras_get_ras_block(adev, obj->head.block, 0);
|
||||
|
||||
|
@ -1584,7 +1583,7 @@ static void amdgpu_ras_interrupt_poison_consumption_handler(struct ras_manager *
|
|||
}
|
||||
|
||||
if (!adev->gmc.xgmi.connected_to_cpu)
|
||||
amdgpu_umc_poison_handler(adev, &err_data, false);
|
||||
amdgpu_umc_poison_handler(adev, false);
|
||||
|
||||
if (block_obj->hw_ops->handle_poison_consumption)
|
||||
poison_stat = block_obj->hw_ops->handle_poison_consumption(adev);
|
||||
|
@ -2848,7 +2847,6 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
|
|||
struct amdgpu_device *adev = NULL;
|
||||
uint32_t gpu_id = 0;
|
||||
uint32_t umc_inst = 0, ch_inst = 0;
|
||||
struct ras_err_data err_data = {0, 0, 0, NULL};
|
||||
|
||||
/*
|
||||
* If the error was generated in UMC_V2, which belongs to GPU UMCs,
|
||||
|
@ -2887,31 +2885,10 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
|
|||
dev_info(adev->dev, "Uncorrectable error detected in UMC inst: %d, chan_idx: %d",
|
||||
umc_inst, ch_inst);
|
||||
|
||||
err_data.err_addr =
|
||||
kcalloc(adev->umc.max_ras_err_cnt_per_query,
|
||||
sizeof(struct eeprom_table_record), GFP_KERNEL);
|
||||
if (!err_data.err_addr) {
|
||||
dev_warn(adev->dev,
|
||||
"Failed to alloc memory for umc error record in mca notifier!\n");
|
||||
if (!amdgpu_umc_page_retirement_mca(adev, m->addr, ch_inst, umc_inst))
|
||||
return NOTIFY_OK;
|
||||
else
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate UMC channel address to Physical address
|
||||
*/
|
||||
if (adev->umc.ras &&
|
||||
adev->umc.ras->convert_ras_error_address)
|
||||
adev->umc.ras->convert_ras_error_address(adev,
|
||||
&err_data, m->addr, ch_inst, umc_inst);
|
||||
|
||||
if (amdgpu_bad_page_threshold != 0) {
|
||||
amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
|
||||
err_data.err_addr_cnt);
|
||||
amdgpu_ras_save_bad_pages(adev);
|
||||
}
|
||||
|
||||
kfree(err_data.err_addr);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block amdgpu_bad_page_nb = {
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#define EEPROM_I2C_MADDR_ARCTURUS_D342 0x0
|
||||
#define EEPROM_I2C_MADDR_SIENNA_CICHLID 0x0
|
||||
#define EEPROM_I2C_MADDR_ALDEBARAN 0x0
|
||||
#define EEPROM_I2C_MADDR_SMU_13_0_0 (0x54UL << 16)
|
||||
#define EEPROM_I2C_MADDR_54H (0x54UL << 16)
|
||||
|
||||
/*
|
||||
* The 2 macros bellow represent the actual size in bytes that
|
||||
|
@ -90,6 +90,16 @@
|
|||
|
||||
static bool __is_ras_eeprom_supported(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->asic_type == CHIP_IP_DISCOVERY) {
|
||||
switch (adev->ip_versions[MP1_HWIP][0]) {
|
||||
case IP_VERSION(13, 0, 0):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return adev->asic_type == CHIP_VEGA20 ||
|
||||
adev->asic_type == CHIP_ARCTURUS ||
|
||||
adev->asic_type == CHIP_SIENNA_CICHLID ||
|
||||
|
@ -114,6 +124,19 @@ static bool __get_eeprom_i2c_addr_arct(struct amdgpu_device *adev,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool __get_eeprom_i2c_addr_ip_discovery(struct amdgpu_device *adev,
|
||||
struct amdgpu_ras_eeprom_control *control)
|
||||
{
|
||||
switch (adev->ip_versions[MP1_HWIP][0]) {
|
||||
case IP_VERSION(13, 0, 0):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
control->i2c_address = EEPROM_I2C_MADDR_54H;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev,
|
||||
struct amdgpu_ras_eeprom_control *control)
|
||||
{
|
||||
|
@ -153,13 +176,16 @@ static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev,
|
|||
control->i2c_address = EEPROM_I2C_MADDR_ALDEBARAN;
|
||||
break;
|
||||
|
||||
case CHIP_IP_DISCOVERY:
|
||||
return __get_eeprom_i2c_addr_ip_discovery(adev, control);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (adev->ip_versions[MP1_HWIP][0]) {
|
||||
case IP_VERSION(13, 0, 0):
|
||||
control->i2c_address = EEPROM_I2C_MADDR_SMU_13_0_0;
|
||||
control->i2c_address = EEPROM_I2C_MADDR_54H;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -121,6 +121,7 @@ static ssize_t amdgpu_securedisplay_debugfs_write(struct file *f, const char __u
|
|||
|
||||
switch (op) {
|
||||
case 1:
|
||||
mutex_lock(&psp->securedisplay_context.mutex);
|
||||
psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,
|
||||
TA_SECUREDISPLAY_COMMAND__QUERY_TA);
|
||||
ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__QUERY_TA);
|
||||
|
@ -131,8 +132,10 @@ static ssize_t amdgpu_securedisplay_debugfs_write(struct file *f, const char __u
|
|||
else
|
||||
psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status);
|
||||
}
|
||||
mutex_unlock(&psp->securedisplay_context.mutex);
|
||||
break;
|
||||
case 2:
|
||||
mutex_lock(&psp->securedisplay_context.mutex);
|
||||
psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,
|
||||
TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC);
|
||||
securedisplay_cmd->securedisplay_in_message.send_roi_crc.phy_id = phy_id;
|
||||
|
@ -146,6 +149,7 @@ static ssize_t amdgpu_securedisplay_debugfs_write(struct file *f, const char __u
|
|||
psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&psp->securedisplay_context.mutex);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev, "Invalid input: %s\n", str);
|
||||
|
|
|
@ -2295,9 +2295,9 @@ static ssize_t amdgpu_iomem_read(struct file *f, char __user *buf,
|
|||
if (p->mapping != adev->mman.bdev.dev_mapping)
|
||||
return -EPERM;
|
||||
|
||||
ptr = kmap(p);
|
||||
ptr = kmap_local_page(p);
|
||||
r = copy_to_user(buf, ptr + off, bytes);
|
||||
kunmap(p);
|
||||
kunmap_local(ptr);
|
||||
if (r)
|
||||
return -EFAULT;
|
||||
|
||||
|
@ -2346,9 +2346,9 @@ static ssize_t amdgpu_iomem_write(struct file *f, const char __user *buf,
|
|||
if (p->mapping != adev->mman.bdev.dev_mapping)
|
||||
return -EPERM;
|
||||
|
||||
ptr = kmap(p);
|
||||
ptr = kmap_local_page(p);
|
||||
r = copy_from_user(ptr + off, buf, bytes);
|
||||
kunmap(p);
|
||||
kunmap_local(ptr);
|
||||
if (r)
|
||||
return -EFAULT;
|
||||
|
||||
|
|
|
@ -698,6 +698,7 @@ FW_VERSION_ATTR(rlc_srlg_fw_version, 0444, gfx.rlc_srlg_fw_version);
|
|||
FW_VERSION_ATTR(rlc_srls_fw_version, 0444, gfx.rlc_srls_fw_version);
|
||||
FW_VERSION_ATTR(mec_fw_version, 0444, gfx.mec_fw_version);
|
||||
FW_VERSION_ATTR(mec2_fw_version, 0444, gfx.mec2_fw_version);
|
||||
FW_VERSION_ATTR(imu_fw_version, 0444, gfx.imu_fw_version);
|
||||
FW_VERSION_ATTR(sos_fw_version, 0444, psp.sos.fw_version);
|
||||
FW_VERSION_ATTR(asd_fw_version, 0444, psp.asd_context.bin_desc.fw_version);
|
||||
FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ras_context.context.bin_desc.fw_version);
|
||||
|
@ -719,7 +720,8 @@ static struct attribute *fw_attrs[] = {
|
|||
&dev_attr_ta_ras_fw_version.attr, &dev_attr_ta_xgmi_fw_version.attr,
|
||||
&dev_attr_smc_fw_version.attr, &dev_attr_sdma_fw_version.attr,
|
||||
&dev_attr_sdma2_fw_version.attr, &dev_attr_vcn_fw_version.attr,
|
||||
&dev_attr_dmcu_fw_version.attr, NULL
|
||||
&dev_attr_dmcu_fw_version.attr, &dev_attr_imu_fw_version.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group fw_attr_group = {
|
||||
|
|
|
@ -125,6 +125,7 @@ enum psp_fw_type {
|
|||
PSP_FW_TYPE_PSP_INTF_DRV,
|
||||
PSP_FW_TYPE_PSP_DBG_DRV,
|
||||
PSP_FW_TYPE_PSP_RAS_DRV,
|
||||
PSP_FW_TYPE_MAX_INDEX,
|
||||
};
|
||||
|
||||
/* version_major=2, version_minor=0 */
|
||||
|
|
|
@ -22,6 +22,59 @@
|
|||
*/
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "umc_v6_7.h"
|
||||
|
||||
static int amdgpu_umc_convert_error_address(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data, uint64_t err_addr,
|
||||
uint32_t ch_inst, uint32_t umc_inst)
|
||||
{
|
||||
switch (adev->ip_versions[UMC_HWIP][0]) {
|
||||
case IP_VERSION(6, 7, 0):
|
||||
umc_v6_7_convert_error_address(adev,
|
||||
err_data, err_addr, ch_inst, umc_inst);
|
||||
break;
|
||||
default:
|
||||
dev_warn(adev->dev,
|
||||
"UMC address to Physical address translation is not supported\n");
|
||||
return AMDGPU_RAS_FAIL;
|
||||
}
|
||||
|
||||
return AMDGPU_RAS_SUCCESS;
|
||||
}
|
||||
|
||||
int amdgpu_umc_page_retirement_mca(struct amdgpu_device *adev,
|
||||
uint64_t err_addr, uint32_t ch_inst, uint32_t umc_inst)
|
||||
{
|
||||
struct ras_err_data err_data = {0, 0, 0, NULL};
|
||||
int ret = AMDGPU_RAS_FAIL;
|
||||
|
||||
err_data.err_addr =
|
||||
kcalloc(adev->umc.max_ras_err_cnt_per_query,
|
||||
sizeof(struct eeprom_table_record), GFP_KERNEL);
|
||||
if (!err_data.err_addr) {
|
||||
dev_warn(adev->dev,
|
||||
"Failed to alloc memory for umc error record in MCA notifier!\n");
|
||||
return AMDGPU_RAS_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate UMC channel address to Physical address
|
||||
*/
|
||||
ret = amdgpu_umc_convert_error_address(adev, &err_data, err_addr,
|
||||
ch_inst, umc_inst);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (amdgpu_bad_page_threshold != 0) {
|
||||
amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
|
||||
err_data.err_addr_cnt);
|
||||
amdgpu_ras_save_bad_pages(adev);
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(err_data.err_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
|
||||
void *ras_error_status,
|
||||
|
@ -112,23 +165,29 @@ static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
|
|||
return AMDGPU_RAS_SUCCESS;
|
||||
}
|
||||
|
||||
int amdgpu_umc_poison_handler(struct amdgpu_device *adev,
|
||||
void *ras_error_status,
|
||||
bool reset)
|
||||
int amdgpu_umc_poison_handler(struct amdgpu_device *adev, bool reset)
|
||||
{
|
||||
int ret;
|
||||
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
|
||||
struct ras_common_if head = {
|
||||
.block = AMDGPU_RAS_BLOCK__UMC,
|
||||
};
|
||||
struct ras_manager *obj = amdgpu_ras_find_obj(adev, &head);
|
||||
int ret = AMDGPU_RAS_SUCCESS;
|
||||
|
||||
ret =
|
||||
amdgpu_umc_do_page_retirement(adev, ras_error_status, NULL, reset);
|
||||
if (!adev->gmc.xgmi.connected_to_cpu) {
|
||||
struct ras_err_data err_data = {0, 0, 0, NULL};
|
||||
struct ras_common_if head = {
|
||||
.block = AMDGPU_RAS_BLOCK__UMC,
|
||||
};
|
||||
struct ras_manager *obj = amdgpu_ras_find_obj(adev, &head);
|
||||
|
||||
if (ret == AMDGPU_RAS_SUCCESS && obj) {
|
||||
obj->err_data.ue_count += err_data->ue_count;
|
||||
obj->err_data.ce_count += err_data->ce_count;
|
||||
ret = amdgpu_umc_do_page_retirement(adev, &err_data, NULL, reset);
|
||||
|
||||
if (ret == AMDGPU_RAS_SUCCESS && obj) {
|
||||
obj->err_data.ue_count += err_data.ue_count;
|
||||
obj->err_data.ce_count += err_data.ce_count;
|
||||
}
|
||||
} else if (reset) {
|
||||
/* MCA poison handler is only responsible for GPU reset,
|
||||
* let MCA notifier do page retirement.
|
||||
*/
|
||||
kgd2kfd_set_sram_ecc_flag(adev->kfd.dev);
|
||||
amdgpu_ras_reset_gpu(adev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -51,9 +51,6 @@ struct amdgpu_umc_ras {
|
|||
struct amdgpu_ras_block_object ras_block;
|
||||
void (*err_cnt_init)(struct amdgpu_device *adev);
|
||||
bool (*query_ras_poison_mode)(struct amdgpu_device *adev);
|
||||
void (*convert_ras_error_address)(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data, uint64_t err_addr,
|
||||
uint32_t ch_inst, uint32_t umc_inst);
|
||||
void (*ecc_info_query_ras_error_count)(struct amdgpu_device *adev,
|
||||
void *ras_error_status);
|
||||
void (*ecc_info_query_ras_error_address)(struct amdgpu_device *adev,
|
||||
|
@ -86,9 +83,7 @@ struct amdgpu_umc {
|
|||
};
|
||||
|
||||
int amdgpu_umc_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
|
||||
int amdgpu_umc_poison_handler(struct amdgpu_device *adev,
|
||||
void *ras_error_status,
|
||||
bool reset);
|
||||
int amdgpu_umc_poison_handler(struct amdgpu_device *adev, bool reset);
|
||||
int amdgpu_umc_process_ecc_irq(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry);
|
||||
|
@ -101,4 +96,6 @@ void amdgpu_umc_fill_error_record(struct ras_err_data *err_data,
|
|||
int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev,
|
||||
void *ras_error_status,
|
||||
struct amdgpu_iv_entry *entry);
|
||||
int amdgpu_umc_page_retirement_mca(struct amdgpu_device *adev,
|
||||
uint64_t err_addr, uint32_t ch_inst, uint32_t umc_inst);
|
||||
#endif
|
||||
|
|
|
@ -64,6 +64,10 @@ void amdgpu_virt_init_setting(struct amdgpu_device *adev)
|
|||
ddev->driver_features &= ~DRIVER_ATOMIC;
|
||||
adev->cg_flags = 0;
|
||||
adev->pg_flags = 0;
|
||||
|
||||
/* enable mcbp for sriov asic_type before soc21 */
|
||||
amdgpu_mcbp = (adev->asic_type < CHIP_IP_DISCOVERY) ? 1 : 0;
|
||||
|
||||
}
|
||||
|
||||
void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
|
||||
|
@ -547,6 +551,7 @@ static void amdgpu_virt_populate_vf2pf_ucode_info(struct amdgpu_device *adev)
|
|||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_RLC_SRLS, adev->gfx.rlc_srls_fw_version);
|
||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_MEC, adev->gfx.mec_fw_version);
|
||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_MEC2, adev->gfx.mec2_fw_version);
|
||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_IMU, adev->gfx.imu_fw_version);
|
||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SOS, adev->psp.sos.fw_version);
|
||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_ASD,
|
||||
adev->psp.asd_context.bin_desc.fw_version);
|
||||
|
|
|
@ -75,6 +75,8 @@ struct amdgpu_vf_error_buffer {
|
|||
uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE];
|
||||
};
|
||||
|
||||
enum idh_request;
|
||||
|
||||
/**
|
||||
* struct amdgpu_virt_ops - amdgpu device virt operations
|
||||
*/
|
||||
|
@ -84,7 +86,8 @@ struct amdgpu_virt_ops {
|
|||
int (*req_init_data)(struct amdgpu_device *adev);
|
||||
int (*reset_gpu)(struct amdgpu_device *adev);
|
||||
int (*wait_reset)(struct amdgpu_device *adev);
|
||||
void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3);
|
||||
void (*trans_msg)(struct amdgpu_device *adev, enum idh_request req,
|
||||
u32 data1, u32 data2, u32 data3);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -498,6 +498,8 @@ static int amdgpu_vkms_sw_init(void *handle)
|
|||
adev_to_drm(adev)->mode_config.preferred_depth = 24;
|
||||
adev_to_drm(adev)->mode_config.prefer_shadow = 1;
|
||||
|
||||
adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
|
||||
|
||||
r = amdgpu_display_modeset_create_props(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
|
|
@ -70,6 +70,7 @@ enum amd_sriov_ucode_engine_id {
|
|||
AMD_SRIOV_UCODE_ID_RLC_SRLS,
|
||||
AMD_SRIOV_UCODE_ID_MEC,
|
||||
AMD_SRIOV_UCODE_ID_MEC2,
|
||||
AMD_SRIOV_UCODE_ID_IMU,
|
||||
AMD_SRIOV_UCODE_ID_SOS,
|
||||
AMD_SRIOV_UCODE_ID_ASD,
|
||||
AMD_SRIOV_UCODE_ID_TA_RAS,
|
||||
|
|
|
@ -2081,8 +2081,11 @@ amdgpu_atombios_encoder_get_lcd_info(struct amdgpu_encoder *encoder)
|
|||
}
|
||||
}
|
||||
record += fake_edid_record->ucFakeEDIDLength ?
|
||||
fake_edid_record->ucFakeEDIDLength + 2 :
|
||||
sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
|
||||
struct_size(fake_edid_record,
|
||||
ucFakeEDIDString,
|
||||
fake_edid_record->ucFakeEDIDLength) :
|
||||
/* empty fake edid record must be 3 bytes long */
|
||||
sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
|
||||
break;
|
||||
case LCD_PANEL_RESOLUTION_RECORD_TYPE:
|
||||
panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
|
||||
|
|
|
@ -4453,8 +4453,6 @@ static void gfx_v10_0_gpu_early_init(struct amdgpu_device *adev)
|
|||
{
|
||||
u32 gb_addr_config;
|
||||
|
||||
adev->gfx.funcs = &gfx_v10_0_gfx_funcs;
|
||||
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(10, 1, 10):
|
||||
case IP_VERSION(10, 1, 1):
|
||||
|
@ -6911,6 +6909,8 @@ static int gfx_v10_0_kiq_init_queue(struct amdgpu_ring *ring)
|
|||
mutex_unlock(&adev->srbm_mutex);
|
||||
} else {
|
||||
memset((void *)mqd, 0, sizeof(*mqd));
|
||||
if (amdgpu_sriov_vf(adev) && adev->in_suspend)
|
||||
amdgpu_ring_clear_ring(ring);
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
nv_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
|
||||
amdgpu_ring_init_mqd(ring);
|
||||
|
@ -7593,6 +7593,8 @@ static int gfx_v10_0_early_init(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->gfx.funcs = &gfx_v10_0_gfx_funcs;
|
||||
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(10, 1, 10):
|
||||
case IP_VERSION(10, 1, 1):
|
||||
|
@ -8489,7 +8491,7 @@ static void gfx_v10_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
|||
|
||||
control |= ib->length_dw | (vmid << 24);
|
||||
|
||||
if ((amdgpu_sriov_vf(ring->adev) || amdgpu_mcbp) && (ib->flags & AMDGPU_IB_FLAG_PREEMPT)) {
|
||||
if (amdgpu_mcbp && (ib->flags & AMDGPU_IB_FLAG_PREEMPT)) {
|
||||
control |= INDIRECT_BUFFER_PRE_ENB(1);
|
||||
|
||||
if (flags & AMDGPU_IB_PREEMPTED)
|
||||
|
@ -8664,7 +8666,7 @@ static void gfx_v10_0_ring_emit_cntxcntl(struct amdgpu_ring *ring,
|
|||
{
|
||||
uint32_t dw2 = 0;
|
||||
|
||||
if (amdgpu_mcbp || amdgpu_sriov_vf(ring->adev))
|
||||
if (amdgpu_mcbp)
|
||||
gfx_v10_0_ring_emit_ce_meta(ring,
|
||||
(!amdgpu_sriov_vf(ring->adev) && flags & AMDGPU_IB_PREEMPTED) ? true : false);
|
||||
|
||||
|
|
|
@ -843,7 +843,6 @@ static const struct amdgpu_gfx_funcs gfx_v11_0_gfx_funcs = {
|
|||
|
||||
static int gfx_v11_0_gpu_early_init(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->gfx.funcs = &gfx_v11_0_gfx_funcs;
|
||||
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(11, 0, 0):
|
||||
|
@ -1626,7 +1625,8 @@ static void gfx_v11_0_constants_init(struct amdgpu_device *adev)
|
|||
u32 tmp;
|
||||
int i;
|
||||
|
||||
WREG32_FIELD15_PREREG(GC, 0, GRBM_CNTL, READ_TIMEOUT, 0xff);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
WREG32_FIELD15_PREREG(GC, 0, GRBM_CNTL, READ_TIMEOUT, 0xff);
|
||||
|
||||
gfx_v11_0_setup_rb(adev);
|
||||
gfx_v11_0_get_cu_info(adev, &adev->gfx.cu_info);
|
||||
|
@ -4004,6 +4004,8 @@ static int gfx_v11_0_kiq_init_queue(struct amdgpu_ring *ring)
|
|||
mutex_unlock(&adev->srbm_mutex);
|
||||
} else {
|
||||
memset((void *)mqd, 0, sizeof(*mqd));
|
||||
if (amdgpu_sriov_vf(adev) && adev->in_suspend)
|
||||
amdgpu_ring_clear_ring(ring);
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc21_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
|
||||
amdgpu_ring_init_mqd(ring);
|
||||
|
@ -4656,6 +4658,8 @@ static int gfx_v11_0_early_init(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->gfx.funcs = &gfx_v11_0_gfx_funcs;
|
||||
|
||||
adev->gfx.num_gfx_rings = GFX11_NUM_GFX_RINGS;
|
||||
adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev),
|
||||
AMDGPU_MAX_COMPUTE_RINGS);
|
||||
|
@ -4673,6 +4677,26 @@ static int gfx_v11_0_early_init(void *handle)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v11_0_ras_late_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct ras_common_if *gfx_common_if;
|
||||
int ret;
|
||||
|
||||
gfx_common_if = kzalloc(sizeof(struct ras_common_if), GFP_KERNEL);
|
||||
if (!gfx_common_if)
|
||||
return -ENOMEM;
|
||||
|
||||
gfx_common_if->block = AMDGPU_RAS_BLOCK__GFX;
|
||||
|
||||
ret = amdgpu_ras_feature_enable(adev, gfx_common_if, true);
|
||||
if (ret)
|
||||
dev_warn(adev->dev, "Failed to enable gfx11 ras feature\n");
|
||||
|
||||
kfree(gfx_common_if);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v11_0_late_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
@ -4686,6 +4710,12 @@ static int gfx_v11_0_late_init(void *handle)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(11, 0, 3)) {
|
||||
r = gfx_v11_0_ras_late_init(handle);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5051,6 +5081,7 @@ static int gfx_v11_0_set_powergating_state(void *handle,
|
|||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
amdgpu_gfx_off_ctrl(adev, enable);
|
||||
break;
|
||||
case IP_VERSION(11, 0, 1):
|
||||
|
@ -5298,7 +5329,7 @@ static void gfx_v11_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
|||
|
||||
control |= ib->length_dw | (vmid << 24);
|
||||
|
||||
if ((amdgpu_sriov_vf(ring->adev) || amdgpu_mcbp) && (ib->flags & AMDGPU_IB_FLAG_PREEMPT)) {
|
||||
if (amdgpu_mcbp && (ib->flags & AMDGPU_IB_FLAG_PREEMPT)) {
|
||||
control |= INDIRECT_BUFFER_PRE_ENB(1);
|
||||
|
||||
if (flags & AMDGPU_IB_PREEMPTED)
|
||||
|
@ -6059,6 +6090,7 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_gfx = {
|
|||
.align_mask = 0xff,
|
||||
.nop = PACKET3(PACKET3_NOP, 0x3FFF),
|
||||
.support_64bit_ptrs = true,
|
||||
.secure_submission_supported = true,
|
||||
.vmhub = AMDGPU_GFXHUB_0,
|
||||
.get_rptr = gfx_v11_0_ring_get_rptr_gfx,
|
||||
.get_wptr = gfx_v11_0_ring_get_wptr_gfx,
|
||||
|
|
|
@ -4643,6 +4643,8 @@ static int gfx_v8_0_kiq_init_queue(struct amdgpu_ring *ring)
|
|||
memset((void *)mqd, 0, sizeof(struct vi_mqd_allocation));
|
||||
((struct vi_mqd_allocation *)mqd)->dynamic_cu_mask = 0xFFFFFFFF;
|
||||
((struct vi_mqd_allocation *)mqd)->dynamic_rb_mask = 0xFFFFFFFF;
|
||||
if (amdgpu_sriov_vf(adev) && adev->in_suspend)
|
||||
amdgpu_ring_clear_ring(ring);
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
vi_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
|
||||
gfx_v8_0_mqd_init(ring);
|
||||
|
|
|
@ -1564,7 +1564,7 @@ static void gfx_v9_0_init_always_on_cu_mask(struct amdgpu_device *adev)
|
|||
mask = 1;
|
||||
cu_bitmap = 0;
|
||||
counter = 0;
|
||||
gfx_v9_0_select_se_sh(adev, i, j, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, i, j, 0xffffffff);
|
||||
|
||||
for (k = 0; k < adev->gfx.config.max_cu_per_sh; k ++) {
|
||||
if (cu_info->bitmap[i][j] & mask) {
|
||||
|
@ -1583,7 +1583,7 @@ static void gfx_v9_0_init_always_on_cu_mask(struct amdgpu_device *adev)
|
|||
cu_info->ao_cu_bitmap[i][j] = cu_bitmap;
|
||||
}
|
||||
}
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
}
|
||||
|
||||
|
@ -1605,7 +1605,7 @@ static void gfx_v9_0_init_lbpw(struct amdgpu_device *adev)
|
|||
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
/* set mmRLC_LB_INIT_CU_MASK thru broadcast mode to enable all SE/SH*/
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_INIT_CU_MASK, 0xffffffff);
|
||||
|
||||
/* set mmRLC_LB_PARAMS = 0x003F_1006 */
|
||||
|
@ -1654,7 +1654,7 @@ static void gfx_v9_4_init_lbpw(struct amdgpu_device *adev)
|
|||
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
/* set mmRLC_LB_INIT_CU_MASK thru broadcast mode to enable all SE/SH*/
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
WREG32_SOC15(GC, 0, mmRLC_LB_INIT_CU_MASK, 0xffffffff);
|
||||
|
||||
/* set mmRLC_LB_PARAMS = 0x003F_1006 */
|
||||
|
@ -1919,8 +1919,6 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
|
|||
u32 gb_addr_config;
|
||||
int err;
|
||||
|
||||
adev->gfx.funcs = &gfx_v9_0_gfx_funcs;
|
||||
|
||||
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||
case IP_VERSION(9, 0, 1):
|
||||
adev->gfx.config.max_hw_contexts = 8;
|
||||
|
@ -2324,13 +2322,13 @@ static void gfx_v9_0_setup_rb(struct amdgpu_device *adev)
|
|||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {
|
||||
for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
|
||||
gfx_v9_0_select_se_sh(adev, i, j, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, i, j, 0xffffffff);
|
||||
data = gfx_v9_0_get_rb_active_bitmap(adev);
|
||||
active_rbs |= data << ((i * adev->gfx.config.max_sh_per_se + j) *
|
||||
rb_bitmap_width_per_sh);
|
||||
}
|
||||
}
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
adev->gfx.config.backend_enable_mask = active_rbs;
|
||||
|
@ -2467,14 +2465,14 @@ static void gfx_v9_0_wait_for_rlc_serdes(struct amdgpu_device *adev)
|
|||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {
|
||||
for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
|
||||
gfx_v9_0_select_se_sh(adev, i, j, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, i, j, 0xffffffff);
|
||||
for (k = 0; k < adev->usec_timeout; k++) {
|
||||
if (RREG32_SOC15(GC, 0, mmRLC_SERDES_CU_MASTER_BUSY) == 0)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
if (k == adev->usec_timeout) {
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff,
|
||||
amdgpu_gfx_select_se_sh(adev, 0xffffffff,
|
||||
0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
DRM_INFO("Timeout wait for RLC serdes %u,%u\n",
|
||||
|
@ -2483,7 +2481,7 @@ static void gfx_v9_0_wait_for_rlc_serdes(struct amdgpu_device *adev)
|
|||
}
|
||||
}
|
||||
}
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
mask = RLC_SERDES_NONCU_MASTER_BUSY__SE_MASTER_BUSY_MASK |
|
||||
|
@ -3583,6 +3581,8 @@ static int gfx_v9_0_kiq_init_queue(struct amdgpu_ring *ring)
|
|||
memset((void *)mqd, 0, sizeof(struct v9_mqd_allocation));
|
||||
((struct v9_mqd_allocation *)mqd)->dynamic_cu_mask = 0xFFFFFFFF;
|
||||
((struct v9_mqd_allocation *)mqd)->dynamic_rb_mask = 0xFFFFFFFF;
|
||||
if (amdgpu_sriov_vf(adev) && adev->in_suspend)
|
||||
amdgpu_ring_clear_ring(ring);
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
soc15_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
|
||||
gfx_v9_0_mqd_init(ring);
|
||||
|
@ -4539,6 +4539,8 @@ static int gfx_v9_0_early_init(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->gfx.funcs = &gfx_v9_0_gfx_funcs;
|
||||
|
||||
if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 1) ||
|
||||
adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2))
|
||||
adev->gfx.num_gfx_rings = 0;
|
||||
|
@ -6482,7 +6484,7 @@ static void gfx_v9_0_reset_ras_error_count(struct amdgpu_device *adev)
|
|||
for (i = 0; i < ARRAY_SIZE(gfx_v9_0_edc_counter_regs); i++) {
|
||||
for (j = 0; j < gfx_v9_0_edc_counter_regs[i].se_num; j++) {
|
||||
for (k = 0; k < gfx_v9_0_edc_counter_regs[i].instance; k++) {
|
||||
gfx_v9_0_select_se_sh(adev, j, 0x0, k);
|
||||
amdgpu_gfx_select_se_sh(adev, j, 0x0, k);
|
||||
RREG32(SOC15_REG_ENTRY_OFFSET(gfx_v9_0_edc_counter_regs[i]));
|
||||
}
|
||||
}
|
||||
|
@ -6544,7 +6546,7 @@ static void gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
|
|||
for (i = 0; i < ARRAY_SIZE(gfx_v9_0_edc_counter_regs); i++) {
|
||||
for (j = 0; j < gfx_v9_0_edc_counter_regs[i].se_num; j++) {
|
||||
for (k = 0; k < gfx_v9_0_edc_counter_regs[i].instance; k++) {
|
||||
gfx_v9_0_select_se_sh(adev, j, 0, k);
|
||||
amdgpu_gfx_select_se_sh(adev, j, 0, k);
|
||||
reg_value =
|
||||
RREG32(SOC15_REG_ENTRY_OFFSET(gfx_v9_0_edc_counter_regs[i]));
|
||||
if (reg_value)
|
||||
|
@ -6559,7 +6561,7 @@ static void gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
|
|||
err_data->ce_count += sec_count;
|
||||
err_data->ue_count += ded_count;
|
||||
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
gfx_v9_0_query_utc_edc_status(adev, err_data);
|
||||
|
@ -6963,7 +6965,7 @@ static int gfx_v9_0_get_cu_info(struct amdgpu_device *adev,
|
|||
mask = 1;
|
||||
ao_bitmap = 0;
|
||||
counter = 0;
|
||||
gfx_v9_0_select_se_sh(adev, i, j, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, i, j, 0xffffffff);
|
||||
gfx_v9_0_set_user_cu_inactive_bitmap(
|
||||
adev, disable_masks[i * adev->gfx.config.max_sh_per_se + j]);
|
||||
bitmap = gfx_v9_0_get_cu_active_bitmap(adev);
|
||||
|
@ -6996,7 +6998,7 @@ static int gfx_v9_0_get_cu_info(struct amdgpu_device *adev,
|
|||
cu_info->ao_cu_bitmap[i % 4][j + i / 4] = ao_bitmap;
|
||||
}
|
||||
}
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
cu_info->number = active_cu_number;
|
||||
|
|
|
@ -397,6 +397,9 @@ static void gfxhub_v2_1_gart_disable(struct amdgpu_device *adev)
|
|||
ENABLE_ADVANCED_DRIVER_MODEL, 0);
|
||||
WREG32_SOC15(GC, 0, mmGCMC_VM_MX_L1_TLB_CNTL, tmp);
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return;
|
||||
|
||||
/* Setup L2 cache */
|
||||
WREG32_FIELD15(GC, 0, GCVM_L2_CNTL, ENABLE_L2_CACHE, 0);
|
||||
WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL3, 0);
|
||||
|
|
|
@ -154,6 +154,9 @@ static void gfxhub_v3_0_3_init_system_aperture_regs(struct amdgpu_device *adev)
|
|||
{
|
||||
uint64_t value;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return;
|
||||
|
||||
/* Disable AGP. */
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_AGP_BASE, 0);
|
||||
WREG32_SOC15(GC, 0, regGCMC_VM_AGP_TOP, 0);
|
||||
|
|
|
@ -121,6 +121,10 @@ static int mes_v10_1_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
|||
if (r < 1) {
|
||||
DRM_ERROR("MES failed to response msg=%d\n",
|
||||
x_pkt->header.opcode);
|
||||
|
||||
while (halt_if_hws_hang)
|
||||
schedule();
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -415,10 +419,6 @@ static int mes_v10_1_init_microcode(struct amdgpu_device *adev,
|
|||
|
||||
mes_hdr = (const struct mes_firmware_header_v1_0 *)
|
||||
adev->mes.fw[pipe]->data;
|
||||
adev->mes.ucode_fw_version[pipe] =
|
||||
le32_to_cpu(mes_hdr->mes_ucode_version);
|
||||
adev->mes.ucode_fw_version[pipe] =
|
||||
le32_to_cpu(mes_hdr->mes_ucode_data_version);
|
||||
adev->mes.uc_start_addr[pipe] =
|
||||
le32_to_cpu(mes_hdr->mes_uc_start_addr_lo) |
|
||||
((uint64_t)(le32_to_cpu(mes_hdr->mes_uc_start_addr_hi)) << 32);
|
||||
|
|
|
@ -98,7 +98,14 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
|||
struct amdgpu_device *adev = mes->adev;
|
||||
struct amdgpu_ring *ring = &mes->ring;
|
||||
unsigned long flags;
|
||||
signed long timeout = adev->usec_timeout;
|
||||
|
||||
if (amdgpu_emu_mode) {
|
||||
timeout *= 100;
|
||||
} else if (amdgpu_sriov_vf(adev)) {
|
||||
/* Worst case in sriov where all other 15 VF timeout, each VF needs about 600ms */
|
||||
timeout = 15 * 600 * 1000;
|
||||
}
|
||||
BUG_ON(size % 4 != 0);
|
||||
|
||||
spin_lock_irqsave(&mes->ring_lock, flags);
|
||||
|
@ -118,10 +125,14 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
|||
DRM_DEBUG("MES msg=%d was emitted\n", x_pkt->header.opcode);
|
||||
|
||||
r = amdgpu_fence_wait_polling(ring, ring->fence_drv.sync_seq,
|
||||
adev->usec_timeout * (amdgpu_emu_mode ? 100 : 1));
|
||||
timeout);
|
||||
if (r < 1) {
|
||||
DRM_ERROR("MES failed to response msg=%d\n",
|
||||
x_pkt->header.opcode);
|
||||
|
||||
while (halt_if_hws_hang)
|
||||
schedule();
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -478,10 +489,6 @@ static int mes_v11_0_init_microcode(struct amdgpu_device *adev,
|
|||
|
||||
mes_hdr = (const struct mes_firmware_header_v1_0 *)
|
||||
adev->mes.fw[pipe]->data;
|
||||
adev->mes.ucode_fw_version[pipe] =
|
||||
le32_to_cpu(mes_hdr->mes_ucode_version);
|
||||
adev->mes.ucode_fw_version[pipe] =
|
||||
le32_to_cpu(mes_hdr->mes_ucode_data_version);
|
||||
adev->mes.uc_start_addr[pipe] =
|
||||
le32_to_cpu(mes_hdr->mes_uc_start_addr_lo) |
|
||||
((uint64_t)(le32_to_cpu(mes_hdr->mes_uc_start_addr_hi)) << 32);
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
#include "gc/gc_10_1_0_offset.h"
|
||||
#include "soc15_common.h"
|
||||
|
||||
#define mmMM_ATC_L2_MISC_CG_Sienna_Cichlid 0x064d
|
||||
#define mmMM_ATC_L2_MISC_CG_Sienna_Cichlid_BASE_IDX 0
|
||||
#define mmDAGB0_CNTL_MISC2_Sienna_Cichlid 0x0070
|
||||
#define mmDAGB0_CNTL_MISC2_Sienna_Cichlid_BASE_IDX 0
|
||||
|
||||
|
@ -574,7 +572,6 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad
|
|||
case IP_VERSION(2, 1, 0):
|
||||
case IP_VERSION(2, 1, 1):
|
||||
case IP_VERSION(2, 1, 2):
|
||||
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
|
||||
def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid);
|
||||
break;
|
||||
default:
|
||||
|
@ -608,8 +605,6 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad
|
|||
case IP_VERSION(2, 1, 0):
|
||||
case IP_VERSION(2, 1, 1):
|
||||
case IP_VERSION(2, 1, 2):
|
||||
if (def != data)
|
||||
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data);
|
||||
if (def1 != data1)
|
||||
WREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid, data1);
|
||||
break;
|
||||
|
@ -634,8 +629,8 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade
|
|||
case IP_VERSION(2, 1, 0):
|
||||
case IP_VERSION(2, 1, 1):
|
||||
case IP_VERSION(2, 1, 2):
|
||||
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
|
||||
break;
|
||||
/* There is no ATCL2 in MMHUB for 2.1.x */
|
||||
return;
|
||||
default:
|
||||
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
|
||||
break;
|
||||
|
@ -646,18 +641,8 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade
|
|||
else
|
||||
data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
|
||||
|
||||
if (def != data) {
|
||||
switch (adev->ip_versions[MMHUB_HWIP][0]) {
|
||||
case IP_VERSION(2, 1, 0):
|
||||
case IP_VERSION(2, 1, 1):
|
||||
case IP_VERSION(2, 1, 2):
|
||||
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data);
|
||||
break;
|
||||
default:
|
||||
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (def != data)
|
||||
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
|
||||
}
|
||||
|
||||
static int mmhub_v2_0_set_clockgating(struct amdgpu_device *adev,
|
||||
|
@ -695,7 +680,10 @@ static void mmhub_v2_0_get_clockgating(struct amdgpu_device *adev, u64 *flags)
|
|||
case IP_VERSION(2, 1, 0):
|
||||
case IP_VERSION(2, 1, 1):
|
||||
case IP_VERSION(2, 1, 2):
|
||||
data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
|
||||
/* There is no ATCL2 in MMHUB for 2.1.x. Keep the status
|
||||
* based on DAGB
|
||||
*/
|
||||
data = MM_ATC_L2_MISC_CG__ENABLE_MASK;
|
||||
data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -455,6 +455,9 @@ static void sdma_v6_0_enable(struct amdgpu_device *adev, bool enable)
|
|||
sdma_v6_0_rlc_stop(adev);
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return;
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
f32_cntl = RREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_F32_CNTL));
|
||||
f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, enable ? 0 : 1);
|
||||
|
@ -1523,6 +1526,7 @@ static const struct amdgpu_ring_funcs sdma_v6_0_ring_funcs = {
|
|||
.align_mask = 0xf,
|
||||
.nop = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP),
|
||||
.support_64bit_ptrs = true,
|
||||
.secure_submission_supported = true,
|
||||
.vmhub = AMDGPU_GFXHUB_0,
|
||||
.get_rptr = sdma_v6_0_ring_get_rptr,
|
||||
.get_wptr = sdma_v6_0_ring_get_wptr,
|
||||
|
|
|
@ -112,14 +112,12 @@ static void si_dma_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
|
|||
|
||||
static void si_dma_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *ring;
|
||||
u32 rb_cntl;
|
||||
unsigned i;
|
||||
|
||||
amdgpu_sdma_unset_buffer_funcs_helper(adev);
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
ring = &adev->sdma.instance[i].ring;
|
||||
/* dma0 */
|
||||
rb_cntl = RREG32(DMA_RB_CNTL + sdma_offsets[i]);
|
||||
rb_cntl &= ~DMA_RB_ENABLE;
|
||||
|
|
|
@ -584,10 +584,6 @@ static int soc21_common_early_init(void *handle)
|
|||
AMD_PG_SUPPORT_JPEG |
|
||||
AMD_PG_SUPPORT_ATHUB |
|
||||
AMD_PG_SUPPORT_MMHUB;
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
adev->cg_flags = 0;
|
||||
adev->pg_flags = 0;
|
||||
}
|
||||
adev->external_rev_id = adev->rev_id + 0x1; // TODO: need update
|
||||
break;
|
||||
case IP_VERSION(11, 0, 2):
|
||||
|
@ -645,11 +641,6 @@ static int soc21_common_early_init(void *handle)
|
|||
adev->pg_flags = AMD_PG_SUPPORT_VCN |
|
||||
AMD_PG_SUPPORT_VCN_DPG |
|
||||
AMD_PG_SUPPORT_JPEG;
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
/* hypervisor control CG and PG enablement */
|
||||
adev->cg_flags = 0;
|
||||
adev->pg_flags = 0;
|
||||
}
|
||||
adev->external_rev_id = adev->rev_id + 0x20;
|
||||
break;
|
||||
default:
|
||||
|
@ -657,6 +648,9 @@ static int soc21_common_early_init(void *handle)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
amdgpu_virt_init_setting(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -187,9 +187,9 @@ static void umc_v6_7_ecc_info_query_ras_error_count(struct amdgpu_device *adev,
|
|||
}
|
||||
}
|
||||
|
||||
static void umc_v6_7_convert_error_address(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data, uint64_t err_addr,
|
||||
uint32_t ch_inst, uint32_t umc_inst)
|
||||
void umc_v6_7_convert_error_address(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data, uint64_t err_addr,
|
||||
uint32_t ch_inst, uint32_t umc_inst)
|
||||
{
|
||||
uint32_t channel_index;
|
||||
uint64_t soc_pa, retired_page, column;
|
||||
|
@ -553,5 +553,4 @@ struct amdgpu_umc_ras umc_v6_7_ras = {
|
|||
.query_ras_poison_mode = umc_v6_7_query_ras_poison_mode,
|
||||
.ecc_info_query_ras_error_count = umc_v6_7_ecc_info_query_ras_error_count,
|
||||
.ecc_info_query_ras_error_address = umc_v6_7_ecc_info_query_ras_error_address,
|
||||
.convert_ras_error_address = umc_v6_7_convert_error_address,
|
||||
};
|
||||
|
|
|
@ -71,5 +71,7 @@ extern const uint32_t
|
|||
umc_v6_7_channel_idx_tbl_second[UMC_V6_7_UMC_INSTANCE_NUM][UMC_V6_7_CHANNEL_INSTANCE_NUM];
|
||||
extern const uint32_t
|
||||
umc_v6_7_channel_idx_tbl_first[UMC_V6_7_UMC_INSTANCE_NUM][UMC_V6_7_CHANNEL_INSTANCE_NUM];
|
||||
|
||||
void umc_v6_7_convert_error_address(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data, uint64_t err_addr,
|
||||
uint32_t ch_inst, uint32_t umc_inst);
|
||||
#endif
|
||||
|
|
|
@ -267,7 +267,7 @@ static void vega20_ih_reroute_ih(struct amdgpu_device *adev)
|
|||
/* vega20 ih reroute will go through psp this
|
||||
* function is used for newer asics starting arcturus
|
||||
*/
|
||||
if (adev->asic_type >= CHIP_ARCTURUS) {
|
||||
if (adev->ip_versions[OSSSYS_HWIP][0] >= IP_VERSION(4, 2, 1)) {
|
||||
/* Reroute to IH ring 1 for VMC */
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_INDEX, 0x12);
|
||||
tmp = RREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA);
|
||||
|
@ -308,7 +308,7 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev)
|
|||
|
||||
adev->nbio.funcs->ih_control(adev);
|
||||
|
||||
if (adev->asic_type == CHIP_ARCTURUS &&
|
||||
if ((adev->ip_versions[OSSSYS_HWIP][0] == IP_VERSION(4, 2, 1)) &&
|
||||
adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
|
||||
ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN);
|
||||
if (adev->irq.ih.use_bus_addr) {
|
||||
|
@ -321,7 +321,7 @@ static int vega20_ih_irq_init(struct amdgpu_device *adev)
|
|||
/* psp firmware won't program IH_CHICKEN for aldebaran
|
||||
* driver needs to program it properly according to
|
||||
* MC_SPACE type in IH_RB_CNTL */
|
||||
if (adev->asic_type == CHIP_ALDEBARAN) {
|
||||
if (adev->ip_versions[OSSSYS_HWIP][0] == IP_VERSION(4, 4, 0)) {
|
||||
ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN_ALDEBARAN);
|
||||
if (adev->irq.ih.use_bus_addr) {
|
||||
ih_chicken = REG_SET_FIELD(ih_chicken, IH_CHICKEN,
|
||||
|
|
|
@ -2495,442 +2495,444 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
|
|||
0xbf9f0000, 0x00000000,
|
||||
};
|
||||
static const uint32_t cwsr_trap_gfx11_hex[] = {
|
||||
0xbfa00001, 0xbfa0021e,
|
||||
0xbfa00001, 0xbfa00221,
|
||||
0xb0804006, 0xb8f8f802,
|
||||
0x9178ff78, 0x00020006,
|
||||
0xb8fbf803, 0xbf0d9f6d,
|
||||
0xbfa20006, 0x8b6eff78,
|
||||
0x00002000, 0xbfa10009,
|
||||
0x8b6eff6d, 0x00ff0000,
|
||||
0xbfa2001e, 0x8b6eff7b,
|
||||
0x00000400, 0xbfa20041,
|
||||
0xbf830010, 0xb8fbf803,
|
||||
0xbfa0fffa, 0x8b6eff7b,
|
||||
0x00000900, 0xbfa20015,
|
||||
0x8b6eff7b, 0x000071ff,
|
||||
0xbfa10008, 0x8b6fff7b,
|
||||
0x00007080, 0xbfa10001,
|
||||
0xbeee1287, 0xb8eff801,
|
||||
0x846e8c6e, 0x8b6e6f6e,
|
||||
0xbfa2000a, 0x8b6eff6d,
|
||||
0x00ff0000, 0xbfa20007,
|
||||
0xb8eef801, 0x8b6eff6e,
|
||||
0x00000800, 0xbfa20003,
|
||||
0xb8fbf803, 0xbf0d9e6d,
|
||||
0xbfa10001, 0xbfbd0000,
|
||||
0xbf0d9f6d, 0xbfa20006,
|
||||
0x8b6eff78, 0x00002000,
|
||||
0xbfa10009, 0x8b6eff6d,
|
||||
0x00ff0000, 0xbfa2001e,
|
||||
0x8b6eff7b, 0x00000400,
|
||||
0xbfa20026, 0xbefa4d82,
|
||||
0xbf89fc07, 0x84fa887a,
|
||||
0xf4005bbd, 0xf8000010,
|
||||
0xbf89fc07, 0x846e976e,
|
||||
0x9177ff77, 0x00800000,
|
||||
0x8c776e77, 0xf4045bbd,
|
||||
0xf8000000, 0xbf89fc07,
|
||||
0xf4045ebd, 0xf8000008,
|
||||
0xbf89fc07, 0x8bee6e6e,
|
||||
0xbfa10001, 0xbe80486e,
|
||||
0x8b6eff6d, 0x01ff0000,
|
||||
0xbfa20005, 0x8c78ff78,
|
||||
0x00002000, 0x80ec886c,
|
||||
0x82ed806d, 0xbfa00005,
|
||||
0x8b6eff6d, 0x01000000,
|
||||
0xbfa20002, 0x806c846c,
|
||||
0x826d806d, 0x8b6dff6d,
|
||||
0x0000ffff, 0x8bfe7e7e,
|
||||
0x8bea6a6a, 0xb978f802,
|
||||
0xbe804a6c, 0x8b6dff6d,
|
||||
0x0000ffff, 0xbefa0080,
|
||||
0xb97a0283, 0xbeee007e,
|
||||
0xbeef007f, 0xbefe0180,
|
||||
0xbefe4d84, 0xbf89fc07,
|
||||
0x8b7aff7f, 0x04000000,
|
||||
0x847a857a, 0x8c6d7a6d,
|
||||
0xbefa007e, 0x8b7bff7f,
|
||||
0x0000ffff, 0xbefe00c1,
|
||||
0xbeff00c1, 0xdca6c000,
|
||||
0x007a0000, 0x7e000280,
|
||||
0xbefe007a, 0xbeff007b,
|
||||
0xb8fb02dc, 0x847b997b,
|
||||
0xb8fa3b05, 0x807a817a,
|
||||
0xbf0d997b, 0xbfa20002,
|
||||
0x847a897a, 0xbfa00001,
|
||||
0x847a8a7a, 0xb8fb1e06,
|
||||
0x847b8a7b, 0x807a7b7a,
|
||||
0xbfa20041, 0xbf830010,
|
||||
0xb8fbf803, 0xbfa0fffa,
|
||||
0x8b6eff7b, 0x00000900,
|
||||
0xbfa20015, 0x8b6eff7b,
|
||||
0x000071ff, 0xbfa10008,
|
||||
0x8b6fff7b, 0x00007080,
|
||||
0xbfa10001, 0xbeee1287,
|
||||
0xb8eff801, 0x846e8c6e,
|
||||
0x8b6e6f6e, 0xbfa2000a,
|
||||
0x8b6eff6d, 0x00ff0000,
|
||||
0xbfa20007, 0xb8eef801,
|
||||
0x8b6eff6e, 0x00000800,
|
||||
0xbfa20003, 0x8b6eff7b,
|
||||
0x00000400, 0xbfa20026,
|
||||
0xbefa4d82, 0xbf89fc07,
|
||||
0x84fa887a, 0xf4005bbd,
|
||||
0xf8000010, 0xbf89fc07,
|
||||
0x846e976e, 0x9177ff77,
|
||||
0x00800000, 0x8c776e77,
|
||||
0xf4045bbd, 0xf8000000,
|
||||
0xbf89fc07, 0xf4045ebd,
|
||||
0xf8000008, 0xbf89fc07,
|
||||
0x8bee6e6e, 0xbfa10001,
|
||||
0xbe80486e, 0x8b6eff6d,
|
||||
0x01ff0000, 0xbfa20005,
|
||||
0x8c78ff78, 0x00002000,
|
||||
0x80ec886c, 0x82ed806d,
|
||||
0xbfa00005, 0x8b6eff6d,
|
||||
0x01000000, 0xbfa20002,
|
||||
0x806c846c, 0x826d806d,
|
||||
0x8b6dff6d, 0x0000ffff,
|
||||
0x8bfe7e7e, 0x8bea6a6a,
|
||||
0xb978f802, 0xbe804a6c,
|
||||
0x8b6dff6d, 0x0000ffff,
|
||||
0xbefa0080, 0xb97a0283,
|
||||
0xbeee007e, 0xbeef007f,
|
||||
0xbefe0180, 0xbefe4d84,
|
||||
0xbf89fc07, 0x8b7aff7f,
|
||||
0x04000000, 0x847a857a,
|
||||
0x8c6d7a6d, 0xbefa007e,
|
||||
0x8b7bff7f, 0x0000ffff,
|
||||
0x807aff7a, 0x00000200,
|
||||
0x807a7e7a, 0x827b807b,
|
||||
0xd7610000, 0x00010870,
|
||||
0xd7610000, 0x00010a71,
|
||||
0xd7610000, 0x00010c72,
|
||||
0xd7610000, 0x00010e73,
|
||||
0xd7610000, 0x00011074,
|
||||
0xd7610000, 0x00011275,
|
||||
0xd7610000, 0x00011476,
|
||||
0xd7610000, 0x00011677,
|
||||
0xd7610000, 0x00011a79,
|
||||
0xd7610000, 0x00011c7e,
|
||||
0xd7610000, 0x00011e7f,
|
||||
0xbefe00ff, 0x00003fff,
|
||||
0xbeff0080, 0xdca6c040,
|
||||
0x007a0000, 0xd760007a,
|
||||
0x00011d00, 0xd760007b,
|
||||
0x00011f00, 0xbefe007a,
|
||||
0xbeff007b, 0xbef4007e,
|
||||
0x8b75ff7f, 0x0000ffff,
|
||||
0x8c75ff75, 0x00040000,
|
||||
0xbef60080, 0xbef700ff,
|
||||
0x10807fac, 0xbef1007d,
|
||||
0xbef00080, 0xb8f302dc,
|
||||
0x84739973, 0xbefe00c1,
|
||||
0x857d9973, 0x8b7d817d,
|
||||
0xbf06817d, 0xbfa20002,
|
||||
0xbeff0080, 0xbfa00002,
|
||||
0xbeff00c1, 0xbfa00009,
|
||||
0xbefe00c1, 0xbeff00c1,
|
||||
0xdca6c000, 0x007a0000,
|
||||
0x7e000280, 0xbefe007a,
|
||||
0xbeff007b, 0xb8fb02dc,
|
||||
0x847b997b, 0xb8fa3b05,
|
||||
0x807a817a, 0xbf0d997b,
|
||||
0xbfa20002, 0x847a897a,
|
||||
0xbfa00001, 0x847a8a7a,
|
||||
0xb8fb1e06, 0x847b8a7b,
|
||||
0x807a7b7a, 0x8b7bff7f,
|
||||
0x0000ffff, 0x807aff7a,
|
||||
0x00000200, 0x807a7e7a,
|
||||
0x827b807b, 0xd7610000,
|
||||
0x00010870, 0xd7610000,
|
||||
0x00010a71, 0xd7610000,
|
||||
0x00010c72, 0xd7610000,
|
||||
0x00010e73, 0xd7610000,
|
||||
0x00011074, 0xd7610000,
|
||||
0x00011275, 0xd7610000,
|
||||
0x00011476, 0xd7610000,
|
||||
0x00011677, 0xd7610000,
|
||||
0x00011a79, 0xd7610000,
|
||||
0x00011c7e, 0xd7610000,
|
||||
0x00011e7f, 0xbefe00ff,
|
||||
0x00003fff, 0xbeff0080,
|
||||
0xdca6c040, 0x007a0000,
|
||||
0xd760007a, 0x00011d00,
|
||||
0xd760007b, 0x00011f00,
|
||||
0xbefe007a, 0xbeff007b,
|
||||
0xbef4007e, 0x8b75ff7f,
|
||||
0x0000ffff, 0x8c75ff75,
|
||||
0x00040000, 0xbef60080,
|
||||
0xbef700ff, 0x10807fac,
|
||||
0xbef1007d, 0xbef00080,
|
||||
0xb8f302dc, 0x84739973,
|
||||
0xbefe00c1, 0x857d9973,
|
||||
0x8b7d817d, 0xbf06817d,
|
||||
0xbfa20002, 0xbeff0080,
|
||||
0xbfa00002, 0xbeff00c1,
|
||||
0xbfa00009, 0xbef600ff,
|
||||
0x01000000, 0xe0685080,
|
||||
0x701d0100, 0xe0685100,
|
||||
0x701d0200, 0xe0685180,
|
||||
0x701d0300, 0xbfa00008,
|
||||
0xbef600ff, 0x01000000,
|
||||
0xe0685080, 0x701d0100,
|
||||
0xe0685100, 0x701d0200,
|
||||
0xe0685180, 0x701d0300,
|
||||
0xbfa00008, 0xbef600ff,
|
||||
0x01000000, 0xe0685100,
|
||||
0x701d0100, 0xe0685200,
|
||||
0x701d0200, 0xe0685300,
|
||||
0x701d0300, 0xb8f03b05,
|
||||
0x80708170, 0xbf0d9973,
|
||||
0xbfa20002, 0x84708970,
|
||||
0xbfa00001, 0x84708a70,
|
||||
0xb8fa1e06, 0x847a8a7a,
|
||||
0x80707a70, 0x8070ff70,
|
||||
0x00000200, 0xbef600ff,
|
||||
0x01000000, 0x7e000280,
|
||||
0x7e020280, 0x7e040280,
|
||||
0xbefd0080, 0xd7610002,
|
||||
0x0000fa71, 0x807d817d,
|
||||
0xd7610002, 0x0000fa6c,
|
||||
0x807d817d, 0x917aff6d,
|
||||
0x80000000, 0xd7610002,
|
||||
0x0000fa7a, 0x807d817d,
|
||||
0xd7610002, 0x0000fa6e,
|
||||
0x807d817d, 0xd7610002,
|
||||
0x0000fa6f, 0x807d817d,
|
||||
0xd7610002, 0x0000fa78,
|
||||
0x807d817d, 0xb8faf803,
|
||||
0xd7610002, 0x0000fa7a,
|
||||
0x807d817d, 0xd7610002,
|
||||
0x0000fa7b, 0x807d817d,
|
||||
0xb8f1f801, 0xd7610002,
|
||||
0x0000fa71, 0x807d817d,
|
||||
0xb8f1f814, 0xd7610002,
|
||||
0x0000fa71, 0x807d817d,
|
||||
0xb8f1f815, 0xd7610002,
|
||||
0x0000fa71, 0x807d817d,
|
||||
0xbefe00ff, 0x0000ffff,
|
||||
0xbeff0080, 0xe0685000,
|
||||
0x701d0200, 0xbefe00c1,
|
||||
0xe0685100, 0x701d0100,
|
||||
0xe0685200, 0x701d0200,
|
||||
0xe0685300, 0x701d0300,
|
||||
0xb8f03b05, 0x80708170,
|
||||
0xbf0d9973, 0xbfa20002,
|
||||
0x84708970, 0xbfa00001,
|
||||
0x84708a70, 0xb8fa1e06,
|
||||
0x847a8a7a, 0x80707a70,
|
||||
0x8070ff70, 0x00000200,
|
||||
0xbef600ff, 0x01000000,
|
||||
0xbef90080, 0xbefd0080,
|
||||
0xbf800000, 0xbe804100,
|
||||
0xbe824102, 0xbe844104,
|
||||
0xbe864106, 0xbe884108,
|
||||
0xbe8a410a, 0xbe8c410c,
|
||||
0xbe8e410e, 0xd7610002,
|
||||
0x0000f200, 0x80798179,
|
||||
0xd7610002, 0x0000f201,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f202, 0x80798179,
|
||||
0xd7610002, 0x0000f203,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f204, 0x80798179,
|
||||
0xd7610002, 0x0000f205,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f206, 0x80798179,
|
||||
0xd7610002, 0x0000f207,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f208, 0x80798179,
|
||||
0xd7610002, 0x0000f209,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f20a, 0x80798179,
|
||||
0xd7610002, 0x0000f20b,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f20c, 0x80798179,
|
||||
0xd7610002, 0x0000f20d,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f20e, 0x80798179,
|
||||
0xd7610002, 0x0000f20f,
|
||||
0x80798179, 0xbf06a079,
|
||||
0xbfa10006, 0xe0685000,
|
||||
0x701d0200, 0x8070ff70,
|
||||
0x00000080, 0xbef90080,
|
||||
0x7e040280, 0x807d907d,
|
||||
0xbf0aff7d, 0x00000060,
|
||||
0xbfa2ffbc, 0xbe804100,
|
||||
0xbe824102, 0xbe844104,
|
||||
0xbe864106, 0xbe884108,
|
||||
0xbe8a410a, 0xd7610002,
|
||||
0x0000f200, 0x80798179,
|
||||
0xd7610002, 0x0000f201,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f202, 0x80798179,
|
||||
0xd7610002, 0x0000f203,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f204, 0x80798179,
|
||||
0xd7610002, 0x0000f205,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f206, 0x80798179,
|
||||
0xd7610002, 0x0000f207,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f208, 0x80798179,
|
||||
0xd7610002, 0x0000f209,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f20a, 0x80798179,
|
||||
0xd7610002, 0x0000f20b,
|
||||
0x80798179, 0xe0685000,
|
||||
0x701d0200, 0xbefe00c1,
|
||||
0x857d9973, 0x8b7d817d,
|
||||
0xbf06817d, 0xbfa20002,
|
||||
0xbeff0080, 0xbfa00001,
|
||||
0xbeff00c1, 0xb8fb4306,
|
||||
0x8b7bc17b, 0xbfa10044,
|
||||
0xbfbd0000, 0x8b7aff6d,
|
||||
0x80000000, 0xbfa10040,
|
||||
0x847b867b, 0x847b827b,
|
||||
0xbef6007b, 0xb8f03b05,
|
||||
0x7e000280, 0x7e020280,
|
||||
0x7e040280, 0xbefd0080,
|
||||
0xd7610002, 0x0000fa71,
|
||||
0x807d817d, 0xd7610002,
|
||||
0x0000fa6c, 0x807d817d,
|
||||
0x917aff6d, 0x80000000,
|
||||
0xd7610002, 0x0000fa7a,
|
||||
0x807d817d, 0xd7610002,
|
||||
0x0000fa6e, 0x807d817d,
|
||||
0xd7610002, 0x0000fa6f,
|
||||
0x807d817d, 0xd7610002,
|
||||
0x0000fa78, 0x807d817d,
|
||||
0xb8faf803, 0xd7610002,
|
||||
0x0000fa7a, 0x807d817d,
|
||||
0xd7610002, 0x0000fa7b,
|
||||
0x807d817d, 0xb8f1f801,
|
||||
0xd7610002, 0x0000fa71,
|
||||
0x807d817d, 0xb8f1f814,
|
||||
0xd7610002, 0x0000fa71,
|
||||
0x807d817d, 0xb8f1f815,
|
||||
0xd7610002, 0x0000fa71,
|
||||
0x807d817d, 0xbefe00ff,
|
||||
0x0000ffff, 0xbeff0080,
|
||||
0xe0685000, 0x701d0200,
|
||||
0xbefe00c1, 0xb8f03b05,
|
||||
0x80708170, 0xbf0d9973,
|
||||
0xbfa20002, 0x84708970,
|
||||
0xbfa00001, 0x84708a70,
|
||||
0xb8fa1e06, 0x847a8a7a,
|
||||
0x80707a70, 0x8070ff70,
|
||||
0x00000200, 0x8070ff70,
|
||||
0x00000080, 0xbef600ff,
|
||||
0x01000000, 0xd71f0000,
|
||||
0x000100c1, 0xd7200000,
|
||||
0x000200c1, 0x16000084,
|
||||
0x857d9973, 0x8b7d817d,
|
||||
0xbf06817d, 0xbefd0080,
|
||||
0xbfa20012, 0xbe8300ff,
|
||||
0x00000080, 0xbf800000,
|
||||
0xbf800000, 0xbf800000,
|
||||
0xd8d80000, 0x01000000,
|
||||
0xbf890000, 0xe0685000,
|
||||
0x701d0100, 0x807d037d,
|
||||
0x80700370, 0xd5250000,
|
||||
0x0001ff00, 0x00000080,
|
||||
0xbf0a7b7d, 0xbfa2fff4,
|
||||
0xbfa00011, 0xbe8300ff,
|
||||
0x00000100, 0xbf800000,
|
||||
0xbf800000, 0xbf800000,
|
||||
0xd8d80000, 0x01000000,
|
||||
0xbf890000, 0xe0685000,
|
||||
0x701d0100, 0x807d037d,
|
||||
0x80700370, 0xd5250000,
|
||||
0x0001ff00, 0x00000100,
|
||||
0xbf0a7b7d, 0xbfa2fff4,
|
||||
0x80707a70, 0xbef600ff,
|
||||
0x01000000, 0xbef90080,
|
||||
0xbefd0080, 0xbf800000,
|
||||
0xbe804100, 0xbe824102,
|
||||
0xbe844104, 0xbe864106,
|
||||
0xbe884108, 0xbe8a410a,
|
||||
0xbe8c410c, 0xbe8e410e,
|
||||
0xd7610002, 0x0000f200,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f201, 0x80798179,
|
||||
0xd7610002, 0x0000f202,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f203, 0x80798179,
|
||||
0xd7610002, 0x0000f204,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f205, 0x80798179,
|
||||
0xd7610002, 0x0000f206,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f207, 0x80798179,
|
||||
0xd7610002, 0x0000f208,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f209, 0x80798179,
|
||||
0xd7610002, 0x0000f20a,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f20b, 0x80798179,
|
||||
0xd7610002, 0x0000f20c,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f20d, 0x80798179,
|
||||
0xd7610002, 0x0000f20e,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f20f, 0x80798179,
|
||||
0xbf06a079, 0xbfa10006,
|
||||
0xe0685000, 0x701d0200,
|
||||
0x8070ff70, 0x00000080,
|
||||
0xbef90080, 0x7e040280,
|
||||
0x807d907d, 0xbf0aff7d,
|
||||
0x00000060, 0xbfa2ffbc,
|
||||
0xbe804100, 0xbe824102,
|
||||
0xbe844104, 0xbe864106,
|
||||
0xbe884108, 0xbe8a410a,
|
||||
0xd7610002, 0x0000f200,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f201, 0x80798179,
|
||||
0xd7610002, 0x0000f202,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f203, 0x80798179,
|
||||
0xd7610002, 0x0000f204,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f205, 0x80798179,
|
||||
0xd7610002, 0x0000f206,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f207, 0x80798179,
|
||||
0xd7610002, 0x0000f208,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f209, 0x80798179,
|
||||
0xd7610002, 0x0000f20a,
|
||||
0x80798179, 0xd7610002,
|
||||
0x0000f20b, 0x80798179,
|
||||
0xe0685000, 0x701d0200,
|
||||
0xbefe00c1, 0x857d9973,
|
||||
0x8b7d817d, 0xbf06817d,
|
||||
0xbfa20004, 0xbef000ff,
|
||||
0x00000200, 0xbeff0080,
|
||||
0xbfa00003, 0xbef000ff,
|
||||
0x00000400, 0xbeff00c1,
|
||||
0xb8fb3b05, 0x807b817b,
|
||||
0x847b827b, 0x857d9973,
|
||||
0xbfa20002, 0xbeff0080,
|
||||
0xbfa00001, 0xbeff00c1,
|
||||
0xb8fb4306, 0x8b7bc17b,
|
||||
0xbfa10044, 0xbfbd0000,
|
||||
0x8b7aff6d, 0x80000000,
|
||||
0xbfa10040, 0x847b867b,
|
||||
0x847b827b, 0xbef6007b,
|
||||
0xb8f03b05, 0x80708170,
|
||||
0xbf0d9973, 0xbfa20002,
|
||||
0x84708970, 0xbfa00001,
|
||||
0x84708a70, 0xb8fa1e06,
|
||||
0x847a8a7a, 0x80707a70,
|
||||
0x8070ff70, 0x00000200,
|
||||
0x8070ff70, 0x00000080,
|
||||
0xbef600ff, 0x01000000,
|
||||
0xd71f0000, 0x000100c1,
|
||||
0xd7200000, 0x000200c1,
|
||||
0x16000084, 0x857d9973,
|
||||
0x8b7d817d, 0xbf06817d,
|
||||
0xbfa20017, 0xbef600ff,
|
||||
0xbefd0080, 0xbfa20012,
|
||||
0xbe8300ff, 0x00000080,
|
||||
0xbf800000, 0xbf800000,
|
||||
0xbf800000, 0xd8d80000,
|
||||
0x01000000, 0xbf890000,
|
||||
0xe0685000, 0x701d0100,
|
||||
0x807d037d, 0x80700370,
|
||||
0xd5250000, 0x0001ff00,
|
||||
0x00000080, 0xbf0a7b7d,
|
||||
0xbfa2fff4, 0xbfa00011,
|
||||
0xbe8300ff, 0x00000100,
|
||||
0xbf800000, 0xbf800000,
|
||||
0xbf800000, 0xd8d80000,
|
||||
0x01000000, 0xbf890000,
|
||||
0xe0685000, 0x701d0100,
|
||||
0x807d037d, 0x80700370,
|
||||
0xd5250000, 0x0001ff00,
|
||||
0x00000100, 0xbf0a7b7d,
|
||||
0xbfa2fff4, 0xbefe00c1,
|
||||
0x857d9973, 0x8b7d817d,
|
||||
0xbf06817d, 0xbfa20004,
|
||||
0xbef000ff, 0x00000200,
|
||||
0xbeff0080, 0xbfa00003,
|
||||
0xbef000ff, 0x00000400,
|
||||
0xbeff00c1, 0xb8fb3b05,
|
||||
0x807b817b, 0x847b827b,
|
||||
0x857d9973, 0x8b7d817d,
|
||||
0xbf06817d, 0xbfa20017,
|
||||
0xbef600ff, 0x01000000,
|
||||
0xbefd0084, 0xbf0a7b7d,
|
||||
0xbfa10037, 0x7e008700,
|
||||
0x7e028701, 0x7e048702,
|
||||
0x7e068703, 0xe0685000,
|
||||
0x701d0000, 0xe0685080,
|
||||
0x701d0100, 0xe0685100,
|
||||
0x701d0200, 0xe0685180,
|
||||
0x701d0300, 0x807d847d,
|
||||
0x8070ff70, 0x00000200,
|
||||
0xbf0a7b7d, 0xbfa2ffef,
|
||||
0xbfa00025, 0xbef600ff,
|
||||
0x01000000, 0xbefd0084,
|
||||
0xbf0a7b7d, 0xbfa10037,
|
||||
0xbf0a7b7d, 0xbfa10011,
|
||||
0x7e008700, 0x7e028701,
|
||||
0x7e048702, 0x7e068703,
|
||||
0xe0685000, 0x701d0000,
|
||||
0xe0685080, 0x701d0100,
|
||||
0xe0685100, 0x701d0200,
|
||||
0xe0685180, 0x701d0300,
|
||||
0xe0685100, 0x701d0100,
|
||||
0xe0685200, 0x701d0200,
|
||||
0xe0685300, 0x701d0300,
|
||||
0x807d847d, 0x8070ff70,
|
||||
0x00000200, 0xbf0a7b7d,
|
||||
0xbfa2ffef, 0xbfa00025,
|
||||
0xbef600ff, 0x01000000,
|
||||
0xbefd0084, 0xbf0a7b7d,
|
||||
0xbfa10011, 0x7e008700,
|
||||
0x7e028701, 0x7e048702,
|
||||
0x7e068703, 0xe0685000,
|
||||
0x701d0000, 0xe0685100,
|
||||
0x701d0100, 0xe0685200,
|
||||
0x701d0200, 0xe0685300,
|
||||
0x701d0300, 0x807d847d,
|
||||
0x8070ff70, 0x00000400,
|
||||
0xbf0a7b7d, 0xbfa2ffef,
|
||||
0xb8fb1e06, 0x8b7bc17b,
|
||||
0xbfa1000c, 0x847b837b,
|
||||
0x807b7d7b, 0xbefe00c1,
|
||||
0xbeff0080, 0x7e008700,
|
||||
0xe0685000, 0x701d0000,
|
||||
0x807d817d, 0x8070ff70,
|
||||
0x00000080, 0xbf0a7b7d,
|
||||
0xbfa2fff8, 0xbfa00146,
|
||||
0xbef4007e, 0x8b75ff7f,
|
||||
0x0000ffff, 0x8c75ff75,
|
||||
0x00040000, 0xbef60080,
|
||||
0xbef700ff, 0x10807fac,
|
||||
0xb8f202dc, 0x84729972,
|
||||
0x8b6eff7f, 0x04000000,
|
||||
0xbfa1003a, 0xbefe00c1,
|
||||
0x857d9972, 0x8b7d817d,
|
||||
0xbf06817d, 0xbfa20002,
|
||||
0xbeff0080, 0xbfa00001,
|
||||
0xbeff00c1, 0xb8ef4306,
|
||||
0x8b6fc16f, 0xbfa1002f,
|
||||
0x846f866f, 0x846f826f,
|
||||
0xbef6006f, 0xb8f83b05,
|
||||
0x80788178, 0xbf0d9972,
|
||||
0xbfa20002, 0x84788978,
|
||||
0xbfa00001, 0x84788a78,
|
||||
0xb8ee1e06, 0x846e8a6e,
|
||||
0x80786e78, 0x8078ff78,
|
||||
0x00000200, 0x8078ff78,
|
||||
0x00000080, 0xbef600ff,
|
||||
0x01000000, 0x857d9972,
|
||||
0x8b7d817d, 0xbf06817d,
|
||||
0xbefd0080, 0xbfa2000c,
|
||||
0xe0500000, 0x781d0000,
|
||||
0xbf8903f7, 0xdac00000,
|
||||
0x00000000, 0x807dff7d,
|
||||
0x00000080, 0x8078ff78,
|
||||
0x00000080, 0xbf0a6f7d,
|
||||
0xbfa2fff5, 0xbfa0000b,
|
||||
0xe0500000, 0x781d0000,
|
||||
0xbf8903f7, 0xdac00000,
|
||||
0x00000000, 0x807dff7d,
|
||||
0x00000100, 0x8078ff78,
|
||||
0x00000100, 0xbf0a6f7d,
|
||||
0xbfa2fff5, 0xbef80080,
|
||||
0x00000400, 0xbf0a7b7d,
|
||||
0xbfa2ffef, 0xb8fb1e06,
|
||||
0x8b7bc17b, 0xbfa1000c,
|
||||
0x847b837b, 0x807b7d7b,
|
||||
0xbefe00c1, 0xbeff0080,
|
||||
0x7e008700, 0xe0685000,
|
||||
0x701d0000, 0x807d817d,
|
||||
0x8070ff70, 0x00000080,
|
||||
0xbf0a7b7d, 0xbfa2fff8,
|
||||
0xbfa00146, 0xbef4007e,
|
||||
0x8b75ff7f, 0x0000ffff,
|
||||
0x8c75ff75, 0x00040000,
|
||||
0xbef60080, 0xbef700ff,
|
||||
0x10807fac, 0xb8f202dc,
|
||||
0x84729972, 0x8b6eff7f,
|
||||
0x04000000, 0xbfa1003a,
|
||||
0xbefe00c1, 0x857d9972,
|
||||
0x8b7d817d, 0xbf06817d,
|
||||
0xbfa20002, 0xbeff0080,
|
||||
0xbfa00001, 0xbeff00c1,
|
||||
0xb8ef3b05, 0x806f816f,
|
||||
0x846f826f, 0x857d9972,
|
||||
0x8b7d817d, 0xbf06817d,
|
||||
0xbfa20024, 0xbef600ff,
|
||||
0x01000000, 0xbeee0078,
|
||||
0x8078ff78, 0x00000200,
|
||||
0xbefd0084, 0xbf0a6f7d,
|
||||
0xbfa10050, 0xe0505000,
|
||||
0x781d0000, 0xe0505080,
|
||||
0x781d0100, 0xe0505100,
|
||||
0x781d0200, 0xe0505180,
|
||||
0x781d0300, 0xbf8903f7,
|
||||
0x7e008500, 0x7e028501,
|
||||
0x7e048502, 0x7e068503,
|
||||
0x807d847d, 0x8078ff78,
|
||||
0x00000200, 0xbf0a6f7d,
|
||||
0xbfa2ffee, 0xe0505000,
|
||||
0x6e1d0000, 0xe0505080,
|
||||
0x6e1d0100, 0xe0505100,
|
||||
0x6e1d0200, 0xe0505180,
|
||||
0x6e1d0300, 0xbf8903f7,
|
||||
0xbfa00034, 0xbef600ff,
|
||||
0x01000000, 0xbeee0078,
|
||||
0x8078ff78, 0x00000400,
|
||||
0xbefd0084, 0xbf0a6f7d,
|
||||
0xbfa10012, 0xe0505000,
|
||||
0x781d0000, 0xe0505100,
|
||||
0x781d0100, 0xe0505200,
|
||||
0x781d0200, 0xe0505300,
|
||||
0x781d0300, 0xbf8903f7,
|
||||
0x7e008500, 0x7e028501,
|
||||
0x7e048502, 0x7e068503,
|
||||
0x807d847d, 0x8078ff78,
|
||||
0x00000400, 0xbf0a6f7d,
|
||||
0xbfa2ffee, 0xb8ef1e06,
|
||||
0x8b6fc16f, 0xbfa1000e,
|
||||
0x846f836f, 0x806f7d6f,
|
||||
0xbefe00c1, 0xbeff0080,
|
||||
0xe0505000, 0x781d0000,
|
||||
0xbf8903f7, 0x7e008500,
|
||||
0x807d817d, 0x8078ff78,
|
||||
0x00000080, 0xbf0a6f7d,
|
||||
0xbfa2fff7, 0xbeff00c1,
|
||||
0xe0505000, 0x6e1d0000,
|
||||
0xe0505100, 0x6e1d0100,
|
||||
0xe0505200, 0x6e1d0200,
|
||||
0xe0505300, 0x6e1d0300,
|
||||
0xbf8903f7, 0xb8f83b05,
|
||||
0x80788178, 0xbf0d9972,
|
||||
0xbfa20002, 0x84788978,
|
||||
0xbfa00001, 0x84788a78,
|
||||
0xb8ee1e06, 0x846e8a6e,
|
||||
0x80786e78, 0x8078ff78,
|
||||
0x00000200, 0x80f8ff78,
|
||||
0x00000050, 0xbef600ff,
|
||||
0x01000000, 0xbefd00ff,
|
||||
0x0000006c, 0x80f89078,
|
||||
0xf428403a, 0xf0000000,
|
||||
0xbf89fc07, 0x80fd847d,
|
||||
0xbf800000, 0xbe804300,
|
||||
0xbe824302, 0x80f8a078,
|
||||
0xf42c403a, 0xf0000000,
|
||||
0xbf89fc07, 0x80fd887d,
|
||||
0xbf800000, 0xbe804300,
|
||||
0xbe824302, 0xbe844304,
|
||||
0xbe864306, 0x80f8c078,
|
||||
0xf430403a, 0xf0000000,
|
||||
0xbf89fc07, 0x80fd907d,
|
||||
0xbf800000, 0xbe804300,
|
||||
0xbe824302, 0xbe844304,
|
||||
0xbe864306, 0xbe884308,
|
||||
0xbe8a430a, 0xbe8c430c,
|
||||
0xbe8e430e, 0xbf06807d,
|
||||
0xbfa1fff0, 0xb980f801,
|
||||
0x00000000, 0xbfbd0000,
|
||||
0xb8ef4306, 0x8b6fc16f,
|
||||
0xbfa1002f, 0x846f866f,
|
||||
0x846f826f, 0xbef6006f,
|
||||
0xb8f83b05, 0x80788178,
|
||||
0xbf0d9972, 0xbfa20002,
|
||||
0x84788978, 0xbfa00001,
|
||||
0x84788a78, 0xb8ee1e06,
|
||||
0x846e8a6e, 0x80786e78,
|
||||
0x8078ff78, 0x00000200,
|
||||
0x8078ff78, 0x00000080,
|
||||
0xbef600ff, 0x01000000,
|
||||
0xf4205bfa, 0xf0000000,
|
||||
0x80788478, 0xf4205b3a,
|
||||
0x857d9972, 0x8b7d817d,
|
||||
0xbf06817d, 0xbefd0080,
|
||||
0xbfa2000c, 0xe0500000,
|
||||
0x781d0000, 0xbf8903f7,
|
||||
0xdac00000, 0x00000000,
|
||||
0x807dff7d, 0x00000080,
|
||||
0x8078ff78, 0x00000080,
|
||||
0xbf0a6f7d, 0xbfa2fff5,
|
||||
0xbfa0000b, 0xe0500000,
|
||||
0x781d0000, 0xbf8903f7,
|
||||
0xdac00000, 0x00000000,
|
||||
0x807dff7d, 0x00000100,
|
||||
0x8078ff78, 0x00000100,
|
||||
0xbf0a6f7d, 0xbfa2fff5,
|
||||
0xbef80080, 0xbefe00c1,
|
||||
0x857d9972, 0x8b7d817d,
|
||||
0xbf06817d, 0xbfa20002,
|
||||
0xbeff0080, 0xbfa00001,
|
||||
0xbeff00c1, 0xb8ef3b05,
|
||||
0x806f816f, 0x846f826f,
|
||||
0x857d9972, 0x8b7d817d,
|
||||
0xbf06817d, 0xbfa20024,
|
||||
0xbef600ff, 0x01000000,
|
||||
0xbeee0078, 0x8078ff78,
|
||||
0x00000200, 0xbefd0084,
|
||||
0xbf0a6f7d, 0xbfa10050,
|
||||
0xe0505000, 0x781d0000,
|
||||
0xe0505080, 0x781d0100,
|
||||
0xe0505100, 0x781d0200,
|
||||
0xe0505180, 0x781d0300,
|
||||
0xbf8903f7, 0x7e008500,
|
||||
0x7e028501, 0x7e048502,
|
||||
0x7e068503, 0x807d847d,
|
||||
0x8078ff78, 0x00000200,
|
||||
0xbf0a6f7d, 0xbfa2ffee,
|
||||
0xe0505000, 0x6e1d0000,
|
||||
0xe0505080, 0x6e1d0100,
|
||||
0xe0505100, 0x6e1d0200,
|
||||
0xe0505180, 0x6e1d0300,
|
||||
0xbf8903f7, 0xbfa00034,
|
||||
0xbef600ff, 0x01000000,
|
||||
0xbeee0078, 0x8078ff78,
|
||||
0x00000400, 0xbefd0084,
|
||||
0xbf0a6f7d, 0xbfa10012,
|
||||
0xe0505000, 0x781d0000,
|
||||
0xe0505100, 0x781d0100,
|
||||
0xe0505200, 0x781d0200,
|
||||
0xe0505300, 0x781d0300,
|
||||
0xbf8903f7, 0x7e008500,
|
||||
0x7e028501, 0x7e048502,
|
||||
0x7e068503, 0x807d847d,
|
||||
0x8078ff78, 0x00000400,
|
||||
0xbf0a6f7d, 0xbfa2ffee,
|
||||
0xb8ef1e06, 0x8b6fc16f,
|
||||
0xbfa1000e, 0x846f836f,
|
||||
0x806f7d6f, 0xbefe00c1,
|
||||
0xbeff0080, 0xe0505000,
|
||||
0x781d0000, 0xbf8903f7,
|
||||
0x7e008500, 0x807d817d,
|
||||
0x8078ff78, 0x00000080,
|
||||
0xbf0a6f7d, 0xbfa2fff7,
|
||||
0xbeff00c1, 0xe0505000,
|
||||
0x6e1d0000, 0xe0505100,
|
||||
0x6e1d0100, 0xe0505200,
|
||||
0x6e1d0200, 0xe0505300,
|
||||
0x6e1d0300, 0xbf8903f7,
|
||||
0xb8f83b05, 0x80788178,
|
||||
0xbf0d9972, 0xbfa20002,
|
||||
0x84788978, 0xbfa00001,
|
||||
0x84788a78, 0xb8ee1e06,
|
||||
0x846e8a6e, 0x80786e78,
|
||||
0x8078ff78, 0x00000200,
|
||||
0x80f8ff78, 0x00000050,
|
||||
0xbef600ff, 0x01000000,
|
||||
0xbefd00ff, 0x0000006c,
|
||||
0x80f89078, 0xf428403a,
|
||||
0xf0000000, 0xbf89fc07,
|
||||
0x80fd847d, 0xbf800000,
|
||||
0xbe804300, 0xbe824302,
|
||||
0x80f8a078, 0xf42c403a,
|
||||
0xf0000000, 0xbf89fc07,
|
||||
0x80fd887d, 0xbf800000,
|
||||
0xbe804300, 0xbe824302,
|
||||
0xbe844304, 0xbe864306,
|
||||
0x80f8c078, 0xf430403a,
|
||||
0xf0000000, 0xbf89fc07,
|
||||
0x80fd907d, 0xbf800000,
|
||||
0xbe804300, 0xbe824302,
|
||||
0xbe844304, 0xbe864306,
|
||||
0xbe884308, 0xbe8a430a,
|
||||
0xbe8c430c, 0xbe8e430e,
|
||||
0xbf06807d, 0xbfa1fff0,
|
||||
0xb980f801, 0x00000000,
|
||||
0xbfbd0000, 0xb8f83b05,
|
||||
0x80788178, 0xbf0d9972,
|
||||
0xbfa20002, 0x84788978,
|
||||
0xbfa00001, 0x84788a78,
|
||||
0xb8ee1e06, 0x846e8a6e,
|
||||
0x80786e78, 0x8078ff78,
|
||||
0x00000200, 0xbef600ff,
|
||||
0x01000000, 0xf4205bfa,
|
||||
0xf0000000, 0x80788478,
|
||||
0xf4205b7a, 0xf0000000,
|
||||
0x80788478, 0xf4205c3a,
|
||||
0xf4205b3a, 0xf0000000,
|
||||
0x80788478, 0xf4205b7a,
|
||||
0xf0000000, 0x80788478,
|
||||
0xf4205c7a, 0xf0000000,
|
||||
0x80788478, 0xf4205eba,
|
||||
0xf4205c3a, 0xf0000000,
|
||||
0x80788478, 0xf4205c7a,
|
||||
0xf0000000, 0x80788478,
|
||||
0xf4205efa, 0xf0000000,
|
||||
0x80788478, 0xf4205e7a,
|
||||
0xf4205eba, 0xf0000000,
|
||||
0x80788478, 0xf4205efa,
|
||||
0xf0000000, 0x80788478,
|
||||
0xf4205cfa, 0xf0000000,
|
||||
0x80788478, 0xf4205bba,
|
||||
0xf4205e7a, 0xf0000000,
|
||||
0x80788478, 0xf4205cfa,
|
||||
0xf0000000, 0x80788478,
|
||||
0xbf89fc07, 0xb96ef814,
|
||||
0xf4205bba, 0xf0000000,
|
||||
0x80788478, 0xbf89fc07,
|
||||
0xb96ef815, 0xbefd006f,
|
||||
0xbefe0070, 0xbeff0071,
|
||||
0x8b6f7bff, 0x000003ff,
|
||||
0xb96f4803, 0x8b6f7bff,
|
||||
0xfffff800, 0x856f8b6f,
|
||||
0xb96fa2c3, 0xb973f801,
|
||||
0xb8ee3b05, 0x806e816e,
|
||||
0xbf0d9972, 0xbfa20002,
|
||||
0x846e896e, 0xbfa00001,
|
||||
0x846e8a6e, 0xb8ef1e06,
|
||||
0x846f8a6f, 0x806e6f6e,
|
||||
0x806eff6e, 0x00000200,
|
||||
0x806e746e, 0x826f8075,
|
||||
0x8b6fff6f, 0x0000ffff,
|
||||
0xf4085c37, 0xf8000050,
|
||||
0xf4085d37, 0xf8000060,
|
||||
0xf4005e77, 0xf8000074,
|
||||
0xbf89fc07, 0x8b6dff6d,
|
||||
0x0000ffff, 0x8bfe7e7e,
|
||||
0x8bea6a6a, 0xb8eef802,
|
||||
0xbf0d866e, 0xbfa20002,
|
||||
0xb97af802, 0xbe80486c,
|
||||
0xb97af802, 0xbe804a6c,
|
||||
0xbfb00000, 0xbf9f0000,
|
||||
0xb96ef814, 0xf4205bba,
|
||||
0xf0000000, 0x80788478,
|
||||
0xbf89fc07, 0xb96ef815,
|
||||
0xbefd006f, 0xbefe0070,
|
||||
0xbeff0071, 0x8b6f7bff,
|
||||
0x000003ff, 0xb96f4803,
|
||||
0x8b6f7bff, 0xfffff800,
|
||||
0x856f8b6f, 0xb96fa2c3,
|
||||
0xb973f801, 0xb8ee3b05,
|
||||
0x806e816e, 0xbf0d9972,
|
||||
0xbfa20002, 0x846e896e,
|
||||
0xbfa00001, 0x846e8a6e,
|
||||
0xb8ef1e06, 0x846f8a6f,
|
||||
0x806e6f6e, 0x806eff6e,
|
||||
0x00000200, 0x806e746e,
|
||||
0x826f8075, 0x8b6fff6f,
|
||||
0x0000ffff, 0xf4085c37,
|
||||
0xf8000050, 0xf4085d37,
|
||||
0xf8000060, 0xf4005e77,
|
||||
0xf8000074, 0xbf89fc07,
|
||||
0x8b6dff6d, 0x0000ffff,
|
||||
0x8bfe7e7e, 0x8bea6a6a,
|
||||
0xb8eef802, 0xbf0d866e,
|
||||
0xbfa20002, 0xb97af802,
|
||||
0xbe80486c, 0xb97af802,
|
||||
0xbe804a6c, 0xbfb00000,
|
||||
0xbf9f0000, 0xbf9f0000,
|
||||
0xbf9f0000, 0xbf9f0000,
|
||||
0xbf9f0000, 0x00000000,
|
||||
};
|
||||
|
|
|
@ -186,6 +186,12 @@ L_SKIP_RESTORE:
|
|||
s_getreg_b32 s_save_trapsts, hwreg(HW_REG_TRAPSTS)
|
||||
|
||||
#if SW_SA_TRAP
|
||||
// If ttmp1[30] is set then issue s_barrier to unblock dependent waves.
|
||||
s_bitcmp1_b32 s_save_pc_hi, 30
|
||||
s_cbranch_scc0 L_TRAP_NO_BARRIER
|
||||
s_barrier
|
||||
|
||||
L_TRAP_NO_BARRIER:
|
||||
// If ttmp1[31] is set then trap may occur early.
|
||||
// Spin wait until SAVECTX exception is raised.
|
||||
s_bitcmp1_b32 s_save_pc_hi, 31
|
||||
|
|
|
@ -50,16 +50,6 @@ static inline unsigned int get_and_inc_gpu_processor_id(
|
|||
return current_id;
|
||||
}
|
||||
|
||||
/* Static table to describe GPU Cache information */
|
||||
struct kfd_gpu_cache_info {
|
||||
uint32_t cache_size;
|
||||
uint32_t cache_level;
|
||||
uint32_t flags;
|
||||
/* Indicates how many Compute Units share this cache
|
||||
* within a SA. Value = 1 indicates the cache is not shared
|
||||
*/
|
||||
uint32_t num_cu_shared;
|
||||
};
|
||||
|
||||
static struct kfd_gpu_cache_info kaveri_cache_info[] = {
|
||||
{
|
||||
|
@ -795,6 +785,150 @@ static struct kfd_gpu_cache_info yellow_carp_cache_info[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct kfd_gpu_cache_info gfx1037_cache_info[] = {
|
||||
{
|
||||
/* TCP L1 Cache per CU */
|
||||
.cache_size = 16,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 1,
|
||||
},
|
||||
{
|
||||
/* Scalar L1 Instruction Cache per SQC */
|
||||
.cache_size = 32,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_INST_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* Scalar L1 Data Cache per SQC */
|
||||
.cache_size = 16,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* GL1 Data Cache per SA */
|
||||
.cache_size = 128,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* L2 Data Cache per GPU (Total Tex Cache) */
|
||||
.cache_size = 256,
|
||||
.cache_level = 2,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static struct kfd_gpu_cache_info gc_10_3_6_cache_info[] = {
|
||||
{
|
||||
/* TCP L1 Cache per CU */
|
||||
.cache_size = 16,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 1,
|
||||
},
|
||||
{
|
||||
/* Scalar L1 Instruction Cache per SQC */
|
||||
.cache_size = 32,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_INST_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* Scalar L1 Data Cache per SQC */
|
||||
.cache_size = 16,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* GL1 Data Cache per SA */
|
||||
.cache_size = 128,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* L2 Data Cache per GPU (Total Tex Cache) */
|
||||
.cache_size = 256,
|
||||
.cache_level = 2,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static struct kfd_gpu_cache_info dummy_cache_info[] = {
|
||||
{
|
||||
/* TCP L1 Cache per CU */
|
||||
.cache_size = 16,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 1,
|
||||
},
|
||||
{
|
||||
/* Scalar L1 Instruction Cache per SQC */
|
||||
.cache_size = 32,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_INST_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* Scalar L1 Data Cache per SQC */
|
||||
.cache_size = 16,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 2,
|
||||
},
|
||||
{
|
||||
/* GL1 Data Cache per SA */
|
||||
.cache_size = 128,
|
||||
.cache_level = 1,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 6,
|
||||
},
|
||||
{
|
||||
/* L2 Data Cache per GPU (Total Tex Cache) */
|
||||
.cache_size = 2048,
|
||||
.cache_level = 2,
|
||||
.flags = (CRAT_CACHE_FLAGS_ENABLED |
|
||||
CRAT_CACHE_FLAGS_DATA_CACHE |
|
||||
CRAT_CACHE_FLAGS_SIMD_CACHE),
|
||||
.num_cu_shared = 6,
|
||||
},
|
||||
};
|
||||
|
||||
static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev,
|
||||
struct crat_subtype_computeunit *cu)
|
||||
{
|
||||
|
@ -975,9 +1109,13 @@ static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache,
|
|||
props->cachelines_per_tag = cache->lines_per_tag;
|
||||
props->cache_assoc = cache->associativity;
|
||||
props->cache_latency = cache->cache_latency;
|
||||
|
||||
memcpy(props->sibling_map, cache->sibling_map,
|
||||
sizeof(props->sibling_map));
|
||||
|
||||
/* set the sibling_map_size as 32 for CRAT from ACPI */
|
||||
props->sibling_map_size = CRAT_SIBLINGMAP_SIZE;
|
||||
|
||||
if (cache->flags & CRAT_CACHE_FLAGS_DATA_CACHE)
|
||||
props->cache_type |= HSA_CACHE_TYPE_DATA;
|
||||
if (cache->flags & CRAT_CACHE_FLAGS_INST_CACHE)
|
||||
|
@ -987,7 +1125,6 @@ static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache,
|
|||
if (cache->flags & CRAT_CACHE_FLAGS_SIMD_CACHE)
|
||||
props->cache_type |= HSA_CACHE_TYPE_HSACU;
|
||||
|
||||
dev->cache_count++;
|
||||
dev->node_props.caches_count++;
|
||||
list_add_tail(&props->list, &dev->cache_props);
|
||||
|
||||
|
@ -1195,125 +1332,6 @@ int kfd_parse_crat_table(void *crat_image, struct list_head *device_list,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Helper function. See kfd_fill_gpu_cache_info for parameter description */
|
||||
static int fill_in_l1_pcache(struct crat_subtype_cache *pcache,
|
||||
struct kfd_gpu_cache_info *pcache_info,
|
||||
struct kfd_cu_info *cu_info,
|
||||
int mem_available,
|
||||
int cu_bitmask,
|
||||
int cache_type, unsigned int cu_processor_id,
|
||||
int cu_block)
|
||||
{
|
||||
unsigned int cu_sibling_map_mask;
|
||||
int first_active_cu;
|
||||
|
||||
/* First check if enough memory is available */
|
||||
if (sizeof(struct crat_subtype_cache) > mem_available)
|
||||
return -ENOMEM;
|
||||
|
||||
cu_sibling_map_mask = cu_bitmask;
|
||||
cu_sibling_map_mask >>= cu_block;
|
||||
cu_sibling_map_mask &=
|
||||
((1 << pcache_info[cache_type].num_cu_shared) - 1);
|
||||
first_active_cu = ffs(cu_sibling_map_mask);
|
||||
|
||||
/* CU could be inactive. In case of shared cache find the first active
|
||||
* CU. and incase of non-shared cache check if the CU is inactive. If
|
||||
* inactive active skip it
|
||||
*/
|
||||
if (first_active_cu) {
|
||||
memset(pcache, 0, sizeof(struct crat_subtype_cache));
|
||||
pcache->type = CRAT_SUBTYPE_CACHE_AFFINITY;
|
||||
pcache->length = sizeof(struct crat_subtype_cache);
|
||||
pcache->flags = pcache_info[cache_type].flags;
|
||||
pcache->processor_id_low = cu_processor_id
|
||||
+ (first_active_cu - 1);
|
||||
pcache->cache_level = pcache_info[cache_type].cache_level;
|
||||
pcache->cache_size = pcache_info[cache_type].cache_size;
|
||||
|
||||
/* Sibling map is w.r.t processor_id_low, so shift out
|
||||
* inactive CU
|
||||
*/
|
||||
cu_sibling_map_mask =
|
||||
cu_sibling_map_mask >> (first_active_cu - 1);
|
||||
|
||||
pcache->sibling_map[0] = (uint8_t)(cu_sibling_map_mask & 0xFF);
|
||||
pcache->sibling_map[1] =
|
||||
(uint8_t)((cu_sibling_map_mask >> 8) & 0xFF);
|
||||
pcache->sibling_map[2] =
|
||||
(uint8_t)((cu_sibling_map_mask >> 16) & 0xFF);
|
||||
pcache->sibling_map[3] =
|
||||
(uint8_t)((cu_sibling_map_mask >> 24) & 0xFF);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Helper function. See kfd_fill_gpu_cache_info for parameter description */
|
||||
static int fill_in_l2_l3_pcache(struct crat_subtype_cache *pcache,
|
||||
struct kfd_gpu_cache_info *pcache_info,
|
||||
struct kfd_cu_info *cu_info,
|
||||
int mem_available,
|
||||
int cache_type, unsigned int cu_processor_id)
|
||||
{
|
||||
unsigned int cu_sibling_map_mask;
|
||||
int first_active_cu;
|
||||
int i, j, k;
|
||||
|
||||
/* First check if enough memory is available */
|
||||
if (sizeof(struct crat_subtype_cache) > mem_available)
|
||||
return -ENOMEM;
|
||||
|
||||
cu_sibling_map_mask = cu_info->cu_bitmap[0][0];
|
||||
cu_sibling_map_mask &=
|
||||
((1 << pcache_info[cache_type].num_cu_shared) - 1);
|
||||
first_active_cu = ffs(cu_sibling_map_mask);
|
||||
|
||||
/* CU could be inactive. In case of shared cache find the first active
|
||||
* CU. and incase of non-shared cache check if the CU is inactive. If
|
||||
* inactive active skip it
|
||||
*/
|
||||
if (first_active_cu) {
|
||||
memset(pcache, 0, sizeof(struct crat_subtype_cache));
|
||||
pcache->type = CRAT_SUBTYPE_CACHE_AFFINITY;
|
||||
pcache->length = sizeof(struct crat_subtype_cache);
|
||||
pcache->flags = pcache_info[cache_type].flags;
|
||||
pcache->processor_id_low = cu_processor_id
|
||||
+ (first_active_cu - 1);
|
||||
pcache->cache_level = pcache_info[cache_type].cache_level;
|
||||
pcache->cache_size = pcache_info[cache_type].cache_size;
|
||||
|
||||
/* Sibling map is w.r.t processor_id_low, so shift out
|
||||
* inactive CU
|
||||
*/
|
||||
cu_sibling_map_mask =
|
||||
cu_sibling_map_mask >> (first_active_cu - 1);
|
||||
k = 0;
|
||||
for (i = 0; i < cu_info->num_shader_engines; i++) {
|
||||
for (j = 0; j < cu_info->num_shader_arrays_per_engine;
|
||||
j++) {
|
||||
pcache->sibling_map[k] =
|
||||
(uint8_t)(cu_sibling_map_mask & 0xFF);
|
||||
pcache->sibling_map[k+1] =
|
||||
(uint8_t)((cu_sibling_map_mask >> 8) & 0xFF);
|
||||
pcache->sibling_map[k+2] =
|
||||
(uint8_t)((cu_sibling_map_mask >> 16) & 0xFF);
|
||||
pcache->sibling_map[k+3] =
|
||||
(uint8_t)((cu_sibling_map_mask >> 24) & 0xFF);
|
||||
k += 4;
|
||||
cu_sibling_map_mask =
|
||||
cu_info->cu_bitmap[i % 4][j + i / 4];
|
||||
cu_sibling_map_mask &= (
|
||||
(1 << pcache_info[cache_type].num_cu_shared)
|
||||
- 1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define KFD_MAX_CACHE_TYPES 6
|
||||
|
||||
static int kfd_fill_gpu_cache_info_from_gfx_config(struct kfd_dev *kdev,
|
||||
struct kfd_gpu_cache_info *pcache_info)
|
||||
|
@ -1387,222 +1405,133 @@ static int kfd_fill_gpu_cache_info_from_gfx_config(struct kfd_dev *kdev,
|
|||
return i;
|
||||
}
|
||||
|
||||
/* kfd_fill_gpu_cache_info - Fill GPU cache info using kfd_gpu_cache_info
|
||||
* tables
|
||||
*
|
||||
* @kdev - [IN] GPU device
|
||||
* @gpu_processor_id - [IN] GPU processor ID to which these caches
|
||||
* associate
|
||||
* @available_size - [IN] Amount of memory available in pcache
|
||||
* @cu_info - [IN] Compute Unit info obtained from KGD
|
||||
* @pcache - [OUT] memory into which cache data is to be filled in.
|
||||
* @size_filled - [OUT] amount of data used up in pcache.
|
||||
* @num_of_entries - [OUT] number of caches added
|
||||
*/
|
||||
static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
|
||||
int gpu_processor_id,
|
||||
int available_size,
|
||||
struct kfd_cu_info *cu_info,
|
||||
struct crat_subtype_cache *pcache,
|
||||
int *size_filled,
|
||||
int *num_of_entries)
|
||||
int kfd_get_gpu_cache_info(struct kfd_dev *kdev, struct kfd_gpu_cache_info **pcache_info)
|
||||
{
|
||||
struct kfd_gpu_cache_info *pcache_info;
|
||||
struct kfd_gpu_cache_info cache_info[KFD_MAX_CACHE_TYPES];
|
||||
int num_of_cache_types = 0;
|
||||
int i, j, k;
|
||||
int ct = 0;
|
||||
int mem_available = available_size;
|
||||
unsigned int cu_processor_id;
|
||||
int ret;
|
||||
unsigned int num_cu_shared;
|
||||
|
||||
switch (kdev->adev->asic_type) {
|
||||
case CHIP_KAVERI:
|
||||
pcache_info = kaveri_cache_info;
|
||||
*pcache_info = kaveri_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(kaveri_cache_info);
|
||||
break;
|
||||
case CHIP_HAWAII:
|
||||
pcache_info = hawaii_cache_info;
|
||||
*pcache_info = hawaii_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(hawaii_cache_info);
|
||||
break;
|
||||
case CHIP_CARRIZO:
|
||||
pcache_info = carrizo_cache_info;
|
||||
*pcache_info = carrizo_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(carrizo_cache_info);
|
||||
break;
|
||||
case CHIP_TONGA:
|
||||
pcache_info = tonga_cache_info;
|
||||
*pcache_info = tonga_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(tonga_cache_info);
|
||||
break;
|
||||
case CHIP_FIJI:
|
||||
pcache_info = fiji_cache_info;
|
||||
*pcache_info = fiji_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(fiji_cache_info);
|
||||
break;
|
||||
case CHIP_POLARIS10:
|
||||
pcache_info = polaris10_cache_info;
|
||||
*pcache_info = polaris10_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(polaris10_cache_info);
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
pcache_info = polaris11_cache_info;
|
||||
*pcache_info = polaris11_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(polaris11_cache_info);
|
||||
break;
|
||||
case CHIP_POLARIS12:
|
||||
pcache_info = polaris12_cache_info;
|
||||
*pcache_info = polaris12_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(polaris12_cache_info);
|
||||
break;
|
||||
case CHIP_VEGAM:
|
||||
pcache_info = vegam_cache_info;
|
||||
*pcache_info = vegam_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(vegam_cache_info);
|
||||
break;
|
||||
default:
|
||||
switch (KFD_GC_VERSION(kdev)) {
|
||||
case IP_VERSION(9, 0, 1):
|
||||
pcache_info = vega10_cache_info;
|
||||
*pcache_info = vega10_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(vega10_cache_info);
|
||||
break;
|
||||
case IP_VERSION(9, 2, 1):
|
||||
pcache_info = vega12_cache_info;
|
||||
*pcache_info = vega12_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(vega12_cache_info);
|
||||
break;
|
||||
case IP_VERSION(9, 4, 0):
|
||||
case IP_VERSION(9, 4, 1):
|
||||
pcache_info = vega20_cache_info;
|
||||
*pcache_info = vega20_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(vega20_cache_info);
|
||||
break;
|
||||
case IP_VERSION(9, 4, 2):
|
||||
pcache_info = aldebaran_cache_info;
|
||||
*pcache_info = aldebaran_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(aldebaran_cache_info);
|
||||
break;
|
||||
case IP_VERSION(9, 1, 0):
|
||||
case IP_VERSION(9, 2, 2):
|
||||
pcache_info = raven_cache_info;
|
||||
*pcache_info = raven_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(raven_cache_info);
|
||||
break;
|
||||
case IP_VERSION(9, 3, 0):
|
||||
pcache_info = renoir_cache_info;
|
||||
*pcache_info = renoir_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(renoir_cache_info);
|
||||
break;
|
||||
case IP_VERSION(10, 1, 10):
|
||||
case IP_VERSION(10, 1, 2):
|
||||
case IP_VERSION(10, 1, 3):
|
||||
case IP_VERSION(10, 1, 4):
|
||||
pcache_info = navi10_cache_info;
|
||||
*pcache_info = navi10_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(navi10_cache_info);
|
||||
break;
|
||||
case IP_VERSION(10, 1, 1):
|
||||
pcache_info = navi14_cache_info;
|
||||
*pcache_info = navi14_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(navi14_cache_info);
|
||||
break;
|
||||
case IP_VERSION(10, 3, 0):
|
||||
pcache_info = sienna_cichlid_cache_info;
|
||||
*pcache_info = sienna_cichlid_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(sienna_cichlid_cache_info);
|
||||
break;
|
||||
case IP_VERSION(10, 3, 2):
|
||||
pcache_info = navy_flounder_cache_info;
|
||||
*pcache_info = navy_flounder_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(navy_flounder_cache_info);
|
||||
break;
|
||||
case IP_VERSION(10, 3, 4):
|
||||
pcache_info = dimgrey_cavefish_cache_info;
|
||||
*pcache_info = dimgrey_cavefish_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(dimgrey_cavefish_cache_info);
|
||||
break;
|
||||
case IP_VERSION(10, 3, 1):
|
||||
pcache_info = vangogh_cache_info;
|
||||
*pcache_info = vangogh_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(vangogh_cache_info);
|
||||
break;
|
||||
case IP_VERSION(10, 3, 5):
|
||||
pcache_info = beige_goby_cache_info;
|
||||
*pcache_info = beige_goby_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(beige_goby_cache_info);
|
||||
break;
|
||||
case IP_VERSION(10, 3, 3):
|
||||
case IP_VERSION(10, 3, 6): /* TODO: Double check these on production silicon */
|
||||
case IP_VERSION(10, 3, 7): /* TODO: Double check these on production silicon */
|
||||
pcache_info = yellow_carp_cache_info;
|
||||
*pcache_info = yellow_carp_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(yellow_carp_cache_info);
|
||||
break;
|
||||
case IP_VERSION(10, 3, 6):
|
||||
*pcache_info = gc_10_3_6_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(gc_10_3_6_cache_info);
|
||||
break;
|
||||
case IP_VERSION(10, 3, 7):
|
||||
*pcache_info = gfx1037_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(gfx1037_cache_info);
|
||||
break;
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
pcache_info = cache_info;
|
||||
num_of_cache_types =
|
||||
kfd_fill_gpu_cache_info_from_gfx_config(kdev, pcache_info);
|
||||
kfd_fill_gpu_cache_info_from_gfx_config(kdev, *pcache_info);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
*size_filled = 0;
|
||||
*num_of_entries = 0;
|
||||
|
||||
/* For each type of cache listed in the kfd_gpu_cache_info table,
|
||||
* go through all available Compute Units.
|
||||
* The [i,j,k] loop will
|
||||
* if kfd_gpu_cache_info.num_cu_shared = 1
|
||||
* will parse through all available CU
|
||||
* If (kfd_gpu_cache_info.num_cu_shared != 1)
|
||||
* then it will consider only one CU from
|
||||
* the shared unit
|
||||
*/
|
||||
|
||||
for (ct = 0; ct < num_of_cache_types; ct++) {
|
||||
cu_processor_id = gpu_processor_id;
|
||||
if (pcache_info[ct].cache_level == 1) {
|
||||
for (i = 0; i < cu_info->num_shader_engines; i++) {
|
||||
for (j = 0; j < cu_info->num_shader_arrays_per_engine; j++) {
|
||||
for (k = 0; k < cu_info->num_cu_per_sh;
|
||||
k += pcache_info[ct].num_cu_shared) {
|
||||
ret = fill_in_l1_pcache(pcache,
|
||||
pcache_info,
|
||||
cu_info,
|
||||
mem_available,
|
||||
cu_info->cu_bitmap[i % 4][j + i / 4],
|
||||
ct,
|
||||
cu_processor_id,
|
||||
k);
|
||||
|
||||
if (ret < 0)
|
||||
*pcache_info = dummy_cache_info;
|
||||
num_of_cache_types = ARRAY_SIZE(dummy_cache_info);
|
||||
pr_warn("dummy cache info is used temporarily and real cache info need update later.\n");
|
||||
break;
|
||||
|
||||
if (!ret) {
|
||||
pcache++;
|
||||
(*num_of_entries)++;
|
||||
mem_available -= sizeof(*pcache);
|
||||
(*size_filled) += sizeof(*pcache);
|
||||
}
|
||||
|
||||
/* Move to next CU block */
|
||||
num_cu_shared = ((k + pcache_info[ct].num_cu_shared) <=
|
||||
cu_info->num_cu_per_sh) ?
|
||||
pcache_info[ct].num_cu_shared :
|
||||
(cu_info->num_cu_per_sh - k);
|
||||
cu_processor_id += num_cu_shared;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = fill_in_l2_l3_pcache(pcache,
|
||||
pcache_info,
|
||||
cu_info,
|
||||
mem_available,
|
||||
ct,
|
||||
cu_processor_id);
|
||||
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
if (!ret) {
|
||||
pcache++;
|
||||
(*num_of_entries)++;
|
||||
mem_available -= sizeof(*pcache);
|
||||
(*size_filled) += sizeof(*pcache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pr_debug("Added [%d] GPU cache entries\n", *num_of_entries);
|
||||
|
||||
return 0;
|
||||
return num_of_cache_types;
|
||||
}
|
||||
|
||||
static bool kfd_ignore_crat(void)
|
||||
|
@ -1961,8 +1890,8 @@ static void kfd_find_numa_node_in_srat(struct kfd_dev *kdev)
|
|||
struct acpi_table_header *table_header = NULL;
|
||||
struct acpi_subtable_header *sub_header = NULL;
|
||||
unsigned long table_end, subtable_len;
|
||||
u32 pci_id = pci_domain_nr(kdev->pdev->bus) << 16 |
|
||||
pci_dev_id(kdev->pdev);
|
||||
u32 pci_id = pci_domain_nr(kdev->adev->pdev->bus) << 16 |
|
||||
pci_dev_id(kdev->adev->pdev);
|
||||
u32 bdf;
|
||||
acpi_status status;
|
||||
struct acpi_srat_cpu_affinity *cpu;
|
||||
|
@ -2037,7 +1966,7 @@ static void kfd_find_numa_node_in_srat(struct kfd_dev *kdev)
|
|||
numa_node = 0;
|
||||
|
||||
if (numa_node != NUMA_NO_NODE)
|
||||
set_dev_node(&kdev->pdev->dev, numa_node);
|
||||
set_dev_node(&kdev->adev->pdev->dev, numa_node);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2098,14 +2027,14 @@ static int kfd_fill_gpu_direct_io_link_to_cpu(int *avail_size,
|
|||
sub_type_hdr->proximity_domain_from = proximity_domain;
|
||||
|
||||
#ifdef CONFIG_ACPI_NUMA
|
||||
if (kdev->pdev->dev.numa_node == NUMA_NO_NODE)
|
||||
if (kdev->adev->pdev->dev.numa_node == NUMA_NO_NODE)
|
||||
kfd_find_numa_node_in_srat(kdev);
|
||||
#endif
|
||||
#ifdef CONFIG_NUMA
|
||||
if (kdev->pdev->dev.numa_node == NUMA_NO_NODE)
|
||||
if (kdev->adev->pdev->dev.numa_node == NUMA_NO_NODE)
|
||||
sub_type_hdr->proximity_domain_to = 0;
|
||||
else
|
||||
sub_type_hdr->proximity_domain_to = kdev->pdev->dev.numa_node;
|
||||
sub_type_hdr->proximity_domain_to = kdev->adev->pdev->dev.numa_node;
|
||||
#else
|
||||
sub_type_hdr->proximity_domain_to = 0;
|
||||
#endif
|
||||
|
@ -2161,8 +2090,6 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image,
|
|||
struct kfd_cu_info cu_info;
|
||||
int avail_size = *size;
|
||||
uint32_t total_num_of_cu;
|
||||
int num_of_cache_entries = 0;
|
||||
int cache_mem_filled = 0;
|
||||
uint32_t nid = 0;
|
||||
int ret = 0;
|
||||
|
||||
|
@ -2263,31 +2190,12 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image,
|
|||
crat_table->length += sizeof(struct crat_subtype_memory);
|
||||
crat_table->total_entries++;
|
||||
|
||||
/* TODO: Fill in cache information. This information is NOT readily
|
||||
* available in KGD
|
||||
*/
|
||||
sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr +
|
||||
sub_type_hdr->length);
|
||||
ret = kfd_fill_gpu_cache_info(kdev, cu->processor_id_low,
|
||||
avail_size,
|
||||
&cu_info,
|
||||
(struct crat_subtype_cache *)sub_type_hdr,
|
||||
&cache_mem_filled,
|
||||
&num_of_cache_entries);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
crat_table->length += cache_mem_filled;
|
||||
crat_table->total_entries += num_of_cache_entries;
|
||||
avail_size -= cache_mem_filled;
|
||||
|
||||
/* Fill in Subtype: IO_LINKS
|
||||
* Only direct links are added here which is Link from GPU to
|
||||
* its NUMA node. Indirect links are added by userspace.
|
||||
*/
|
||||
sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr +
|
||||
cache_mem_filled);
|
||||
sub_type_hdr->length);
|
||||
ret = kfd_fill_gpu_direct_io_link_to_cpu(&avail_size, kdev,
|
||||
(struct crat_subtype_iolink *)sub_type_hdr, proximity_domain);
|
||||
|
||||
|
|
|
@ -29,11 +29,10 @@
|
|||
#pragma pack(1)
|
||||
|
||||
/*
|
||||
* 4CC signature values for the CRAT and CDIT ACPI tables
|
||||
* 4CC signature value for the CRAT ACPI table
|
||||
*/
|
||||
|
||||
#define CRAT_SIGNATURE "CRAT"
|
||||
#define CDIT_SIGNATURE "CDIT"
|
||||
|
||||
/*
|
||||
* Component Resource Association Table (CRAT)
|
||||
|
@ -292,31 +291,22 @@ struct crat_subtype_generic {
|
|||
uint32_t flags;
|
||||
};
|
||||
|
||||
/*
|
||||
* Component Locality Distance Information Table (CDIT)
|
||||
*/
|
||||
#define CDIT_OEMID_LENGTH 6
|
||||
#define CDIT_OEMTABLEID_LENGTH 8
|
||||
|
||||
struct cdit_header {
|
||||
uint32_t signature;
|
||||
uint32_t length;
|
||||
uint8_t revision;
|
||||
uint8_t checksum;
|
||||
uint8_t oem_id[CDIT_OEMID_LENGTH];
|
||||
uint8_t oem_table_id[CDIT_OEMTABLEID_LENGTH];
|
||||
uint32_t oem_revision;
|
||||
uint32_t creator_id;
|
||||
uint32_t creator_revision;
|
||||
uint32_t total_entries;
|
||||
uint16_t num_domains;
|
||||
uint8_t entry[1];
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
struct kfd_dev;
|
||||
|
||||
/* Static table to describe GPU Cache information */
|
||||
struct kfd_gpu_cache_info {
|
||||
uint32_t cache_size;
|
||||
uint32_t cache_level;
|
||||
uint32_t flags;
|
||||
/* Indicates how many Compute Units share this cache
|
||||
* within a SA. Value = 1 indicates the cache is not shared
|
||||
*/
|
||||
uint32_t num_cu_shared;
|
||||
};
|
||||
int kfd_get_gpu_cache_info(struct kfd_dev *kdev, struct kfd_gpu_cache_info **pcache_info);
|
||||
|
||||
int kfd_create_crat_image_acpi(void **crat_image, size_t *size);
|
||||
void kfd_destroy_crat_image(void *crat_image);
|
||||
int kfd_parse_crat_table(void *crat_image, struct list_head *device_list,
|
||||
|
|
|
@ -227,7 +227,6 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
|
|||
{
|
||||
struct kfd_dev *kfd = NULL;
|
||||
const struct kfd2kgd_calls *f2g = NULL;
|
||||
struct pci_dev *pdev = adev->pdev;
|
||||
uint32_t gfx_target_version = 0;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
|
@ -429,7 +428,6 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
|
|||
|
||||
kfd->adev = adev;
|
||||
kfd_device_info_init(kfd, vf, gfx_target_version);
|
||||
kfd->pdev = pdev;
|
||||
kfd->init_complete = false;
|
||||
kfd->kfd2kgd = f2g;
|
||||
atomic_set(&kfd->compute_profile, 0);
|
||||
|
@ -511,12 +509,10 @@ static void kfd_smi_init(struct kfd_dev *dev)
|
|||
}
|
||||
|
||||
bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
||||
struct drm_device *ddev,
|
||||
const struct kgd2kfd_shared_resources *gpu_resources)
|
||||
{
|
||||
unsigned int size, map_process_packet_size;
|
||||
|
||||
kfd->ddev = ddev;
|
||||
kfd->mec_fw_version = amdgpu_amdkfd_get_fw_version(kfd->adev,
|
||||
KGD_ENGINE_MEC1);
|
||||
kfd->mec2_fw_version = amdgpu_amdkfd_get_fw_version(kfd->adev,
|
||||
|
@ -541,7 +537,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
|||
kfd->mec_fw_version < kfd->device_info.no_atomic_fw_version)) {
|
||||
dev_info(kfd_device,
|
||||
"skipped device %x:%x, PCI rejects atomics %d<%d\n",
|
||||
kfd->pdev->vendor, kfd->pdev->device,
|
||||
kfd->adev->pdev->vendor, kfd->adev->pdev->device,
|
||||
kfd->mec_fw_version,
|
||||
kfd->device_info.no_atomic_fw_version);
|
||||
return false;
|
||||
|
@ -650,8 +646,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
|||
kfd_smi_init(kfd);
|
||||
|
||||
kfd->init_complete = true;
|
||||
dev_info(kfd_device, "added device %x:%x\n", kfd->pdev->vendor,
|
||||
kfd->pdev->device);
|
||||
dev_info(kfd_device, "added device %x:%x\n", kfd->adev->pdev->vendor,
|
||||
kfd->adev->pdev->device);
|
||||
|
||||
pr_debug("Starting kfd with the following scheduling policy %d\n",
|
||||
kfd->dqm->sched_policy);
|
||||
|
@ -676,7 +672,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
|||
amdgpu_amdkfd_free_gws(kfd->adev, kfd->gws);
|
||||
dev_err(kfd_device,
|
||||
"device %x:%x NOT added due to errors\n",
|
||||
kfd->pdev->vendor, kfd->pdev->device);
|
||||
kfd->adev->pdev->vendor, kfd->adev->pdev->device);
|
||||
out:
|
||||
return kfd->init_complete;
|
||||
}
|
||||
|
@ -789,7 +785,7 @@ int kgd2kfd_resume_iommu(struct kfd_dev *kfd)
|
|||
if (err)
|
||||
dev_err(kfd_device,
|
||||
"Failed to resume IOMMU for device %x:%x\n",
|
||||
kfd->pdev->vendor, kfd->pdev->device);
|
||||
kfd->adev->pdev->vendor, kfd->adev->pdev->device);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -801,7 +797,7 @@ static int kfd_resume(struct kfd_dev *kfd)
|
|||
if (err)
|
||||
dev_err(kfd_device,
|
||||
"Error starting queue manager for device %x:%x\n",
|
||||
kfd->pdev->vendor, kfd->pdev->device);
|
||||
kfd->adev->pdev->vendor, kfd->adev->pdev->device);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ int kfd_iommu_check_device(struct kfd_dev *kfd)
|
|||
return -ENODEV;
|
||||
|
||||
iommu_info.flags = 0;
|
||||
err = amd_iommu_device_info(kfd->pdev, &iommu_info);
|
||||
err = amd_iommu_device_info(kfd->adev->pdev, &iommu_info);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -71,7 +71,7 @@ int kfd_iommu_device_init(struct kfd_dev *kfd)
|
|||
return 0;
|
||||
|
||||
iommu_info.flags = 0;
|
||||
err = amd_iommu_device_info(kfd->pdev, &iommu_info);
|
||||
err = amd_iommu_device_info(kfd->adev->pdev, &iommu_info);
|
||||
if (err < 0) {
|
||||
dev_err(kfd_device,
|
||||
"error getting iommu info. is the iommu enabled?\n");
|
||||
|
@ -121,7 +121,7 @@ int kfd_iommu_bind_process_to_device(struct kfd_process_device *pdd)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = amd_iommu_bind_pasid(dev->pdev, p->pasid, p->lead_thread);
|
||||
err = amd_iommu_bind_pasid(dev->adev->pdev, p->pasid, p->lead_thread);
|
||||
if (!err)
|
||||
pdd->bound = PDD_BOUND;
|
||||
|
||||
|
@ -139,7 +139,8 @@ void kfd_iommu_unbind_process(struct kfd_process *p)
|
|||
|
||||
for (i = 0; i < p->n_pdds; i++)
|
||||
if (p->pdds[i]->bound == PDD_BOUND)
|
||||
amd_iommu_unbind_pasid(p->pdds[i]->dev->pdev, p->pasid);
|
||||
amd_iommu_unbind_pasid(p->pdds[i]->dev->adev->pdev,
|
||||
p->pasid);
|
||||
}
|
||||
|
||||
/* Callback for process shutdown invoked by the IOMMU driver */
|
||||
|
@ -222,7 +223,7 @@ static int kfd_bind_processes_to_device(struct kfd_dev *kfd)
|
|||
continue;
|
||||
}
|
||||
|
||||
err = amd_iommu_bind_pasid(kfd->pdev, p->pasid,
|
||||
err = amd_iommu_bind_pasid(kfd->adev->pdev, p->pasid,
|
||||
p->lead_thread);
|
||||
if (err < 0) {
|
||||
pr_err("Unexpected pasid 0x%x binding failure\n",
|
||||
|
@ -282,9 +283,9 @@ void kfd_iommu_suspend(struct kfd_dev *kfd)
|
|||
|
||||
kfd_unbind_processes_from_device(kfd);
|
||||
|
||||
amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL);
|
||||
amd_iommu_set_invalid_ppr_cb(kfd->pdev, NULL);
|
||||
amd_iommu_free_device(kfd->pdev);
|
||||
amd_iommu_set_invalidate_ctx_cb(kfd->adev->pdev, NULL);
|
||||
amd_iommu_set_invalid_ppr_cb(kfd->adev->pdev, NULL);
|
||||
amd_iommu_free_device(kfd->adev->pdev);
|
||||
}
|
||||
|
||||
/** kfd_iommu_resume - Restore IOMMU after resume
|
||||
|
@ -302,20 +303,20 @@ int kfd_iommu_resume(struct kfd_dev *kfd)
|
|||
|
||||
pasid_limit = kfd_get_pasid_limit();
|
||||
|
||||
err = amd_iommu_init_device(kfd->pdev, pasid_limit);
|
||||
err = amd_iommu_init_device(kfd->adev->pdev, pasid_limit);
|
||||
if (err)
|
||||
return -ENXIO;
|
||||
|
||||
amd_iommu_set_invalidate_ctx_cb(kfd->pdev,
|
||||
amd_iommu_set_invalidate_ctx_cb(kfd->adev->pdev,
|
||||
iommu_pasid_shutdown_callback);
|
||||
amd_iommu_set_invalid_ppr_cb(kfd->pdev,
|
||||
amd_iommu_set_invalid_ppr_cb(kfd->adev->pdev,
|
||||
iommu_invalid_ppr_cb);
|
||||
|
||||
err = kfd_bind_processes_to_device(kfd);
|
||||
if (err) {
|
||||
amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL);
|
||||
amd_iommu_set_invalid_ppr_cb(kfd->pdev, NULL);
|
||||
amd_iommu_free_device(kfd->pdev);
|
||||
amd_iommu_set_invalidate_ctx_cb(kfd->adev->pdev, NULL);
|
||||
amd_iommu_set_invalid_ppr_cb(kfd->adev->pdev, NULL);
|
||||
amd_iommu_free_device(kfd->adev->pdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -529,8 +529,8 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
|
|||
for (addr = start; addr < end;) {
|
||||
unsigned long next;
|
||||
|
||||
vma = find_vma(mm, addr);
|
||||
if (!vma || addr < vma->vm_start)
|
||||
vma = vma_lookup(mm, addr);
|
||||
if (!vma)
|
||||
break;
|
||||
|
||||
next = min(vma->vm_end, end);
|
||||
|
@ -798,8 +798,8 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm,
|
|||
for (addr = start; addr < end;) {
|
||||
unsigned long next;
|
||||
|
||||
vma = find_vma(mm, addr);
|
||||
if (!vma || addr < vma->vm_start) {
|
||||
vma = vma_lookup(mm, addr);
|
||||
if (!vma) {
|
||||
pr_debug("failed to find vma for prange %p\n", prange);
|
||||
r = -EFAULT;
|
||||
break;
|
||||
|
@ -973,12 +973,10 @@ static vm_fault_t svm_migrate_to_ram(struct vm_fault *vmf)
|
|||
out_unlock_svms:
|
||||
mutex_unlock(&p->svms.lock);
|
||||
out_unref_process:
|
||||
pr_debug("CPU fault svms 0x%p address 0x%lx done\n", &p->svms, addr);
|
||||
kfd_unref_process(p);
|
||||
out_mmput:
|
||||
mmput(mm);
|
||||
|
||||
pr_debug("CPU fault svms 0x%p address 0x%lx done\n", &p->svms, addr);
|
||||
|
||||
return r ? VM_FAULT_SIGBUS : 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,291 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
|
||||
/*
|
||||
* Copyright 2014-2022 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 KFD_PM4_HEADERS_DIQ_H_
|
||||
#define KFD_PM4_HEADERS_DIQ_H_
|
||||
|
||||
/*--------------------_INDIRECT_BUFFER-------------------- */
|
||||
|
||||
#ifndef _PM4__INDIRECT_BUFFER_DEFINED
|
||||
#define _PM4__INDIRECT_BUFFER_DEFINED
|
||||
enum _INDIRECT_BUFFER_cache_policy_enum {
|
||||
cache_policy___indirect_buffer__lru = 0,
|
||||
cache_policy___indirect_buffer__stream = 1,
|
||||
cache_policy___indirect_buffer__bypass = 2
|
||||
};
|
||||
|
||||
enum {
|
||||
IT_INDIRECT_BUFFER_PASID = 0x5C
|
||||
};
|
||||
|
||||
struct pm4__indirect_buffer_pasid {
|
||||
union {
|
||||
union PM4_MES_TYPE_3_HEADER header; /* header */
|
||||
unsigned int ordinal1;
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int reserved1:2;
|
||||
unsigned int ib_base_lo:30;
|
||||
} bitfields2;
|
||||
unsigned int ordinal2;
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int ib_base_hi:16;
|
||||
unsigned int reserved2:16;
|
||||
} bitfields3;
|
||||
unsigned int ordinal3;
|
||||
};
|
||||
|
||||
union {
|
||||
unsigned int control;
|
||||
unsigned int ordinal4;
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int pasid:10;
|
||||
unsigned int reserved4:22;
|
||||
} bitfields5;
|
||||
unsigned int ordinal5;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*--------------------_RELEASE_MEM-------------------- */
|
||||
|
||||
#ifndef _PM4__RELEASE_MEM_DEFINED
|
||||
#define _PM4__RELEASE_MEM_DEFINED
|
||||
enum _RELEASE_MEM_event_index_enum {
|
||||
event_index___release_mem__end_of_pipe = 5,
|
||||
event_index___release_mem__shader_done = 6
|
||||
};
|
||||
|
||||
enum _RELEASE_MEM_cache_policy_enum {
|
||||
cache_policy___release_mem__lru = 0,
|
||||
cache_policy___release_mem__stream = 1,
|
||||
cache_policy___release_mem__bypass = 2
|
||||
};
|
||||
|
||||
enum _RELEASE_MEM_dst_sel_enum {
|
||||
dst_sel___release_mem__memory_controller = 0,
|
||||
dst_sel___release_mem__tc_l2 = 1,
|
||||
dst_sel___release_mem__queue_write_pointer_register = 2,
|
||||
dst_sel___release_mem__queue_write_pointer_poll_mask_bit = 3
|
||||
};
|
||||
|
||||
enum _RELEASE_MEM_int_sel_enum {
|
||||
int_sel___release_mem__none = 0,
|
||||
int_sel___release_mem__send_interrupt_only = 1,
|
||||
int_sel___release_mem__send_interrupt_after_write_confirm = 2,
|
||||
int_sel___release_mem__send_data_after_write_confirm = 3
|
||||
};
|
||||
|
||||
enum _RELEASE_MEM_data_sel_enum {
|
||||
data_sel___release_mem__none = 0,
|
||||
data_sel___release_mem__send_32_bit_low = 1,
|
||||
data_sel___release_mem__send_64_bit_data = 2,
|
||||
data_sel___release_mem__send_gpu_clock_counter = 3,
|
||||
data_sel___release_mem__send_cp_perfcounter_hi_lo = 4,
|
||||
data_sel___release_mem__store_gds_data_to_memory = 5
|
||||
};
|
||||
|
||||
struct pm4__release_mem {
|
||||
union {
|
||||
union PM4_MES_TYPE_3_HEADER header; /*header */
|
||||
unsigned int ordinal1;
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int event_type:6;
|
||||
unsigned int reserved1:2;
|
||||
enum _RELEASE_MEM_event_index_enum event_index:4;
|
||||
unsigned int tcl1_vol_action_ena:1;
|
||||
unsigned int tc_vol_action_ena:1;
|
||||
unsigned int reserved2:1;
|
||||
unsigned int tc_wb_action_ena:1;
|
||||
unsigned int tcl1_action_ena:1;
|
||||
unsigned int tc_action_ena:1;
|
||||
unsigned int reserved3:6;
|
||||
unsigned int atc:1;
|
||||
enum _RELEASE_MEM_cache_policy_enum cache_policy:2;
|
||||
unsigned int reserved4:5;
|
||||
} bitfields2;
|
||||
unsigned int ordinal2;
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int reserved5:16;
|
||||
enum _RELEASE_MEM_dst_sel_enum dst_sel:2;
|
||||
unsigned int reserved6:6;
|
||||
enum _RELEASE_MEM_int_sel_enum int_sel:3;
|
||||
unsigned int reserved7:2;
|
||||
enum _RELEASE_MEM_data_sel_enum data_sel:3;
|
||||
} bitfields3;
|
||||
unsigned int ordinal3;
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int reserved8:2;
|
||||
unsigned int address_lo_32b:30;
|
||||
} bitfields4;
|
||||
struct {
|
||||
unsigned int reserved9:3;
|
||||
unsigned int address_lo_64b:29;
|
||||
} bitfields5;
|
||||
unsigned int ordinal4;
|
||||
};
|
||||
|
||||
unsigned int address_hi;
|
||||
|
||||
unsigned int data_lo;
|
||||
|
||||
unsigned int data_hi;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/*--------------------_SET_CONFIG_REG-------------------- */
|
||||
|
||||
#ifndef _PM4__SET_CONFIG_REG_DEFINED
|
||||
#define _PM4__SET_CONFIG_REG_DEFINED
|
||||
|
||||
struct pm4__set_config_reg {
|
||||
union {
|
||||
union PM4_MES_TYPE_3_HEADER header; /*header */
|
||||
unsigned int ordinal1;
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int reg_offset:16;
|
||||
unsigned int reserved1:7;
|
||||
unsigned int vmid_shift:5;
|
||||
unsigned int insert_vmid:1;
|
||||
unsigned int reserved2:3;
|
||||
} bitfields2;
|
||||
unsigned int ordinal2;
|
||||
};
|
||||
|
||||
unsigned int reg_data[1]; /*1..N of these fields */
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
/*--------------------_WAIT_REG_MEM-------------------- */
|
||||
|
||||
#ifndef _PM4__WAIT_REG_MEM_DEFINED
|
||||
#define _PM4__WAIT_REG_MEM_DEFINED
|
||||
enum _WAIT_REG_MEM_function_enum {
|
||||
function___wait_reg_mem__always_pass = 0,
|
||||
function___wait_reg_mem__less_than_ref_value = 1,
|
||||
function___wait_reg_mem__less_than_equal_to_the_ref_value = 2,
|
||||
function___wait_reg_mem__equal_to_the_reference_value = 3,
|
||||
function___wait_reg_mem__not_equal_reference_value = 4,
|
||||
function___wait_reg_mem__greater_than_or_equal_reference_value = 5,
|
||||
function___wait_reg_mem__greater_than_reference_value = 6,
|
||||
function___wait_reg_mem__reserved = 7
|
||||
};
|
||||
|
||||
enum _WAIT_REG_MEM_mem_space_enum {
|
||||
mem_space___wait_reg_mem__register_space = 0,
|
||||
mem_space___wait_reg_mem__memory_space = 1
|
||||
};
|
||||
|
||||
enum _WAIT_REG_MEM_operation_enum {
|
||||
operation___wait_reg_mem__wait_reg_mem = 0,
|
||||
operation___wait_reg_mem__wr_wait_wr_reg = 1
|
||||
};
|
||||
|
||||
struct pm4__wait_reg_mem {
|
||||
union {
|
||||
union PM4_MES_TYPE_3_HEADER header; /*header */
|
||||
unsigned int ordinal1;
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
enum _WAIT_REG_MEM_function_enum function:3;
|
||||
unsigned int reserved1:1;
|
||||
enum _WAIT_REG_MEM_mem_space_enum mem_space:2;
|
||||
enum _WAIT_REG_MEM_operation_enum operation:2;
|
||||
unsigned int reserved2:24;
|
||||
} bitfields2;
|
||||
unsigned int ordinal2;
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int reserved3:2;
|
||||
unsigned int memory_poll_addr_lo:30;
|
||||
} bitfields3;
|
||||
struct {
|
||||
unsigned int register_poll_addr:16;
|
||||
unsigned int reserved4:16;
|
||||
} bitfields4;
|
||||
struct {
|
||||
unsigned int register_write_addr:16;
|
||||
unsigned int reserved5:16;
|
||||
} bitfields5;
|
||||
unsigned int ordinal3;
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int poll_address_hi:16;
|
||||
unsigned int reserved6:16;
|
||||
} bitfields6;
|
||||
struct {
|
||||
unsigned int register_write_addr:16;
|
||||
unsigned int reserved7:16;
|
||||
} bitfields7;
|
||||
unsigned int ordinal4;
|
||||
};
|
||||
|
||||
unsigned int reference;
|
||||
|
||||
unsigned int mask;
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int poll_interval:16;
|
||||
unsigned int reserved8:16;
|
||||
} bitfields8;
|
||||
unsigned int ordinal7;
|
||||
};
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* KFD_PM4_HEADERS_DIQ_H_ */
|
|
@ -254,8 +254,6 @@ struct kfd_dev {
|
|||
struct amdgpu_device *adev;
|
||||
|
||||
struct kfd_device_info device_info;
|
||||
struct pci_dev *pdev;
|
||||
struct drm_device *ddev;
|
||||
|
||||
unsigned int id; /* topology stub index */
|
||||
|
||||
|
@ -1365,7 +1363,7 @@ void kfd_dec_compute_active(struct kfd_dev *dev);
|
|||
static inline int kfd_devcgroup_check_permission(struct kfd_dev *kfd)
|
||||
{
|
||||
#if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
|
||||
struct drm_device *ddev = kfd->ddev;
|
||||
struct drm_device *ddev = adev_to_drm(kfd->adev);
|
||||
|
||||
return devcgroup_check_permission(DEVCG_DEV_CHAR, DRM_MAJOR,
|
||||
ddev->render->index,
|
||||
|
|
|
@ -1050,8 +1050,8 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
|
|||
* for auto suspend
|
||||
*/
|
||||
if (pdd->runtime_inuse) {
|
||||
pm_runtime_mark_last_busy(pdd->dev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(pdd->dev->ddev->dev);
|
||||
pm_runtime_mark_last_busy(adev_to_drm(pdd->dev->adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(pdd->dev->adev)->dev);
|
||||
pdd->runtime_inuse = false;
|
||||
}
|
||||
|
||||
|
@ -1633,9 +1633,9 @@ struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
|
|||
* pdd is destroyed.
|
||||
*/
|
||||
if (!pdd->runtime_inuse) {
|
||||
err = pm_runtime_get_sync(dev->ddev->dev);
|
||||
err = pm_runtime_get_sync(adev_to_drm(dev->adev)->dev);
|
||||
if (err < 0) {
|
||||
pm_runtime_put_autosuspend(dev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(dev->adev)->dev);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
}
|
||||
|
@ -1655,8 +1655,8 @@ struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
|
|||
out:
|
||||
/* balance runpm reference count and exit with error */
|
||||
if (!pdd->runtime_inuse) {
|
||||
pm_runtime_mark_last_busy(dev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(dev->ddev->dev);
|
||||
pm_runtime_mark_last_busy(adev_to_drm(dev->adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(dev->adev)->dev);
|
||||
}
|
||||
|
||||
return ERR_PTR(err);
|
||||
|
|
|
@ -259,7 +259,7 @@ void svm_range_free_dma_mappings(struct svm_range *prange)
|
|||
pr_debug("failed to find device idx %d\n", gpuidx);
|
||||
continue;
|
||||
}
|
||||
dev = &pdd->dev->pdev->dev;
|
||||
dev = &pdd->dev->adev->pdev->dev;
|
||||
svm_range_dma_unmap(dev, dma_addr, 0, prange->npages);
|
||||
kvfree(dma_addr);
|
||||
prange->dma_addr[gpuidx] = NULL;
|
||||
|
@ -1586,8 +1586,8 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
|
|||
unsigned long npages;
|
||||
bool readonly;
|
||||
|
||||
vma = find_vma(mm, addr);
|
||||
if (!vma || addr < vma->vm_start) {
|
||||
vma = vma_lookup(mm, addr);
|
||||
if (!vma) {
|
||||
r = -EFAULT;
|
||||
goto unreserve_out;
|
||||
}
|
||||
|
@ -2542,8 +2542,8 @@ svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr,
|
|||
struct interval_tree_node *node;
|
||||
unsigned long start_limit, end_limit;
|
||||
|
||||
vma = find_vma(p->mm, addr << PAGE_SHIFT);
|
||||
if (!vma || (addr << PAGE_SHIFT) < vma->vm_start) {
|
||||
vma = vma_lookup(p->mm, addr << PAGE_SHIFT);
|
||||
if (!vma) {
|
||||
pr_debug("VMA does not exist in address [0x%llx]\n", addr);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
@ -2871,8 +2871,8 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
|
|||
/* __do_munmap removed VMA, return success as we are handling stale
|
||||
* retry fault.
|
||||
*/
|
||||
vma = find_vma(mm, addr << PAGE_SHIFT);
|
||||
if (!vma || (addr << PAGE_SHIFT) < vma->vm_start) {
|
||||
vma = vma_lookup(mm, addr << PAGE_SHIFT);
|
||||
if (!vma) {
|
||||
pr_debug("address 0x%llx VMA is removed\n", addr);
|
||||
r = 0;
|
||||
goto out_unlock_range;
|
||||
|
@ -3152,9 +3152,8 @@ svm_range_is_valid(struct kfd_process *p, uint64_t start, uint64_t size)
|
|||
start <<= PAGE_SHIFT;
|
||||
end = start + (size << PAGE_SHIFT);
|
||||
do {
|
||||
vma = find_vma(p->mm, start);
|
||||
if (!vma || start < vma->vm_start ||
|
||||
(vma->vm_flags & device_vma))
|
||||
vma = vma_lookup(p->mm, start);
|
||||
if (!vma || (vma->vm_flags & device_vma))
|
||||
return -EFAULT;
|
||||
start = min(end, vma->vm_end);
|
||||
} while (start < end);
|
||||
|
|
|
@ -115,7 +115,7 @@ struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev)
|
|||
down_read(&topology_lock);
|
||||
|
||||
list_for_each_entry(top_dev, &topology_device_list, list)
|
||||
if (top_dev->gpu && top_dev->gpu->pdev == pdev) {
|
||||
if (top_dev->gpu && top_dev->gpu->adev->pdev == pdev) {
|
||||
device = top_dev->gpu;
|
||||
break;
|
||||
}
|
||||
|
@ -364,7 +364,6 @@ static ssize_t kfd_cache_show(struct kobject *kobj, struct attribute *attr,
|
|||
|
||||
/* Making sure that the buffer is an empty string */
|
||||
buffer[0] = 0;
|
||||
|
||||
cache = container_of(attr, struct kfd_cache_properties, attr);
|
||||
if (cache->gpu && kfd_devcgroup_check_permission(cache->gpu))
|
||||
return -EPERM;
|
||||
|
@ -379,12 +378,13 @@ static ssize_t kfd_cache_show(struct kobject *kobj, struct attribute *attr,
|
|||
sysfs_show_32bit_prop(buffer, offs, "association", cache->cache_assoc);
|
||||
sysfs_show_32bit_prop(buffer, offs, "latency", cache->cache_latency);
|
||||
sysfs_show_32bit_prop(buffer, offs, "type", cache->cache_type);
|
||||
|
||||
offs += snprintf(buffer+offs, PAGE_SIZE-offs, "sibling_map ");
|
||||
for (i = 0; i < CRAT_SIBLINGMAP_SIZE; i++)
|
||||
for (i = 0; i < cache->sibling_map_size; i++)
|
||||
for (j = 0; j < sizeof(cache->sibling_map[0])*8; j++)
|
||||
/* Check each bit */
|
||||
offs += snprintf(buffer+offs, PAGE_SIZE-offs, "%d,",
|
||||
(cache->sibling_map[i] >> j) & 1);
|
||||
(cache->sibling_map[i] >> j) & 1);
|
||||
|
||||
/* Replace the last "," with end of line */
|
||||
buffer[offs-1] = '\n';
|
||||
|
@ -1169,13 +1169,12 @@ static uint32_t kfd_generate_gpu_id(struct kfd_dev *gpu)
|
|||
|
||||
local_mem_size = gpu->local_mem_info.local_mem_size_private +
|
||||
gpu->local_mem_info.local_mem_size_public;
|
||||
|
||||
buf[0] = gpu->pdev->devfn;
|
||||
buf[1] = gpu->pdev->subsystem_vendor |
|
||||
(gpu->pdev->subsystem_device << 16);
|
||||
buf[2] = pci_domain_nr(gpu->pdev->bus);
|
||||
buf[3] = gpu->pdev->device;
|
||||
buf[4] = gpu->pdev->bus->number;
|
||||
buf[0] = gpu->adev->pdev->devfn;
|
||||
buf[1] = gpu->adev->pdev->subsystem_vendor |
|
||||
(gpu->adev->pdev->subsystem_device << 16);
|
||||
buf[2] = pci_domain_nr(gpu->adev->pdev->bus);
|
||||
buf[3] = gpu->adev->pdev->device;
|
||||
buf[4] = gpu->adev->pdev->bus->number;
|
||||
buf[5] = lower_32_bits(local_mem_size);
|
||||
buf[6] = upper_32_bits(local_mem_size);
|
||||
|
||||
|
@ -1198,7 +1197,6 @@ static struct kfd_topology_device *kfd_assign_gpu(struct kfd_dev *gpu)
|
|||
struct kfd_iolink_properties *iolink;
|
||||
struct kfd_iolink_properties *p2plink;
|
||||
|
||||
down_write(&topology_lock);
|
||||
list_for_each_entry(dev, &topology_device_list, list) {
|
||||
/* Discrete GPUs need their own topology device list
|
||||
* entries. Don't assign them to CPU/APU nodes.
|
||||
|
@ -1222,7 +1220,6 @@ static struct kfd_topology_device *kfd_assign_gpu(struct kfd_dev *gpu)
|
|||
break;
|
||||
}
|
||||
}
|
||||
up_write(&topology_lock);
|
||||
return out_dev;
|
||||
}
|
||||
|
||||
|
@ -1269,7 +1266,7 @@ static void kfd_set_iolink_no_atomics(struct kfd_topology_device *dev,
|
|||
if (target_gpu_dev) {
|
||||
uint32_t cap;
|
||||
|
||||
pcie_capability_read_dword(target_gpu_dev->gpu->pdev,
|
||||
pcie_capability_read_dword(target_gpu_dev->gpu->adev->pdev,
|
||||
PCI_EXP_DEVCAP2, &cap);
|
||||
|
||||
if (!(cap & (PCI_EXP_DEVCAP2_ATOMIC_COMP32 |
|
||||
|
@ -1593,6 +1590,221 @@ static int kfd_dev_create_p2p_links(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Helper function. See kfd_fill_gpu_cache_info for parameter description */
|
||||
static int fill_in_l1_pcache(struct kfd_cache_properties **props_ext,
|
||||
struct kfd_gpu_cache_info *pcache_info,
|
||||
struct kfd_cu_info *cu_info,
|
||||
int cu_bitmask,
|
||||
int cache_type, unsigned int cu_processor_id,
|
||||
int cu_block)
|
||||
{
|
||||
unsigned int cu_sibling_map_mask;
|
||||
int first_active_cu;
|
||||
struct kfd_cache_properties *pcache = NULL;
|
||||
|
||||
cu_sibling_map_mask = cu_bitmask;
|
||||
cu_sibling_map_mask >>= cu_block;
|
||||
cu_sibling_map_mask &= ((1 << pcache_info[cache_type].num_cu_shared) - 1);
|
||||
first_active_cu = ffs(cu_sibling_map_mask);
|
||||
|
||||
/* CU could be inactive. In case of shared cache find the first active
|
||||
* CU. and incase of non-shared cache check if the CU is inactive. If
|
||||
* inactive active skip it
|
||||
*/
|
||||
if (first_active_cu) {
|
||||
pcache = kfd_alloc_struct(pcache);
|
||||
if (!pcache)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(pcache, 0, sizeof(struct kfd_cache_properties));
|
||||
pcache->processor_id_low = cu_processor_id + (first_active_cu - 1);
|
||||
pcache->cache_level = pcache_info[cache_type].cache_level;
|
||||
pcache->cache_size = pcache_info[cache_type].cache_size;
|
||||
|
||||
if (pcache_info[cache_type].flags & CRAT_CACHE_FLAGS_DATA_CACHE)
|
||||
pcache->cache_type |= HSA_CACHE_TYPE_DATA;
|
||||
if (pcache_info[cache_type].flags & CRAT_CACHE_FLAGS_INST_CACHE)
|
||||
pcache->cache_type |= HSA_CACHE_TYPE_INSTRUCTION;
|
||||
if (pcache_info[cache_type].flags & CRAT_CACHE_FLAGS_CPU_CACHE)
|
||||
pcache->cache_type |= HSA_CACHE_TYPE_CPU;
|
||||
if (pcache_info[cache_type].flags & CRAT_CACHE_FLAGS_SIMD_CACHE)
|
||||
pcache->cache_type |= HSA_CACHE_TYPE_HSACU;
|
||||
|
||||
/* Sibling map is w.r.t processor_id_low, so shift out
|
||||
* inactive CU
|
||||
*/
|
||||
cu_sibling_map_mask =
|
||||
cu_sibling_map_mask >> (first_active_cu - 1);
|
||||
|
||||
pcache->sibling_map[0] = (uint8_t)(cu_sibling_map_mask & 0xFF);
|
||||
pcache->sibling_map[1] =
|
||||
(uint8_t)((cu_sibling_map_mask >> 8) & 0xFF);
|
||||
pcache->sibling_map[2] =
|
||||
(uint8_t)((cu_sibling_map_mask >> 16) & 0xFF);
|
||||
pcache->sibling_map[3] =
|
||||
(uint8_t)((cu_sibling_map_mask >> 24) & 0xFF);
|
||||
|
||||
pcache->sibling_map_size = 4;
|
||||
*props_ext = pcache;
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Helper function. See kfd_fill_gpu_cache_info for parameter description */
|
||||
static int fill_in_l2_l3_pcache(struct kfd_cache_properties **props_ext,
|
||||
struct kfd_gpu_cache_info *pcache_info,
|
||||
struct kfd_cu_info *cu_info,
|
||||
int cache_type, unsigned int cu_processor_id)
|
||||
{
|
||||
unsigned int cu_sibling_map_mask;
|
||||
int first_active_cu;
|
||||
int i, j, k;
|
||||
struct kfd_cache_properties *pcache = NULL;
|
||||
|
||||
cu_sibling_map_mask = cu_info->cu_bitmap[0][0];
|
||||
cu_sibling_map_mask &=
|
||||
((1 << pcache_info[cache_type].num_cu_shared) - 1);
|
||||
first_active_cu = ffs(cu_sibling_map_mask);
|
||||
|
||||
/* CU could be inactive. In case of shared cache find the first active
|
||||
* CU. and incase of non-shared cache check if the CU is inactive. If
|
||||
* inactive active skip it
|
||||
*/
|
||||
if (first_active_cu) {
|
||||
pcache = kfd_alloc_struct(pcache);
|
||||
if (!pcache)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(pcache, 0, sizeof(struct kfd_cache_properties));
|
||||
pcache->processor_id_low = cu_processor_id
|
||||
+ (first_active_cu - 1);
|
||||
pcache->cache_level = pcache_info[cache_type].cache_level;
|
||||
pcache->cache_size = pcache_info[cache_type].cache_size;
|
||||
|
||||
if (pcache_info[cache_type].flags & CRAT_CACHE_FLAGS_DATA_CACHE)
|
||||
pcache->cache_type |= HSA_CACHE_TYPE_DATA;
|
||||
if (pcache_info[cache_type].flags & CRAT_CACHE_FLAGS_INST_CACHE)
|
||||
pcache->cache_type |= HSA_CACHE_TYPE_INSTRUCTION;
|
||||
if (pcache_info[cache_type].flags & CRAT_CACHE_FLAGS_CPU_CACHE)
|
||||
pcache->cache_type |= HSA_CACHE_TYPE_CPU;
|
||||
if (pcache_info[cache_type].flags & CRAT_CACHE_FLAGS_SIMD_CACHE)
|
||||
pcache->cache_type |= HSA_CACHE_TYPE_HSACU;
|
||||
|
||||
/* Sibling map is w.r.t processor_id_low, so shift out
|
||||
* inactive CU
|
||||
*/
|
||||
cu_sibling_map_mask = cu_sibling_map_mask >> (first_active_cu - 1);
|
||||
k = 0;
|
||||
|
||||
for (i = 0; i < cu_info->num_shader_engines; i++) {
|
||||
for (j = 0; j < cu_info->num_shader_arrays_per_engine; j++) {
|
||||
pcache->sibling_map[k] = (uint8_t)(cu_sibling_map_mask & 0xFF);
|
||||
pcache->sibling_map[k+1] = (uint8_t)((cu_sibling_map_mask >> 8) & 0xFF);
|
||||
pcache->sibling_map[k+2] = (uint8_t)((cu_sibling_map_mask >> 16) & 0xFF);
|
||||
pcache->sibling_map[k+3] = (uint8_t)((cu_sibling_map_mask >> 24) & 0xFF);
|
||||
k += 4;
|
||||
|
||||
cu_sibling_map_mask = cu_info->cu_bitmap[i % 4][j + i / 4];
|
||||
cu_sibling_map_mask &= ((1 << pcache_info[cache_type].num_cu_shared) - 1);
|
||||
}
|
||||
}
|
||||
pcache->sibling_map_size = k;
|
||||
*props_ext = pcache;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define KFD_MAX_CACHE_TYPES 6
|
||||
|
||||
/* kfd_fill_cache_non_crat_info - Fill GPU cache info using kfd_gpu_cache_info
|
||||
* tables
|
||||
*/
|
||||
void kfd_fill_cache_non_crat_info(struct kfd_topology_device *dev, struct kfd_dev *kdev)
|
||||
{
|
||||
struct kfd_gpu_cache_info *pcache_info = NULL;
|
||||
int i, j, k;
|
||||
int ct = 0;
|
||||
unsigned int cu_processor_id;
|
||||
int ret;
|
||||
unsigned int num_cu_shared;
|
||||
struct kfd_cu_info cu_info;
|
||||
struct kfd_cu_info *pcu_info;
|
||||
int gpu_processor_id;
|
||||
struct kfd_cache_properties *props_ext;
|
||||
int num_of_entries = 0;
|
||||
int num_of_cache_types = 0;
|
||||
struct kfd_gpu_cache_info cache_info[KFD_MAX_CACHE_TYPES];
|
||||
|
||||
amdgpu_amdkfd_get_cu_info(kdev->adev, &cu_info);
|
||||
pcu_info = &cu_info;
|
||||
|
||||
gpu_processor_id = dev->node_props.simd_id_base;
|
||||
|
||||
pcache_info = cache_info;
|
||||
num_of_cache_types = kfd_get_gpu_cache_info(kdev, &pcache_info);
|
||||
if (!num_of_cache_types) {
|
||||
pr_warn("no cache info found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* For each type of cache listed in the kfd_gpu_cache_info table,
|
||||
* go through all available Compute Units.
|
||||
* The [i,j,k] loop will
|
||||
* if kfd_gpu_cache_info.num_cu_shared = 1
|
||||
* will parse through all available CU
|
||||
* If (kfd_gpu_cache_info.num_cu_shared != 1)
|
||||
* then it will consider only one CU from
|
||||
* the shared unit
|
||||
*/
|
||||
for (ct = 0; ct < num_of_cache_types; ct++) {
|
||||
cu_processor_id = gpu_processor_id;
|
||||
if (pcache_info[ct].cache_level == 1) {
|
||||
for (i = 0; i < pcu_info->num_shader_engines; i++) {
|
||||
for (j = 0; j < pcu_info->num_shader_arrays_per_engine; j++) {
|
||||
for (k = 0; k < pcu_info->num_cu_per_sh; k += pcache_info[ct].num_cu_shared) {
|
||||
|
||||
ret = fill_in_l1_pcache(&props_ext, pcache_info, pcu_info,
|
||||
pcu_info->cu_bitmap[i % 4][j + i / 4], ct,
|
||||
cu_processor_id, k);
|
||||
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
if (!ret) {
|
||||
num_of_entries++;
|
||||
list_add_tail(&props_ext->list, &dev->cache_props);
|
||||
}
|
||||
|
||||
/* Move to next CU block */
|
||||
num_cu_shared = ((k + pcache_info[ct].num_cu_shared) <=
|
||||
pcu_info->num_cu_per_sh) ?
|
||||
pcache_info[ct].num_cu_shared :
|
||||
(pcu_info->num_cu_per_sh - k);
|
||||
cu_processor_id += num_cu_shared;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = fill_in_l2_l3_pcache(&props_ext, pcache_info,
|
||||
pcu_info, ct, cu_processor_id);
|
||||
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
if (!ret) {
|
||||
num_of_entries++;
|
||||
list_add_tail(&props_ext->list, &dev->cache_props);
|
||||
}
|
||||
}
|
||||
}
|
||||
dev->node_props.caches_count += num_of_entries;
|
||||
pr_debug("Added [%d] GPU cache entries\n", num_of_entries);
|
||||
}
|
||||
|
||||
int kfd_topology_add_device(struct kfd_dev *gpu)
|
||||
{
|
||||
uint32_t gpu_id;
|
||||
|
@ -1617,9 +1829,9 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
|
|||
* CRAT to create a new topology device. Once created assign the gpu to
|
||||
* that topology device
|
||||
*/
|
||||
down_write(&topology_lock);
|
||||
dev = kfd_assign_gpu(gpu);
|
||||
if (!dev) {
|
||||
down_write(&topology_lock);
|
||||
proximity_domain = ++topology_crat_proximity_domain;
|
||||
|
||||
res = kfd_create_crat_image_virtual(&crat_image, &image_size,
|
||||
|
@ -1631,6 +1843,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
|
|||
topology_crat_proximity_domain--;
|
||||
return res;
|
||||
}
|
||||
|
||||
res = kfd_parse_crat_table(crat_image,
|
||||
&temp_topology_device_list,
|
||||
proximity_domain);
|
||||
|
@ -1644,23 +1857,28 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
|
|||
kfd_topology_update_device_list(&temp_topology_device_list,
|
||||
&topology_device_list);
|
||||
|
||||
/* Update the SYSFS tree, since we added another topology
|
||||
* device
|
||||
*/
|
||||
res = kfd_topology_update_sysfs();
|
||||
up_write(&topology_lock);
|
||||
|
||||
if (!res)
|
||||
sys_props.generation_count++;
|
||||
else
|
||||
pr_err("Failed to update GPU (ID: 0x%x) to sysfs topology. res=%d\n",
|
||||
gpu_id, res);
|
||||
dev = kfd_assign_gpu(gpu);
|
||||
if (WARN_ON(!dev)) {
|
||||
res = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Fill the cache affinity information here for the GPUs
|
||||
* using VCRAT
|
||||
*/
|
||||
kfd_fill_cache_non_crat_info(dev, gpu);
|
||||
|
||||
/* Update the SYSFS tree, since we added another topology
|
||||
* device
|
||||
*/
|
||||
res = kfd_topology_update_sysfs();
|
||||
if (!res)
|
||||
sys_props.generation_count++;
|
||||
else
|
||||
pr_err("Failed to update GPU (ID: 0x%x) to sysfs topology. res=%d\n",
|
||||
gpu_id, res);
|
||||
}
|
||||
up_write(&topology_lock);
|
||||
|
||||
dev->gpu_id = gpu_id;
|
||||
gpu->id = gpu_id;
|
||||
|
@ -1688,13 +1906,13 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
|
|||
cu_info.num_shader_arrays_per_engine;
|
||||
|
||||
dev->node_props.gfx_target_version = gpu->device_info.gfx_target_version;
|
||||
dev->node_props.vendor_id = gpu->pdev->vendor;
|
||||
dev->node_props.device_id = gpu->pdev->device;
|
||||
dev->node_props.vendor_id = gpu->adev->pdev->vendor;
|
||||
dev->node_props.device_id = gpu->adev->pdev->device;
|
||||
dev->node_props.capability |=
|
||||
((dev->gpu->adev->rev_id << HSA_CAP_ASIC_REVISION_SHIFT) &
|
||||
HSA_CAP_ASIC_REVISION_MASK);
|
||||
dev->node_props.location_id = pci_dev_id(gpu->pdev);
|
||||
dev->node_props.domain = pci_domain_nr(gpu->pdev->bus);
|
||||
dev->node_props.location_id = pci_dev_id(gpu->adev->pdev);
|
||||
dev->node_props.domain = pci_domain_nr(gpu->adev->pdev->bus);
|
||||
dev->node_props.max_engine_clk_fcompute =
|
||||
amdgpu_amdkfd_get_max_engine_clock_in_mhz(dev->gpu->adev);
|
||||
dev->node_props.max_engine_clk_ccompute =
|
||||
|
|
|
@ -80,6 +80,8 @@ struct kfd_mem_properties {
|
|||
struct attribute attr;
|
||||
};
|
||||
|
||||
#define CACHE_SIBLINGMAP_SIZE 64
|
||||
|
||||
struct kfd_cache_properties {
|
||||
struct list_head list;
|
||||
uint32_t processor_id_low;
|
||||
|
@ -90,10 +92,11 @@ struct kfd_cache_properties {
|
|||
uint32_t cache_assoc;
|
||||
uint32_t cache_latency;
|
||||
uint32_t cache_type;
|
||||
uint8_t sibling_map[CRAT_SIBLINGMAP_SIZE];
|
||||
uint8_t sibling_map[CACHE_SIBLINGMAP_SIZE];
|
||||
struct kfd_dev *gpu;
|
||||
struct kobject *kobj;
|
||||
struct attribute attr;
|
||||
uint32_t sibling_map_size;
|
||||
};
|
||||
|
||||
struct kfd_iolink_properties {
|
||||
|
@ -128,7 +131,6 @@ struct kfd_topology_device {
|
|||
uint32_t proximity_domain;
|
||||
struct kfd_node_properties node_props;
|
||||
struct list_head mem_props;
|
||||
uint32_t cache_count;
|
||||
struct list_head cache_props;
|
||||
struct list_head io_link_props;
|
||||
struct list_head p2p_link_props;
|
||||
|
|
|
@ -6,7 +6,8 @@ config DRM_AMD_DC
|
|||
bool "AMD DC - Enable new display engine"
|
||||
default y
|
||||
select SND_HDA_COMPONENT if SND_HDA_CORE
|
||||
select DRM_AMD_DC_DCN if (X86 || PPC_LONG_DOUBLE_128)
|
||||
# !CC_IS_CLANG: https://github.com/ClangBuiltLinux/linux/issues/1752
|
||||
select DRM_AMD_DC_DCN if (X86 || PPC_LONG_DOUBLE_128 || (ARM64 && KERNEL_MODE_NEON && !CC_IS_CLANG))
|
||||
help
|
||||
Choose this option if you want to use the new display engine
|
||||
support for AMDGPU. This adds required support for Vega and
|
||||
|
|
|
@ -1399,7 +1399,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
|||
|
||||
mutex_init(&adev->dm.dc_lock);
|
||||
mutex_init(&adev->dm.audio_lock);
|
||||
spin_lock_init(&adev->dm.vblank_lock);
|
||||
|
||||
if(amdgpu_dm_irq_init(adev)) {
|
||||
DRM_ERROR("amdgpu: failed to initialize DM IRQ support.\n");
|
||||
|
@ -1549,6 +1548,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
|
|||
|
||||
adev->dm.dc->debug.visual_confirm = amdgpu_dc_visual_confirm;
|
||||
|
||||
/* TODO: Remove after DP2 receiver gets proper support of Cable ID feature */
|
||||
adev->dm.dc->debug.ignore_cable_id = true;
|
||||
|
||||
r = dm_dmub_hw_init(adev);
|
||||
if (r) {
|
||||
DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r);
|
||||
|
@ -5602,16 +5604,14 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
|
|||
{
|
||||
struct drm_connector *drm_connector = &aconnector->base;
|
||||
uint32_t link_bandwidth_kbps;
|
||||
uint32_t max_dsc_target_bpp_limit_override = 0;
|
||||
struct dc *dc = sink->ctx->dc;
|
||||
uint32_t max_supported_bw_in_kbps, timing_bw_in_kbps;
|
||||
uint32_t dsc_max_supported_bw_in_kbps;
|
||||
uint32_t max_dsc_target_bpp_limit_override =
|
||||
drm_connector->display_info.max_dsc_bpp;
|
||||
|
||||
link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
|
||||
dc_link_get_link_cap(aconnector->dc_link));
|
||||
if (stream->link && stream->link->local_sink)
|
||||
max_dsc_target_bpp_limit_override =
|
||||
stream->link->local_sink->edid_caps.panel_patch.max_dsc_target_bpp_limit;
|
||||
|
||||
/* Set DSC policy according to dsc_clock_en */
|
||||
dc_dsc_policy_set_enable_dsc_when_not_needed(
|
||||
|
@ -5692,6 +5692,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||
bool scale = dm_state ? (dm_state->scaling != RMX_OFF) : false;
|
||||
int mode_refresh;
|
||||
int preferred_refresh = 0;
|
||||
enum color_transfer_func tf = TRANSFER_FUNC_UNKNOWN;
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
struct dsc_dec_dpcd_caps dsc_caps;
|
||||
#endif
|
||||
|
@ -5815,7 +5816,9 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||
if (stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED)
|
||||
stream->use_vsc_sdp_for_colorimetry = true;
|
||||
}
|
||||
mod_build_vsc_infopacket(stream, &stream->vsc_infopacket, stream->output_color_space);
|
||||
if (stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22)
|
||||
tf = TRANSFER_FUNC_GAMMA_22;
|
||||
mod_build_vsc_infopacket(stream, &stream->vsc_infopacket, stream->output_color_space, tf);
|
||||
aconnector->psr_skip_count = AMDGPU_DM_PSR_ENTRY_DELAY;
|
||||
|
||||
}
|
||||
|
@ -6145,6 +6148,70 @@ static void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector)
|
|||
create_eml_sink(aconnector);
|
||||
}
|
||||
|
||||
static enum dc_status dm_validate_stream_and_context(struct dc *dc,
|
||||
struct dc_stream_state *stream)
|
||||
{
|
||||
enum dc_status dc_result = DC_ERROR_UNEXPECTED;
|
||||
struct dc_plane_state *dc_plane_state = NULL;
|
||||
struct dc_state *dc_state = NULL;
|
||||
|
||||
if (!stream)
|
||||
goto cleanup;
|
||||
|
||||
dc_plane_state = dc_create_plane_state(dc);
|
||||
if (!dc_plane_state)
|
||||
goto cleanup;
|
||||
|
||||
dc_state = dc_create_state(dc);
|
||||
if (!dc_state)
|
||||
goto cleanup;
|
||||
|
||||
/* populate stream to plane */
|
||||
dc_plane_state->src_rect.height = stream->src.height;
|
||||
dc_plane_state->src_rect.width = stream->src.width;
|
||||
dc_plane_state->dst_rect.height = stream->src.height;
|
||||
dc_plane_state->dst_rect.width = stream->src.width;
|
||||
dc_plane_state->clip_rect.height = stream->src.height;
|
||||
dc_plane_state->clip_rect.width = stream->src.width;
|
||||
dc_plane_state->plane_size.surface_pitch = ((stream->src.width + 255) / 256) * 256;
|
||||
dc_plane_state->plane_size.surface_size.height = stream->src.height;
|
||||
dc_plane_state->plane_size.surface_size.width = stream->src.width;
|
||||
dc_plane_state->plane_size.chroma_size.height = stream->src.height;
|
||||
dc_plane_state->plane_size.chroma_size.width = stream->src.width;
|
||||
dc_plane_state->tiling_info.gfx9.swizzle = DC_SW_UNKNOWN;
|
||||
dc_plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB8888;
|
||||
dc_plane_state->tiling_info.gfx9.swizzle = DC_SW_UNKNOWN;
|
||||
dc_plane_state->rotation = ROTATION_ANGLE_0;
|
||||
dc_plane_state->is_tiling_rotated = false;
|
||||
dc_plane_state->tiling_info.gfx8.array_mode = DC_ARRAY_LINEAR_GENERAL;
|
||||
|
||||
dc_result = dc_validate_stream(dc, stream);
|
||||
if (dc_result == DC_OK)
|
||||
dc_result = dc_validate_plane(dc, dc_plane_state);
|
||||
|
||||
if (dc_result == DC_OK)
|
||||
dc_result = dc_add_stream_to_ctx(dc, dc_state, stream);
|
||||
|
||||
if (dc_result == DC_OK && !dc_add_plane_to_context(
|
||||
dc,
|
||||
stream,
|
||||
dc_plane_state,
|
||||
dc_state))
|
||||
dc_result = DC_FAIL_ATTACH_SURFACES;
|
||||
|
||||
if (dc_result == DC_OK)
|
||||
dc_result = dc_validate_global_state(dc, dc_state, true);
|
||||
|
||||
cleanup:
|
||||
if (dc_state)
|
||||
dc_release_state(dc_state);
|
||||
|
||||
if (dc_plane_state)
|
||||
dc_plane_state_release(dc_plane_state);
|
||||
|
||||
return dc_result;
|
||||
}
|
||||
|
||||
struct dc_stream_state *
|
||||
create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||
const struct drm_display_mode *drm_mode,
|
||||
|
@ -6171,6 +6238,9 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
|||
if (dc_result == DC_OK && stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
dc_result = dm_dp_mst_is_port_support_mode(aconnector, stream);
|
||||
|
||||
if (dc_result == DC_OK)
|
||||
dc_result = dm_validate_stream_and_context(adev->dm.dc, stream);
|
||||
|
||||
if (dc_result != DC_OK) {
|
||||
DRM_DEBUG_KMS("Mode %dx%d (clk %d) failed DC validation with error %d (%s)\n",
|
||||
drm_mode->hdisplay,
|
||||
|
@ -7832,6 +7902,9 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||
*/
|
||||
if (acrtc_state->stream->link->psr_settings.psr_version >= DC_PSR_VERSION_SU_1 &&
|
||||
acrtc_attach->dm_irq_params.allow_psr_entry &&
|
||||
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
|
||||
!amdgpu_dm_crc_window_is_activated(acrtc_state->base.crtc) &&
|
||||
#endif
|
||||
!acrtc_state->stream->link->psr_settings.psr_allow_active)
|
||||
amdgpu_dm_psr_enable(acrtc_state->stream);
|
||||
} else {
|
||||
|
@ -8293,8 +8366,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
if (amdgpu_dm_crc_window_is_activated(crtc)) {
|
||||
spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
|
||||
acrtc->dm_irq_params.crc_window.update_win = true;
|
||||
acrtc->dm_irq_params.crc_window.skip_frame_cnt = 2;
|
||||
acrtc->dm_irq_params.window_param.update_win = true;
|
||||
acrtc->dm_irq_params.window_param.skip_frame_cnt = 2;
|
||||
spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
crc_rd_wrk->crtc = crtc;
|
||||
spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
|
|
|
@ -365,13 +365,6 @@ struct amdgpu_display_manager {
|
|||
*/
|
||||
struct mutex audio_lock;
|
||||
|
||||
/**
|
||||
* @vblank_lock:
|
||||
*
|
||||
* Guards access to deferred vblank work state.
|
||||
*/
|
||||
spinlock_t vblank_lock;
|
||||
|
||||
/**
|
||||
* @audio_component:
|
||||
*
|
||||
|
|
|
@ -89,13 +89,13 @@ static void amdgpu_dm_set_crc_window_default(struct drm_crtc *crtc)
|
|||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
spin_lock_irq(&drm_dev->event_lock);
|
||||
acrtc->dm_irq_params.crc_window.x_start = 0;
|
||||
acrtc->dm_irq_params.crc_window.y_start = 0;
|
||||
acrtc->dm_irq_params.crc_window.x_end = 0;
|
||||
acrtc->dm_irq_params.crc_window.y_end = 0;
|
||||
acrtc->dm_irq_params.crc_window.activated = false;
|
||||
acrtc->dm_irq_params.crc_window.update_win = false;
|
||||
acrtc->dm_irq_params.crc_window.skip_frame_cnt = 0;
|
||||
acrtc->dm_irq_params.window_param.x_start = 0;
|
||||
acrtc->dm_irq_params.window_param.y_start = 0;
|
||||
acrtc->dm_irq_params.window_param.x_end = 0;
|
||||
acrtc->dm_irq_params.window_param.y_end = 0;
|
||||
acrtc->dm_irq_params.window_param.activated = false;
|
||||
acrtc->dm_irq_params.window_param.update_win = false;
|
||||
acrtc->dm_irq_params.window_param.skip_frame_cnt = 0;
|
||||
spin_unlock_irq(&drm_dev->event_lock);
|
||||
}
|
||||
|
||||
|
@ -123,6 +123,8 @@ static void amdgpu_dm_crtc_notify_ta_to_read(struct work_struct *work)
|
|||
phy_id = crc_rd_wrk->phy_inst;
|
||||
spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
|
||||
mutex_lock(&psp->securedisplay_context.mutex);
|
||||
|
||||
psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,
|
||||
TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC);
|
||||
securedisplay_cmd->securedisplay_in_message.send_roi_crc.phy_id =
|
||||
|
@ -133,6 +135,24 @@ static void amdgpu_dm_crtc_notify_ta_to_read(struct work_struct *work)
|
|||
psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&psp->securedisplay_context.mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
amdgpu_dm_forward_crc_window(struct work_struct *work)
|
||||
{
|
||||
struct crc_fw_work *crc_fw_wrk;
|
||||
struct amdgpu_display_manager *dm;
|
||||
|
||||
crc_fw_wrk = container_of(work, struct crc_fw_work, forward_roi_work);
|
||||
dm = crc_fw_wrk->dm;
|
||||
|
||||
mutex_lock(&dm->dc_lock);
|
||||
dc_stream_forward_crc_window(dm->dc, &crc_fw_wrk->rect, crc_fw_wrk->stream, crc_fw_wrk->is_stop_cmd);
|
||||
mutex_unlock(&dm->dc_lock);
|
||||
|
||||
kfree(crc_fw_wrk);
|
||||
}
|
||||
|
||||
bool amdgpu_dm_crc_window_is_activated(struct drm_crtc *crtc)
|
||||
|
@ -142,7 +162,7 @@ bool amdgpu_dm_crc_window_is_activated(struct drm_crtc *crtc)
|
|||
bool ret = false;
|
||||
|
||||
spin_lock_irq(&drm_dev->event_lock);
|
||||
ret = acrtc->dm_irq_params.crc_window.activated;
|
||||
ret = acrtc->dm_irq_params.window_param.activated;
|
||||
spin_unlock_irq(&drm_dev->event_lock);
|
||||
|
||||
return ret;
|
||||
|
@ -187,9 +207,11 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc,
|
|||
if (adev->dm.crc_rd_wrk) {
|
||||
flush_work(&adev->dm.crc_rd_wrk->notify_ta_work);
|
||||
spin_lock_irq(&adev->dm.crc_rd_wrk->crc_rd_work_lock);
|
||||
|
||||
if (adev->dm.crc_rd_wrk->crtc == crtc) {
|
||||
dc_stream_stop_dmcu_crc_win_update(stream_state->ctx->dc,
|
||||
dm_crtc_state->stream);
|
||||
/* stop ROI update on this crtc */
|
||||
dc_stream_forward_crc_window(stream_state->ctx->dc,
|
||||
NULL, stream_state, true);
|
||||
adev->dm.crc_rd_wrk->crtc = NULL;
|
||||
}
|
||||
spin_unlock_irq(&adev->dm.crc_rd_wrk->crc_rd_work_lock);
|
||||
|
@ -439,14 +461,9 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
|
|||
enum amdgpu_dm_pipe_crc_source cur_crc_src;
|
||||
struct amdgpu_crtc *acrtc = NULL;
|
||||
struct amdgpu_device *adev = NULL;
|
||||
struct crc_rd_work *crc_rd_wrk = NULL;
|
||||
struct crc_params *crc_window = NULL, tmp_window;
|
||||
struct crc_rd_work *crc_rd_wrk;
|
||||
struct crc_fw_work *crc_fw_wrk;
|
||||
unsigned long flags1, flags2;
|
||||
struct crtc_position position;
|
||||
uint32_t v_blank;
|
||||
uint32_t v_back_porch;
|
||||
uint32_t crc_window_latch_up_line;
|
||||
struct dc_crtc_timing *timing_out;
|
||||
|
||||
if (crtc == NULL)
|
||||
return;
|
||||
|
@ -458,74 +475,54 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
|
|||
spin_lock_irqsave(&drm_dev->event_lock, flags1);
|
||||
stream_state = acrtc->dm_irq_params.stream;
|
||||
cur_crc_src = acrtc->dm_irq_params.crc_src;
|
||||
timing_out = &stream_state->timing;
|
||||
|
||||
/* Early return if CRC capture is not enabled. */
|
||||
if (!amdgpu_dm_is_valid_crc_source(cur_crc_src))
|
||||
goto cleanup;
|
||||
|
||||
if (dm_is_crc_source_crtc(cur_crc_src)) {
|
||||
if (acrtc->dm_irq_params.crc_window.activated) {
|
||||
if (acrtc->dm_irq_params.crc_window.update_win) {
|
||||
if (acrtc->dm_irq_params.crc_window.skip_frame_cnt) {
|
||||
acrtc->dm_irq_params.crc_window.skip_frame_cnt -= 1;
|
||||
goto cleanup;
|
||||
}
|
||||
crc_window = &tmp_window;
|
||||
if (!dm_is_crc_source_crtc(cur_crc_src))
|
||||
goto cleanup;
|
||||
|
||||
tmp_window.windowa_x_start =
|
||||
acrtc->dm_irq_params.crc_window.x_start;
|
||||
tmp_window.windowa_y_start =
|
||||
acrtc->dm_irq_params.crc_window.y_start;
|
||||
tmp_window.windowa_x_end =
|
||||
acrtc->dm_irq_params.crc_window.x_end;
|
||||
tmp_window.windowa_y_end =
|
||||
acrtc->dm_irq_params.crc_window.y_end;
|
||||
tmp_window.windowb_x_start =
|
||||
acrtc->dm_irq_params.crc_window.x_start;
|
||||
tmp_window.windowb_y_start =
|
||||
acrtc->dm_irq_params.crc_window.y_start;
|
||||
tmp_window.windowb_x_end =
|
||||
acrtc->dm_irq_params.crc_window.x_end;
|
||||
tmp_window.windowb_y_end =
|
||||
acrtc->dm_irq_params.crc_window.y_end;
|
||||
if (!acrtc->dm_irq_params.window_param.activated)
|
||||
goto cleanup;
|
||||
|
||||
dc_stream_forward_dmcu_crc_window(stream_state->ctx->dc,
|
||||
stream_state, crc_window);
|
||||
if (acrtc->dm_irq_params.window_param.update_win) {
|
||||
if (acrtc->dm_irq_params.window_param.skip_frame_cnt) {
|
||||
acrtc->dm_irq_params.window_param.skip_frame_cnt -= 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
acrtc->dm_irq_params.crc_window.update_win = false;
|
||||
/* prepare work for dmub to update ROI */
|
||||
crc_fw_wrk = kzalloc(sizeof(*crc_fw_wrk), GFP_ATOMIC);
|
||||
if (!crc_fw_wrk)
|
||||
goto cleanup;
|
||||
|
||||
dc_stream_get_crtc_position(stream_state->ctx->dc, &stream_state, 1,
|
||||
&position.vertical_count,
|
||||
&position.nominal_vcount);
|
||||
INIT_WORK(&crc_fw_wrk->forward_roi_work, amdgpu_dm_forward_crc_window);
|
||||
crc_fw_wrk->dm = &adev->dm;
|
||||
crc_fw_wrk->stream = stream_state;
|
||||
crc_fw_wrk->rect.x = acrtc->dm_irq_params.window_param.x_start;
|
||||
crc_fw_wrk->rect.y = acrtc->dm_irq_params.window_param.y_start;
|
||||
crc_fw_wrk->rect.width = acrtc->dm_irq_params.window_param.x_end -
|
||||
acrtc->dm_irq_params.window_param.x_start;
|
||||
crc_fw_wrk->rect.height = acrtc->dm_irq_params.window_param.y_end -
|
||||
acrtc->dm_irq_params.window_param.y_start;
|
||||
schedule_work(&crc_fw_wrk->forward_roi_work);
|
||||
|
||||
v_blank = timing_out->v_total - timing_out->v_border_top -
|
||||
timing_out->v_addressable - timing_out->v_border_bottom;
|
||||
acrtc->dm_irq_params.window_param.update_win = false;
|
||||
acrtc->dm_irq_params.window_param.skip_frame_cnt = 1;
|
||||
|
||||
v_back_porch = v_blank - timing_out->v_front_porch -
|
||||
timing_out->v_sync_width;
|
||||
} else {
|
||||
if (acrtc->dm_irq_params.window_param.skip_frame_cnt) {
|
||||
acrtc->dm_irq_params.window_param.skip_frame_cnt -= 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
crc_window_latch_up_line = v_back_porch + timing_out->v_sync_width;
|
||||
|
||||
/* take 3 lines margin*/
|
||||
if ((position.vertical_count + 3) >= crc_window_latch_up_line)
|
||||
acrtc->dm_irq_params.crc_window.skip_frame_cnt = 1;
|
||||
else
|
||||
acrtc->dm_irq_params.crc_window.skip_frame_cnt = 0;
|
||||
} else {
|
||||
if (acrtc->dm_irq_params.crc_window.skip_frame_cnt == 0) {
|
||||
if (adev->dm.crc_rd_wrk) {
|
||||
crc_rd_wrk = adev->dm.crc_rd_wrk;
|
||||
spin_lock_irqsave(&crc_rd_wrk->crc_rd_work_lock, flags2);
|
||||
crc_rd_wrk->phy_inst =
|
||||
stream_state->link->link_enc_hw_inst;
|
||||
spin_unlock_irqrestore(&crc_rd_wrk->crc_rd_work_lock, flags2);
|
||||
schedule_work(&crc_rd_wrk->notify_ta_work);
|
||||
}
|
||||
} else {
|
||||
acrtc->dm_irq_params.crc_window.skip_frame_cnt -= 1;
|
||||
}
|
||||
}
|
||||
if (adev->dm.crc_rd_wrk) {
|
||||
crc_rd_wrk = adev->dm.crc_rd_wrk;
|
||||
spin_lock_irqsave(&crc_rd_wrk->crc_rd_work_lock, flags2);
|
||||
crc_rd_wrk->phy_inst = stream_state->link->link_enc_hw_inst;
|
||||
spin_unlock_irqrestore(&crc_rd_wrk->crc_rd_work_lock, flags2);
|
||||
schedule_work(&crc_rd_wrk->notify_ta_work);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ enum amdgpu_dm_pipe_crc_source {
|
|||
};
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
|
||||
struct crc_window_parm {
|
||||
struct crc_window_param {
|
||||
uint16_t x_start;
|
||||
uint16_t y_start;
|
||||
uint16_t x_end;
|
||||
|
@ -53,6 +53,7 @@ struct crc_window_parm {
|
|||
int skip_frame_cnt;
|
||||
};
|
||||
|
||||
/* read_work for driver to call PSP to read */
|
||||
struct crc_rd_work {
|
||||
struct work_struct notify_ta_work;
|
||||
/* To protect crc_rd_work carried fields*/
|
||||
|
@ -60,6 +61,15 @@ struct crc_rd_work {
|
|||
struct drm_crtc *crtc;
|
||||
uint8_t phy_inst;
|
||||
};
|
||||
|
||||
/* forward_work for driver to forward ROI to dmu */
|
||||
struct crc_fw_work {
|
||||
struct work_struct forward_roi_work;
|
||||
struct amdgpu_display_manager *dm;
|
||||
struct dc_stream_state *stream;
|
||||
struct rect rect;
|
||||
bool is_stop_cmd;
|
||||
};
|
||||
#endif
|
||||
|
||||
static inline bool amdgpu_dm_is_valid_crc_source(enum amdgpu_dm_pipe_crc_source source)
|
||||
|
|
|
@ -127,6 +127,9 @@ static void vblank_control_worker(struct work_struct *work)
|
|||
amdgpu_dm_psr_disable(vblank_work->stream);
|
||||
} else if (vblank_work->stream->link->psr_settings.psr_feature_enabled &&
|
||||
!vblank_work->stream->link->psr_settings.psr_allow_active &&
|
||||
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
|
||||
!amdgpu_dm_crc_window_is_activated(&vblank_work->acrtc->base) &&
|
||||
#endif
|
||||
vblank_work->acrtc->dm_irq_params.allow_psr_entry) {
|
||||
amdgpu_dm_psr_enable(vblank_work->stream);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
#include "link_hwss.h"
|
||||
#include "dc/dc_dmub_srv.h"
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
|
||||
#include "amdgpu_dm_psr.h"
|
||||
#endif
|
||||
|
||||
struct dmub_debugfs_trace_header {
|
||||
uint32_t entry_count;
|
||||
uint32_t reserved[3];
|
||||
|
@ -299,6 +303,8 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
|
|||
case LINK_RATE_HIGH2:
|
||||
case LINK_RATE_HIGH3:
|
||||
case LINK_RATE_UHBR10:
|
||||
case LINK_RATE_UHBR13_5:
|
||||
case LINK_RATE_UHBR20:
|
||||
break;
|
||||
default:
|
||||
valid_input = false;
|
||||
|
@ -3079,8 +3085,8 @@ static int crc_win_x_start_set(void *data, u64 val)
|
|||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
spin_lock_irq(&drm_dev->event_lock);
|
||||
acrtc->dm_irq_params.crc_window.x_start = (uint16_t) val;
|
||||
acrtc->dm_irq_params.crc_window.update_win = false;
|
||||
acrtc->dm_irq_params.window_param.x_start = (uint16_t) val;
|
||||
acrtc->dm_irq_params.window_param.update_win = false;
|
||||
spin_unlock_irq(&drm_dev->event_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -3096,7 +3102,7 @@ static int crc_win_x_start_get(void *data, u64 *val)
|
|||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
spin_lock_irq(&drm_dev->event_lock);
|
||||
*val = acrtc->dm_irq_params.crc_window.x_start;
|
||||
*val = acrtc->dm_irq_params.window_param.x_start;
|
||||
spin_unlock_irq(&drm_dev->event_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -3116,8 +3122,8 @@ static int crc_win_y_start_set(void *data, u64 val)
|
|||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
spin_lock_irq(&drm_dev->event_lock);
|
||||
acrtc->dm_irq_params.crc_window.y_start = (uint16_t) val;
|
||||
acrtc->dm_irq_params.crc_window.update_win = false;
|
||||
acrtc->dm_irq_params.window_param.y_start = (uint16_t) val;
|
||||
acrtc->dm_irq_params.window_param.update_win = false;
|
||||
spin_unlock_irq(&drm_dev->event_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -3133,7 +3139,7 @@ static int crc_win_y_start_get(void *data, u64 *val)
|
|||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
spin_lock_irq(&drm_dev->event_lock);
|
||||
*val = acrtc->dm_irq_params.crc_window.y_start;
|
||||
*val = acrtc->dm_irq_params.window_param.y_start;
|
||||
spin_unlock_irq(&drm_dev->event_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -3152,8 +3158,8 @@ static int crc_win_x_end_set(void *data, u64 val)
|
|||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
spin_lock_irq(&drm_dev->event_lock);
|
||||
acrtc->dm_irq_params.crc_window.x_end = (uint16_t) val;
|
||||
acrtc->dm_irq_params.crc_window.update_win = false;
|
||||
acrtc->dm_irq_params.window_param.x_end = (uint16_t) val;
|
||||
acrtc->dm_irq_params.window_param.update_win = false;
|
||||
spin_unlock_irq(&drm_dev->event_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -3169,7 +3175,7 @@ static int crc_win_x_end_get(void *data, u64 *val)
|
|||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
spin_lock_irq(&drm_dev->event_lock);
|
||||
*val = acrtc->dm_irq_params.crc_window.x_end;
|
||||
*val = acrtc->dm_irq_params.window_param.x_end;
|
||||
spin_unlock_irq(&drm_dev->event_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -3188,8 +3194,8 @@ static int crc_win_y_end_set(void *data, u64 val)
|
|||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
spin_lock_irq(&drm_dev->event_lock);
|
||||
acrtc->dm_irq_params.crc_window.y_end = (uint16_t) val;
|
||||
acrtc->dm_irq_params.crc_window.update_win = false;
|
||||
acrtc->dm_irq_params.window_param.y_end = (uint16_t) val;
|
||||
acrtc->dm_irq_params.window_param.update_win = false;
|
||||
spin_unlock_irq(&drm_dev->event_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -3205,7 +3211,7 @@ static int crc_win_y_end_get(void *data, u64 *val)
|
|||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
spin_lock_irq(&drm_dev->event_lock);
|
||||
*val = acrtc->dm_irq_params.crc_window.y_end;
|
||||
*val = acrtc->dm_irq_params.window_param.y_end;
|
||||
spin_unlock_irq(&drm_dev->event_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -3228,31 +3234,38 @@ static int crc_win_update_set(void *data, u64 val)
|
|||
return 0;
|
||||
|
||||
if (val) {
|
||||
new_acrtc = to_amdgpu_crtc(new_crtc);
|
||||
mutex_lock(&adev->dm.dc_lock);
|
||||
/* PSR may write to OTG CRC window control register,
|
||||
* so close it before starting secure_display.
|
||||
*/
|
||||
amdgpu_dm_psr_disable(new_acrtc->dm_irq_params.stream);
|
||||
|
||||
spin_lock_irq(&adev_to_drm(adev)->event_lock);
|
||||
spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
if (crc_rd_wrk->crtc) {
|
||||
old_crtc = crc_rd_wrk->crtc;
|
||||
old_acrtc = to_amdgpu_crtc(old_crtc);
|
||||
}
|
||||
new_acrtc = to_amdgpu_crtc(new_crtc);
|
||||
|
||||
if (old_crtc && old_crtc != new_crtc) {
|
||||
old_acrtc->dm_irq_params.crc_window.activated = false;
|
||||
old_acrtc->dm_irq_params.crc_window.update_win = false;
|
||||
old_acrtc->dm_irq_params.crc_window.skip_frame_cnt = 0;
|
||||
old_acrtc->dm_irq_params.window_param.activated = false;
|
||||
old_acrtc->dm_irq_params.window_param.update_win = false;
|
||||
old_acrtc->dm_irq_params.window_param.skip_frame_cnt = 0;
|
||||
|
||||
new_acrtc->dm_irq_params.crc_window.activated = true;
|
||||
new_acrtc->dm_irq_params.crc_window.update_win = true;
|
||||
new_acrtc->dm_irq_params.crc_window.skip_frame_cnt = 0;
|
||||
new_acrtc->dm_irq_params.window_param.activated = true;
|
||||
new_acrtc->dm_irq_params.window_param.update_win = true;
|
||||
new_acrtc->dm_irq_params.window_param.skip_frame_cnt = 0;
|
||||
crc_rd_wrk->crtc = new_crtc;
|
||||
} else {
|
||||
new_acrtc->dm_irq_params.crc_window.activated = true;
|
||||
new_acrtc->dm_irq_params.crc_window.update_win = true;
|
||||
new_acrtc->dm_irq_params.crc_window.skip_frame_cnt = 0;
|
||||
new_acrtc->dm_irq_params.window_param.activated = true;
|
||||
new_acrtc->dm_irq_params.window_param.update_win = true;
|
||||
new_acrtc->dm_irq_params.window_param.skip_frame_cnt = 0;
|
||||
crc_rd_wrk->crtc = new_crtc;
|
||||
}
|
||||
spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
spin_unlock_irq(&adev_to_drm(adev)->event_lock);
|
||||
mutex_unlock(&adev->dm.dc_lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -495,7 +495,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
|
|||
link->dp.mst_enabled = config->mst_enabled;
|
||||
link->dp.usb4_enabled = config->usb4_enabled;
|
||||
display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION;
|
||||
link->adjust.auth_delay = 3;
|
||||
link->adjust.auth_delay = 0;
|
||||
link->adjust.hdcp1.disable = 0;
|
||||
conn_state = aconnector->base.state;
|
||||
|
||||
|
|
|
@ -42,39 +42,6 @@
|
|||
#include "dm_helpers.h"
|
||||
#include "ddc_service_types.h"
|
||||
|
||||
struct monitor_patch_info {
|
||||
unsigned int manufacturer_id;
|
||||
unsigned int product_id;
|
||||
void (*patch_func)(struct dc_edid_caps *edid_caps, unsigned int param);
|
||||
unsigned int patch_param;
|
||||
};
|
||||
static void set_max_dsc_bpp_limit(struct dc_edid_caps *edid_caps, unsigned int param);
|
||||
|
||||
static const struct monitor_patch_info monitor_patch_table[] = {
|
||||
{0x6D1E, 0x5BBF, set_max_dsc_bpp_limit, 15},
|
||||
{0x6D1E, 0x5B9A, set_max_dsc_bpp_limit, 15},
|
||||
};
|
||||
|
||||
static void set_max_dsc_bpp_limit(struct dc_edid_caps *edid_caps, unsigned int param)
|
||||
{
|
||||
if (edid_caps)
|
||||
edid_caps->panel_patch.max_dsc_target_bpp_limit = param;
|
||||
}
|
||||
|
||||
static int amdgpu_dm_patch_edid_caps(struct dc_edid_caps *edid_caps)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(monitor_patch_table); i++)
|
||||
if ((edid_caps->manufacturer_id == monitor_patch_table[i].manufacturer_id)
|
||||
&& (edid_caps->product_id == monitor_patch_table[i].product_id)) {
|
||||
monitor_patch_table[i].patch_func(edid_caps, monitor_patch_table[i].patch_param);
|
||||
ret++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* dm_helpers_parse_edid_caps
|
||||
*
|
||||
* Parse edid caps
|
||||
|
@ -149,8 +116,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
|
|||
kfree(sads);
|
||||
kfree(sadb);
|
||||
|
||||
amdgpu_dm_patch_edid_caps(edid_caps);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ struct dm_irq_params {
|
|||
#ifdef CONFIG_DEBUG_FS
|
||||
enum amdgpu_dm_pipe_crc_source crc_src;
|
||||
#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
|
||||
struct crc_window_parm crc_window;
|
||||
struct crc_window_param window_param;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -642,15 +642,18 @@ static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *p
|
|||
int count,
|
||||
int k)
|
||||
{
|
||||
struct drm_connector *drm_connector;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
drm_connector = ¶ms[i].aconnector->base;
|
||||
|
||||
memset(¶ms[i].timing->dsc_cfg, 0, sizeof(params[i].timing->dsc_cfg));
|
||||
if (vars[i + k].dsc_enabled && dc_dsc_compute_config(
|
||||
params[i].sink->ctx->dc->res_pool->dscs[0],
|
||||
¶ms[i].sink->dsc_caps.dsc_dec_caps,
|
||||
params[i].sink->ctx->dc->debug.dsc_min_slice_height_override,
|
||||
params[i].sink->edid_caps.panel_patch.max_dsc_target_bpp_limit,
|
||||
drm_connector->display_info.max_dsc_bpp,
|
||||
0,
|
||||
params[i].timing,
|
||||
¶ms[i].timing->dsc_cfg)) {
|
||||
|
@ -692,12 +695,16 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn)
|
|||
struct dc_dsc_config dsc_config;
|
||||
u64 kbps;
|
||||
|
||||
struct drm_connector *drm_connector = ¶m.aconnector->base;
|
||||
uint32_t max_dsc_target_bpp_limit_override =
|
||||
drm_connector->display_info.max_dsc_bpp;
|
||||
|
||||
kbps = div_u64((u64)pbn * 994 * 8 * 54, 64);
|
||||
dc_dsc_compute_config(
|
||||
param.sink->ctx->dc->res_pool->dscs[0],
|
||||
¶m.sink->dsc_caps.dsc_dec_caps,
|
||||
param.sink->ctx->dc->debug.dsc_min_slice_height_override,
|
||||
param.sink->edid_caps.panel_patch.max_dsc_target_bpp_limit,
|
||||
max_dsc_target_bpp_limit_override,
|
||||
(int) kbps, param.timing, &dsc_config);
|
||||
|
||||
return dsc_config.bits_per_pixel;
|
||||
|
|
|
@ -1369,7 +1369,7 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
|
|||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(plane->dev);
|
||||
const struct drm_format_info *info = drm_format_info(format);
|
||||
struct hw_asic_id asic_id = adev->dm.dc->ctx->asic_id;
|
||||
int i;
|
||||
|
||||
enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3;
|
||||
|
||||
|
@ -1386,49 +1386,13 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* check if swizzle mode is supported by this version of DCN */
|
||||
switch (asic_id.chip_family) {
|
||||
case FAMILY_SI:
|
||||
case FAMILY_CI:
|
||||
case FAMILY_KV:
|
||||
case FAMILY_CZ:
|
||||
case FAMILY_VI:
|
||||
/* asics before AI does not have modifier support */
|
||||
return false;
|
||||
case FAMILY_AI:
|
||||
case FAMILY_RV:
|
||||
case FAMILY_NV:
|
||||
case FAMILY_VGH:
|
||||
case FAMILY_YELLOW_CARP:
|
||||
case AMDGPU_FAMILY_GC_10_3_6:
|
||||
case AMDGPU_FAMILY_GC_10_3_7:
|
||||
switch (AMD_FMT_MOD_GET(TILE, modifier)) {
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_D_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_S_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_D:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case AMDGPU_FAMILY_GC_11_0_0:
|
||||
case AMDGPU_FAMILY_GC_11_0_1:
|
||||
switch (AMD_FMT_MOD_GET(TILE, modifier)) {
|
||||
case AMD_FMT_MOD_TILE_GFX11_256K_R_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_D_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_S_X:
|
||||
case AMD_FMT_MOD_TILE_GFX9_64K_D:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT(0); /* Unknown asic */
|
||||
break;
|
||||
/* Check that the modifier is on the list of the plane's supported modifiers. */
|
||||
for (i = 0; i < plane->modifier_count; i++) {
|
||||
if (modifier == plane->modifiers[i])
|
||||
break;
|
||||
}
|
||||
if (i == plane->modifier_count)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* For D swizzle the canonical modifier depends on the bpp, so check
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <drm/drm_framebuffer.h>
|
||||
#include <drm/drm_encoder.h>
|
||||
#include <drm/drm_atomic.h>
|
||||
#include "dcn10/dcn10_optc.h"
|
||||
|
||||
#include "dc/inc/core_types.h"
|
||||
|
||||
|
@ -662,6 +663,69 @@ TRACE_EVENT(dcn_fpu,
|
|||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(dcn_optc_lock_unlock_state,
|
||||
TP_PROTO(const struct optc *optc_state, int instance, bool lock, const char *function, const int line),
|
||||
TP_ARGS(optc_state, instance, lock, function, line),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(const char *, function)
|
||||
__field(int, instance)
|
||||
__field(bool, lock)
|
||||
__field(int, line)
|
||||
__field(int, opp_count)
|
||||
__field(int, max_h_total)
|
||||
__field(int, max_v_total)
|
||||
__field(int, min_h_blank)
|
||||
__field(int, min_h_sync_width)
|
||||
__field(int, min_v_sync_width)
|
||||
__field(int, min_v_blank)
|
||||
__field(int, min_v_blank_interlace)
|
||||
__field(int, vstartup_start)
|
||||
__field(int, vupdate_offset)
|
||||
__field(int, vupdate_width)
|
||||
__field(int, vready_offset)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->function = function;
|
||||
__entry->instance = instance;
|
||||
__entry->lock = lock;
|
||||
__entry->line = line;
|
||||
__entry->opp_count = optc_state->opp_count;
|
||||
__entry->max_h_total = optc_state->max_h_total;
|
||||
__entry->max_v_total = optc_state->max_v_total;
|
||||
__entry->min_h_blank = optc_state->min_h_blank;
|
||||
__entry->min_h_sync_width = optc_state->min_h_sync_width;
|
||||
__entry->min_v_sync_width = optc_state->min_v_sync_width;
|
||||
__entry->min_v_blank = optc_state->min_v_blank;
|
||||
__entry->min_v_blank_interlace = optc_state->min_v_blank_interlace;
|
||||
__entry->vstartup_start = optc_state->vstartup_start;
|
||||
__entry->vupdate_offset = optc_state->vupdate_offset;
|
||||
__entry->vupdate_width = optc_state->vupdate_width;
|
||||
__entry->vready_offset = optc_state->vupdate_offset;
|
||||
),
|
||||
TP_printk("%s: %s()+%d: optc_instance=%d opp_count=%d max_h_total=%d max_v_total=%d "
|
||||
"min_h_blank=%d min_h_sync_width=%d min_v_sync_width=%d min_v_blank=%d "
|
||||
"min_v_blank_interlace=%d vstartup_start=%d vupdate_offset=%d vupdate_width=%d "
|
||||
"vready_offset=%d",
|
||||
__entry->lock ? "Lock" : "Unlock",
|
||||
__entry->function,
|
||||
__entry->line,
|
||||
__entry->instance,
|
||||
__entry->opp_count,
|
||||
__entry->max_h_total,
|
||||
__entry->max_v_total,
|
||||
__entry->min_h_blank,
|
||||
__entry->min_h_sync_width,
|
||||
__entry->min_v_sync_width,
|
||||
__entry->min_v_blank,
|
||||
__entry->min_v_blank_interlace,
|
||||
__entry->vstartup_start,
|
||||
__entry->vupdate_offset,
|
||||
__entry->vupdate_width,
|
||||
__entry->vready_offset
|
||||
)
|
||||
);
|
||||
|
||||
#endif /* _AMDGPU_DM_TRACE_H_ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#elif defined(CONFIG_PPC64)
|
||||
#include <asm/switch_to.h>
|
||||
#include <asm/cputable.h>
|
||||
#elif defined(CONFIG_ARM64)
|
||||
#include <asm/neon.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -99,6 +101,8 @@ void dc_fpu_begin(const char *function_name, const int line)
|
|||
preempt_disable();
|
||||
enable_kernel_fp();
|
||||
}
|
||||
#elif defined(CONFIG_ARM64)
|
||||
kernel_neon_begin();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -136,6 +140,8 @@ void dc_fpu_end(const char *function_name, const int line)
|
|||
disable_kernel_fp();
|
||||
preempt_enable();
|
||||
}
|
||||
#elif defined(CONFIG_ARM64)
|
||||
kernel_neon_end();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#ifndef DAL_DC_RN_CLK_MGR_VBIOS_SMU_H_
|
||||
#define DAL_DC_RN_CLK_MGR_VBIOS_SMU_H_
|
||||
|
||||
enum dcn_pwr_state;
|
||||
|
||||
int rn_vbios_smu_get_smu_version(struct clk_mgr_internal *clk_mgr);
|
||||
int rn_vbios_smu_set_dispclk(struct clk_mgr_internal *clk_mgr, int requested_dispclk_khz);
|
||||
int rn_vbios_smu_set_dprefclk(struct clk_mgr_internal *clk_mgr);
|
||||
|
@ -33,7 +35,7 @@ int rn_vbios_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int reque
|
|||
int rn_vbios_smu_set_min_deep_sleep_dcfclk(struct clk_mgr_internal *clk_mgr, int requested_min_ds_dcfclk_khz);
|
||||
void rn_vbios_smu_set_phyclk(struct clk_mgr_internal *clk_mgr, int requested_phyclk_khz);
|
||||
int rn_vbios_smu_set_dppclk(struct clk_mgr_internal *clk_mgr, int requested_dpp_khz);
|
||||
void rn_vbios_smu_set_dcn_low_power_state(struct clk_mgr_internal *clk_mgr, int display_count);
|
||||
void rn_vbios_smu_set_dcn_low_power_state(struct clk_mgr_internal *clk_mgr, enum dcn_pwr_state);
|
||||
void rn_vbios_smu_enable_48mhz_tmdp_refclk_pwrdwn(struct clk_mgr_internal *clk_mgr, bool enable);
|
||||
void rn_vbios_smu_enable_pme_wa(struct clk_mgr_internal *clk_mgr);
|
||||
int rn_vbios_smu_is_periodic_retraining_disabled(struct clk_mgr_internal *clk_mgr);
|
||||
|
|
|
@ -458,19 +458,6 @@ static void dcn315_get_dpm_table_from_smu(struct clk_mgr_internal *clk_mgr,
|
|||
dcn315_smu_transfer_dpm_table_smu_2_dram(clk_mgr);
|
||||
}
|
||||
|
||||
static uint32_t find_max_clk_value(const uint32_t clocks[], uint32_t num_clocks)
|
||||
{
|
||||
uint32_t max = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_clocks; ++i) {
|
||||
if (clocks[i] > max)
|
||||
max = clocks[i];
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
static void dcn315_clk_mgr_helper_populate_bw_params(
|
||||
struct clk_mgr_internal *clk_mgr,
|
||||
struct integrated_info *bios_info,
|
||||
|
@ -478,29 +465,21 @@ static void dcn315_clk_mgr_helper_populate_bw_params(
|
|||
{
|
||||
int i;
|
||||
struct clk_bw_params *bw_params = clk_mgr->base.bw_params;
|
||||
uint32_t max_pstate = 0, max_fclk = 0, min_pstate = 0;
|
||||
uint32_t max_pstate = clock_table->NumDfPstatesEnabled - 1;
|
||||
struct clk_limit_table_entry def_max = bw_params->clk_table.entries[bw_params->clk_table.num_entries - 1];
|
||||
|
||||
/* Find highest fclk pstate */
|
||||
for (i = 0; i < clock_table->NumDfPstatesEnabled; i++) {
|
||||
if (clock_table->DfPstateTable[i].FClk > max_fclk) {
|
||||
max_fclk = clock_table->DfPstateTable[i].FClk;
|
||||
max_pstate = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* For 315 we want to base clock table on dcfclk, need at least one entry regardless of pmfw table */
|
||||
for (i = 0; i < clock_table->NumDcfClkLevelsEnabled; i++) {
|
||||
int j;
|
||||
uint32_t min_fclk = clock_table->DfPstateTable[0].FClk;
|
||||
|
||||
for (j = 1; j < clock_table->NumDfPstatesEnabled; j++) {
|
||||
if (clock_table->DfPstateTable[j].Voltage <= clock_table->SocVoltage[i]
|
||||
&& clock_table->DfPstateTable[j].FClk < min_fclk) {
|
||||
min_fclk = clock_table->DfPstateTable[j].FClk;
|
||||
min_pstate = j;
|
||||
}
|
||||
/* DF table is sorted with clocks decreasing */
|
||||
for (j = clock_table->NumDfPstatesEnabled - 2; j >= 0; j--) {
|
||||
if (clock_table->DfPstateTable[j].Voltage <= clock_table->SocVoltage[i])
|
||||
max_pstate = j;
|
||||
}
|
||||
/* Max DCFCLK should match up with max pstate */
|
||||
if (i == clock_table->NumDcfClkLevelsEnabled - 1)
|
||||
max_pstate = 0;
|
||||
|
||||
/* First search defaults for the clocks we don't read using closest lower or equal default dcfclk */
|
||||
for (j = bw_params->clk_table.num_entries - 1; j > 0; j--)
|
||||
|
@ -511,9 +490,9 @@ static void dcn315_clk_mgr_helper_populate_bw_params(
|
|||
bw_params->clk_table.entries[i].dtbclk_mhz = bw_params->clk_table.entries[j].dtbclk_mhz;
|
||||
|
||||
/* Now update clocks we do read */
|
||||
bw_params->clk_table.entries[i].fclk_mhz = min_fclk;
|
||||
bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[min_pstate].MemClk;
|
||||
bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[min_pstate].Voltage;
|
||||
bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[max_pstate].FClk;
|
||||
bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[max_pstate].MemClk;
|
||||
bw_params->clk_table.entries[i].voltage = clock_table->SocVoltage[i];
|
||||
bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[i];
|
||||
bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i];
|
||||
bw_params->clk_table.entries[i].dispclk_mhz = clock_table->DispClocks[i];
|
||||
|
@ -521,25 +500,16 @@ static void dcn315_clk_mgr_helper_populate_bw_params(
|
|||
bw_params->clk_table.entries[i].wck_ratio = 1;
|
||||
}
|
||||
|
||||
/* Make sure to include at least one entry and highest pstate */
|
||||
if (max_pstate != min_pstate || i == 0) {
|
||||
bw_params->clk_table.entries[i].fclk_mhz = max_fclk;
|
||||
bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[max_pstate].MemClk;
|
||||
bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[max_pstate].Voltage;
|
||||
bw_params->clk_table.entries[i].dcfclk_mhz = find_max_clk_value(clock_table->DcfClocks, NUM_DCFCLK_DPM_LEVELS);
|
||||
/* Make sure to include at least one entry */
|
||||
if (i == 0) {
|
||||
bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[0].FClk;
|
||||
bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[0].MemClk;
|
||||
bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[0].Voltage;
|
||||
bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[0];
|
||||
bw_params->clk_table.entries[i].wck_ratio = 1;
|
||||
i++;
|
||||
}
|
||||
bw_params->clk_table.num_entries = i--;
|
||||
|
||||
/* Make sure all highest clocks are included*/
|
||||
bw_params->clk_table.entries[i].socclk_mhz = find_max_clk_value(clock_table->SocClocks, NUM_SOCCLK_DPM_LEVELS);
|
||||
bw_params->clk_table.entries[i].dispclk_mhz = find_max_clk_value(clock_table->DispClocks, NUM_DISPCLK_DPM_LEVELS);
|
||||
bw_params->clk_table.entries[i].dppclk_mhz = find_max_clk_value(clock_table->DppClocks, NUM_DPPCLK_DPM_LEVELS);
|
||||
ASSERT(clock_table->DcfClocks[i] == find_max_clk_value(clock_table->DcfClocks, NUM_DCFCLK_DPM_LEVELS));
|
||||
bw_params->clk_table.entries[i].phyclk_mhz = def_max.phyclk_mhz;
|
||||
bw_params->clk_table.entries[i].phyclk_d18_mhz = def_max.phyclk_d18_mhz;
|
||||
bw_params->clk_table.entries[i].dtbclk_mhz = def_max.dtbclk_mhz;
|
||||
bw_params->clk_table.num_entries = i;
|
||||
|
||||
/* Set any 0 clocks to max default setting. Not an issue for
|
||||
* power since we aren't doing switching in such case anyway
|
||||
|
@ -565,6 +535,11 @@ static void dcn315_clk_mgr_helper_populate_bw_params(
|
|||
if (!bw_params->clk_table.entries[i].dtbclk_mhz)
|
||||
bw_params->clk_table.entries[i].dtbclk_mhz = def_max.dtbclk_mhz;
|
||||
}
|
||||
|
||||
/* Make sure all highest default clocks are included*/
|
||||
ASSERT(bw_params->clk_table.entries[i-1].phyclk_mhz == def_max.phyclk_mhz);
|
||||
ASSERT(bw_params->clk_table.entries[i-1].phyclk_d18_mhz == def_max.phyclk_d18_mhz);
|
||||
ASSERT(bw_params->clk_table.entries[i-1].dtbclk_mhz == def_max.dtbclk_mhz);
|
||||
ASSERT(bw_params->clk_table.entries[i-1].dcfclk_mhz);
|
||||
bw_params->vram_type = bios_info->memory_type;
|
||||
bw_params->num_channels = bios_info->ma_channel_number;
|
||||
|
|
|
@ -157,6 +157,7 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
|
|||
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
|
||||
unsigned int num_levels;
|
||||
struct clk_limit_num_entries *num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk;
|
||||
unsigned int i;
|
||||
|
||||
memset(&(clk_mgr_base->clks), 0, sizeof(struct dc_clocks));
|
||||
clk_mgr_base->clks.p_state_change_support = true;
|
||||
|
@ -205,18 +206,17 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
|
|||
clk_mgr->dpm_present = true;
|
||||
|
||||
if (clk_mgr_base->ctx->dc->debug.min_disp_clk_khz) {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < num_levels; i++)
|
||||
if (clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz
|
||||
< khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_disp_clk_khz))
|
||||
clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz
|
||||
= khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_disp_clk_khz);
|
||||
}
|
||||
for (i = 0; i < num_levels; i++)
|
||||
if (clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz > 1950)
|
||||
clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz = 1950;
|
||||
|
||||
if (clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz) {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < num_levels; i++)
|
||||
if (clk_mgr_base->bw_params->clk_table.entries[i].dppclk_mhz
|
||||
< khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz))
|
||||
|
@ -669,6 +669,9 @@ static void dcn32_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base)
|
|||
&clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz,
|
||||
&num_entries_per_clk->num_memclk_levels);
|
||||
|
||||
/* memclk must have at least one level */
|
||||
num_entries_per_clk->num_memclk_levels = num_entries_per_clk->num_memclk_levels ? num_entries_per_clk->num_memclk_levels : 1;
|
||||
|
||||
dcn32_init_single_clock(clk_mgr, PPCLK_FCLK,
|
||||
&clk_mgr_base->bw_params->clk_table.entries[0].fclk_mhz,
|
||||
&num_entries_per_clk->num_fclk_levels);
|
||||
|
|
|
@ -135,9 +135,7 @@ static const char DC_BUILD_ID[] = "production-build";
|
|||
* one or two (in the pipe-split case).
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Private functions
|
||||
******************************************************************************/
|
||||
/* Private functions */
|
||||
|
||||
static inline void elevate_update_type(enum surface_update_type *original, enum surface_update_type new)
|
||||
{
|
||||
|
@ -401,9 +399,6 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
|||
{
|
||||
int i;
|
||||
|
||||
if (memcmp(adjust, &stream->adjust, sizeof(struct dc_crtc_timing_adjust)) == 0)
|
||||
return true;
|
||||
|
||||
stream->adjust.v_total_max = adjust->v_total_max;
|
||||
stream->adjust.v_total_mid = adjust->v_total_mid;
|
||||
stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num;
|
||||
|
@ -424,18 +419,14 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
|||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************
|
||||
* Function: dc_stream_get_last_vrr_vtotal
|
||||
* dc_stream_get_last_used_drr_vtotal - dc_stream_get_last_vrr_vtotal
|
||||
*
|
||||
* @brief
|
||||
* Looks up the pipe context of dc_stream_state and gets the
|
||||
* last VTOTAL used by DRR (Dynamic Refresh Rate)
|
||||
* @dc: [in] dc reference
|
||||
* @stream: [in] Initial dc stream state
|
||||
* @adjust: [in] Updated parameters for vertical_total_min and
|
||||
*
|
||||
* @param [in] dc: dc reference
|
||||
* @param [in] stream: Initial dc stream state
|
||||
* @param [in] adjust: Updated parameters for vertical_total_min and
|
||||
* vertical_total_max
|
||||
*****************************************************************************
|
||||
* Looks up the pipe context of dc_stream_state and gets the last VTOTAL used
|
||||
* by DRR (Dynamic Refresh Rate)
|
||||
*/
|
||||
bool dc_stream_get_last_used_drr_vtotal(struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
|
@ -491,86 +482,79 @@ bool dc_stream_get_crtc_position(struct dc *dc,
|
|||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
bool dc_stream_forward_dmcu_crc_window(struct dc *dc, struct dc_stream_state *stream,
|
||||
struct crc_params *crc_window)
|
||||
static inline void
|
||||
dc_stream_forward_dmub_crc_window(struct dc_dmub_srv *dmub_srv,
|
||||
struct rect *rect, struct otg_phy_mux *mux_mapping, bool is_stop)
|
||||
{
|
||||
int i;
|
||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||
struct pipe_ctx *pipe;
|
||||
struct crc_region tmp_win, *crc_win;
|
||||
struct otg_phy_mux mapping_tmp, *mux_mapping;
|
||||
union dmub_rb_cmd cmd = {0};
|
||||
|
||||
/*crc window can't be null*/
|
||||
if (!crc_window)
|
||||
return false;
|
||||
cmd.secure_display.roi_info.phy_id = mux_mapping->phy_output_num;
|
||||
cmd.secure_display.roi_info.otg_id = mux_mapping->otg_output_num;
|
||||
|
||||
if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu))) {
|
||||
crc_win = &tmp_win;
|
||||
mux_mapping = &mapping_tmp;
|
||||
/*set crc window*/
|
||||
tmp_win.x_start = crc_window->windowa_x_start;
|
||||
tmp_win.y_start = crc_window->windowa_y_start;
|
||||
tmp_win.x_end = crc_window->windowa_x_end;
|
||||
tmp_win.y_end = crc_window->windowa_y_end;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe->stream == stream && !pipe->top_pipe && !pipe->prev_odm_pipe)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Stream not found */
|
||||
if (i == MAX_PIPES)
|
||||
return false;
|
||||
|
||||
|
||||
/*set mux routing info*/
|
||||
mapping_tmp.phy_output_num = stream->link->link_enc_hw_inst;
|
||||
mapping_tmp.otg_output_num = pipe->stream_res.tg->inst;
|
||||
|
||||
dmcu->funcs->forward_crc_window(dmcu, crc_win, mux_mapping);
|
||||
if (is_stop) {
|
||||
cmd.secure_display.header.type = DMUB_CMD__SECURE_DISPLAY;
|
||||
cmd.secure_display.header.sub_type = DMUB_CMD__SECURE_DISPLAY_CRC_STOP_UPDATE;
|
||||
} else {
|
||||
DC_LOG_DC("dmcu is not initialized");
|
||||
return false;
|
||||
cmd.secure_display.header.type = DMUB_CMD__SECURE_DISPLAY;
|
||||
cmd.secure_display.header.sub_type = DMUB_CMD__SECURE_DISPLAY_CRC_WIN_NOTIFY;
|
||||
cmd.secure_display.roi_info.x_start = rect->x;
|
||||
cmd.secure_display.roi_info.y_start = rect->y;
|
||||
cmd.secure_display.roi_info.x_end = rect->x + rect->width;
|
||||
cmd.secure_display.roi_info.y_end = rect->y + rect->height;
|
||||
}
|
||||
|
||||
return true;
|
||||
dc_dmub_srv_cmd_queue(dmub_srv, &cmd);
|
||||
dc_dmub_srv_cmd_execute(dmub_srv);
|
||||
}
|
||||
|
||||
bool dc_stream_stop_dmcu_crc_win_update(struct dc *dc, struct dc_stream_state *stream)
|
||||
static inline void
|
||||
dc_stream_forward_dmcu_crc_window(struct dmcu *dmcu,
|
||||
struct rect *rect, struct otg_phy_mux *mux_mapping, bool is_stop)
|
||||
{
|
||||
int i;
|
||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||
struct pipe_ctx *pipe;
|
||||
struct otg_phy_mux mapping_tmp, *mux_mapping;
|
||||
|
||||
if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu))) {
|
||||
mux_mapping = &mapping_tmp;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe->stream == stream && !pipe->top_pipe && !pipe->prev_odm_pipe)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Stream not found */
|
||||
if (i == MAX_PIPES)
|
||||
return false;
|
||||
|
||||
|
||||
/*set mux routing info*/
|
||||
mapping_tmp.phy_output_num = stream->link->link_enc_hw_inst;
|
||||
mapping_tmp.otg_output_num = pipe->stream_res.tg->inst;
|
||||
|
||||
if (is_stop)
|
||||
dmcu->funcs->stop_crc_win_update(dmcu, mux_mapping);
|
||||
} else {
|
||||
DC_LOG_DC("dmcu is not initialized");
|
||||
return false;
|
||||
else
|
||||
dmcu->funcs->forward_crc_window(dmcu, rect, mux_mapping);
|
||||
}
|
||||
|
||||
bool
|
||||
dc_stream_forward_crc_window(struct dc *dc,
|
||||
struct rect *rect, struct dc_stream_state *stream, bool is_stop)
|
||||
{
|
||||
struct dmcu *dmcu;
|
||||
struct dc_dmub_srv *dmub_srv;
|
||||
struct otg_phy_mux mux_mapping;
|
||||
struct pipe_ctx *pipe;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe->stream == stream && !pipe->top_pipe && !pipe->prev_odm_pipe)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Stream not found */
|
||||
if (i == MAX_PIPES)
|
||||
return false;
|
||||
|
||||
mux_mapping.phy_output_num = stream->link->link_enc_hw_inst;
|
||||
mux_mapping.otg_output_num = pipe->stream_res.tg->inst;
|
||||
|
||||
dmcu = dc->res_pool->dmcu;
|
||||
dmub_srv = dc->ctx->dmub_srv;
|
||||
|
||||
/* forward to dmub */
|
||||
if (dmub_srv)
|
||||
dc_stream_forward_dmub_crc_window(dmub_srv, rect, &mux_mapping, is_stop);
|
||||
/* forward to dmcu */
|
||||
else if (dmcu && dmcu->funcs->is_dmcu_initialized(dmcu))
|
||||
dc_stream_forward_dmcu_crc_window(dmcu, rect, &mux_mapping, is_stop);
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_DRM_AMD_SECURE_DISPLAY */
|
||||
|
||||
/**
|
||||
* dc_stream_configure_crc() - Configure CRC capture for the given stream.
|
||||
|
@ -1219,9 +1203,7 @@ static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
|
|||
PERF_TRACE();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Public functions
|
||||
******************************************************************************/
|
||||
/* Public functions */
|
||||
|
||||
struct dc *dc_create(const struct dc_init_data *init_params)
|
||||
{
|
||||
|
@ -1488,17 +1470,19 @@ static void program_timing_sync(
|
|||
}
|
||||
}
|
||||
|
||||
static bool context_changed(
|
||||
struct dc *dc,
|
||||
struct dc_state *context)
|
||||
static bool streams_changed(struct dc *dc,
|
||||
struct dc_stream_state *streams[],
|
||||
uint8_t stream_count)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if (context->stream_count != dc->current_state->stream_count)
|
||||
if (stream_count != dc->current_state->stream_count)
|
||||
return true;
|
||||
|
||||
for (i = 0; i < dc->current_state->stream_count; i++) {
|
||||
if (dc->current_state->streams[i] != context->streams[i])
|
||||
if (dc->current_state->streams[i] != streams[i])
|
||||
return true;
|
||||
if (!streams[i]->link->link_state_valid)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1722,8 +1706,13 @@ void dc_z10_save_init(struct dc *dc)
|
|||
dc->hwss.z10_save_init(dc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Applies given context to HW and copy it into current context.
|
||||
/**
|
||||
* dc_commit_state_no_check - Apply context to the hardware
|
||||
*
|
||||
* @dc: DC object with the current status to be updated
|
||||
* @context: New state that will become the current status at the end of this function
|
||||
*
|
||||
* Applies given context to the hardware and copy it into current context.
|
||||
* It's up to the user to release the src context afterwards.
|
||||
*/
|
||||
static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context)
|
||||
|
@ -1888,12 +1877,108 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* dc_commit_streams - Commit current stream state
|
||||
*
|
||||
* @dc: DC object with the commit state to be configured in the hardware
|
||||
* @streams: Array with a list of stream state
|
||||
* @stream_count: Total of streams
|
||||
*
|
||||
* Function responsible for commit streams change to the hardware.
|
||||
*
|
||||
* Return:
|
||||
* Return DC_OK if everything work as expected, otherwise, return a dc_status
|
||||
* code.
|
||||
*/
|
||||
enum dc_status dc_commit_streams(struct dc *dc,
|
||||
struct dc_stream_state *streams[],
|
||||
uint8_t stream_count)
|
||||
{
|
||||
int i, j;
|
||||
struct dc_state *context;
|
||||
enum dc_status res = DC_OK;
|
||||
struct dc_validation_set set[MAX_STREAMS] = {0};
|
||||
|
||||
if (dc->ctx->dce_environment == DCE_ENV_VIRTUAL_HW)
|
||||
return res;
|
||||
|
||||
if (!streams_changed(dc, streams, stream_count))
|
||||
return res;
|
||||
|
||||
DC_LOG_DC("%s: %d streams\n", __func__, stream_count);
|
||||
|
||||
for (i = 0; i < stream_count; i++) {
|
||||
struct dc_stream_state *stream = streams[i];
|
||||
struct dc_stream_status *status = dc_stream_get_status(stream);
|
||||
|
||||
dc_stream_log(dc, stream);
|
||||
|
||||
set[i].stream = stream;
|
||||
|
||||
if (status) {
|
||||
set[i].plane_count = status->plane_count;
|
||||
for (j = 0; j < status->plane_count; j++)
|
||||
set[i].plane_states[j] = status->plane_states[j];
|
||||
}
|
||||
}
|
||||
|
||||
context = dc_create_state(dc);
|
||||
if (!context)
|
||||
goto context_alloc_fail;
|
||||
|
||||
dc_resource_state_copy_construct_current(dc, context);
|
||||
|
||||
res = dc_validate_with_context(dc, set, stream_count, context, false);
|
||||
if (res != DC_OK) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
res = dc_commit_state_no_check(dc, context);
|
||||
|
||||
for (i = 0; i < stream_count; i++) {
|
||||
for (j = 0; j < context->stream_count; j++) {
|
||||
if (streams[i]->stream_id == context->streams[j]->stream_id)
|
||||
streams[i]->out.otg_offset = context->stream_status[j].primary_otg_inst;
|
||||
|
||||
if (dc_is_embedded_signal(streams[i]->signal)) {
|
||||
struct dc_stream_status *status = dc_stream_get_status_from_state(context, streams[i]);
|
||||
|
||||
if (dc->hwss.is_abm_supported)
|
||||
status->is_abm_supported = dc->hwss.is_abm_supported(dc, context, streams[i]);
|
||||
else
|
||||
status->is_abm_supported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
dc_release_state(context);
|
||||
|
||||
context_alloc_fail:
|
||||
|
||||
DC_LOG_DC("%s Finished.\n", __func__);
|
||||
|
||||
return (res == DC_OK);
|
||||
}
|
||||
|
||||
/* TODO: When the transition to the new commit sequence is done, remove this
|
||||
* function in favor of dc_commit_streams. */
|
||||
bool dc_commit_state(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
enum dc_status result = DC_ERROR_UNEXPECTED;
|
||||
int i;
|
||||
|
||||
if (!context_changed(dc, context))
|
||||
/* TODO: Since change commit sequence can have a huge impact,
|
||||
* we decided to only enable it for DCN3x. However, as soon as
|
||||
* we get more confident about this change we'll need to enable
|
||||
* the new sequence for all ASICs. */
|
||||
if (dc->ctx->dce_version >= DCN_VERSION_3_2) {
|
||||
result = dc_commit_streams(dc, context->streams, context->stream_count);
|
||||
return result == DC_OK;
|
||||
}
|
||||
|
||||
if (!streams_changed(dc, context->streams, context->stream_count))
|
||||
return DC_OK;
|
||||
|
||||
DC_LOG_DC("%s: %d streams\n",
|
||||
|
@ -3563,10 +3648,24 @@ static void commit_planes_for_stream(struct dc *dc,
|
|||
}
|
||||
}
|
||||
|
||||
/* Determines if the incoming context requires a applying transition state with unnecessary
|
||||
* pipe splitting and ODM disabled, due to hardware limitations. In a case where
|
||||
* the OPP associated with an MPCC might change due to plane additions, this function
|
||||
/**
|
||||
* could_mpcc_tree_change_for_active_pipes - Check if an OPP associated with MPCC might change
|
||||
*
|
||||
* @dc: Used to get the current state status
|
||||
* @stream: Target stream, which we want to remove the attached planes
|
||||
* @surface_count: Number of surface update
|
||||
* @is_plane_addition: [in] Fill out with true if it is a plane addition case
|
||||
*
|
||||
* DCN32x and newer support a feature named Dynamic ODM which can conflict with
|
||||
* the MPO if used simultaneously in some specific configurations (e.g.,
|
||||
* 4k@144). This function checks if the incoming context requires applying a
|
||||
* transition state with unnecessary pipe splitting and ODM disabled to
|
||||
* circumvent our hardware limitations to prevent this edge case. If the OPP
|
||||
* associated with an MPCC might change due to plane additions, this function
|
||||
* returns true.
|
||||
*
|
||||
* Return:
|
||||
* Return true if OPP and MPCC might change, otherwise, return false.
|
||||
*/
|
||||
static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
|
@ -3641,6 +3740,24 @@ static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
|
|||
return force_minimal_pipe_splitting;
|
||||
}
|
||||
|
||||
/**
|
||||
* commit_minimal_transition_state - Create a transition pipe split state
|
||||
*
|
||||
* @dc: Used to get the current state status
|
||||
* @transition_base_context: New transition state
|
||||
*
|
||||
* In some specific configurations, such as pipe split on multi-display with
|
||||
* MPO and/or Dynamic ODM, removing a plane may cause unsupported pipe
|
||||
* programming when moving to new planes. To mitigate those types of problems,
|
||||
* this function adds a transition state that minimizes pipe usage before
|
||||
* programming the new configuration. When adding a new plane, the current
|
||||
* state requires the least pipes, so it is applied without splitting. When
|
||||
* removing a plane, the new state requires the least pipes, so it is applied
|
||||
* without splitting.
|
||||
*
|
||||
* Return:
|
||||
* Return false if something is wrong in the transition state.
|
||||
*/
|
||||
static bool commit_minimal_transition_state(struct dc *dc,
|
||||
struct dc_state *transition_base_context)
|
||||
{
|
||||
|
@ -3650,9 +3767,35 @@ static bool commit_minimal_transition_state(struct dc *dc,
|
|||
bool temp_subvp_policy;
|
||||
enum dc_status ret = DC_ERROR_UNEXPECTED;
|
||||
unsigned int i, j;
|
||||
unsigned int pipe_in_use = 0;
|
||||
|
||||
if (!transition_context)
|
||||
return false;
|
||||
/* Setup:
|
||||
* Store the current ODM and MPC config in some temp variables to be
|
||||
* restored after we commit the transition state.
|
||||
*/
|
||||
|
||||
/* check current pipes in use*/
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &transition_base_context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (pipe->plane_state)
|
||||
pipe_in_use++;
|
||||
}
|
||||
|
||||
/* When the OS add a new surface if we have been used all of pipes with odm combine
|
||||
* and mpc split feature, it need use commit_minimal_transition_state to transition safely.
|
||||
* After OS exit MPO, it will back to use odm and mpc split with all of pipes, we need
|
||||
* call it again. Otherwise return true to skip.
|
||||
*
|
||||
* Reduce the scenarios to use dc_commit_state_no_check in the stage of flip. Especially
|
||||
* enter/exit MPO when DCN still have enough resources.
|
||||
*/
|
||||
if (pipe_in_use != dc->res_pool->pipe_count) {
|
||||
dc_release_state(transition_context);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!dc->config.is_vmin_only_asic) {
|
||||
tmp_mpc_policy = dc->debug.pipe_split_policy;
|
||||
|
@ -3667,7 +3810,7 @@ static bool commit_minimal_transition_state(struct dc *dc,
|
|||
|
||||
dc_resource_state_copy_construct(transition_base_context, transition_context);
|
||||
|
||||
//commit minimal state
|
||||
/* commit minimal state */
|
||||
if (dc->res_pool->funcs->validate_bandwidth(dc, transition_context, false)) {
|
||||
for (i = 0; i < transition_context->stream_count; i++) {
|
||||
struct dc_stream_status *stream_status = &transition_context->stream_status[i];
|
||||
|
@ -3685,10 +3828,12 @@ static bool commit_minimal_transition_state(struct dc *dc,
|
|||
ret = dc_commit_state_no_check(dc, transition_context);
|
||||
}
|
||||
|
||||
/*always release as dc_commit_state_no_check retains in good case*/
|
||||
/* always release as dc_commit_state_no_check retains in good case */
|
||||
dc_release_state(transition_context);
|
||||
|
||||
/*restore previous pipe split and odm policy*/
|
||||
/* TearDown:
|
||||
* Restore original configuration for ODM and MPO.
|
||||
*/
|
||||
if (!dc->config.is_vmin_only_asic)
|
||||
dc->debug.pipe_split_policy = tmp_mpc_policy;
|
||||
|
||||
|
@ -3696,12 +3841,12 @@ static bool commit_minimal_transition_state(struct dc *dc,
|
|||
dc->debug.force_disable_subvp = temp_subvp_policy;
|
||||
|
||||
if (ret != DC_OK) {
|
||||
/*this should never happen*/
|
||||
/* this should never happen */
|
||||
BREAK_TO_DEBUGGER();
|
||||
return false;
|
||||
}
|
||||
|
||||
/*force full surface update*/
|
||||
/* force full surface update */
|
||||
for (i = 0; i < dc->current_state->stream_count; i++) {
|
||||
for (j = 0; j < dc->current_state->stream_status[i].plane_count; j++) {
|
||||
dc->current_state->stream_status[i].plane_states[j]->update_flags.raw = 0xFFFFFFFF;
|
||||
|
@ -3806,6 +3951,18 @@ void dc_commit_updates_for_stream(struct dc *dc,
|
|||
struct dc_context *dc_ctx = dc->ctx;
|
||||
int i, j;
|
||||
|
||||
/* TODO: Since change commit sequence can have a huge impact,
|
||||
* we decided to only enable it for DCN3x. However, as soon as
|
||||
* we get more confident about this change we'll need to enable
|
||||
* the new sequence for all ASICs.
|
||||
*/
|
||||
if (dc->ctx->dce_version >= DCN_VERSION_3_2) {
|
||||
dc_update_planes_and_stream(dc, srf_updates,
|
||||
surface_count, stream,
|
||||
stream_update);
|
||||
return;
|
||||
}
|
||||
|
||||
stream_status = dc_stream_get_status(stream);
|
||||
context = dc->current_state;
|
||||
|
||||
|
@ -4387,21 +4544,17 @@ void dc_mclk_switch_using_fw_based_vblank_stretch_shut_down(struct dc *dc)
|
|||
dc->current_state->bw_ctx.bw.dcn.clk.fw_based_mclk_switching_shut_down = true;
|
||||
}
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function: dc_is_dmub_outbox_supported -
|
||||
/**
|
||||
* dc_is_dmub_outbox_supported - Check if DMUB firmware support outbox notification
|
||||
*
|
||||
* @brief
|
||||
* Checks whether DMUB FW supports outbox notifications, if supported
|
||||
* DM should register outbox interrupt prior to actually enabling interrupts
|
||||
* via dc_enable_dmub_outbox
|
||||
* @dc: [in] dc structure
|
||||
*
|
||||
* @param
|
||||
* [in] dc: dc structure
|
||||
* Checks whether DMUB FW supports outbox notifications, if supported DM
|
||||
* should register outbox interrupt prior to actually enabling interrupts
|
||||
* via dc_enable_dmub_outbox
|
||||
*
|
||||
* @return
|
||||
* True if DMUB FW supports outbox notifications, False otherwise
|
||||
*****************************************************************************
|
||||
* Return:
|
||||
* True if DMUB FW supports outbox notifications, False otherwise
|
||||
*/
|
||||
bool dc_is_dmub_outbox_supported(struct dc *dc)
|
||||
{
|
||||
|
@ -4419,21 +4572,17 @@ bool dc_is_dmub_outbox_supported(struct dc *dc)
|
|||
return dc->debug.enable_dmub_aux_for_legacy_ddc;
|
||||
}
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function: dc_enable_dmub_notifications
|
||||
/**
|
||||
* dc_enable_dmub_notifications - Check if dmub fw supports outbox
|
||||
*
|
||||
* @brief
|
||||
* Calls dc_is_dmub_outbox_supported to check if dmub fw supports outbox
|
||||
* notifications. All DMs shall switch to dc_is_dmub_outbox_supported.
|
||||
* This API shall be removed after switching.
|
||||
* @dc: [in] dc structure
|
||||
*
|
||||
* @param
|
||||
* [in] dc: dc structure
|
||||
* Calls dc_is_dmub_outbox_supported to check if dmub fw supports outbox
|
||||
* notifications. All DMs shall switch to dc_is_dmub_outbox_supported. This
|
||||
* API shall be removed after switching.
|
||||
*
|
||||
* @return
|
||||
* True if DMUB FW supports outbox notifications, False otherwise
|
||||
*****************************************************************************
|
||||
* Return:
|
||||
* True if DMUB FW supports outbox notifications, False otherwise
|
||||
*/
|
||||
bool dc_enable_dmub_notifications(struct dc *dc)
|
||||
{
|
||||
|
@ -4441,18 +4590,11 @@ bool dc_enable_dmub_notifications(struct dc *dc)
|
|||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************
|
||||
* Function: dc_enable_dmub_outbox
|
||||
* dc_enable_dmub_outbox - Enables DMUB unsolicited notification
|
||||
*
|
||||
* @brief
|
||||
* Enables DMUB unsolicited notifications to x86 via outbox
|
||||
* dc: [in] dc structure
|
||||
*
|
||||
* @param
|
||||
* [in] dc: dc structure
|
||||
*
|
||||
* @return
|
||||
* None
|
||||
*****************************************************************************
|
||||
* Enables DMUB unsolicited notifications to x86 via outbox.
|
||||
*/
|
||||
void dc_enable_dmub_outbox(struct dc *dc)
|
||||
{
|
||||
|
@ -4553,21 +4695,17 @@ uint8_t get_link_index_from_dpia_port_index(const struct dc *dc,
|
|||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************
|
||||
* Function: dc_process_dmub_set_config_async
|
||||
* dc_process_dmub_set_config_async - Submits set_config command
|
||||
*
|
||||
* @brief
|
||||
* Submits set_config command to dmub via inbox message
|
||||
* @dc: [in] dc structure
|
||||
* @link_index: [in] link_index: link index
|
||||
* @payload: [in] aux payload
|
||||
* @notify: [out] set_config immediate reply
|
||||
*
|
||||
* @param
|
||||
* [in] dc: dc structure
|
||||
* [in] link_index: link index
|
||||
* [in] payload: aux payload
|
||||
* [out] notify: set_config immediate reply
|
||||
* Submits set_config command to dmub via inbox message.
|
||||
*
|
||||
* @return
|
||||
* True if successful, False if failure
|
||||
*****************************************************************************
|
||||
* Return:
|
||||
* True if successful, False if failure
|
||||
*/
|
||||
bool dc_process_dmub_set_config_async(struct dc *dc,
|
||||
uint32_t link_index,
|
||||
|
@ -4603,21 +4741,17 @@ bool dc_process_dmub_set_config_async(struct dc *dc,
|
|||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************
|
||||
* Function: dc_process_dmub_set_mst_slots
|
||||
* dc_process_dmub_set_mst_slots - Submits MST solt allocation
|
||||
*
|
||||
* @brief
|
||||
* Submits mst slot allocation command to dmub via inbox message
|
||||
* @dc: [in] dc structure
|
||||
* @link_index: [in] link index
|
||||
* @mst_alloc_slots: [in] mst slots to be allotted
|
||||
* @mst_slots_in_use: [out] mst slots in use returned in failure case
|
||||
*
|
||||
* @param
|
||||
* [in] dc: dc structure
|
||||
* [in] link_index: link index
|
||||
* [in] mst_alloc_slots: mst slots to be allotted
|
||||
* [out] mst_slots_in_use: mst slots in use returned in failure case
|
||||
* Submits mst slot allocation command to dmub via inbox message
|
||||
*
|
||||
* @return
|
||||
* DC_OK if successful, DC_ERROR if failure
|
||||
*****************************************************************************
|
||||
* Return:
|
||||
* DC_OK if successful, DC_ERROR if failure
|
||||
*/
|
||||
enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc,
|
||||
uint32_t link_index,
|
||||
|
@ -4657,19 +4791,12 @@ enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc,
|
|||
}
|
||||
|
||||
/**
|
||||
*****************************************************************************
|
||||
* Function: dc_process_dmub_dpia_hpd_int_enable
|
||||
* dc_process_dmub_dpia_hpd_int_enable - Submits DPIA DPD interruption
|
||||
*
|
||||
* @brief
|
||||
* Submits dpia hpd int enable command to dmub via inbox message
|
||||
* @dc [in]: dc structure
|
||||
* @hpd_int_enable [in]: 1 for hpd int enable, 0 to disable
|
||||
*
|
||||
* @param
|
||||
* [in] dc: dc structure
|
||||
* [in] hpd_int_enable: 1 for hpd int enable, 0 to disable
|
||||
*
|
||||
* @return
|
||||
* None
|
||||
*****************************************************************************
|
||||
* Submits dpia hpd int enable command to dmub via inbox message
|
||||
*/
|
||||
void dc_process_dmub_dpia_hpd_int_enable(const struct dc *dc,
|
||||
uint32_t hpd_int_enable)
|
||||
|
@ -4698,16 +4825,13 @@ void dc_disable_accelerated_mode(struct dc *dc)
|
|||
|
||||
|
||||
/**
|
||||
*****************************************************************************
|
||||
* dc_notify_vsync_int_state() - notifies vsync enable/disable state
|
||||
* dc_notify_vsync_int_state - notifies vsync enable/disable state
|
||||
* @dc: dc structure
|
||||
* @stream: stream where vsync int state changed
|
||||
* @enable: whether vsync is enabled or disabled
|
||||
* @stream: stream where vsync int state changed
|
||||
* @enable: whether vsync is enabled or disabled
|
||||
*
|
||||
* Called when vsync is enabled/disabled
|
||||
* Will notify DMUB to start/stop ABM interrupts after steady state is reached
|
||||
*
|
||||
*****************************************************************************
|
||||
* Called when vsync is enabled/disabled Will notify DMUB to start/stop ABM
|
||||
* interrupts after steady state is reached.
|
||||
*/
|
||||
void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bool enable)
|
||||
{
|
||||
|
@ -4749,14 +4873,18 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bo
|
|||
if (pipe->stream_res.abm && pipe->stream_res.abm->funcs->set_abm_pause)
|
||||
pipe->stream_res.abm->funcs->set_abm_pause(pipe->stream_res.abm, !enable, i, pipe->stream_res.tg->inst);
|
||||
}
|
||||
/*
|
||||
* dc_extended_blank_supported: Decide whether extended blank is supported
|
||||
|
||||
/**
|
||||
* dc_extended_blank_supported 0 Decide whether extended blank is supported
|
||||
*
|
||||
* Extended blank is a freesync optimization feature to be enabled in the future.
|
||||
* During the extra vblank period gained from freesync, we have the ability to enter z9/z10.
|
||||
* @dc: [in] Current DC state
|
||||
*
|
||||
* @param [in] dc: Current DC state
|
||||
* @return: Indicate whether extended blank is supported (true or false)
|
||||
* Extended blank is a freesync optimization feature to be enabled in the
|
||||
* future. During the extra vblank period gained from freesync, we have the
|
||||
* ability to enter z9/z10.
|
||||
*
|
||||
* Return:
|
||||
* Indicate whether extended blank is supported (true or false)
|
||||
*/
|
||||
bool dc_extended_blank_supported(struct dc *dc)
|
||||
{
|
||||
|
|
|
@ -366,6 +366,7 @@ void get_hdr_visual_confirm_color(
|
|||
struct tg_color *color)
|
||||
{
|
||||
uint32_t color_value = MAX_TG_COLOR_VALUE;
|
||||
bool is_sdr = false;
|
||||
|
||||
/* Determine the overscan color based on the top-most (desktop) plane's context */
|
||||
struct pipe_ctx *top_pipe_ctx = pipe_ctx;
|
||||
|
@ -382,7 +383,8 @@ void get_hdr_visual_confirm_color(
|
|||
/* FreeSync 2 ARGB2101010 - set border color to pink */
|
||||
color->color_r_cr = color_value;
|
||||
color->color_b_cb = color_value;
|
||||
}
|
||||
} else
|
||||
is_sdr = true;
|
||||
break;
|
||||
case PIXEL_FORMAT_FP16:
|
||||
if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) {
|
||||
|
@ -391,14 +393,19 @@ void get_hdr_visual_confirm_color(
|
|||
} else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) {
|
||||
/* FreeSync 2 HDR - set border color to green */
|
||||
color->color_g_y = color_value;
|
||||
}
|
||||
} else
|
||||
is_sdr = true;
|
||||
break;
|
||||
default:
|
||||
is_sdr = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_sdr) {
|
||||
/* SDR - set border color to Gray */
|
||||
color->color_r_cr = color_value/2;
|
||||
color->color_b_cb = color_value/2;
|
||||
color->color_g_y = color_value/2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4229,6 +4229,7 @@ static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pi
|
|||
link_hwss->ext.set_throttled_vcp_size(pipe_ctx, avg_time_slots_per_mtp);
|
||||
|
||||
dc->hwss.unblank_stream(pipe_ctx, &stream->link->cur_link_settings);
|
||||
dc->hwss.enable_audio_stream(pipe_ctx);
|
||||
}
|
||||
|
||||
void core_link_enable_stream(
|
||||
|
@ -4308,10 +4309,7 @@ void core_link_enable_stream(
|
|||
/* Still enable stream features & audio on seamless boot for DP external displays */
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT) {
|
||||
enable_stream_features(pipe_ctx);
|
||||
if (pipe_ctx->stream_res.audio != NULL) {
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc);
|
||||
dc->hwss.enable_audio_stream(pipe_ctx);
|
||||
}
|
||||
dc->hwss.enable_audio_stream(pipe_ctx);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_HDCP)
|
||||
|
|
|
@ -5031,7 +5031,7 @@ static bool dpcd_read_sink_ext_caps(struct dc_link *link)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool dp_retrieve_lttpr_cap(struct dc_link *link)
|
||||
enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link)
|
||||
{
|
||||
uint8_t lttpr_dpcd_data[8];
|
||||
enum dc_status status = DC_ERROR_UNEXPECTED;
|
||||
|
@ -5099,7 +5099,7 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
|
|||
CONN_DATA_DETECT(link, lttpr_dpcd_data, sizeof(lttpr_dpcd_data), "LTTPR Caps: ");
|
||||
|
||||
DC_LOG_DC("is_lttpr_present = %d\n", is_lttpr_present);
|
||||
return is_lttpr_present;
|
||||
return status;
|
||||
}
|
||||
|
||||
bool dp_is_lttpr_present(struct dc_link *link)
|
||||
|
@ -5227,122 +5227,11 @@ static void retrieve_cable_id(struct dc_link *link)
|
|||
&link->dpcd_caps.cable_id, &usbc_cable_id);
|
||||
}
|
||||
|
||||
/* DPRX may take some time to respond to AUX messages after HPD asserted.
|
||||
* If AUX read unsuccessful, try to wake unresponsive DPRX by toggling DPCD SET_POWER (0x600).
|
||||
*/
|
||||
static enum dc_status wa_try_to_wake_dprx(struct dc_link *link, uint64_t timeout_ms)
|
||||
static enum dc_status wake_up_aux_channel(struct dc_link *link)
|
||||
{
|
||||
enum dc_status status = DC_ERROR_UNEXPECTED;
|
||||
uint8_t dpcd_data = 0;
|
||||
uint64_t start_ts = 0;
|
||||
uint64_t current_ts = 0;
|
||||
uint64_t time_taken_ms = 0;
|
||||
enum dc_connection_type type = dc_connection_none;
|
||||
bool lttpr_present;
|
||||
bool vbios_lttpr_interop = link->dc->caps.vbios_lttpr_aware;
|
||||
|
||||
lttpr_present = dp_is_lttpr_present(link) ||
|
||||
(!vbios_lttpr_interop || !link->dc->caps.extended_aux_timeout_support);
|
||||
DC_LOG_DC("lttpr_present = %d.\n", lttpr_present ? 1 : 0);
|
||||
|
||||
/* Issue an AUX read to test DPRX responsiveness. If LTTPR is supported the first read is expected to
|
||||
* be to determine LTTPR capabilities. Otherwise trying to read power state should be an innocuous AUX read.
|
||||
*/
|
||||
if (lttpr_present)
|
||||
status = core_link_read_dpcd(
|
||||
link,
|
||||
DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
|
||||
&dpcd_data,
|
||||
sizeof(dpcd_data));
|
||||
else
|
||||
status = core_link_read_dpcd(
|
||||
link,
|
||||
DP_SET_POWER,
|
||||
&dpcd_data,
|
||||
sizeof(dpcd_data));
|
||||
|
||||
if (status != DC_OK) {
|
||||
DC_LOG_WARNING("%s: Read DPCD LTTPR_CAP failed - try to toggle DPCD SET_POWER for %lld ms.",
|
||||
__func__,
|
||||
timeout_ms);
|
||||
start_ts = dm_get_timestamp(link->ctx);
|
||||
|
||||
do {
|
||||
if (!dc_link_detect_sink(link, &type) || type == dc_connection_none)
|
||||
break;
|
||||
|
||||
dpcd_data = DP_SET_POWER_D3;
|
||||
status = core_link_write_dpcd(
|
||||
link,
|
||||
DP_SET_POWER,
|
||||
&dpcd_data,
|
||||
sizeof(dpcd_data));
|
||||
|
||||
dpcd_data = DP_SET_POWER_D0;
|
||||
status = core_link_write_dpcd(
|
||||
link,
|
||||
DP_SET_POWER,
|
||||
&dpcd_data,
|
||||
sizeof(dpcd_data));
|
||||
|
||||
current_ts = dm_get_timestamp(link->ctx);
|
||||
time_taken_ms = div_u64(dm_get_elapse_time_in_ns(link->ctx, current_ts, start_ts), 1000000);
|
||||
} while (status != DC_OK && time_taken_ms < timeout_ms);
|
||||
|
||||
DC_LOG_WARNING("%s: DPCD SET_POWER %s after %lld ms%s",
|
||||
__func__,
|
||||
(status == DC_OK) ? "succeeded" : "failed",
|
||||
time_taken_ms,
|
||||
(type == dc_connection_none) ? ". Unplugged." : ".");
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bool retrieve_link_cap(struct dc_link *link)
|
||||
{
|
||||
/* DP_ADAPTER_CAP - DP_DPCD_REV + 1 == 16 and also DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT + 1 == 16,
|
||||
* which means size 16 will be good for both of those DPCD register block reads
|
||||
*/
|
||||
uint8_t dpcd_data[16];
|
||||
/*Only need to read 1 byte starting from DP_DPRX_FEATURE_ENUMERATION_LIST.
|
||||
*/
|
||||
uint8_t dpcd_dprx_data = '\0';
|
||||
uint8_t dpcd_power_state = '\0';
|
||||
|
||||
struct dp_device_vendor_id sink_id;
|
||||
union down_stream_port_count down_strm_port_count;
|
||||
union edp_configuration_cap edp_config_cap;
|
||||
union dp_downstream_port_present ds_port = { 0 };
|
||||
enum dc_status status = DC_ERROR_UNEXPECTED;
|
||||
uint32_t read_dpcd_retry_cnt = 3;
|
||||
uint32_t aux_channel_retry_cnt = 0;
|
||||
int i;
|
||||
struct dp_sink_hw_fw_revision dp_hw_fw_revision;
|
||||
const uint32_t post_oui_delay = 30; // 30ms
|
||||
bool is_lttpr_present = false;
|
||||
|
||||
memset(dpcd_data, '\0', sizeof(dpcd_data));
|
||||
memset(&down_strm_port_count,
|
||||
'\0', sizeof(union down_stream_port_count));
|
||||
memset(&edp_config_cap, '\0',
|
||||
sizeof(union edp_configuration_cap));
|
||||
|
||||
/* if extended timeout is supported in hardware,
|
||||
* default to LTTPR timeout (3.2ms) first as a W/A for DP link layer
|
||||
* CTS 4.2.1.1 regression introduced by CTS specs requirement update.
|
||||
*/
|
||||
dc_link_aux_try_to_configure_timeout(link->ddc,
|
||||
LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD);
|
||||
|
||||
/* Try to ensure AUX channel active before proceeding. */
|
||||
if (link->dc->debug.aux_wake_wa.bits.enable_wa) {
|
||||
uint64_t timeout_ms = link->dc->debug.aux_wake_wa.bits.timeout_ms;
|
||||
|
||||
if (link->dc->debug.aux_wake_wa.bits.use_default_timeout)
|
||||
timeout_ms = LINK_AUX_WAKE_TIMEOUT_MS;
|
||||
status = wa_try_to_wake_dprx(link, timeout_ms);
|
||||
}
|
||||
uint8_t dpcd_power_state = '\0';
|
||||
|
||||
while (status != DC_OK && aux_channel_retry_cnt < 10) {
|
||||
status = core_link_read_dpcd(link, DP_SET_POWER,
|
||||
|
@ -5359,7 +5248,6 @@ static bool retrieve_link_cap(struct dc_link *link)
|
|||
}
|
||||
}
|
||||
|
||||
/* If aux channel is not active, return false and trigger another detect*/
|
||||
if (status != DC_OK) {
|
||||
dpcd_power_state = DP_SET_POWER_D0;
|
||||
status = core_link_write_dpcd(
|
||||
|
@ -5374,12 +5262,56 @@ static bool retrieve_link_cap(struct dc_link *link)
|
|||
DP_SET_POWER,
|
||||
&dpcd_power_state,
|
||||
sizeof(dpcd_power_state));
|
||||
return false;
|
||||
return DC_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
is_lttpr_present = dp_retrieve_lttpr_cap(link);
|
||||
return DC_OK;
|
||||
}
|
||||
|
||||
if (is_lttpr_present)
|
||||
static bool retrieve_link_cap(struct dc_link *link)
|
||||
{
|
||||
/* DP_ADAPTER_CAP - DP_DPCD_REV + 1 == 16 and also DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT + 1 == 16,
|
||||
* which means size 16 will be good for both of those DPCD register block reads
|
||||
*/
|
||||
uint8_t dpcd_data[16];
|
||||
/*Only need to read 1 byte starting from DP_DPRX_FEATURE_ENUMERATION_LIST.
|
||||
*/
|
||||
uint8_t dpcd_dprx_data = '\0';
|
||||
|
||||
struct dp_device_vendor_id sink_id;
|
||||
union down_stream_port_count down_strm_port_count;
|
||||
union edp_configuration_cap edp_config_cap;
|
||||
union dp_downstream_port_present ds_port = { 0 };
|
||||
enum dc_status status = DC_ERROR_UNEXPECTED;
|
||||
uint32_t read_dpcd_retry_cnt = 3;
|
||||
int i;
|
||||
struct dp_sink_hw_fw_revision dp_hw_fw_revision;
|
||||
const uint32_t post_oui_delay = 30; // 30ms
|
||||
|
||||
memset(dpcd_data, '\0', sizeof(dpcd_data));
|
||||
memset(&down_strm_port_count,
|
||||
'\0', sizeof(union down_stream_port_count));
|
||||
memset(&edp_config_cap, '\0',
|
||||
sizeof(union edp_configuration_cap));
|
||||
|
||||
/* if extended timeout is supported in hardware,
|
||||
* default to LTTPR timeout (3.2ms) first as a W/A for DP link layer
|
||||
* CTS 4.2.1.1 regression introduced by CTS specs requirement update.
|
||||
*/
|
||||
dc_link_aux_try_to_configure_timeout(link->ddc,
|
||||
LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD);
|
||||
|
||||
status = dp_retrieve_lttpr_cap(link);
|
||||
|
||||
if (status != DC_OK) {
|
||||
status = wake_up_aux_channel(link);
|
||||
if (status == DC_OK)
|
||||
dp_retrieve_lttpr_cap(link);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dp_is_lttpr_present(link))
|
||||
configure_lttpr_mode_transparent(link);
|
||||
|
||||
/* Read DP tunneling information. */
|
||||
|
@ -5406,7 +5338,7 @@ static bool retrieve_link_cap(struct dc_link *link)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!is_lttpr_present)
|
||||
if (!dp_is_lttpr_present(link))
|
||||
dc_link_aux_try_to_configure_timeout(link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD);
|
||||
|
||||
{
|
||||
|
@ -7339,19 +7271,7 @@ void dp_retrain_link_dp_test(struct dc_link *link,
|
|||
link->dc->hwss.unblank_stream(&pipes[i],
|
||||
link_setting);
|
||||
|
||||
if (pipes[i].stream_res.audio) {
|
||||
/* notify audio driver for
|
||||
* audio modes of monitor */
|
||||
pipes[i].stream_res.audio->funcs->az_enable(
|
||||
pipes[i].stream_res.audio);
|
||||
|
||||
/* un-mute audio */
|
||||
/* TODO: audio should be per stream rather than
|
||||
* per link */
|
||||
pipes[i].stream_res.stream_enc->funcs->
|
||||
audio_mute_control(
|
||||
pipes[i].stream_res.stream_enc, false);
|
||||
}
|
||||
link->dc->hwss.enable_audio_stream(&pipes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1768,6 +1768,17 @@ bool dc_remove_plane_from_context(
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* dc_rem_all_planes_for_stream - Remove planes attached to the target stream.
|
||||
*
|
||||
* @dc: Current dc state.
|
||||
* @stream: Target stream, which we want to remove the attached plans.
|
||||
* @context: New context.
|
||||
*
|
||||
* Return:
|
||||
* Return true if DC was able to remove all planes from the target
|
||||
* stream, otherwise, return false.
|
||||
*/
|
||||
bool dc_rem_all_planes_for_stream(
|
||||
const struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
|
@ -2562,9 +2573,12 @@ enum dc_status resource_map_pool_resources(
|
|||
|
||||
/**
|
||||
* dc_resource_state_copy_construct_current() - Creates a new dc_state from existing state
|
||||
* Is a shallow copy. Increments refcounts on existing streams and planes.
|
||||
*
|
||||
* @dc: copy out of dc->current_state
|
||||
* @dst_ctx: copy into this
|
||||
*
|
||||
* This function makes a shallow copy of the current DC state and increments
|
||||
* refcounts on existing streams and planes.
|
||||
*/
|
||||
void dc_resource_state_copy_construct_current(
|
||||
const struct dc *dc,
|
||||
|
@ -2593,15 +2607,241 @@ bool dc_resource_is_dsc_encoding_supported(const struct dc *dc)
|
|||
return dc->res_pool->res_cap->num_dsc > 0;
|
||||
}
|
||||
|
||||
static bool planes_changed_for_existing_stream(struct dc_state *context,
|
||||
struct dc_stream_state *stream,
|
||||
const struct dc_validation_set set[],
|
||||
int set_count)
|
||||
{
|
||||
int i, j;
|
||||
struct dc_stream_status *stream_status = NULL;
|
||||
|
||||
for (i = 0; i < context->stream_count; i++) {
|
||||
if (context->streams[i] == stream) {
|
||||
stream_status = &context->stream_status[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream_status)
|
||||
ASSERT(0);
|
||||
|
||||
for (i = 0; i < set_count; i++)
|
||||
if (set[i].stream == stream)
|
||||
break;
|
||||
|
||||
if (i == set_count)
|
||||
ASSERT(0);
|
||||
|
||||
if (set[i].plane_count != stream_status->plane_count)
|
||||
return true;
|
||||
|
||||
for (j = 0; j < set[i].plane_count; j++)
|
||||
if (set[i].plane_states[j] != stream_status->plane_states[j])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* dc_validate_global_state() - Determine if HW can support a given state
|
||||
* Checks HW resource availability and bandwidth requirement.
|
||||
* dc_validate_with_context - Validate and update the potential new stream in the context object
|
||||
*
|
||||
* @dc: Used to get the current state status
|
||||
* @set: An array of dc_validation_set with all the current streams reference
|
||||
* @set_count: Total of streams
|
||||
* @context: New context
|
||||
* @fast_validate: Enable or disable fast validation
|
||||
*
|
||||
* This function updates the potential new stream in the context object. It
|
||||
* creates multiple lists for the add, remove, and unchanged streams. In
|
||||
* particular, if the unchanged streams have a plane that changed, it is
|
||||
* necessary to remove all planes from the unchanged streams. In summary, this
|
||||
* function is responsible for validating the new context.
|
||||
*
|
||||
* Return:
|
||||
* In case of success, return DC_OK (1), otherwise, return a DC error.
|
||||
*/
|
||||
enum dc_status dc_validate_with_context(struct dc *dc,
|
||||
const struct dc_validation_set set[],
|
||||
int set_count,
|
||||
struct dc_state *context,
|
||||
bool fast_validate)
|
||||
{
|
||||
struct dc_stream_state *unchanged_streams[MAX_PIPES] = { 0 };
|
||||
struct dc_stream_state *del_streams[MAX_PIPES] = { 0 };
|
||||
struct dc_stream_state *add_streams[MAX_PIPES] = { 0 };
|
||||
int old_stream_count = context->stream_count;
|
||||
enum dc_status res = DC_ERROR_UNEXPECTED;
|
||||
int unchanged_streams_count = 0;
|
||||
int del_streams_count = 0;
|
||||
int add_streams_count = 0;
|
||||
bool found = false;
|
||||
int i, j, k;
|
||||
|
||||
DC_LOGGER_INIT(dc->ctx->logger);
|
||||
|
||||
/* First build a list of streams to be remove from current context */
|
||||
for (i = 0; i < old_stream_count; i++) {
|
||||
struct dc_stream_state *stream = context->streams[i];
|
||||
|
||||
for (j = 0; j < set_count; j++) {
|
||||
if (stream == set[j].stream) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
del_streams[del_streams_count++] = stream;
|
||||
|
||||
found = false;
|
||||
}
|
||||
|
||||
/* Second, build a list of new streams */
|
||||
for (i = 0; i < set_count; i++) {
|
||||
struct dc_stream_state *stream = set[i].stream;
|
||||
|
||||
for (j = 0; j < old_stream_count; j++) {
|
||||
if (stream == context->streams[j]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
add_streams[add_streams_count++] = stream;
|
||||
|
||||
found = false;
|
||||
}
|
||||
|
||||
/* Build a list of unchanged streams which is necessary for handling
|
||||
* planes change such as added, removed, and updated.
|
||||
*/
|
||||
for (i = 0; i < set_count; i++) {
|
||||
/* Check if stream is part of the delete list */
|
||||
for (j = 0; j < del_streams_count; j++) {
|
||||
if (set[i].stream == del_streams[j]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
/* Check if stream is part of the add list */
|
||||
for (j = 0; j < add_streams_count; j++) {
|
||||
if (set[i].stream == add_streams[j]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
unchanged_streams[unchanged_streams_count++] = set[i].stream;
|
||||
|
||||
found = false;
|
||||
}
|
||||
|
||||
/* Remove all planes for unchanged streams if planes changed */
|
||||
for (i = 0; i < unchanged_streams_count; i++) {
|
||||
if (planes_changed_for_existing_stream(context,
|
||||
unchanged_streams[i],
|
||||
set,
|
||||
set_count)) {
|
||||
if (!dc_rem_all_planes_for_stream(dc,
|
||||
unchanged_streams[i],
|
||||
context)) {
|
||||
res = DC_FAIL_DETACH_SURFACES;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove all planes for removed streams and then remove the streams */
|
||||
for (i = 0; i < del_streams_count; i++) {
|
||||
/* Need to cpy the dwb data from the old stream in order to efc to work */
|
||||
if (del_streams[i]->num_wb_info > 0) {
|
||||
for (j = 0; j < add_streams_count; j++) {
|
||||
if (del_streams[i]->sink == add_streams[j]->sink) {
|
||||
add_streams[j]->num_wb_info = del_streams[i]->num_wb_info;
|
||||
for (k = 0; k < del_streams[i]->num_wb_info; k++)
|
||||
add_streams[j]->writeback_info[k] = del_streams[i]->writeback_info[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dc_rem_all_planes_for_stream(dc, del_streams[i], context)) {
|
||||
res = DC_FAIL_DETACH_SURFACES;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
res = dc_remove_stream_from_ctx(dc, context, del_streams[i]);
|
||||
if (res != DC_OK)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Swap seamless boot stream to pipe 0 (if needed) to ensure pipe_ctx
|
||||
* matches. This may change in the future if seamless_boot_stream can be
|
||||
* multiple.
|
||||
*/
|
||||
for (i = 0; i < add_streams_count; i++) {
|
||||
mark_seamless_boot_stream(dc, add_streams[i]);
|
||||
if (add_streams[i]->apply_seamless_boot_optimization && i != 0) {
|
||||
struct dc_stream_state *temp = add_streams[0];
|
||||
|
||||
add_streams[0] = add_streams[i];
|
||||
add_streams[i] = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add new streams and then add all planes for the new stream */
|
||||
for (i = 0; i < add_streams_count; i++) {
|
||||
calculate_phy_pix_clks(add_streams[i]);
|
||||
res = dc_add_stream_to_ctx(dc, context, add_streams[i]);
|
||||
if (res != DC_OK)
|
||||
goto fail;
|
||||
|
||||
if (!add_all_planes_for_stream(dc, add_streams[i], set, set_count, context)) {
|
||||
res = DC_FAIL_ATTACH_SURFACES;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add all planes for unchanged streams if planes changed */
|
||||
for (i = 0; i < unchanged_streams_count; i++) {
|
||||
if (planes_changed_for_existing_stream(context,
|
||||
unchanged_streams[i],
|
||||
set,
|
||||
set_count)) {
|
||||
if (!add_all_planes_for_stream(dc, unchanged_streams[i], set, set_count, context)) {
|
||||
res = DC_FAIL_ATTACH_SURFACES;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res = dc_validate_global_state(dc, context, fast_validate);
|
||||
|
||||
fail:
|
||||
if (res != DC_OK)
|
||||
DC_LOG_WARNING("%s:resource validation failed, dc_status:%d\n",
|
||||
__func__,
|
||||
res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* dc_validate_global_state() - Determine if hardware can support a given state
|
||||
*
|
||||
* @dc: dc struct for this driver
|
||||
* @new_ctx: state to be validated
|
||||
* @fast_validate: set to true if only yes/no to support matters
|
||||
*
|
||||
* Return: DC_OK if the result can be programmed. Otherwise, an error code.
|
||||
* Checks hardware resource availability and bandwidth requirement.
|
||||
*
|
||||
* Return:
|
||||
* DC_OK if the result can be programmed. Otherwise, an error code.
|
||||
*/
|
||||
enum dc_status dc_validate_global_state(
|
||||
struct dc *dc,
|
||||
|
@ -2789,6 +3029,12 @@ static void set_avi_info_frame(
|
|||
hdmi_info.bits.C0_C1 = COLORIMETRY_EXTENDED;
|
||||
}
|
||||
|
||||
if (pixel_encoding && color_space == COLOR_SPACE_2020_YCBCR &&
|
||||
stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) {
|
||||
hdmi_info.bits.EC0_EC2 = 0;
|
||||
hdmi_info.bits.C0_C1 = COLORIMETRY_ITU709;
|
||||
}
|
||||
|
||||
/* TODO: un-hardcode aspect ratio */
|
||||
aspect = stream->timing.aspect_ratio;
|
||||
|
||||
|
@ -3734,4 +3980,4 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm(
|
|||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ struct aux_payload;
|
|||
struct set_config_cmd_payload;
|
||||
struct dmub_notification;
|
||||
|
||||
#define DC_VER "3.2.207"
|
||||
#define DC_VER "3.2.210"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
|
@ -56,9 +56,7 @@ struct dmub_notification;
|
|||
#define MIN_VIEWPORT_SIZE 12
|
||||
#define MAX_NUM_EDP 2
|
||||
|
||||
/*******************************************************************************
|
||||
* Display Core Interfaces
|
||||
******************************************************************************/
|
||||
/* Display Core Interfaces */
|
||||
struct dc_versions {
|
||||
const char *dc_ver;
|
||||
struct dmcu_version dmcu_version;
|
||||
|
@ -395,6 +393,7 @@ struct dc_config {
|
|||
bool disable_dmcu;
|
||||
bool enable_4to1MPC;
|
||||
bool enable_windowed_mpo_odm;
|
||||
bool forceHBR2CP2520; // Used for switching between test patterns TPS4 and CP2520
|
||||
uint32_t allow_edp_hotplug_detection;
|
||||
bool clamp_min_dcfclk;
|
||||
uint64_t vblank_alignment_dto_params;
|
||||
|
@ -494,9 +493,12 @@ enum dcn_zstate_support_state {
|
|||
DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY,
|
||||
DCN_ZSTATE_SUPPORT_DISALLOW,
|
||||
};
|
||||
/*
|
||||
* For any clocks that may differ per pipe
|
||||
* only the max is stored in this structure
|
||||
|
||||
/**
|
||||
* dc_clocks - DC pipe clocks
|
||||
*
|
||||
* For any clocks that may differ per pipe only the max is stored in this
|
||||
* structure
|
||||
*/
|
||||
struct dc_clocks {
|
||||
int dispclk_khz;
|
||||
|
@ -523,6 +525,16 @@ struct dc_clocks {
|
|||
bool prev_p_state_change_support;
|
||||
bool fclk_prev_p_state_change_support;
|
||||
int num_ways;
|
||||
|
||||
/**
|
||||
* @fw_based_mclk_switching
|
||||
*
|
||||
* DC has a mechanism that leverage the variable refresh rate to switch
|
||||
* memory clock in cases that we have a large latency to achieve the
|
||||
* memory clock change and a short vblank window. DC has some
|
||||
* requirements to enable this feature, and this field describes if the
|
||||
* system support or not such a feature.
|
||||
*/
|
||||
bool fw_based_mclk_switching;
|
||||
bool fw_based_mclk_switching_shut_down;
|
||||
int prev_num_ways;
|
||||
|
@ -764,7 +776,6 @@ struct dc_debug_options {
|
|||
bool disable_mem_low_power;
|
||||
bool pstate_enabled;
|
||||
bool disable_dmcu;
|
||||
bool disable_psr;
|
||||
bool force_abm_enable;
|
||||
bool disable_stereo_support;
|
||||
bool vsr_support;
|
||||
|
@ -852,6 +863,7 @@ struct dc_debug_options {
|
|||
bool enable_double_buffered_dsc_pg_support;
|
||||
bool enable_dp_dig_pixel_rate_div_policy;
|
||||
enum lttpr_mode lttpr_mode_override;
|
||||
unsigned int dsc_delay_factor_wa_x1000;
|
||||
};
|
||||
|
||||
struct gpu_info_soc_bounding_box_v1_0;
|
||||
|
@ -988,9 +1000,7 @@ void dc_init_callbacks(struct dc *dc,
|
|||
void dc_deinit_callbacks(struct dc *dc);
|
||||
void dc_destroy(struct dc **dc);
|
||||
|
||||
/*******************************************************************************
|
||||
* Surface Interfaces
|
||||
******************************************************************************/
|
||||
/* Surface Interfaces */
|
||||
|
||||
enum {
|
||||
TRANSFER_FUNC_POINTS = 1025
|
||||
|
@ -1269,12 +1279,23 @@ void dc_post_update_surfaces_to_stream(
|
|||
|
||||
#include "dc_stream.h"
|
||||
|
||||
/*
|
||||
* Structure to store surface/stream associations for validation
|
||||
/**
|
||||
* struct dc_validation_set - Struct to store surface/stream associations for validation
|
||||
*/
|
||||
struct dc_validation_set {
|
||||
/**
|
||||
* @stream: Stream state properties
|
||||
*/
|
||||
struct dc_stream_state *stream;
|
||||
|
||||
/**
|
||||
* @plane_state: Surface state
|
||||
*/
|
||||
struct dc_plane_state *plane_states[MAX_SURFACES];
|
||||
|
||||
/**
|
||||
* @plane_count: Total of active planes
|
||||
*/
|
||||
uint8_t plane_count;
|
||||
};
|
||||
|
||||
|
@ -1286,6 +1307,12 @@ enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *pla
|
|||
|
||||
void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info);
|
||||
|
||||
enum dc_status dc_validate_with_context(struct dc *dc,
|
||||
const struct dc_validation_set set[],
|
||||
int set_count,
|
||||
struct dc_state *context,
|
||||
bool fast_validate);
|
||||
|
||||
bool dc_set_generic_gpio_for_stereo(bool enable,
|
||||
struct gpio_service *gpio_service);
|
||||
|
||||
|
@ -1321,15 +1348,12 @@ 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
|
||||
* The streams parameter is an absolute set of all active streams.
|
||||
*
|
||||
* After this call:
|
||||
* Phy, Encoder, Timing Generator are programmed and enabled.
|
||||
* New streams are enabled with blank stream; no memory read.
|
||||
*/
|
||||
enum dc_status dc_commit_streams(struct dc *dc,
|
||||
struct dc_stream_state *streams[],
|
||||
uint8_t stream_count);
|
||||
|
||||
/* TODO: When the transition to the new commit sequence is done, remove this
|
||||
* function in favor of dc_commit_streams. */
|
||||
bool dc_commit_state(struct dc *dc, struct dc_state *context);
|
||||
|
||||
struct dc_state *dc_create_state(struct dc *dc);
|
||||
|
@ -1337,9 +1361,7 @@ struct dc_state *dc_copy_state(struct dc_state *src_ctx);
|
|||
void dc_retain_state(struct dc_state *context);
|
||||
void dc_release_state(struct dc_state *context);
|
||||
|
||||
/*******************************************************************************
|
||||
* Link Interfaces
|
||||
******************************************************************************/
|
||||
/* Link Interfaces */
|
||||
|
||||
struct dpcd_caps {
|
||||
union dpcd_rev dpcd_rev;
|
||||
|
@ -1441,9 +1463,7 @@ struct hdcp_caps {
|
|||
|
||||
uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane);
|
||||
|
||||
/*******************************************************************************
|
||||
* Sink Interfaces - A sink corresponds to a display output device
|
||||
******************************************************************************/
|
||||
/* Sink Interfaces - A sink corresponds to a display output device */
|
||||
|
||||
struct dc_container_id {
|
||||
// 128bit GUID in binary form
|
||||
|
@ -1526,9 +1546,7 @@ struct dc_cursor {
|
|||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Interrupt interfaces
|
||||
******************************************************************************/
|
||||
/* Interrupt interfaces */
|
||||
enum dc_irq_source dc_interrupt_to_irq_source(
|
||||
struct dc *dc,
|
||||
uint32_t src_id,
|
||||
|
@ -1540,9 +1558,7 @@ enum dc_irq_source dc_get_hpd_irq_source_at_index(
|
|||
|
||||
void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bool enable);
|
||||
|
||||
/*******************************************************************************
|
||||
* Power Interfaces
|
||||
******************************************************************************/
|
||||
/* Power Interfaces */
|
||||
|
||||
void dc_set_power_state(
|
||||
struct dc *dc,
|
||||
|
@ -1615,14 +1631,10 @@ enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc,
|
|||
void dc_process_dmub_dpia_hpd_int_enable(const struct dc *dc,
|
||||
uint32_t hpd_int_enable);
|
||||
|
||||
/*******************************************************************************
|
||||
* DSC Interfaces
|
||||
******************************************************************************/
|
||||
/* DSC Interfaces */
|
||||
#include "dc_dsc.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Disable acc mode Interfaces
|
||||
******************************************************************************/
|
||||
/* Disable acc mode Interfaces */
|
||||
void dc_disable_accelerated_mode(struct dc *dc);
|
||||
|
||||
#endif /* DC_INTERFACE_H_ */
|
||||
|
|
|
@ -423,25 +423,20 @@ void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc *dc, struct pipe_ctx *pi
|
|||
|
||||
#ifdef CONFIG_DRM_AMD_DC_DCN
|
||||
/**
|
||||
* ***********************************************************************************************
|
||||
* populate_subvp_cmd_drr_info: Helper to populate DRR pipe info for the DMCUB subvp command
|
||||
* populate_subvp_cmd_drr_info - Helper to populate DRR pipe info for the DMCUB subvp command
|
||||
*
|
||||
* Populate the DMCUB SubVP command with DRR pipe info. All the information required for calculating
|
||||
* the SubVP + DRR microschedule is populated here.
|
||||
* @dc: [in] current dc state
|
||||
* @subvp_pipe: [in] pipe_ctx for the SubVP pipe
|
||||
* @vblank_pipe: [in] pipe_ctx for the DRR pipe
|
||||
* @pipe_data: [in] Pipe data which stores the VBLANK/DRR info
|
||||
*
|
||||
* Populate the DMCUB SubVP command with DRR pipe info. All the information
|
||||
* required for calculating the SubVP + DRR microschedule is populated here.
|
||||
*
|
||||
* High level algorithm:
|
||||
* 1. Get timing for SubVP pipe, phantom pipe, and DRR pipe
|
||||
* 2. Calculate the min and max vtotal which supports SubVP + DRR microschedule
|
||||
* 3. Populate the drr_info with the min and max supported vtotal values
|
||||
*
|
||||
* @param [in] dc: current dc state
|
||||
* @param [in] subvp_pipe: pipe_ctx for the SubVP pipe
|
||||
* @param [in] vblank_pipe: pipe_ctx for the DRR pipe
|
||||
* @param [in] pipe_data: Pipe data which stores the VBLANK/DRR info
|
||||
*
|
||||
* @return: void
|
||||
*
|
||||
* ***********************************************************************************************
|
||||
*/
|
||||
static void populate_subvp_cmd_drr_info(struct dc *dc,
|
||||
struct pipe_ctx *subvp_pipe,
|
||||
|
@ -493,22 +488,18 @@ static void populate_subvp_cmd_drr_info(struct dc *dc,
|
|||
}
|
||||
|
||||
/**
|
||||
* ***********************************************************************************************
|
||||
* populate_subvp_cmd_vblank_pipe_info: Helper to populate VBLANK pipe info for the DMUB subvp command
|
||||
* populate_subvp_cmd_vblank_pipe_info - Helper to populate VBLANK pipe info for the DMUB subvp command
|
||||
*
|
||||
* Populate the DMCUB SubVP command with VBLANK pipe info. All the information required to calculate
|
||||
* the microschedule for SubVP + VBLANK case is stored in the pipe_data (subvp_data and vblank_data).
|
||||
* Also check if the VBLANK pipe is a DRR display -- if it is make a call to populate drr_info.
|
||||
* @dc: [in] current dc state
|
||||
* @context: [in] new dc state
|
||||
* @cmd: [in] DMUB cmd to be populated with SubVP info
|
||||
* @vblank_pipe: [in] pipe_ctx for the VBLANK pipe
|
||||
* @cmd_pipe_index: [in] index for the pipe array in DMCUB SubVP cmd
|
||||
*
|
||||
* @param [in] dc: current dc state
|
||||
* @param [in] context: new dc state
|
||||
* @param [in] cmd: DMUB cmd to be populated with SubVP info
|
||||
* @param [in] vblank_pipe: pipe_ctx for the VBLANK pipe
|
||||
* @param [in] cmd_pipe_index: index for the pipe array in DMCUB SubVP cmd
|
||||
*
|
||||
* @return: void
|
||||
*
|
||||
* ***********************************************************************************************
|
||||
* Populate the DMCUB SubVP command with VBLANK pipe info. All the information
|
||||
* required to calculate the microschedule for SubVP + VBLANK case is stored in
|
||||
* the pipe_data (subvp_data and vblank_data). Also check if the VBLANK pipe
|
||||
* is a DRR display -- if it is make a call to populate drr_info.
|
||||
*/
|
||||
static void populate_subvp_cmd_vblank_pipe_info(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
|
@ -551,22 +542,18 @@ static void populate_subvp_cmd_vblank_pipe_info(struct dc *dc,
|
|||
}
|
||||
|
||||
/**
|
||||
* ***********************************************************************************************
|
||||
* update_subvp_prefetch_end_to_mall_start: Helper for SubVP + SubVP case
|
||||
* update_subvp_prefetch_end_to_mall_start - Helper for SubVP + SubVP case
|
||||
*
|
||||
* For SubVP + SubVP, we use a single vertical interrupt to start the microschedule for both
|
||||
* SubVP pipes. In order for this to work correctly, the MALL REGION of both SubVP pipes must
|
||||
* start at the same time. This function lengthens the prefetch end to mall start delay of the
|
||||
* SubVP pipe that has the shorter prefetch so that both MALL REGION's will start at the same time.
|
||||
* @dc: [in] current dc state
|
||||
* @context: [in] new dc state
|
||||
* @cmd: [in] DMUB cmd to be populated with SubVP info
|
||||
* @subvp_pipes: [in] Array of SubVP pipes (should always be length 2)
|
||||
*
|
||||
* @param [in] dc: current dc state
|
||||
* @param [in] context: new dc state
|
||||
* @param [in] cmd: DMUB cmd to be populated with SubVP info
|
||||
* @param [in] subvp_pipes: Array of SubVP pipes (should always be length 2)
|
||||
*
|
||||
* @return: void
|
||||
*
|
||||
* ***********************************************************************************************
|
||||
* For SubVP + SubVP, we use a single vertical interrupt to start the
|
||||
* microschedule for both SubVP pipes. In order for this to work correctly, the
|
||||
* MALL REGION of both SubVP pipes must start at the same time. This function
|
||||
* lengthens the prefetch end to mall start delay of the SubVP pipe that has
|
||||
* the shorter prefetch so that both MALL REGION's will start at the same time.
|
||||
*/
|
||||
static void update_subvp_prefetch_end_to_mall_start(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
|
@ -608,22 +595,17 @@ static void update_subvp_prefetch_end_to_mall_start(struct dc *dc,
|
|||
}
|
||||
|
||||
/**
|
||||
* ***************************************************************************************
|
||||
* setup_subvp_dmub_command: Helper to populate the SubVP pipe info for the DMUB subvp command
|
||||
* populate_subvp_cmd_pipe_info - Helper to populate the SubVP pipe info for the DMUB subvp command
|
||||
*
|
||||
* Populate the DMCUB SubVP command with SubVP pipe info. All the information required to
|
||||
* calculate the microschedule for the SubVP pipe is stored in the pipe_data of the DMCUB
|
||||
* SubVP command.
|
||||
* @dc: [in] current dc state
|
||||
* @context: [in] new dc state
|
||||
* @cmd: [in] DMUB cmd to be populated with SubVP info
|
||||
* @subvp_pipe: [in] pipe_ctx for the SubVP pipe
|
||||
* @cmd_pipe_index: [in] index for the pipe array in DMCUB SubVP cmd
|
||||
*
|
||||
* @param [in] dc: current dc state
|
||||
* @param [in] context: new dc state
|
||||
* @param [in] cmd: DMUB cmd to be populated with SubVP info
|
||||
* @param [in] subvp_pipe: pipe_ctx for the SubVP pipe
|
||||
* @param [in] cmd_pipe_index: index for the pipe array in DMCUB SubVP cmd
|
||||
*
|
||||
* @return: void
|
||||
*
|
||||
* ***************************************************************************************
|
||||
* Populate the DMCUB SubVP command with SubVP pipe info. All the information
|
||||
* required to calculate the microschedule for the SubVP pipe is stored in the
|
||||
* pipe_data of the DMCUB SubVP command.
|
||||
*/
|
||||
static void populate_subvp_cmd_pipe_info(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
|
@ -703,19 +685,14 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
|
|||
}
|
||||
|
||||
/**
|
||||
* ***************************************************************************************
|
||||
* dc_dmub_setup_subvp_dmub_command: Populate the DMCUB SubVP command
|
||||
* dc_dmub_setup_subvp_dmub_command - Populate the DMCUB SubVP command
|
||||
*
|
||||
* This function loops through each pipe and populates the DMUB
|
||||
* SubVP CMD info based on the pipe (e.g. SubVP, VBLANK).
|
||||
* @dc: [in] current dc state
|
||||
* @context: [in] new dc state
|
||||
* @cmd: [in] DMUB cmd to be populated with SubVP info
|
||||
*
|
||||
* @param [in] dc: current dc state
|
||||
* @param [in] context: new dc state
|
||||
* @param [in] cmd: DMUB cmd to be populated with SubVP info
|
||||
*
|
||||
* @return: void
|
||||
*
|
||||
* ***************************************************************************************
|
||||
* This function loops through each pipe and populates the DMUB SubVP CMD info
|
||||
* based on the pipe (e.g. SubVP, VBLANK).
|
||||
*/
|
||||
void dc_dmub_setup_subvp_dmub_command(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
|
@ -962,19 +939,14 @@ static void dc_build_cursor_attribute_update_payload1(
|
|||
}
|
||||
|
||||
/**
|
||||
* ***************************************************************************************
|
||||
* dc_send_update_cursor_info_to_dmu: Populate the DMCUB Cursor update info command
|
||||
* dc_send_update_cursor_info_to_dmu - Populate the DMCUB Cursor update info command
|
||||
*
|
||||
* This function would store the cursor related information and pass it into dmub
|
||||
* @pCtx: [in] pipe context
|
||||
* @pipe_idx: [in] pipe index
|
||||
*
|
||||
* @param [in] pCtx: pipe context
|
||||
* @param [in] pipe_idx: pipe index
|
||||
*
|
||||
* @return: void
|
||||
*
|
||||
* ***************************************************************************************
|
||||
* This function would store the cursor related information and pass it into
|
||||
* dmub
|
||||
*/
|
||||
|
||||
void dc_send_update_cursor_info_to_dmu(
|
||||
struct pipe_ctx *pCtx, uint8_t pipe_idx)
|
||||
{
|
||||
|
|
|
@ -117,7 +117,7 @@ struct psr_settings {
|
|||
* Add a struct dc_panel_config under dc_link
|
||||
*/
|
||||
struct dc_panel_config {
|
||||
// extra panel power sequence parameters
|
||||
/* extra panel power sequence parameters */
|
||||
struct pps {
|
||||
unsigned int extra_t3_ms;
|
||||
unsigned int extra_t7_ms;
|
||||
|
@ -127,13 +127,21 @@ struct dc_panel_config {
|
|||
unsigned int extra_t12_ms;
|
||||
unsigned int extra_post_OUI_ms;
|
||||
} pps;
|
||||
// ABM
|
||||
/* PSR */
|
||||
struct psr {
|
||||
bool disable_psr;
|
||||
bool disallow_psrsu;
|
||||
bool rc_disable;
|
||||
bool rc_allow_static_screen;
|
||||
bool rc_allow_fullscreen_VPB;
|
||||
} psr;
|
||||
/* ABM */
|
||||
struct varib {
|
||||
unsigned int varibright_feature_enable;
|
||||
unsigned int def_varibright_level;
|
||||
unsigned int abm_config_setting;
|
||||
} varib;
|
||||
// edp DSC
|
||||
/* edp DSC */
|
||||
struct dsc {
|
||||
bool disable_dsc_edp;
|
||||
unsigned int force_dsc_edp_policy;
|
||||
|
@ -158,6 +166,14 @@ struct dc_link {
|
|||
enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse */
|
||||
bool is_hpd_filter_disabled;
|
||||
bool dp_ss_off;
|
||||
|
||||
/**
|
||||
* @link_state_valid:
|
||||
*
|
||||
* If there is no link and local sink, this variable should be set to
|
||||
* false. Otherwise, it should be set to true; usually, the function
|
||||
* core_link_enable_stream sets this field to true.
|
||||
*/
|
||||
bool link_state_valid;
|
||||
bool aux_access_disabled;
|
||||
bool sync_lt_in_progress;
|
||||
|
|
|
@ -41,6 +41,10 @@ struct timing_sync_info {
|
|||
struct dc_stream_status {
|
||||
int primary_otg_inst;
|
||||
int stream_enc_inst;
|
||||
|
||||
/**
|
||||
* @plane_count: Total of planes attached to a single stream
|
||||
*/
|
||||
int plane_count;
|
||||
int audio_inst;
|
||||
struct timing_sync_info timing_sync_info;
|
||||
|
@ -197,7 +201,18 @@ struct dc_stream_state {
|
|||
bool use_vsc_sdp_for_colorimetry;
|
||||
bool ignore_msa_timing_param;
|
||||
|
||||
/**
|
||||
* @allow_freesync:
|
||||
*
|
||||
* It say if Freesync is enabled or not.
|
||||
*/
|
||||
bool allow_freesync;
|
||||
|
||||
/**
|
||||
* @vrr_active_variable:
|
||||
*
|
||||
* It describes if VRR is in use.
|
||||
*/
|
||||
bool vrr_active_variable;
|
||||
bool freesync_on_desktop;
|
||||
|
||||
|
@ -517,10 +532,10 @@ bool dc_stream_get_crtc_position(struct dc *dc,
|
|||
unsigned int *nom_v_pos);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
bool dc_stream_forward_dmcu_crc_window(struct dc *dc, struct dc_stream_state *stream,
|
||||
struct crc_params *crc_window);
|
||||
bool dc_stream_stop_dmcu_crc_win_update(struct dc *dc,
|
||||
struct dc_stream_state *stream);
|
||||
bool dc_stream_forward_crc_window(struct dc *dc,
|
||||
struct rect *rect,
|
||||
struct dc_stream_state *stream,
|
||||
bool is_stop);
|
||||
#endif
|
||||
|
||||
bool dc_stream_configure_crc(struct dc *dc,
|
||||
|
|
|
@ -40,3 +40,5 @@
|
|||
|
||||
#define TRACE_DCN_FPU(begin, function, line, ref_count) \
|
||||
trace_dcn_fpu(begin, function, line, ref_count)
|
||||
#define TRACE_OPTC_LOCK_UNLOCK_STATE(optc, inst, lock) \
|
||||
trace_dcn_optc_lock_unlock_state(optc, inst, lock, __func__, __LINE__)
|
||||
|
|
|
@ -993,4 +993,11 @@ struct display_endpoint_id {
|
|||
enum display_endpoint_type ep_type;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
struct otg_phy_mux {
|
||||
uint8_t phy_output_num;
|
||||
uint8_t otg_output_num;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* DC_TYPES_H_ */
|
||||
|
|
|
@ -927,19 +927,20 @@ static bool dcn10_recv_edid_cea_ack(struct dmcu *dmcu, int *offset)
|
|||
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
static void dcn10_forward_crc_window(struct dmcu *dmcu,
|
||||
struct crc_region *crc_win,
|
||||
struct rect *rect,
|
||||
struct otg_phy_mux *mux_mapping)
|
||||
{
|
||||
struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
|
||||
unsigned int dmcu_max_retry_on_wait_reg_ready = 801;
|
||||
unsigned int dmcu_wait_reg_ready_interval = 100;
|
||||
unsigned int crc_start = 0, crc_end = 0, otg_phy_mux = 0;
|
||||
int x_start, y_start, x_end, y_end;
|
||||
|
||||
/* If microcontroller is not running, do nothing */
|
||||
if (dmcu->dmcu_state != DMCU_RUNNING)
|
||||
return;
|
||||
|
||||
if (!crc_win)
|
||||
if (!rect)
|
||||
return;
|
||||
|
||||
/* waitDMCUReadyForCmd */
|
||||
|
@ -947,9 +948,14 @@ static void dcn10_forward_crc_window(struct dmcu *dmcu,
|
|||
dmcu_wait_reg_ready_interval,
|
||||
dmcu_max_retry_on_wait_reg_ready);
|
||||
|
||||
x_start = rect->x;
|
||||
y_start = rect->y;
|
||||
x_end = x_start + rect->width;
|
||||
y_end = y_start + rect->height;
|
||||
|
||||
/* build up nitification data */
|
||||
crc_start = (((unsigned int) crc_win->x_start) << 16) | crc_win->y_start;
|
||||
crc_end = (((unsigned int) crc_win->x_end) << 16) | crc_win->y_end;
|
||||
crc_start = (((unsigned int) x_start) << 16) | y_start;
|
||||
crc_end = (((unsigned int) x_end) << 16) | y_end;
|
||||
otg_phy_mux =
|
||||
(((unsigned int) mux_mapping->otg_output_num) << 16) | mux_mapping->phy_output_num;
|
||||
|
||||
|
|
|
@ -399,7 +399,11 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
|
|||
link->psr_settings.force_ffu_mode = 0;
|
||||
copy_settings_data->force_ffu_mode = link->psr_settings.force_ffu_mode;
|
||||
|
||||
if (link->fec_state == dc_link_fec_enabled &&
|
||||
if (((link->dpcd_caps.fec_cap.bits.FEC_CAPABLE &&
|
||||
!link->dc->debug.disable_fec) &&
|
||||
(link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT &&
|
||||
!link->panel_config.dsc.disable_dsc_edp &&
|
||||
link->dc->caps.edp_dsc_support)) &&
|
||||
link->dpcd_caps.sink_dev_id == DP_DEVICE_ID_38EC11 &&
|
||||
(!memcmp(link->dpcd_caps.sink_dev_id_str, DP_SINK_DEVICE_STR_ID_1,
|
||||
sizeof(DP_SINK_DEVICE_STR_ID_1)) ||
|
||||
|
|
|
@ -688,16 +688,6 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
|
|||
early_control = lane_count;
|
||||
|
||||
tg->funcs->set_early_control(tg, early_control);
|
||||
|
||||
/* enable audio only within mode set */
|
||||
if (pipe_ctx->stream_res.audio != NULL) {
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
static enum bp_result link_transmitter_control(
|
||||
|
@ -1081,12 +1071,14 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx)
|
|||
struct dc *dc;
|
||||
struct clk_mgr *clk_mgr;
|
||||
unsigned int i, num_audio = 1;
|
||||
const struct link_hwss *link_hwss;
|
||||
|
||||
if (!pipe_ctx->stream)
|
||||
return;
|
||||
|
||||
dc = pipe_ctx->stream->ctx->dc;
|
||||
clk_mgr = dc->clk_mgr;
|
||||
link_hwss = get_link_hwss(pipe_ctx->stream->link, &pipe_ctx->link_res);
|
||||
|
||||
if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == true)
|
||||
return;
|
||||
|
@ -1103,56 +1095,35 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx)
|
|||
if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa)
|
||||
/*this is the first audio. apply the PME w/a in order to wake AZ from D3*/
|
||||
clk_mgr->funcs->enable_pme_wa(clk_mgr);
|
||||
/* un-mute audio */
|
||||
/* TODO: audio should be per stream rather than per link */
|
||||
if (is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->audio_mute_control(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc, false);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
|
||||
pipe_ctx->stream_res.stream_enc, false);
|
||||
|
||||
link_hwss->enable_audio_packet(pipe_ctx);
|
||||
|
||||
if (pipe_ctx->stream_res.audio)
|
||||
pipe_ctx->stream_res.audio->enabled = true;
|
||||
}
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
dp_source_sequence_trace(pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_ENABLE_AUDIO_STREAM);
|
||||
}
|
||||
|
||||
void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc *dc;
|
||||
struct clk_mgr *clk_mgr;
|
||||
const struct link_hwss *link_hwss;
|
||||
|
||||
if (!pipe_ctx || !pipe_ctx->stream)
|
||||
return;
|
||||
|
||||
dc = pipe_ctx->stream->ctx->dc;
|
||||
clk_mgr = dc->clk_mgr;
|
||||
link_hwss = get_link_hwss(pipe_ctx->stream->link, &pipe_ctx->link_res);
|
||||
|
||||
if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false)
|
||||
return;
|
||||
|
||||
if (is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->audio_mute_control(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc, true);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
|
||||
pipe_ctx->stream_res.stream_enc, true);
|
||||
link_hwss->disable_audio_packet(pipe_ctx);
|
||||
|
||||
if (pipe_ctx->stream_res.audio) {
|
||||
pipe_ctx->stream_res.audio->enabled = false;
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
if (is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_disable(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable(
|
||||
pipe_ctx->stream_res.stream_enc);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable(
|
||||
pipe_ctx->stream_res.stream_enc);
|
||||
|
||||
if (clk_mgr->funcs->enable_pme_wa)
|
||||
/*this is the first audio. apply the PME w/a in order to wake AZ from D3*/
|
||||
clk_mgr->funcs->enable_pme_wa(clk_mgr);
|
||||
|
@ -1163,9 +1134,6 @@ void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx)
|
|||
* stream->stream_engine_id);
|
||||
*/
|
||||
}
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
dp_source_sequence_trace(pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_DISABLE_AUDIO_STREAM);
|
||||
}
|
||||
|
||||
void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
|
||||
|
@ -1487,6 +1455,9 @@ static enum dc_status apply_single_controller_ctx_to_hw(
|
|||
unsigned int event_triggers = 0;
|
||||
struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe;
|
||||
struct dce_hwseq *hws = dc->hwseq;
|
||||
const struct link_hwss *link_hwss = get_link_hwss(
|
||||
link, &pipe_ctx->link_res);
|
||||
|
||||
|
||||
if (hws->funcs.disable_stream_gating) {
|
||||
hws->funcs.disable_stream_gating(dc, pipe_ctx);
|
||||
|
@ -1497,23 +1468,8 @@ static enum dc_status apply_single_controller_ctx_to_hw(
|
|||
|
||||
build_audio_output(context, pipe_ctx, &audio_output);
|
||||
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
if (is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_setup(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
pipe_ctx->stream_res.audio->inst,
|
||||
&pipe_ctx->stream->audio_info);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
pipe_ctx->stream_res.audio->inst,
|
||||
&pipe_ctx->stream->audio_info);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
pipe_ctx->stream_res.audio->inst,
|
||||
&pipe_ctx->stream->audio_info,
|
||||
&audio_output.crtc_info);
|
||||
link_hwss->setup_audio_output(pipe_ctx, &audio_output,
|
||||
pipe_ctx->stream_res.audio->inst);
|
||||
|
||||
pipe_ctx->stream_res.audio->funcs->az_configure(
|
||||
pipe_ctx->stream_res.audio,
|
||||
|
|
|
@ -1128,6 +1128,7 @@ struct resource_pool *dce60_create_resource_pool(
|
|||
if (dce60_construct(num_virtual_links, dc, pool))
|
||||
return &pool->base;
|
||||
|
||||
kfree(pool);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1325,6 +1326,7 @@ struct resource_pool *dce61_create_resource_pool(
|
|||
if (dce61_construct(num_virtual_links, dc, pool))
|
||||
return &pool->base;
|
||||
|
||||
kfree(pool);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1518,6 +1520,7 @@ struct resource_pool *dce64_create_resource_pool(
|
|||
if (dce64_construct(num_virtual_links, dc, pool))
|
||||
return &pool->base;
|
||||
|
||||
kfree(pool);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1137,6 +1137,7 @@ struct resource_pool *dce80_create_resource_pool(
|
|||
if (dce80_construct(num_virtual_links, dc, pool))
|
||||
return &pool->base;
|
||||
|
||||
kfree(pool);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1336,6 +1337,7 @@ struct resource_pool *dce81_create_resource_pool(
|
|||
if (dce81_construct(num_virtual_links, dc, pool))
|
||||
return &pool->base;
|
||||
|
||||
kfree(pool);
|
||||
BREAK_TO_DEBUGGER();
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "reg_helper.h"
|
||||
#include "dcn10_optc.h"
|
||||
#include "dc.h"
|
||||
#include "dc_trace.h"
|
||||
|
||||
#define REG(reg)\
|
||||
optc1->tg_regs->reg
|
||||
|
@ -657,6 +658,8 @@ void optc1_lock(struct timing_generator *optc)
|
|||
REG_WAIT(OTG_MASTER_UPDATE_LOCK,
|
||||
UPDATE_LOCK_STATUS, 1,
|
||||
1, 10);
|
||||
|
||||
TRACE_OPTC_LOCK_UNLOCK_STATE(optc1, optc->inst, true);
|
||||
}
|
||||
|
||||
void optc1_unlock(struct timing_generator *optc)
|
||||
|
@ -665,6 +668,8 @@ void optc1_unlock(struct timing_generator *optc)
|
|||
|
||||
REG_SET(OTG_MASTER_UPDATE_LOCK, 0,
|
||||
OTG_MASTER_UPDATE_LOCK, 0);
|
||||
|
||||
TRACE_OPTC_LOCK_UNLOCK_STATE(optc1, optc->inst, false);
|
||||
}
|
||||
|
||||
void optc1_get_position(struct timing_generator *optc,
|
||||
|
|
|
@ -1295,47 +1295,6 @@ static uint32_t read_pipe_fuses(struct dc_context *ctx)
|
|||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some architectures don't support soft-float (e.g. aarch64), on those
|
||||
* this function has to be called with hardfloat enabled, make sure not
|
||||
* to inline it so whatever fp stuff is done stays inside
|
||||
*/
|
||||
static noinline void dcn10_resource_construct_fp(
|
||||
struct dc *dc)
|
||||
{
|
||||
if (dc->ctx->dce_version == DCN_VERSION_1_01) {
|
||||
struct dcn_soc_bounding_box *dcn_soc = dc->dcn_soc;
|
||||
struct dcn_ip_params *dcn_ip = dc->dcn_ip;
|
||||
struct display_mode_lib *dml = &dc->dml;
|
||||
|
||||
dml->ip.max_num_dpp = 3;
|
||||
/* TODO how to handle 23.84? */
|
||||
dcn_soc->dram_clock_change_latency = 23;
|
||||
dcn_ip->max_num_dpp = 3;
|
||||
}
|
||||
if (ASICREV_IS_RV1_F0(dc->ctx->asic_id.hw_internal_rev)) {
|
||||
dc->dcn_soc->urgent_latency = 3;
|
||||
dc->debug.disable_dmcu = true;
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = 41.60f;
|
||||
}
|
||||
|
||||
|
||||
dc->dcn_soc->number_of_channels = dc->ctx->asic_id.vram_width / ddr4_dram_width;
|
||||
ASSERT(dc->dcn_soc->number_of_channels < 3);
|
||||
if (dc->dcn_soc->number_of_channels == 0)/*old sbios bug*/
|
||||
dc->dcn_soc->number_of_channels = 2;
|
||||
|
||||
if (dc->dcn_soc->number_of_channels == 1) {
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = 19.2f;
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 = 17.066f;
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 = 14.933f;
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 = 12.8f;
|
||||
if (ASICREV_IS_RV1_F0(dc->ctx->asic_id.hw_internal_rev)) {
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = 20.80f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool verify_clock_values(struct dm_pp_clock_levels_with_voltage *clks)
|
||||
{
|
||||
int i;
|
||||
|
@ -1510,8 +1469,9 @@ static bool dcn10_resource_construct(
|
|||
memcpy(dc->dcn_ip, &dcn10_ip_defaults, sizeof(dcn10_ip_defaults));
|
||||
memcpy(dc->dcn_soc, &dcn10_soc_defaults, sizeof(dcn10_soc_defaults));
|
||||
|
||||
/* Other architectures we build for build this with soft-float */
|
||||
DC_FP_START();
|
||||
dcn10_resource_construct_fp(dc);
|
||||
DC_FP_END();
|
||||
|
||||
if (!dc->config.is_vmin_only_asic)
|
||||
if (ASICREV_IS_RAVEN2(dc->ctx->asic_id.hw_internal_rev))
|
||||
|
|
|
@ -623,6 +623,10 @@ void hubp2_cursor_set_attributes(
|
|||
hubp->att.size.bits.width = attr->width;
|
||||
hubp->att.size.bits.height = attr->height;
|
||||
hubp->att.cur_ctl.bits.mode = attr->color_format;
|
||||
|
||||
hubp->cur_rect.w = attr->width;
|
||||
hubp->cur_rect.h = attr->height;
|
||||
|
||||
hubp->att.cur_ctl.bits.pitch = hw_pitch;
|
||||
hubp->att.cur_ctl.bits.line_per_chunk = lpc;
|
||||
hubp->att.cur_ctl.bits.cur_2x_magnify = attr->attribute_flags.bits.ENABLE_MAGNIFICATION;
|
||||
|
|
|
@ -1079,6 +1079,29 @@ void dcn20_blank_pixel_data(
|
|||
0);
|
||||
}
|
||||
|
||||
if (!blank && dc->debug.enable_single_display_2to1_odm_policy) {
|
||||
/* when exiting dynamic ODM need to reinit DPG state for unused pipes */
|
||||
struct pipe_ctx *old_odm_pipe = dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx].next_odm_pipe;
|
||||
|
||||
odm_pipe = pipe_ctx->next_odm_pipe;
|
||||
|
||||
while (old_odm_pipe) {
|
||||
if (!odm_pipe || old_odm_pipe->pipe_idx != odm_pipe->pipe_idx)
|
||||
dc->hwss.set_disp_pattern_generator(dc,
|
||||
old_odm_pipe,
|
||||
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
|
||||
CONTROLLER_DP_COLOR_SPACE_UDEFINED,
|
||||
COLOR_DEPTH_888,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
old_odm_pipe = old_odm_pipe->next_odm_pipe;
|
||||
if (odm_pipe)
|
||||
odm_pipe = odm_pipe->next_odm_pipe;
|
||||
}
|
||||
}
|
||||
|
||||
if (!blank)
|
||||
if (stream_res->abm) {
|
||||
dc->hwss.set_pipe(pipe_ctx);
|
||||
|
@ -1270,16 +1293,6 @@ void dcn20_pipe_control_lock(
|
|||
lock,
|
||||
&hw_locks,
|
||||
&inst_flags);
|
||||
} else if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
|
||||
union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 };
|
||||
hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK;
|
||||
hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER;
|
||||
hw_lock_cmd.bits.lock_pipe = 1;
|
||||
hw_lock_cmd.bits.otg_inst = pipe->stream_res.tg->inst;
|
||||
hw_lock_cmd.bits.lock = lock;
|
||||
if (!lock)
|
||||
hw_lock_cmd.bits.should_release = 1;
|
||||
dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd);
|
||||
} else if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {
|
||||
if (lock)
|
||||
pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
|
||||
|
@ -1650,10 +1663,7 @@ static void dcn20_program_pipe(
|
|||
pipe_ctx->pipe_dlg_param.vupdate_width);
|
||||
|
||||
if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) {
|
||||
pipe_ctx->stream_res.tg->funcs->wait_for_state(
|
||||
pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
|
||||
pipe_ctx->stream_res.tg->funcs->wait_for_state(
|
||||
pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
|
||||
pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
|
||||
}
|
||||
|
||||
pipe_ctx->stream_res.tg->funcs->set_vtg_params(
|
||||
|
@ -1856,7 +1866,7 @@ void dcn20_post_unlock_program_front_end(
|
|||
|
||||
for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS*1000
|
||||
&& hubp->funcs->hubp_is_flip_pending(hubp); j++)
|
||||
mdelay(1);
|
||||
udelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2611,14 +2621,6 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
|
|||
|
||||
if (dc->hwseq->funcs.set_pixels_per_cycle)
|
||||
dc->hwseq->funcs.set_pixels_per_cycle(pipe_ctx);
|
||||
|
||||
/* enable audio only within mode set */
|
||||
if (pipe_ctx->stream_res.audio != NULL) {
|
||||
if (is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.hpo_dp_stream_enc);
|
||||
else if (dc_is_dp_signal(pipe_ctx->stream->signal))
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc);
|
||||
}
|
||||
}
|
||||
|
||||
void dcn20_program_dmdata_engine(struct pipe_ctx *pipe_ctx)
|
||||
|
|
|
@ -1454,6 +1454,22 @@ enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* dcn20_split_stream_for_odm - Check if stream can be splited for ODM
|
||||
*
|
||||
* @dc: DC object with resource pool info required for pipe split
|
||||
* @res_ctx: Persistent state of resources
|
||||
* @prev_odm_pipe: Reference to the previous ODM pipe
|
||||
* @next_odm_pipe: Reference to the next ODM pipe
|
||||
*
|
||||
* This function takes a logically active pipe and a logically free pipe and
|
||||
* halves all the scaling parameters that need to be halved while populating
|
||||
* the free pipe with the required resources and configuring the next/previous
|
||||
* ODM pipe pointers.
|
||||
*
|
||||
* Return:
|
||||
* Return true if split stream for ODM is possible, otherwise, return false.
|
||||
*/
|
||||
bool dcn20_split_stream_for_odm(
|
||||
const struct dc *dc,
|
||||
struct resource_context *res_ctx,
|
||||
|
|
|
@ -671,12 +671,15 @@ static const struct dc_debug_options debug_defaults_diags = {
|
|||
.disable_pplib_wm_range = true,
|
||||
.disable_stutter = true,
|
||||
.disable_48mhz_pwrdwn = true,
|
||||
.disable_psr = true,
|
||||
.enable_tri_buf = true,
|
||||
.use_max_lb = true
|
||||
};
|
||||
|
||||
static const struct dc_panel_config panel_config_defaults = {
|
||||
.psr = {
|
||||
.disable_psr = false,
|
||||
.disallow_psrsu = false,
|
||||
},
|
||||
.ilr = {
|
||||
.optimize_edp_link_rate = true,
|
||||
},
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "dc_dmub_srv.h"
|
||||
|
||||
#include "dml/dcn30/dcn30_fpu.h"
|
||||
#include "dc_trace.h"
|
||||
|
||||
#define REG(reg)\
|
||||
optc1->tg_regs->reg
|
||||
|
@ -58,6 +59,8 @@ void optc3_triplebuffer_lock(struct timing_generator *optc)
|
|||
REG_WAIT(OTG_MASTER_UPDATE_LOCK,
|
||||
UPDATE_LOCK_STATUS, 1,
|
||||
1, 10);
|
||||
|
||||
TRACE_OPTC_LOCK_UNLOCK_STATE(optc1, optc->inst, true);
|
||||
}
|
||||
|
||||
void optc3_lock_doublebuffer_enable(struct timing_generator *optc)
|
||||
|
@ -93,6 +96,8 @@ void optc3_lock_doublebuffer_enable(struct timing_generator *optc)
|
|||
MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, 0,
|
||||
MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, 100,
|
||||
OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, 1);
|
||||
|
||||
TRACE_OPTC_LOCK_UNLOCK_STATE(optc1, optc->inst, true);
|
||||
}
|
||||
|
||||
void optc3_lock_doublebuffer_disable(struct timing_generator *optc)
|
||||
|
@ -108,6 +113,8 @@ void optc3_lock_doublebuffer_disable(struct timing_generator *optc)
|
|||
|
||||
REG_UPDATE(OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, 0);
|
||||
REG_UPDATE(OTG_GLOBAL_CONTROL0, MASTER_UPDATE_LOCK_DB_EN, 0);
|
||||
|
||||
TRACE_OPTC_LOCK_UNLOCK_STATE(optc1, optc->inst, true);
|
||||
}
|
||||
|
||||
void optc3_lock(struct timing_generator *optc)
|
||||
|
@ -122,6 +129,8 @@ void optc3_lock(struct timing_generator *optc)
|
|||
REG_WAIT(OTG_MASTER_UPDATE_LOCK,
|
||||
UPDATE_LOCK_STATUS, 1,
|
||||
1, 10);
|
||||
|
||||
TRACE_OPTC_LOCK_UNLOCK_STATE(optc1, optc->inst, true);
|
||||
}
|
||||
|
||||
void optc3_set_out_mux(struct timing_generator *optc, enum otg_out_mux_dest dest)
|
||||
|
|
|
@ -723,7 +723,6 @@ static const struct dc_debug_options debug_defaults_drv = {
|
|||
.underflow_assert_delay_us = 0xFFFFFFFF,
|
||||
.dwb_fi_phase = -1, // -1 = disable,
|
||||
.dmub_command_table = true,
|
||||
.disable_psr = false,
|
||||
.use_max_lb = true,
|
||||
.exit_idle_opt_for_cursor_updates = true
|
||||
};
|
||||
|
@ -742,11 +741,17 @@ static const struct dc_debug_options debug_defaults_diags = {
|
|||
.scl_reset_length10 = true,
|
||||
.dwb_fi_phase = -1, // -1 = disable
|
||||
.dmub_command_table = true,
|
||||
.disable_psr = true,
|
||||
.enable_tri_buf = true,
|
||||
.use_max_lb = true
|
||||
};
|
||||
|
||||
static const struct dc_panel_config panel_config_defaults = {
|
||||
.psr = {
|
||||
.disable_psr = false,
|
||||
.disallow_psrsu = false,
|
||||
},
|
||||
};
|
||||
|
||||
static void dcn30_dpp_destroy(struct dpp **dpp)
|
||||
{
|
||||
kfree(TO_DCN20_DPP(*dpp));
|
||||
|
@ -2212,6 +2217,11 @@ void dcn30_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params
|
|||
}
|
||||
}
|
||||
|
||||
static void dcn30_get_panel_config_defaults(struct dc_panel_config *panel_config)
|
||||
{
|
||||
*panel_config = panel_config_defaults;
|
||||
}
|
||||
|
||||
static const struct resource_funcs dcn30_res_pool_funcs = {
|
||||
.destroy = dcn30_destroy_resource_pool,
|
||||
.link_enc_create = dcn30_link_encoder_create,
|
||||
|
@ -2231,6 +2241,7 @@ static const struct resource_funcs dcn30_res_pool_funcs = {
|
|||
.release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,
|
||||
.update_bw_bounding_box = dcn30_update_bw_bounding_box,
|
||||
.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
|
||||
.get_panel_config_defaults = dcn30_get_panel_config_defaults,
|
||||
};
|
||||
|
||||
#define CTX ctx
|
||||
|
|
|
@ -112,10 +112,16 @@ static const struct dc_debug_options debug_defaults_diags = {
|
|||
.dwb_fi_phase = -1, // -1 = disable
|
||||
.dmub_command_table = true,
|
||||
.enable_tri_buf = true,
|
||||
.disable_psr = true,
|
||||
.use_max_lb = true
|
||||
};
|
||||
|
||||
static const struct dc_panel_config panel_config_defaults = {
|
||||
.psr = {
|
||||
.disable_psr = false,
|
||||
.disallow_psrsu = false,
|
||||
},
|
||||
};
|
||||
|
||||
enum dcn302_clk_src_array_id {
|
||||
DCN302_CLK_SRC_PLL0,
|
||||
DCN302_CLK_SRC_PLL1,
|
||||
|
@ -1132,6 +1138,11 @@ void dcn302_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
|
|||
DC_FP_END();
|
||||
}
|
||||
|
||||
static void dcn302_get_panel_config_defaults(struct dc_panel_config *panel_config)
|
||||
{
|
||||
*panel_config = panel_config_defaults;
|
||||
}
|
||||
|
||||
static struct resource_funcs dcn302_res_pool_funcs = {
|
||||
.destroy = dcn302_destroy_resource_pool,
|
||||
.link_enc_create = dcn302_link_encoder_create,
|
||||
|
@ -1151,6 +1162,7 @@ static struct resource_funcs dcn302_res_pool_funcs = {
|
|||
.release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,
|
||||
.update_bw_bounding_box = dcn302_update_bw_bounding_box,
|
||||
.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
|
||||
.get_panel_config_defaults = dcn302_get_panel_config_defaults,
|
||||
};
|
||||
|
||||
static struct dc_cap_funcs cap_funcs = {
|
||||
|
|
|
@ -96,7 +96,13 @@ static const struct dc_debug_options debug_defaults_diags = {
|
|||
.dwb_fi_phase = -1, // -1 = disable
|
||||
.dmub_command_table = true,
|
||||
.enable_tri_buf = true,
|
||||
.disable_psr = true,
|
||||
};
|
||||
|
||||
static const struct dc_panel_config panel_config_defaults = {
|
||||
.psr = {
|
||||
.disable_psr = false,
|
||||
.disallow_psrsu = false,
|
||||
},
|
||||
};
|
||||
|
||||
enum dcn303_clk_src_array_id {
|
||||
|
@ -1055,6 +1061,10 @@ static void dcn303_destroy_resource_pool(struct resource_pool **pool)
|
|||
*pool = NULL;
|
||||
}
|
||||
|
||||
static void dcn303_get_panel_config_defaults(struct dc_panel_config *panel_config)
|
||||
{
|
||||
*panel_config = panel_config_defaults;
|
||||
}
|
||||
|
||||
void dcn303_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
|
||||
{
|
||||
|
@ -1082,6 +1092,7 @@ static struct resource_funcs dcn303_res_pool_funcs = {
|
|||
.release_post_bldn_3dlut = dcn30_release_post_bldn_3dlut,
|
||||
.update_bw_bounding_box = dcn303_update_bw_bounding_box,
|
||||
.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
|
||||
.get_panel_config_defaults = dcn303_get_panel_config_defaults,
|
||||
};
|
||||
|
||||
static struct dc_cap_funcs cap_funcs = {
|
||||
|
|
|
@ -134,23 +134,10 @@ static void apg31_se_audio_setup(
|
|||
|
||||
/* Disable forced mem power off */
|
||||
REG_UPDATE(APG_MEM_PWR, APG_MEM_PWR_FORCE, 0);
|
||||
|
||||
apg31_enable(apg);
|
||||
}
|
||||
|
||||
static void apg31_audio_mute_control(
|
||||
struct apg *apg,
|
||||
bool mute)
|
||||
{
|
||||
if (mute)
|
||||
apg31_disable(apg);
|
||||
else
|
||||
apg31_enable(apg);
|
||||
}
|
||||
|
||||
static struct apg_funcs dcn31_apg_funcs = {
|
||||
.se_audio_setup = apg31_se_audio_setup,
|
||||
.audio_mute_control = apg31_audio_mute_control,
|
||||
.enable_apg = apg31_enable,
|
||||
.disable_apg = apg31_disable,
|
||||
};
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue