mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 23:52:08 +02:00
amd-drm-fixes-6.8-2024-01-18:
amdgpu: - DSC fixes - DC resource pool fixes - OTG fix - DML2 fixes - Aux fix - GFX10 RLC firmware handling fix - Revert a broken workaround for SMU 13.0.2 - DC writeback fix - Enable gfxoff when ROCm apps are active on gfx11 with the proper FW version amdkfd: - Fix dma-buf exports using GEM handles -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCZamliAAKCRC93/aFa7yZ 2LnkAP9N72FbCtH5VRbP+8RFVRRU6Bvn/o3VRJj8cdl0fBUtbQEAtTLxTx838ryP RMGvboRc9tZv8WJ7W9YbBWkCWwKGWQc= =oH8o -----END PGP SIGNATURE----- Merge tag 'amd-drm-fixes-6.8-2024-01-18' of https://gitlab.freedesktop.org/agd5f/linux into drm-next amd-drm-fixes-6.8-2024-01-18: amdgpu: - DSC fixes - DC resource pool fixes - OTG fix - DML2 fixes - Aux fix - GFX10 RLC firmware handling fix - Revert a broken workaround for SMU 13.0.2 - DC writeback fix - Enable gfxoff when ROCm apps are active on gfx11 with the proper FW version amdkfd: - Fix dma-buf exports using GEM handles Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240118223127.4904-1-alexander.deucher@amd.com
This commit is contained in:
commit
0a1123c7b9
|
|
@ -254,8 +254,6 @@ extern int amdgpu_agp;
|
|||
|
||||
extern int amdgpu_wbrf;
|
||||
|
||||
extern int fw_bo_location;
|
||||
|
||||
#define AMDGPU_VM_MAX_NUM_CTX 4096
|
||||
#define AMDGPU_SG_THRESHOLD (256*1024*1024)
|
||||
#define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000
|
||||
|
|
@ -1146,6 +1144,7 @@ struct amdgpu_device {
|
|||
bool debug_vm;
|
||||
bool debug_largebar;
|
||||
bool debug_disable_soft_recovery;
|
||||
bool debug_use_vram_fw_buf;
|
||||
};
|
||||
|
||||
static inline uint32_t amdgpu_ip_version(const struct amdgpu_device *adev,
|
||||
|
|
|
|||
|
|
@ -138,6 +138,9 @@ static void amdgpu_amdkfd_reset_work(struct work_struct *work)
|
|||
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
|
||||
}
|
||||
|
||||
static const struct drm_client_funcs kfd_client_funcs = {
|
||||
.unregister = drm_client_release,
|
||||
};
|
||||
void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -161,7 +164,7 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
|||
.enable_mes = adev->enable_mes,
|
||||
};
|
||||
|
||||
ret = drm_client_init(&adev->ddev, &adev->kfd.client, "kfd", NULL);
|
||||
ret = drm_client_init(&adev->ddev, &adev->kfd.client, "kfd", &kfd_client_funcs);
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "Failed to init DRM client: %d\n", ret);
|
||||
return;
|
||||
|
|
@ -695,10 +698,8 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
|
|||
void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle)
|
||||
{
|
||||
enum amd_powergating_state state = idle ? AMD_PG_STATE_GATE : AMD_PG_STATE_UNGATE;
|
||||
/* Temporary workaround to fix issues observed in some
|
||||
* compute applications when GFXOFF is enabled on GFX11.
|
||||
*/
|
||||
if (IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 11) {
|
||||
if (IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 11 &&
|
||||
((adev->mes.kiq_version & AMDGPU_MES_VERSION_MASK) <= 64)) {
|
||||
pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled");
|
||||
amdgpu_gfx_off_ctrl(adev, idle);
|
||||
} else if ((IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 9) &&
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_mem *mem);
|
|||
int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo);
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
|
||||
struct dma_fence **ef);
|
||||
struct dma_fence __rcu **ef);
|
||||
int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev,
|
||||
struct kfd_vm_fault_info *info);
|
||||
int amdgpu_amdkfd_gpuvm_import_dmabuf_fd(struct amdgpu_device *adev, int fd,
|
||||
|
|
|
|||
|
|
@ -2802,7 +2802,7 @@ static void amdgpu_amdkfd_restore_userptr_worker(struct work_struct *work)
|
|||
put_task_struct(usertask);
|
||||
}
|
||||
|
||||
static void replace_eviction_fence(struct dma_fence **ef,
|
||||
static void replace_eviction_fence(struct dma_fence __rcu **ef,
|
||||
struct dma_fence *new_ef)
|
||||
{
|
||||
struct dma_fence *old_ef = rcu_replace_pointer(*ef, new_ef, true
|
||||
|
|
@ -2837,7 +2837,7 @@ static void replace_eviction_fence(struct dma_fence **ef,
|
|||
* 7. Add fence to all PD and PT BOs.
|
||||
* 8. Unreserve all BOs
|
||||
*/
|
||||
int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
|
||||
int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence __rcu **ef)
|
||||
{
|
||||
struct amdkfd_process_info *process_info = info;
|
||||
struct amdgpu_vm *peer_vm;
|
||||
|
|
|
|||
|
|
@ -1544,6 +1544,7 @@ bool amdgpu_device_need_post(struct amdgpu_device *adev)
|
|||
return true;
|
||||
|
||||
fw_ver = *((uint32_t *)adev->pm.fw->data + 69);
|
||||
release_firmware(adev->pm.fw);
|
||||
if (fw_ver < 0x00160e00)
|
||||
return true;
|
||||
}
|
||||
|
|
@ -5245,7 +5246,6 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
|||
struct amdgpu_device *tmp_adev = NULL;
|
||||
bool need_full_reset, skip_hw_reset, vram_lost = false;
|
||||
int r = 0;
|
||||
bool gpu_reset_for_dev_remove = 0;
|
||||
|
||||
/* Try reset handler method first */
|
||||
tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
|
||||
|
|
@ -5265,10 +5265,6 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
|||
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
|
||||
skip_hw_reset = test_bit(AMDGPU_SKIP_HW_RESET, &reset_context->flags);
|
||||
|
||||
gpu_reset_for_dev_remove =
|
||||
test_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context->flags) &&
|
||||
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
|
||||
|
||||
/*
|
||||
* ASIC reset has to be done on all XGMI hive nodes ASAP
|
||||
* to allow proper links negotiation in FW (within 1 sec)
|
||||
|
|
@ -5311,18 +5307,6 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
|||
amdgpu_ras_intr_cleared();
|
||||
}
|
||||
|
||||
/* Since the mode1 reset affects base ip blocks, the
|
||||
* phase1 ip blocks need to be resumed. Otherwise there
|
||||
* will be a BIOS signature error and the psp bootloader
|
||||
* can't load kdb on the next amdgpu install.
|
||||
*/
|
||||
if (gpu_reset_for_dev_remove) {
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list)
|
||||
amdgpu_device_ip_resume_phase1(tmp_adev);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
||||
if (need_full_reset) {
|
||||
/* post card */
|
||||
|
|
@ -5559,11 +5543,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
int i, r = 0;
|
||||
bool need_emergency_restart = false;
|
||||
bool audio_suspended = false;
|
||||
bool gpu_reset_for_dev_remove = false;
|
||||
|
||||
gpu_reset_for_dev_remove =
|
||||
test_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context->flags) &&
|
||||
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
|
||||
|
||||
/*
|
||||
* Special case: RAS triggered and full reset isn't supported
|
||||
|
|
@ -5601,7 +5580,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) {
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
|
||||
list_add_tail(&tmp_adev->reset_list, &device_list);
|
||||
if (gpu_reset_for_dev_remove && adev->shutdown)
|
||||
if (adev->shutdown)
|
||||
tmp_adev->shutdown = true;
|
||||
}
|
||||
if (!list_is_first(&adev->reset_list, &device_list))
|
||||
|
|
@ -5686,10 +5665,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
|
||||
retry: /* Rest of adevs pre asic reset from XGMI hive. */
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
||||
if (gpu_reset_for_dev_remove) {
|
||||
/* Workaroud for ASICs need to disable SMC first */
|
||||
amdgpu_device_smu_fini_early(tmp_adev);
|
||||
}
|
||||
r = amdgpu_device_pre_asic_reset(tmp_adev, reset_context);
|
||||
/*TODO Should we stop ?*/
|
||||
if (r) {
|
||||
|
|
@ -5721,9 +5696,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
r = amdgpu_do_asic_reset(device_list_handle, reset_context);
|
||||
if (r && r == -EAGAIN)
|
||||
goto retry;
|
||||
|
||||
if (!r && gpu_reset_for_dev_remove)
|
||||
goto recover_end;
|
||||
}
|
||||
|
||||
skip_hw_reset:
|
||||
|
|
@ -5779,7 +5751,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
amdgpu_ras_set_error_query_ready(tmp_adev, true);
|
||||
}
|
||||
|
||||
recover_end:
|
||||
tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
|
||||
reset_list);
|
||||
amdgpu_device_unlock_reset_domain(tmp_adev->reset_domain);
|
||||
|
|
|
|||
|
|
@ -1963,8 +1963,6 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
break;
|
||||
case IP_VERSION(9, 4, 3):
|
||||
if (!amdgpu_exp_hw_support)
|
||||
return -EINVAL;
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v9_4_3_ip_block);
|
||||
break;
|
||||
case IP_VERSION(10, 1, 10):
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ enum AMDGPU_DEBUG_MASK {
|
|||
AMDGPU_DEBUG_VM = BIT(0),
|
||||
AMDGPU_DEBUG_LARGEBAR = BIT(1),
|
||||
AMDGPU_DEBUG_DISABLE_GPU_SOFT_RECOVERY = BIT(2),
|
||||
AMDGPU_DEBUG_USE_VRAM_FW_BUF = BIT(3),
|
||||
};
|
||||
|
||||
unsigned int amdgpu_vram_limit = UINT_MAX;
|
||||
|
|
@ -210,7 +211,6 @@ int amdgpu_seamless = -1; /* auto */
|
|||
uint amdgpu_debug_mask;
|
||||
int amdgpu_agp = -1; /* auto */
|
||||
int amdgpu_wbrf = -1;
|
||||
int fw_bo_location = -1;
|
||||
|
||||
static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
|
||||
|
||||
|
|
@ -990,10 +990,6 @@ MODULE_PARM_DESC(wbrf,
|
|||
"Enable Wifi RFI interference mitigation (0 = disabled, 1 = enabled, -1 = auto(default)");
|
||||
module_param_named(wbrf, amdgpu_wbrf, int, 0444);
|
||||
|
||||
MODULE_PARM_DESC(fw_bo_location,
|
||||
"location to put firmware bo for frontdoor loading (-1 = auto (default), 0 = on ram, 1 = on vram");
|
||||
module_param(fw_bo_location, int, 0644);
|
||||
|
||||
/* These devices are not supported by amdgpu.
|
||||
* They are supported by the mach64, r128, radeon drivers
|
||||
*/
|
||||
|
|
@ -2122,6 +2118,11 @@ static void amdgpu_init_debug_options(struct amdgpu_device *adev)
|
|||
pr_info("debug: soft reset for GPU recovery disabled\n");
|
||||
adev->debug_disable_soft_recovery = true;
|
||||
}
|
||||
|
||||
if (amdgpu_debug_mask & AMDGPU_DEBUG_USE_VRAM_FW_BUF) {
|
||||
pr_info("debug: place fw in vram for frontdoor loading\n");
|
||||
adev->debug_use_vram_fw_buf = true;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long amdgpu_fix_asic_type(struct pci_dev *pdev, unsigned long flags)
|
||||
|
|
@ -2233,6 +2234,8 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
|
|||
|
||||
pci_set_drvdata(pdev, ddev);
|
||||
|
||||
amdgpu_init_debug_options(adev);
|
||||
|
||||
ret = amdgpu_driver_load_kms(adev, flags);
|
||||
if (ret)
|
||||
goto err_pci;
|
||||
|
|
@ -2313,8 +2316,6 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
|
|||
amdgpu_get_secondary_funcs(adev);
|
||||
}
|
||||
|
||||
amdgpu_init_debug_options(adev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_pci:
|
||||
|
|
@ -2336,38 +2337,6 @@ amdgpu_pci_remove(struct pci_dev *pdev)
|
|||
pm_runtime_forbid(dev->dev);
|
||||
}
|
||||
|
||||
if (amdgpu_ip_version(adev, 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) {
|
||||
struct amdgpu_hive_info *hive;
|
||||
|
||||
hive = amdgpu_get_xgmi_hive(adev);
|
||||
if (hive->device_remove_count == 0)
|
||||
need_to_reset_gpu = true;
|
||||
hive->device_remove_count++;
|
||||
amdgpu_put_xgmi_hive(hive);
|
||||
} else {
|
||||
need_to_reset_gpu = true;
|
||||
}
|
||||
|
||||
/* Workaround for ASICs need to reset SMU.
|
||||
* Called only when the first device is removed.
|
||||
*/
|
||||
if (need_to_reset_gpu) {
|
||||
struct amdgpu_reset_context reset_context;
|
||||
|
||||
adev->shutdown = true;
|
||||
memset(&reset_context, 0, sizeof(reset_context));
|
||||
reset_context.method = AMD_RESET_METHOD_NONE;
|
||||
reset_context.reset_req_dev = adev;
|
||||
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
set_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context.flags);
|
||||
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_driver_unload_kms(dev);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1045,21 +1045,28 @@ int amdgpu_gmc_vram_checking(struct amdgpu_device *adev)
|
|||
* seconds, so here, we just pick up three parts for emulation.
|
||||
*/
|
||||
ret = memcmp(vram_ptr, cptr, 10);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (ret) {
|
||||
ret = -EIO;
|
||||
goto release_buffer;
|
||||
}
|
||||
|
||||
ret = memcmp(vram_ptr + (size / 2), cptr, 10);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (ret) {
|
||||
ret = -EIO;
|
||||
goto release_buffer;
|
||||
}
|
||||
|
||||
ret = memcmp(vram_ptr + size - 10, cptr, 10);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (ret) {
|
||||
ret = -EIO;
|
||||
goto release_buffer;
|
||||
}
|
||||
|
||||
release_buffer:
|
||||
amdgpu_bo_free_kernel(&vram_bo, &vram_gpu,
|
||||
&vram_ptr);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t current_memory_partition_show(
|
||||
|
|
|
|||
|
|
@ -1105,7 +1105,12 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|||
if (amdgpu_dpm_read_sensor(adev,
|
||||
AMDGPU_PP_SENSOR_GPU_AVG_POWER,
|
||||
(void *)&ui32, &ui32_size)) {
|
||||
return -EINVAL;
|
||||
/* fall back to input power for backwards compat */
|
||||
if (amdgpu_dpm_read_sensor(adev,
|
||||
AMDGPU_PP_SENSOR_GPU_INPUT_POWER,
|
||||
(void *)&ui32, &ui32_size)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
ui32 >>= 8;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ static int psp_sw_init(void *handle)
|
|||
}
|
||||
|
||||
ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG,
|
||||
(amdgpu_sriov_vf(adev) || fw_bo_location == 1) ?
|
||||
(amdgpu_sriov_vf(adev) || adev->debug_use_vram_fw_buf) ?
|
||||
AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT,
|
||||
&psp->fw_pri_bo,
|
||||
&psp->fw_pri_mc_addr,
|
||||
|
|
|
|||
|
|
@ -305,11 +305,13 @@ static int amdgpu_ras_debugfs_ctrl_parse_data(struct file *f,
|
|||
return -EINVAL;
|
||||
|
||||
data->head.block = block_id;
|
||||
/* only ue and ce errors are supported */
|
||||
/* only ue, ce and poison errors are supported */
|
||||
if (!memcmp("ue", err, 2))
|
||||
data->head.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||
else if (!memcmp("ce", err, 2))
|
||||
data->head.type = AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE;
|
||||
else if (!memcmp("poison", err, 6))
|
||||
data->head.type = AMDGPU_RAS_ERROR__POISON;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -431,9 +433,10 @@ static void amdgpu_ras_instance_mask_check(struct amdgpu_device *adev,
|
|||
* The block is one of: umc, sdma, gfx, etc.
|
||||
* see ras_block_string[] for details
|
||||
*
|
||||
* The error type is one of: ue, ce, where,
|
||||
* The error type is one of: ue, ce and poison where,
|
||||
* ue is multi-uncorrectable
|
||||
* ce is single-correctable
|
||||
* poison is poison
|
||||
*
|
||||
* The sub-block is a the sub-block index, pass 0 if there is no sub-block.
|
||||
* The address and value are hexadecimal numbers, leading 0x is optional.
|
||||
|
|
@ -1067,8 +1070,7 @@ static void amdgpu_ras_error_print_error_data(struct amdgpu_device *adev,
|
|||
mcm_info = &err_info->mcm_info;
|
||||
if (err_info->ce_count) {
|
||||
dev_info(adev->dev, "socket: %d, die: %d, "
|
||||
"%lld new correctable hardware errors detected in %s block, "
|
||||
"no user action is needed\n",
|
||||
"%lld new correctable hardware errors detected in %s block\n",
|
||||
mcm_info->socket_id,
|
||||
mcm_info->die_id,
|
||||
err_info->ce_count,
|
||||
|
|
@ -1080,8 +1082,7 @@ static void amdgpu_ras_error_print_error_data(struct amdgpu_device *adev,
|
|||
err_info = &err_node->err_info;
|
||||
mcm_info = &err_info->mcm_info;
|
||||
dev_info(adev->dev, "socket: %d, die: %d, "
|
||||
"%lld correctable hardware errors detected in total in %s block, "
|
||||
"no user action is needed\n",
|
||||
"%lld correctable hardware errors detected in total in %s block\n",
|
||||
mcm_info->socket_id, mcm_info->die_id, err_info->ce_count, blk_name);
|
||||
}
|
||||
}
|
||||
|
|
@ -1108,16 +1109,14 @@ static void amdgpu_ras_error_generate_report(struct amdgpu_device *adev,
|
|||
adev->smuio.funcs->get_die_id) {
|
||||
dev_info(adev->dev, "socket: %d, die: %d "
|
||||
"%ld correctable hardware errors "
|
||||
"detected in %s block, no user "
|
||||
"action is needed.\n",
|
||||
"detected in %s block\n",
|
||||
adev->smuio.funcs->get_socket_id(adev),
|
||||
adev->smuio.funcs->get_die_id(adev),
|
||||
ras_mgr->err_data.ce_count,
|
||||
blk_name);
|
||||
} else {
|
||||
dev_info(adev->dev, "%ld correctable hardware errors "
|
||||
"detected in %s block, no user "
|
||||
"action is needed.\n",
|
||||
"detected in %s block\n",
|
||||
ras_mgr->err_data.ce_count,
|
||||
blk_name);
|
||||
}
|
||||
|
|
@ -1920,7 +1919,7 @@ static void amdgpu_ras_interrupt_poison_creation_handler(struct ras_manager *obj
|
|||
struct amdgpu_iv_entry *entry)
|
||||
{
|
||||
dev_info(obj->adev->dev,
|
||||
"Poison is created, no user action is needed.\n");
|
||||
"Poison is created\n");
|
||||
}
|
||||
|
||||
static void amdgpu_ras_interrupt_umc_handler(struct ras_manager *obj,
|
||||
|
|
@ -2920,6 +2919,11 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
|
|||
|
||||
amdgpu_ras_query_poison_mode(adev);
|
||||
|
||||
/* Packed socket_id to ras feature mask bits[31:29] */
|
||||
if (adev->smuio.funcs &&
|
||||
adev->smuio.funcs->get_socket_id)
|
||||
con->features |= ((adev->smuio.funcs->get_socket_id(adev)) << 29);
|
||||
|
||||
/* Get RAS schema for particular SOC */
|
||||
con->schema = amdgpu_get_ras_schema(adev);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ enum AMDGPU_RESET_FLAGS {
|
|||
|
||||
AMDGPU_NEED_FULL_RESET = 0,
|
||||
AMDGPU_SKIP_HW_RESET = 1,
|
||||
AMDGPU_RESET_FOR_DEVICE_REMOVE = 2,
|
||||
};
|
||||
|
||||
struct amdgpu_reset_context {
|
||||
|
|
|
|||
|
|
@ -1062,7 +1062,7 @@ int amdgpu_ucode_create_bo(struct amdgpu_device *adev)
|
|||
{
|
||||
if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) {
|
||||
amdgpu_bo_create_kernel(adev, adev->firmware.fw_size, PAGE_SIZE,
|
||||
(amdgpu_sriov_vf(adev) || fw_bo_location == 1) ?
|
||||
(amdgpu_sriov_vf(adev) || adev->debug_use_vram_fw_buf) ?
|
||||
AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->firmware.fw_buf,
|
||||
&adev->firmware.fw_buf_mc,
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ struct amdgpu_mem_stats;
|
|||
#define AMDGPU_VM_FAULT_STOP_FIRST 1
|
||||
#define AMDGPU_VM_FAULT_STOP_ALWAYS 2
|
||||
|
||||
/* Reserve 4MB VRAM for page tables */
|
||||
/* How much VRAM be reserved for page tables */
|
||||
#define AMDGPU_VM_RESERVED_VRAM (8ULL << 20)
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -59,11 +59,8 @@ static inline uint16_t complete_integer_division_u16(
|
|||
|
||||
static uint16_t vpe_u1_8_from_fraction(uint16_t numerator, uint16_t denominator)
|
||||
{
|
||||
bool arg1_negative = numerator < 0;
|
||||
bool arg2_negative = denominator < 0;
|
||||
|
||||
uint16_t arg1_value = (uint16_t)(arg1_negative ? -numerator : numerator);
|
||||
uint16_t arg2_value = (uint16_t)(arg2_negative ? -denominator : denominator);
|
||||
u16 arg1_value = numerator;
|
||||
u16 arg2_value = denominator;
|
||||
|
||||
uint16_t remainder;
|
||||
|
||||
|
|
@ -100,9 +97,6 @@ static uint16_t vpe_u1_8_from_fraction(uint16_t numerator, uint16_t denominator)
|
|||
res_value += summand;
|
||||
}
|
||||
|
||||
if (arg1_negative ^ arg2_negative)
|
||||
res_value = -res_value;
|
||||
|
||||
return res_value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ struct amdgpu_hive_info {
|
|||
} pstate;
|
||||
|
||||
struct amdgpu_reset_domain *reset_domain;
|
||||
uint32_t device_remove_count;
|
||||
atomic_t ras_recovery;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#define regATHUB_MISC_CNTL_V3_0_1 0x00d7
|
||||
#define regATHUB_MISC_CNTL_V3_0_1_BASE_IDX 0
|
||||
#define regATHUB_MISC_CNTL_V3_3_0 0x00d8
|
||||
#define regATHUB_MISC_CNTL_V3_3_0_BASE_IDX 0
|
||||
|
||||
|
||||
static uint32_t athub_v3_0_get_cg_cntl(struct amdgpu_device *adev)
|
||||
|
|
@ -40,6 +42,9 @@ static uint32_t athub_v3_0_get_cg_cntl(struct amdgpu_device *adev)
|
|||
case IP_VERSION(3, 0, 1):
|
||||
data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_0_1);
|
||||
break;
|
||||
case IP_VERSION(3, 3, 0):
|
||||
data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_3_0);
|
||||
break;
|
||||
default:
|
||||
data = RREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL);
|
||||
break;
|
||||
|
|
@ -53,6 +58,9 @@ static void athub_v3_0_set_cg_cntl(struct amdgpu_device *adev, uint32_t data)
|
|||
case IP_VERSION(3, 0, 1):
|
||||
WREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_0_1, data);
|
||||
break;
|
||||
case IP_VERSION(3, 3, 0):
|
||||
WREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL_V3_3_0, data);
|
||||
break;
|
||||
default:
|
||||
WREG32_SOC15(ATHUB, 0, regATHUB_MISC_CNTL, data);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -3996,16 +3996,13 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
|||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", ucode_prefix);
|
||||
err = amdgpu_ucode_request(adev, &adev->gfx.rlc_fw, fw_name);
|
||||
/* don't check this. There are apparently firmwares in the wild with
|
||||
* incorrect size in the header
|
||||
*/
|
||||
if (err == -ENODEV)
|
||||
goto out;
|
||||
err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
dev_dbg(adev->dev,
|
||||
"gfx10: amdgpu_ucode_request() failed \"%s\"\n",
|
||||
fw_name);
|
||||
goto out;
|
||||
|
||||
/* don't validate this firmware. There are apparently firmwares
|
||||
* in the wild with incorrect size in the header
|
||||
*/
|
||||
rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
|
||||
version_major = le16_to_cpu(rlc_hdr->header.header_version_major);
|
||||
version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor);
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ static const struct soc15_reg_golden golden_settings_gc_11_5_0[] = {
|
|||
SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL, 0xffffffff, 0xf37fff3f),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL3, 0xfffffffb, 0x00f40188),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL4, 0xf0ffffff, 0x8000b007),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL4, 0xf0ffffff, 0x80009007),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regPA_CL_ENHANCE, 0xf1ffffff, 0x00880007),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regPC_CONFIG_CNTL_1, 0xffffffff, 0x00010000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, regTA_CNTL_AUX, 0xf7f7ffff, 0x01030000),
|
||||
|
|
@ -6383,6 +6383,9 @@ static int gfx_v11_0_get_cu_info(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++) {
|
||||
bitmap = i * adev->gfx.config.max_sh_per_se + j;
|
||||
if (!((gfx_v11_0_get_sa_active_bitmap(adev) >> bitmap) & 1))
|
||||
continue;
|
||||
mask = 1;
|
||||
counter = 0;
|
||||
gfx_v11_0_select_se_sh(adev, i, j, 0xffffffff, 0);
|
||||
|
|
|
|||
|
|
@ -456,10 +456,12 @@ static void gfxhub_v1_2_xcc_gart_disable(struct amdgpu_device *adev,
|
|||
WREG32_SOC15_RLC(GC, GET_INST(GC, j), regMC_VM_MX_L1_TLB_CNTL, tmp);
|
||||
|
||||
/* Setup L2 cache */
|
||||
tmp = RREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0);
|
||||
WREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL, tmp);
|
||||
WREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL3, 0);
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
tmp = RREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0);
|
||||
WREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL, tmp);
|
||||
WREG32_SOC15(GC, GET_INST(GC, j), regVM_L2_CNTL3, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -401,8 +401,7 @@ static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device
|
|||
|
||||
if (err_data.ce_count)
|
||||
dev_info(adev->dev, "%ld correctable hardware "
|
||||
"errors detected in %s block, "
|
||||
"no user action is needed.\n",
|
||||
"errors detected in %s block\n",
|
||||
obj->err_data.ce_count,
|
||||
get_ras_block_str(adev->nbio.ras_if));
|
||||
|
||||
|
|
|
|||
|
|
@ -597,8 +597,7 @@ static void nbio_v7_9_handle_ras_controller_intr_no_bifring(struct amdgpu_device
|
|||
|
||||
if (err_data.ce_count)
|
||||
dev_info(adev->dev, "%ld correctable hardware "
|
||||
"errors detected in %s block, "
|
||||
"no user action is needed.\n",
|
||||
"errors detected in %s block\n",
|
||||
obj->err_data.ce_count,
|
||||
get_ras_block_str(adev->nbio.ras_if));
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ static void umc_v6_7_query_error_status_helper(struct amdgpu_device *adev,
|
|||
uint64_t reg_value;
|
||||
|
||||
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1)
|
||||
dev_info(adev->dev, "Deferred error, no user action is needed.\n");
|
||||
dev_info(adev->dev, "Deferred error\n");
|
||||
|
||||
if (mc_umc_status)
|
||||
dev_info(adev->dev, "MCA STATUS 0x%llx, umc_reg_offset 0x%x\n", mc_umc_status, umc_reg_offset);
|
||||
|
|
|
|||
|
|
@ -1026,7 +1026,7 @@ int kgd2kfd_init_zone_device(struct amdgpu_device *adev)
|
|||
} else {
|
||||
res = devm_request_free_mem_region(adev->dev, &iomem_resource, size);
|
||||
if (IS_ERR(res))
|
||||
return -ENOMEM;
|
||||
return PTR_ERR(res);
|
||||
pgmap->range.start = res->start;
|
||||
pgmap->range.end = res->end;
|
||||
pgmap->type = MEMORY_DEVICE_PRIVATE;
|
||||
|
|
@ -1042,10 +1042,10 @@ int kgd2kfd_init_zone_device(struct amdgpu_device *adev)
|
|||
r = devm_memremap_pages(adev->dev, pgmap);
|
||||
if (IS_ERR(r)) {
|
||||
pr_err("failed to register HMM device memory\n");
|
||||
/* Disable SVM support capability */
|
||||
pgmap->type = 0;
|
||||
if (pgmap->type == MEMORY_DEVICE_PRIVATE)
|
||||
devm_release_mem_region(adev->dev, res->start, resource_size(res));
|
||||
/* Disable SVM support capability */
|
||||
pgmap->type = 0;
|
||||
return PTR_ERR(r);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -917,7 +917,7 @@ struct kfd_process {
|
|||
* fence will be triggered during eviction and new one will be created
|
||||
* during restore
|
||||
*/
|
||||
struct dma_fence *ef;
|
||||
struct dma_fence __rcu *ef;
|
||||
|
||||
/* Work items for evicting and restoring BOs */
|
||||
struct delayed_work eviction_work;
|
||||
|
|
|
|||
|
|
@ -1110,6 +1110,7 @@ static void kfd_process_wq_release(struct work_struct *work)
|
|||
{
|
||||
struct kfd_process *p = container_of(work, struct kfd_process,
|
||||
release_work);
|
||||
struct dma_fence *ef;
|
||||
|
||||
kfd_process_dequeue_from_all_devices(p);
|
||||
pqm_uninit(&p->pqm);
|
||||
|
|
@ -1118,7 +1119,9 @@ static void kfd_process_wq_release(struct work_struct *work)
|
|||
* destroyed. This allows any BOs to be freed without
|
||||
* triggering pointless evictions or waiting for fences.
|
||||
*/
|
||||
dma_fence_signal(p->ef);
|
||||
synchronize_rcu();
|
||||
ef = rcu_access_pointer(p->ef);
|
||||
dma_fence_signal(ef);
|
||||
|
||||
kfd_process_remove_sysfs(p);
|
||||
|
||||
|
|
@ -1127,7 +1130,7 @@ static void kfd_process_wq_release(struct work_struct *work)
|
|||
svm_range_list_fini(p);
|
||||
|
||||
kfd_process_destroy_pdds(p);
|
||||
dma_fence_put(p->ef);
|
||||
dma_fence_put(ef);
|
||||
|
||||
kfd_event_free_process(p);
|
||||
|
||||
|
|
|
|||
|
|
@ -404,14 +404,9 @@ static void svm_range_bo_release(struct kref *kref)
|
|||
spin_lock(&svm_bo->list_lock);
|
||||
}
|
||||
spin_unlock(&svm_bo->list_lock);
|
||||
if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base)) {
|
||||
/* We're not in the eviction worker.
|
||||
* Signal the fence and synchronize with any
|
||||
* pending eviction work.
|
||||
*/
|
||||
if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base))
|
||||
/* We're not in the eviction worker. Signal the fence. */
|
||||
dma_fence_signal(&svm_bo->eviction_fence->base);
|
||||
cancel_work_sync(&svm_bo->eviction_work);
|
||||
}
|
||||
dma_fence_put(&svm_bo->eviction_fence->base);
|
||||
amdgpu_bo_unref(&svm_bo->bo);
|
||||
kfree(svm_bo);
|
||||
|
|
@ -2345,8 +2340,10 @@ static void svm_range_deferred_list_work(struct work_struct *work)
|
|||
mutex_unlock(&svms->lock);
|
||||
mmap_write_unlock(mm);
|
||||
|
||||
/* Pairs with mmget in svm_range_add_list_work */
|
||||
mmput(mm);
|
||||
/* Pairs with mmget in svm_range_add_list_work. If dropping the
|
||||
* last mm refcount, schedule release work to avoid circular locking
|
||||
*/
|
||||
mmput_async(mm);
|
||||
|
||||
spin_lock(&svms->deferred_list_lock);
|
||||
}
|
||||
|
|
@ -2657,6 +2654,7 @@ svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr,
|
|||
{
|
||||
struct vm_area_struct *vma;
|
||||
struct interval_tree_node *node;
|
||||
struct rb_node *rb_node;
|
||||
unsigned long start_limit, end_limit;
|
||||
|
||||
vma = vma_lookup(p->mm, addr << PAGE_SHIFT);
|
||||
|
|
@ -2676,16 +2674,15 @@ svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr,
|
|||
if (node) {
|
||||
end_limit = min(end_limit, node->start);
|
||||
/* Last range that ends before the fault address */
|
||||
node = container_of(rb_prev(&node->rb),
|
||||
struct interval_tree_node, rb);
|
||||
rb_node = rb_prev(&node->rb);
|
||||
} else {
|
||||
/* Last range must end before addr because
|
||||
* there was no range after addr
|
||||
*/
|
||||
node = container_of(rb_last(&p->svms.objects.rb_root),
|
||||
struct interval_tree_node, rb);
|
||||
rb_node = rb_last(&p->svms.objects.rb_root);
|
||||
}
|
||||
if (node) {
|
||||
if (rb_node) {
|
||||
node = container_of(rb_node, struct interval_tree_node, rb);
|
||||
if (node->last >= addr) {
|
||||
WARN(1, "Overlap with prev node and page fault addr\n");
|
||||
return -EFAULT;
|
||||
|
|
@ -3432,13 +3429,14 @@ svm_range_trigger_migration(struct mm_struct *mm, struct svm_range *prange,
|
|||
|
||||
int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence)
|
||||
{
|
||||
if (!fence)
|
||||
return -EINVAL;
|
||||
|
||||
if (dma_fence_is_signaled(&fence->base))
|
||||
return 0;
|
||||
|
||||
if (fence->svm_bo) {
|
||||
/* Dereferencing fence->svm_bo is safe here because the fence hasn't
|
||||
* signaled yet and we're under the protection of the fence->lock.
|
||||
* After the fence is signaled in svm_range_bo_release, we cannot get
|
||||
* here any more.
|
||||
*
|
||||
* Reference is dropped in svm_range_evict_svm_bo_worker.
|
||||
*/
|
||||
if (svm_bo_ref_unless_zero(fence->svm_bo)) {
|
||||
WRITE_ONCE(fence->svm_bo->evicting, 1);
|
||||
schedule_work(&fence->svm_bo->eviction_work);
|
||||
}
|
||||
|
|
@ -3453,8 +3451,6 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
|
|||
int r = 0;
|
||||
|
||||
svm_bo = container_of(work, struct svm_range_bo, eviction_work);
|
||||
if (!svm_bo_ref_unless_zero(svm_bo))
|
||||
return; /* svm_bo was freed while eviction was pending */
|
||||
|
||||
if (mmget_not_zero(svm_bo->eviction_fence->mm)) {
|
||||
mm = svm_bo->eviction_fence->mm;
|
||||
|
|
|
|||
|
|
@ -9293,10 +9293,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
if (!new_con_state->writeback_job)
|
||||
continue;
|
||||
|
||||
new_crtc_state = NULL;
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
|
||||
|
||||
if (acrtc)
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
|
||||
if (!new_crtc_state)
|
||||
continue;
|
||||
|
||||
if (acrtc->wb_enabled)
|
||||
continue;
|
||||
|
|
@ -10753,7 +10753,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
DRM_DEBUG_DRIVER("drm_dp_mst_atomic_check() failed\n");
|
||||
goto fail;
|
||||
}
|
||||
status = dc_validate_global_state(dc, dm_state->context, false);
|
||||
status = dc_validate_global_state(dc, dm_state->context, true);
|
||||
if (status != DC_OK) {
|
||||
DRM_DEBUG_DRIVER("DC global validation failure: %s (%d)",
|
||||
dc_status_to_str(status), status);
|
||||
|
|
|
|||
|
|
@ -1239,7 +1239,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
|
|||
if (has_crtc_cm_degamma && ret != -EINVAL) {
|
||||
drm_dbg_kms(crtc->base.crtc->dev,
|
||||
"doesn't support plane and CRTC degamma at the same time\n");
|
||||
return -EINVAL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* If we are here, it means we don't have plane degamma settings, check
|
||||
|
|
|
|||
|
|
@ -979,6 +979,11 @@ int dm_helper_dmub_aux_transfer_sync(
|
|||
struct aux_payload *payload,
|
||||
enum aux_return_code_type *operation_result)
|
||||
{
|
||||
if (!link->hpd_status) {
|
||||
*operation_result = AUX_RET_ERROR_HPD_DISCON;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return amdgpu_dm_process_dmub_aux_transfer_sync(ctx, link->link_index, payload,
|
||||
operation_result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,20 @@ static const struct IP_BASE CLK_BASE = { { { { 0x00016C00, 0x02401800, 0, 0, 0,
|
|||
#define CLK1_CLK_PLL_REQ__PllSpineDiv_MASK 0x0000F000L
|
||||
#define CLK1_CLK_PLL_REQ__FbMult_frac_MASK 0xFFFF0000L
|
||||
|
||||
#define regCLK1_CLK2_BYPASS_CNTL 0x029c
|
||||
#define regCLK1_CLK2_BYPASS_CNTL_BASE_IDX 0
|
||||
|
||||
#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL__SHIFT 0x0
|
||||
#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV__SHIFT 0x10
|
||||
#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL_MASK 0x00000007L
|
||||
#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV_MASK 0x000F0000L
|
||||
|
||||
#define regCLK6_0_CLK6_spll_field_8 0x464b
|
||||
#define regCLK6_0_CLK6_spll_field_8_BASE_IDX 0
|
||||
|
||||
#define CLK6_0_CLK6_spll_field_8__spll_ssc_en__SHIFT 0xd
|
||||
#define CLK6_0_CLK6_spll_field_8__spll_ssc_en_MASK 0x00002000L
|
||||
|
||||
#define REG(reg_name) \
|
||||
(CLK_BASE.instance[0].segment[reg ## reg_name ## _BASE_IDX] + reg ## reg_name)
|
||||
|
||||
|
|
@ -131,35 +145,63 @@ static int dcn314_get_active_display_cnt_wa(
|
|||
return display_count;
|
||||
}
|
||||
|
||||
static void dcn314_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable)
|
||||
static void dcn314_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context,
|
||||
bool safe_to_lower, bool disable)
|
||||
{
|
||||
struct dc *dc = clk_mgr_base->ctx->dc;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; ++i) {
|
||||
struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
struct pipe_ctx *pipe = safe_to_lower
|
||||
? &context->res_ctx.pipe_ctx[i]
|
||||
: &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (pipe->top_pipe || pipe->prev_odm_pipe)
|
||||
continue;
|
||||
if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) {
|
||||
struct stream_encoder *stream_enc = pipe->stream_res.stream_enc;
|
||||
|
||||
if (disable) {
|
||||
if (stream_enc && stream_enc->funcs->disable_fifo)
|
||||
pipe->stream_res.stream_enc->funcs->disable_fifo(stream_enc);
|
||||
if (pipe->stream_res.tg && pipe->stream_res.tg->funcs->immediate_disable_crtc)
|
||||
pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
|
||||
|
||||
pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
|
||||
reset_sync_context_for_pipe(dc, context, i);
|
||||
} else {
|
||||
pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
|
||||
|
||||
if (stream_enc && stream_enc->funcs->enable_fifo)
|
||||
pipe->stream_res.stream_enc->funcs->enable_fifo(stream_enc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool dcn314_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base)
|
||||
{
|
||||
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
|
||||
uint32_t ssc_enable;
|
||||
|
||||
REG_GET(CLK6_0_CLK6_spll_field_8, spll_ssc_en, &ssc_enable);
|
||||
|
||||
return ssc_enable == 1;
|
||||
}
|
||||
|
||||
void dcn314_init_clocks(struct clk_mgr *clk_mgr)
|
||||
{
|
||||
struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr);
|
||||
uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz;
|
||||
|
||||
memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
|
||||
// Assumption is that boot state always supports pstate
|
||||
clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk; // restore ref_dtbclk
|
||||
clk_mgr->clks.p_state_change_support = true;
|
||||
clk_mgr->clks.prev_p_state_change_support = true;
|
||||
clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN;
|
||||
clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN;
|
||||
|
||||
// to adjust dp_dto reference clock if ssc is enable otherwise to apply dprefclk
|
||||
if (dcn314_is_spll_ssc_enabled(clk_mgr))
|
||||
clk_mgr->dp_dto_source_clock_in_khz =
|
||||
dce_adjust_dp_ref_freq_for_ss(clk_mgr_int, clk_mgr->dprefclk_khz);
|
||||
else
|
||||
clk_mgr->dp_dto_source_clock_in_khz = clk_mgr->dprefclk_khz;
|
||||
}
|
||||
|
||||
void dcn314_update_clocks(struct clk_mgr *clk_mgr_base,
|
||||
struct dc_state *context,
|
||||
bool safe_to_lower)
|
||||
|
|
@ -252,11 +294,11 @@ void dcn314_update_clocks(struct clk_mgr *clk_mgr_base,
|
|||
}
|
||||
|
||||
if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
|
||||
dcn314_disable_otg_wa(clk_mgr_base, context, true);
|
||||
dcn314_disable_otg_wa(clk_mgr_base, context, safe_to_lower, true);
|
||||
|
||||
clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
|
||||
dcn314_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
|
||||
dcn314_disable_otg_wa(clk_mgr_base, context, false);
|
||||
dcn314_disable_otg_wa(clk_mgr_base, context, safe_to_lower, false);
|
||||
|
||||
update_dispclk = true;
|
||||
}
|
||||
|
|
@ -436,6 +478,11 @@ static DpmClocks314_t dummy_clocks;
|
|||
|
||||
static struct dcn314_watermarks dummy_wms = { 0 };
|
||||
|
||||
static struct dcn314_ss_info_table ss_info_table = {
|
||||
.ss_divider = 1000,
|
||||
.ss_percentage = {0, 0, 375, 375, 375}
|
||||
};
|
||||
|
||||
static void dcn314_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn314_watermarks *table)
|
||||
{
|
||||
int i, num_valid_sets;
|
||||
|
|
@ -708,13 +755,31 @@ static struct clk_mgr_funcs dcn314_funcs = {
|
|||
.get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
|
||||
.get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
|
||||
.update_clocks = dcn314_update_clocks,
|
||||
.init_clocks = dcn31_init_clocks,
|
||||
.init_clocks = dcn314_init_clocks,
|
||||
.enable_pme_wa = dcn314_enable_pme_wa,
|
||||
.are_clock_states_equal = dcn314_are_clock_states_equal,
|
||||
.notify_wm_ranges = dcn314_notify_wm_ranges
|
||||
};
|
||||
extern struct clk_mgr_funcs dcn3_fpga_funcs;
|
||||
|
||||
static void dcn314_read_ss_info_from_lut(struct clk_mgr_internal *clk_mgr)
|
||||
{
|
||||
uint32_t clock_source;
|
||||
//uint32_t ssc_enable;
|
||||
|
||||
REG_GET(CLK1_CLK2_BYPASS_CNTL, CLK2_BYPASS_SEL, &clock_source);
|
||||
//REG_GET(CLK6_0_CLK6_spll_field_8, spll_ssc_en, &ssc_enable);
|
||||
|
||||
if (dcn314_is_spll_ssc_enabled(&clk_mgr->base) && (clock_source < ARRAY_SIZE(ss_info_table.ss_percentage))) {
|
||||
clk_mgr->dprefclk_ss_percentage = ss_info_table.ss_percentage[clock_source];
|
||||
|
||||
if (clk_mgr->dprefclk_ss_percentage != 0) {
|
||||
clk_mgr->ss_on_dprefclk = true;
|
||||
clk_mgr->dprefclk_ss_divider = ss_info_table.ss_divider;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dcn314_clk_mgr_construct(
|
||||
struct dc_context *ctx,
|
||||
struct clk_mgr_dcn314 *clk_mgr,
|
||||
|
|
@ -782,6 +847,7 @@ void dcn314_clk_mgr_construct(
|
|||
clk_mgr->base.base.dprefclk_khz = 600000;
|
||||
clk_mgr->base.base.clks.ref_dtbclk_khz = 600000;
|
||||
dce_clock_read_ss_info(&clk_mgr->base);
|
||||
dcn314_read_ss_info_from_lut(&clk_mgr->base);
|
||||
/*if bios enabled SS, driver needs to adjust dtb clock, only enable with correct bios*/
|
||||
|
||||
clk_mgr->base.base.bw_params = &dcn314_bw_params;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#define __DCN314_CLK_MGR_H__
|
||||
#include "clk_mgr_internal.h"
|
||||
|
||||
#define DCN314_NUM_CLOCK_SOURCES 5
|
||||
|
||||
struct dcn314_watermarks;
|
||||
|
||||
struct dcn314_smu_watermark_set {
|
||||
|
|
@ -40,9 +42,18 @@ struct clk_mgr_dcn314 {
|
|||
struct dcn314_smu_watermark_set smu_wm_set;
|
||||
};
|
||||
|
||||
struct dcn314_ss_info_table {
|
||||
uint32_t ss_divider;
|
||||
uint32_t ss_percentage[DCN314_NUM_CLOCK_SOURCES];
|
||||
};
|
||||
|
||||
bool dcn314_are_clock_states_equal(struct dc_clocks *a,
|
||||
struct dc_clocks *b);
|
||||
|
||||
bool dcn314_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base);
|
||||
|
||||
void dcn314_init_clocks(struct clk_mgr *clk_mgr);
|
||||
|
||||
void dcn314_update_clocks(struct clk_mgr *clk_mgr_base,
|
||||
struct dc_state *context,
|
||||
bool safe_to_lower);
|
||||
|
|
|
|||
|
|
@ -411,12 +411,9 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
|||
* avoid conflicting with firmware updates.
|
||||
*/
|
||||
if (dc->ctx->dce_version > DCE_VERSION_MAX)
|
||||
if (dc->optimized_required)
|
||||
if (dc->optimized_required || dc->wm_optimized_required)
|
||||
return false;
|
||||
|
||||
if (!memcmp(&stream->adjust, adjust, sizeof(*adjust)))
|
||||
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;
|
||||
|
|
@ -2230,6 +2227,7 @@ void dc_post_update_surfaces_to_stream(struct dc *dc)
|
|||
}
|
||||
|
||||
dc->optimized_required = false;
|
||||
dc->wm_optimized_required = false;
|
||||
}
|
||||
|
||||
bool dc_set_generic_gpio_for_stereo(bool enable,
|
||||
|
|
@ -2652,6 +2650,8 @@ enum surface_update_type dc_check_update_surfaces_for_stream(
|
|||
} else if (memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0) {
|
||||
dc->optimized_required = true;
|
||||
}
|
||||
|
||||
dc->optimized_required |= dc->wm_optimized_required;
|
||||
}
|
||||
|
||||
return type;
|
||||
|
|
@ -2859,6 +2859,9 @@ static void copy_stream_update_to_stream(struct dc *dc,
|
|||
if (update->vrr_active_fixed)
|
||||
stream->vrr_active_fixed = *update->vrr_active_fixed;
|
||||
|
||||
if (update->crtc_timing_adjust)
|
||||
stream->adjust = *update->crtc_timing_adjust;
|
||||
|
||||
if (update->dpms_off)
|
||||
stream->dpms_off = *update->dpms_off;
|
||||
|
||||
|
|
@ -3519,7 +3522,7 @@ static void commit_planes_for_stream(struct dc *dc,
|
|||
top_pipe_to_program = resource_get_otg_master_for_stream(
|
||||
&context->res_ctx,
|
||||
stream);
|
||||
|
||||
ASSERT(top_pipe_to_program != NULL);
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
|
||||
|
|
@ -4288,7 +4291,8 @@ static bool full_update_required(struct dc *dc,
|
|||
stream_update->mst_bw_update ||
|
||||
stream_update->func_shaper ||
|
||||
stream_update->lut3d_func ||
|
||||
stream_update->pending_test_pattern))
|
||||
stream_update->pending_test_pattern ||
|
||||
stream_update->crtc_timing_adjust))
|
||||
return true;
|
||||
|
||||
if (stream) {
|
||||
|
|
@ -4341,6 +4345,8 @@ static bool should_commit_minimal_transition_for_windowed_mpo_odm(struct dc *dc,
|
|||
|
||||
cur_pipe = resource_get_otg_master_for_stream(&dc->current_state->res_ctx, stream);
|
||||
new_pipe = resource_get_otg_master_for_stream(&context->res_ctx, stream);
|
||||
if (!cur_pipe || !new_pipe)
|
||||
return false;
|
||||
cur_is_odm_in_use = resource_get_odm_slice_count(cur_pipe) > 1;
|
||||
new_is_odm_in_use = resource_get_odm_slice_count(new_pipe) > 1;
|
||||
if (cur_is_odm_in_use == new_is_odm_in_use)
|
||||
|
|
|
|||
|
|
@ -2194,6 +2194,10 @@ void resource_log_pipe_topology_update(struct dc *dc, struct dc_state *state)
|
|||
for (stream_idx = 0; stream_idx < state->stream_count; stream_idx++) {
|
||||
otg_master = resource_get_otg_master_for_stream(
|
||||
&state->res_ctx, state->streams[stream_idx]);
|
||||
if (!otg_master || otg_master->stream_res.tg == NULL) {
|
||||
DC_LOG_DC("topology update: otg_master NULL stream_idx %d!\n", stream_idx);
|
||||
return;
|
||||
}
|
||||
slice_count = resource_get_opp_heads_for_otg_master(otg_master,
|
||||
&state->res_ctx, opp_heads);
|
||||
for (slice_idx = 0; slice_idx < slice_count; slice_idx++) {
|
||||
|
|
@ -4986,20 +4990,6 @@ enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,
|
|||
return DC_OK;
|
||||
}
|
||||
|
||||
bool resource_subvp_in_use(struct dc *dc,
|
||||
struct dc_state *context)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (dc_state_get_pipe_subvp_type(context, pipe) != SUBVP_NONE)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool check_subvp_sw_cursor_fallback_req(const struct dc *dc, struct dc_stream_state *stream)
|
||||
{
|
||||
if (!dc->debug.disable_subvp_high_refresh && is_subvp_high_refresh_candidate(stream))
|
||||
|
|
|
|||
|
|
@ -267,7 +267,8 @@ void dc_state_construct(struct dc *dc, struct dc_state *state)
|
|||
state->clk_mgr = dc->clk_mgr;
|
||||
|
||||
/* Initialise DIG link encoder resource tracking variables. */
|
||||
link_enc_cfg_init(dc, state);
|
||||
if (dc->res_pool)
|
||||
link_enc_cfg_init(dc, state);
|
||||
}
|
||||
|
||||
void dc_state_destruct(struct dc_state *state)
|
||||
|
|
@ -433,8 +434,9 @@ bool dc_state_add_plane(
|
|||
|
||||
otg_master_pipe = resource_get_otg_master_for_stream(
|
||||
&state->res_ctx, stream);
|
||||
added = resource_append_dpp_pipes_for_plane_composition(state,
|
||||
dc->current_state, pool, otg_master_pipe, plane_state);
|
||||
if (otg_master_pipe)
|
||||
added = resource_append_dpp_pipes_for_plane_composition(state,
|
||||
dc->current_state, pool, otg_master_pipe, plane_state);
|
||||
|
||||
if (added) {
|
||||
stream_status->plane_states[stream_status->plane_count] =
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ struct aux_payload;
|
|||
struct set_config_cmd_payload;
|
||||
struct dmub_notification;
|
||||
|
||||
#define DC_VER "3.2.265"
|
||||
#define DC_VER "3.2.266"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
|
|
@ -1036,6 +1036,7 @@ struct dc {
|
|||
|
||||
/* Require to optimize clocks and bandwidth for added/removed planes */
|
||||
bool optimized_required;
|
||||
bool wm_optimized_required;
|
||||
bool idle_optimizations_allowed;
|
||||
bool enable_c20_dtm_b0;
|
||||
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ union stream_update_flags {
|
|||
uint32_t wb_update:1;
|
||||
uint32_t dsc_changed : 1;
|
||||
uint32_t mst_bw : 1;
|
||||
uint32_t crtc_timing_adjust : 1;
|
||||
uint32_t fams_changed : 1;
|
||||
} bits;
|
||||
|
||||
|
|
@ -325,6 +326,7 @@ struct dc_stream_update {
|
|||
struct dc_3dlut *lut3d_func;
|
||||
|
||||
struct test_pattern *pending_test_pattern;
|
||||
struct dc_crtc_timing_adjust *crtc_timing_adjust;
|
||||
};
|
||||
|
||||
bool dc_is_stream_unchanged(
|
||||
|
|
|
|||
|
|
@ -1140,23 +1140,25 @@ struct dc_panel_config {
|
|||
} ilr;
|
||||
};
|
||||
|
||||
#define MAX_SINKS_PER_LINK 4
|
||||
|
||||
/*
|
||||
* USB4 DPIA BW ALLOCATION STRUCTS
|
||||
*/
|
||||
struct dc_dpia_bw_alloc {
|
||||
int sink_verified_bw; // The Verified BW that sink can allocated and use that has been verified already
|
||||
int sink_allocated_bw; // The Actual Allocated BW that sink currently allocated
|
||||
int sink_max_bw; // The Max BW that sink can require/support
|
||||
int remote_sink_req_bw[MAX_SINKS_PER_LINK]; // BW requested by remote sinks
|
||||
int link_verified_bw; // The Verified BW that link can allocated and use that has been verified already
|
||||
int link_max_bw; // The Max BW that link can require/support
|
||||
int allocated_bw; // The Actual Allocated BW for this DPIA
|
||||
int estimated_bw; // The estimated available BW for this DPIA
|
||||
int bw_granularity; // BW Granularity
|
||||
int dp_overhead; // DP overhead in dp tunneling
|
||||
bool bw_alloc_enabled; // The BW Alloc Mode Support is turned ON for all 3: DP-Tx & Dpia & CM
|
||||
bool response_ready; // Response ready from the CM side
|
||||
uint8_t nrd_max_lane_count; // Non-reduced max lane count
|
||||
uint8_t nrd_max_link_rate; // Non-reduced max link rate
|
||||
};
|
||||
|
||||
#define MAX_SINKS_PER_LINK 4
|
||||
|
||||
enum dc_hpd_enable_select {
|
||||
HPD_EN_FOR_ALL_EDP = 0,
|
||||
HPD_EN_FOR_PRIMARY_EDP_ONLY,
|
||||
|
|
|
|||
|
|
@ -782,7 +782,7 @@ static void get_azalia_clock_info_dp(
|
|||
/*audio_dto_module = dpDtoSourceClockInkhz * 10,000;
|
||||
* [khz] ->[100Hz] */
|
||||
azalia_clock_info->audio_dto_module =
|
||||
pll_info->dp_dto_source_clock_in_khz * 10;
|
||||
pll_info->audio_dto_source_clock_in_khz * 10;
|
||||
}
|
||||
|
||||
void dce_aud_wall_dto_setup(
|
||||
|
|
|
|||
|
|
@ -975,6 +975,9 @@ static bool dcn31_program_pix_clk(
|
|||
look_up_in_video_optimized_rate_tlb(pix_clk_params->requested_pix_clk_100hz / 10);
|
||||
struct bp_pixel_clock_parameters bp_pc_params = {0};
|
||||
enum transmitter_color_depth bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_24;
|
||||
|
||||
if (clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz != 0)
|
||||
dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz;
|
||||
// For these signal types Driver to program DP_DTO without calling VBIOS Command table
|
||||
if (dc_is_dp_signal(pix_clk_params->signal_type) || dc_is_virtual_signal(pix_clk_params->signal_type)) {
|
||||
if (e) {
|
||||
|
|
@ -1088,6 +1091,10 @@ static bool get_pixel_clk_frequency_100hz(
|
|||
struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source);
|
||||
unsigned int clock_hz = 0;
|
||||
unsigned int modulo_hz = 0;
|
||||
unsigned int dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dprefclk_khz;
|
||||
|
||||
if (clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz != 0)
|
||||
dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz;
|
||||
|
||||
if (clock_source->id == CLOCK_SOURCE_ID_DP_DTO) {
|
||||
clock_hz = REG_READ(PHASE[inst]);
|
||||
|
|
@ -1100,7 +1107,7 @@ static bool get_pixel_clk_frequency_100hz(
|
|||
modulo_hz = REG_READ(MODULO[inst]);
|
||||
if (modulo_hz)
|
||||
*pixel_clk_khz = div_u64((uint64_t)clock_hz*
|
||||
clock_source->ctx->dc->clk_mgr->dprefclk_khz*10,
|
||||
dp_dto_ref_khz*10,
|
||||
modulo_hz);
|
||||
else
|
||||
*pixel_clk_khz = 0;
|
||||
|
|
|
|||
|
|
@ -183,6 +183,20 @@ bool dcn32_all_pipes_have_stream_and_plane(struct dc *dc,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool dcn32_subvp_in_use(struct dc *dc,
|
||||
struct dc_state *context)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (dc_state_get_pipe_subvp_type(context, pipe) != SUBVP_NONE)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dcn32_mpo_in_use(struct dc_state *context)
|
||||
{
|
||||
uint32_t i;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
#include "dcn30/dcn30_resource.h"
|
||||
#include "link.h"
|
||||
#include "dc_state_priv.h"
|
||||
#include "resource.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
||||
|
|
@ -292,7 +291,7 @@ int dcn32_find_dummy_latency_index_for_fw_based_mclk_switch(struct dc *dc,
|
|||
|
||||
/* for subvp + DRR case, if subvp pipes are still present we support pstate */
|
||||
if (vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported &&
|
||||
resource_subvp_in_use(dc, context))
|
||||
dcn32_subvp_in_use(dc, context))
|
||||
vba->DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] = temp_clock_change_support;
|
||||
|
||||
if (vlevel < context->bw_ctx.dml.vba.soc.num_states &&
|
||||
|
|
@ -2273,7 +2272,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
|
|||
unsigned int dummy_latency_index = 0;
|
||||
int maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;
|
||||
unsigned int min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed;
|
||||
bool subvp_active = resource_subvp_in_use(dc, context);
|
||||
bool subvp_in_use = dcn32_subvp_in_use(dc, context);
|
||||
unsigned int min_dram_speed_mts_margin;
|
||||
bool need_fclk_lat_as_dummy = false;
|
||||
bool is_subvp_p_drr = false;
|
||||
|
|
@ -2282,7 +2281,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
|
|||
dc_assert_fp_enabled();
|
||||
|
||||
/* need to find dummy latency index for subvp */
|
||||
if (subvp_active) {
|
||||
if (subvp_in_use) {
|
||||
/* Override DRAMClockChangeSupport for SubVP + DRR case where the DRR cannot switch without stretching it's VBLANK */
|
||||
if (!pstate_en) {
|
||||
context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] = dm_dram_clock_change_vblank_w_mall_sub_vp;
|
||||
|
|
@ -2468,7 +2467,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
|
|||
dc->clk_mgr->bw_params->clk_table.entries[min_dram_speed_mts_offset].memclk_mhz * 16;
|
||||
}
|
||||
|
||||
if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && !subvp_active) {
|
||||
if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && !subvp_in_use) {
|
||||
/* find largest table entry that is lower than dram speed,
|
||||
* but lower than DPM0 still uses DPM0
|
||||
*/
|
||||
|
|
@ -3528,7 +3527,7 @@ void dcn32_set_clock_limits(const struct _vcs_dpi_soc_bounding_box_st *soc_bb)
|
|||
void dcn32_override_min_req_memclk(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
// WA: restrict FPO and SubVP to use first non-strobe mode (DCN32 BW issue)
|
||||
if ((context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || resource_subvp_in_use(dc, context)) &&
|
||||
if ((context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dcn32_subvp_in_use(dc, context)) &&
|
||||
dc->dml.soc.num_chans <= 8) {
|
||||
int num_mclk_levels = dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_memclk_levels;
|
||||
|
||||
|
|
|
|||
|
|
@ -166,9 +166,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = {
|
|||
.num_states = 5,
|
||||
.sr_exit_time_us = 14.0,
|
||||
.sr_enter_plus_exit_time_us = 16.0,
|
||||
.sr_exit_z8_time_us = 525.0,
|
||||
.sr_enter_plus_exit_z8_time_us = 715.0,
|
||||
.fclk_change_latency_us = 20.0,
|
||||
.sr_exit_z8_time_us = 210.0,
|
||||
.sr_enter_plus_exit_z8_time_us = 320.0,
|
||||
.fclk_change_latency_us = 24.0,
|
||||
.usr_retraining_latency_us = 2,
|
||||
.writeback_latency_us = 12.0,
|
||||
|
||||
|
|
|
|||
|
|
@ -6229,7 +6229,7 @@ static void set_calculate_prefetch_schedule_params(struct display_mode_lib_st *m
|
|||
CalculatePrefetchSchedule_params->GPUVMEnable = mode_lib->ms.cache_display_cfg.plane.GPUVMEnable;
|
||||
CalculatePrefetchSchedule_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable;
|
||||
CalculatePrefetchSchedule_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
|
||||
CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
|
||||
CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
|
||||
CalculatePrefetchSchedule_params->DynamicMetadataEnable = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataEnable[k];
|
||||
CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled;
|
||||
CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataLinesBeforeActiveRequired[k];
|
||||
|
|
@ -6329,7 +6329,7 @@ static void dml_prefetch_check(struct display_mode_lib_st *mode_lib)
|
|||
mode_lib->ms.NoOfDPPThisState,
|
||||
mode_lib->ms.dpte_group_bytes,
|
||||
s->HostVMInefficiencyFactor,
|
||||
mode_lib->ms.soc.hostvm_min_page_size_kbytes,
|
||||
mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
|
||||
mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels);
|
||||
|
||||
s->NextMaxVStartup = s->MaxVStartupAllPlanes[j];
|
||||
|
|
@ -6542,7 +6542,7 @@ static void dml_prefetch_check(struct display_mode_lib_st *mode_lib)
|
|||
mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
|
||||
mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels,
|
||||
mode_lib->ms.cache_display_cfg.plane.GPUVMEnable,
|
||||
mode_lib->ms.soc.hostvm_min_page_size_kbytes,
|
||||
mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
|
||||
mode_lib->ms.PDEAndMetaPTEBytesPerFrame[j][k],
|
||||
mode_lib->ms.MetaRowBytes[j][k],
|
||||
mode_lib->ms.DPTEBytesPerRow[j][k],
|
||||
|
|
@ -7687,7 +7687,7 @@ dml_bool_t dml_core_mode_support(struct display_mode_lib_st *mode_lib)
|
|||
CalculateVMRowAndSwath_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
|
||||
CalculateVMRowAndSwath_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
|
||||
CalculateVMRowAndSwath_params->GPUVMMinPageSizeKBytes = mode_lib->ms.cache_display_cfg.plane.GPUVMMinPageSizeKBytes;
|
||||
CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
|
||||
CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
|
||||
CalculateVMRowAndSwath_params->PTEBufferModeOverrideEn = mode_lib->ms.cache_display_cfg.plane.PTEBufferModeOverrideEn;
|
||||
CalculateVMRowAndSwath_params->PTEBufferModeOverrideVal = mode_lib->ms.cache_display_cfg.plane.PTEBufferMode;
|
||||
CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = mode_lib->ms.PTEBufferSizeNotExceededPerState;
|
||||
|
|
@ -7957,7 +7957,7 @@ dml_bool_t dml_core_mode_support(struct display_mode_lib_st *mode_lib)
|
|||
UseMinimumDCFCLK_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
|
||||
UseMinimumDCFCLK_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable;
|
||||
UseMinimumDCFCLK_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes;
|
||||
UseMinimumDCFCLK_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
|
||||
UseMinimumDCFCLK_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
|
||||
UseMinimumDCFCLK_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
|
||||
UseMinimumDCFCLK_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled;
|
||||
UseMinimumDCFCLK_params->ImmediateFlipRequirement = s->ImmediateFlipRequiredFinal;
|
||||
|
|
@ -8699,7 +8699,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
|
|||
CalculateVMRowAndSwath_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
|
||||
CalculateVMRowAndSwath_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels;
|
||||
CalculateVMRowAndSwath_params->GPUVMMinPageSizeKBytes = mode_lib->ms.cache_display_cfg.plane.GPUVMMinPageSizeKBytes;
|
||||
CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
|
||||
CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
|
||||
CalculateVMRowAndSwath_params->PTEBufferModeOverrideEn = mode_lib->ms.cache_display_cfg.plane.PTEBufferModeOverrideEn;
|
||||
CalculateVMRowAndSwath_params->PTEBufferModeOverrideVal = mode_lib->ms.cache_display_cfg.plane.PTEBufferMode;
|
||||
CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = s->dummy_boolean_array[0];
|
||||
|
|
@ -8805,7 +8805,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
|
|||
mode_lib->ms.cache_display_cfg.hw.DPPPerSurface,
|
||||
locals->dpte_group_bytes,
|
||||
s->HostVMInefficiencyFactor,
|
||||
mode_lib->ms.soc.hostvm_min_page_size_kbytes,
|
||||
mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
|
||||
mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels);
|
||||
|
||||
locals->TCalc = 24.0 / locals->DCFCLKDeepSleep;
|
||||
|
|
@ -8995,7 +8995,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
|
|||
CalculatePrefetchSchedule_params->GPUVMEnable = mode_lib->ms.cache_display_cfg.plane.GPUVMEnable;
|
||||
CalculatePrefetchSchedule_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable;
|
||||
CalculatePrefetchSchedule_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels;
|
||||
CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes;
|
||||
CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024;
|
||||
CalculatePrefetchSchedule_params->DynamicMetadataEnable = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataEnable[k];
|
||||
CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled;
|
||||
CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataLinesBeforeActiveRequired[k];
|
||||
|
|
@ -9240,7 +9240,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
|
|||
mode_lib->ms.cache_display_cfg.plane.HostVMEnable,
|
||||
mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels,
|
||||
mode_lib->ms.cache_display_cfg.plane.GPUVMEnable,
|
||||
mode_lib->ms.soc.hostvm_min_page_size_kbytes,
|
||||
mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024,
|
||||
locals->PDEAndMetaPTEBytesFrame[k],
|
||||
locals->MetaRowByte[k],
|
||||
locals->PixelPTEBytesPerRow[k],
|
||||
|
|
@ -9446,13 +9446,13 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
|
|||
CalculateWatermarks_params->CompressedBufferSizeInkByte = locals->CompressedBufferSizeInkByte;
|
||||
|
||||
// Output
|
||||
CalculateWatermarks_params->Watermark = &s->dummy_watermark; // Watermarks *Watermark
|
||||
CalculateWatermarks_params->DRAMClockChangeSupport = &mode_lib->ms.support.DRAMClockChangeSupport[0];
|
||||
CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = &s->dummy_single_array[0][0]; // dml_float_t *MaxActiveDRAMClockChangeLatencySupported[]
|
||||
CalculateWatermarks_params->SubViewportLinesNeededInMALL = &mode_lib->ms.SubViewportLinesNeededInMALL[j]; // dml_uint_t SubViewportLinesNeededInMALL[]
|
||||
CalculateWatermarks_params->FCLKChangeSupport = &mode_lib->ms.support.FCLKChangeSupport[0];
|
||||
CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &s->dummy_single[0]; // dml_float_t *MaxActiveFCLKChangeLatencySupported
|
||||
CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->ms.support.USRRetrainingSupport[0];
|
||||
CalculateWatermarks_params->Watermark = &locals->Watermark; // Watermarks *Watermark
|
||||
CalculateWatermarks_params->DRAMClockChangeSupport = &locals->DRAMClockChangeSupport;
|
||||
CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = locals->MaxActiveDRAMClockChangeLatencySupported; // dml_float_t *MaxActiveDRAMClockChangeLatencySupported[]
|
||||
CalculateWatermarks_params->SubViewportLinesNeededInMALL = locals->SubViewportLinesNeededInMALL; // dml_uint_t SubViewportLinesNeededInMALL[]
|
||||
CalculateWatermarks_params->FCLKChangeSupport = &locals->FCLKChangeSupport;
|
||||
CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &locals->MaxActiveFCLKChangeLatencySupported; // dml_float_t *MaxActiveFCLKChangeLatencySupported
|
||||
CalculateWatermarks_params->USRRetrainingSupport = &locals->USRRetrainingSupport;
|
||||
|
||||
CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
|
||||
&mode_lib->scratch,
|
||||
|
|
|
|||
|
|
@ -626,8 +626,8 @@ static void populate_dml_output_cfg_from_stream_state(struct dml_output_cfg_st *
|
|||
if (is_dp2p0_output_encoder(pipe))
|
||||
out->OutputEncoder[location] = dml_dp2p0;
|
||||
break;
|
||||
out->OutputEncoder[location] = dml_edp;
|
||||
case SIGNAL_TYPE_EDP:
|
||||
out->OutputEncoder[location] = dml_edp;
|
||||
break;
|
||||
case SIGNAL_TYPE_HDMI_TYPE_A:
|
||||
case SIGNAL_TYPE_DVI_SINGLE_LINK:
|
||||
|
|
|
|||
|
|
@ -1354,7 +1354,7 @@ static void build_audio_output(
|
|||
if (state->clk_mgr &&
|
||||
(pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
|
||||
pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) {
|
||||
audio_output->pll_info.dp_dto_source_clock_in_khz =
|
||||
audio_output->pll_info.audio_dto_source_clock_in_khz =
|
||||
state->clk_mgr->funcs->get_dp_ref_clk_frequency(
|
||||
state->clk_mgr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3076,7 +3076,7 @@ void dcn10_prepare_bandwidth(
|
|||
context,
|
||||
false);
|
||||
|
||||
dc->optimized_required |= hubbub->funcs->program_watermarks(hubbub,
|
||||
dc->wm_optimized_required = hubbub->funcs->program_watermarks(hubbub,
|
||||
&context->bw_ctx.bw.dcn.watermarks,
|
||||
dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
|
||||
true);
|
||||
|
|
|
|||
|
|
@ -1882,42 +1882,6 @@ static void dcn20_program_pipe(
|
|||
}
|
||||
}
|
||||
|
||||
static void update_vmin_vmax_fams(struct dc *dc,
|
||||
struct dc_state *context)
|
||||
{
|
||||
uint32_t i;
|
||||
struct drr_params params = {0};
|
||||
bool subvp_in_use = resource_subvp_in_use(dc, context);
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (resource_is_pipe_type(pipe, OTG_MASTER) &&
|
||||
((subvp_in_use && dc_state_get_pipe_subvp_type(context, pipe) != SUBVP_PHANTOM &&
|
||||
pipe->stream->allow_freesync) || (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && pipe->stream->fpo_in_use))) {
|
||||
if (!pipe->stream->vrr_active_variable && !pipe->stream->vrr_active_fixed) {
|
||||
struct timing_generator *tg = context->res_ctx.pipe_ctx[i].stream_res.tg;
|
||||
|
||||
/* DRR should be configured already if we're in active variable
|
||||
* or active fixed, so only program if we're not in this state
|
||||
*/
|
||||
params.vertical_total_min = pipe->stream->timing.v_total;
|
||||
params.vertical_total_max = pipe->stream->timing.v_total;
|
||||
tg->funcs->set_drr(tg, ¶ms);
|
||||
}
|
||||
} else {
|
||||
if (resource_is_pipe_type(pipe, OTG_MASTER) &&
|
||||
!pipe->stream->vrr_active_variable &&
|
||||
!pipe->stream->vrr_active_fixed) {
|
||||
struct timing_generator *tg = context->res_ctx.pipe_ctx[i].stream_res.tg;
|
||||
params.vertical_total_min = 0;
|
||||
params.vertical_total_max = 0;
|
||||
tg->funcs->set_drr(tg, ¶ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dcn20_program_front_end_for_ctx(
|
||||
struct dc *dc,
|
||||
struct dc_state *context)
|
||||
|
|
@ -1994,7 +1958,6 @@ void dcn20_program_front_end_for_ctx(
|
|||
&& context->res_ctx.pipe_ctx[i].stream)
|
||||
hws->funcs.blank_pixel_data(dc, &context->res_ctx.pipe_ctx[i], true);
|
||||
|
||||
update_vmin_vmax_fams(dc, context);
|
||||
|
||||
/* Disconnect mpcc */
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||
|
|
@ -2196,10 +2159,10 @@ void dcn20_prepare_bandwidth(
|
|||
}
|
||||
|
||||
/* program dchubbub watermarks:
|
||||
* For assigning optimized_required, use |= operator since we don't want
|
||||
* For assigning wm_optimized_required, use |= operator since we don't want
|
||||
* to clear the value if the optimize has not happened yet
|
||||
*/
|
||||
dc->optimized_required |= hubbub->funcs->program_watermarks(hubbub,
|
||||
dc->wm_optimized_required |= hubbub->funcs->program_watermarks(hubbub,
|
||||
&context->bw_ctx.bw.dcn.watermarks,
|
||||
dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
|
||||
false);
|
||||
|
|
@ -2212,10 +2175,10 @@ void dcn20_prepare_bandwidth(
|
|||
if (hubbub->funcs->program_compbuf_size) {
|
||||
if (context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes) {
|
||||
compbuf_size_kb = context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes;
|
||||
dc->optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.dml.ip.min_comp_buffer_size_kbytes);
|
||||
dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.dml.ip.min_comp_buffer_size_kbytes);
|
||||
} else {
|
||||
compbuf_size_kb = context->bw_ctx.bw.dcn.compbuf_size_kb;
|
||||
dc->optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.bw.dcn.compbuf_size_kb);
|
||||
dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.bw.dcn.compbuf_size_kb);
|
||||
}
|
||||
|
||||
hubbub->funcs->program_compbuf_size(hubbub, compbuf_size_kb, false);
|
||||
|
|
|
|||
|
|
@ -333,6 +333,7 @@ struct clk_mgr {
|
|||
bool force_smu_not_present;
|
||||
bool dc_mode_softmax_enabled;
|
||||
int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes
|
||||
int dp_dto_source_clock_in_khz; // Used to program DP DTO with ss adjustment on DCN314
|
||||
int dentist_vco_freq_khz;
|
||||
struct clk_state_registers_and_bypass boot_snapshot;
|
||||
struct clk_bw_params *bw_params;
|
||||
|
|
|
|||
|
|
@ -609,9 +609,6 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy(
|
|||
struct pipe_ctx *sec_pipe,
|
||||
bool odm);
|
||||
|
||||
bool resource_subvp_in_use(struct dc *dc,
|
||||
struct dc_state *context);
|
||||
|
||||
/* A test harness interface that modifies dp encoder resources in the given dc
|
||||
* state and bypasses the need to revalidate. The interface assumes that the
|
||||
* test harness interface is called with pre-validated link config stored in the
|
||||
|
|
|
|||
|
|
@ -900,11 +900,15 @@ bool link_set_dsc_pps_packet(struct pipe_ctx *pipe_ctx, bool enable, bool immedi
|
|||
{
|
||||
struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
DC_LOGGER_INIT(dsc->ctx->logger);
|
||||
|
||||
if (!pipe_ctx->stream->timing.flags.DSC || !dsc)
|
||||
if (!pipe_ctx->stream->timing.flags.DSC)
|
||||
return false;
|
||||
|
||||
if (!dsc)
|
||||
return false;
|
||||
|
||||
DC_LOGGER_INIT(dsc->ctx->logger);
|
||||
|
||||
if (enable) {
|
||||
struct dsc_config dsc_cfg;
|
||||
uint8_t dsc_packed_pps[128];
|
||||
|
|
@ -2005,17 +2009,11 @@ static enum dc_status enable_link_dp(struct dc_state *state,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the link is DP-over-USB4 do the following:
|
||||
* - Train with fallback when enabling DPIA link. Conventional links are
|
||||
/* Train with fallback when enabling DPIA link. Conventional links are
|
||||
* trained with fallback during sink detection.
|
||||
* - Allocate only what the stream needs for bw in Gbps. Inform the CM
|
||||
* in case stream needs more or less bw from what has been allocated
|
||||
* earlier at plug time.
|
||||
*/
|
||||
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
|
||||
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
|
||||
do_fallback = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Temporary w/a to get DP2.0 link rates to work with SST.
|
||||
|
|
@ -2197,6 +2195,32 @@ static enum dc_status enable_link(
|
|||
return status;
|
||||
}
|
||||
|
||||
static bool allocate_usb4_bandwidth_for_stream(struct dc_stream_state *stream, int bw)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool allocate_usb4_bandwidth(struct dc_stream_state *stream)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
int bw = dc_bandwidth_in_kbps_from_timing(&stream->timing,
|
||||
dc_link_get_highest_encoding_format(stream->sink->link));
|
||||
|
||||
ret = allocate_usb4_bandwidth_for_stream(stream, bw);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool deallocate_usb4_bandwidth(struct dc_stream_state *stream)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
ret = allocate_usb4_bandwidth_for_stream(stream, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
|
|
@ -2232,6 +2256,9 @@ void link_set_dpms_off(struct pipe_ctx *pipe_ctx)
|
|||
update_psp_stream_config(pipe_ctx, true);
|
||||
dc->hwss.blank_stream(pipe_ctx);
|
||||
|
||||
if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
|
||||
deallocate_usb4_bandwidth(pipe_ctx->stream);
|
||||
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
deallocate_mst_payload(pipe_ctx);
|
||||
else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
|
||||
|
|
@ -2474,6 +2501,9 @@ void link_set_dpms_on(
|
|||
}
|
||||
}
|
||||
|
||||
if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
|
||||
allocate_usb4_bandwidth(pipe_ctx->stream);
|
||||
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
allocate_mst_payload(pipe_ctx);
|
||||
else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT &&
|
||||
|
|
|
|||
|
|
@ -346,23 +346,61 @@ enum dc_status link_validate_mode_timing(
|
|||
return DC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function calculates the bandwidth required for the stream timing
|
||||
* and aggregates the stream bandwidth for the respective dpia link
|
||||
*
|
||||
* @stream: pointer to the dc_stream_state struct instance
|
||||
* @num_streams: number of streams to be validated
|
||||
*
|
||||
* return: true if validation is succeeded
|
||||
*/
|
||||
bool link_validate_dpia_bandwidth(const struct dc_stream_state *stream, const unsigned int num_streams)
|
||||
{
|
||||
bool ret = true;
|
||||
int bw_needed[MAX_DPIA_NUM];
|
||||
struct dc_link *link[MAX_DPIA_NUM];
|
||||
|
||||
if (!num_streams || num_streams > MAX_DPIA_NUM)
|
||||
return ret;
|
||||
int bw_needed[MAX_DPIA_NUM] = {0};
|
||||
struct dc_link *dpia_link[MAX_DPIA_NUM] = {0};
|
||||
int num_dpias = 0;
|
||||
|
||||
for (uint8_t i = 0; i < num_streams; ++i) {
|
||||
if (stream[i].signal == SIGNAL_TYPE_DISPLAY_PORT) {
|
||||
/* new dpia sst stream, check whether it exceeds max dpia */
|
||||
if (num_dpias >= MAX_DPIA_NUM)
|
||||
return false;
|
||||
|
||||
link[i] = stream[i].link;
|
||||
bw_needed[i] = dc_bandwidth_in_kbps_from_timing(&stream[i].timing,
|
||||
dc_link_get_highest_encoding_format(link[i]));
|
||||
dpia_link[num_dpias] = stream[i].link;
|
||||
bw_needed[num_dpias] = dc_bandwidth_in_kbps_from_timing(&stream[i].timing,
|
||||
dc_link_get_highest_encoding_format(dpia_link[num_dpias]));
|
||||
num_dpias++;
|
||||
} else if (stream[i].signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
|
||||
uint8_t j = 0;
|
||||
/* check whether its a known dpia link */
|
||||
for (; j < num_dpias; ++j) {
|
||||
if (dpia_link[j] == stream[i].link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == num_dpias) {
|
||||
/* new dpia mst stream, check whether it exceeds max dpia */
|
||||
if (num_dpias >= MAX_DPIA_NUM)
|
||||
return false;
|
||||
else {
|
||||
dpia_link[j] = stream[i].link;
|
||||
num_dpias++;
|
||||
}
|
||||
}
|
||||
|
||||
bw_needed[j] += dc_bandwidth_in_kbps_from_timing(&stream[i].timing,
|
||||
dc_link_get_highest_encoding_format(dpia_link[j]));
|
||||
}
|
||||
}
|
||||
|
||||
ret = dpia_validate_usb4_bw(link, bw_needed, num_streams);
|
||||
/* Include dp overheads */
|
||||
for (uint8_t i = 0; i < num_dpias; ++i) {
|
||||
int dp_overhead = 0;
|
||||
|
||||
return ret;
|
||||
dp_overhead = link_dp_dpia_get_dp_overhead_in_dp_tunneling(dpia_link[i]);
|
||||
bw_needed[i] += dp_overhead;
|
||||
}
|
||||
|
||||
return dpia_validate_usb4_bw(dpia_link, bw_needed, num_dpias);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,25 +82,33 @@ bool dpia_query_hpd_status(struct dc_link *link)
|
|||
{
|
||||
union dmub_rb_cmd cmd = {0};
|
||||
struct dc_dmub_srv *dmub_srv = link->ctx->dmub_srv;
|
||||
bool is_hpd_high = false;
|
||||
|
||||
/* prepare QUERY_HPD command */
|
||||
cmd.query_hpd.header.type = DMUB_CMD__QUERY_HPD_STATE;
|
||||
cmd.query_hpd.data.instance = link->link_id.enum_id - ENUM_ID_1;
|
||||
cmd.query_hpd.data.ch_type = AUX_CHANNEL_DPIA;
|
||||
|
||||
/* Return HPD status reported by DMUB if query successfully executed. */
|
||||
if (dc_wake_and_execute_dmub_cmd(dmub_srv->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) &&
|
||||
cmd.query_hpd.data.status == AUX_RET_SUCCESS)
|
||||
is_hpd_high = cmd.query_hpd.data.result;
|
||||
/* Query dpia hpd status from dmub */
|
||||
if (dc_wake_and_execute_dmub_cmd(dmub_srv->ctx, &cmd,
|
||||
DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY) &&
|
||||
cmd.query_hpd.data.status == AUX_RET_SUCCESS) {
|
||||
DC_LOG_DEBUG("%s: for link(%d) dpia(%d) success, current_hpd_status(%d) new_hpd_status(%d)\n",
|
||||
__func__,
|
||||
link->link_index,
|
||||
link->link_id.enum_id - ENUM_ID_1,
|
||||
link->hpd_status,
|
||||
cmd.query_hpd.data.result);
|
||||
link->hpd_status = cmd.query_hpd.data.result;
|
||||
} else {
|
||||
DC_LOG_ERROR("%s: for link(%d) dpia(%d) failed with status(%d), current_hpd_status(%d) new_hpd_status(0)\n",
|
||||
__func__,
|
||||
link->link_index,
|
||||
link->link_id.enum_id - ENUM_ID_1,
|
||||
cmd.query_hpd.data.status,
|
||||
link->hpd_status);
|
||||
link->hpd_status = false;
|
||||
}
|
||||
|
||||
DC_LOG_DEBUG("%s: link(%d) dpia(%d) cmd_status(%d) result(%d)\n",
|
||||
__func__,
|
||||
link->link_index,
|
||||
link->link_id.enum_id - ENUM_ID_1,
|
||||
cmd.query_hpd.data.status,
|
||||
cmd.query_hpd.data.result);
|
||||
|
||||
return is_hpd_high;
|
||||
return link->hpd_status;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,12 +54,18 @@ static bool get_bw_alloc_proceed_flag(struct dc_link *tmp)
|
|||
static void reset_bw_alloc_struct(struct dc_link *link)
|
||||
{
|
||||
link->dpia_bw_alloc_config.bw_alloc_enabled = false;
|
||||
link->dpia_bw_alloc_config.sink_verified_bw = 0;
|
||||
link->dpia_bw_alloc_config.sink_max_bw = 0;
|
||||
link->dpia_bw_alloc_config.link_verified_bw = 0;
|
||||
link->dpia_bw_alloc_config.link_max_bw = 0;
|
||||
link->dpia_bw_alloc_config.allocated_bw = 0;
|
||||
link->dpia_bw_alloc_config.estimated_bw = 0;
|
||||
link->dpia_bw_alloc_config.bw_granularity = 0;
|
||||
link->dpia_bw_alloc_config.dp_overhead = 0;
|
||||
link->dpia_bw_alloc_config.response_ready = false;
|
||||
link->dpia_bw_alloc_config.sink_allocated_bw = 0;
|
||||
link->dpia_bw_alloc_config.nrd_max_lane_count = 0;
|
||||
link->dpia_bw_alloc_config.nrd_max_link_rate = 0;
|
||||
for (int i = 0; i < MAX_SINKS_PER_LINK; i++)
|
||||
link->dpia_bw_alloc_config.remote_sink_req_bw[i] = 0;
|
||||
DC_LOG_DEBUG("reset usb4 bw alloc of link(%d)\n", link->link_index);
|
||||
}
|
||||
|
||||
#define BW_GRANULARITY_0 4 // 0.25 Gbps
|
||||
|
|
@ -210,8 +216,8 @@ static int get_host_router_total_dp_tunnel_bw(const struct dc *dc, uint8_t hr_in
|
|||
link_dpia_primary->dpia_bw_alloc_config.bw_alloc_enabled) &&
|
||||
(link_dpia_secondary->hpd_status &&
|
||||
link_dpia_secondary->dpia_bw_alloc_config.bw_alloc_enabled)) {
|
||||
total_bw += link_dpia_primary->dpia_bw_alloc_config.estimated_bw +
|
||||
link_dpia_secondary->dpia_bw_alloc_config.sink_allocated_bw;
|
||||
total_bw += link_dpia_primary->dpia_bw_alloc_config.estimated_bw +
|
||||
link_dpia_secondary->dpia_bw_alloc_config.allocated_bw;
|
||||
} else if (link_dpia_primary->hpd_status &&
|
||||
link_dpia_primary->dpia_bw_alloc_config.bw_alloc_enabled) {
|
||||
total_bw = link_dpia_primary->dpia_bw_alloc_config.estimated_bw;
|
||||
|
|
@ -264,7 +270,7 @@ static void set_usb4_req_bw_req(struct dc_link *link, int req_bw)
|
|||
|
||||
/* Error check whether requested and allocated are equal */
|
||||
req_bw = requested_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity);
|
||||
if (req_bw == link->dpia_bw_alloc_config.sink_allocated_bw) {
|
||||
if (req_bw == link->dpia_bw_alloc_config.allocated_bw) {
|
||||
DC_LOG_ERROR("%s: Request bw equals to allocated bw for link(%d)\n",
|
||||
__func__, link->link_index);
|
||||
}
|
||||
|
|
@ -387,9 +393,9 @@ void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t res
|
|||
DC_LOG_DEBUG("%s: BW REQ SUCCESS for DP-TX Request for link(%d)\n",
|
||||
__func__, link->link_index);
|
||||
DC_LOG_DEBUG("%s: current allocated_bw(%d), new allocated_bw(%d)\n",
|
||||
__func__, link->dpia_bw_alloc_config.sink_allocated_bw, bw_needed);
|
||||
__func__, link->dpia_bw_alloc_config.allocated_bw, bw_needed);
|
||||
|
||||
link->dpia_bw_alloc_config.sink_allocated_bw = bw_needed;
|
||||
link->dpia_bw_alloc_config.allocated_bw = bw_needed;
|
||||
|
||||
link->dpia_bw_alloc_config.response_ready = true;
|
||||
break;
|
||||
|
|
@ -427,8 +433,8 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea
|
|||
if (link->hpd_status && peak_bw > 0) {
|
||||
|
||||
// If DP over USB4 then we need to check BW allocation
|
||||
link->dpia_bw_alloc_config.sink_max_bw = peak_bw;
|
||||
set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.sink_max_bw);
|
||||
link->dpia_bw_alloc_config.link_max_bw = peak_bw;
|
||||
set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.link_max_bw);
|
||||
|
||||
do {
|
||||
if (timeout > 0)
|
||||
|
|
@ -440,8 +446,8 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea
|
|||
|
||||
if (!timeout)
|
||||
ret = 0;// ERROR TIMEOUT waiting for response for allocating bw
|
||||
else if (link->dpia_bw_alloc_config.sink_allocated_bw > 0)
|
||||
ret = link->dpia_bw_alloc_config.sink_allocated_bw;
|
||||
else if (link->dpia_bw_alloc_config.allocated_bw > 0)
|
||||
ret = link->dpia_bw_alloc_config.allocated_bw;
|
||||
}
|
||||
//2. Cold Unplug
|
||||
else if (!link->hpd_status)
|
||||
|
|
@ -450,7 +456,6 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw)
|
||||
{
|
||||
bool ret = false;
|
||||
|
|
@ -458,7 +463,7 @@ bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int r
|
|||
|
||||
DC_LOG_DEBUG("%s: ENTER: link(%d), hpd_status(%d), current allocated_bw(%d), req_bw(%d)\n",
|
||||
__func__, link->link_index, link->hpd_status,
|
||||
link->dpia_bw_alloc_config.sink_allocated_bw, req_bw);
|
||||
link->dpia_bw_alloc_config.allocated_bw, req_bw);
|
||||
|
||||
if (!get_bw_alloc_proceed_flag(link))
|
||||
goto out;
|
||||
|
|
@ -523,3 +528,30 @@ bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed_per_dpia, const
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int link_dp_dpia_get_dp_overhead_in_dp_tunneling(struct dc_link *link)
|
||||
{
|
||||
int dp_overhead = 0, link_mst_overhead = 0;
|
||||
|
||||
if (!get_bw_alloc_proceed_flag((link)))
|
||||
return dp_overhead;
|
||||
|
||||
/* if its mst link, add MTPH overhead */
|
||||
if ((link->type == dc_connection_mst_branch) &&
|
||||
!link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) {
|
||||
/* For 8b/10b encoding: MTP is 64 time slots long, slot 0 is used for MTPH
|
||||
* MST overhead is 1/64 of link bandwidth (excluding any overhead)
|
||||
*/
|
||||
const struct dc_link_settings *link_cap =
|
||||
dc_link_get_link_cap(link);
|
||||
uint32_t link_bw_in_kbps = (uint32_t)link_cap->link_rate *
|
||||
(uint32_t)link_cap->lane_count *
|
||||
LINK_RATE_REF_FREQ_IN_KHZ * 8;
|
||||
link_mst_overhead = (link_bw_in_kbps / 64) + ((link_bw_in_kbps % 64) ? 1 : 0);
|
||||
}
|
||||
|
||||
/* add all the overheads */
|
||||
dp_overhead = link_mst_overhead;
|
||||
|
||||
return dp_overhead;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,4 +99,13 @@ void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t res
|
|||
*/
|
||||
bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed, const unsigned int num_dpias);
|
||||
|
||||
/*
|
||||
* Obtain all the DP overheads in dp tunneling for the dpia link
|
||||
*
|
||||
* @link: pointer to the dc_link struct instance
|
||||
*
|
||||
* return: DP overheads in DP tunneling
|
||||
*/
|
||||
int link_dp_dpia_get_dp_overhead_in_dp_tunneling(struct dc_link *link);
|
||||
|
||||
#endif /* DC_INC_LINK_DP_DPIA_BW_H_ */
|
||||
|
|
|
|||
|
|
@ -930,8 +930,8 @@ bool edp_get_replay_state(const struct dc_link *link, uint64_t *state)
|
|||
bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state *stream)
|
||||
{
|
||||
/* To-do: Setup Replay */
|
||||
struct dc *dc = link->ctx->dc;
|
||||
struct dmub_replay *replay = dc->res_pool->replay;
|
||||
struct dc *dc;
|
||||
struct dmub_replay *replay;
|
||||
int i;
|
||||
unsigned int panel_inst;
|
||||
struct replay_context replay_context = { 0 };
|
||||
|
|
@ -947,6 +947,10 @@ bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state *stream
|
|||
if (!link)
|
||||
return false;
|
||||
|
||||
dc = link->ctx->dc;
|
||||
|
||||
replay = dc->res_pool->replay;
|
||||
|
||||
if (!replay)
|
||||
return false;
|
||||
|
||||
|
|
@ -975,8 +979,7 @@ bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state *stream
|
|||
|
||||
replay_context.line_time_in_ns = lineTimeInNs;
|
||||
|
||||
if (replay)
|
||||
link->replay_settings.replay_feature_enabled =
|
||||
link->replay_settings.replay_feature_enabled =
|
||||
replay->funcs->replay_copy_settings(replay, link, &replay_context, panel_inst);
|
||||
if (link->replay_settings.replay_feature_enabled) {
|
||||
|
||||
|
|
|
|||
|
|
@ -166,12 +166,6 @@ static bool optc32_disable_crtc(struct timing_generator *optc)
|
|||
{
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
|
||||
/* disable otg request until end of the first line
|
||||
* in the vertical blank region
|
||||
*/
|
||||
REG_UPDATE(OTG_CONTROL,
|
||||
OTG_MASTER_EN, 0);
|
||||
|
||||
REG_UPDATE_5(OPTC_DATA_SOURCE_SELECT,
|
||||
OPTC_SEG0_SRC_SEL, 0xf,
|
||||
OPTC_SEG1_SRC_SEL, 0xf,
|
||||
|
|
@ -179,6 +173,15 @@ static bool optc32_disable_crtc(struct timing_generator *optc)
|
|||
OPTC_SEG3_SRC_SEL, 0xf,
|
||||
OPTC_NUM_OF_INPUT_SEGMENT, 0);
|
||||
|
||||
REG_UPDATE(OPTC_MEMORY_CONFIG,
|
||||
OPTC_MEM_SEL, 0);
|
||||
|
||||
/* disable otg request until end of the first line
|
||||
* in the vertical blank region
|
||||
*/
|
||||
REG_UPDATE(OTG_CONTROL,
|
||||
OTG_MASTER_EN, 0);
|
||||
|
||||
REG_UPDATE(CONTROL,
|
||||
VTG0_ENABLE, 0);
|
||||
|
||||
|
|
@ -205,6 +208,13 @@ static void optc32_disable_phantom_otg(struct timing_generator *optc)
|
|||
{
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
|
||||
REG_UPDATE_5(OPTC_DATA_SOURCE_SELECT,
|
||||
OPTC_SEG0_SRC_SEL, 0xf,
|
||||
OPTC_SEG1_SRC_SEL, 0xf,
|
||||
OPTC_SEG2_SRC_SEL, 0xf,
|
||||
OPTC_SEG3_SRC_SEL, 0xf,
|
||||
OPTC_NUM_OF_INPUT_SEGMENT, 0);
|
||||
|
||||
REG_UPDATE(OTG_CONTROL, OTG_MASTER_EN, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,12 +138,6 @@ static bool optc35_disable_crtc(struct timing_generator *optc)
|
|||
{
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
|
||||
/* disable otg request until end of the first line
|
||||
* in the vertical blank region
|
||||
*/
|
||||
REG_UPDATE(OTG_CONTROL,
|
||||
OTG_MASTER_EN, 0);
|
||||
|
||||
REG_UPDATE_5(OPTC_DATA_SOURCE_SELECT,
|
||||
OPTC_SEG0_SRC_SEL, 0xf,
|
||||
OPTC_SEG1_SRC_SEL, 0xf,
|
||||
|
|
@ -151,6 +145,15 @@ static bool optc35_disable_crtc(struct timing_generator *optc)
|
|||
OPTC_SEG3_SRC_SEL, 0xf,
|
||||
OPTC_NUM_OF_INPUT_SEGMENT, 0);
|
||||
|
||||
REG_UPDATE(OPTC_MEMORY_CONFIG,
|
||||
OPTC_MEM_SEL, 0);
|
||||
|
||||
/* disable otg request until end of the first line
|
||||
* in the vertical blank region
|
||||
*/
|
||||
REG_UPDATE(OTG_CONTROL,
|
||||
OTG_MASTER_EN, 0);
|
||||
|
||||
REG_UPDATE(CONTROL,
|
||||
VTG0_ENABLE, 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -1899,7 +1899,7 @@ int dcn32_populate_dml_pipes_from_context(
|
|||
|
||||
static struct dc_cap_funcs cap_funcs = {
|
||||
.get_dcc_compression_cap = dcn20_get_dcc_compression_cap,
|
||||
.get_subvp_en = resource_subvp_in_use,
|
||||
.get_subvp_en = dcn32_subvp_in_use,
|
||||
};
|
||||
|
||||
void dcn32_calculate_wm_and_dlg(struct dc *dc, struct dc_state *context,
|
||||
|
|
|
|||
|
|
@ -131,6 +131,9 @@ void dcn32_merge_pipes_for_subvp(struct dc *dc,
|
|||
bool dcn32_all_pipes_have_stream_and_plane(struct dc *dc,
|
||||
struct dc_state *context);
|
||||
|
||||
bool dcn32_subvp_in_use(struct dc *dc,
|
||||
struct dc_state *context);
|
||||
|
||||
bool dcn32_mpo_in_use(struct dc_state *context);
|
||||
|
||||
bool dcn32_any_surfaces_rotated(struct dc *dc, struct dc_state *context);
|
||||
|
|
|
|||
|
|
@ -1574,7 +1574,7 @@ static void dcn321_destroy_resource_pool(struct resource_pool **pool)
|
|||
|
||||
static struct dc_cap_funcs cap_funcs = {
|
||||
.get_dcc_compression_cap = dcn20_get_dcc_compression_cap,
|
||||
.get_subvp_en = resource_subvp_in_use,
|
||||
.get_subvp_en = dcn32_subvp_in_use,
|
||||
};
|
||||
|
||||
static void dcn321_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ enum audio_dto_source {
|
|||
/* PLL information required for AZALIA DTO calculation */
|
||||
|
||||
struct audio_pll_info {
|
||||
uint32_t dp_dto_source_clock_in_khz;
|
||||
uint32_t audio_dto_source_clock_in_khz;
|
||||
uint32_t feed_back_divider;
|
||||
enum audio_dto_source dto_source;
|
||||
bool ss_enabled;
|
||||
|
|
|
|||
|
|
@ -8707,10 +8707,10 @@
|
|||
#define regBIF_BX1_MM_CFGREGS_CNTL_BASE_IDX 2
|
||||
#define regBIF_BX1_BX_RESET_CNTL 0x00f0
|
||||
#define regBIF_BX1_BX_RESET_CNTL_BASE_IDX 2
|
||||
#define regBIF_BX1_INTERRUPT_CNTL 0x8e11
|
||||
#define regBIF_BX1_INTERRUPT_CNTL_BASE_IDX 5
|
||||
#define regBIF_BX1_INTERRUPT_CNTL2 0x8e12
|
||||
#define regBIF_BX1_INTERRUPT_CNTL2_BASE_IDX 5
|
||||
#define regBIF_BX1_INTERRUPT_CNTL 0x00f1
|
||||
#define regBIF_BX1_INTERRUPT_CNTL_BASE_IDX 2
|
||||
#define regBIF_BX1_INTERRUPT_CNTL2 0x00f2
|
||||
#define regBIF_BX1_INTERRUPT_CNTL2_BASE_IDX 2
|
||||
#define regBIF_BX1_CLKREQB_PAD_CNTL 0x00f8
|
||||
#define regBIF_BX1_CLKREQB_PAD_CNTL_BASE_IDX 2
|
||||
#define regBIF_BX1_BIF_FEATURES_CONTROL_MISC 0x00fb
|
||||
|
|
|
|||
|
|
@ -4349,11 +4349,19 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
|
|||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB, (void *)&value, &size))
|
||||
seq_printf(m, "\t%u mV (VDDNB)\n", value);
|
||||
size = sizeof(uint32_t);
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&query, &size))
|
||||
seq_printf(m, "\t%u.%02u W (average GPU)\n", query >> 8, query & 0xff);
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&query, &size)) {
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
seq_printf(m, "\t%u.%02u W (average SoC including CPU)\n", query >> 8, query & 0xff);
|
||||
else
|
||||
seq_printf(m, "\t%u.%02u W (average SoC)\n", query >> 8, query & 0xff);
|
||||
}
|
||||
size = sizeof(uint32_t);
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER, (void *)&query, &size))
|
||||
seq_printf(m, "\t%u.%02u W (current GPU)\n", query >> 8, query & 0xff);
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER, (void *)&query, &size)) {
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
seq_printf(m, "\t%u.%02u W (current SoC including CPU)\n", query >> 8, query & 0xff);
|
||||
else
|
||||
seq_printf(m, "\t%u.%02u W (current SoC)\n", query >> 8, query & 0xff);
|
||||
}
|
||||
size = sizeof(value);
|
||||
seq_printf(m, "\n");
|
||||
|
||||
|
|
@ -4379,9 +4387,9 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
|
|||
/* VCN clocks */
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VCN_POWER_STATE, (void *)&value, &size)) {
|
||||
if (!value) {
|
||||
seq_printf(m, "VCN: Disabled\n");
|
||||
seq_printf(m, "VCN: Powered down\n");
|
||||
} else {
|
||||
seq_printf(m, "VCN: Enabled\n");
|
||||
seq_printf(m, "VCN: Powered up\n");
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_DCLK, (void *)&value, &size))
|
||||
seq_printf(m, "\t%u MHz (DCLK)\n", value/100);
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_VCLK, (void *)&value, &size))
|
||||
|
|
@ -4393,9 +4401,9 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
|
|||
/* UVD clocks */
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_POWER, (void *)&value, &size)) {
|
||||
if (!value) {
|
||||
seq_printf(m, "UVD: Disabled\n");
|
||||
seq_printf(m, "UVD: Powered down\n");
|
||||
} else {
|
||||
seq_printf(m, "UVD: Enabled\n");
|
||||
seq_printf(m, "UVD: Powered up\n");
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_DCLK, (void *)&value, &size))
|
||||
seq_printf(m, "\t%u MHz (DCLK)\n", value/100);
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_VCLK, (void *)&value, &size))
|
||||
|
|
@ -4407,9 +4415,9 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
|
|||
/* VCE clocks */
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VCE_POWER, (void *)&value, &size)) {
|
||||
if (!value) {
|
||||
seq_printf(m, "VCE: Disabled\n");
|
||||
seq_printf(m, "VCE: Powered down\n");
|
||||
} else {
|
||||
seq_printf(m, "VCE: Enabled\n");
|
||||
seq_printf(m, "VCE: Powered up\n");
|
||||
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VCE_ECCLK, (void *)&value, &size))
|
||||
seq_printf(m, "\t%u MHz (ECCLK)\n", value/100);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ static int get_platform_power_management_table(
|
|||
struct pp_hwmgr *hwmgr,
|
||||
ATOM_Tonga_PPM_Table *atom_ppm_table)
|
||||
{
|
||||
struct phm_ppm_table *ptr = kzalloc(sizeof(ATOM_Tonga_PPM_Table), GFP_KERNEL);
|
||||
struct phm_ppm_table *ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
|
||||
struct phm_ppt_v1_information *pp_table_information =
|
||||
(struct phm_ppt_v1_information *)(hwmgr->pptable);
|
||||
|
||||
|
|
|
|||
|
|
@ -3999,6 +3999,7 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx,
|
|||
uint32_t sclk, mclk, activity_percent;
|
||||
uint32_t offset, val_vid;
|
||||
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
|
||||
struct amdgpu_device *adev = hwmgr->adev;
|
||||
|
||||
/* size must be at least 4 bytes for all sensors */
|
||||
if (*size < 4)
|
||||
|
|
@ -4042,7 +4043,21 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx,
|
|||
*size = 4;
|
||||
return 0;
|
||||
case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
|
||||
return smu7_get_gpu_power(hwmgr, (uint32_t *)value);
|
||||
if ((adev->asic_type != CHIP_HAWAII) &&
|
||||
(adev->asic_type != CHIP_BONAIRE) &&
|
||||
(adev->asic_type != CHIP_FIJI) &&
|
||||
(adev->asic_type != CHIP_TONGA))
|
||||
return smu7_get_gpu_power(hwmgr, (uint32_t *)value);
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
|
||||
if ((adev->asic_type != CHIP_HAWAII) &&
|
||||
(adev->asic_type != CHIP_BONAIRE) &&
|
||||
(adev->asic_type != CHIP_FIJI) &&
|
||||
(adev->asic_type != CHIP_TONGA))
|
||||
return -EOPNOTSUPP;
|
||||
else
|
||||
return smu7_get_gpu_power(hwmgr, (uint32_t *)value);
|
||||
case AMDGPU_PP_SENSOR_VDDGFX:
|
||||
if ((data->vr_config & VRCONF_VDDGFX_MASK) ==
|
||||
(VR_SVI2_PLANE_2 << VRCONF_VDDGFX_SHIFT))
|
||||
|
|
|
|||
|
|
@ -970,7 +970,9 @@ static int smu_v13_0_6_print_clks(struct smu_context *smu, char *buf, int size,
|
|||
if (i < (clocks.num_levels - 1))
|
||||
clk2 = clocks.data[i + 1].clocks_in_khz / 1000;
|
||||
|
||||
if (curr_clk >= clk1 && curr_clk < clk2) {
|
||||
if (curr_clk == clk1) {
|
||||
level = i;
|
||||
} else if (curr_clk >= clk1 && curr_clk < clk2) {
|
||||
level = (curr_clk - clk1) <= (clk2 - curr_clk) ?
|
||||
i :
|
||||
i + 1;
|
||||
|
|
@ -2235,17 +2237,18 @@ static int smu_v13_0_6_mode2_reset(struct smu_context *smu)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
dev_err(adev->dev,
|
||||
"failed to send mode2 message \tparam: 0x%08x error code %d\n",
|
||||
SMU_RESET_MODE_2, ret);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
} while (ret == -ETIME && timeout);
|
||||
|
||||
out:
|
||||
mutex_unlock(&smu->message_lock);
|
||||
|
||||
if (ret)
|
||||
dev_err(adev->dev, "failed to send mode2 reset, error code %d",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user