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:
Dave Airlie 2022-11-08 16:32:31 +10:00
commit 49e8e6343d
164 changed files with 3215 additions and 2377 deletions

View file

@ -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))

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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);

View file

@ -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 */

View file

@ -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 */

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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 = {

View file

@ -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:

View file

@ -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);

View file

@ -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;

View file

@ -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 = {

View file

@ -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 */

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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);
};
/*

View file

@ -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;

View file

@ -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,

View file

@ -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;

View file

@ -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);

View file

@ -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,

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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:

View file

@ -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,

View file

@ -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;

View file

@ -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;
}

View file

@ -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,
};

View file

@ -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

View file

@ -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,

View file

@ -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,
};

View file

@ -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

View file

@ -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);

View file

@ -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,

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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_ */

View file

@ -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,

View file

@ -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);

View file

@ -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);

View file

@ -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 =

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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:
*

View file

@ -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);
}
}

View file

@ -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)

View file

@ -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);
}

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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
};

View file

@ -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 = &params[i].aconnector->base;
memset(&params[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],
&params[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,
&params[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 = &param.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],
&param.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;

View file

@ -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

View file

@ -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

View file

@ -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
}

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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)
{

View file

@ -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;
}
}

View file

@ -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)

View file

@ -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]);
}
}
}

View file

@ -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;
}
}

View file

@ -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_ */

View file

@ -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)
{

View file

@ -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;

View file

@ -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,

View file

@ -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__)

View file

@ -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_ */

View file

@ -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;

View file

@ -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)) ||

View file

@ -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,

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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,

View file

@ -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))

View file

@ -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;

View file

@ -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)

View file

@ -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,

View file

@ -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,
},

View file

@ -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)

View file

@ -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

View file

@ -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 = {

View file

@ -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 = {

View file

@ -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