Merge tag 'amd-drm-next-6.2-2022-11-25' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-6.2-2022-11-25: amdgpu: - Old GCC fix - GFX11 fixes - PSP suspend/resume fix - PCI ref count fix - DC KASAN fix - DCN 3.2.x fixes - Dell platform suspend/resume fixes - DCN 3.1.4 fixes - RAS fixes - SMU 13.x fixes - Flex array changes - VCN 4.0 RAS updates - Add missing licsense to some files - Documentation updates - SR-IOV fixes - DP MST DSC fix amdkfd: - Fix topology locking in error case Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20221125180519.6389-1-alexander.deucher@amd.com
This commit is contained in:
@@ -327,7 +327,6 @@ static void amdgpu_connector_free_edid(struct drm_connector *connector)
|
||||
|
||||
kfree(amdgpu_connector->edid);
|
||||
amdgpu_connector->edid = NULL;
|
||||
drm_connector_update_edid_property(connector, NULL);
|
||||
}
|
||||
|
||||
static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector)
|
||||
|
||||
@@ -4181,21 +4181,15 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
||||
|
||||
r = amdgpu_device_ip_resume(adev);
|
||||
|
||||
/* no matter what r is, always need to properly release full GPU */
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
amdgpu_virt_init_data_exchange(adev);
|
||||
amdgpu_virt_release_full_gpu(adev, true);
|
||||
}
|
||||
|
||||
if (r) {
|
||||
dev_err(adev->dev, "amdgpu_device_ip_resume failed (%d).\n", r);
|
||||
return r;
|
||||
goto exit;
|
||||
}
|
||||
amdgpu_fence_driver_hw_init(adev);
|
||||
|
||||
r = amdgpu_device_ip_late_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
goto exit;
|
||||
|
||||
queue_delayed_work(system_wq, &adev->delayed_init_work,
|
||||
msecs_to_jiffies(AMDGPU_RESUME_MS));
|
||||
@@ -4203,12 +4197,19 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
||||
if (!adev->in_s0ix) {
|
||||
r = amdgpu_amdkfd_resume(adev, adev->in_runpm);
|
||||
if (r)
|
||||
return r;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
amdgpu_virt_init_data_exchange(adev);
|
||||
amdgpu_virt_release_full_gpu(adev, true);
|
||||
}
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Make sure IB tests flushed */
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
amdgpu_irq_gpu_reset_resume_helper(adev);
|
||||
flush_delayed_work(&adev->delayed_init_work);
|
||||
|
||||
if (adev->in_s0ix) {
|
||||
@@ -5045,6 +5046,8 @@ static void amdgpu_device_resume_display_audio(struct amdgpu_device *adev)
|
||||
pm_runtime_enable(&(p->dev));
|
||||
pm_runtime_resume(&(p->dev));
|
||||
}
|
||||
|
||||
pci_dev_put(p);
|
||||
}
|
||||
|
||||
static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
|
||||
@@ -5083,6 +5086,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
|
||||
|
||||
if (expires < ktime_get_mono_fast_ns()) {
|
||||
dev_warn(adev->dev, "failed to suspend display audio\n");
|
||||
pci_dev_put(p);
|
||||
/* TODO: abort the succeeding gpu reset? */
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
@@ -5090,6 +5094,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
|
||||
|
||||
pm_runtime_disable(&(p->dev));
|
||||
|
||||
pci_dev_put(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1702,11 +1702,13 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
static void amdgpu_discovery_set_sriov_display(struct amdgpu_device *adev)
|
||||
{
|
||||
amdgpu_device_set_sriov_virtual_display(adev);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
|
||||
{
|
||||
|
||||
@@ -238,8 +238,7 @@ module_param_named(gartsize, amdgpu_gart_size, uint, 0600);
|
||||
|
||||
/**
|
||||
* DOC: gttsize (int)
|
||||
* Restrict the size of GTT domain in MiB for testing. The default is -1 (It's VRAM size if 3GB < VRAM < 3/4 RAM,
|
||||
* otherwise 3/4 RAM size).
|
||||
* Restrict the size of GTT domain in MiB for testing. The default is -1 (Use 1/2 RAM, minimum value is 3GB).
|
||||
*/
|
||||
MODULE_PARM_DESC(gttsize, "Size of the GTT domain in megabytes (-1 = auto)");
|
||||
module_param_named(gttsize, amdgpu_gtt_size, int, 0600);
|
||||
|
||||
@@ -479,6 +479,12 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
|
||||
unsigned i;
|
||||
unsigned vmhub, inv_eng;
|
||||
|
||||
if (adev->enable_mes) {
|
||||
/* reserve engine 5 for firmware */
|
||||
for (vmhub = 0; vmhub < AMDGPU_MAX_VMHUBS; vmhub++)
|
||||
vm_inv_engs[vmhub] &= ~(1 << 5);
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->num_rings; ++i) {
|
||||
ring = adev->rings[i];
|
||||
vmhub = ring->funcs->vmhub;
|
||||
|
||||
@@ -174,7 +174,12 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
|
||||
drm_sched_job_cleanup(s_job);
|
||||
|
||||
amdgpu_sync_free(&job->explicit_sync);
|
||||
dma_fence_put(&job->hw_fence);
|
||||
|
||||
/* only put the hw fence if has embedded fence */
|
||||
if (!job->hw_fence.ops)
|
||||
kfree(job);
|
||||
else
|
||||
dma_fence_put(&job->hw_fence);
|
||||
}
|
||||
|
||||
void amdgpu_job_set_gang_leader(struct amdgpu_job *job,
|
||||
|
||||
@@ -198,6 +198,7 @@ void psp_ta_free_shared_buf(struct ta_mem_context *mem_ctx)
|
||||
{
|
||||
amdgpu_bo_free_kernel(&mem_ctx->shared_bo, &mem_ctx->shared_mc_addr,
|
||||
&mem_ctx->shared_buf);
|
||||
mem_ctx->shared_bo = NULL;
|
||||
}
|
||||
|
||||
static void psp_free_shared_bufs(struct psp_context *psp)
|
||||
@@ -208,6 +209,7 @@ static void psp_free_shared_bufs(struct psp_context *psp)
|
||||
/* free TMR memory buffer */
|
||||
pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
|
||||
amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, pptr);
|
||||
psp->tmr_bo = NULL;
|
||||
|
||||
/* free xgmi shared memory */
|
||||
psp_ta_free_shared_buf(&psp->xgmi_context.context.mem_context);
|
||||
@@ -769,7 +771,7 @@ static int psp_load_toc(struct psp_context *psp,
|
||||
/* Set up Trusted Memory Region */
|
||||
static int psp_tmr_init(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
int tmr_size;
|
||||
void *tmr_buf;
|
||||
void **pptr;
|
||||
@@ -796,10 +798,12 @@ static int psp_tmr_init(struct psp_context *psp)
|
||||
}
|
||||
}
|
||||
|
||||
pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
|
||||
ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&psp->tmr_bo, &psp->tmr_mc_addr, pptr);
|
||||
if (!psp->tmr_bo) {
|
||||
pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
|
||||
ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&psp->tmr_bo, &psp->tmr_mc_addr, pptr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2727,8 +2731,6 @@ static int psp_suspend(void *handle)
|
||||
}
|
||||
|
||||
out:
|
||||
psp_free_shared_bufs(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#define RB_ENABLED (1 << 0)
|
||||
#define RB4_ENABLED (1 << 1)
|
||||
#define MMSCH_DOORBELL_OFFSET 0x8
|
||||
|
||||
#define MMSCH_VF_ENGINE_STATUS__PASS 0x1
|
||||
|
||||
|
||||
@@ -770,6 +770,33 @@ static void vcn_v2_5_enable_clock_gating(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
static void vcn_v2_6_enable_ras(struct amdgpu_device *adev, int inst_idx,
|
||||
bool indirect)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
if (adev->ip_versions[UVD_HWIP][0] != IP_VERSION(2, 6, 0))
|
||||
return;
|
||||
|
||||
tmp = VCN_RAS_CNTL__VCPU_VCODEC_REARM_MASK |
|
||||
VCN_RAS_CNTL__VCPU_VCODEC_IH_EN_MASK |
|
||||
VCN_RAS_CNTL__VCPU_VCODEC_PMI_EN_MASK |
|
||||
VCN_RAS_CNTL__VCPU_VCODEC_STALL_EN_MASK;
|
||||
WREG32_SOC15_DPG_MODE(inst_idx,
|
||||
SOC15_DPG_MODE_OFFSET(VCN, 0, mmVCN_RAS_CNTL),
|
||||
tmp, 0, indirect);
|
||||
|
||||
tmp = UVD_VCPU_INT_EN__RASCNTL_VCPU_VCODEC_EN_MASK;
|
||||
WREG32_SOC15_DPG_MODE(inst_idx,
|
||||
SOC15_DPG_MODE_OFFSET(VCN, 0, mmUVD_VCPU_INT_EN),
|
||||
tmp, 0, indirect);
|
||||
|
||||
tmp = UVD_SYS_INT_EN__RASCNTL_VCPU_VCODEC_EN_MASK;
|
||||
WREG32_SOC15_DPG_MODE(inst_idx,
|
||||
SOC15_DPG_MODE_OFFSET(VCN, 0, mmUVD_SYS_INT_EN),
|
||||
tmp, 0, indirect);
|
||||
}
|
||||
|
||||
static int vcn_v2_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
|
||||
{
|
||||
volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
|
||||
@@ -849,6 +876,8 @@ static int vcn_v2_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, boo
|
||||
WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
|
||||
VCN, 0, mmUVD_LMI_CTRL2), 0, 0, indirect);
|
||||
|
||||
vcn_v2_6_enable_ras(adev, inst_idx, indirect);
|
||||
|
||||
/* unblock VCPU register access */
|
||||
WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
|
||||
VCN, 0, mmUVD_RB_ARB_CTRL), 0, 0, indirect);
|
||||
|
||||
@@ -103,7 +103,6 @@ static int vcn_v4_0_sw_init(void *handle)
|
||||
struct amdgpu_ring *ring;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int i, r;
|
||||
int vcn_doorbell_index = 0;
|
||||
|
||||
r = amdgpu_vcn_sw_init(adev);
|
||||
if (r)
|
||||
@@ -115,12 +114,6 @@ static int vcn_v4_0_sw_init(void *handle)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
vcn_doorbell_index = adev->doorbell_index.vcn.vcn_ring0_1 - MMSCH_DOORBELL_OFFSET;
|
||||
/* get DWORD offset */
|
||||
vcn_doorbell_index = vcn_doorbell_index << 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
|
||||
volatile struct amdgpu_vcn4_fw_shared *fw_shared;
|
||||
|
||||
@@ -144,7 +137,7 @@ static int vcn_v4_0_sw_init(void *handle)
|
||||
ring = &adev->vcn.inst[i].ring_enc[0];
|
||||
ring->use_doorbell = true;
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
ring->doorbell_index = vcn_doorbell_index + i * (adev->vcn.num_enc_rings + 1) + 1;
|
||||
ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + i * (adev->vcn.num_enc_rings + 1) + 1;
|
||||
else
|
||||
ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + 8 * i;
|
||||
|
||||
|
||||
@@ -1805,21 +1805,75 @@ static void kfd_fill_cache_non_crat_info(struct kfd_topology_device *dev, struct
|
||||
pr_debug("Added [%d] GPU cache entries\n", num_of_entries);
|
||||
}
|
||||
|
||||
static int kfd_topology_add_device_locked(struct kfd_dev *gpu, uint32_t gpu_id,
|
||||
struct kfd_topology_device **dev)
|
||||
{
|
||||
int proximity_domain = ++topology_crat_proximity_domain;
|
||||
struct list_head temp_topology_device_list;
|
||||
void *crat_image = NULL;
|
||||
size_t image_size = 0;
|
||||
int res;
|
||||
|
||||
res = kfd_create_crat_image_virtual(&crat_image, &image_size,
|
||||
COMPUTE_UNIT_GPU, gpu,
|
||||
proximity_domain);
|
||||
if (res) {
|
||||
pr_err("Error creating VCRAT for GPU (ID: 0x%x)\n",
|
||||
gpu_id);
|
||||
topology_crat_proximity_domain--;
|
||||
goto err;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&temp_topology_device_list);
|
||||
|
||||
res = kfd_parse_crat_table(crat_image,
|
||||
&temp_topology_device_list,
|
||||
proximity_domain);
|
||||
if (res) {
|
||||
pr_err("Error parsing VCRAT for GPU (ID: 0x%x)\n",
|
||||
gpu_id);
|
||||
topology_crat_proximity_domain--;
|
||||
goto err;
|
||||
}
|
||||
|
||||
kfd_topology_update_device_list(&temp_topology_device_list,
|
||||
&topology_device_list);
|
||||
|
||||
*dev = kfd_assign_gpu(gpu);
|
||||
if (WARN_ON(!*dev)) {
|
||||
res = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Fill the cache affinity information here for the GPUs
|
||||
* using VCRAT
|
||||
*/
|
||||
kfd_fill_cache_non_crat_info(*dev, gpu);
|
||||
|
||||
/* Update the SYSFS tree, since we added another topology
|
||||
* device
|
||||
*/
|
||||
res = kfd_topology_update_sysfs();
|
||||
if (!res)
|
||||
sys_props.generation_count++;
|
||||
else
|
||||
pr_err("Failed to update GPU (ID: 0x%x) to sysfs topology. res=%d\n",
|
||||
gpu_id, res);
|
||||
|
||||
err:
|
||||
kfd_destroy_crat_image(crat_image);
|
||||
return res;
|
||||
}
|
||||
|
||||
int kfd_topology_add_device(struct kfd_dev *gpu)
|
||||
{
|
||||
uint32_t gpu_id;
|
||||
struct kfd_topology_device *dev;
|
||||
struct kfd_cu_info cu_info;
|
||||
int res = 0;
|
||||
struct list_head temp_topology_device_list;
|
||||
void *crat_image = NULL;
|
||||
size_t image_size = 0;
|
||||
int proximity_domain;
|
||||
int i;
|
||||
const char *asic_name = amdgpu_asic_name[gpu->adev->asic_type];
|
||||
|
||||
INIT_LIST_HEAD(&temp_topology_device_list);
|
||||
|
||||
gpu_id = kfd_generate_gpu_id(gpu);
|
||||
pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id);
|
||||
|
||||
@@ -1831,54 +1885,11 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
|
||||
*/
|
||||
down_write(&topology_lock);
|
||||
dev = kfd_assign_gpu(gpu);
|
||||
if (!dev) {
|
||||
proximity_domain = ++topology_crat_proximity_domain;
|
||||
|
||||
res = kfd_create_crat_image_virtual(&crat_image, &image_size,
|
||||
COMPUTE_UNIT_GPU, gpu,
|
||||
proximity_domain);
|
||||
if (res) {
|
||||
pr_err("Error creating VCRAT for GPU (ID: 0x%x)\n",
|
||||
gpu_id);
|
||||
topology_crat_proximity_domain--;
|
||||
return res;
|
||||
}
|
||||
|
||||
res = kfd_parse_crat_table(crat_image,
|
||||
&temp_topology_device_list,
|
||||
proximity_domain);
|
||||
if (res) {
|
||||
pr_err("Error parsing VCRAT for GPU (ID: 0x%x)\n",
|
||||
gpu_id);
|
||||
topology_crat_proximity_domain--;
|
||||
goto err;
|
||||
}
|
||||
|
||||
kfd_topology_update_device_list(&temp_topology_device_list,
|
||||
&topology_device_list);
|
||||
|
||||
dev = kfd_assign_gpu(gpu);
|
||||
if (WARN_ON(!dev)) {
|
||||
res = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Fill the cache affinity information here for the GPUs
|
||||
* using VCRAT
|
||||
*/
|
||||
kfd_fill_cache_non_crat_info(dev, gpu);
|
||||
|
||||
/* Update the SYSFS tree, since we added another topology
|
||||
* device
|
||||
*/
|
||||
res = kfd_topology_update_sysfs();
|
||||
if (!res)
|
||||
sys_props.generation_count++;
|
||||
else
|
||||
pr_err("Failed to update GPU (ID: 0x%x) to sysfs topology. res=%d\n",
|
||||
gpu_id, res);
|
||||
}
|
||||
if (!dev)
|
||||
res = kfd_topology_add_device_locked(gpu, gpu_id, &dev);
|
||||
up_write(&topology_lock);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
dev->gpu_id = gpu_id;
|
||||
gpu->id = gpu_id;
|
||||
@@ -2003,8 +2014,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
|
||||
|
||||
if (!res)
|
||||
kfd_notify_gpu_change(gpu_id, 1);
|
||||
err:
|
||||
kfd_destroy_crat_image(crat_image);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -1371,7 +1371,44 @@ static const struct dmi_system_id hpd_disconnect_quirk_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower Plus 7010"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower 7010"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF Plus 7010"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF 7010"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro Plus 7010"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro 7010"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
/* TODO: refactor this from a fixed table to a dynamic option */
|
||||
};
|
||||
|
||||
static void retrieve_dmi_info(struct amdgpu_display_manager *dm)
|
||||
|
||||
@@ -1187,7 +1187,7 @@ static int pre_compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
||||
struct amdgpu_dm_connector *aconnector;
|
||||
struct drm_dp_mst_topology_mgr *mst_mgr;
|
||||
int link_vars_start_index = 0;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < dc_state->stream_count; i++)
|
||||
computed_streams[i] = false;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// This is a stripped-down version of the smu11_driver_if.h file for the relevant DAL interfaces.
|
||||
|
||||
#define SMU11_DRIVER_IF_VERSION 0x40
|
||||
|
||||
@@ -333,8 +333,8 @@ void dcn31_smu_set_zstate_support(struct clk_mgr_internal *clk_mgr, enum dcn_zst
|
||||
(support == DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY))
|
||||
support = DCN_ZSTATE_SUPPORT_DISALLOW;
|
||||
|
||||
|
||||
if (support == DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY)
|
||||
if (support == DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY ||
|
||||
support == DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY)
|
||||
param = 1;
|
||||
else
|
||||
param = 0;
|
||||
|
||||
@@ -346,8 +346,6 @@ void dcn314_smu_set_zstate_support(struct clk_mgr_internal *clk_mgr, enum dcn_zs
|
||||
if (!clk_mgr->smu_present)
|
||||
return;
|
||||
|
||||
// Arg[15:0] = 8/9/0 for Z8/Z9/disallow -> existing bits
|
||||
// Arg[16] = Disallow Z9 -> new bit
|
||||
switch (support) {
|
||||
|
||||
case DCN_ZSTATE_SUPPORT_ALLOW:
|
||||
@@ -366,6 +364,16 @@ void dcn314_smu_set_zstate_support(struct clk_mgr_internal *clk_mgr, enum dcn_zs
|
||||
param = (1 << 10);
|
||||
break;
|
||||
|
||||
case DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY:
|
||||
msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
|
||||
param = (1 << 10) | (1 << 8);
|
||||
break;
|
||||
|
||||
case DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY:
|
||||
msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
|
||||
param = (1 << 8);
|
||||
break;
|
||||
|
||||
default: //DCN_ZSTATE_SUPPORT_UNKNOWN
|
||||
msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
|
||||
param = 0;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// This is a stripped-down version of the smu13_driver_if.h file for the relevant DAL interfaces.
|
||||
|
||||
#define SMU13_DRIVER_IF_VERSION 0x18
|
||||
|
||||
@@ -1192,7 +1192,7 @@ static void disable_vbios_mode_if_required(
|
||||
|
||||
if (pix_clk_100hz != requested_pix_clk_100hz) {
|
||||
core_link_disable_stream(pipe);
|
||||
pipe->stream->dpms_off = true;
|
||||
pipe->stream->dpms_off = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3098,6 +3098,19 @@ static bool update_planes_and_stream_state(struct dc *dc,
|
||||
|
||||
if (update_type == UPDATE_TYPE_FULL) {
|
||||
if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) {
|
||||
/* For phantom pipes we remove and create a new set of phantom pipes
|
||||
* for each full update (because we don't know if we'll need phantom
|
||||
* pipes until after the first round of validation). However, if validation
|
||||
* fails we need to keep the existing phantom pipes (because we don't update
|
||||
* the dc->current_state).
|
||||
*
|
||||
* The phantom stream/plane refcount is decremented for validation because
|
||||
* we assume it'll be removed (the free comes when the dc_state is freed),
|
||||
* but if validation fails we have to increment back the refcount so it's
|
||||
* consistent.
|
||||
*/
|
||||
if (dc->res_pool->funcs->retain_phantom_pipes)
|
||||
dc->res_pool->funcs->retain_phantom_pipes(dc, dc->current_state);
|
||||
BREAK_TO_DEBUGGER();
|
||||
goto fail;
|
||||
}
|
||||
@@ -3740,6 +3753,8 @@ static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
|
||||
|
||||
struct dc_stream_status *cur_stream_status = stream_get_status(dc->current_state, stream);
|
||||
bool force_minimal_pipe_splitting = false;
|
||||
bool subvp_active = false;
|
||||
uint32_t i;
|
||||
|
||||
*is_plane_addition = false;
|
||||
|
||||
@@ -3771,11 +3786,25 @@ static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc,
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (pipe->stream && pipe->stream->mall_stream_config.type != SUBVP_NONE) {
|
||||
subvp_active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* For SubVP when adding or removing planes we need to add a minimal transition
|
||||
* (even when disabling all planes). Whenever disabling a phantom pipe, we
|
||||
* must use the minimal transition path to disable the pipe correctly.
|
||||
*
|
||||
* We want to use the minimal transition whenever subvp is active, not only if
|
||||
* a plane is being added / removed from a subvp stream (MPO plane can be added
|
||||
* to a DRR pipe of SubVP + DRR config, in which case we still want to run through
|
||||
* a min transition to disable subvp.
|
||||
*/
|
||||
if (cur_stream_status && stream->mall_stream_config.type == SUBVP_MAIN) {
|
||||
if (cur_stream_status && subvp_active) {
|
||||
/* determine if minimal transition is required due to SubVP*/
|
||||
if (cur_stream_status->plane_count > surface_count) {
|
||||
force_minimal_pipe_splitting = true;
|
||||
|
||||
@@ -332,9 +332,21 @@ bool dc_stream_set_cursor_attributes(
|
||||
|
||||
dc = stream->ctx->dc;
|
||||
|
||||
if (dc->debug.allow_sw_cursor_fallback && attributes->height * attributes->width * 4 > 16384)
|
||||
if (stream->mall_stream_config.type == SUBVP_MAIN)
|
||||
/* SubVP is not compatible with HW cursor larger than 64 x 64 x 4.
|
||||
* Therefore, if cursor is greater than 64 x 64 x 4, fallback to SW cursor in the following case:
|
||||
* 1. For single display cases, if resolution is >= 5K and refresh rate < 120hz
|
||||
* 2. For multi display cases, if resolution is >= 4K and refresh rate < 120hz
|
||||
*
|
||||
* [< 120hz is a requirement for SubVP configs]
|
||||
*/
|
||||
if (dc->debug.allow_sw_cursor_fallback && attributes->height * attributes->width * 4 > 16384) {
|
||||
if (dc->current_state->stream_count == 1 && stream->timing.v_addressable >= 2880 &&
|
||||
((stream->timing.pix_clk_100hz * 100) / stream->timing.v_total / stream->timing.h_total) < 120)
|
||||
return false;
|
||||
else if (dc->current_state->stream_count > 1 && stream->timing.v_addressable >= 2160 &&
|
||||
((stream->timing.pix_clk_100hz * 100) / stream->timing.v_total / stream->timing.h_total) < 120)
|
||||
return false;
|
||||
}
|
||||
|
||||
stream->cursor_attributes = *attributes;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ struct aux_payload;
|
||||
struct set_config_cmd_payload;
|
||||
struct dmub_notification;
|
||||
|
||||
#define DC_VER "3.2.212"
|
||||
#define DC_VER "3.2.213"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
@@ -267,6 +267,7 @@ struct dc_caps {
|
||||
uint16_t subvp_pstate_allow_width_us;
|
||||
uint16_t subvp_vertical_int_margin_us;
|
||||
bool seamless_odm;
|
||||
uint8_t subvp_drr_vblank_start_margin_us;
|
||||
};
|
||||
|
||||
struct dc_bug_wa {
|
||||
@@ -492,6 +493,8 @@ enum dcn_pwr_state {
|
||||
enum dcn_zstate_support_state {
|
||||
DCN_ZSTATE_SUPPORT_UNKNOWN,
|
||||
DCN_ZSTATE_SUPPORT_ALLOW,
|
||||
DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY,
|
||||
DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY,
|
||||
DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY,
|
||||
DCN_ZSTATE_SUPPORT_DISALLOW,
|
||||
};
|
||||
@@ -849,6 +852,7 @@ struct dc_debug_options {
|
||||
unsigned int force_subvp_num_ways;
|
||||
unsigned int force_mall_ss_num_ways;
|
||||
bool alloc_extra_way_for_cursor;
|
||||
uint32_t subvp_extra_lines;
|
||||
bool force_usr_allow;
|
||||
/* uses value at boot and disables switch */
|
||||
bool disable_dtb_ref_clk_switch;
|
||||
|
||||
@@ -493,6 +493,7 @@ static void populate_subvp_cmd_drr_info(struct dc *dc,
|
||||
|
||||
pipe_data->pipe_config.vblank_data.drr_info.min_vtotal_supported = min_vtotal_supported;
|
||||
pipe_data->pipe_config.vblank_data.drr_info.max_vtotal_supported = max_vtotal_supported;
|
||||
pipe_data->pipe_config.vblank_data.drr_info.drr_vblank_start_margin = dc->caps.subvp_drr_vblank_start_margin_us;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -151,6 +151,20 @@ struct dc_panel_config {
|
||||
bool optimize_edp_link_rate; /* eDP ILR */
|
||||
} ilr;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 padding_bw; // The Padding "Un-used" BW allocated by CM for padding reasons
|
||||
int sink_max_bw; // The Max BW that sink can require/support
|
||||
int estimated_bw; // The estimated available BW for this DPIA
|
||||
int bw_granularity; // BW Granularity
|
||||
bool bw_alloc_enabled; // The BW Alloc Mode Support is turned ON for all 3: DP-Tx & Dpia & CM
|
||||
};
|
||||
|
||||
/*
|
||||
* A link contains one or more sinks and their connected status.
|
||||
* The currently active signal type (HDMI, DP-SST, DP-MST) is also reported.
|
||||
|
||||
@@ -144,7 +144,7 @@ struct test_pattern {
|
||||
unsigned int cust_pattern_size;
|
||||
};
|
||||
|
||||
#define SUBVP_DRR_MARGIN_US 500 // 500us for DRR margin (SubVP + DRR)
|
||||
#define SUBVP_DRR_MARGIN_US 600 // 600us for DRR margin (SubVP + DRR)
|
||||
|
||||
enum mall_stream_type {
|
||||
SUBVP_NONE, // subvp not in use
|
||||
|
||||
@@ -1561,8 +1561,13 @@ static enum dc_status apply_single_controller_ctx_to_hw(
|
||||
|
||||
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != NULL;
|
||||
|
||||
pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false;
|
||||
|
||||
/* Phantom and main stream share the same link (because the stream
|
||||
* is constructed with the same sink). Make sure not to override
|
||||
* and link programming on the main.
|
||||
*/
|
||||
if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) {
|
||||
pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false;
|
||||
}
|
||||
return DC_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -359,7 +359,8 @@ static const struct dce_audio_registers audio_regs[] = {
|
||||
audio_regs(2),
|
||||
audio_regs(3),
|
||||
audio_regs(4),
|
||||
audio_regs(5)
|
||||
audio_regs(5),
|
||||
audio_regs(6),
|
||||
};
|
||||
|
||||
#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
|
||||
|
||||
@@ -436,34 +436,48 @@ void dpp1_set_cursor_position(
|
||||
uint32_t height)
|
||||
{
|
||||
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
|
||||
int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x;
|
||||
int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
|
||||
int x_pos = pos->x - param->viewport.x;
|
||||
int y_pos = pos->y - param->viewport.y;
|
||||
int x_hotspot = pos->x_hotspot;
|
||||
int y_hotspot = pos->y_hotspot;
|
||||
int src_x_offset = x_pos - pos->x_hotspot;
|
||||
int src_y_offset = y_pos - pos->y_hotspot;
|
||||
int cursor_height = (int)height;
|
||||
int cursor_width = (int)width;
|
||||
uint32_t cur_en = pos->enable ? 1 : 0;
|
||||
|
||||
// Cursor width/height and hotspots need to be rotated for offset calculation
|
||||
// Transform cursor width / height and hotspots for offset calculations
|
||||
if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) {
|
||||
swap(width, height);
|
||||
swap(cursor_height, cursor_width);
|
||||
swap(x_hotspot, y_hotspot);
|
||||
|
||||
if (param->rotation == ROTATION_ANGLE_90) {
|
||||
src_x_offset = pos->x - pos->y_hotspot - param->viewport.x;
|
||||
src_y_offset = pos->y - pos->x_hotspot - param->viewport.y;
|
||||
// hotspot = (-y, x)
|
||||
src_x_offset = x_pos - (cursor_width - x_hotspot);
|
||||
src_y_offset = y_pos - y_hotspot;
|
||||
} else if (param->rotation == ROTATION_ANGLE_270) {
|
||||
// hotspot = (y, -x)
|
||||
src_x_offset = x_pos - x_hotspot;
|
||||
src_y_offset = y_pos - (cursor_height - y_hotspot);
|
||||
}
|
||||
} else if (param->rotation == ROTATION_ANGLE_180) {
|
||||
// hotspot = (-x, -y)
|
||||
if (!param->mirror)
|
||||
src_x_offset = pos->x - param->viewport.x;
|
||||
src_x_offset = x_pos - (cursor_width - x_hotspot);
|
||||
|
||||
src_y_offset = pos->y - param->viewport.y;
|
||||
src_y_offset = y_pos - (cursor_height - y_hotspot);
|
||||
}
|
||||
|
||||
if (src_x_offset >= (int)param->viewport.width)
|
||||
cur_en = 0; /* not visible beyond right edge*/
|
||||
|
||||
if (src_x_offset + (int)width <= 0)
|
||||
if (src_x_offset + cursor_width <= 0)
|
||||
cur_en = 0; /* not visible beyond left edge*/
|
||||
|
||||
if (src_y_offset >= (int)param->viewport.height)
|
||||
cur_en = 0; /* not visible beyond bottom edge*/
|
||||
|
||||
if (src_y_offset + (int)height <= 0)
|
||||
if (src_y_offset + cursor_height <= 0)
|
||||
cur_en = 0; /* not visible beyond top edge*/
|
||||
|
||||
REG_UPDATE(CURSOR0_CONTROL,
|
||||
|
||||
@@ -1179,10 +1179,12 @@ void hubp1_cursor_set_position(
|
||||
const struct dc_cursor_mi_param *param)
|
||||
{
|
||||
struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
|
||||
int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x;
|
||||
int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
|
||||
int x_pos = pos->x - param->viewport.x;
|
||||
int y_pos = pos->y - param->viewport.y;
|
||||
int x_hotspot = pos->x_hotspot;
|
||||
int y_hotspot = pos->y_hotspot;
|
||||
int src_x_offset = x_pos - pos->x_hotspot;
|
||||
int src_y_offset = y_pos - pos->y_hotspot;
|
||||
int cursor_height = (int)hubp->curs_attr.height;
|
||||
int cursor_width = (int)hubp->curs_attr.width;
|
||||
uint32_t dst_x_offset;
|
||||
@@ -1200,18 +1202,26 @@ void hubp1_cursor_set_position(
|
||||
if (hubp->curs_attr.address.quad_part == 0)
|
||||
return;
|
||||
|
||||
// Rotated cursor width/height and hotspots tweaks for offset calculation
|
||||
// Transform cursor width / height and hotspots for offset calculations
|
||||
if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) {
|
||||
swap(cursor_height, cursor_width);
|
||||
swap(x_hotspot, y_hotspot);
|
||||
|
||||
if (param->rotation == ROTATION_ANGLE_90) {
|
||||
src_x_offset = pos->x - pos->y_hotspot - param->viewport.x;
|
||||
src_y_offset = pos->y - pos->x_hotspot - param->viewport.y;
|
||||
// hotspot = (-y, x)
|
||||
src_x_offset = x_pos - (cursor_width - x_hotspot);
|
||||
src_y_offset = y_pos - y_hotspot;
|
||||
} else if (param->rotation == ROTATION_ANGLE_270) {
|
||||
// hotspot = (y, -x)
|
||||
src_x_offset = x_pos - x_hotspot;
|
||||
src_y_offset = y_pos - (cursor_height - y_hotspot);
|
||||
}
|
||||
} else if (param->rotation == ROTATION_ANGLE_180) {
|
||||
// hotspot = (-x, -y)
|
||||
if (!param->mirror)
|
||||
src_x_offset = pos->x - param->viewport.x;
|
||||
src_x_offset = x_pos - (cursor_width - x_hotspot);
|
||||
|
||||
src_y_offset = pos->y - param->viewport.y;
|
||||
src_y_offset = y_pos - (cursor_height - y_hotspot);
|
||||
}
|
||||
|
||||
dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
|
||||
@@ -1248,8 +1258,8 @@ void hubp1_cursor_set_position(
|
||||
CURSOR_Y_POSITION, pos->y);
|
||||
|
||||
REG_SET_2(CURSOR_HOT_SPOT, 0,
|
||||
CURSOR_HOT_SPOT_X, x_hotspot,
|
||||
CURSOR_HOT_SPOT_Y, y_hotspot);
|
||||
CURSOR_HOT_SPOT_X, pos->x_hotspot,
|
||||
CURSOR_HOT_SPOT_Y, pos->y_hotspot);
|
||||
|
||||
REG_SET(CURSOR_DST_OFFSET, 0,
|
||||
CURSOR_DST_X_OFFSET, dst_x_offset);
|
||||
|
||||
@@ -2252,6 +2252,12 @@ void dcn10_enable_timing_synchronization(
|
||||
opp = grouped_pipes[i]->stream_res.opp;
|
||||
tg = grouped_pipes[i]->stream_res.tg;
|
||||
tg->funcs->get_otg_active_size(tg, &width, &height);
|
||||
|
||||
if (!tg->funcs->is_tg_enabled(tg)) {
|
||||
DC_SYNC_INFO("Skipping timing sync on disabled OTG\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (opp->funcs->opp_program_dpg_dimensions)
|
||||
opp->funcs->opp_program_dpg_dimensions(opp, width, 2*(height) + 1);
|
||||
}
|
||||
|
||||
@@ -973,10 +973,12 @@ void hubp2_cursor_set_position(
|
||||
const struct dc_cursor_mi_param *param)
|
||||
{
|
||||
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
|
||||
int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x;
|
||||
int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
|
||||
int x_pos = pos->x - param->viewport.x;
|
||||
int y_pos = pos->y - param->viewport.y;
|
||||
int x_hotspot = pos->x_hotspot;
|
||||
int y_hotspot = pos->y_hotspot;
|
||||
int src_x_offset = x_pos - pos->x_hotspot;
|
||||
int src_y_offset = y_pos - pos->y_hotspot;
|
||||
int cursor_height = (int)hubp->curs_attr.height;
|
||||
int cursor_width = (int)hubp->curs_attr.width;
|
||||
uint32_t dst_x_offset;
|
||||
@@ -994,18 +996,26 @@ void hubp2_cursor_set_position(
|
||||
if (hubp->curs_attr.address.quad_part == 0)
|
||||
return;
|
||||
|
||||
// Rotated cursor width/height and hotspots tweaks for offset calculation
|
||||
// Transform cursor width / height and hotspots for offset calculations
|
||||
if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) {
|
||||
swap(cursor_height, cursor_width);
|
||||
swap(x_hotspot, y_hotspot);
|
||||
|
||||
if (param->rotation == ROTATION_ANGLE_90) {
|
||||
src_x_offset = pos->x - pos->y_hotspot - param->viewport.x;
|
||||
src_y_offset = pos->y - pos->x_hotspot - param->viewport.y;
|
||||
// hotspot = (-y, x)
|
||||
src_x_offset = x_pos - (cursor_width - x_hotspot);
|
||||
src_y_offset = y_pos - y_hotspot;
|
||||
} else if (param->rotation == ROTATION_ANGLE_270) {
|
||||
// hotspot = (y, -x)
|
||||
src_x_offset = x_pos - x_hotspot;
|
||||
src_y_offset = y_pos - (cursor_height - y_hotspot);
|
||||
}
|
||||
} else if (param->rotation == ROTATION_ANGLE_180) {
|
||||
// hotspot = (-x, -y)
|
||||
if (!param->mirror)
|
||||
src_x_offset = pos->x - param->viewport.x;
|
||||
src_x_offset = x_pos - (cursor_width - x_hotspot);
|
||||
|
||||
src_y_offset = pos->y - param->viewport.y;
|
||||
src_y_offset = y_pos - (cursor_height - y_hotspot);
|
||||
}
|
||||
|
||||
dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
|
||||
@@ -1042,8 +1052,8 @@ void hubp2_cursor_set_position(
|
||||
CURSOR_Y_POSITION, pos->y);
|
||||
|
||||
REG_SET_2(CURSOR_HOT_SPOT, 0,
|
||||
CURSOR_HOT_SPOT_X, x_hotspot,
|
||||
CURSOR_HOT_SPOT_Y, y_hotspot);
|
||||
CURSOR_HOT_SPOT_X, pos->x_hotspot,
|
||||
CURSOR_HOT_SPOT_Y, pos->y_hotspot);
|
||||
|
||||
REG_SET(CURSOR_DST_OFFSET, 0,
|
||||
CURSOR_DST_X_OFFSET, dst_x_offset);
|
||||
@@ -1052,8 +1062,8 @@ void hubp2_cursor_set_position(
|
||||
hubp->pos.cur_ctl.bits.cur_enable = cur_en;
|
||||
hubp->pos.position.bits.x_pos = pos->x;
|
||||
hubp->pos.position.bits.y_pos = pos->y;
|
||||
hubp->pos.hot_spot.bits.x_hot = x_hotspot;
|
||||
hubp->pos.hot_spot.bits.y_hot = y_hotspot;
|
||||
hubp->pos.hot_spot.bits.x_hot = pos->x_hotspot;
|
||||
hubp->pos.hot_spot.bits.y_hot = pos->y_hotspot;
|
||||
hubp->pos.dst_offset.bits.dst_x_offset = dst_x_offset;
|
||||
/* Cursor Rectangle Cache
|
||||
* Cursor bitmaps have different hotspot values
|
||||
|
||||
@@ -96,6 +96,13 @@ static void dccg314_set_pixel_rate_div(
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
enum pixel_rate_div cur_k1 = PIXEL_RATE_DIV_NA, cur_k2 = PIXEL_RATE_DIV_NA;
|
||||
|
||||
// Don't program 0xF into the register field. Not valid since
|
||||
// K1 / K2 field is only 1 / 2 bits wide
|
||||
if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
|
||||
dccg314_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
|
||||
if (k1 == cur_k1 && k2 == cur_k2)
|
||||
return;
|
||||
|
||||
@@ -348,10 +348,8 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
|
||||
two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing);
|
||||
odm_combine_factor = get_odm_config(pipe_ctx, NULL);
|
||||
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL)
|
||||
return odm_combine_factor;
|
||||
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
*k1_div = PIXEL_RATE_DIV_BY_1;
|
||||
*k2_div = PIXEL_RATE_DIV_BY_1;
|
||||
} else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
|
||||
*k1_div = PIXEL_RATE_DIV_BY_1;
|
||||
@@ -359,7 +357,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
|
||||
*k2_div = PIXEL_RATE_DIV_BY_2;
|
||||
else
|
||||
*k2_div = PIXEL_RATE_DIV_BY_4;
|
||||
} else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
|
||||
} else if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) {
|
||||
if (two_pix_per_container) {
|
||||
*k1_div = PIXEL_RATE_DIV_BY_1;
|
||||
*k2_div = PIXEL_RATE_DIV_BY_2;
|
||||
|
||||
@@ -96,8 +96,10 @@ static void dccg32_set_pixel_rate_div(
|
||||
|
||||
// Don't program 0xF into the register field. Not valid since
|
||||
// K1 / K2 field is only 1 / 2 bits wide
|
||||
if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA)
|
||||
if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
|
||||
BREAK_TO_DEBUGGER();
|
||||
return;
|
||||
}
|
||||
|
||||
dccg32_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
|
||||
if (k1 == cur_k1 && k2 == cur_k2)
|
||||
|
||||
@@ -227,8 +227,13 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
|
||||
/* If PSR is supported on an eDP panel that's connected, but that panel is
|
||||
* not in PSR at the time of trying to enter MALL SS, we have to include it
|
||||
* in the static screen CAB calculation
|
||||
*/
|
||||
if (!pipe->stream || !pipe->plane_state ||
|
||||
pipe->stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED ||
|
||||
(pipe->stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED &&
|
||||
pipe->stream->link->psr_settings.psr_allow_active) ||
|
||||
pipe->stream->mall_stream_config.type == SUBVP_PHANTOM)
|
||||
continue;
|
||||
|
||||
@@ -1170,10 +1175,8 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign
|
||||
two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing);
|
||||
odm_combine_factor = get_odm_config(pipe_ctx, NULL);
|
||||
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL)
|
||||
return odm_combine_factor;
|
||||
|
||||
if (is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
*k1_div = PIXEL_RATE_DIV_BY_1;
|
||||
*k2_div = PIXEL_RATE_DIV_BY_1;
|
||||
} else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
|
||||
*k1_div = PIXEL_RATE_DIV_BY_1;
|
||||
|
||||
@@ -723,7 +723,7 @@ static const struct dc_debug_options debug_defaults_drv = {
|
||||
/* Must match enable_single_display_2to1_odm_policy to support dynamic ODM transitions*/
|
||||
.enable_double_buffered_dsc_pg_support = true,
|
||||
.enable_dp_dig_pixel_rate_div_policy = 1,
|
||||
.allow_sw_cursor_fallback = false,
|
||||
.allow_sw_cursor_fallback = false, // Linux can't do SW cursor "fallback"
|
||||
.alloc_extra_way_for_cursor = true,
|
||||
.min_prefetch_in_strobe_ns = 60000, // 60us
|
||||
};
|
||||
@@ -1721,6 +1721,27 @@ static struct dc_stream_state *dcn32_enable_phantom_stream(struct dc *dc,
|
||||
return phantom_stream;
|
||||
}
|
||||
|
||||
void dcn32_retain_phantom_pipes(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
int i;
|
||||
struct dc_plane_state *phantom_plane = NULL;
|
||||
struct dc_stream_state *phantom_stream = NULL;
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (!pipe->top_pipe && !pipe->prev_odm_pipe &&
|
||||
pipe->plane_state && pipe->stream &&
|
||||
pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
|
||||
phantom_plane = pipe->plane_state;
|
||||
phantom_stream = pipe->stream;
|
||||
|
||||
dc_plane_state_retain(phantom_plane);
|
||||
dc_stream_retain(phantom_stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return true if removed piped from ctx, false otherwise
|
||||
bool dcn32_remove_phantom_pipes(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
@@ -1903,7 +1924,7 @@ int dcn32_populate_dml_pipes_from_context(
|
||||
|
||||
pipes[pipe_cnt].pipe.dest.odm_combine_policy = dm_odm_combine_policy_dal;
|
||||
if (context->stream_count == 1 &&
|
||||
context->stream_status[0].plane_count <= 1 &&
|
||||
context->stream_status[0].plane_count == 1 &&
|
||||
!dc_is_hdmi_signal(res_ctx->pipe_ctx[i].stream->signal) &&
|
||||
is_h_timing_divisible_by_2(res_ctx->pipe_ctx[i].stream) &&
|
||||
pipe->stream->timing.pix_clk_100hz * 100 > DCN3_2_VMIN_DISPCLK_HZ &&
|
||||
@@ -2033,6 +2054,7 @@ static struct resource_funcs dcn32_res_pool_funcs = {
|
||||
.update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
|
||||
.add_phantom_pipes = dcn32_add_phantom_pipes,
|
||||
.remove_phantom_pipes = dcn32_remove_phantom_pipes,
|
||||
.retain_phantom_pipes = dcn32_retain_phantom_pipes,
|
||||
};
|
||||
|
||||
|
||||
@@ -2124,6 +2146,7 @@ static bool dcn32_resource_construct(
|
||||
dc->caps.subvp_swath_height_margin_lines = 16;
|
||||
dc->caps.subvp_pstate_allow_width_us = 20;
|
||||
dc->caps.subvp_vertical_int_margin_us = 30;
|
||||
dc->caps.subvp_drr_vblank_start_margin_us = 100; // 100us margin
|
||||
|
||||
dc->caps.max_slave_planes = 2;
|
||||
dc->caps.max_slave_yuv_planes = 2;
|
||||
|
||||
@@ -83,6 +83,9 @@ bool dcn32_release_post_bldn_3dlut(
|
||||
bool dcn32_remove_phantom_pipes(struct dc *dc,
|
||||
struct dc_state *context);
|
||||
|
||||
void dcn32_retain_phantom_pipes(struct dc *dc,
|
||||
struct dc_state *context);
|
||||
|
||||
void dcn32_add_phantom_pipes(struct dc *dc,
|
||||
struct dc_state *context,
|
||||
display_e2e_pipe_params_st *pipes,
|
||||
|
||||
@@ -111,7 +111,7 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
|
||||
mall_alloc_width_blk_aligned = full_vp_width_blk_aligned;
|
||||
|
||||
/* mall_alloc_height_blk_aligned_l/c = CEILING(sub_vp_height_l/c - 1, blk_height_l/c) + blk_height_l/c */
|
||||
mall_alloc_height_blk_aligned = (pipe->stream->timing.v_addressable - 1 + mblk_height - 1) /
|
||||
mall_alloc_height_blk_aligned = (pipe->plane_res.scl_data.viewport.height - 1 + mblk_height - 1) /
|
||||
mblk_height * mblk_height + mblk_height;
|
||||
|
||||
/* full_mblk_width_ub_l/c = mall_alloc_width_blk_aligned_l/c;
|
||||
|
||||
@@ -721,7 +721,7 @@ static const struct dc_debug_options debug_defaults_drv = {
|
||||
/*must match enable_single_display_2to1_odm_policy to support dynamic ODM transitions*/
|
||||
.enable_double_buffered_dsc_pg_support = true,
|
||||
.enable_dp_dig_pixel_rate_div_policy = 1,
|
||||
.allow_sw_cursor_fallback = false,
|
||||
.allow_sw_cursor_fallback = false, // Linux can't do SW cursor "fallback"
|
||||
.alloc_extra_way_for_cursor = true,
|
||||
.min_prefetch_in_strobe_ns = 60000, // 60us
|
||||
};
|
||||
@@ -1621,6 +1621,7 @@ static struct resource_funcs dcn321_res_pool_funcs = {
|
||||
.update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
|
||||
.add_phantom_pipes = dcn32_add_phantom_pipes,
|
||||
.remove_phantom_pipes = dcn32_remove_phantom_pipes,
|
||||
.retain_phantom_pipes = dcn32_retain_phantom_pipes,
|
||||
};
|
||||
|
||||
|
||||
@@ -1711,6 +1712,7 @@ static bool dcn321_resource_construct(
|
||||
dc->caps.subvp_swath_height_margin_lines = 16;
|
||||
dc->caps.subvp_pstate_allow_width_us = 20;
|
||||
dc->caps.subvp_vertical_int_margin_us = 30;
|
||||
dc->caps.subvp_drr_vblank_start_margin_us = 100; // 100us margin
|
||||
dc->caps.max_slave_planes = 1;
|
||||
dc->caps.max_slave_yuv_planes = 1;
|
||||
dc->caps.max_slave_rgb_planes = 1;
|
||||
|
||||
@@ -949,6 +949,7 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struc
|
||||
int plane_count;
|
||||
int i;
|
||||
unsigned int optimized_min_dst_y_next_start_us;
|
||||
bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > 1000.0;
|
||||
|
||||
plane_count = 0;
|
||||
optimized_min_dst_y_next_start_us = 0;
|
||||
@@ -963,6 +964,8 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struc
|
||||
* 2. single eDP, on link 0, 1 plane and stutter period > 5ms
|
||||
* Z10 only cases:
|
||||
* 1. single eDP, on link 0, 1 plane and stutter period >= 5ms
|
||||
* Z8 cases:
|
||||
* 1. stutter period sufficient
|
||||
* Zstate not allowed cases:
|
||||
* 1. Everything else
|
||||
*/
|
||||
@@ -990,11 +993,14 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struc
|
||||
if (context->bw_ctx.dml.vba.StutterPeriod > 5000.0 || optimized_min_dst_y_next_start_us > 5000)
|
||||
return DCN_ZSTATE_SUPPORT_ALLOW;
|
||||
else if (link->psr_settings.psr_version == DC_PSR_VERSION_1 && !link->panel_config.psr.disable_psr)
|
||||
return DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY;
|
||||
return allow_z8 ? DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY : DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY;
|
||||
else
|
||||
return DCN_ZSTATE_SUPPORT_DISALLOW;
|
||||
} else
|
||||
return allow_z8 ? DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY : DCN_ZSTATE_SUPPORT_DISALLOW;
|
||||
} else if (allow_z8) {
|
||||
return DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY;
|
||||
} else {
|
||||
return DCN_ZSTATE_SUPPORT_DISALLOW;
|
||||
}
|
||||
}
|
||||
|
||||
void dcn20_calculate_dlg_params(
|
||||
|
||||
@@ -149,8 +149,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_14_soc = {
|
||||
.num_states = 5,
|
||||
.sr_exit_time_us = 16.5,
|
||||
.sr_enter_plus_exit_time_us = 18.5,
|
||||
.sr_exit_z8_time_us = 442.0,
|
||||
.sr_enter_plus_exit_z8_time_us = 560.0,
|
||||
.sr_exit_z8_time_us = 280.0,
|
||||
.sr_enter_plus_exit_z8_time_us = 350.0,
|
||||
.writeback_latency_us = 12.0,
|
||||
.dram_channel_width_bytes = 4,
|
||||
.round_trip_ping_latency_dcfclk_cycles = 106,
|
||||
|
||||
@@ -157,7 +157,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = {
|
||||
.dispclk_dppclk_vco_speed_mhz = 4300.0,
|
||||
.do_urgent_latency_adjustment = true,
|
||||
.urgent_latency_adjustment_fabric_clock_component_us = 1.0,
|
||||
.urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
|
||||
.urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
|
||||
};
|
||||
|
||||
void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
|
||||
@@ -211,7 +211,7 @@ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
|
||||
/* 'DalDummyClockChangeLatencyNs' registry key option set to 0x7FFFFFFF can be used to disable Set C for dummy p-state */
|
||||
if (clk_mgr->base.ctx->dc->bb_overrides.dummy_clock_change_latency_ns != 0x7FFFFFFF) {
|
||||
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].valid = true;
|
||||
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 38;
|
||||
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 50;
|
||||
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.fclk_change_latency_us = fclk_change_latency_us;
|
||||
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us;
|
||||
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;
|
||||
@@ -221,7 +221,7 @@ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
|
||||
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz;
|
||||
clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF;
|
||||
clk_mgr->base.bw_params->dummy_pstate_table[0].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[0].memclk_mhz * 16;
|
||||
clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 38;
|
||||
clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 50;
|
||||
clk_mgr->base.bw_params->dummy_pstate_table[1].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[1].memclk_mhz * 16;
|
||||
clk_mgr->base.bw_params->dummy_pstate_table[1].dummy_pstate_latency_us = 9;
|
||||
clk_mgr->base.bw_params->dummy_pstate_table[2].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[2].memclk_mhz * 16;
|
||||
@@ -256,16 +256,24 @@ int dcn32_find_dummy_latency_index_for_fw_based_mclk_switch(struct dc *dc,
|
||||
int vlevel)
|
||||
{
|
||||
const int max_latency_table_entries = 4;
|
||||
const struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
|
||||
struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
|
||||
int dummy_latency_index = 0;
|
||||
enum clock_change_support temp_clock_change_support = vba->DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
|
||||
|
||||
dc_assert_fp_enabled();
|
||||
|
||||
while (dummy_latency_index < max_latency_table_entries) {
|
||||
if (temp_clock_change_support != dm_dram_clock_change_unsupported)
|
||||
vba->DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] = temp_clock_change_support;
|
||||
context->bw_ctx.dml.soc.dram_clock_change_latency_us =
|
||||
dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
|
||||
dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false);
|
||||
|
||||
/* for subvp + DRR case, if subvp pipes are still present we support pstate */
|
||||
if (vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported &&
|
||||
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 &&
|
||||
vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] != dm_dram_clock_change_unsupported)
|
||||
break;
|
||||
@@ -577,6 +585,9 @@ void dcn32_set_phantom_stream_timing(struct dc *dc,
|
||||
num_dpp = vba->NoOfDPP[vba->VoltageLevel][vba->maxMpcComb][vba->pipe_plane[pipe_idx]];
|
||||
phantom_vactive += num_dpp > 1 ? vba->meta_row_height[vba->pipe_plane[pipe_idx]] : 0;
|
||||
|
||||
/* dc->debug.subvp_extra_lines 0 by default*/
|
||||
phantom_vactive += dc->debug.subvp_extra_lines;
|
||||
|
||||
// For backporch of phantom pipe, use vstartup of the main pipe
|
||||
phantom_bp = get_vstartup(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
|
||||
|
||||
@@ -1141,7 +1152,7 @@ static void dcn32_full_validate_bw_helper(struct dc *dc,
|
||||
context->bw_ctx.dml.soc.allow_for_pstate_or_stutter_in_vblank_final ==
|
||||
dm_prefetch_support_uclk_fclk_and_stutter) {
|
||||
context->bw_ctx.dml.soc.allow_for_pstate_or_stutter_in_vblank_final =
|
||||
dm_prefetch_support_stutter;
|
||||
dm_prefetch_support_fclk_and_stutter;
|
||||
/* There are params (such as FabricClock) that need to be recalculated
|
||||
* after validation fails (otherwise it will be 0). Calculation for
|
||||
* phantom vactive requires call into DML, so we must ensure all the
|
||||
@@ -1756,6 +1767,7 @@ bool dcn32_internal_validate_bw(struct dc *dc,
|
||||
if (repopulate_pipes) {
|
||||
int flag_max_mpc_comb = vba->maxMpcComb;
|
||||
int flag_vlevel = vlevel;
|
||||
int i;
|
||||
|
||||
pipe_cnt = dc->res_pool->funcs->populate_dml_pipes(dc, context, pipes, fast_validate);
|
||||
|
||||
@@ -1774,7 +1786,7 @@ bool dcn32_internal_validate_bw(struct dc *dc,
|
||||
flag_max_mpc_comb != context->bw_ctx.dml.vba.maxMpcComb) {
|
||||
/* check the context constructed with pipe split flags is still valid*/
|
||||
bool flags_valid = false;
|
||||
for (int i = flag_vlevel; i < context->bw_ctx.dml.soc.num_states; i++) {
|
||||
for (i = flag_vlevel; i < context->bw_ctx.dml.soc.num_states; i++) {
|
||||
if (vba->ModeSupport[i][flag_max_mpc_comb]) {
|
||||
vba->maxMpcComb = flag_max_mpc_comb;
|
||||
vba->VoltageLevel = i;
|
||||
@@ -1816,14 +1828,38 @@ 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_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 = true;
|
||||
|
||||
dc_assert_fp_enabled();
|
||||
|
||||
// Override DRAMClockChangeSupport for SubVP + DRR case where the DRR cannot switch without stretching it's VBLANK
|
||||
if (!pstate_en && dcn32_subvp_in_use(dc, context)) {
|
||||
context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] = dm_dram_clock_change_vblank_w_mall_sub_vp;
|
||||
pstate_en = true;
|
||||
/* need to find dummy latency index for subvp */
|
||||
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][context->bw_ctx.dml.vba.maxMpcComb] = dm_dram_clock_change_vblank_w_mall_sub_vp;
|
||||
pstate_en = true;
|
||||
is_subvp_p_drr = true;
|
||||
}
|
||||
dummy_latency_index = dcn32_find_dummy_latency_index_for_fw_based_mclk_switch(dc,
|
||||
context, pipes, pipe_cnt, vlevel);
|
||||
|
||||
/* For DCN32/321 need to validate with fclk pstate change latency equal to dummy so prefetch is
|
||||
* scheduled correctly to account for dummy pstate.
|
||||
*/
|
||||
if (context->bw_ctx.dml.soc.fclk_change_latency_us < dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us) {
|
||||
need_fclk_lat_as_dummy = true;
|
||||
context->bw_ctx.dml.soc.fclk_change_latency_us =
|
||||
dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
|
||||
}
|
||||
context->bw_ctx.dml.soc.dram_clock_change_latency_us =
|
||||
dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
|
||||
dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false);
|
||||
if (is_subvp_p_drr) {
|
||||
context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] = dm_dram_clock_change_vblank_w_mall_sub_vp;
|
||||
}
|
||||
}
|
||||
|
||||
context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = false;
|
||||
@@ -1847,9 +1883,11 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
|
||||
/* For DCN32/321 need to validate with fclk pstate change latency equal to dummy so
|
||||
* prefetch is scheduled correctly to account for dummy pstate.
|
||||
*/
|
||||
if (dummy_latency_index == 0)
|
||||
if (context->bw_ctx.dml.soc.fclk_change_latency_us < dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us) {
|
||||
need_fclk_lat_as_dummy = true;
|
||||
context->bw_ctx.dml.soc.fclk_change_latency_us =
|
||||
dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
|
||||
}
|
||||
dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false);
|
||||
maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;
|
||||
dcfclk_from_fw_based_mclk_switching = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
|
||||
@@ -1951,13 +1989,13 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
|
||||
|
||||
if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] ==
|
||||
dm_dram_clock_change_unsupported) {
|
||||
int min_dram_speed_mts_offset = dc->clk_mgr->bw_params->clk_table.num_entries - 1;
|
||||
int min_dram_speed_mts_offset = dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1;
|
||||
|
||||
min_dram_speed_mts =
|
||||
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) {
|
||||
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
|
||||
*/
|
||||
@@ -2037,7 +2075,8 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
|
||||
|
||||
context->perf_params.stutter_period_us = context->bw_ctx.dml.vba.StutterPeriod;
|
||||
|
||||
if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && dummy_latency_index == 0)
|
||||
/* for proper prefetch calculations, if dummy lat > fclk lat, use fclk lat = dummy lat */
|
||||
if (need_fclk_lat_as_dummy)
|
||||
context->bw_ctx.dml.soc.fclk_change_latency_us =
|
||||
dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
|
||||
|
||||
@@ -2050,10 +2089,12 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
|
||||
|
||||
if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
|
||||
dcn30_setup_mclk_switch_using_fw_based_vblank_stretch(dc, context);
|
||||
if (dummy_latency_index == 0)
|
||||
context->bw_ctx.dml.soc.fclk_change_latency_us =
|
||||
dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.fclk_change_latency_us;
|
||||
}
|
||||
|
||||
/* revert fclk lat changes if required */
|
||||
if (need_fclk_lat_as_dummy)
|
||||
context->bw_ctx.dml.soc.fclk_change_latency_us =
|
||||
dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.fclk_change_latency_us;
|
||||
}
|
||||
|
||||
static void dcn32_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
|
||||
|
||||
@@ -670,6 +670,25 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
|
||||
v->cursor_bw[k] = mode_lib->vba.NumberOfCursors[k] * mode_lib->vba.CursorWidth[k][0] * mode_lib->vba.CursorBPP[k][0] / 8 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * mode_lib->vba.VRatio[k];
|
||||
}
|
||||
|
||||
v->NotEnoughDETSwathFillLatencyHiding = dml32_CalculateDETSwathFillLatencyHiding(
|
||||
mode_lib->vba.NumberOfActiveSurfaces,
|
||||
mode_lib->vba.ReturnBW,
|
||||
v->UrgentLatency,
|
||||
mode_lib->vba.SwathHeightY,
|
||||
mode_lib->vba.SwathHeightC,
|
||||
v->swath_width_luma_ub,
|
||||
v->swath_width_chroma_ub,
|
||||
v->BytePerPixelDETY,
|
||||
v->BytePerPixelDETC,
|
||||
mode_lib->vba.DETBufferSizeY,
|
||||
mode_lib->vba.DETBufferSizeC,
|
||||
mode_lib->vba.DPPPerPlane,
|
||||
mode_lib->vba.HTotal,
|
||||
mode_lib->vba.PixelClock,
|
||||
mode_lib->vba.VRatio,
|
||||
mode_lib->vba.VRatioChroma,
|
||||
mode_lib->vba.UsesMALLForPStateChange);
|
||||
|
||||
for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) {
|
||||
v->MaxVStartupLines[k] = ((mode_lib->vba.Interlace[k] &&
|
||||
!mode_lib->vba.ProgressiveToInterlaceUnitInOPP) ?
|
||||
@@ -1664,6 +1683,7 @@ static void mode_support_configuration(struct vba_vars_st *v,
|
||||
&& mode_lib->vba.PTEBufferSizeNotExceeded[i][j] == true
|
||||
&& mode_lib->vba.DCCMetaBufferSizeNotExceeded[i][j] == true
|
||||
&& mode_lib->vba.NonsupportedDSCInputBPC == false
|
||||
&& mode_lib->vba.NotEnoughDETSwathFillLatencyHidingPerState[i][j] == false
|
||||
&& !mode_lib->vba.ExceededMALLSize
|
||||
&& ((mode_lib->vba.HostVMEnable == false
|
||||
&& !mode_lib->vba.ImmediateFlipRequiredFinal)
|
||||
@@ -2286,7 +2306,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
&& (mode_lib->vba.Output[k] == dm_dp || mode_lib->vba.Output[k] == dm_dp2p0
|
||||
|| mode_lib->vba.Output[k] == dm_edp
|
||||
|| mode_lib->vba.Output[k] == dm_hdmi)
|
||||
&& mode_lib->vba.OutputBppPerState[i][k] == 0 && (mode_lib->vba.UsesMALLForPStateChange[k] != dm_use_mall_pstate_change_phantom_pipe)) {
|
||||
&& mode_lib->vba.OutputBppPerState[i][k] == 0) {
|
||||
mode_lib->vba.LinkCapacitySupport[i] = false;
|
||||
}
|
||||
}
|
||||
@@ -3158,6 +3178,25 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
mode_lib->vba.UrgentBurstFactorChroma,
|
||||
mode_lib->vba.UrgentBurstFactorCursor);
|
||||
|
||||
mode_lib->vba.NotEnoughDETSwathFillLatencyHidingPerState[i][j] = dml32_CalculateDETSwathFillLatencyHiding(
|
||||
mode_lib->vba.NumberOfActiveSurfaces,
|
||||
mode_lib->vba.ReturnBWPerState[i][j],
|
||||
mode_lib->vba.UrgLatency[i],
|
||||
mode_lib->vba.SwathHeightYThisState,
|
||||
mode_lib->vba.SwathHeightCThisState,
|
||||
mode_lib->vba.swath_width_luma_ub_this_state,
|
||||
mode_lib->vba.swath_width_chroma_ub_this_state,
|
||||
mode_lib->vba.BytePerPixelInDETY,
|
||||
mode_lib->vba.BytePerPixelInDETC,
|
||||
mode_lib->vba.DETBufferSizeYThisState,
|
||||
mode_lib->vba.DETBufferSizeCThisState,
|
||||
mode_lib->vba.NoOfDPPThisState,
|
||||
mode_lib->vba.HTotal,
|
||||
mode_lib->vba.PixelClock,
|
||||
mode_lib->vba.VRatio,
|
||||
mode_lib->vba.VRatioChroma,
|
||||
mode_lib->vba.UsesMALLForPStateChange);
|
||||
|
||||
v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.VMDataOnlyReturnBWPerState = dml32_get_return_bw_mbps_vm_only(&mode_lib->vba.soc, i,
|
||||
mode_lib->vba.DCFCLKState[i][j], mode_lib->vba.FabricClockPerState[i],
|
||||
mode_lib->vba.DRAMSpeedPerState[i]);
|
||||
|
||||
@@ -6228,3 +6228,72 @@ void dml32_CalculateImmediateFlipBandwithSupport(unsigned int NumberOfActiveSurf
|
||||
*ImmediateFlipBandwidthSupport = (*TotalBandwidth <= ReturnBW);
|
||||
*FractionOfUrgentBandwidth = *TotalBandwidth / ReturnBW;
|
||||
}
|
||||
|
||||
bool dml32_CalculateDETSwathFillLatencyHiding(unsigned int NumberOfActiveSurfaces,
|
||||
double ReturnBW,
|
||||
double UrgentLatency,
|
||||
unsigned int SwathHeightY[],
|
||||
unsigned int SwathHeightC[],
|
||||
unsigned int SwathWidthY[],
|
||||
unsigned int SwathWidthC[],
|
||||
double BytePerPixelInDETY[],
|
||||
double BytePerPixelInDETC[],
|
||||
unsigned int DETBufferSizeY[],
|
||||
unsigned int DETBufferSizeC[],
|
||||
unsigned int NumOfDPP[],
|
||||
unsigned int HTotal[],
|
||||
double PixelClock[],
|
||||
double VRatioY[],
|
||||
double VRatioC[],
|
||||
enum dm_use_mall_for_pstate_change_mode UsesMALLForPStateChange[DC__NUM_DPP__MAX])
|
||||
{
|
||||
int k;
|
||||
double SwathSizeAllSurfaces = 0;
|
||||
double SwathSizeAllSurfacesInFetchTimeUs;
|
||||
double DETSwathLatencyHidingUs;
|
||||
double DETSwathLatencyHidingYUs;
|
||||
double DETSwathLatencyHidingCUs;
|
||||
double SwathSizePerSurfaceY[DC__NUM_DPP__MAX];
|
||||
double SwathSizePerSurfaceC[DC__NUM_DPP__MAX];
|
||||
bool NotEnoughDETSwathFillLatencyHiding = false;
|
||||
|
||||
/* calculate sum of single swath size for all pipes in bytes*/
|
||||
for (k = 0; k < NumberOfActiveSurfaces; k++) {
|
||||
SwathSizePerSurfaceY[k] += SwathHeightY[k] * SwathWidthY[k] * BytePerPixelInDETY[k] * NumOfDPP[k];
|
||||
|
||||
if (SwathHeightC[k] != 0)
|
||||
SwathSizePerSurfaceC[k] += SwathHeightC[k] * SwathWidthC[k] * BytePerPixelInDETC[k] * NumOfDPP[k];
|
||||
else
|
||||
SwathSizePerSurfaceC[k] = 0;
|
||||
|
||||
SwathSizeAllSurfaces += SwathSizePerSurfaceY[k] + SwathSizePerSurfaceC[k];
|
||||
}
|
||||
|
||||
SwathSizeAllSurfacesInFetchTimeUs = SwathSizeAllSurfaces / ReturnBW + UrgentLatency;
|
||||
|
||||
/* ensure all DET - 1 swath can hide a fetch for all surfaces */
|
||||
for (k = 0; k < NumberOfActiveSurfaces; k++) {
|
||||
double LineTime = HTotal[k] / PixelClock[k];
|
||||
|
||||
/* only care if surface is not phantom */
|
||||
if (UsesMALLForPStateChange[k] != dm_use_mall_pstate_change_phantom_pipe) {
|
||||
DETSwathLatencyHidingYUs = (dml_floor(DETBufferSizeY[k] / BytePerPixelInDETY[k] / SwathWidthY[k], 1.0) - SwathHeightY[k]) / VRatioY[k] * LineTime;
|
||||
|
||||
if (SwathHeightC[k] != 0) {
|
||||
DETSwathLatencyHidingCUs = (dml_floor(DETBufferSizeC[k] / BytePerPixelInDETC[k] / SwathWidthC[k], 1.0) - SwathHeightC[k]) / VRatioC[k] * LineTime;
|
||||
|
||||
DETSwathLatencyHidingUs = dml_min(DETSwathLatencyHidingYUs, DETSwathLatencyHidingCUs);
|
||||
} else {
|
||||
DETSwathLatencyHidingUs = DETSwathLatencyHidingYUs;
|
||||
}
|
||||
|
||||
/* DET must be able to hide time to fetch 1 swath for each surface */
|
||||
if (DETSwathLatencyHidingUs < SwathSizeAllSurfacesInFetchTimeUs) {
|
||||
NotEnoughDETSwathFillLatencyHiding = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NotEnoughDETSwathFillLatencyHiding;
|
||||
}
|
||||
|
||||
@@ -1141,4 +1141,22 @@ void dml32_CalculateImmediateFlipBandwithSupport(unsigned int NumberOfActiveSurf
|
||||
double *FractionOfUrgentBandwidth,
|
||||
bool *ImmediateFlipBandwidthSupport);
|
||||
|
||||
bool dml32_CalculateDETSwathFillLatencyHiding(unsigned int NumberOfActiveSurfaces,
|
||||
double ReturnBW,
|
||||
double UrgentLatency,
|
||||
unsigned int SwathHeightY[],
|
||||
unsigned int SwathHeightC[],
|
||||
unsigned int SwathWidthY[],
|
||||
unsigned int SwathWidthC[],
|
||||
double BytePerPixelInDETY[],
|
||||
double BytePerPixelInDETC[],
|
||||
unsigned int DETBufferSizeY[],
|
||||
unsigned int DETBufferSizeC[],
|
||||
unsigned int NumOfDPP[],
|
||||
unsigned int HTotal[],
|
||||
double PixelClock[],
|
||||
double VRatioY[],
|
||||
double VRatioC[],
|
||||
enum dm_use_mall_for_pstate_change_mode UsesMALLForPStateChange[DC__NUM_DPP__MAX]);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -126,9 +126,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
|
||||
.sr_enter_plus_exit_z8_time_us = 320,
|
||||
.writeback_latency_us = 12.0,
|
||||
.round_trip_ping_latency_dcfclk_cycles = 263,
|
||||
.urgent_latency_pixel_data_only_us = 9.35,
|
||||
.urgent_latency_pixel_mixed_with_vm_data_us = 9.35,
|
||||
.urgent_latency_vm_data_only_us = 9.35,
|
||||
.urgent_latency_pixel_data_only_us = 4,
|
||||
.urgent_latency_pixel_mixed_with_vm_data_us = 4,
|
||||
.urgent_latency_vm_data_only_us = 4,
|
||||
.fclk_change_latency_us = 20,
|
||||
.usr_retraining_latency_us = 2,
|
||||
.smn_latency_us = 2,
|
||||
@@ -156,7 +156,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
|
||||
.dispclk_dppclk_vco_speed_mhz = 4300.0,
|
||||
.do_urgent_latency_adjustment = true,
|
||||
.urgent_latency_adjustment_fabric_clock_component_us = 1.0,
|
||||
.urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
|
||||
.urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
|
||||
};
|
||||
|
||||
static void get_optimal_ntuple(struct _vcs_dpi_voltage_scaling_st *entry)
|
||||
|
||||
@@ -1050,6 +1050,7 @@ struct vba_vars_st {
|
||||
double MinFullDETBufferingTime;
|
||||
double AverageReadBandwidthGBytePerSecond;
|
||||
bool FirstMainPlane;
|
||||
bool NotEnoughDETSwathFillLatencyHiding;
|
||||
|
||||
unsigned int ViewportWidthChroma[DC__NUM_DPP__MAX];
|
||||
unsigned int ViewportHeightChroma[DC__NUM_DPP__MAX];
|
||||
@@ -1233,6 +1234,7 @@ struct vba_vars_st {
|
||||
unsigned int BlockWidthC[DC__NUM_DPP__MAX];
|
||||
unsigned int SubViewportLinesNeededInMALL[DC__NUM_DPP__MAX];
|
||||
bool VActiveBandwithSupport[DC__VOLTAGE_STATES][2];
|
||||
bool NotEnoughDETSwathFillLatencyHidingPerState[DC__VOLTAGE_STATES][2];
|
||||
struct dummy_vars dummy_vars;
|
||||
};
|
||||
|
||||
|
||||
@@ -241,6 +241,7 @@ struct resource_funcs {
|
||||
unsigned int index);
|
||||
|
||||
bool (*remove_phantom_pipes)(struct dc *dc, struct dc_state *context);
|
||||
void (*retain_phantom_pipes)(struct dc *dc, struct dc_state *context);
|
||||
void (*get_panel_config_defaults)(struct dc_panel_config *panel_config);
|
||||
};
|
||||
|
||||
|
||||
@@ -83,10 +83,15 @@ static const struct dpp_input_csc_matrix __maybe_unused dpp_input_csc_matrix[] =
|
||||
{COLOR_SPACE_YCBCR709,
|
||||
{0x3265, 0x2000, 0, 0xe6ce, 0xf105, 0x2000, 0xfa01, 0xa7d, 0,
|
||||
0x2000, 0x3b61, 0xe24f} },
|
||||
|
||||
{COLOR_SPACE_YCBCR709_LIMITED,
|
||||
{0x39a6, 0x2568, 0, 0xe0d6, 0xeedd, 0x2568, 0xf925, 0x9a8, 0,
|
||||
0x2568, 0x43ee, 0xdbb2} }
|
||||
0x2568, 0x43ee, 0xdbb2} },
|
||||
{COLOR_SPACE_2020_YCBCR,
|
||||
{0x2F30, 0x2000, 0, 0xE869, 0xEDB7, 0x2000, 0xFABC, 0xBC6, 0,
|
||||
0x2000, 0x3C34, 0xE1E6} },
|
||||
{COLOR_SPACE_2020_RGB_LIMITEDRANGE,
|
||||
{0x35E0, 0x255F, 0, 0xE2B3, 0xEB20, 0x255F, 0xF9FD, 0xB1E, 0,
|
||||
0x255F, 0x44BD, 0xDB43} }
|
||||
};
|
||||
|
||||
struct dpp_grph_csc_adjustment {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
|
||||
/*
|
||||
* Copyright 2022 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
/*********************************************************************/
|
||||
// USB4 DPIA BANDWIDTH ALLOCATION LOGIC
|
||||
/*********************************************************************/
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DC_INC_LINK_DP_DPIA_BW_H_
|
||||
#define DC_INC_LINK_DP_DPIA_BW_H_
|
||||
|
||||
// XXX: TODO: Re-add for Phase 2
|
||||
/* Number of Host Routers per motherboard is 2 and 2 DPIA per host router */
|
||||
#define MAX_HR_NUM 2
|
||||
|
||||
struct dc_host_router_bw_alloc {
|
||||
int max_bw[MAX_HR_NUM]; // The Max BW that each Host Router has available to be shared btw DPIAs
|
||||
int total_estimated_bw[MAX_HR_NUM]; // The Total Verified and available BW that Host Router has
|
||||
};
|
||||
|
||||
/*
|
||||
* Enable BW Allocation Mode Support from the DP-Tx side
|
||||
*
|
||||
* @link: pointer to the dc_link struct instance
|
||||
*
|
||||
* return: SUCCESS or FAILURE
|
||||
*/
|
||||
bool set_dptx_usb4_bw_alloc_support(struct dc_link *link);
|
||||
|
||||
/*
|
||||
* Send a request from DP-Tx requesting to allocate BW remotely after
|
||||
* allocating it locally. This will get processed by CM and a CB function
|
||||
* will be called.
|
||||
*
|
||||
* @link: pointer to the dc_link struct instance
|
||||
* @req_bw: The requested bw in Kbyte to allocated
|
||||
*
|
||||
* return: none
|
||||
*/
|
||||
void set_usb4_req_bw_req(struct dc_link *link, int req_bw);
|
||||
|
||||
/*
|
||||
* CB function for when the status of the Req above is complete. We will
|
||||
* find out the result of allocating on CM and update structs accordingly
|
||||
*
|
||||
* @link: pointer to the dc_link struct instance
|
||||
*
|
||||
* return: none
|
||||
*/
|
||||
void get_usb4_req_bw_resp(struct dc_link *link);
|
||||
|
||||
#endif /* DC_INC_LINK_DP_DPIA_BW_H_ */
|
||||
@@ -1029,13 +1029,14 @@ struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 {
|
||||
uint16_t vtotal;
|
||||
uint16_t htotal;
|
||||
uint8_t vblank_pipe_index;
|
||||
uint8_t padding[2];
|
||||
uint8_t padding[1];
|
||||
struct {
|
||||
uint8_t drr_in_use;
|
||||
uint8_t drr_window_size_ms; // Indicates largest VMIN/VMAX adjustment per frame
|
||||
uint16_t min_vtotal_supported; // Min VTOTAL that supports switching in VBLANK
|
||||
uint16_t max_vtotal_supported; // Max VTOTAL that can support SubVP static scheduling
|
||||
uint8_t use_ramping; // Use ramping or not
|
||||
uint8_t drr_vblank_start_margin;
|
||||
} drr_info; // DRR considered as part of SubVP + VBLANK case
|
||||
} vblank_data;
|
||||
} pipe_config;
|
||||
|
||||
@@ -102,9 +102,18 @@ static const struct abm_parameters abm_settings_config1[abm_defines_max_level] =
|
||||
{0x82, 0x4d, 0x20, 0x00, 0x00, 0xff, 0xb3, 0x70, 0x70, 0xcccc, 0xcccc},
|
||||
};
|
||||
|
||||
static const struct abm_parameters abm_settings_config2[abm_defines_max_level] = {
|
||||
// min_red max_red bright_pos dark_pos bright_gain contrast dev min_knee max_knee blRed blStart
|
||||
{0xf0, 0xbf, 0x20, 0x00, 0x88, 0x99, 0xb3, 0x40, 0xe0, 0x0000, 0xcccc},
|
||||
{0xd8, 0x85, 0x20, 0x00, 0x70, 0x90, 0xa8, 0x40, 0xc8, 0x0700, 0xb333},
|
||||
{0xb8, 0x58, 0x20, 0x00, 0x64, 0x88, 0x78, 0x70, 0xa0, 0x7000, 0x9999},
|
||||
{0x82, 0x40, 0x20, 0x00, 0x00, 0xb8, 0xb3, 0x70, 0x70, 0xc333, 0xb333},
|
||||
};
|
||||
|
||||
static const struct abm_parameters * const abm_settings[] = {
|
||||
abm_settings_config0,
|
||||
abm_settings_config1,
|
||||
abm_settings_config2,
|
||||
};
|
||||
|
||||
#define NUM_AMBI_LEVEL 5
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
#ifndef _dcn_3_0_0_OFFSET_HEADER
|
||||
#define _dcn_3_0_0_OFFSET_HEADER
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
#ifndef _dcn_3_0_0_SH_MASK_HEADER
|
||||
#define _dcn_3_0_0_SH_MASK_HEADER
|
||||
|
||||
|
||||
@@ -993,7 +993,8 @@
|
||||
#define mmUVD_RAS_VCPU_VCODEC_STATUS_BASE_IDX 1
|
||||
#define mmUVD_RAS_MMSCH_FATAL_ERROR 0x0058
|
||||
#define mmUVD_RAS_MMSCH_FATAL_ERROR_BASE_IDX 1
|
||||
|
||||
#define mmVCN_RAS_CNTL 0x04b9
|
||||
#define mmVCN_RAS_CNTL_BASE_IDX 1
|
||||
|
||||
/* JPEG 2_6_0 regs */
|
||||
#define mmUVD_RAS_JPEG0_STATUS 0x0059
|
||||
|
||||
@@ -3618,6 +3618,33 @@
|
||||
#define UVD_RAS_MMSCH_FATAL_ERROR__POISONED_VF_MASK 0x7FFFFFFFL
|
||||
#define UVD_RAS_MMSCH_FATAL_ERROR__POISONED_PF_MASK 0x80000000L
|
||||
|
||||
//VCN 2_6_0 VCN_RAS_CNTL
|
||||
#define VCN_RAS_CNTL__VCPU_VCODEC_IH_EN__SHIFT 0x0
|
||||
#define VCN_RAS_CNTL__MMSCH_FATAL_ERROR_EN__SHIFT 0x1
|
||||
#define VCN_RAS_CNTL__VCPU_VCODEC_PMI_EN__SHIFT 0x4
|
||||
#define VCN_RAS_CNTL__MMSCH_PMI_EN__SHIFT 0x5
|
||||
#define VCN_RAS_CNTL__VCPU_VCODEC_REARM__SHIFT 0x8
|
||||
#define VCN_RAS_CNTL__MMSCH_REARM__SHIFT 0x9
|
||||
#define VCN_RAS_CNTL__VCPU_VCODEC_STALL_EN__SHIFT 0xc
|
||||
#define VCN_RAS_CNTL__VCPU_VCODEC_READY__SHIFT 0x10
|
||||
#define VCN_RAS_CNTL__MMSCH_READY__SHIFT 0x11
|
||||
#define VCN_RAS_CNTL__VCPU_VCODEC_IH_EN_MASK 0x00000001L
|
||||
#define VCN_RAS_CNTL__MMSCH_FATAL_ERROR_EN_MASK 0x00000002L
|
||||
#define VCN_RAS_CNTL__VCPU_VCODEC_PMI_EN_MASK 0x00000010L
|
||||
#define VCN_RAS_CNTL__MMSCH_PMI_EN_MASK 0x00000020L
|
||||
#define VCN_RAS_CNTL__VCPU_VCODEC_REARM_MASK 0x00000100L
|
||||
#define VCN_RAS_CNTL__MMSCH_REARM_MASK 0x00000200L
|
||||
#define VCN_RAS_CNTL__VCPU_VCODEC_STALL_EN_MASK 0x00001000L
|
||||
#define VCN_RAS_CNTL__VCPU_VCODEC_READY_MASK 0x00010000L
|
||||
#define VCN_RAS_CNTL__MMSCH_READY_MASK 0x00020000L
|
||||
|
||||
//VCN 2_6_0 UVD_VCPU_INT_EN
|
||||
#define UVD_VCPU_INT_EN__RASCNTL_VCPU_VCODEC_EN__SHIFT 0x16
|
||||
#define UVD_VCPU_INT_EN__RASCNTL_VCPU_VCODEC_EN_MASK 0x00400000L
|
||||
|
||||
//VCN 2_6_0 UVD_SYS_INT_EN
|
||||
#define UVD_SYS_INT_EN__RASCNTL_VCPU_VCODEC_EN_MASK 0x04000000L
|
||||
|
||||
/* JPEG 2_6_0 UVD_RAS_JPEG0_STATUS */
|
||||
#define UVD_RAS_JPEG0_STATUS__POISONED_VF__SHIFT 0x0
|
||||
#define UVD_RAS_JPEG0_STATUS__POISONED_PF__SHIFT 0x1f
|
||||
|
||||
@@ -9292,7 +9292,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
VFCT_IMAGE_HEADER VbiosHeader;
|
||||
UCHAR VbiosContent[1];
|
||||
UCHAR VbiosContent[];
|
||||
}GOP_VBIOS_CONTENT;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
#ifndef YELLOW_CARP_OFFSET_H
|
||||
#define YELLOW_CARP_OFFSET_H
|
||||
|
||||
|
||||
@@ -168,6 +168,7 @@ struct smu_temperature_range {
|
||||
int mem_crit_max;
|
||||
int mem_emergency_max;
|
||||
int software_shutdown_temp;
|
||||
int software_shutdown_temp_offset;
|
||||
};
|
||||
|
||||
struct smu_state_validation_block {
|
||||
|
||||
@@ -25,10 +25,10 @@
|
||||
|
||||
// *** IMPORTANT ***
|
||||
// PMFW TEAM: Always increment the interface version on any change to this file
|
||||
#define SMU13_DRIVER_IF_VERSION 0x2C
|
||||
#define SMU13_DRIVER_IF_VERSION 0x35
|
||||
|
||||
//Increment this version if SkuTable_t or BoardTable_t change
|
||||
#define PPTABLE_VERSION 0x20
|
||||
#define PPTABLE_VERSION 0x27
|
||||
|
||||
#define NUM_GFXCLK_DPM_LEVELS 16
|
||||
#define NUM_SOCCLK_DPM_LEVELS 8
|
||||
@@ -96,7 +96,7 @@
|
||||
#define FEATURE_MEM_TEMP_READ_BIT 47
|
||||
#define FEATURE_ATHUB_MMHUB_PG_BIT 48
|
||||
#define FEATURE_SOC_PCC_BIT 49
|
||||
#define FEATURE_SPARE_50_BIT 50
|
||||
#define FEATURE_EDC_PWRBRK_BIT 50
|
||||
#define FEATURE_SPARE_51_BIT 51
|
||||
#define FEATURE_SPARE_52_BIT 52
|
||||
#define FEATURE_SPARE_53_BIT 53
|
||||
@@ -282,15 +282,15 @@ typedef enum {
|
||||
} I2cControllerPort_e;
|
||||
|
||||
typedef enum {
|
||||
I2C_CONTROLLER_NAME_VR_GFX = 0,
|
||||
I2C_CONTROLLER_NAME_VR_SOC,
|
||||
I2C_CONTROLLER_NAME_VR_VMEMP,
|
||||
I2C_CONTROLLER_NAME_VR_VDDIO,
|
||||
I2C_CONTROLLER_NAME_LIQUID0,
|
||||
I2C_CONTROLLER_NAME_LIQUID1,
|
||||
I2C_CONTROLLER_NAME_PLX,
|
||||
I2C_CONTROLLER_NAME_OTHER,
|
||||
I2C_CONTROLLER_NAME_COUNT,
|
||||
I2C_CONTROLLER_NAME_VR_GFX = 0,
|
||||
I2C_CONTROLLER_NAME_VR_SOC,
|
||||
I2C_CONTROLLER_NAME_VR_VMEMP,
|
||||
I2C_CONTROLLER_NAME_VR_VDDIO,
|
||||
I2C_CONTROLLER_NAME_LIQUID0,
|
||||
I2C_CONTROLLER_NAME_LIQUID1,
|
||||
I2C_CONTROLLER_NAME_PLX,
|
||||
I2C_CONTROLLER_NAME_FAN_INTAKE,
|
||||
I2C_CONTROLLER_NAME_COUNT,
|
||||
} I2cControllerName_e;
|
||||
|
||||
typedef enum {
|
||||
@@ -302,6 +302,7 @@ typedef enum {
|
||||
I2C_CONTROLLER_THROTTLER_LIQUID0,
|
||||
I2C_CONTROLLER_THROTTLER_LIQUID1,
|
||||
I2C_CONTROLLER_THROTTLER_PLX,
|
||||
I2C_CONTROLLER_THROTTLER_FAN_INTAKE,
|
||||
I2C_CONTROLLER_THROTTLER_INA3221,
|
||||
I2C_CONTROLLER_THROTTLER_COUNT,
|
||||
} I2cControllerThrottler_e;
|
||||
@@ -309,8 +310,9 @@ typedef enum {
|
||||
typedef enum {
|
||||
I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5,
|
||||
I2C_CONTROLLER_PROTOCOL_VR_IR35217,
|
||||
I2C_CONTROLLER_PROTOCOL_TMP_TMP102A,
|
||||
I2C_CONTROLLER_PROTOCOL_TMP_MAX31875,
|
||||
I2C_CONTROLLER_PROTOCOL_INA3221,
|
||||
I2C_CONTROLLER_PROTOCOL_TMP_MAX6604,
|
||||
I2C_CONTROLLER_PROTOCOL_COUNT,
|
||||
} I2cControllerProtocol_e;
|
||||
|
||||
@@ -690,6 +692,9 @@ typedef struct {
|
||||
#define PP_OD_FEATURE_UCLK_BIT 8
|
||||
#define PP_OD_FEATURE_ZERO_FAN_BIT 9
|
||||
#define PP_OD_FEATURE_TEMPERATURE_BIT 10
|
||||
#define PP_OD_FEATURE_POWER_FEATURE_CTRL_BIT 11
|
||||
#define PP_OD_FEATURE_ASIC_TDC_BIT 12
|
||||
#define PP_OD_FEATURE_COUNT 13
|
||||
|
||||
typedef enum {
|
||||
PP_OD_POWER_FEATURE_ALWAYS_ENABLED,
|
||||
@@ -697,6 +702,11 @@ typedef enum {
|
||||
PP_OD_POWER_FEATURE_ALWAYS_DISABLED,
|
||||
} PP_OD_POWER_FEATURE_e;
|
||||
|
||||
typedef enum {
|
||||
FAN_MODE_AUTO = 0,
|
||||
FAN_MODE_MANUAL_LINEAR,
|
||||
} FanMode_e;
|
||||
|
||||
typedef struct {
|
||||
uint32_t FeatureCtrlMask;
|
||||
|
||||
@@ -708,8 +718,8 @@ typedef struct {
|
||||
uint8_t RuntimePwrSavingFeaturesCtrl;
|
||||
|
||||
//Frequency changes
|
||||
int16_t GfxclkFmin; // MHz
|
||||
int16_t GfxclkFmax; // MHz
|
||||
int16_t GfxclkFmin; // MHz
|
||||
int16_t GfxclkFmax; // MHz
|
||||
uint16_t UclkFmin; // MHz
|
||||
uint16_t UclkFmax; // MHz
|
||||
|
||||
@@ -730,7 +740,12 @@ typedef struct {
|
||||
uint8_t MaxOpTemp;
|
||||
uint8_t Padding[4];
|
||||
|
||||
uint32_t Spare[12];
|
||||
uint16_t GfxVoltageFullCtrlMode;
|
||||
uint16_t GfxclkFullCtrlMode;
|
||||
uint16_t UclkFullCtrlMode;
|
||||
int16_t AsicTdc;
|
||||
|
||||
uint32_t Spare[10];
|
||||
uint32_t MmHubPadding[8]; // SMU internal use. Adding here instead of external as a workaround
|
||||
} OverDriveTable_t;
|
||||
|
||||
@@ -748,8 +763,8 @@ typedef struct {
|
||||
uint8_t IdlePwrSavingFeaturesCtrl;
|
||||
uint8_t RuntimePwrSavingFeaturesCtrl;
|
||||
|
||||
uint16_t GfxclkFmin; // MHz
|
||||
uint16_t GfxclkFmax; // MHz
|
||||
int16_t GfxclkFmin; // MHz
|
||||
int16_t GfxclkFmax; // MHz
|
||||
uint16_t UclkFmin; // MHz
|
||||
uint16_t UclkFmax; // MHz
|
||||
|
||||
@@ -769,7 +784,12 @@ typedef struct {
|
||||
uint8_t MaxOpTemp;
|
||||
uint8_t Padding[4];
|
||||
|
||||
uint32_t Spare[12];
|
||||
uint16_t GfxVoltageFullCtrlMode;
|
||||
uint16_t GfxclkFullCtrlMode;
|
||||
uint16_t UclkFullCtrlMode;
|
||||
int16_t AsicTdc;
|
||||
|
||||
uint32_t Spare[10];
|
||||
|
||||
} OverDriveLimits_t;
|
||||
|
||||
@@ -903,7 +923,8 @@ typedef struct {
|
||||
uint16_t FanStartTempMin;
|
||||
uint16_t FanStartTempMax;
|
||||
|
||||
uint32_t Spare[12];
|
||||
uint16_t PowerMinPpt0[POWER_SOURCE_COUNT];
|
||||
uint32_t Spare[11];
|
||||
|
||||
} MsgLimits_t;
|
||||
|
||||
@@ -1086,11 +1107,13 @@ typedef struct {
|
||||
uint32_t GfxoffSpare[15];
|
||||
|
||||
// GFX GPO
|
||||
float DfllBtcMasterScalerM;
|
||||
uint32_t DfllBtcMasterScalerM;
|
||||
int32_t DfllBtcMasterScalerB;
|
||||
float DfllBtcSlaveScalerM;
|
||||
uint32_t DfllBtcSlaveScalerM;
|
||||
int32_t DfllBtcSlaveScalerB;
|
||||
uint32_t GfxGpoSpare[12];
|
||||
uint32_t DfllPccAsWaitCtrl; //GDFLL_AS_WAIT_CTRL_PCC register value to be passed to RLC msg
|
||||
uint32_t DfllPccAsStepCtrl; //GDFLL_AS_STEP_CTRL_PCC register value to be passed to RLC msg
|
||||
uint32_t GfxGpoSpare[10];
|
||||
|
||||
// GFX DCS
|
||||
|
||||
@@ -1106,7 +1129,10 @@ typedef struct {
|
||||
uint16_t DcsTimeout; //This is the amount of time SMU FW waits for RLC to put GFX into GFXOFF before reverting to the fallback mechanism of throttling GFXCLK to Fmin.
|
||||
|
||||
|
||||
uint32_t DcsSpare[16];
|
||||
uint32_t DcsSpare[14];
|
||||
|
||||
// UCLK section
|
||||
uint16_t ShadowFreqTableUclk[NUM_UCLK_DPM_LEVELS]; // In MHz
|
||||
|
||||
// UCLK section
|
||||
uint8_t UseStrobeModeOptimizations; //Set to indicate that FW should use strobe mode optimizations
|
||||
@@ -1163,13 +1189,14 @@ typedef struct {
|
||||
uint16_t IntakeTempHighIntakeAcousticLimit;
|
||||
uint16_t IntakeTempAcouticLimitReleaseRate;
|
||||
|
||||
uint16_t FanStalledTempLimitOffset;
|
||||
int16_t FanAbnormalTempLimitOffset;
|
||||
uint16_t FanStalledTriggerRpm;
|
||||
uint16_t FanAbnormalTriggerRpm;
|
||||
uint16_t FanPadding;
|
||||
|
||||
uint32_t FanSpare[14];
|
||||
uint16_t FanAbnormalTriggerRpmCoeff;
|
||||
uint16_t FanAbnormalDetectionEnable;
|
||||
|
||||
uint8_t FanIntakeSensorSupport;
|
||||
uint8_t FanIntakePadding[3];
|
||||
uint32_t FanSpare[13];
|
||||
// SECTION: VDD_GFX AVFS
|
||||
|
||||
uint8_t OverrideGfxAvfsFuses;
|
||||
@@ -1193,7 +1220,6 @@ typedef struct {
|
||||
uint32_t dGbV_dT_vmin;
|
||||
uint32_t dGbV_dT_vmax;
|
||||
|
||||
//Unused: PMFW-9370
|
||||
uint32_t V2F_vmin_range_low;
|
||||
uint32_t V2F_vmin_range_high;
|
||||
uint32_t V2F_vmax_range_low;
|
||||
@@ -1238,8 +1264,21 @@ typedef struct {
|
||||
// SECTION: Advanced Options
|
||||
uint32_t DebugOverrides;
|
||||
|
||||
// Section: Total Board Power idle vs active coefficients
|
||||
uint8_t TotalBoardPowerSupport;
|
||||
uint8_t TotalBoardPowerPadding[3];
|
||||
|
||||
int16_t TotalIdleBoardPowerM;
|
||||
int16_t TotalIdleBoardPowerB;
|
||||
int16_t TotalBoardPowerM;
|
||||
int16_t TotalBoardPowerB;
|
||||
|
||||
QuadraticInt_t qFeffCoeffGameClock[POWER_SOURCE_COUNT];
|
||||
QuadraticInt_t qFeffCoeffBaseClock[POWER_SOURCE_COUNT];
|
||||
QuadraticInt_t qFeffCoeffBoostClock[POWER_SOURCE_COUNT];
|
||||
|
||||
// SECTION: Sku Reserved
|
||||
uint32_t Spare[64];
|
||||
uint32_t Spare[43];
|
||||
|
||||
// Padding for MMHUB - do not modify this
|
||||
uint32_t MmHubPadding[8];
|
||||
@@ -1304,7 +1343,8 @@ typedef struct {
|
||||
// SECTION: Clock Spread Spectrum
|
||||
|
||||
// UCLK Spread Spectrum
|
||||
uint16_t UclkSpreadPadding;
|
||||
uint8_t UclkTrainingModeSpreadPercent; // Q4.4
|
||||
uint8_t UclkSpreadPadding;
|
||||
uint16_t UclkSpreadFreq; // kHz
|
||||
|
||||
// UCLK Spread Spectrum
|
||||
@@ -1317,11 +1357,7 @@ typedef struct {
|
||||
|
||||
// Section: Memory Config
|
||||
uint8_t DramWidth; // Width of interface to the channel for each DRAM module. See DRAM_BIT_WIDTH_TYPE_e
|
||||
uint8_t PaddingMem1[3];
|
||||
|
||||
// Section: Total Board Power
|
||||
uint16_t TotalBoardPower; //Only needed for TCP Estimated case, where TCP = TGP+Total Board Power
|
||||
uint16_t BoardPowerPadding;
|
||||
uint8_t PaddingMem1[7];
|
||||
|
||||
// SECTION: UMC feature flags
|
||||
uint8_t HsrEnabled;
|
||||
@@ -1423,8 +1459,11 @@ typedef struct {
|
||||
uint16_t Vcn1ActivityPercentage ;
|
||||
|
||||
uint32_t EnergyAccumulator;
|
||||
uint16_t AverageSocketPower ;
|
||||
uint16_t AverageSocketPower;
|
||||
uint16_t AverageTotalBoardPower;
|
||||
|
||||
uint16_t AvgTemperature[TEMP_COUNT];
|
||||
uint16_t AvgTemperatureFanIntake;
|
||||
|
||||
uint8_t PcieRate ;
|
||||
uint8_t PcieWidth ;
|
||||
@@ -1592,5 +1631,7 @@ typedef struct {
|
||||
#define IH_INTERRUPT_CONTEXT_ID_AUDIO_D0 0x5
|
||||
#define IH_INTERRUPT_CONTEXT_ID_AUDIO_D3 0x6
|
||||
#define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING 0x7
|
||||
#define IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL 0x8
|
||||
#define IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY 0x9
|
||||
|
||||
#endif
|
||||
|
||||
@@ -131,7 +131,13 @@
|
||||
#define PPSMC_MSG_EnableAudioStutterWA 0x44
|
||||
#define PPSMC_MSG_PowerUpUmsch 0x45
|
||||
#define PPSMC_MSG_PowerDownUmsch 0x46
|
||||
#define PPSMC_Message_Count 0x47
|
||||
#define PPSMC_MSG_SetDcsArch 0x47
|
||||
#define PPSMC_MSG_TriggerVFFLR 0x48
|
||||
#define PPSMC_MSG_SetNumBadMemoryPagesRetired 0x49
|
||||
#define PPSMC_MSG_SetBadMemoryPagesRetiredFlagsPerChannel 0x4A
|
||||
#define PPSMC_MSG_SetPriorityDeltaGain 0x4B
|
||||
#define PPSMC_MSG_AllowIHHostInterrupt 0x4C
|
||||
#define PPSMC_Message_Count 0x4D
|
||||
|
||||
//Debug Dump Message
|
||||
#define DEBUGSMC_MSG_TestMessage 0x1
|
||||
|
||||
@@ -239,7 +239,9 @@
|
||||
__SMU_DUMMY_MAP(DriverMode2Reset), \
|
||||
__SMU_DUMMY_MAP(GetGfxOffStatus), \
|
||||
__SMU_DUMMY_MAP(GetGfxOffEntryCount), \
|
||||
__SMU_DUMMY_MAP(LogGfxOffResidency),
|
||||
__SMU_DUMMY_MAP(LogGfxOffResidency), \
|
||||
__SMU_DUMMY_MAP(SetNumBadMemoryPagesRetired), \
|
||||
__SMU_DUMMY_MAP(SetBadMemoryPagesRetiredFlagsPerChannel),
|
||||
|
||||
#undef __SMU_DUMMY_MAP
|
||||
#define __SMU_DUMMY_MAP(type) SMU_MSG_##type
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07
|
||||
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
|
||||
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32
|
||||
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x2C
|
||||
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x35
|
||||
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_10 0x1D
|
||||
|
||||
#define SMU13_MODE1_RESET_WAIT_TIME_IN_MS 500 //500ms
|
||||
|
||||
@@ -1376,6 +1376,7 @@ static int smu_v13_0_irq_process(struct amdgpu_device *adev,
|
||||
*/
|
||||
uint32_t ctxid = entry->src_data[0];
|
||||
uint32_t data;
|
||||
uint32_t high;
|
||||
|
||||
if (client_id == SOC15_IH_CLIENTID_THM) {
|
||||
switch (src_id) {
|
||||
@@ -1432,6 +1433,36 @@ static int smu_v13_0_irq_process(struct amdgpu_device *adev,
|
||||
schedule_work(&smu->throttling_logging_work);
|
||||
|
||||
break;
|
||||
case 0x8:
|
||||
high = smu->thermal_range.software_shutdown_temp +
|
||||
smu->thermal_range.software_shutdown_temp_offset;
|
||||
high = min_t(typeof(high),
|
||||
SMU_THERMAL_MAXIMUM_ALERT_TEMP,
|
||||
high);
|
||||
dev_emerg(adev->dev, "Reduce soft CTF limit to %d (by an offset %d)\n",
|
||||
high,
|
||||
smu->thermal_range.software_shutdown_temp_offset);
|
||||
|
||||
data = RREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL);
|
||||
data = REG_SET_FIELD(data, THM_THERMAL_INT_CTRL,
|
||||
DIG_THERM_INTH,
|
||||
(high & 0xff));
|
||||
data = data & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
|
||||
WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL, data);
|
||||
break;
|
||||
case 0x9:
|
||||
high = min_t(typeof(high),
|
||||
SMU_THERMAL_MAXIMUM_ALERT_TEMP,
|
||||
smu->thermal_range.software_shutdown_temp);
|
||||
dev_emerg(adev->dev, "Recover soft CTF limit to %d\n", high);
|
||||
|
||||
data = RREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL);
|
||||
data = REG_SET_FIELD(data, THM_THERMAL_INT_CTRL,
|
||||
DIG_THERM_INTH,
|
||||
(high & 0xff));
|
||||
data = data & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
|
||||
WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +141,9 @@ static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] =
|
||||
MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 0),
|
||||
MSG_MAP(DFCstateControl, PPSMC_MSG_SetExternalClientDfCstateAllow, 0),
|
||||
MSG_MAP(ArmD3, PPSMC_MSG_ArmD3, 0),
|
||||
MSG_MAP(SetNumBadMemoryPagesRetired, PPSMC_MSG_SetNumBadMemoryPagesRetired, 0),
|
||||
MSG_MAP(SetBadMemoryPagesRetiredFlagsPerChannel,
|
||||
PPSMC_MSG_SetBadMemoryPagesRetiredFlagsPerChannel, 0),
|
||||
};
|
||||
|
||||
static struct cmn2asic_mapping smu_v13_0_0_clk_map[SMU_CLK_COUNT] = {
|
||||
@@ -1838,6 +1841,40 @@ static void smu_v13_0_0_set_smu_mailbox_registers(struct smu_context *smu)
|
||||
smu->debug_resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_54);
|
||||
}
|
||||
|
||||
static int smu_v13_0_0_smu_send_bad_mem_page_num(struct smu_context *smu,
|
||||
uint32_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* message SMU to update the bad page number on SMUBUS */
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu,
|
||||
SMU_MSG_SetNumBadMemoryPagesRetired,
|
||||
size, NULL);
|
||||
if (ret)
|
||||
dev_err(smu->adev->dev,
|
||||
"[%s] failed to message SMU to update bad memory pages number\n",
|
||||
__func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int smu_v13_0_0_send_bad_mem_channel_flag(struct smu_context *smu,
|
||||
uint32_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* message SMU to update the bad channel info on SMUBUS */
|
||||
ret = smu_cmn_send_smc_msg_with_param(smu,
|
||||
SMU_MSG_SetBadMemoryPagesRetiredFlagsPerChannel,
|
||||
size, NULL);
|
||||
if (ret)
|
||||
dev_err(smu->adev->dev,
|
||||
"[%s] failed to message SMU to update bad memory pages channel info\n",
|
||||
__func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
|
||||
.get_allowed_feature_mask = smu_v13_0_0_get_allowed_feature_mask,
|
||||
.set_default_dpm_table = smu_v13_0_0_set_default_dpm_table,
|
||||
@@ -1908,6 +1945,8 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
|
||||
.mode1_reset = smu_v13_0_0_mode1_reset,
|
||||
.set_mp1_state = smu_v13_0_0_set_mp1_state,
|
||||
.set_df_cstate = smu_v13_0_0_set_df_cstate,
|
||||
.send_hbm_bad_pages_num = smu_v13_0_0_smu_send_bad_mem_page_num,
|
||||
.send_hbm_bad_channel_flag = smu_v13_0_0_send_bad_mem_channel_flag,
|
||||
};
|
||||
|
||||
void smu_v13_0_0_set_ppt_funcs(struct smu_context *smu)
|
||||
|
||||
@@ -1223,6 +1223,7 @@ static int smu_v13_0_7_get_thermal_temperature_range(struct smu_context *smu,
|
||||
range->mem_emergency_max = (pptable->SkuTable.TemperatureLimit[TEMP_MEM] + CTF_OFFSET_MEM)*
|
||||
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
|
||||
range->software_shutdown_temp = powerplay_table->software_shutdown_temp;
|
||||
range->software_shutdown_temp_offset = pptable->SkuTable.FanAbnormalTempLimitOffset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user