summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-04-24 11:33:23 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-04-24 11:33:23 -0700
commit92c4c9fdc838d3b41a996bb700ea64b9e78fc7ea (patch)
treee5a1763ce1295ccdeb94f4e26ee52eb4f3c3aed6 /drivers
parent892c894b4ba4e4eb835f99de6fe7c41871e6d4f8 (diff)
parente49712ef03dbc4e282dd0e76469642279c2811e5 (diff)
Merge tag 'drm-next-2026-04-24' of https://gitlab.freedesktop.org/drm/kernel
Pull drm next fixes from Dave Airlie: "This is the first of two fixes for the merge PRs, the other is based on 7.0 branch. This mostly AMD fixes, a couple of weeks of backlog built up and this weeks. The main complaint I've seen is some boot warnings around the FP code handling which this should fix. Otherwise a single rcar-du and a single i915 fix. amdgpu: - SMU 14 fixes - Partition fixes - SMUIO 15.x fix - SR-IOV fixes - JPEG fix - PSP 15.x fix - NBIF fix - Devcoredump fixes - DPC fix - RAS fixes - Aldebaran smu fix - IP discovery fix - SDMA 7.1 fix - Runtime pm fix - MES 12.1 fix - DML2 fixes - DCN 4.2 fixes - YCbCr fixes - Freesync fixes - ISM fixes - Overlay cursor fix - DC FP fixes - UserQ locking fixes - DC idle state manager fix - ASPM fix - GPUVM SVM fix - DCE 6 fix amdkfd: - Fix memory clear handling - num_of_nodes bounds check fix i915: - Fix uninitialized variable in the alignment loop [psr] rcar-du: - fix NULL-ptr crash" * tag 'drm-next-2026-04-24' of https://gitlab.freedesktop.org/drm/kernel: (75 commits) drm/amdkfd: Add upper bound check for num_of_nodes drm: rcar-du: Fix crash when no CMM is available drm/amd/display: Disable 10-bit truncation and dithering on DCE 6.x drm/amdgpu: OR init_pte_flags into invalid leaf PTE updates drm/amd: Adjust ASPM support quirk to cover more Intel hosts drm/amd/display: Undo accidental fix revert in amdgpu_dm_ism.c drm/i915/psr: Init variable to avoid early exit from et alignment loop drm/amdgpu: drop userq fence driver refs out of fence process() drm/amdgpu/userq: unpin and unref doorbell and wptr outside mutex drm/amdgpu/userq: use pm_runtime_resume_and_get and fix err handling drm/amdgpu/userq: unmap_helper dont return the queue state drm/amdgpu/userq: unmap is to be called before freeing doorbell/wptr bo drm/amdgpu/userq: hold root bo lock in caller of input_va_validate drm/amdgpu/userq: caller to take reserv lock for vas_list_cleanup drm/amdgpu/userq: create_mqd does not need userq_mutex drm/amdgpu/userq: dont lock root bo with userq_mutex held drm/amdgpu/userq: fix kerneldoc for amdgpu_userq_ensure_ev_fence drm/amdgpu/userq: clean the VA mapping list for failed queue creation drm/amdgpu/userq: avoid uneccessary locking in amdgpu_userq_create drm/amd/display: Fix ISM teardown crash from NULL dc dereference ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c36
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c20
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c140
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c47
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c31
-rw-r--r--drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c52
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mes_userqueue.c21
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mes_v12_1.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v15_0.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c12
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_chardev.c3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_priv.h1
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_topology.c11
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c135
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h7
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c7
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c241
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_ism.c15
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c78
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h13
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_dsc.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_stream.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_types.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dm_helpers.h10
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c37
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/Makefile1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_core.c17
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c14
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c24
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper_fpu.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h25
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_display_cfg_types.h14
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c37
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h40
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.c73
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn42.c192
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn42.h17
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.h10
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_factory.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_standalone_libraries/lib_float_math.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_top/dml2_top_soc15.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml2_dc_resource_mgmt.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml2_utils.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper.c11
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper_fpu.c10
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml_display_rq_dlg_calc.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c13
-rw-r--r--drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_detection.c25
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_dpms.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c7
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c7
-rw-r--r--drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn42/dcn42_soc_and_ip_translator.c4
-rw-r--r--drivers/gpu/drm/amd/display/include/ddc_service_types.h1
-rw-r--r--drivers/gpu/drm/amd/display/modules/freesync/freesync.c32
-rw-r--r--drivers/gpu/drm/amd/display/modules/power/power_helpers.c49
-rw-r--r--drivers/gpu/drm/amd/display/modules/vmid/vmid.c8
-rw-r--r--drivers/gpu/drm/amd/pm/amdgpu_pm.c14
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c3
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h1
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c6
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c70
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c37
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h14
-rw-r--r--drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c9
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.c2
-rw-r--r--drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c6
98 files changed, 1377 insertions, 532 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 29b400cdd6d5..72a5a29e63f6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1735,7 +1735,8 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
alloc_domain = AMDGPU_GEM_DOMAIN_GTT;
alloc_flags = 0;
} else {
- alloc_flags = AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE;
+ alloc_flags = AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE |
+ AMDGPU_GEM_CREATE_VRAM_CLEARED;
alloc_flags |= (flags & KFD_IOC_ALLOC_MEM_FLAGS_PUBLIC) ?
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED : 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index b04fa9fd90b7..92c98e999efe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -866,6 +866,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
if (dret) {
amdgpu_connector->detected_by_load = false;
drm_edid_free(amdgpu_connector->edid);
+ amdgpu_connector->edid = NULL;
amdgpu_connector_get_edid(connector);
if (!amdgpu_connector->edid) {
@@ -882,6 +883,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
*/
if (amdgpu_connector->use_digital && amdgpu_connector->shared_ddc) {
drm_edid_free(amdgpu_connector->edid);
+ amdgpu_connector->edid = NULL;
ret = connector_status_disconnected;
} else {
ret = connector_status_connected;
@@ -977,6 +979,7 @@ static void amdgpu_connector_shared_ddc(enum drm_connector_status *status,
if (!amdgpu_display_hpd_sense(adev,
amdgpu_connector->hpd.hpd)) {
drm_edid_free(amdgpu_connector->edid);
+ amdgpu_connector->edid = NULL;
*status = connector_status_disconnected;
}
}
@@ -1046,6 +1049,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
if (dret) {
amdgpu_connector->detected_by_load = false;
drm_edid_free(amdgpu_connector->edid);
+ amdgpu_connector->edid = NULL;
amdgpu_connector_get_edid(connector);
if (!amdgpu_connector->edid) {
@@ -1062,6 +1066,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
*/
if ((!amdgpu_connector->use_digital) && amdgpu_connector->shared_ddc) {
drm_edid_free(amdgpu_connector->edid);
+ amdgpu_connector->edid = NULL;
ret = connector_status_disconnected;
} else {
ret = connector_status_connected;
@@ -1412,6 +1417,7 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
}
drm_edid_free(amdgpu_connector->edid);
+ amdgpu_connector->edid = NULL;
if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c
index c72c345334d0..4e6e390854e6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c
@@ -32,6 +32,8 @@ static const guid_t BOOT = BOOT_TYPE;
static const guid_t CRASHDUMP = AMD_CRASHDUMP;
static const guid_t RUNTIME = AMD_GPU_NONSTANDARD_ERROR;
+#define CPER_SIGNATURE_SZ (sizeof(((struct cper_hdr *)0)->signature))
+
static void __inc_entry_length(struct cper_hdr *hdr, uint32_t size)
{
hdr->record_length += size;
@@ -425,23 +427,40 @@ int amdgpu_cper_generate_ce_records(struct amdgpu_device *adev,
static bool amdgpu_cper_is_hdr(struct amdgpu_ring *ring, u64 pos)
{
- struct cper_hdr *chdr;
+ char signature[CPER_SIGNATURE_SZ];
+
+ if ((pos << 2) >= ring->ring_size)
+ return false;
- chdr = (struct cper_hdr *)&(ring->ring[pos]);
- return strcmp(chdr->signature, "CPER") ? false : true;
+ if ((pos << 2) + CPER_SIGNATURE_SZ <= ring->ring_size) {
+ memcpy(signature, &ring->ring[pos], CPER_SIGNATURE_SZ);
+ } else {
+ u32 chunk = ring->ring_size - (pos << 2);
+
+ memcpy(signature, &ring->ring[pos], chunk);
+ memcpy(signature + chunk, ring->ring, CPER_SIGNATURE_SZ - chunk);
+ }
+
+ return !memcmp(signature, "CPER", CPER_SIGNATURE_SZ);
}
static u32 amdgpu_cper_ring_get_ent_sz(struct amdgpu_ring *ring, u64 pos)
{
- struct cper_hdr *chdr;
+ struct cper_hdr chdr;
u64 p;
u32 chunk, rec_len = 0;
- chdr = (struct cper_hdr *)&(ring->ring[pos]);
chunk = ring->ring_size - (pos << 2);
- if (!strcmp(chdr->signature, "CPER")) {
- rec_len = chdr->record_length;
+ if (amdgpu_cper_is_hdr(ring, pos)) {
+ if (chunk >= sizeof(chdr)) {
+ memcpy(&chdr, &ring->ring[pos], sizeof(chdr));
+ } else {
+ memcpy(&chdr, &ring->ring[pos], chunk);
+ memcpy((u8 *)&chdr + chunk, ring->ring, sizeof(chdr) - chunk);
+ }
+
+ rec_len = chdr.record_length;
goto calc;
}
@@ -450,8 +469,7 @@ static u32 amdgpu_cper_ring_get_ent_sz(struct amdgpu_ring *ring, u64 pos)
goto calc;
for (p = pos + 1; p <= ring->buf_mask; p++) {
- chdr = (struct cper_hdr *)&(ring->ring[p]);
- if (!strcmp(chdr->signature, "CPER")) {
+ if (amdgpu_cper_is_hdr(ring, p)) {
rec_len = (p - pos) << 2;
goto calc;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
index 3f1cc2265645..d386bc775d03 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
@@ -464,6 +464,9 @@ static void amdgpu_devcoredump_deferred_work(struct work_struct *work)
struct amdgpu_device *adev = container_of(work, typeof(*adev), coredump_work);
struct amdgpu_coredump_info *coredump = adev->coredump;
+ if (!coredump)
+ goto end;
+
/* Do a one-time preparation of the coredump output because
* repeatingly calling drm_coredump_printer is very slow.
*/
@@ -499,7 +502,7 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
int i, off, idx;
/* No need to generate a new coredump if there's one in progress already. */
- if (work_pending(&adev->coredump_work))
+ if (work_busy(&adev->coredump_work))
return;
if (job && job->pasid)
@@ -511,7 +514,6 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
coredump->skip_vram_check = skip_vram_check;
coredump->reset_vram_lost = vram_lost;
- coredump->pasid = job->pasid;
if (job && job->pasid) {
struct amdgpu_task_info *ti;
@@ -521,6 +523,7 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
coredump->reset_task_info = *ti;
amdgpu_vm_put_task_info(ti);
}
+ coredump->pasid = job->pasid;
coredump->num_ibs = job->num_ibs;
for (i = 0; i < job->num_ibs; ++i) {
coredump->ibs[i].gpu_addr = job->ibs[i].gpu_addr;
@@ -563,7 +566,7 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
coredump->rings[idx].offset = off;
memcpy(&coredump->rings_dw[off], ring->ring, ring->ring_size);
- off += ring->ring_size;
+ off += ring->ring_size / 4;
idx++;
}
coredump->num_rings = idx;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 584c9ec28bf1..737ef1ef96a5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1334,18 +1334,15 @@ static bool amdgpu_device_aspm_support_quirk(struct amdgpu_device *adev)
#if IS_ENABLED(CONFIG_X86)
struct cpuinfo_x86 *c = &cpu_data(0);
- if (!(amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(12, 0, 0) ||
- amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(12, 0, 1)))
- return false;
-
- if (c->x86 == 6 &&
- adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN5) {
+ if (c->x86_vendor == X86_VENDOR_INTEL) {
switch (c->x86_model) {
case VFM_MODEL(INTEL_ALDERLAKE):
case VFM_MODEL(INTEL_ALDERLAKE_L):
case VFM_MODEL(INTEL_RAPTORLAKE):
case VFM_MODEL(INTEL_RAPTORLAKE_P):
case VFM_MODEL(INTEL_RAPTORLAKE_S):
+ case VFM_MODEL(INTEL_TIGERLAKE):
+ case VFM_MODEL(INTEL_TIGERLAKE_L):
return true;
default:
return false;
@@ -5518,8 +5515,6 @@ static void amdgpu_device_recovery_prepare(struct amdgpu_device *adev,
list_add_tail(&tmp_adev->reset_list, device_list);
if (adev->shutdown)
tmp_adev->shutdown = true;
- if (amdgpu_reset_in_dpc(adev))
- tmp_adev->pcie_reset_ctx.in_link_reset = true;
}
if (!list_is_first(&adev->reset_list, device_list))
list_rotate_to_front(&adev->reset_list, device_list);
@@ -6291,6 +6286,9 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta
amdgpu_reset_set_dpc_status(adev, true);
mutex_lock(&hive->hive_lock);
+ } else {
+ if (amdgpu_device_bus_status_check(adev))
+ amdgpu_reset_set_dpc_status(adev, true);
}
memset(&reset_context, 0, sizeof(reset_context));
INIT_LIST_HEAD(&device_list);
@@ -6411,6 +6409,7 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head)
tmp_adev->pcie_reset_ctx.in_link_reset = true;
} else {
+ adev->pcie_reset_ctx.in_link_reset = true;
set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags);
}
@@ -6467,9 +6466,10 @@ void amdgpu_pci_resume(struct pci_dev *pdev)
tmp_adev->pcie_reset_ctx.in_link_reset = false;
list_add_tail(&tmp_adev->reset_list, &device_list);
}
- } else
+ } else {
+ adev->pcie_reset_ctx.in_link_reset = false;
list_add_tail(&adev->reset_list, &device_list);
-
+ }
amdgpu_device_sched_resume(&device_list, NULL, NULL);
amdgpu_device_gpu_resume(adev, &device_list, false);
amdgpu_device_recovery_put_reset_lock(adev, &device_list);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 8ec5465c3349..fcad7daaa41b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -535,10 +535,11 @@ static int amdgpu_discovery_get_table_info(struct amdgpu_device *adev,
*info = &bhdrv2->table_list[table_id];
break;
case 1:
+ case 0:
*info = &bhdr->table_list[table_id];
break;
default:
- dev_err(adev->dev, "Invalid ip discovery table version\n");
+ dev_err(adev->dev, "Invalid ip discovery table version %d\n",bhdr->version_major);
return -EINVAL;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index 2956e45c9254..b8ca876694ff 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -2013,6 +2013,8 @@ static void amdgpu_gfx_sysfs_xcp_fini(struct amdgpu_device *adev)
(xcp_mgr->funcs && xcp_mgr->funcs->switch_partition_mode);
device_remove_file(adev->dev, &dev_attr_current_compute_partition);
+ device_remove_file(adev->dev, &dev_attr_compute_partition_mem_alloc_mode);
+
if (xcp_switch_supported)
device_remove_file(adev->dev,
&dev_attr_available_compute_partition);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index bfca5b040a32..d5abf785ca17 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -239,13 +239,12 @@ int amdgpu_userq_input_va_validate(struct amdgpu_device *adev,
u64 size;
int r = 0;
+ /* Caller must hold vm->root.bo reservation */
+ dma_resv_assert_held(queue->vm->root.bo->tbo.base.resv);
+
user_addr = (addr & AMDGPU_GMC_HOLE_MASK) >> AMDGPU_GPU_PAGE_SHIFT;
size = expected_size >> AMDGPU_GPU_PAGE_SHIFT;
- r = amdgpu_bo_reserve(vm->root.bo, false);
- if (r)
- return r;
-
va_map = amdgpu_vm_bo_lookup_mapping(vm, user_addr);
if (!va_map) {
r = -EINVAL;
@@ -255,13 +254,11 @@ int amdgpu_userq_input_va_validate(struct amdgpu_device *adev,
if (user_addr >= va_map->start &&
va_map->last - user_addr + 1 >= size) {
amdgpu_userq_buffer_va_list_add(queue, va_map, user_addr);
- amdgpu_bo_unreserve(vm->root.bo);
return 0;
}
r = -EINVAL;
out_err:
- amdgpu_bo_unreserve(vm->root.bo);
return r;
}
@@ -270,15 +267,13 @@ static bool amdgpu_userq_buffer_va_mapped(struct amdgpu_vm *vm, u64 addr)
struct amdgpu_bo_va_mapping *mapping;
bool r;
- if (amdgpu_bo_reserve(vm->root.bo, false))
- return false;
+ dma_resv_assert_held(vm->root.bo->tbo.base.resv);
mapping = amdgpu_vm_bo_lookup_mapping(vm, addr);
if (!IS_ERR_OR_NULL(mapping) && atomic_read(&mapping->bo_va->userq_va_mapped))
r = true;
else
r = false;
- amdgpu_bo_unreserve(vm->root.bo);
return r;
}
@@ -314,25 +309,21 @@ static int amdgpu_userq_buffer_vas_list_cleanup(struct amdgpu_device *adev,
{
struct amdgpu_userq_va_cursor *va_cursor, *tmp;
struct amdgpu_bo_va_mapping *mapping;
- int r;
- r = amdgpu_bo_reserve(queue->vm->root.bo, false);
- if (r)
- return r;
+ /* Caller must hold vm->root.bo reservation */
+ dma_resv_assert_held(queue->vm->root.bo->tbo.base.resv);
list_for_each_entry_safe(va_cursor, tmp, &queue->userq_va_list, list) {
mapping = amdgpu_vm_bo_lookup_mapping(queue->vm, va_cursor->gpu_addr);
if (!mapping) {
- r = -EINVAL;
- goto err;
+ return -EINVAL;
}
dev_dbg(adev->dev, "delete the userq:%p va:%llx\n",
queue, va_cursor->gpu_addr);
amdgpu_userq_buffer_va_list_del(mapping, va_cursor);
}
-err:
- amdgpu_bo_unreserve(queue->vm->root.bo);
- return r;
+
+ return 0;
}
static int amdgpu_userq_preempt_helper(struct amdgpu_usermode_queue *queue)
@@ -446,8 +437,6 @@ static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue)
/* Wait for mode-1 reset to complete */
down_read(&adev->reset_domain->sem);
- /* Drop the userq reference. */
- amdgpu_userq_buffer_vas_list_cleanup(adev, queue);
uq_funcs->mqd_destroy(queue);
/* Use interrupt-safe locking since IRQ handlers may access these XArrays */
xa_erase_irq(&adev->userq_doorbell_xa, queue->doorbell_index);
@@ -455,11 +444,19 @@ static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue)
queue->fence_drv = NULL;
queue->userq_mgr = NULL;
list_del(&queue->userq_va_list);
- kfree(queue);
up_read(&adev->reset_domain->sem);
}
+/**
+ * amdgpu_userq_ensure_ev_fence - ensure a valid, unsignaled eviction fence exists
+ * @uq_mgr: the usermode queue manager for this process
+ * @evf_mgr: the eviction fence manager to check and rearm
+ *
+ * Ensures that a valid and not yet signaled eviction fence is attached to the
+ * usermode queue before any queue operations proceed. If it is signalled, then
+ * rearm a new eviction fence.
+ */
void
amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *uq_mgr,
struct amdgpu_eviction_fence_mgr *evf_mgr)
@@ -619,6 +616,9 @@ static int
amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
{
struct amdgpu_device *adev = uq_mgr->adev;
+ struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(uq_mgr);
+ struct amdgpu_vm *vm = &fpriv->vm;
+
int r = 0;
cancel_delayed_work_sync(&uq_mgr->resume_work);
@@ -626,38 +626,44 @@ amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_que
/* Cancel any pending hang detection work and cleanup */
cancel_delayed_work_sync(&queue->hang_detect_work);
+ r = amdgpu_bo_reserve(vm->root.bo, false);
+ if (r) {
+ drm_file_err(uq_mgr->file, "Failed to reserve root bo during userqueue destroy\n");
+ return r;
+ }
+ amdgpu_userq_buffer_vas_list_cleanup(adev, queue);
+ amdgpu_bo_unreserve(vm->root.bo);
+
mutex_lock(&uq_mgr->userq_mutex);
queue->hang_detect_fence = NULL;
amdgpu_userq_wait_for_last_fence(queue);
- r = amdgpu_bo_reserve(queue->db_obj.obj, true);
- if (!r) {
- amdgpu_bo_unpin(queue->db_obj.obj);
- amdgpu_bo_unreserve(queue->db_obj.obj);
- }
- amdgpu_bo_unref(&queue->db_obj.obj);
-
- r = amdgpu_bo_reserve(queue->wptr_obj.obj, true);
- if (!r) {
- amdgpu_bo_unpin(queue->wptr_obj.obj);
- amdgpu_bo_unreserve(queue->wptr_obj.obj);
- }
- amdgpu_bo_unref(&queue->wptr_obj.obj);
-
- atomic_dec(&uq_mgr->userq_count[queue->queue_type]);
#if defined(CONFIG_DEBUG_FS)
debugfs_remove_recursive(queue->debugfs_queue);
#endif
amdgpu_userq_detect_and_reset_queues(uq_mgr);
r = amdgpu_userq_unmap_helper(queue);
/*TODO: It requires a reset for userq hw unmap error*/
- if (unlikely(r != AMDGPU_USERQ_STATE_UNMAPPED)) {
+ if (r) {
drm_warn(adev_to_drm(uq_mgr->adev), "trying to destroy a HW mapping userq\n");
queue->state = AMDGPU_USERQ_STATE_HUNG;
}
+
+ atomic_dec(&uq_mgr->userq_count[queue->queue_type]);
amdgpu_userq_cleanup(queue);
mutex_unlock(&uq_mgr->userq_mutex);
+ amdgpu_bo_reserve(queue->db_obj.obj, true);
+ amdgpu_bo_unpin(queue->db_obj.obj);
+ amdgpu_bo_unreserve(queue->db_obj.obj);
+ amdgpu_bo_unref(&queue->db_obj.obj);
+
+ amdgpu_bo_reserve(queue->wptr_obj.obj, true);
+ amdgpu_bo_unpin(queue->wptr_obj.obj);
+ amdgpu_bo_unreserve(queue->wptr_obj.obj);
+ amdgpu_bo_unref(&queue->wptr_obj.obj);
+ kfree(queue);
+
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
@@ -730,35 +736,25 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
if (r)
return r;
- r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
+ r = pm_runtime_resume_and_get(adev_to_drm(adev)->dev);
if (r < 0) {
- drm_file_err(uq_mgr->file, "pm_runtime_get_sync() failed for userqueue create\n");
- pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
+ drm_file_err(uq_mgr->file, "pm_runtime_resume_and_get() failed for userqueue create\n");
return r;
}
- /*
- * There could be a situation that we are creating a new queue while
- * the other queues under this UQ_mgr are suspended. So if there is any
- * resume work pending, wait for it to get done.
- *
- * This will also make sure we have a valid eviction fence ready to be used.
- */
- amdgpu_userq_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr);
-
uq_funcs = adev->userq_funcs[args->in.ip_type];
if (!uq_funcs) {
drm_file_err(uq_mgr->file, "Usermode queue is not supported for this IP (%u)\n",
args->in.ip_type);
r = -EINVAL;
- goto unlock;
+ goto err_pm_runtime;
}
queue = kzalloc_obj(struct amdgpu_usermode_queue);
if (!queue) {
drm_file_err(uq_mgr->file, "Failed to allocate memory for queue\n");
r = -ENOMEM;
- goto unlock;
+ goto err_pm_runtime;
}
INIT_LIST_HEAD(&queue->userq_va_list);
@@ -773,20 +769,27 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
db_info.doorbell_offset = args->in.doorbell_offset;
queue->userq_mgr = uq_mgr;
+
/* Validate the userq virtual address.*/
+ r = amdgpu_bo_reserve(fpriv->vm.root.bo, false);
+ if (r)
+ goto free_queue;
+
if (amdgpu_userq_input_va_validate(adev, queue, args->in.queue_va, args->in.queue_size) ||
amdgpu_userq_input_va_validate(adev, queue, args->in.rptr_va, AMDGPU_GPU_PAGE_SIZE) ||
amdgpu_userq_input_va_validate(adev, queue, args->in.wptr_va, AMDGPU_GPU_PAGE_SIZE)) {
r = -EINVAL;
- goto free_queue;
+ amdgpu_bo_unreserve(fpriv->vm.root.bo);
+ goto clean_mapping;
}
+ amdgpu_bo_unreserve(fpriv->vm.root.bo);
/* Convert relative doorbell offset into absolute doorbell index */
index = amdgpu_userq_get_doorbell_index(uq_mgr, &db_info, filp);
if (index == (uint64_t)-EINVAL) {
drm_file_err(uq_mgr->file, "Failed to get doorbell for queue\n");
r = -EINVAL;
- goto free_queue;
+ goto clean_mapping;
}
queue->doorbell_index = index;
@@ -794,7 +797,7 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
r = amdgpu_userq_fence_driver_alloc(adev, &queue->fence_drv);
if (r) {
drm_file_err(uq_mgr->file, "Failed to alloc fence driver\n");
- goto free_queue;
+ goto clean_mapping;
}
r = uq_funcs->mqd_create(queue, &args->in);
@@ -803,6 +806,8 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
goto clean_fence_driver;
}
+ amdgpu_userq_ensure_ev_fence(&fpriv->userq_mgr, &fpriv->evf_mgr);
+
/* don't map the queue if scheduling is halted */
if (adev->userq_halt_for_enforce_isolation &&
((queue->queue_type == AMDGPU_HW_IP_GFX) ||
@@ -814,7 +819,6 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
r = amdgpu_userq_map_helper(queue);
if (r) {
drm_file_err(uq_mgr->file, "Failed to map Queue\n");
- down_read(&adev->reset_domain->sem);
goto clean_mqd;
}
}
@@ -830,9 +834,8 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
if (r) {
if (!skip_map_queue)
amdgpu_userq_unmap_helper(queue);
-
r = -ENOMEM;
- goto clean_mqd;
+ goto clean_reset_domain;
}
r = xa_err(xa_store_irq(&adev->userq_doorbell_xa, index, queue, GFP_KERNEL));
@@ -840,8 +843,7 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
xa_erase(&uq_mgr->userq_xa, qid);
if (!skip_map_queue)
amdgpu_userq_unmap_helper(queue);
-
- goto clean_mqd;
+ goto clean_reset_domain;
}
up_read(&adev->reset_domain->sem);
@@ -853,16 +855,21 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
mutex_unlock(&uq_mgr->userq_mutex);
return 0;
+clean_reset_domain:
+ up_read(&adev->reset_domain->sem);
clean_mqd:
+ mutex_unlock(&uq_mgr->userq_mutex);
uq_funcs->mqd_destroy(queue);
- up_read(&adev->reset_domain->sem);
clean_fence_driver:
amdgpu_userq_fence_driver_free(queue);
+clean_mapping:
+ amdgpu_bo_reserve(fpriv->vm.root.bo, true);
+ amdgpu_userq_buffer_vas_list_cleanup(adev, queue);
+ amdgpu_bo_unreserve(fpriv->vm.root.bo);
free_queue:
kfree(queue);
-unlock:
- mutex_unlock(&uq_mgr->userq_mutex);
-
+err_pm_runtime:
+ pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
@@ -992,10 +999,16 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
static int
amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr)
{
+ struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(uq_mgr);
+ struct amdgpu_vm *vm = &fpriv->vm;
struct amdgpu_usermode_queue *queue;
unsigned long queue_id;
int ret = 0, r;
+
+ if (amdgpu_bo_reserve(vm->root.bo, false))
+ return false;
+
mutex_lock(&uq_mgr->userq_mutex);
/* Resume all the queues for this process */
xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {
@@ -1013,6 +1026,7 @@ amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr)
}
mutex_unlock(&uq_mgr->userq_mutex);
+ amdgpu_bo_unreserve(vm->root.bo);
if (ret)
drm_file_err(uq_mgr->file,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
index 5784f2b3ecae..da39ac862f37 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
@@ -145,13 +145,22 @@ amdgpu_userq_fence_driver_free(struct amdgpu_usermode_queue *userq)
amdgpu_userq_fence_driver_put(userq->fence_drv);
}
+static void
+amdgpu_userq_fence_put_fence_drv_array(struct amdgpu_userq_fence *userq_fence)
+{
+ unsigned long i;
+ for (i = 0; i < userq_fence->fence_drv_array_count; i++)
+ amdgpu_userq_fence_driver_put(userq_fence->fence_drv_array[i]);
+ userq_fence->fence_drv_array_count = 0;
+}
+
void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_drv)
{
struct amdgpu_userq_fence *userq_fence, *tmp;
+ LIST_HEAD(to_be_signaled);
struct dma_fence *fence;
unsigned long flags;
u64 rptr;
- int i;
if (!fence_drv)
return;
@@ -159,21 +168,26 @@ void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_d
spin_lock_irqsave(&fence_drv->fence_list_lock, flags);
rptr = amdgpu_userq_fence_read(fence_drv);
- list_for_each_entry_safe(userq_fence, tmp, &fence_drv->fences, link) {
- fence = &userq_fence->base;
-
- if (rptr < fence->seqno)
+ list_for_each_entry(userq_fence, &fence_drv->fences, link) {
+ if (rptr < userq_fence->base.seqno)
break;
+ }
- dma_fence_signal(fence);
-
- for (i = 0; i < userq_fence->fence_drv_array_count; i++)
- amdgpu_userq_fence_driver_put(userq_fence->fence_drv_array[i]);
+ list_cut_before(&to_be_signaled, &fence_drv->fences,
+ &userq_fence->link);
+ spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags);
- list_del(&userq_fence->link);
+ list_for_each_entry_safe(userq_fence, tmp, &to_be_signaled, link) {
+ fence = &userq_fence->base;
+ list_del_init(&userq_fence->link);
+ dma_fence_signal(fence);
+ /* Drop fence_drv_array outside fence_list_lock
+ * to avoid the recursion lock.
+ */
+ amdgpu_userq_fence_put_fence_drv_array(userq_fence);
dma_fence_put(fence);
}
- spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags);
+
}
void amdgpu_userq_fence_driver_destroy(struct kref *ref)
@@ -228,6 +242,7 @@ static int amdgpu_userq_fence_create(struct amdgpu_usermode_queue *userq,
struct amdgpu_userq_fence_driver *fence_drv;
struct dma_fence *fence;
unsigned long flags;
+ bool signaled = false;
fence_drv = userq->fence_drv;
if (!fence_drv)
@@ -274,13 +289,17 @@ static int amdgpu_userq_fence_create(struct amdgpu_usermode_queue *userq,
/* Check if hardware has already processed the job */
spin_lock_irqsave(&fence_drv->fence_list_lock, flags);
- if (!dma_fence_is_signaled(fence))
+ if (!dma_fence_is_signaled(fence)) {
list_add_tail(&userq_fence->link, &fence_drv->fences);
- else
+ } else {
+ signaled = true;
dma_fence_put(fence);
-
+ }
spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags);
+ if (signaled)
+ amdgpu_userq_fence_put_fence_drv_array(userq_fence);
+
*f = fence;
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index 03d95dca93d7..debb82a2e031 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -34,6 +34,7 @@
#include "amdgpu.h"
#include "amdgpu_pm.h"
#include "amdgpu_vcn.h"
+#include "amdgpu_reset.h"
#include "soc15d.h"
/* Firmware Names */
@@ -361,7 +362,7 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev, int i)
/* err_event_athub and dpc recovery will corrupt VCPU buffer, so we need to
* restore fw data and clear buffer in amdgpu_vcn_resume() */
- if (in_ras_intr || adev->pcie_reset_ctx.in_link_reset)
+ if (in_ras_intr || amdgpu_reset_in_dpc(adev))
return 0;
return amdgpu_vcn_save_vcpu_bo_inst(adev, i);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
index 22e2e5b47341..f078db3fef79 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
@@ -21,6 +21,8 @@
*/
#include "amdgpu_vm.h"
+#include "amdgpu.h"
+#include "amdgpu_reset.h"
#include "amdgpu_object.h"
#include "amdgpu_trace.h"
@@ -108,11 +110,19 @@ static int amdgpu_vm_cpu_update(struct amdgpu_vm_update_params *p,
static int amdgpu_vm_cpu_commit(struct amdgpu_vm_update_params *p,
struct dma_fence **fence)
{
+ struct amdgpu_device *adev = p->adev;
+
if (p->needs_flush)
atomic64_inc(&p->vm->tlb_seq);
mb();
- amdgpu_device_flush_hdp(p->adev, NULL);
+ /* A reset flushed the HDP anyway, so that here can be skipped when a reset is ongoing */
+ if (!down_read_trylock(&adev->reset_domain->sem))
+ return 0;
+
+ amdgpu_device_flush_hdp(adev, NULL);
+ up_read(&adev->reset_domain->sem);
+
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
index 31a437ce9570..a930f1522f96 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
@@ -693,8 +693,11 @@ static void amdgpu_vm_pte_update_flags(struct amdgpu_vm_update_params *params,
!(flags & AMDGPU_PTE_VALID) &&
!(flags & AMDGPU_PTE_PRT_FLAG(params->adev))) {
- /* Workaround for fault priority problem on GMC9 */
- flags |= AMDGPU_PTE_EXECUTABLE;
+ /* Workaround for fault priority problem on GMC9 and GFX12,
+ * EXECUTABLE for GMC9 fault priority and init_pte_flags
+ * (e.g. AMDGPU_PTE_IS_PTE on GFX12)
+ */
+ flags |= AMDGPU_PTE_EXECUTABLE | adev->gmc.init_pte_flags;
}
/*
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index 5097de940a19..8c82e90f871b 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -64,6 +64,11 @@
#define regPC_CONFIG_CNTL_1 0x194d
#define regPC_CONFIG_CNTL_1_BASE_IDX 1
+#define regGOLDEN_TSC_COUNT_UPPER_smu_15_0_0 0x0030
+#define regGOLDEN_TSC_COUNT_UPPER_smu_15_0_0_BASE_IDX 1
+#define regGOLDEN_TSC_COUNT_LOWER_smu_15_0_0 0x0031
+#define regGOLDEN_TSC_COUNT_LOWER_smu_15_0_0_BASE_IDX 1
+
#define regCP_GFX_MQD_CONTROL_DEFAULT 0x00000100
#define regCP_GFX_HQD_VMID_DEFAULT 0x00000000
#define regCP_GFX_HQD_QUEUE_PRIORITY_DEFAULT 0x00000000
@@ -5234,11 +5239,27 @@ static uint64_t gfx_v11_0_get_gpu_clock_counter(struct amdgpu_device *adev)
amdgpu_gfx_off_ctrl(adev, true);
} else {
preempt_disable();
- clock_counter_hi_pre = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER);
- clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER);
- clock_counter_hi_after = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER);
- if (clock_counter_hi_pre != clock_counter_hi_after)
- clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER);
+ if (amdgpu_ip_version(adev, SMUIO_HWIP, 0) < IP_VERSION(15, 0, 0)) {
+ clock_counter_hi_pre = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_UPPER);
+ clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_LOWER);
+ clock_counter_hi_after = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_UPPER);
+ if (clock_counter_hi_pre != clock_counter_hi_after)
+ clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_LOWER);
+ } else {
+ clock_counter_hi_pre = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_UPPER_smu_15_0_0);
+ clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_LOWER_smu_15_0_0);
+ clock_counter_hi_after = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_UPPER_smu_15_0_0);
+ if (clock_counter_hi_pre != clock_counter_hi_after)
+ clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0,
+ regGOLDEN_TSC_COUNT_LOWER_smu_15_0_0);
+ }
preempt_enable();
}
clock = clock_counter_lo | (clock_counter_hi_after << 32ULL);
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
index 4b4aa9553624..82abe181c730 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
@@ -736,15 +736,35 @@ static void jpeg_v4_0_3_dec_ring_set_wptr(struct amdgpu_ring *ring)
*/
void jpeg_v4_0_3_dec_ring_insert_start(struct amdgpu_ring *ring)
{
- if (!amdgpu_sriov_vf(ring->adev)) {
+ struct amdgpu_device *adev = ring->adev;
+
+ if (!amdgpu_sriov_vf(adev)) {
+ int jpeg_inst = GET_INST(JPEG, ring->me);
+ uint32_t value = 0x80004000; /* default DS14 */
+
amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
0, 0, PACKETJ_TYPE0));
- amdgpu_ring_write(ring, 0x62a04); /* PCTL0_MMHUB_DEEPSLEEP_IB */
+
+ /* PCTL0__MMHUB_DEEPSLEEP_IB could be different on different mmhub version */
+ switch (amdgpu_ip_version(adev, MMHUB_HWIP, 0)) {
+ case IP_VERSION(4, 1, 0):
+ amdgpu_ring_write(ring, 0x69004);
+ value = 0x80010000;
+ break;
+ case IP_VERSION(4, 2, 0):
+ amdgpu_ring_write(ring, 0x60804);
+ if (jpeg_inst & 1)
+ value = 0x80010000;
+ break;
+ default:
+ amdgpu_ring_write(ring, 0x62a04);
+ break;
+ }
amdgpu_ring_write(ring,
PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, 0,
0, PACKETJ_TYPE0));
- amdgpu_ring_write(ring, 0x80004000);
+ amdgpu_ring_write(ring, value);
}
}
@@ -757,15 +777,35 @@ void jpeg_v4_0_3_dec_ring_insert_start(struct amdgpu_ring *ring)
*/
void jpeg_v4_0_3_dec_ring_insert_end(struct amdgpu_ring *ring)
{
- if (!amdgpu_sriov_vf(ring->adev)) {
+ struct amdgpu_device *adev = ring->adev;
+
+ if (!amdgpu_sriov_vf(adev)) {
+ int jpeg_inst = GET_INST(JPEG, ring->me);
+ uint32_t value = 0x00004000; /* default DS14 */
+
amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
0, 0, PACKETJ_TYPE0));
- amdgpu_ring_write(ring, 0x62a04);
+
+ /* PCTL0__MMHUB_DEEPSLEEP_IB could be different on different mmhub version */
+ switch (amdgpu_ip_version(adev, MMHUB_HWIP, 0)) {
+ case IP_VERSION(4, 1, 0):
+ amdgpu_ring_write(ring, 0x69004);
+ value = 0x00010000;
+ break;
+ case IP_VERSION(4, 2, 0):
+ amdgpu_ring_write(ring, 0x60804);
+ if (jpeg_inst & 1)
+ value = 0x00010000;
+ break;
+ default:
+ amdgpu_ring_write(ring, 0x62a04);
+ break;
+ }
amdgpu_ring_write(ring,
PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, 0,
0, PACKETJ_TYPE0));
- amdgpu_ring_write(ring, 0x00004000);
+ amdgpu_ring_write(ring, value);
}
}
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index faac21ee5739..2fc39a6938f6 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -322,8 +322,14 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
goto free_mqd;
}
+ r = amdgpu_bo_reserve(queue->vm->root.bo, false);
+ if (r) {
+ kfree(compute_mqd);
+ goto free_mqd;
+ }
r = amdgpu_userq_input_va_validate(adev, queue, compute_mqd->eop_va,
2048);
+ amdgpu_bo_unreserve(queue->vm->root.bo);
if (r) {
kfree(compute_mqd);
goto free_mqd;
@@ -365,14 +371,22 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
userq_props->tmz_queue =
mqd_user->flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE;
+ r = amdgpu_bo_reserve(queue->vm->root.bo, false);
+ if (r) {
+ kfree(mqd_gfx_v11);
+ goto free_mqd;
+ }
r = amdgpu_userq_input_va_validate(adev, queue, mqd_gfx_v11->shadow_va,
shadow_info.shadow_size);
if (r) {
+ amdgpu_bo_unreserve(queue->vm->root.bo);
kfree(mqd_gfx_v11);
goto free_mqd;
}
+
r = amdgpu_userq_input_va_validate(adev, queue, mqd_gfx_v11->csa_va,
shadow_info.csa_size);
+ amdgpu_bo_unreserve(queue->vm->root.bo);
if (r) {
kfree(mqd_gfx_v11);
goto free_mqd;
@@ -394,8 +408,15 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
r = -ENOMEM;
goto free_mqd;
}
+
+ r = amdgpu_bo_reserve(queue->vm->root.bo, false);
+ if (r) {
+ kfree(mqd_sdma_v11);
+ goto free_mqd;
+ }
r = amdgpu_userq_input_va_validate(adev, queue, mqd_sdma_v11->csa_va,
32);
+ amdgpu_bo_unreserve(queue->vm->root.bo);
if (r) {
kfree(mqd_sdma_v11);
goto free_mqd;
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
index 0e9089544769..cec801278126 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
@@ -2028,7 +2028,7 @@ static int mes_v12_1_test_ring(struct amdgpu_device *adev, int xcc_id,
int num_xcc = NUM_XCC(adev->gfx.xcc_mask);
int sdma_ring_align = 0x10, compute_ring_align = 0x100;
uint32_t tmp, xcc_offset;
- int r = 0, i, wptr = 0;
+ int r = 0, i, j, wptr = 0;
if (queue_type == AMDGPU_RING_TYPE_COMPUTE) {
if (!adev->mes.enable_coop_mode) {
@@ -2077,11 +2077,11 @@ static int mes_v12_1_test_ring(struct amdgpu_device *adev, int xcc_id,
tmp = RREG32_SOC15(GC, GET_INST(GC, xcc_id),
regSCRATCH_REG0);
} else {
- for (i = 0; i < num_xcc; i++) {
- if (xcc_id != adev->mes.master_xcc_ids[i])
+ for (j = 0; j < num_xcc; j++) {
+ if (xcc_id != adev->mes.master_xcc_ids[j])
continue;
- tmp = RREG32_SOC15(GC, GET_INST(GC, i),
+ tmp = RREG32_SOC15(GC, GET_INST(GC, j),
regSCRATCH_REG0);
if (tmp != 0xDEADBEEF)
break;
diff --git a/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c b/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c
index db14a1a326d2..b6f832c53860 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbif_v6_3_1.c
@@ -54,6 +54,8 @@
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL_nbif_4_10_BASE_IDX 3
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL1_nbif_4_10 0x4f0af6
#define regGDC_S2A0_S2A_DOORBELL_ENTRY_5_CTRL1_nbif_4_10_BASE_IDX 3
+#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10 0x0021
+#define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10_BASE_IDX 2
static void nbif_v6_3_1_remap_hdp_registers(struct amdgpu_device *adev)
{
@@ -65,7 +67,12 @@ static void nbif_v6_3_1_remap_hdp_registers(struct amdgpu_device *adev)
static u32 nbif_v6_3_1_get_rev_id(struct amdgpu_device *adev)
{
- u32 tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0);
+ u32 tmp;
+
+ if (amdgpu_ip_version(adev, NBIO_HWIP, 0) == IP_VERSION(7, 11, 4))
+ tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_nbif_4_10);
+ else
+ tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0);
tmp &= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK;
tmp >>= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT;
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c
index 73a709773e85..2a8582e87f2b 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c
@@ -32,6 +32,7 @@
#include "mp/mp_15_0_0_sh_mask.h"
MODULE_FIRMWARE("amdgpu/psp_15_0_0_toc.bin");
+MODULE_FIRMWARE("amdgpu/psp_15_0_0_ta.bin");
static int psp_v15_0_0_init_microcode(struct psp_context *psp)
{
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
index f20e0fc3fc74..061934a2e93a 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_1.c
@@ -1268,6 +1268,18 @@ static int sdma_v7_1_early_init(struct amdgpu_ip_block *ip_block)
struct amdgpu_device *adev = ip_block->adev;
int r;
+ switch (amdgpu_user_queue) {
+ case -1:
+ default:
+ adev->sdma.no_user_submission = true;
+ adev->sdma.disable_uq = true;
+ break;
+ case 0:
+ adev->sdma.no_user_submission = false;
+ adev->sdma.disable_uq = true;
+ break;
+ }
+
r = amdgpu_sdma_init_microcode(adev, 0, true);
if (r) {
DRM_ERROR("Failed to init sdma firmware!\n");
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 462a32abf720..55ea5145a28a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -776,6 +776,9 @@ static int kfd_ioctl_get_process_apertures_new(struct file *filp,
goto out_unlock;
}
+ if (args->num_of_nodes > kfd_topology_get_num_devices())
+ return -EINVAL;
+
/* Fill in process-aperture information for all available
* nodes, but not more than args->num_of_nodes as that is
* the amount of memory allocated by user
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index fa025bea9b4f..6e333bfa17d6 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -1191,6 +1191,7 @@ static inline struct kfd_node *kfd_node_by_irq_ids(struct amdgpu_device *adev,
return NULL;
}
int kfd_topology_enum_kfd_devices(uint8_t idx, struct kfd_node **kdev);
+uint32_t kfd_topology_get_num_devices(void);
int kfd_numa_node_to_apic_id(int numa_node_id);
uint32_t kfd_gpu_node_num(void);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index 995f2c2528a9..29dee26261ab 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -2297,6 +2297,17 @@ int kfd_topology_remove_device(struct kfd_node *gpu)
return res;
}
+uint32_t kfd_topology_get_num_devices(void)
+{
+ uint32_t num_devices;
+
+ down_read(&topology_lock);
+ num_devices = sys_props.num_devices;
+ up_read(&topology_lock);
+
+ return num_devices;
+}
+
/* kfd_topology_enum_kfd_devices - Enumerate through all devices in KFD
* topology. If GPU device is found @idx, then valid kfd_dev pointer is
* returned through @kdev
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1d9ceb432ec3..e96a12ff2d31 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -95,6 +95,7 @@
#include <drm/drm_utils.h>
#include <drm/drm_vblank.h>
#include <drm/drm_audio_component.h>
+#include <drm/drm_colorop.h>
#include <drm/drm_gem_atomic_helper.h>
#include <media/cec-notifier.h>
@@ -2255,6 +2256,10 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
adev->dm.idle_workqueue = NULL;
}
+ /* Disable ISM before dc_destroy() invalidates dm->dc */
+ scoped_guard(mutex, &adev->dm.dc_lock)
+ amdgpu_dm_ism_disable(&adev->dm);
+
amdgpu_dm_destroy_drm_device(&adev->dm);
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
@@ -3994,7 +3999,7 @@ void amdgpu_dm_update_connector_after_detect(
if (sink) {
if (aconnector->dc_sink) {
- amdgpu_dm_update_freesync_caps(connector, NULL);
+ amdgpu_dm_update_freesync_caps(connector, NULL, true);
/*
* retain and release below are used to
* bump up refcount for sink because the link doesn't point
@@ -4006,9 +4011,9 @@ void amdgpu_dm_update_connector_after_detect(
aconnector->dc_sink = sink;
dc_sink_retain(aconnector->dc_sink);
amdgpu_dm_update_freesync_caps(connector,
- aconnector->drm_edid);
+ aconnector->drm_edid, true);
} else {
- amdgpu_dm_update_freesync_caps(connector, NULL);
+ amdgpu_dm_update_freesync_caps(connector, NULL, true);
if (!aconnector->dc_sink) {
aconnector->dc_sink = aconnector->dc_em_sink;
dc_sink_retain(aconnector->dc_sink);
@@ -4052,7 +4057,7 @@ void amdgpu_dm_update_connector_after_detect(
* If yes, put it here.
*/
if (aconnector->dc_sink) {
- amdgpu_dm_update_freesync_caps(connector, NULL);
+ amdgpu_dm_update_freesync_caps(connector, NULL, true);
dc_sink_release(aconnector->dc_sink);
}
@@ -4085,13 +4090,13 @@ void amdgpu_dm_update_connector_after_detect(
"failed to create aconnector->requested_timing\n");
}
- amdgpu_dm_update_freesync_caps(connector, aconnector->drm_edid);
+ amdgpu_dm_update_freesync_caps(connector, aconnector->drm_edid, true);
update_connector_ext_caps(aconnector);
dm_set_panel_type(aconnector);
} else {
hdmi_cec_unset_edid(aconnector);
drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux);
- amdgpu_dm_update_freesync_caps(connector, NULL);
+ amdgpu_dm_update_freesync_caps(connector, NULL, true);
aconnector->num_modes = 0;
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
@@ -8855,7 +8860,7 @@ static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector,
* drm_edid_connector_add_modes() and need to be
* restored here.
*/
- amdgpu_dm_update_freesync_caps(connector, drm_edid);
+ amdgpu_dm_update_freesync_caps(connector, drm_edid, false);
} else {
amdgpu_dm_connector->num_modes = 0;
}
@@ -12330,6 +12335,38 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm
*/
/**
+ * dm_plane_color_pipeline_active() - Check if a plane's color pipeline active.
+ * @state: DRM atomic state
+ * @plane: DRM plane to check
+ * @use_old: if true, inspect the old colorop states; otherwise the new ones
+ *
+ * A color pipeline may be selected (color_pipeline != NULL) but still is
+ * inactive if every colorop in the chain is bypassed. Only return
+ * true when at least one colorop has bypass == false, meaning the cursor
+ * would be subjected to the transformation in native mode.
+ *
+ * Return: true if the pipeline modifies pixels, false otherwise.
+ */
+static bool dm_plane_color_pipeline_active(struct drm_atomic_state *state,
+ struct drm_plane *plane,
+ bool use_old)
+{
+ struct drm_colorop *colorop;
+ struct drm_colorop_state *old_colorop_state, *new_colorop_state;
+ int i;
+
+ for_each_oldnew_colorop_in_state(state, colorop, old_colorop_state, new_colorop_state, i) {
+ struct drm_colorop_state *cstate = use_old ? old_colorop_state : new_colorop_state;
+
+ if (cstate->colorop->plane != plane)
+ continue;
+ if (!cstate->bypass)
+ return true;
+ }
+ return false;
+}
+
+/**
* dm_crtc_get_cursor_mode() - Determine the required cursor mode on crtc
* @adev: amdgpu device
* @state: DRM atomic state
@@ -12340,8 +12377,8 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm
* the dm_crtc_state.
*
* The cursor should be enabled in overlay mode if there exists an underlying
- * plane - on which the cursor may be blended - that is either YUV formatted, or
- * scaled differently from the cursor.
+ * plane - on which the cursor may be blended - that is either YUV formatted,
+ * scaled differently from the cursor, or has a color pipeline active.
*
* Since zpos info is required, drm_atomic_normalize_zpos must be called before
* calling this function.
@@ -12379,7 +12416,7 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev,
/*
* Cursor mode can change if a plane's format changes, scale changes, is
- * enabled/disabled, or z-order changes.
+ * enabled/disabled, z-order changes, or color management properties change.
*/
for_each_oldnew_plane_in_state(state, plane, old_plane_state, plane_state, i) {
int new_scale_w, new_scale_h, old_scale_w, old_scale_h;
@@ -12404,6 +12441,12 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev,
consider_mode_change = true;
break;
}
+
+ if (dm_plane_color_pipeline_active(state, plane, true) !=
+ dm_plane_color_pipeline_active(state, plane, false)) {
+ consider_mode_change = true;
+ break;
+ }
}
if (!consider_mode_change && !crtc_state->zpos_changed)
@@ -12444,6 +12487,12 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev,
return 0;
}
+ /* Underlying plane has an active color pipeline - cursor would be transformed */
+ if (dm_plane_color_pipeline_active(state, plane, false)) {
+ *cursor_mode = DM_CURSOR_OVERLAY_MODE;
+ return 0;
+ }
+
dm_get_plane_scale(plane_state,
&underlying_scale_w, &underlying_scale_h);
dm_get_plane_scale(cursor_state,
@@ -12823,7 +12872,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
goto fail;
} else if (required_cursor_mode == DM_CURSOR_OVERLAY_MODE) {
drm_dbg_driver(crtc->dev,
- "[CRTC:%d:%s] Cannot enable native cursor due to scaling or YUV restrictions\n",
+ "[CRTC:%d:%s] Cannot enable native cursor due to scaling, YUV, or color pipeline restrictions\n",
crtc->base.id, crtc->name);
ret = -EINVAL;
goto fail;
@@ -13088,6 +13137,7 @@ static bool dm_edid_parser_send_cea(struct amdgpu_display_manager *dm,
vsdb->amd_vsdb_version = output->amd_vsdb.amd_vsdb_version;
vsdb->min_refresh_rate_hz = output->amd_vsdb.min_frame_rate;
vsdb->max_refresh_rate_hz = output->amd_vsdb.max_frame_rate;
+ vsdb->freesync_mccs_vcp_code = output->amd_vsdb.freesync_mccs_vcp_code;
} else {
drm_warn(adev_to_drm(dm->adev), "Unknown EDID CEA parser results\n");
return false;
@@ -13122,6 +13172,8 @@ static bool parse_edid_cea_dmcu(struct amdgpu_display_manager *dm,
vsdb_info->amd_vsdb_version = version;
vsdb_info->min_refresh_rate_hz = min_rate;
vsdb_info->max_refresh_rate_hz = max_rate;
+ /* Not enabled on DMCU*/
+ vsdb_info->freesync_mccs_vcp_code = 0;
return true;
}
/* not amd vsdb */
@@ -13260,6 +13312,10 @@ static int parse_hdmi_amd_vsdb(struct amdgpu_dm_connector *aconnector,
*
* @connector: Connector to query.
* @drm_edid: DRM EDID from monitor
+ * @do_mccs: Controls whether MCCS (Monitor Control Command Set) over
+ * DDC (Display Data Channel) transactions are performed. When true,
+ * the driver queries the monitor to get or update additional FreeSync
+ * capability information. When false, these transactions are skipped.
*
* Amdgpu supports Freesync in DP and HDMI displays, and it is required to keep
* track of some of the display information in the internal data struct used by
@@ -13267,7 +13323,7 @@ static int parse_hdmi_amd_vsdb(struct amdgpu_dm_connector *aconnector,
* FreeSync parameters.
*/
void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
- const struct drm_edid *drm_edid)
+ const struct drm_edid *drm_edid, bool do_mccs)
{
int i = 0;
struct amdgpu_dm_connector *amdgpu_dm_connector =
@@ -13333,14 +13389,19 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
} else if (drm_edid && sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) {
i = parse_hdmi_amd_vsdb(amdgpu_dm_connector, edid, &vsdb_info);
- if (i >= 0 && vsdb_info.freesync_supported) {
- amdgpu_dm_connector->min_vfreq = vsdb_info.min_refresh_rate_hz;
- amdgpu_dm_connector->max_vfreq = vsdb_info.max_refresh_rate_hz;
- if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10)
- freesync_capable = true;
+ if (i >= 0) {
+ amdgpu_dm_connector->vsdb_info = vsdb_info;
+ sink->edid_caps.freesync_vcp_code = vsdb_info.freesync_mccs_vcp_code;
- connector->display_info.monitor_range.min_vfreq = vsdb_info.min_refresh_rate_hz;
- connector->display_info.monitor_range.max_vfreq = vsdb_info.max_refresh_rate_hz;
+ if (vsdb_info.freesync_supported) {
+ amdgpu_dm_connector->min_vfreq = vsdb_info.min_refresh_rate_hz;
+ amdgpu_dm_connector->max_vfreq = vsdb_info.max_refresh_rate_hz;
+ if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10)
+ freesync_capable = true;
+
+ connector->display_info.monitor_range.min_vfreq = vsdb_info.min_refresh_rate_hz;
+ connector->display_info.monitor_range.max_vfreq = vsdb_info.max_refresh_rate_hz;
+ }
}
}
@@ -13349,22 +13410,38 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
if (as_type == FREESYNC_TYPE_PCON_IN_WHITELIST) {
i = parse_hdmi_amd_vsdb(amdgpu_dm_connector, edid, &vsdb_info);
- if (i >= 0 && vsdb_info.freesync_supported && vsdb_info.amd_vsdb_version > 0) {
-
- amdgpu_dm_connector->pack_sdp_v1_3 = true;
- amdgpu_dm_connector->as_type = as_type;
+ if (i >= 0) {
amdgpu_dm_connector->vsdb_info = vsdb_info;
+ sink->edid_caps.freesync_vcp_code = vsdb_info.freesync_mccs_vcp_code;
- amdgpu_dm_connector->min_vfreq = vsdb_info.min_refresh_rate_hz;
- amdgpu_dm_connector->max_vfreq = vsdb_info.max_refresh_rate_hz;
- if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10)
- freesync_capable = true;
+ if (vsdb_info.freesync_supported && vsdb_info.amd_vsdb_version > 0) {
+ amdgpu_dm_connector->pack_sdp_v1_3 = true;
+ amdgpu_dm_connector->as_type = as_type;
- connector->display_info.monitor_range.min_vfreq = vsdb_info.min_refresh_rate_hz;
- connector->display_info.monitor_range.max_vfreq = vsdb_info.max_refresh_rate_hz;
+ amdgpu_dm_connector->min_vfreq = vsdb_info.min_refresh_rate_hz;
+ amdgpu_dm_connector->max_vfreq = vsdb_info.max_refresh_rate_hz;
+ if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10)
+ freesync_capable = true;
+
+ connector->display_info.monitor_range.min_vfreq = vsdb_info.min_refresh_rate_hz;
+ connector->display_info.monitor_range.max_vfreq = vsdb_info.max_refresh_rate_hz;
+ }
}
}
+ /* Handle MCCS */
+ if (do_mccs)
+ dm_helpers_read_mccs_caps(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
+
+ if ((sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A ||
+ as_type == FREESYNC_TYPE_PCON_IN_WHITELIST) &&
+ (!sink->edid_caps.freesync_vcp_code ||
+ (sink->edid_caps.freesync_vcp_code && !sink->mccs_caps.freesync_supported)))
+ freesync_capable = false;
+
+ if (do_mccs && sink->mccs_caps.freesync_supported && freesync_capable)
+ dm_helpers_mccs_vcp_set(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
+
update:
if (dm_con_state)
dm_con_state->freesync_capable = freesync_capable;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 63ce1f52b697..74a8fe1a1999 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -759,6 +759,11 @@ struct amdgpu_hdmi_vsdb_info {
unsigned int max_refresh_rate_hz;
/**
+ * @freesync_mccs_vcp_code: MCCS VCP code for freesync state
+ */
+ unsigned int freesync_mccs_vcp_code;
+
+ /**
* @replay_mode: Replay supported
*/
bool replay_mode;
@@ -1066,7 +1071,7 @@ void dm_restore_drm_connector_state(struct drm_device *dev,
struct drm_connector *connector);
void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
- const struct drm_edid *drm_edid);
+ const struct drm_edid *drm_edid, bool do_mccs);
void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 5d2715f78314..d69f5a75b685 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -457,9 +457,12 @@ static struct drm_crtc_state *amdgpu_dm_crtc_duplicate_state(struct drm_crtc *cr
static void amdgpu_dm_crtc_destroy(struct drm_crtc *crtc)
{
- struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
+ /*
+ * amdgpu_dm_ism_fini() is intentionally called in amdgpu_dm_fini().
+ * It must be called before dc_destroy() in amdgpu_dm_fini()
+ * to avoid ISM accessing an invalid dc handle once dc is released.
+ */
- amdgpu_dm_ism_fini(&acrtc->ism);
drm_crtc_cleanup(crtc);
kfree(crtc);
}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index f3fa8eb4bcce..3b8ae7798a93 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -49,6 +49,45 @@
#include "ddc_service_types.h"
#include "clk_mgr.h"
+#define MCCS_DEST_ADDR (0x6E >> 1)
+#define MCCS_SRC_ADDR 0x51
+#define MCCS_LENGTH_OFFSET 0x80
+#define MCCS_MAX_DATA_SIZE 0x20
+
+enum mccs_op_code {
+ MCCS_OP_CODE_VCP_REQUEST = 0x01,
+ MCCS_OP_CODE_VCP_REPLY = 0x02,
+ MCCS_OP_CODE_VCP_SET = 0x03,
+ MCCS_OP_CODE_VCP_RESET = 0x09,
+ MCCS_OP_CODE_CAP_REQUEST = 0xF3,
+ MCCS_OP_CODE_CAP_REPLY = 0xE3
+};
+
+enum mccs_op_buff_size {
+ MCCS_OP_BUFF_SIZE__WR_VCP_REQUEST = 5,
+ MCCS_OP_BUFF_SIZE_RD_VCP_REQUEST = 11,
+ MCCS_OP_BUFF_SIZE_WR_VCP_SET = 7,
+};
+
+enum vcp_reply_mask {
+ FREESYNC_SUPPORTED = 0x1
+};
+
+union vcp_reply {
+ struct {
+ unsigned char src_addr;
+ unsigned char length; /* Length is offset by MccsLengthOffs = 0x80 */
+ unsigned char reply_op_code; /* Should return MCCS_OP_CODE_VCP_REPLY = 0x02 */
+ unsigned char result_code; /* 00h No Error, 01h Unsupported VCP Code */
+ unsigned char request_code; /* Should return mccs vcp code sent in the vcp request */
+ unsigned char type_code; /* VCP type code: 00h Set parameter, 01h Momentary */
+ unsigned char max_value[2]; /* 2 bytes returning max value current value */
+ unsigned char present_value[2]; /* NOTE: Byte0 is MSB, Byte1 is LSB */
+ unsigned char check_sum;
+ } bytes;
+ unsigned char raw[11];
+};
+
static u32 edid_extract_panel_id(struct edid *edid)
{
return (u32)edid->mfg_id[0] << 24 |
@@ -1400,6 +1439,8 @@ static bool dm_is_freesync_pcon_whitelist(const uint32_t branch_dev_id)
case DP_BRANCH_DEVICE_ID_0060AD:
case DP_BRANCH_DEVICE_ID_00E04C:
case DP_BRANCH_DEVICE_ID_90CC24:
+ case DP_BRANCH_DEVICE_ID_001CF8:
+ case DP_BRANCH_DEVICE_ID_001FF2:
ret_val = true;
break;
default:
@@ -1439,3 +1480,203 @@ bool dm_helpers_is_hdr_on(struct dc_context *ctx, struct dc_stream_state *stream
// TODO
return false;
}
+
+static int mccs_operation_vcp_request(unsigned int vcp_code, struct dc_link *link,
+ union vcp_reply *reply)
+{
+ const unsigned char retry_interval_ms = 40;
+ unsigned char retry = 5;
+ struct amdgpu_dm_connector *aconnector = link->priv;
+ struct i2c_adapter *ddc;
+ struct i2c_msg msg = {0};
+ int ret = 0;
+ int idx;
+
+ unsigned char wr_data[MCCS_OP_BUFF_SIZE__WR_VCP_REQUEST] = {
+ MCCS_SRC_ADDR, /* Byte0 - Src Addr */
+ MCCS_LENGTH_OFFSET + 2, /* Byte1 - Length */
+ MCCS_OP_CODE_VCP_REQUEST, /* Byte2 - MCCS Command */
+ (unsigned char) vcp_code, /* Byte3 - VCP Code */
+ MCCS_DEST_ADDR << 1 /* Byte4 - CheckSum */
+ };
+
+ /* calculate checksum */
+ for (idx = 0; idx < (MCCS_OP_BUFF_SIZE__WR_VCP_REQUEST - 1); idx++)
+ wr_data[(MCCS_OP_BUFF_SIZE__WR_VCP_REQUEST-1)] ^= wr_data[idx];
+
+ if (link->aux_mode)
+ ddc = &aconnector->dm_dp_aux.aux.ddc;
+ else
+ ddc = &aconnector->i2c->base;
+
+ do {
+ msg.addr = MCCS_DEST_ADDR;
+ msg.flags = 0;
+ msg.len = MCCS_OP_BUFF_SIZE__WR_VCP_REQUEST;
+ msg.buf = wr_data;
+
+ ret = i2c_transfer(ddc, &msg, 1);
+ if (ret != 1)
+ goto mccs_retry;
+
+ msleep(retry_interval_ms);
+
+ msg.addr = MCCS_DEST_ADDR;
+ msg.flags = I2C_M_RD;
+ msg.len = MCCS_OP_BUFF_SIZE_RD_VCP_REQUEST;
+ msg.buf = reply->raw;
+
+ ret = i2c_transfer(ddc, &msg, 1);
+
+ /* sink might reply with null msg if it can't reply in time */
+ if (ret == 1 && reply->bytes.length > MCCS_LENGTH_OFFSET)
+ break;
+mccs_retry:
+ retry--;
+ msleep(retry_interval_ms);
+ } while (retry);
+
+ if (!retry) {
+ drm_dbg_driver(aconnector->base.dev,
+ "%s: MCCS VCP request failed after retries", __func__);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+void dm_helpers_read_mccs_caps(struct dc_context *ctx, struct dc_link *link,
+ struct dc_sink *sink)
+{
+ bool mccs_op = false;
+ struct dpcd_caps *dpcd_caps;
+ struct drm_device *dev;
+ uint16_t freesync_vcp_value = 0;
+ union vcp_reply vcp_reply_value = {0};
+
+ if (!ctx)
+ return;
+ dev = adev_to_drm(ctx->driver_context);
+
+ if (!link || !sink) {
+ drm_dbg_driver(dev, "%s: link or sink is NULL", __func__);
+ return;
+ }
+
+ sink->mccs_caps.freesync_supported = false;
+ dpcd_caps = &link->dpcd_caps;
+
+ if (sink->edid_caps.freesync_vcp_code != 0) {
+ if (dc_is_dp_signal(link->connector_signal)) {
+ if ((dpcd_caps->dpcd_rev.raw >= DPCD_REV_14) &&
+ (dpcd_caps->dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER) &&
+ dm_is_freesync_pcon_whitelist(dpcd_caps->branch_dev_id) &&
+ (dpcd_caps->adaptive_sync_caps.dp_adap_sync_caps.bits.ADAPTIVE_SYNC_SDP_SUPPORT == true))
+ mccs_op = true;
+
+ if ((dpcd_caps->dongle_type != DISPLAY_DONGLE_NONE &&
+ dpcd_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER)) {
+ if (mccs_op == false)
+ drm_dbg_driver(dev, "%s: Legacy Pcon support", __func__);
+ mccs_op = true;
+ }
+
+ if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
+ // Todo: Freesync over MST
+ mccs_op = false;
+ }
+ }
+
+ if (dc_is_hdmi_signal(link->connector_signal)) {
+ drm_dbg_driver(dev, "%s: Local HDMI sink", __func__);
+ mccs_op = true;
+ }
+
+ if (mccs_op == true) {
+ // MCCS VCP request to get VCP value
+ if (!mccs_operation_vcp_request(sink->edid_caps.freesync_vcp_code, link,
+ &vcp_reply_value)) {
+ freesync_vcp_value = vcp_reply_value.bytes.present_value[1];
+ freesync_vcp_value |= (uint16_t) vcp_reply_value.bytes.present_value[0] << 8;
+ }
+ // If VCP Value bit 0 is 1, freesyncSupport = true
+ sink->mccs_caps.freesync_supported =
+ (freesync_vcp_value & FREESYNC_SUPPORTED) ? true : false;
+ }
+ }
+}
+
+static int mccs_operation_vcp_set(unsigned int vcp_code, struct dc_link *link, uint16_t value)
+{
+ const unsigned char retry_interval_ms = 40;
+ unsigned char retry = 5;
+ struct amdgpu_dm_connector *aconnector = link->priv;
+ struct i2c_adapter *ddc;
+ struct i2c_msg msg = {0};
+ int ret = 0;
+ int idx;
+
+ unsigned char wr_data[MCCS_OP_BUFF_SIZE_WR_VCP_SET] = {
+ MCCS_SRC_ADDR, /* Byte0 - Src Addr */
+ MCCS_LENGTH_OFFSET + 4, /* Byte1 - Length */
+ MCCS_OP_CODE_VCP_SET, /* Byte2 - MCCS Command */
+ (unsigned char)vcp_code, /* Byte3 - VCP Code */
+ (unsigned char)(value >> 8), /* Byte4 - Value High Byte */
+ (unsigned char)(value & 0xFF), /* Byte5 - Value Low Byte */
+ MCCS_DEST_ADDR << 1 /* Byte6 - CheckSum */
+ };
+
+ /* calculate checksum */
+ for (idx = 0; idx < (MCCS_OP_BUFF_SIZE_WR_VCP_SET - 1); idx++)
+ wr_data[MCCS_OP_BUFF_SIZE_WR_VCP_SET - 1] ^= wr_data[idx];
+
+ if (link->aux_mode)
+ ddc = &aconnector->dm_dp_aux.aux.ddc;
+ else
+ ddc = &aconnector->i2c->base;
+
+ do {
+ msg.addr = MCCS_DEST_ADDR;
+ msg.flags = 0;
+ msg.len = MCCS_OP_BUFF_SIZE_WR_VCP_SET;
+ msg.buf = wr_data;
+
+ ret = i2c_transfer(ddc, &msg, 1);
+ if (ret == 1)
+ break;
+
+ retry--;
+ msleep(retry_interval_ms);
+ } while (retry);
+
+ if (!retry)
+ return -EIO;
+
+ return 0;
+}
+
+void dm_helpers_mccs_vcp_set(struct dc_context *ctx, struct dc_link *link,
+ struct dc_sink *sink)
+{
+ struct drm_device *dev;
+ const uint16_t enable = 0x0101;
+
+ if (!ctx)
+ return;
+ dev = adev_to_drm(ctx->driver_context);
+
+ if (!link || !sink) {
+ drm_dbg_driver(dev, "%s: link or sink is NULL", __func__);
+ return;
+ }
+
+ if (!sink->mccs_caps.freesync_supported) {
+ drm_dbg_driver(dev, "%s: MCCS freesync not supported on this sink", __func__);
+ return;
+ }
+
+ if (mccs_operation_vcp_set(sink->edid_caps.freesync_vcp_code, link, enable))
+ drm_dbg_driver(dev, "%s: Failed to set VCP code %d", __func__,
+ sink->edid_caps.freesync_vcp_code);
+}
+
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_ism.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_ism.c
index a3ccb6fdc372..a64e95860e99 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_ism.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_ism.c
@@ -270,7 +270,6 @@ static void dm_ism_commit_idle_optimization_state(struct amdgpu_dm_ism *ism,
struct amdgpu_crtc *acrtc = ism_to_amdgpu_crtc(ism);
struct amdgpu_device *adev = drm_to_adev(acrtc->base.dev);
struct amdgpu_display_manager *dm = &adev->dm;
- int r;
trace_amdgpu_dm_ism_commit(dm->active_vblank_irq_count,
vblank_enabled,
@@ -323,16 +322,7 @@ static void dm_ism_commit_idle_optimization_state(struct amdgpu_dm_ism *ism,
*/
if (!vblank_enabled && dm->active_vblank_irq_count == 0) {
dc_post_update_surfaces_to_stream(dm->dc);
-
- r = amdgpu_dpm_pause_power_profile(adev, true);
- if (r)
- dev_warn(adev->dev, "failed to set default power profile mode\n");
-
dc_allow_idle_optimizations(dm->dc, true);
-
- r = amdgpu_dpm_pause_power_profile(adev, false);
- if (r)
- dev_warn(adev->dev, "failed to restore the power profile mode\n");
}
}
@@ -472,6 +462,9 @@ void amdgpu_dm_ism_commit_event(struct amdgpu_dm_ism *ism,
/* ISM transitions must be called with mutex acquired */
ASSERT(mutex_is_locked(&dm->dc_lock));
+ /* ISM should not run after dc is destroyed */
+ ASSERT(dm->dc);
+
if (!acrtc_state) {
trace_amdgpu_dm_ism_event(acrtc->crtc_id, "NO_STATE",
"NO_STATE", "N/A");
@@ -545,6 +538,8 @@ void amdgpu_dm_ism_disable(struct amdgpu_display_manager *dm)
struct amdgpu_crtc *acrtc;
struct amdgpu_dm_ism *ism;
+ ASSERT(mutex_is_locked(&dm->dc_lock));
+
drm_for_each_crtc(crtc, dm->ddev) {
acrtc = to_amdgpu_crtc(crtc);
ism = &acrtc->ism;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 5d8c4c7020b1..be038d9014bb 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -474,7 +474,7 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
if (aconnector->dc_sink) {
amdgpu_dm_update_freesync_caps(
- connector, aconnector->drm_edid);
+ connector, aconnector->drm_edid, true);
#if defined(CONFIG_DRM_AMD_DC_FP)
if (!validate_dsc_caps_on_connector(aconnector))
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c
index ec888aed207d..6a97ce69a562 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn42/dcn42_clk_mgr.c
@@ -611,80 +611,6 @@ static struct clk_bw_params dcn42_bw_params = {
};
-static struct wm_table ddr5_wm_table = {
- .entries = {
- {
- .wm_inst = WM_A,
- .wm_type = WM_TYPE_PSTATE_CHG,
- .pstate_latency_us = 11.72,
- .sr_exit_time_us = 28.0,
- .sr_enter_plus_exit_time_us = 30.0,
- .valid = true,
- },
- {
- .wm_inst = WM_B,
- .wm_type = WM_TYPE_PSTATE_CHG,
- .pstate_latency_us = 11.72,
- .sr_exit_time_us = 28.0,
- .sr_enter_plus_exit_time_us = 30.0,
- .valid = true,
- },
- {
- .wm_inst = WM_C,
- .wm_type = WM_TYPE_PSTATE_CHG,
- .pstate_latency_us = 11.72,
- .sr_exit_time_us = 28.0,
- .sr_enter_plus_exit_time_us = 30.0,
- .valid = true,
- },
- {
- .wm_inst = WM_D,
- .wm_type = WM_TYPE_PSTATE_CHG,
- .pstate_latency_us = 11.72,
- .sr_exit_time_us = 28.0,
- .sr_enter_plus_exit_time_us = 30.0,
- .valid = true,
- },
- }
-};
-
-static struct wm_table lpddr5_wm_table = {
- .entries = {
- {
- .wm_inst = WM_A,
- .wm_type = WM_TYPE_PSTATE_CHG,
- .pstate_latency_us = 11.65333,
- .sr_exit_time_us = 28.0,
- .sr_enter_plus_exit_time_us = 30.0,
- .valid = true,
- },
- {
- .wm_inst = WM_B,
- .wm_type = WM_TYPE_PSTATE_CHG,
- .pstate_latency_us = 11.65333,
- .sr_exit_time_us = 28.0,
- .sr_enter_plus_exit_time_us = 30.0,
- .valid = true,
- },
- {
- .wm_inst = WM_C,
- .wm_type = WM_TYPE_PSTATE_CHG,
- .pstate_latency_us = 11.65333,
- .sr_exit_time_us = 28.0,
- .sr_enter_plus_exit_time_us = 30.0,
- .valid = true,
- },
- {
- .wm_inst = WM_D,
- .wm_type = WM_TYPE_PSTATE_CHG,
- .pstate_latency_us = 11.65333,
- .sr_exit_time_us = 28.0,
- .sr_enter_plus_exit_time_us = 30.0,
- .valid = true,
- },
- }
-};
-
struct dcn42_ss_info_table dcn42_ss_info_table = {
.ss_divider = 1000,
.ss_percentage = {0, 0, 375, 375, 375}
@@ -1141,10 +1067,6 @@ void dcn42_clk_mgr_construct(
if (ctx->dc_bios->integrated_info) {
clk_mgr->base.base.dentist_vco_freq_khz = ctx->dc_bios->integrated_info->dentist_vco_freq;
- if (ctx->dc_bios->integrated_info->memory_type == LpDdr5MemType)
- dcn42_bw_params.wm_table = lpddr5_wm_table;
- else
- dcn42_bw_params.wm_table = ddr5_wm_table;
dcn42_bw_params.vram_type = ctx->dc_bios->integrated_info->memory_type;
dcn42_bw_params.dram_channel_width_bytes = ctx->dc_bios->integrated_info->memory_type == 0x22 ? 8 : 4;
dcn42_bw_params.num_channels = ctx->dc_bios->integrated_info->ma_channel_number ? ctx->dc_bios->integrated_info->ma_channel_number : 1;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index 952968ecd46e..7333f5905330 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -23,8 +23,6 @@
*
*/
-#include <linux/array_size.h>
-
#include "dm_services.h"
#include "core_types.h"
#include "timing_generator.h"
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 00b894602423..05991a10f8bf 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -5069,6 +5069,12 @@ void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
}
}
+ if (stream->ctx->dce_version < DCE_VERSION_8_0 &&
+ stream->timing.display_color_depth >= COLOR_DEPTH_101010) {
+ /* DCE 6.x doesn't support 10-bit truncation or dither options. */
+ option = DITHER_OPTION_DISABLE;
+ }
+
if (option == DITHER_OPTION_DISABLE)
return;
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 55ec281db3b7..7f55ba09b191 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -63,7 +63,7 @@ struct dcn_dsc_reg_state;
struct dcn_optc_reg_state;
struct dcn_dccg_reg_state;
-#define DC_VER "3.2.376"
+#define DC_VER "3.2.378"
/**
* MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC
@@ -562,6 +562,7 @@ struct dc_config {
bool frame_update_cmd_version2;
struct spl_sharpness_range dcn_sharpness_range;
struct spl_sharpness_range dcn_override_sharpness_range;
+ bool no_native422_support;
};
enum visual_confirm {
@@ -986,7 +987,6 @@ struct link_service;
* causing an issue or not.
*/
struct dc_debug_options {
- bool native422_support;
bool disable_dsc;
enum visual_confirm visual_confirm;
int visual_confirm_rect_height;
@@ -1061,9 +1061,11 @@ struct dc_debug_options {
bool hdmi20_disable;
bool skip_detection_link_training;
uint32_t edid_read_retry_times;
- unsigned int force_odm_combine; //bit vector based on otg inst
- unsigned int seamless_boot_odm_combine;
- unsigned int force_odm_combine_4to1; //bit vector based on otg inst
+
+ uint8_t force_odm_combine; //bit vector based on otg inst
+ uint8_t seamless_boot_odm_combine;
+ uint8_t force_odm_combine_4to1; //bit vector based on otg inst
+
int minimum_z8_residency_time;
int minimum_z10_residency_time;
bool disable_z9_mpc;
@@ -2725,6 +2727,7 @@ struct dc_sink {
struct stereo_3d_features features_3d[TIMING_3D_FORMAT_MAX];
bool converter_disable_audio;
+ struct mccs_caps mccs_caps;
struct scdc_caps scdc_caps;
struct dc_sink_dsc_caps dsc_caps;
struct dc_sink_fec_caps fec_caps;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dsc.h b/drivers/gpu/drm/amd/display/dc/dc_dsc.h
index 9d18f1c08079..101bce6b8de6 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dsc.h
@@ -52,6 +52,7 @@ struct dc_dsc_policy {
uint32_t max_target_bpp;
uint32_t min_target_bpp;
bool enable_dsc_when_not_needed;
+ bool ycbcr422_simple;
};
struct dc_dsc_config_options {
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index 86394203cee7..7c38fa6f8cb1 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -162,13 +162,13 @@ struct test_pattern {
#define SUBVP_DRR_MARGIN_US 100 // 100us for DRR margin (SubVP + DRR)
struct dc_stream_debug_options {
- char force_odm_combine_segments;
+ uint8_t force_odm_combine_segments;
/*
* When force_odm_combine_segments is non zero, allow dc to
* temporarily transition to ODM bypass when minimal transition state
* is required to prevent visual glitches showing on the screen
*/
- char allow_transition_for_forced_odm;
+ uint8_t allow_transition_for_forced_odm;
};
#define LUMINANCE_DATA_TABLE_SIZE 10
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index fd8ec1660312..c08d5c005df6 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -205,6 +205,8 @@ struct dc_edid_caps {
uint32_t audio_latency;
uint32_t video_latency;
+ unsigned char freesync_vcp_code;
+
uint8_t qs_bit;
uint8_t qy_bit;
@@ -1313,6 +1315,10 @@ struct dc_panel_config {
} rio;
};
+struct mccs_caps {
+ bool freesync_supported;
+};
+
#define MAX_SINKS_PER_LINK 4
/*
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
index 71a876e3dfd4..25c13822fede 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
@@ -23,8 +23,6 @@
*
*/
-#include <linux/array_size.h>
-
#include "dm_services.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
index 2818df555e62..107aec6a1265 100644
--- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h
+++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h
@@ -181,6 +181,16 @@ enum dc_edid_status dm_helpers_read_local_edid(
struct dc_link *link,
struct dc_sink *sink);
+void dm_helpers_read_mccs_caps(
+ struct dc_context *ctx,
+ struct dc_link *link,
+ struct dc_sink *sink);
+
+void dm_helpers_mccs_vcp_set(
+ struct dc_context *ctx,
+ struct dc_link *link,
+ struct dc_sink *sink);
+
bool dm_helpers_dp_handle_test_pattern_request(
struct dc_context *ctx,
const struct dc_link *link,
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
index 887744d56d6a..e82f2d531211 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
@@ -2399,7 +2399,7 @@ static struct _vcs_dpi_voltage_scaling_st construct_low_pstate_lvl(struct clk_li
return low_pstate_lvl;
}
-void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+void dcn21_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
{
struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits;
struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h
index aed00039ca62..8b2226c5bbbf 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.h
@@ -78,7 +78,7 @@ int dcn21_populate_dml_pipes_from_context(struct dc *dc,
enum dc_validate_mode validate_mode);
bool dcn21_validate_bandwidth_fp(struct dc *dc, struct dc_state *context, enum
dc_validate_mode, display_e2e_pipe_params_st *pipes);
-void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
+void dcn21_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params);
void dcn21_clk_mgr_set_bw_params_wm_table(struct clk_bw_params *bw_params);
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
index 1a28061bb9ff..ad23215da9f8 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
@@ -587,7 +587,7 @@ void dcn31_calculate_wm_and_dlg_fp(
context->bw_ctx.bw.dcn.compbuf_size_kb = context->bw_ctx.dml.ip.config_return_buffer_size_in_kbytes - total_det;
}
-void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+void dcn31_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
{
struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits;
struct clk_limit_table *clk_table = &bw_params->clk_table;
@@ -665,7 +665,7 @@ void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params
dml_init_instance(&dc->dml, &dcn3_1_soc, &dcn3_1_ip, DML_PROJECT_DCN31);
}
-void dcn315_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+void dcn315_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
{
struct clk_limit_table *clk_table = &bw_params->clk_table;
int i, max_dispclk_mhz = 0, max_dppclk_mhz = 0;
@@ -726,7 +726,7 @@ void dcn315_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
dml_init_instance(&dc->dml, &dcn3_15_soc, &dcn3_15_ip, DML_PROJECT_DCN315);
}
-void dcn316_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+void dcn316_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params)
{
struct _vcs_dpi_voltage_scaling_st *s = dc->scratch.update_bw_bounding_box.clock_limits;
struct clk_limit_table *clk_table = &bw_params->clk_table;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.h
index dfcc5d50071e..0b7fcbbfd17b 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.h
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.h
@@ -44,9 +44,9 @@ void dcn31_calculate_wm_and_dlg_fp(
int pipe_cnt,
int vlevel);
-void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
-void dcn315_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
-void dcn316_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params);
+void dcn31_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params);
+void dcn315_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params);
+void dcn316_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_params);
int dcn_get_max_non_odm_pix_rate_100hz(struct _vcs_dpi_soc_bounding_box_st *soc);
int dcn_get_approx_det_segs_required_for_pstate(
struct _vcs_dpi_soc_bounding_box_st *soc,
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index e29497204df7..eb199215d298 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -1610,38 +1610,6 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
return false;
}
-static void dcn20_adjust_freesync_v_startup(const struct dc_crtc_timing *dc_crtc_timing, int *vstartup_start)
-{
- struct dc_crtc_timing patched_crtc_timing;
- uint32_t asic_blank_end = 0;
- uint32_t asic_blank_start = 0;
- uint32_t newVstartup = 0;
-
- patched_crtc_timing = *dc_crtc_timing;
-
- if (patched_crtc_timing.flags.INTERLACE == 1) {
- if (patched_crtc_timing.v_front_porch < 2)
- patched_crtc_timing.v_front_porch = 2;
- } else {
- if (patched_crtc_timing.v_front_porch < 1)
- patched_crtc_timing.v_front_porch = 1;
- }
-
- /* blank_start = frame end - front porch */
- asic_blank_start = patched_crtc_timing.v_total -
- patched_crtc_timing.v_front_porch;
-
- /* blank_end = blank_start - active */
- asic_blank_end = asic_blank_start -
- patched_crtc_timing.v_border_bottom -
- patched_crtc_timing.v_addressable -
- patched_crtc_timing.v_border_top;
-
- newVstartup = asic_blank_end + (patched_crtc_timing.v_total - asic_blank_start);
-
- *vstartup_start = ((newVstartup > *vstartup_start) ? newVstartup : *vstartup_start);
-}
-
static void dcn32_calculate_dlg_params(struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt, int vlevel)
@@ -1756,11 +1724,6 @@ static void dcn32_calculate_dlg_params(struct dc *dc, struct dc_state *context,
}
}
- if (context->res_ctx.pipe_ctx[i].stream->adaptive_sync_infopacket.valid)
- dcn20_adjust_freesync_v_startup(
- &context->res_ctx.pipe_ctx[i].stream->timing,
- &context->res_ctx.pipe_ctx[i].pipe_dlg_param.vstartup_start);
-
pipe_idx++;
}
/* If DCN isn't making memory requests we can allow pstate change and lower clocks */
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/Makefile b/drivers/gpu/drm/amd/display/dc/dml2_0/Makefile
index 2625943d7f7e..8a451c36fdb3 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/Makefile
@@ -100,6 +100,7 @@ DML21 += src/dml2_mcg/dml2_mcg_factory.o
DML21 += src/dml2_pmo/dml2_pmo_dcn3.o
DML21 += src/dml2_pmo/dml2_pmo_factory.o
DML21 += src/dml2_pmo/dml2_pmo_dcn4_fams2.o
+DML21 += src/dml2_pmo/dml2_pmo_dcn42.o
DML21 += src/dml2_standalone_libraries/lib_float_math.o
DML21 += dml21_translation_helper.o
DML21 += dml21_wrapper.o
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_core.c b/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_core.c
index 8e8935995fca..698d62fb9cf7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_core.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_core.c
@@ -1812,6 +1812,8 @@ static dml_float_t CalculateWriteBackDISPCLK(
dml_uint_t WritebackLineBufferSize,
dml_float_t DISPCLKDPPCLKVCOSpeed)
{
+ (void)WritebackPixelFormat;
+ (void)WritebackVRatio;
dml_float_t DISPCLK_H, DISPCLK_V, DISPCLK_HB;
DISPCLK_H = PixelClock * dml_ceil(WritebackHTaps / 8.0, 1) / WritebackHRatio;
@@ -1830,6 +1832,8 @@ static dml_float_t CalculateWriteBackDelay(
dml_uint_t WritebackSourceHeight,
dml_uint_t HTotal)
{
+ (void)WritebackPixelFormat;
+ (void)WritebackHRatio;
dml_float_t CalculateWriteBackDelay;
dml_float_t Line_length;
dml_float_t Output_lines_last_notclamped;
@@ -1977,6 +1981,7 @@ static void CalculateFlipSchedule(
dml_float_t *final_flip_bw,
dml_bool_t *ImmediateFlipSupportedForPipe)
{
+ (void)HostVMMinPageSize;
dml_float_t min_row_time = 0.0;
dml_uint_t HostVMDynamicLevelsTrips = 0;
dml_float_t TimeForFetchingMetaPTEImmediateFlip = 0;
@@ -2118,6 +2123,11 @@ static void CalculateDCCConfiguration(
dml_uint_t *IndependentBlockLuma,
dml_uint_t *IndependentBlockChroma)
{
+ (void)SurfaceWidthChroma;
+ (void)SurfaceHeightChroma;
+ (void)TilingFormat;
+ (void)BytePerPixelDETY;
+ (void)BytePerPixelDETC;
dml_uint_t DETBufferSizeForDCC = nomDETInKByte * 1024;
dml_uint_t yuv420;
@@ -2489,6 +2499,7 @@ static dml_uint_t CalculateVMAndRowBytes(
dml_uint_t *DPDE0BytesFrame,
dml_uint_t *MetaPTEBytesFrame)
{
+ (void)SourcePixelFormat;
dml_uint_t MPDEBytesFrame;
dml_uint_t DCCMetaSurfaceBytes;
dml_uint_t ExtraDPDEBytesFrame;
@@ -3662,6 +3673,8 @@ static void CalculateVMGroupAndRequestTimes(
dml_float_t TimePerVMRequestVBlank[],
dml_float_t TimePerVMRequestFlip[])
{
+ (void)dpte_row_width_luma_ub;
+ (void)dpte_row_width_chroma_ub;
dml_uint_t num_group_per_lower_vm_stage;
dml_uint_t num_req_per_lower_vm_stage;
@@ -3762,6 +3775,7 @@ static void CalculateVMGroupAndRequestTimes(
static void CalculateStutterEfficiency(struct display_mode_lib_scratch_st *scratch,
struct CalculateStutterEfficiency_params_st *p)
{
+ (void)scratch;
dml_float_t DETBufferingTimeY = 0;
dml_float_t SwathWidthYCriticalSurface = 0;
dml_float_t SwathHeightYCriticalSurface = 0;
@@ -4085,6 +4099,7 @@ static void CalculateStutterEfficiency(struct display_mode_lib_scratch_st *scrat
static void CalculateSwathAndDETConfiguration(struct display_mode_lib_scratch_st *scratch,
struct CalculateSwathAndDETConfiguration_params_st *p)
{
+ (void)scratch;
dml_uint_t MaximumSwathHeightY[__DML_NUM_PLANES__];
dml_uint_t MaximumSwathHeightC[__DML_NUM_PLANES__];
dml_uint_t RoundedUpMaxSwathSizeBytesY[__DML_NUM_PLANES__];
@@ -4331,6 +4346,7 @@ static void CalculateSwathWidth(
dml_uint_t swath_width_luma_ub[], // per-pipe
dml_uint_t swath_width_chroma_ub[]) // per-pipe
{
+ (void)BytePerPixY;
enum dml_odm_mode MainSurfaceODMMode;
dml_uint_t surface_width_ub_l;
dml_uint_t surface_height_ub_l;
@@ -5029,6 +5045,7 @@ static void CalculateMaxDETAndMinCompressedBufferSize(
dml_uint_t *nomDETInKByte,
dml_uint_t *MinCompressedBufferSizeInKByte)
{
+ (void)ROBBufferSizeInKByte;
*MaxTotalDETInKByte = ConfigReturnBufferSizeInKByte - ConfigReturnBufferSegmentSizeInKByte;
*nomDETInKByte = (dml_uint_t)(dml_floor((dml_float_t) *MaxTotalDETInKByte / (dml_float_t) MaxNumDPP, ConfigReturnBufferSegmentSizeInKByte));
*MinCompressedBufferSizeInKByte = ConfigReturnBufferSizeInKByte - *MaxTotalDETInKByte;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c b/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c
index 4022f91193ed..b2fada6c44c3 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c
@@ -178,6 +178,7 @@ dml_float_t dml_log2(dml_float_t x)
dml_float_t dml_round(dml_float_t val, dml_bool_t bankers_rounding)
{
+ (void)bankers_rounding;
// if (bankers_rounding)
// return (dml_float_t) lrint(val);
// else {
@@ -217,6 +218,7 @@ dml_uint_t dml_round_to_multiple(dml_uint_t num, dml_uint_t multiple, dml_bool_t
void dml_print_data_rq_regs_st(const dml_display_plane_rq_regs_st *rq_regs)
{
+ (void)rq_regs;
dml_print("DML: ===================================== \n");
dml_print("DML: DISPLAY_PLANE_RQ_REGS_ST\n");
dml_print("DML: chunk_size = 0x%x\n", rq_regs->chunk_size);
@@ -248,6 +250,7 @@ void dml_print_rq_regs_st(const dml_display_rq_regs_st *rq_regs)
void dml_print_dlg_regs_st(const dml_display_dlg_regs_st *dlg_regs)
{
+ (void)dlg_regs;
dml_print("DML: ===================================== \n");
dml_print("DML: DISPLAY_DLG_REGS_ST \n");
dml_print("DML: refcyc_h_blank_end = 0x%x\n", dlg_regs->refcyc_h_blank_end);
@@ -299,6 +302,7 @@ void dml_print_dlg_regs_st(const dml_display_dlg_regs_st *dlg_regs)
void dml_print_ttu_regs_st(const dml_display_ttu_regs_st *ttu_regs)
{
+ (void)ttu_regs;
dml_print("DML: ===================================== \n");
dml_print("DML: DISPLAY_TTU_REGS_ST \n");
dml_print("DML: qos_level_low_wm = 0x%x\n", ttu_regs->qos_level_low_wm);
@@ -326,6 +330,7 @@ void dml_print_ttu_regs_st(const dml_display_ttu_regs_st *ttu_regs)
void dml_print_dml_policy(const struct dml_mode_eval_policy_st *policy)
{
+ (void)policy;
dml_print("DML: ===================================== \n");
dml_print("DML: DML_MODE_EVAL_POLICY_ST\n");
dml_print("DML: Policy: UseUnboundedRequesting = 0x%x\n", policy->UseUnboundedRequesting);
@@ -353,6 +358,8 @@ void dml_print_dml_policy(const struct dml_mode_eval_policy_st *policy)
void dml_print_mode_support(struct display_mode_lib_st *mode_lib, dml_uint_t j)
{
+ (void)j;
+ (void)mode_lib;
dml_print("DML: MODE SUPPORT: ===============================================\n");
dml_print("DML: MODE SUPPORT: Voltage State %d\n", j);
dml_print("DML: MODE SUPPORT: Mode Supported : %s\n", mode_lib->ms.support.ModeSupport[j] == true ? "Supported" : "NOT Supported");
@@ -526,6 +533,7 @@ void dml_print_dml_mode_support_info(const struct dml_mode_support_info_st *supp
void dml_print_dml_display_cfg_timing(const struct dml_timing_cfg_st *timing, dml_uint_t num_plane)
{
+ (void)timing;
for (dml_uint_t i = 0; i < num_plane; i++) {
dml_print("DML: timing_cfg: plane=%d, HTotal = %d\n", i, timing->HTotal[i]);
dml_print("DML: timing_cfg: plane=%d, VTotal = %d\n", i, timing->VTotal[i]);
@@ -542,6 +550,7 @@ void dml_print_dml_display_cfg_timing(const struct dml_timing_cfg_st *timing, dm
void dml_print_dml_display_cfg_plane(const struct dml_plane_cfg_st *plane, dml_uint_t num_plane)
{
+ (void)plane;
dml_print("DML: plane_cfg: num_plane = %d\n", num_plane);
dml_print("DML: plane_cfg: GPUVMEnable = %d\n", plane->GPUVMEnable);
dml_print("DML: plane_cfg: HostVMEnable = %d\n", plane->HostVMEnable);
@@ -590,6 +599,7 @@ void dml_print_dml_display_cfg_plane(const struct dml_plane_cfg_st *plane, dml_u
void dml_print_dml_display_cfg_surface(const struct dml_surface_cfg_st *surface, dml_uint_t num_plane)
{
+ (void)surface;
for (dml_uint_t i = 0; i < num_plane; i++) {
dml_print("DML: surface_cfg: plane=%d, PitchY = %d\n", i, surface->PitchY[i]);
dml_print("DML: surface_cfg: plane=%d, SurfaceWidthY = %d\n", i, surface->SurfaceWidthY[i]);
@@ -609,6 +619,7 @@ void dml_print_dml_display_cfg_surface(const struct dml_surface_cfg_st *surface,
void dml_print_dml_display_cfg_hw_resource(const struct dml_hw_resource_st *hw, dml_uint_t num_plane)
{
+ (void)hw;
for (dml_uint_t i = 0; i < num_plane; i++) {
dml_print("DML: hw_resource: plane=%d, ODMMode = %d\n", i, hw->ODMMode[i]);
dml_print("DML: hw_resource: plane=%d, DPPPerSurface = %d\n", i, hw->DPPPerSurface[i]);
@@ -620,6 +631,7 @@ void dml_print_dml_display_cfg_hw_resource(const struct dml_hw_resource_st *hw,
__DML_DLL_EXPORT__ void dml_print_soc_state_bounding_box(const struct soc_state_bounding_box_st *state)
{
+ (void)state;
dml_print("DML: state_bbox: socclk_mhz = %f\n", state->socclk_mhz);
dml_print("DML: state_bbox: dscclk_mhz = %f\n", state->dscclk_mhz);
dml_print("DML: state_bbox: phyclk_mhz = %f\n", state->phyclk_mhz);
@@ -649,6 +661,7 @@ __DML_DLL_EXPORT__ void dml_print_soc_state_bounding_box(const struct soc_state_
__DML_DLL_EXPORT__ void dml_print_soc_bounding_box(const struct soc_bounding_box_st *soc)
{
+ (void)soc;
dml_print("DML: soc_bbox: dprefclk_mhz = %f\n", soc->dprefclk_mhz);
dml_print("DML: soc_bbox: xtalclk_mhz = %f\n", soc->xtalclk_mhz);
dml_print("DML: soc_bbox: pcierefclk_mhz = %f\n", soc->pcierefclk_mhz);
@@ -686,6 +699,7 @@ __DML_DLL_EXPORT__ void dml_print_soc_bounding_box(const struct soc_bounding_box
__DML_DLL_EXPORT__ void dml_print_clk_cfg(const struct dml_clk_cfg_st *clk_cfg)
{
+ (void)clk_cfg;
dml_print("DML: clk_cfg: 0-use_required, 1-use pipe.clks_cfg, 2-use state bbox\n");
dml_print("DML: clk_cfg: dcfclk_option = %d\n", clk_cfg->dcfclk_option);
dml_print("DML: clk_cfg: dispclk_option = %d\n", clk_cfg->dispclk_option);
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c
index 2f0e0048bea8..476030193f14 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_translation_helper.c
@@ -389,7 +389,9 @@ static void populate_dml21_dummy_surface_cfg(struct dml2_surface_cfg *surface, c
surface->tiling = dml2_sw_64kb_2d;
}
-static void populate_dml21_dummy_plane_cfg(struct dml2_plane_parameters *plane, const struct dc_stream_state *stream)
+static void populate_dml21_dummy_plane_cfg(struct dml2_plane_parameters *plane,
+ const struct dc_stream_state *stream,
+ const struct dml2_soc_bb *soc_bb)
{
unsigned int width, height;
@@ -433,7 +435,8 @@ static void populate_dml21_dummy_plane_cfg(struct dml2_plane_parameters *plane,
plane->pixel_format = dml2_444_32;
plane->dynamic_meta_data.enable = false;
- plane->overrides.gpuvm_min_page_size_kbytes = 256;
+ plane->overrides.gpuvm_min_page_size_kbytes = soc_bb->gpuvm_min_page_size_kbytes;
+ plane->overrides.hostvm_min_page_size_kbytes = soc_bb->hostvm_min_page_size_kbytes;
}
static void populate_dml21_surface_config_from_plane_state(
@@ -441,6 +444,7 @@ static void populate_dml21_surface_config_from_plane_state(
struct dml2_surface_cfg *surface,
const struct dc_plane_state *plane_state)
{
+ (void)in_dc;
surface->plane0.pitch = plane_state->plane_size.surface_pitch;
surface->plane1.pitch = plane_state->plane_size.chroma_pitch;
surface->plane0.height = plane_state->plane_size.surface_size.height;
@@ -503,7 +507,7 @@ static const struct scaler_data *get_scaler_data_for_plane(
static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dml_ctx,
struct dml2_plane_parameters *plane, const struct dc_plane_state *plane_state,
- const struct dc_state *context, unsigned int stream_index)
+ const struct dc_state *context, unsigned int stream_index, const struct dml2_soc_bb *soc_bb)
{
const struct scaler_data *scaler_data = get_scaler_data_for_plane(dml_ctx, plane_state, context);
struct dc_stream_state *stream = context->streams[stream_index];
@@ -647,7 +651,8 @@ static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dm
plane->composition.rotation_angle = (enum dml2_rotation_angle) plane_state->rotation;
plane->stream_index = stream_index;
- plane->overrides.gpuvm_min_page_size_kbytes = 256;
+ plane->overrides.gpuvm_min_page_size_kbytes = soc_bb->gpuvm_min_page_size_kbytes;
+ plane->overrides.hostvm_min_page_size_kbytes = soc_bb->hostvm_min_page_size_kbytes;
plane->immediate_flip = plane_state->flip_immediate;
@@ -785,7 +790,9 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_s
if (context->stream_status[stream_index].plane_count == 0) {
disp_cfg_plane_location = dml_dispcfg->num_planes++;
populate_dml21_dummy_surface_cfg(&dml_dispcfg->plane_descriptors[disp_cfg_plane_location].surface, context->streams[stream_index]);
- populate_dml21_dummy_plane_cfg(&dml_dispcfg->plane_descriptors[disp_cfg_plane_location], context->streams[stream_index]);
+ populate_dml21_dummy_plane_cfg(
+ &dml_dispcfg->plane_descriptors[disp_cfg_plane_location],
+ context->streams[stream_index], &dml_ctx->v21.dml_init.soc_bb);
dml_dispcfg->plane_descriptors[disp_cfg_plane_location].stream_index = disp_cfg_stream_location;
} else {
for (plane_index = 0; plane_index < context->stream_status[stream_index].plane_count; plane_index++) {
@@ -797,7 +804,10 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_s
ASSERT(disp_cfg_plane_location >= 0 && disp_cfg_plane_location < __DML2_WRAPPER_MAX_STREAMS_PLANES__);
populate_dml21_surface_config_from_plane_state(in_dc, &dml_dispcfg->plane_descriptors[disp_cfg_plane_location].surface, context->stream_status[stream_index].plane_states[plane_index]);
- populate_dml21_plane_config_from_plane_state(dml_ctx, &dml_dispcfg->plane_descriptors[disp_cfg_plane_location], context->stream_status[stream_index].plane_states[plane_index], context, stream_index);
+ populate_dml21_plane_config_from_plane_state(
+ dml_ctx, &dml_dispcfg->plane_descriptors[disp_cfg_plane_location],
+ context->stream_status[stream_index].plane_states[plane_index],
+ context, stream_index, &dml_ctx->v21.dml_init.soc_bb);
dml_dispcfg->plane_descriptors[disp_cfg_plane_location].stream_index = disp_cfg_stream_location;
if (dml21_wrapper_get_plane_id(context, context->streams[stream_index]->stream_id, context->stream_status[stream_index].plane_states[plane_index], &dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[disp_cfg_plane_location]))
@@ -873,6 +883,7 @@ static struct dml2_dchub_watermark_regs *wm_set_index_to_dc_wm_set(union dcn_wat
void dml21_extract_watermark_sets(const struct dc *in_dc, union dcn_watermark_set *watermarks, struct dml2_context *in_ctx)
{
+ (void)in_dc;
const struct dml2_display_cfg_programming *programming = in_ctx->v21.mode_programming.programming;
unsigned int wm_index;
@@ -907,6 +918,7 @@ void dml21_get_pipe_mcache_config(
struct dml2_per_plane_programming *pln_prog,
struct dml2_pipe_configuration_descriptor *mcache_pipe_config)
{
+ (void)context;
mcache_pipe_config->plane0.viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x;
mcache_pipe_config->plane0.viewport_width = pipe_ctx->plane_res.scl_data.viewport.width;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c
index 4724b08c77e1..732de97335fa 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c
@@ -88,6 +88,7 @@ int dml21_find_dc_pipes_for_plane(const struct dc *in_dc,
struct pipe_ctx *dc_phantom_pipes[__DML2_WRAPPER_MAX_STREAMS_PLANES__],
int dml_plane_idx)
{
+ (void)in_dc;
unsigned int dml_stream_index;
unsigned int main_stream_id;
unsigned int dc_plane_index;
@@ -282,6 +283,7 @@ static struct dc_plane_state *dml21_add_phantom_plane(struct dml2_context *dml_c
struct dc_plane_state *main_plane,
struct dml2_per_plane_programming *plane_programming)
{
+ (void)plane_programming;
struct dc_plane_state *phantom_plane;
phantom_plane = dml_ctx->config.svp_pstate.callbacks.create_phantom_plane(dc, context, main_plane);
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper.c
index 7398f8b69adb..8bed59e976d1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper.c
@@ -58,8 +58,8 @@ bool dml21_create(const struct dc *in_dc, struct dml2_context **dml_ctx, const s
void dml21_destroy(struct dml2_context *dml2)
{
- vfree(dml2->v21.dml_init.dml2_instance);
- vfree(dml2->v21.mode_programming.programming);
+ DC_RUN_WITH_PREEMPTION_ENABLED(vfree(dml2->v21.dml_init.dml2_instance));
+ DC_RUN_WITH_PREEMPTION_ENABLED(vfree(dml2->v21.mode_programming.programming));
}
void dml21_copy(struct dml2_context *dst_dml_ctx,
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper_fpu.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper_fpu.c
index cc992af6ac9c..de40d7bae252 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_wrapper_fpu.c
@@ -51,6 +51,8 @@ void dml21_reinit(const struct dc *in_dc, struct dml2_context *dml_ctx, const st
static void dml21_calculate_rq_and_dlg_params(const struct dc *dc, struct dc_state *context, struct resource_context *out_new_hw_state,
struct dml2_context *in_ctx, unsigned int pipe_cnt)
{
+ (void)out_new_hw_state;
+ (void)pipe_cnt;
unsigned int dml_prog_idx = 0, dc_pipe_index = 0, num_dpps_required = 0;
struct dml2_per_plane_programming *pln_prog = NULL;
struct dml2_per_stream_programming *stream_prog = NULL;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h
index c75778ea7a2c..040d89f6de35 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h
@@ -68,6 +68,7 @@ static const struct dml2_soc_qos_parameters dml_dcn42_variant_a_soc_qos_params =
.qos_type = dml2_qos_param_type_dcn3,
};
+/* Default SOC bounding box for DCN42 based on LPDDR5/LPCAMM2 latencies*/
static const struct dml2_soc_bb dml2_socbb_dcn42 = {
.clk_table = {
.wck_ratio = {
@@ -185,12 +186,13 @@ static const struct dml2_soc_bb dml2_socbb_dcn42 = {
.qos_type = dml2_qos_param_type_dcn3,
},
+ /* DCN42 params for LPDDR5/LPCAMM2 */
.power_management_parameters = {
- .dram_clk_change_blackout_us = 29,
+ .dram_clk_change_blackout_us = 36,
.fclk_change_blackout_us = 0,
.g7_ppt_blackout_us = 0,
- .stutter_enter_plus_exit_latency_us = 11,
- .stutter_exit_latency_us = 9,
+ .stutter_enter_plus_exit_latency_us = 14,
+ .stutter_exit_latency_us = 12,
.z8_stutter_enter_plus_exit_latency_us = 300,
.z8_stutter_exit_latency_us = 200,
},
@@ -203,12 +205,12 @@ static const struct dml2_soc_bb dml2_socbb_dcn42 = {
.xtalclk_mhz = 24,
.pcie_refclk_mhz = 100,
.dchub_refclk_mhz = 50,
- .mall_allocated_for_dcn_mbytes = 64,
+ .mall_allocated_for_dcn_mbytes = 0,
.max_outstanding_reqs = 256,
.fabric_datapath_to_dcn_data_return_bytes = 32,
.return_bus_width_bytes = 64,
.hostvm_min_page_size_kbytes = 4,
- .gpuvm_min_page_size_kbytes = 256,
+ .gpuvm_min_page_size_kbytes = 4,
.gpuvm_max_page_table_levels = 1,
.hostvm_max_non_cached_page_table_levels = 2,
.phy_downspread_percent = 0.38,
@@ -222,6 +224,17 @@ static const struct dml2_soc_bb dml2_socbb_dcn42 = {
.max_fclk_for_uclk_dpm_khz = 2200 * 1000,
};
+/* DCN42 params for DDR5 */
+struct dml2_soc_power_management_parameters dcn42_ddr5_power_management_parameters = {
+ .dram_clk_change_blackout_us = 36,
+ .fclk_change_blackout_us = 0,
+ .g7_ppt_blackout_us = 0,
+ .stutter_enter_plus_exit_latency_us = 23.5,
+ .stutter_exit_latency_us = 21.5,
+ .z8_stutter_enter_plus_exit_latency_us = 300,
+ .z8_stutter_exit_latency_us = 200,
+};
+
static const struct dml2_ip_capabilities dml2_dcn42_max_ip_caps = {
.pipe_count = 4,
.otg_count = 4,
@@ -234,7 +247,7 @@ static const struct dml2_ip_capabilities dml2_dcn42_max_ip_caps = {
.config_return_buffer_segment_size_in_kbytes = 64,
.meta_fifo_size_in_kentries = 32,
.compressed_buffer_segment_size_in_kbytes = 64,
- .cursor_buffer_size = 24,
+ .cursor_buffer_size = 42,
.max_flip_time_us = 110,
.max_flip_time_lines = 50,
.hostvm_mode = 0,
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_display_cfg_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_display_cfg_types.h
index 4e9abe1a568d..79dfba54344c 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_display_cfg_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_display_cfg_types.h
@@ -26,20 +26,6 @@ enum dml2_swizzle_mode {
dml2_gfx11_sw_64kb_r_x,
dml2_gfx11_sw_256kb_d_x,
dml2_gfx11_sw_256kb_r_x,
-
- dml2_sw_linear_256b, // GFX10 SW_LINEAR only accepts 256 byte aligned pitch
- dml2_gfx10_sw_64kb_r_x,
- dml2_gfx102_sw_64kb_s,
- dml2_gfx102_sw_64kb_s_t,
- dml2_gfx102_sw_64kb_s_x,
- dml2_gfx102_sw_64kb_r_x,
-
- dml2_linear_64elements, // GFX7 LINEAR_ALIGNED accepts pitch alignment of the maximum of 64 elements or 256 bytes
- dml2_gfx7_1d_thin,
- dml2_gfx7_2d_thin_gen_zero,
- dml2_gfx7_2d_thin_gen_one,
- dml2_gfx7_2d_thin_arlene,
- dml2_gfx7_2d_thin_anubis
};
enum dml2_source_format_class {
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c
index 99fc2f0666e2..858e7bbc511f 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4.c
@@ -135,7 +135,7 @@ struct dml2_core_ip_params core_dcn42_ip_caps_base = {
.cursor_64bpp_support = true,
.dynamic_metadata_vm_enabled = false,
- .max_num_hdmi_frl_outputs = 0,
+ .max_num_hdmi_frl_outputs = 1,
.max_num_dp2p0_outputs = 2,
.max_num_dp2p0_streams = 4,
.imall_supported = 1,
@@ -155,7 +155,7 @@ struct dml2_core_ip_params core_dcn42_ip_caps_base = {
.min_meta_chunk_size_bytes = 256,
.dchub_arb_to_ret_delay = 102,
- .hostvm_mode = 1,
+ .hostvm_mode = 0,
};
static void patch_ip_caps_with_explicit_ip_params(struct dml2_ip_capabilities *ip_caps, const struct dml2_core_ip_params *ip_params)
@@ -281,6 +281,7 @@ static void create_phantom_stream_from_main_stream(struct dml2_stream_parameters
static void create_phantom_plane_from_main_plane(struct dml2_plane_parameters *phantom, const struct dml2_plane_parameters *main,
const struct dml2_stream_parameters *phantom_stream, int phantom_stream_index, const struct dml2_stream_parameters *main_stream)
{
+ (void)main_stream;
memcpy(phantom, main, sizeof(struct dml2_plane_parameters));
phantom->stream_index = phantom_stream_index;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
index f6402e199354..827bd9143c87 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
@@ -840,6 +840,7 @@ static void CalculateSwathWidth(
unsigned int swath_width_luma_ub[], // per-pipe
unsigned int swath_width_chroma_ub[]) // per-pipe
{
+ (void)BytePerPixY;
enum dml2_odm_mode MainSurfaceODMMode;
double odm_hactive_factor = 1.0;
unsigned int req_width_horz_y;
@@ -1283,6 +1284,8 @@ static double TruncToValidBPP(
// Output
unsigned int *RequiredSlots)
{
+ (void)DSCInputBitPerComponent;
+ (void)RequiredSlots;
double MaxLinkBPP;
unsigned int MinDSCBPP;
double MaxDSCBPP;
@@ -1922,6 +1925,7 @@ static void CalculateRowBandwidth(
double *dpte_row_bw,
double *meta_row_bw)
{
+ (void)use_one_row_for_frame;
if (!DCCEnable || !mrq_present) {
*meta_row_bw = 0;
} else if (dml_is_420(SourcePixelFormat) || SourcePixelFormat == dml2_rgbe_alpha) {
@@ -2020,6 +2024,11 @@ static void CalculateDCCConfiguration(
unsigned int *IndependentBlockLuma,
unsigned int *IndependentBlockChroma)
{
+ (void)SurfaceWidthChroma;
+ (void)SurfaceHeightChroma;
+ (void)TilingFormat;
+ (void)BytePerPixelDETY;
+ (void)BytePerPixelDETC;
unsigned int DETBufferSizeForDCC = nomDETInKByte * 1024;
unsigned int segment_order_horz_contiguous_luma;
@@ -2270,6 +2279,7 @@ static void calculate_mcache_row_bytes(
struct dml2_core_internal_scratch *scratch,
struct dml2_core_calcs_calculate_mcache_row_bytes_params *p)
{
+ (void)scratch;
unsigned int vmpg_bytes = 0;
unsigned int blk_bytes = 0;
float meta_per_mvmpg_per_channel = 0;
@@ -3642,6 +3652,8 @@ static double CalculateWriteBackDelay(
unsigned int WritebackSourceHeight,
unsigned int HTotal)
{
+ (void)WritebackPixelFormat;
+ (void)WritebackHRatio;
double CalculateWriteBackDelay;
double Line_length;
double Output_lines_last_notclamped;
@@ -3959,6 +3971,7 @@ static enum dml2_odm_mode DecideODMMode(unsigned int HActive,
double SurfaceRequiredDISPCLKWithODMCombineThreeToOne,
double SurfaceRequiredDISPCLKWithODMCombineFourToOne)
{
+ (void)SurfaceRequiredDISPCLKWithODMCombineFourToOne;
enum dml2_odm_mode MinimumRequiredODMModeForMaxDispClock;
enum dml2_odm_mode MinimumRequiredODMModeForMaxDSCHActive;
enum dml2_odm_mode MinimumRequiredODMModeForMax420HActive;
@@ -4460,6 +4473,8 @@ static double CalculateWriteBackDISPCLK(
unsigned int HTotal,
unsigned int WritebackLineBufferSize)
{
+ (void)WritebackPixelFormat;
+ (void)WritebackVRatio;
double DISPCLK_H, DISPCLK_V, DISPCLK_HB;
DISPCLK_H = PixelClock * math_ceil2((double)WritebackHTaps / 8.0, 1) / WritebackHRatio;
@@ -4561,6 +4576,10 @@ static void CalculateSurfaceSizeInMall(
unsigned int SurfaceSizeInMALL[],
bool *ExceededMALLSize)
{
+ (void)Read256BytesBlockWidthY;
+ (void)Read256BytesBlockWidthC;
+ (void)Read256BytesBlockHeightY;
+ (void)Read256BytesBlockHeightC;
unsigned int TotalSurfaceSizeInMALLForSS = 0;
unsigned int TotalSurfaceSizeInMALLForSubVP = 0;
unsigned int MALLAllocatedForDCNInBytes = MALLAllocatedForDCN * 1024 * 1024;
@@ -4620,6 +4639,7 @@ static void calculate_tdlut_setting(
struct dml2_core_internal_scratch *scratch,
struct dml2_core_calcs_calculate_tdlut_setting_params *p)
{
+ (void)scratch;
// locals
unsigned int tdlut_bpe = 8;
unsigned int tdlut_width;
@@ -6503,6 +6523,7 @@ static void CalculateFlipSchedule(
double *final_flip_bw,
bool *ImmediateFlipSupportedForPipe)
{
+ (void)use_one_row_for_frame_flip;
struct dml2_core_shared_CalculateFlipSchedule_locals *l = &s->CalculateFlipSchedule_locals;
l->dual_plane = dml_is_420(SourcePixelFormat) || SourcePixelFormat == dml2_rgbe_alpha;
@@ -7381,7 +7402,7 @@ static noinline_for_stack void dml_core_ms_prefetch_check(struct dml2_core_inter
s->tdlut_bytes_per_group,
s->HostVMInefficiencyFactor,
s->HostVMInefficiencyFactorPrefetch,
- mode_lib->soc.hostvm_min_page_size_kbytes,
+ mode_lib->soc.hostvm_min_page_size_kbytes * 1024,
mode_lib->soc.qos_parameters.qos_type,
!(display_cfg->overrides.max_outstanding_when_urgent_expected_disable),
mode_lib->soc.max_outstanding_reqs,
@@ -7477,12 +7498,11 @@ static noinline_for_stack void dml_core_ms_prefetch_check(struct dml2_core_inter
CalculatePrefetchSchedule_params->OutputFormat = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format;
CalculatePrefetchSchedule_params->MaxInterDCNTileRepeaters = mode_lib->ip.max_inter_dcn_tile_repeaters;
CalculatePrefetchSchedule_params->VStartup = s->MaximumVStartup[k];
- CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->soc.hostvm_min_page_size_kbytes;
+ CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->soc.hostvm_min_page_size_kbytes * 1024;
CalculatePrefetchSchedule_params->DynamicMetadataEnable = display_cfg->plane_descriptors[k].dynamic_meta_data.enable;
CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ip.dynamic_metadata_vm_enabled;
CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = display_cfg->plane_descriptors[k].dynamic_meta_data.lines_before_active_required;
CalculatePrefetchSchedule_params->DynamicMetadataTransmittedBytes = display_cfg->plane_descriptors[k].dynamic_meta_data.transmitted_bytes;
- CalculatePrefetchSchedule_params->UrgentLatency = mode_lib->ms.UrgLatency;
CalculatePrefetchSchedule_params->ExtraLatencyPrefetch = mode_lib->ms.ExtraLatencyPrefetch;
CalculatePrefetchSchedule_params->TCalc = mode_lib->ms.TimeCalc;
CalculatePrefetchSchedule_params->vm_bytes = mode_lib->ms.vm_bytes[k];
@@ -8965,7 +8985,7 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
CalculateVMRowAndSwath_params->MALLAllocatedForDCN = mode_lib->soc.mall_allocated_for_dcn_mbytes;
CalculateVMRowAndSwath_params->SwathWidthY = mode_lib->ms.SwathWidthY;
CalculateVMRowAndSwath_params->SwathWidthC = mode_lib->ms.SwathWidthC;
- CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->soc.hostvm_min_page_size_kbytes;
+ CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->soc.hostvm_min_page_size_kbytes * 1024;
CalculateVMRowAndSwath_params->DCCMetaBufferSizeBytes = mode_lib->ip.dcc_meta_buffer_size_bytes;
CalculateVMRowAndSwath_params->mrq_present = mode_lib->ip.dcn_mrq_present;
@@ -9968,6 +9988,8 @@ static void CalculateVMGroupAndRequestTimes(
double TimePerVMRequestVBlank[],
double TimePerVMRequestFlip[])
{
+ (void)dpte_row_width_luma_ub;
+ (void)dpte_row_width_chroma_ub;
unsigned int num_group_per_lower_vm_stage = 0;
unsigned int num_req_per_lower_vm_stage = 0;
unsigned int num_group_per_lower_vm_stage_flip;
@@ -10755,7 +10777,7 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
CalculateVMRowAndSwath_params->MALLAllocatedForDCN = mode_lib->soc.mall_allocated_for_dcn_mbytes;
CalculateVMRowAndSwath_params->SwathWidthY = mode_lib->mp.SwathWidthY;
CalculateVMRowAndSwath_params->SwathWidthC = mode_lib->mp.SwathWidthC;
- CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->soc.hostvm_min_page_size_kbytes;
+ CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->soc.hostvm_min_page_size_kbytes * 1024;
CalculateVMRowAndSwath_params->DCCMetaBufferSizeBytes = mode_lib->ip.dcc_meta_buffer_size_bytes;
CalculateVMRowAndSwath_params->mrq_present = mode_lib->ip.dcn_mrq_present;
@@ -10971,7 +10993,7 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
s->tdlut_bytes_per_group,
s->HostVMInefficiencyFactor,
s->HostVMInefficiencyFactorPrefetch,
- mode_lib->soc.hostvm_min_page_size_kbytes,
+ mode_lib->soc.hostvm_min_page_size_kbytes * 1024,
mode_lib->soc.qos_parameters.qos_type,
!(display_cfg->overrides.max_outstanding_when_urgent_expected_disable),
mode_lib->soc.max_outstanding_reqs,
@@ -11264,12 +11286,11 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
CalculatePrefetchSchedule_params->OutputFormat = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format;
CalculatePrefetchSchedule_params->MaxInterDCNTileRepeaters = mode_lib->ip.max_inter_dcn_tile_repeaters;
CalculatePrefetchSchedule_params->VStartup = s->MaxVStartupLines[k];
- CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->soc.hostvm_min_page_size_kbytes;
+ CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->soc.hostvm_min_page_size_kbytes * 1024;
CalculatePrefetchSchedule_params->DynamicMetadataEnable = display_cfg->plane_descriptors[k].dynamic_meta_data.enable;
CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ip.dynamic_metadata_vm_enabled;
CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = display_cfg->plane_descriptors[k].dynamic_meta_data.lines_before_active_required;
CalculatePrefetchSchedule_params->DynamicMetadataTransmittedBytes = display_cfg->plane_descriptors[k].dynamic_meta_data.transmitted_bytes;
- CalculatePrefetchSchedule_params->UrgentLatency = mode_lib->mp.UrgentLatency;
CalculatePrefetchSchedule_params->ExtraLatencyPrefetch = mode_lib->mp.ExtraLatencyPrefetch;
CalculatePrefetchSchedule_params->TCalc = mode_lib->mp.TCalc;
CalculatePrefetchSchedule_params->vm_bytes = mode_lib->mp.vm_bytes[k];
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
index 953f40fde1e1..080bc3c3d244 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
@@ -269,6 +269,9 @@ struct dml2_core_internal_mode_support_info {
bool global_dram_clock_change_supported;
bool global_fclk_change_supported;
bool global_temp_read_or_ppt_supported;
+ bool fclk_pstate_schedule_admissible;
+ bool temp_read_pstate_schedule_admissible;
+ bool ppt_pstate_schedule_admissible;
bool USRRetrainingSupport;
bool AvgBandwidthSupport;
bool UrgVactiveBandwidthSupport;
@@ -1063,6 +1066,8 @@ struct dml2_core_calcs_mode_support_locals {
bool dummy_boolean_array[2][DML2_MAX_PLANES];
double dummy_single[3];
double dummy_single_array[DML2_MAX_PLANES];
+ double dummy_double_array[3][DML2_MAX_PLANES];
+ enum dml2_pstate_method dummy_pstate_method_array[DML2_MAX_PLANES];
struct dml2_core_internal_watermarks dummy_watermark;
double dummy_bw[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max];
double surface_dummy_bw[dml2_core_internal_soc_state_max][dml2_core_internal_bw_max][DML2_MAX_PLANES];
@@ -1721,30 +1726,30 @@ struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_param
double ReturnBW;
bool SynchronizeTimings;
bool SynchronizeDRRDisplaysForUCLKPStateChange;
- unsigned int *dpte_group_bytes;
+ const unsigned int *dpte_group_bytes;
struct dml2_core_internal_SOCParametersList mmSOCParameters;
unsigned int WritebackChunkSize;
double SOCCLK;
double DCFClkDeepSleep;
- unsigned int *DETBufferSizeY;
- unsigned int *DETBufferSizeC;
- unsigned int *SwathHeightY;
- unsigned int *SwathHeightC;
- unsigned int *SwathWidthY;
- unsigned int *SwathWidthC;
- unsigned int *DPPPerSurface;
- double *BytePerPixelDETY;
- double *BytePerPixelDETC;
- unsigned int *DSTXAfterScaler;
- unsigned int *DSTYAfterScaler;
+ const unsigned int *DETBufferSizeY;
+ const unsigned int *DETBufferSizeC;
+ const unsigned int *SwathHeightY;
+ const unsigned int *SwathHeightC;
+ const unsigned int *SwathWidthY;
+ const unsigned int *SwathWidthC;
+ const unsigned int *DPPPerSurface;
+ const double *BytePerPixelDETY;
+ const double *BytePerPixelDETC;
+ const unsigned int *DSTXAfterScaler;
+ const unsigned int *DSTYAfterScaler;
bool UnboundedRequestEnabled;
unsigned int CompressedBufferSizeInkByte;
bool max_outstanding_when_urgent_expected;
- unsigned int max_outstanding_requests;
- unsigned int max_request_size_bytes;
- unsigned int *meta_row_height_l;
- unsigned int *meta_row_height_c;
- enum dml2_pstate_method *uclk_pstate_switch_modes;
+ const unsigned int max_outstanding_requests;
+ const unsigned int max_request_size_bytes;
+ const unsigned int *meta_row_height_l;
+ const unsigned int *meta_row_height_c;
+ const enum dml2_pstate_method *uclk_pstate_switch_modes;
// Output
struct dml2_core_internal_watermarks *Watermark;
@@ -1931,7 +1936,6 @@ struct dml2_core_calcs_CalculatePrefetchSchedule_params {
bool DynamicMetadataVMEnabled;
unsigned int DynamicMetadataLinesBeforeActiveRequired;
unsigned int DynamicMetadataTransmittedBytes;
- double UrgentLatency;
double ExtraLatencyPrefetch;
double TCalc;
unsigned int vm_bytes;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.c
index 6930ba7ce5b7..4f5533dc0430 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.c
@@ -428,10 +428,6 @@ bool dml2_core_utils_is_phantom_pipe(const struct dml2_plane_parameters *plane_c
unsigned int dml2_core_utils_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel)
{
- if (dml2_core_utils_get_gfx_version(sw_mode) == 10 || dml2_core_utils_get_gfx_version(sw_mode) == 7) {
- return dml2_core_utils_get_tile_block_size_bytes_backcompat(sw_mode, byte_per_pixel);
- }
-
if (sw_mode == dml2_sw_linear)
return 256;
else if (sw_mode == dml2_sw_256b_2d)
@@ -462,56 +458,14 @@ unsigned int dml2_core_utils_get_tile_block_size_bytes(enum dml2_swizzle_mode sw
};
}
-unsigned int dml2_core_utils_get_tile_block_size_bytes_backcompat(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel)
-{
- if (sw_mode == dml2_sw_linear_256b)
- return 256;
- else if (sw_mode == dml2_gfx10_sw_64kb_r_x)
- return 65536;
- else if (sw_mode == dml2_gfx102_sw_64kb_s)
- return 65536;
- else if (sw_mode == dml2_gfx102_sw_64kb_s_t)
- return 65536;
- else if (sw_mode == dml2_gfx102_sw_64kb_s_x)
- return 65536;
- else if (sw_mode == dml2_gfx102_sw_64kb_r_x)
- return 65536;
- else if (sw_mode == dml2_linear_64elements)
- return 256;
- else if (sw_mode == dml2_gfx7_1d_thin)
- return 256;
- else if (sw_mode == dml2_gfx7_2d_thin_gen_zero)
- return (128 * 64 * byte_per_pixel);
- else if (sw_mode == dml2_gfx7_2d_thin_gen_one)
- return (128 * 128 * byte_per_pixel);
- else if (sw_mode == dml2_gfx7_2d_thin_arlene)
- return (64 * 32 * byte_per_pixel);
- else if (sw_mode == dml2_gfx7_2d_thin_anubis)
- return (128 * 128 * byte_per_pixel);
- else {
- DML_ASSERT(0);
- return 256;
- };
-}
-
bool dml2_core_utils_get_segment_horizontal_contiguous(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel)
{
- if (dml2_core_utils_get_gfx_version(sw_mode) == 10 || dml2_core_utils_get_gfx_version(sw_mode) == 7) {
- return dml2_core_utils_get_segment_horizontal_contiguous_backcompat(sw_mode, byte_per_pixel);
- } else {
- return (byte_per_pixel != 2);
- }
-}
-
-bool dml2_core_utils_get_segment_horizontal_contiguous_backcompat(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel)
-{
- return !((byte_per_pixel == 4) &&
- ((sw_mode == dml2_gfx10_sw_64kb_r_x) || (sw_mode == dml2_gfx102_sw_64kb_s) || (sw_mode == dml2_gfx102_sw_64kb_s_t) || (sw_mode == dml2_gfx102_sw_64kb_s_x)));
+ return (byte_per_pixel != 2);
}
bool dml2_core_utils_is_linear(enum dml2_swizzle_mode sw_mode)
{
- return (sw_mode == dml2_sw_linear || sw_mode == dml2_sw_linear_256b || sw_mode == dml2_linear_64elements);
+ return sw_mode == dml2_sw_linear;
};
@@ -544,20 +498,6 @@ int unsigned dml2_core_utils_get_gfx_version(enum dml2_swizzle_mode sw_mode)
sw_mode == dml2_gfx11_sw_256kb_d_x ||
sw_mode == dml2_gfx11_sw_256kb_r_x)
version = 11;
- else if (sw_mode == dml2_sw_linear_256b ||
- sw_mode == dml2_gfx10_sw_64kb_r_x ||
- sw_mode == dml2_gfx102_sw_64kb_s ||
- sw_mode == dml2_gfx102_sw_64kb_s_t ||
- sw_mode == dml2_gfx102_sw_64kb_s_x ||
- sw_mode == dml2_gfx102_sw_64kb_r_x)
- version = 10;
- else if (sw_mode == dml2_linear_64elements ||
- sw_mode == dml2_gfx7_1d_thin ||
- sw_mode == dml2_gfx7_2d_thin_gen_zero ||
- sw_mode == dml2_gfx7_2d_thin_gen_one ||
- sw_mode == dml2_gfx7_2d_thin_arlene ||
- sw_mode == dml2_gfx7_2d_thin_anubis)
- version = 7;
else {
DML_LOG_VERBOSE("ERROR: Invalid sw_mode setting! val=%u\n", sw_mode);
DML_ASSERT(0);
@@ -648,6 +588,7 @@ static void create_phantom_stream_from_main_stream(struct dml2_stream_parameters
static void create_phantom_plane_from_main_plane(struct dml2_plane_parameters *phantom, const struct dml2_plane_parameters *main,
const struct dml2_stream_parameters *phantom_stream, int phantom_stream_index, const struct dml2_stream_parameters *main_stream)
{
+ (void)main_stream;
memcpy(phantom, main, sizeof(struct dml2_plane_parameters));
phantom->stream_index = phantom_stream_index;
@@ -845,3 +786,11 @@ bool dml2_core_utils_is_odm_split(enum dml2_odm_mode odm_mode)
return false;
}
}
+
+double dml2_core_utils_get_frame_time_us(const struct dml2_stream_parameters *stream)
+{
+ double otg_vline_time_us = (double)stream->timing.h_total / (double)stream->timing.pixel_clock_khz * 1000.0;
+ double non_vtotal = stream->timing.vblank_nom + stream->timing.v_active;
+ double frame_time_us = non_vtotal * otg_vline_time_us;
+ return frame_time_us;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.h
index 471e73ed671c..60fa2abfef85 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_utils.h
@@ -22,8 +22,6 @@ void dml2_core_utils_pipe_plane_mapping(const struct core_display_cfg_support_in
bool dml2_core_utils_is_phantom_pipe(const struct dml2_plane_parameters *plane_cfg);
unsigned int dml2_core_utils_get_tile_block_size_bytes(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel);
bool dml2_core_utils_get_segment_horizontal_contiguous(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel);
-unsigned int dml2_core_utils_get_tile_block_size_bytes_backcompat(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel);
-bool dml2_core_utils_get_segment_horizontal_contiguous_backcompat(enum dml2_swizzle_mode sw_mode, unsigned int byte_per_pixel);
bool dml2_core_utils_is_vertical_rotation(enum dml2_rotation_angle Scan);
bool dml2_core_utils_is_linear(enum dml2_swizzle_mode sw_mode);
int unsigned dml2_core_utils_get_gfx_version(enum dml2_swizzle_mode sw_mode);
@@ -41,5 +39,6 @@ bool dml2_core_utils_is_hpo_dp_encoder(const struct dml2_stream_parameters *stre
bool dml2_core_utils_is_dp_8b_10b_link_rate(enum dml2_output_link_dp_rate rate);
bool dml2_core_utils_is_dp_128b_132b_link_rate(enum dml2_output_link_dp_rate rate);
bool dml2_core_utils_is_odm_split(enum dml2_odm_mode odm_mode);
+double dml2_core_utils_get_frame_time_us(const struct dml2_stream_parameters *stream);
#endif /* __DML2_CORE_UTILS_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
index ab0b4a4b5d65..5ffe211a6643 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
@@ -552,6 +552,7 @@ static int get_displays_without_vactive_margin_mask(struct dml2_dpmm_map_mode_to
static int get_displays_with_fams_mask(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out, int latency_hiding_requirement_us)
{
+ (void)latency_hiding_requirement_us;
unsigned int i;
int displays_with_fams_mask = 0x0;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.c
index 1f2d9e97f5fd..39965ff2e111 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_factory.c
@@ -8,11 +8,13 @@
static bool dummy_map_mode_to_soc_dpm(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out)
{
+ (void)in_out;
return true;
}
static bool dummy_map_watermarks(struct dml2_dpmm_map_watermarks_params_in_out *in_out)
{
+ (void)in_out;
return true;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.c
index 3dcd2c250633..fb0b0ac547c7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_mcg/dml2_mcg_factory.c
@@ -9,6 +9,7 @@
static bool dummy_build_min_clock_table(struct dml2_mcg_build_min_clock_table_params_in_out *in_out)
{
+ (void)in_out;
return true;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn42.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn42.c
new file mode 100644
index 000000000000..30fd5efe4b87
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn42.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: MIT
+//
+// Copyright 2026 Advanced Micro Devices, Inc.
+
+#include "dml2_pmo_dcn42.h"
+#include "lib_float_math.h"
+#include "dml2_debug.h"
+#include "dml2_pmo_dcn4_fams2.h"
+
+/*
+ * DCN42 PMO Policy Implementation
+ * This implementation provides VBlank-only strategies for 1, 2, 3, and 4 display
+ * configurations, ensuring p-state watermark support in the blank period only.
+ */
+
+static const struct dml2_pmo_pstate_strategy dcn42_strategy_list_1_display[] = {
+ // VBlank only
+ {
+ .per_stream_pstate_method = { dml2_pstate_method_vblank, dml2_pstate_method_na, dml2_pstate_method_na, dml2_pstate_method_na },
+ .allow_state_increase = true,
+ },
+};
+
+static const int dcn42_strategy_list_1_display_size = sizeof(dcn42_strategy_list_1_display) / sizeof(struct dml2_pmo_pstate_strategy);
+
+static const struct dml2_pmo_pstate_strategy dcn42_strategy_list_2_display[] = {
+ // VBlank only for both displays
+ {
+ .per_stream_pstate_method = { dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_na, dml2_pstate_method_na },
+ .allow_state_increase = true,
+ },
+};
+
+static const int dcn42_strategy_list_2_display_size = sizeof(dcn42_strategy_list_2_display) / sizeof(struct dml2_pmo_pstate_strategy);
+
+static const struct dml2_pmo_pstate_strategy dcn42_strategy_list_3_display[] = {
+ // VBlank only for all three displays
+ {
+ .per_stream_pstate_method = { dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_na },
+ .allow_state_increase = true,
+ },
+};
+
+static const int dcn42_strategy_list_3_display_size = sizeof(dcn42_strategy_list_3_display) / sizeof(struct dml2_pmo_pstate_strategy);
+
+static const struct dml2_pmo_pstate_strategy dcn42_strategy_list_4_display[] = {
+ // VBlank only for all four displays
+ {
+ .per_stream_pstate_method = { dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_vblank, dml2_pstate_method_vblank },
+ .allow_state_increase = true,
+ },
+};
+
+static const int dcn42_strategy_list_4_display_size = sizeof(dcn42_strategy_list_4_display) / sizeof(struct dml2_pmo_pstate_strategy);
+
+bool pmo_dcn42_test_for_pstate_support(struct dml2_pmo_test_for_pstate_support_in_out *in_out)
+{
+ const struct dml2_pmo_scratch *s = &in_out->instance->scratch;
+ const int REQUIRED_RESERVED_TIME =
+ (int)in_out->instance->soc_bb->power_management_parameters.dram_clk_change_blackout_us;
+ bool p_state_supported = true;
+ unsigned int stream_index;
+
+ if (in_out->base_display_config->display_config.overrides.all_streams_blanked)
+ return true;
+
+ if (s->pmo_dcn4.cur_pstate_candidate < 0)
+ return false;
+
+ for (stream_index = 0; stream_index < in_out->base_display_config->display_config.num_streams; stream_index++) {
+ if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_vblank) {
+ if (dcn4_get_minimum_reserved_time_us_for_planes(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < REQUIRED_RESERVED_TIME ||
+ dcn4_get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) > 0) {
+ p_state_supported = false;
+ break;
+ }
+ } else {
+ p_state_supported = false;
+ break;
+ }
+ }
+
+ return p_state_supported;
+}
+
+bool pmo_dcn42_initialize(struct dml2_pmo_initialize_in_out *in_out)
+{
+ int i = 0;
+ struct dml2_pmo_instance *pmo = in_out->instance;
+
+ unsigned int base_list_size = 0;
+ const struct dml2_pmo_pstate_strategy *base_list = NULL;
+ unsigned int *expanded_list_size = NULL;
+ struct dml2_pmo_pstate_strategy *expanded_list = NULL;
+
+ DML_LOG_COMP_IF_ENTER();
+
+ pmo->soc_bb = in_out->soc_bb;
+ pmo->ip_caps = in_out->ip_caps;
+ pmo->mpc_combine_limit = 2;
+ pmo->odm_combine_limit = 4;
+ pmo->mcg_clock_table_size = in_out->mcg_clock_table_size;
+
+ /*
+ * DCN42 does not support FAMS features like SubVP and DRR.
+ * These parameters are initialized to safe values but won't be used
+ * since our strategies only use VBlank.
+ */
+ pmo->fams_params.v2.subvp.refresh_rate_limit_max = 0;
+ pmo->fams_params.v2.subvp.refresh_rate_limit_min = 0;
+ pmo->fams_params.v2.drr.refresh_rate_limit_max = 0;
+ pmo->fams_params.v2.drr.refresh_rate_limit_min = 0;
+
+ pmo->options = in_out->options;
+
+ /* Generate permutations of p-state configs from base strategy list */
+ for (i = 0; i < PMO_DCN4_MAX_DISPLAYS; i++) {
+ switch (i+1) {
+ case 1:
+ if (pmo->options->override_strategy_lists[i] && pmo->options->num_override_strategies_per_list[i]) {
+ base_list = pmo->options->override_strategy_lists[i];
+ base_list_size = pmo->options->num_override_strategies_per_list[i];
+ } else {
+ base_list = dcn42_strategy_list_1_display;
+ base_list_size = dcn42_strategy_list_1_display_size;
+ }
+
+ expanded_list_size = &pmo->init_data.pmo_dcn4.num_expanded_strategies_per_list[i];
+ expanded_list = pmo->init_data.pmo_dcn4.expanded_strategy_list_1_display;
+
+ break;
+ case 2:
+ if (pmo->options->override_strategy_lists[i] && pmo->options->num_override_strategies_per_list[i]) {
+ base_list = pmo->options->override_strategy_lists[i];
+ base_list_size = pmo->options->num_override_strategies_per_list[i];
+ } else {
+ base_list = dcn42_strategy_list_2_display;
+ base_list_size = dcn42_strategy_list_2_display_size;
+ }
+
+ expanded_list_size = &pmo->init_data.pmo_dcn4.num_expanded_strategies_per_list[i];
+ expanded_list = pmo->init_data.pmo_dcn4.expanded_strategy_list_2_display;
+
+ break;
+ case 3:
+ if (pmo->options->override_strategy_lists[i] && pmo->options->num_override_strategies_per_list[i]) {
+ base_list = pmo->options->override_strategy_lists[i];
+ base_list_size = pmo->options->num_override_strategies_per_list[i];
+ } else {
+ base_list = dcn42_strategy_list_3_display;
+ base_list_size = dcn42_strategy_list_3_display_size;
+ }
+
+ expanded_list_size = &pmo->init_data.pmo_dcn4.num_expanded_strategies_per_list[i];
+ expanded_list = pmo->init_data.pmo_dcn4.expanded_strategy_list_3_display;
+
+ break;
+ case 4:
+ if (pmo->options->override_strategy_lists[i] && pmo->options->num_override_strategies_per_list[i]) {
+ base_list = pmo->options->override_strategy_lists[i];
+ base_list_size = pmo->options->num_override_strategies_per_list[i];
+ } else {
+ base_list = dcn42_strategy_list_4_display;
+ base_list_size = dcn42_strategy_list_4_display_size;
+ }
+
+ expanded_list_size = &pmo->init_data.pmo_dcn4.num_expanded_strategies_per_list[i];
+ expanded_list = pmo->init_data.pmo_dcn4.expanded_strategy_list_4_display;
+
+ break;
+ }
+
+ DML_ASSERT(base_list_size <= PMO_DCN4_MAX_BASE_STRATEGIES);
+
+ /*
+ * Populate list using DCN4 FAMS2 expansion function.
+ * Since our strategies only contain VBlank methods, the expansion
+ * will not introduce any FAMS-specific logic.
+ */
+ pmo_dcn4_fams2_expand_base_pstate_strategies(
+ base_list,
+ base_list_size,
+ i + 1,
+ expanded_list,
+ expanded_list_size);
+ }
+
+ DML_LOG_DEBUG("%s exit with true\n", __func__);
+ DML_LOG_COMP_IF_EXIT();
+
+ return true;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn42.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn42.h
new file mode 100644
index 000000000000..31ba8575351d
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn42.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2026 Advanced Micro Devices, Inc.
+ */
+
+#ifndef __DML2_PMO_DCN42_H__
+#define __DML2_PMO_DCN42_H__
+
+#include "dml2_internal_shared_types.h"
+
+struct dml2_pmo_initialize_in_out;
+struct dml2_pmo_test_for_pstate_support_in_out;
+
+bool pmo_dcn42_initialize(struct dml2_pmo_initialize_in_out *in_out);
+bool pmo_dcn42_test_for_pstate_support(struct dml2_pmo_test_for_pstate_support_in_out *in_out);
+
+#endif /* __DML2_PMO_DCN42_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
index e8691983c0eb..b348c65a0f75 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
@@ -428,6 +428,7 @@ static void insert_strategy_into_expanded_list(
struct dml2_pmo_pstate_strategy *expanded_strategy_list,
unsigned int *num_expanded_strategies)
{
+ (void)stream_count;
if (expanded_strategy_list && num_expanded_strategies) {
memcpy(&expanded_strategy_list[*num_expanded_strategies], per_stream_pstate_strategy, sizeof(struct dml2_pmo_pstate_strategy));
@@ -520,6 +521,7 @@ static bool is_variant_method_valid(const struct dml2_pmo_pstate_strategy *base_
const unsigned int num_streams_per_variant_method[PMO_DCN4_MAX_DISPLAYS],
const unsigned int stream_count)
{
+ (void)variant_strategy;
bool valid = true;
unsigned int i;
@@ -1180,6 +1182,7 @@ static bool all_timings_support_svp(const struct dml2_pmo_instance *pmo,
static void insert_into_candidate_list(const struct dml2_pmo_pstate_strategy *pstate_strategy, int stream_count, struct dml2_pmo_scratch *scratch)
{
+ (void)stream_count;
scratch->pmo_dcn4.pstate_strategy_candidates[scratch->pmo_dcn4.num_pstate_candidates] = *pstate_strategy;
scratch->pmo_dcn4.num_pstate_candidates++;
}
@@ -1659,7 +1662,7 @@ static bool validate_pstate_support_strategy_cofunctionality(struct dml2_pmo_ins
return is_config_schedulable(pmo, display_cfg, pstate_strategy);
}
-static int get_vactive_pstate_margin(const struct display_configuation_with_meta *display_cfg, int plane_mask)
+int dcn4_get_vactive_pstate_margin(const struct display_configuation_with_meta *display_cfg, int plane_mask)
{
unsigned int i;
int min_vactive_margin_us = 0xFFFFFFF;
@@ -1847,6 +1850,7 @@ static void build_subvp_meta_per_stream(struct dml2_pmo_instance *pmo,
struct display_configuation_with_meta *display_config,
int stream_index)
{
+ (void)display_config;
struct dml2_implicit_svp_meta *stream_svp_meta = &pmo->scratch.pmo_dcn4.stream_svp_meta[stream_index];
struct dml2_pstate_meta *stream_pstate_meta = &pmo->scratch.pmo_dcn4.stream_pstate_meta[stream_index];
@@ -1903,7 +1907,7 @@ bool pmo_dcn4_fams2_init_for_pstate_support(struct dml2_pmo_init_for_pstate_supp
// Figure out which streams can do vactive, and also build up implicit SVP and FAMS2 meta
for (stream_index = 0; stream_index < display_config->display_config.num_streams; stream_index++) {
- if (get_vactive_pstate_margin(display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) >= (int)(MIN_VACTIVE_MARGIN_PCT * pmo->soc_bb->power_management_parameters.dram_clk_change_blackout_us))
+ if (dcn4_get_vactive_pstate_margin(display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) >= (int)(MIN_VACTIVE_MARGIN_PCT * pmo->soc_bb->power_management_parameters.dram_clk_change_blackout_us))
set_bit_in_bitfield(&s->pmo_dcn4.stream_vactive_capability_mask, stream_index);
/* FAMS2 meta */
@@ -1990,6 +1994,7 @@ static void setup_planes_for_drr_by_mask(struct display_configuation_with_meta *
struct dml2_pmo_instance *pmo,
int plane_mask)
{
+ (void)pmo;
unsigned int plane_index;
struct dml2_plane_parameters *plane;
@@ -2177,7 +2182,9 @@ static bool setup_display_config(struct display_configuation_with_meta *display_
return success;
}
-static int get_minimum_reserved_time_us_for_planes(struct display_configuation_with_meta *display_config, int plane_mask)
+int dcn4_get_minimum_reserved_time_us_for_planes(
+ const struct display_configuation_with_meta *display_config,
+ int plane_mask)
{
int min_time_us = 0xFFFFFF;
unsigned int plane_index = 0;
@@ -2217,16 +2224,16 @@ bool pmo_dcn4_fams2_test_for_pstate_support(struct dml2_pmo_test_for_pstate_supp
if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_vactive ||
s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_vactive_drr) {
- if (get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < (MIN_VACTIVE_MARGIN_PCT * in_out->instance->soc_bb->power_management_parameters.dram_clk_change_blackout_us) ||
+ if (dcn4_get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < (MIN_VACTIVE_MARGIN_PCT * in_out->instance->soc_bb->power_management_parameters.dram_clk_change_blackout_us) ||
get_vactive_det_fill_latency_delay_us(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) > stream_pstate_meta->method_vactive.max_vactive_det_fill_delay_us) {
p_state_supported = false;
break;
}
} else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_vblank ||
s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_vblank_drr) {
- if (get_minimum_reserved_time_us_for_planes(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) <
+ if (dcn4_get_minimum_reserved_time_us_for_planes(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) <
REQUIRED_RESERVED_TIME ||
- get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < MIN_VACTIVE_MARGIN_VBLANK) {
+ dcn4_get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < MIN_VACTIVE_MARGIN_VBLANK) {
p_state_supported = false;
break;
}
@@ -2238,7 +2245,7 @@ bool pmo_dcn4_fams2_test_for_pstate_support(struct dml2_pmo_test_for_pstate_supp
}
} else if (s->pmo_dcn4.pstate_strategy_candidates[s->pmo_dcn4.cur_pstate_candidate].per_stream_pstate_method[stream_index] == dml2_pstate_method_fw_drr) {
if (!all_planes_match_method(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index], dml2_pstate_method_fw_drr) ||
- get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < MIN_VACTIVE_MARGIN_DRR) {
+ dcn4_get_vactive_pstate_margin(in_out->base_display_config, s->pmo_dcn4.stream_plane_mask[stream_index]) < MIN_VACTIVE_MARGIN_DRR) {
p_state_supported = false;
break;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.h
index 6baab7ad6ecc..f0afa8002a2f 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.h
@@ -7,6 +7,16 @@
#include "dml2_internal_shared_types.h"
+struct display_configuation_with_meta;
+
+int dcn4_get_vactive_pstate_margin(
+ const struct display_configuation_with_meta *display_cfg,
+ int plane_mask);
+
+int dcn4_get_minimum_reserved_time_us_for_planes(
+ const struct display_configuation_with_meta *display_config,
+ int plane_mask);
+
bool pmo_dcn4_fams2_initialize(struct dml2_pmo_initialize_in_out *in_out);
bool pmo_dcn4_fams2_optimize_dcc_mcache(struct dml2_pmo_optimize_dcc_mcache_in_out *in_out);
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_factory.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_factory.c
index 4d687fa86caa..83802aac11cd 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_factory.c
@@ -9,16 +9,19 @@
static bool dummy_init_for_stutter(struct dml2_pmo_init_for_stutter_in_out *in_out)
{
+ (void)in_out;
return false;
}
static bool dummy_test_for_stutter(struct dml2_pmo_test_for_stutter_in_out *in_out)
{
+ (void)in_out;
return true;
}
static bool dummy_optimize_for_stutter(struct dml2_pmo_optimize_for_stutter_in_out *in_out)
{
+ (void)in_out;
return false;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_standalone_libraries/lib_float_math.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_standalone_libraries/lib_float_math.c
index e17b5ceba447..dc5bc649f3ac 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_standalone_libraries/lib_float_math.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_standalone_libraries/lib_float_math.c
@@ -23,7 +23,7 @@ double math_mod(const double arg1, const double arg2)
return arg2;
if (isNaN(arg2))
return arg1;
- return arg1 - arg1 * ((int)(arg1 / arg2));
+ return arg1 - arg2 * ((int)(arg1 / arg2));
}
double math_min2(const double arg1, const double arg2)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_top/dml2_top_soc15.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_top/dml2_top_soc15.c
index 4a7c4c62111e..fa20a91c6e16 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_top/dml2_top_soc15.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_top/dml2_top_soc15.c
@@ -17,6 +17,7 @@ static void setup_unoptimized_display_config_with_meta(const struct dml2_instanc
static void setup_speculative_display_config_with_meta(const struct dml2_instance *dml, struct display_configuation_with_meta *out, const struct dml2_display_cfg *display_config)
{
+ (void)dml;
memcpy(&out->display_config, display_config, sizeof(struct dml2_display_cfg));
out->stage1.min_clk_index_for_latency = 0;
}
@@ -472,6 +473,7 @@ static unsigned int count_elements_in_span(int *array, unsigned int array_size,
static bool calculate_h_split_for_scaling_transform(int full_vp_width, int h_active, int num_pipes,
enum dml2_scaling_transform scaling_transform, int *pipe_vp_x_start, int *pipe_vp_x_end)
{
+ (void)h_active;
int i, slice_width;
const char MAX_SCL_VP_OVERLAP = 3;
bool success = false;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_dc_resource_mgmt.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_dc_resource_mgmt.c
index 6ef93c6fc1cd..6b78334c2554 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_dc_resource_mgmt.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_dc_resource_mgmt.c
@@ -178,6 +178,10 @@ static unsigned int find_pipes_assigned_to_plane(struct dml2_context *ctx,
static bool validate_pipe_assignment(const struct dml2_context *ctx, const struct dc_state *state, const struct dml_display_cfg_st *disp_cfg, const struct dml2_dml_to_dc_pipe_mapping *mapping)
{
+ (void)ctx;
+ (void)disp_cfg;
+ (void)mapping;
+ (void)state;
// int i, j, k;
//
// unsigned int plane_id;
@@ -292,6 +296,7 @@ static unsigned int find_last_resort_pipe_candidates(const struct dc_state *exis
const unsigned int stream_id,
unsigned int *last_resort_pipe_candidates)
{
+ (void)stream_id;
unsigned int num_last_resort_candidates = 0;
int i;
@@ -541,6 +546,7 @@ static void add_odm_slice_to_odm_tree(struct dml2_context *ctx,
struct dc_pipe_mapping_scratch *scratch,
unsigned int odm_slice_index)
{
+ (void)ctx;
struct pipe_ctx *pipe = NULL;
int i;
@@ -567,6 +573,8 @@ static struct pipe_ctx *add_plane_to_blend_tree(struct dml2_context *ctx,
unsigned int odm_slice,
struct pipe_ctx *top_pipe)
{
+ (void)ctx;
+ (void)plane;
int i;
for (i = 0; i < pipe_pool->num_pipes_assigned_to_plane_for_mpcc_combine; i++) {
@@ -722,6 +730,7 @@ static void free_unused_pipes_for_plane(struct dml2_context *ctx, struct dc_stat
static void remove_pipes_from_blend_trees(struct dml2_context *ctx, struct dc_state *state, struct dc_plane_pipe_pool *pipe_pool, unsigned int odm_slice)
{
+ (void)ctx;
struct pipe_ctx *pipe;
int i;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c
index cf3a69aba638..8e0997441ee0 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c
@@ -33,6 +33,7 @@
void dml2_init_ip_params(struct dml2_context *dml2, const struct dc *in_dc, struct ip_params_st *out)
{
+ (void)in_dc;
switch (dml2->v20.dml_core_ctx.project) {
case dml_project_dcn32:
case dml_project_dcn321:
@@ -244,6 +245,7 @@ void dml2_init_ip_params(struct dml2_context *dml2, const struct dc *in_dc, stru
void dml2_init_socbb_params(struct dml2_context *dml2, const struct dc *in_dc, struct soc_bounding_box_st *out)
{
+ (void)in_dc;
out->dprefclk_mhz = dml2->config.bbox_overrides.dprefclk_mhz;
out->xtalclk_mhz = dml2->config.bbox_overrides.xtalclk_mhz;
out->pcierefclk_mhz = 100;
@@ -328,6 +330,7 @@ void dml2_init_socbb_params(struct dml2_context *dml2, const struct dc *in_dc, s
void dml2_init_soc_states(struct dml2_context *dml2, const struct dc *in_dc,
const struct soc_bounding_box_st *in_bbox, struct soc_states_st *out)
{
+ (void)in_dc;
struct dml2_policy_build_synthetic_soc_states_scratch *s = &dml2->v20.scratch.create_scratch.build_synthetic_socbb_scratch;
struct dml2_policy_build_synthetic_soc_states_params *p = &dml2->v20.scratch.build_synthetic_socbb_params;
int dcfclk_stas_mhz[NUM_DCFCLK_STAS] = {0};
@@ -782,6 +785,7 @@ static void populate_dml_timing_cfg_from_stream_state(struct dml_timing_cfg_st *
static void populate_dml_output_cfg_from_stream_state(struct dml_output_cfg_st *out, unsigned int location,
const struct dc_stream_state *in, const struct pipe_ctx *pipe, struct dml2_context *dml2)
{
+ (void)pipe;
unsigned int output_bpc;
out->DSCEnable[location] = (enum dml_dsc_enable)in->timing.flags.DSC;
@@ -1133,6 +1137,7 @@ static void populate_dml_plane_cfg_from_plane_state(struct dml_plane_cfg_st *out
static unsigned int map_stream_to_dml_display_cfg(const struct dml2_context *dml2,
const struct dc_stream_state *stream, const struct dml_display_cfg_st *dml_dispcfg)
{
+ (void)dml_dispcfg;
int i = 0;
int location = -1;
@@ -1173,6 +1178,7 @@ static bool get_plane_id(struct dml2_context *dml2, const struct dc_state *conte
static unsigned int map_plane_to_dml_display_cfg(const struct dml2_context *dml2, const struct dc_plane_state *plane,
const struct dc_state *context, const struct dml_display_cfg_st *dml_dispcfg, unsigned int stream_id, int plane_index)
{
+ (void)dml_dispcfg;
unsigned int plane_id;
unsigned int i = 0;
unsigned int location = UINT_MAX;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_utils.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_utils.c
index 6c7cdf102906..86567e232415 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_utils.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_utils.c
@@ -465,6 +465,7 @@ void dml2_initialize_det_scratch(struct dml2_context *in_ctx)
static unsigned int find_planes_per_stream_and_stream_count(struct dml2_context *in_ctx, struct dml_display_cfg_st *dml_dispcfg, int *num_of_planes_per_stream)
{
+ (void)in_ctx;
unsigned int plane_index, stream_index = 0, num_of_streams;
for (plane_index = 0; plane_index < dml_dispcfg->num_surfaces; plane_index++) {
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper.c
index 93b7613fc4f2..1772e74349c7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper.c
@@ -108,6 +108,17 @@ bool dml2_create(const struct dc *in_dc, const struct dml2_configuration_options
return true;
}
+void dml2_destroy(struct dml2_context *dml2)
+{
+ if (!dml2)
+ return;
+
+ if (dml2->architecture == dml2_architecture_21)
+ dml21_destroy(dml2);
+
+ DC_RUN_WITH_PREEMPTION_ENABLED(vfree(dml2));
+}
+
void dml2_reinit(const struct dc *in_dc,
const struct dml2_configuration_options *config,
struct dml2_context **dml2)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper_fpu.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper_fpu.c
index 66624cfc27b1..a14e3004a7b7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_wrapper_fpu.c
@@ -548,16 +548,6 @@ void dml2_apply_debug_options(const struct dc *dc, struct dml2_context *dml2)
}
}
-void dml2_destroy(struct dml2_context *dml2)
-{
- if (!dml2)
- return;
-
- if (dml2->architecture == dml2_architecture_21)
- dml21_destroy(dml2);
- vfree(dml2);
-}
-
void dml2_extract_dram_and_fclk_change_support(struct dml2_context *dml2,
unsigned int *fclk_change_support, unsigned int *dram_clk_change_support)
{
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml_display_rq_dlg_calc.c
index 00d22e542469..18962bbf455b 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml_display_rq_dlg_calc.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml_display_rq_dlg_calc.c
@@ -563,6 +563,7 @@ void dml_rq_dlg_get_dlg_reg(dml_display_dlg_regs_st *disp_dlg_regs,
void dml_rq_dlg_get_arb_params(struct display_mode_lib_st *mode_lib, dml_display_arb_params_st *arb_param)
{
+ (void)mode_lib;
memset(arb_param, 0, sizeof(*arb_param));
arb_param->max_req_outstanding = 256;
arb_param->min_req_outstanding = 256; // turn off the sat level feature if this set to max
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
index 5b3584ad5b6b..8dfb6dd14eb2 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
@@ -680,9 +680,6 @@ static void get_dsc_enc_caps(
} else {
build_dsc_enc_caps(dsc, dsc_enc_caps);
}
-
- if (dsc->ctx->dc->debug.native422_support)
- dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 1;
}
/* Returns 'false' if no intersection was found for at least one capability.
@@ -1100,13 +1097,14 @@ static bool setup_dsc_config(
branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_0_mps;
break;
case PIXEL_ENCODING_YCBCR422:
- is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_NATIVE_422;
- sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_1_mps;
- branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_1_mps;
- if (!is_dsc_possible) {
+ if (policy.ycbcr422_simple) {
is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_SIMPLE_422;
dsc_cfg->ycbcr422_simple = is_dsc_possible;
sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_0_mps;
+ } else {
+ is_dsc_possible = (bool)dsc_common_caps.color_formats.bits.YCBCR_NATIVE_422;
+ sink_per_slice_throughput_mps = dsc_sink_caps->throughput_mode_1_mps;
+ branch_max_throughput_mps = dsc_sink_caps->branch_overall_throughput_1_mps;
}
break;
case PIXEL_ENCODING_YCBCR420:
@@ -1406,6 +1404,7 @@ void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
policy->min_target_bpp = 8;
/* DP specs limits to 3 x bpc */
policy->max_target_bpp = 3 * bpc;
+ policy->ycbcr422_simple = true;
break;
case PIXEL_ENCODING_YCBCR420:
/* DP specs limits to 6 */
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c
index 242f1e6f0d8f..6e1e759462bf 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c
@@ -100,7 +100,7 @@ void dsc2_get_enc_caps(struct dsc_enc_caps *dsc_enc_caps, int pixel_clock_100Hz)
dsc_enc_caps->color_formats.bits.RGB = 1;
dsc_enc_caps->color_formats.bits.YCBCR_444 = 1;
dsc_enc_caps->color_formats.bits.YCBCR_SIMPLE_422 = 1;
- dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 0;
+ dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 1;
dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_420 = 1;
dsc_enc_caps->color_depth.bits.COLOR_DEPTH_8_BPC = 1;
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c
index e712985f7abd..17acb64a9d80 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c
@@ -128,7 +128,7 @@ void dsc35_get_single_enc_caps(struct dsc_enc_caps *dsc_enc_caps, unsigned int m
dsc_enc_caps->color_formats.bits.RGB = 1;
dsc_enc_caps->color_formats.bits.YCBCR_444 = 1;
dsc_enc_caps->color_formats.bits.YCBCR_SIMPLE_422 = 1;
- dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 0;
+ dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 1;
dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_420 = 1;
dsc_enc_caps->color_depth.bits.COLOR_DEPTH_8_BPC = 1;
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c
index 3bf737195bac..41c3b814b6bd 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c
@@ -78,7 +78,7 @@ static void dsc401_get_single_enc_caps(struct dsc_enc_caps *dsc_enc_caps, unsign
dsc_enc_caps->color_formats.bits.RGB = 1;
dsc_enc_caps->color_formats.bits.YCBCR_444 = 1;
dsc_enc_caps->color_formats.bits.YCBCR_SIMPLE_422 = 1;
- dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 0;
+ dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 1;
dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_420 = 1;
dsc_enc_caps->color_depth.bits.COLOR_DEPTH_8_BPC = 1;
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
index 59851924bfcd..794dd6a95918 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -781,10 +781,8 @@ static void restore_phy_clocks_for_destructive_link_verification(const struct dc
}
static void verify_link_capability_destructive(struct dc_link *link,
- struct dc_sink *sink,
enum dc_detect_reason reason)
{
- (void)sink;
bool should_prepare_phy_clocks =
should_prepare_phy_clocks_for_link_verification(link->dc, reason);
@@ -857,11 +855,11 @@ static bool should_verify_link_capability_destructively(struct dc_link *link,
return destrictive;
}
-static void verify_link_capability(struct dc_link *link, struct dc_sink *sink,
+static void verify_link_capability(struct dc_link *link,
enum dc_detect_reason reason)
{
if (should_verify_link_capability_destructively(link, reason))
- verify_link_capability_destructive(link, sink, reason);
+ verify_link_capability_destructive(link, reason);
else
verify_link_capability_non_destructive(link);
}
@@ -1236,6 +1234,20 @@ static bool detect_link_and_local_sink(struct dc_link *link,
if (dc_is_hdmi_signal(link->connector_signal))
read_scdc_caps(link->ddc, link->local_sink);
+ /* When FreeSync is toggled through OSD,
+ * we see same EDID no matter what. Check MCCS caps
+ * to see if we should update FreeSync caps now.
+ */
+ dm_helpers_read_mccs_caps(
+ link->ctx,
+ link,
+ sink);
+
+ if (prev_sink != NULL) {
+ if (memcmp(&sink->mccs_caps, &prev_sink->mccs_caps, sizeof(struct mccs_caps)))
+ same_edid = false;
+ }
+
if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
sink_caps.transaction_type ==
DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
@@ -1455,8 +1467,9 @@ bool link_detect(struct dc_link *link, enum dc_detect_reason reason)
is_local_sink_detect_success = detect_link_and_local_sink(link, reason);
- if (is_local_sink_detect_success && link->local_sink)
- verify_link_capability(link, link->local_sink, reason);
+ if (is_local_sink_detect_success && link->local_sink) {
+ verify_link_capability(link, reason);
+ }
DC_LOG_DC("%s: link_index=%d is_local_sink_detect_success=%d pre_link_type=%d link_type=%d\n", __func__,
link->link_index, is_local_sink_detect_success, pre_link_type, link->type);
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
index b4f46408a000..e12c25896364 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
@@ -181,7 +181,8 @@ void link_set_all_streams_dpms_off_for_link(struct dc_link *link)
/* link can be also enabled by vbios. In this case it is not recorded
* in pipe_ctx. Disable link phy here to make sure it is completely off
*/
- dp_disable_link_phy(link, &link_res, link->connector_signal);
+ if (dc_is_dp_signal(link->connector_signal))
+ dp_disable_link_phy(link, &link_res, link->connector_signal);
}
void link_resume(struct dc_link *link)
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
index e12bf3dd3e46..782a45caa13d 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
@@ -743,8 +743,6 @@ static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_setting
{
struct dc_link_settings initial_link_setting = {
LANE_COUNT_ONE, LINK_RATE_LOW, LINK_SPREAD_DISABLED, false, 0};
- if (link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN)
- initial_link_setting.link_rate = link->preferred_link_setting.link_rate;
struct dc_link_settings current_link_setting =
initial_link_setting;
uint32_t link_bw;
@@ -752,6 +750,9 @@ static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_setting
if (req_bw > dp_link_bandwidth_kbps(link, &link->verified_link_cap))
return false;
+ if (link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN)
+ initial_link_setting.link_rate = link->preferred_link_setting.link_rate;
+
/* search for the minimum link setting that:
* 1. is supported according to the link training result
* 2. could support the b/w requested by the timing
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
index 54ebf8cf607f..84f6d9dc443f 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
@@ -1394,6 +1394,13 @@ static enum dc_status dcn21_patch_unknown_plane_state(struct dc_plane_state *pla
return dcn20_patch_unknown_plane_state(plane_state);
}
+static void dcn21_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+{
+ DC_FP_START();
+ dcn21_update_bw_bounding_box_fpu(dc, bw_params);
+ DC_FP_END();
+}
+
static const struct resource_funcs dcn21_res_pool_funcs = {
.destroy = dcn21_destroy_resource_pool,
.link_enc_create = dcn21_link_encoder_create,
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
index ee4bc2c2e73a..39944d90ea98 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
@@ -1854,6 +1854,13 @@ static struct dc_cap_funcs cap_funcs = {
.get_dcc_compression_cap = dcn20_get_dcc_compression_cap
};
+static void dcn31_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+{
+ DC_FP_START();
+ dcn31_update_bw_bounding_box_fpu(dc, bw_params);
+ DC_FP_END();
+}
+
static struct resource_funcs dcn31_res_pool_funcs = {
.destroy = dcn31_destroy_resource_pool,
.link_enc_create = dcn31_link_encoder_create,
@@ -1996,6 +2003,8 @@ static bool dcn31_resource_construct(
dc->config.use_pipe_ctx_sync_logic = true;
dc->config.disable_hbr_audio_dp2 = true;
+ dc->config.no_native422_support = true;
+
/* read VBIOS LTTPR caps */
{
if (ctx->dc_bios->funcs->get_lttpr_caps) {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
index 2ca673114841..975e14f3f5fa 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
@@ -1849,6 +1849,13 @@ static struct dc_cap_funcs cap_funcs = {
.get_dcc_compression_cap = dcn20_get_dcc_compression_cap
};
+static void dcn315_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+{
+ DC_FP_START();
+ dcn315_update_bw_bounding_box_fpu(dc, bw_params);
+ DC_FP_END();
+}
+
static struct resource_funcs dcn315_res_pool_funcs = {
.destroy = dcn315_destroy_resource_pool,
.link_enc_create = dcn31_link_encoder_create,
@@ -1959,6 +1966,8 @@ static bool dcn315_resource_construct(
dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
dc->caps.color.mpc.ocsc = 1;
+ dc->config.no_native422_support = true;
+
/* read VBIOS LTTPR caps */
{
if (ctx->dc_bios->funcs->get_lttpr_caps) {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
index 2242df112a3f..914d91df174c 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
@@ -1725,6 +1725,13 @@ static struct dc_cap_funcs cap_funcs = {
.get_dcc_compression_cap = dcn20_get_dcc_compression_cap
};
+static void dcn316_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
+{
+ DC_FP_START();
+ dcn316_update_bw_bounding_box_fpu(dc, bw_params);
+ DC_FP_END();
+}
+
static struct resource_funcs dcn316_res_pool_funcs = {
.destroy = dcn316_destroy_resource_pool,
.link_enc_create = dcn31_link_encoder_create,
diff --git a/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn42/dcn42_soc_and_ip_translator.c b/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn42/dcn42_soc_and_ip_translator.c
index 146a6e47934b..e723b4d0aff3 100644
--- a/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn42/dcn42_soc_and_ip_translator.c
+++ b/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/dcn42/dcn42_soc_and_ip_translator.c
@@ -155,6 +155,10 @@ static void dcn42_update_soc_bb_with_values_from_clk_mgr(struct dml2_soc_bb *soc
dcn42_convert_dc_clock_table_to_soc_bb_clock_table(&soc_bb->clk_table, &soc_bb->vmin_limit,
dc->clk_mgr->bw_params);
}
+
+ if (dc->clk_mgr->bw_params->vram_type == Ddr5MemType) {
+ soc_bb->power_management_parameters = dcn42_ddr5_power_management_parameters;
+ }
}
static void apply_soc_bb_updates(struct dml2_soc_bb *soc_bb, const struct dc *dc, const struct dml2_configuration_options *config)
diff --git a/drivers/gpu/drm/amd/display/include/ddc_service_types.h b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
index 1c603b12957f..53210e3aa0e0 100644
--- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h
@@ -36,6 +36,7 @@
#define DP_BRANCH_DEVICE_ID_006037 0x006037
#define DP_BRANCH_DEVICE_ID_001CF8 0x001CF8
#define DP_BRANCH_DEVICE_ID_0060AD 0x0060AD
+#define DP_BRANCH_DEVICE_ID_001FF2 0x001FF2
#define DP_BRANCH_HW_REV_10 0x10
#define DP_BRANCH_HW_REV_20 0x20
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index c9150019aab0..f3b41087678b 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -153,7 +153,7 @@ unsigned int mod_freesync_calc_v_total_from_refresh(
* round down the vtotal value to avoid stretching vblank over
* panel's vtotal boundary.
*/
- v_total = div64_u64(div64_u64(((unsigned long long)(
+ v_total = (unsigned int)div64_u64(div64_u64(((unsigned long long)(
frame_duration_in_ns) * (stream->timing.pix_clk_100hz / 10)),
stream->timing.h_total), 1000000);
} else if (refresh_in_uhz >= stream->timing.max_refresh_in_uhz) {
@@ -161,11 +161,11 @@ unsigned int mod_freesync_calc_v_total_from_refresh(
* round up the vtotal value to prevent off-by-one error causing
* v_total_min to be below the panel's lower bound
*/
- v_total = div64_u64(div64_u64(((unsigned long long)(
+ v_total = (unsigned int)div64_u64(div64_u64(((unsigned long long)(
frame_duration_in_ns) * (stream->timing.pix_clk_100hz / 10)),
stream->timing.h_total) + (1000000 - 1), 1000000);
} else {
- v_total = div64_u64(div64_u64(((unsigned long long)(
+ v_total = (unsigned int)div64_u64(div64_u64(((unsigned long long)(
frame_duration_in_ns) * (stream->timing.pix_clk_100hz / 10)),
stream->timing.h_total) + 500000, 1000000);
}
@@ -196,11 +196,11 @@ static unsigned int calc_v_total_from_duration(
uint32_t h_total_up_scaled;
h_total_up_scaled = stream->timing.h_total * 10000;
- v_total = div_u64((unsigned long long)duration_in_us
+ v_total = (unsigned int)div_u64((unsigned long long)duration_in_us
* stream->timing.pix_clk_100hz + (h_total_up_scaled - 1),
h_total_up_scaled); //ceiling for MMax and MMin for MVRR
} else {
- v_total = div64_u64(div64_u64(((unsigned long long)(
+ v_total = (unsigned int)div64_u64(div64_u64(((unsigned long long)(
duration_in_us) * (stream->timing.pix_clk_100hz / 10)),
stream->timing.h_total), 1000);
}
@@ -232,22 +232,28 @@ static void update_v_total_for_static_ramp(
target_duration_in_us;
/* Calculate ratio between new and current frame duration with 3 digit */
- unsigned int frame_duration_ratio = div64_u64(1000000,
+ uint64_t frame_duration_ratio_u64 = div64_u64(1000000,
(1000 + div64_u64(((unsigned long long)(
STATIC_SCREEN_RAMP_DELTA_REFRESH_RATE_PER_FRAME) *
current_duration_in_us),
1000000)));
+ ASSERT(frame_duration_ratio_u64 <= 0xFFFFFFFF);
+ unsigned int frame_duration_ratio = (unsigned int)frame_duration_ratio_u64;
/* Calculate delta between new and current frame duration in us */
- unsigned int frame_duration_delta = div64_u64(((unsigned long long)(
+ uint64_t frame_duration_delta_u64 = div64_u64(((unsigned long long)(
current_duration_in_us) *
(1000 - frame_duration_ratio)), 1000);
+ ASSERT(frame_duration_delta_u64 <= 0xFFFFFFFF);
+ unsigned int frame_duration_delta = (unsigned int)frame_duration_delta_u64;
/* Adjust frame duration delta based on ratio between current and
* standard frame duration (frame duration at 60 Hz refresh rate).
*/
- unsigned int ramp_rate_interpolated = div64_u64(((unsigned long long)(
+ uint64_t ramp_rate_interpolated_u64 = div64_u64(((unsigned long long)(
frame_duration_delta) * current_duration_in_us), 16666);
+ ASSERT(ramp_rate_interpolated_u64 <= 0xFFFFFFFF);
+ unsigned int ramp_rate_interpolated = (unsigned int)ramp_rate_interpolated_u64;
/* Going to a higher refresh rate (lower frame duration) */
if (ramp_direction_is_up) {
@@ -277,7 +283,7 @@ static void update_v_total_for_static_ramp(
}
}
- v_total = div64_u64(div64_u64(((unsigned long long)(
+ v_total = (unsigned int)div64_u64(div64_u64(((unsigned long long)(
current_duration_in_us) * (stream->timing.pix_clk_100hz / 10)),
stream->timing.h_total), 1000);
@@ -1058,8 +1064,12 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
else
in_out_vrr->fixed_refresh_in_uhz = 0;
- refresh_range = div_u64(in_out_vrr->max_refresh_in_uhz + 500000, 1000000) -
- div_u64(in_out_vrr->min_refresh_in_uhz + 500000, 1000000);
+ {
+ uint64_t rr_tmp = div_u64(in_out_vrr->max_refresh_in_uhz + 500000, 1000000) -
+ div_u64(in_out_vrr->min_refresh_in_uhz + 500000, 1000000);
+ ASSERT(rr_tmp <= 0xFFFFFFFF);
+ refresh_range = (unsigned int)rr_tmp;
+ }
in_out_vrr->supported = true;
}
diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
index df3b8383b06d..5d444e9eb38f 100644
--- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
+++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
@@ -250,10 +250,12 @@ static void fill_backlight_transform_table(struct dmcu_iram_parameters params,
unsigned int lut_index;
table->backlight_thresholds[0] = 0;
- table->backlight_offsets[0] = params.backlight_lut_array[0];
+ ASSERT(params.backlight_lut_array[0] <= 0xFFFF);
+ table->backlight_offsets[0] = (uint16_t)params.backlight_lut_array[0];
table->backlight_thresholds[num_entries-1] = 0xFFFF;
+ ASSERT(params.backlight_lut_array[params.backlight_lut_array_size - 1] <= 0xFFFF);
table->backlight_offsets[num_entries-1] =
- params.backlight_lut_array[params.backlight_lut_array_size - 1];
+ (uint16_t)params.backlight_lut_array[params.backlight_lut_array_size - 1];
/* Setup all brightness levels between 0% and 100% exclusive
* Fills brightness-to-backlight transform table. Backlight custom curve
@@ -265,12 +267,17 @@ static void fill_backlight_transform_table(struct dmcu_iram_parameters params,
*/
for (i = 1; i+1 < num_entries; i++) {
lut_index = (params.backlight_lut_array_size - 1) * i / (num_entries - 1);
+
ASSERT(lut_index < params.backlight_lut_array_size);
- table->backlight_thresholds[i] =
- cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries));
- table->backlight_offsets[i] =
- cpu_to_be16(params.backlight_lut_array[lut_index]);
+ unsigned int threshold_val = DIV_ROUNDUP((i * 65536), num_entries);
+ unsigned int offset_val = params.backlight_lut_array[lut_index];
+
+ ASSERT(threshold_val <= 0xFFFF);
+ ASSERT(offset_val <= 0xFFFF);
+
+ table->backlight_thresholds[i] = cpu_to_be16((uint16_t)threshold_val);
+ table->backlight_offsets[i] = cpu_to_be16((uint16_t)offset_val);
}
}
@@ -282,10 +289,12 @@ static void fill_backlight_transform_table_v_2_2(struct dmcu_iram_parameters par
unsigned int lut_index;
table->backlight_thresholds[0] = 0;
- table->backlight_offsets[0] = params.backlight_lut_array[0];
+ ASSERT(params.backlight_lut_array[0] <= 0xFFFF);
+ table->backlight_offsets[0] = (uint16_t)params.backlight_lut_array[0];
table->backlight_thresholds[num_entries-1] = 0xFFFF;
+ ASSERT(params.backlight_lut_array[params.backlight_lut_array_size - 1] <= 0xFFFF);
table->backlight_offsets[num_entries-1] =
- params.backlight_lut_array[params.backlight_lut_array_size - 1];
+ (uint16_t)params.backlight_lut_array[params.backlight_lut_array_size - 1];
/* Setup all brightness levels between 0% and 100% exclusive
* Fills brightness-to-backlight transform table. Backlight custom curve
@@ -299,12 +308,16 @@ static void fill_backlight_transform_table_v_2_2(struct dmcu_iram_parameters par
lut_index = DIV_ROUNDUP((i * params.backlight_lut_array_size), num_entries);
ASSERT(lut_index < params.backlight_lut_array_size);
+ unsigned int threshold_val = DIV_ROUNDUP((i * 65536), num_entries);
+ unsigned int offset_val = params.backlight_lut_array[lut_index];
+
+ ASSERT(threshold_val <= 0xFFFF);
+ ASSERT(offset_val <= 0xFFFF);
+
table->backlight_thresholds[i] = (big_endian) ?
- cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries)) :
- cpu_to_le16(DIV_ROUNDUP((i * 65536), num_entries));
+ cpu_to_be16((uint16_t)threshold_val) : cpu_to_le16((uint16_t)threshold_val);
table->backlight_offsets[i] = (big_endian) ?
- cpu_to_be16(params.backlight_lut_array[lut_index]) :
- cpu_to_le16(params.backlight_lut_array[lut_index]);
+ cpu_to_be16((uint16_t)offset_val) : cpu_to_le16((uint16_t)offset_val);
}
}
@@ -740,9 +753,12 @@ bool dmub_init_abm_config(struct resource_pool *res_pool,
}
if (params.backlight_ramping_override) {
+
+ ASSERT(params.backlight_ramping_reduction <= 0xFFFF);
+ ASSERT(params.backlight_ramping_start <= 0xFFFF);
for (i = 0; i < NUM_AGGR_LEVEL; i++) {
- config.blRampReduction[i] = params.backlight_ramping_reduction;
- config.blRampStart[i] = params.backlight_ramping_start;
+ config.blRampReduction[i] = (uint16_t)params.backlight_ramping_reduction;
+ config.blRampStart[i] = (uint16_t)params.backlight_ramping_start;
}
} else {
for (i = 0; i < NUM_AGGR_LEVEL; i++) {
@@ -1060,6 +1076,7 @@ void calculate_replay_link_off_frame_count(struct dc_link *link,
bool fill_custom_backlight_caps(unsigned int config_no, struct dm_acpi_atif_backlight_caps *caps)
{
unsigned int data_points_size;
+ uint64_t caps_size;
if (config_no >= ARRAY_SIZE(custom_backlight_profiles))
return false;
@@ -1067,7 +1084,9 @@ bool fill_custom_backlight_caps(unsigned int config_no, struct dm_acpi_atif_back
data_points_size = custom_backlight_profiles[config_no].num_data_points
* sizeof(custom_backlight_profiles[config_no].data_points[0]);
- caps->size = sizeof(struct dm_acpi_atif_backlight_caps) - sizeof(caps->data_points) + data_points_size;
+ caps_size = sizeof(struct dm_acpi_atif_backlight_caps) - sizeof(caps->data_points) + data_points_size;
+ ASSERT(caps_size <= 0xFFFF);
+ caps->size = (uint16_t)caps_size;
caps->flags = 0;
caps->error_code = 0;
caps->ac_level_percentage = custom_backlight_profiles[config_no].ac_level_percentage;
diff --git a/drivers/gpu/drm/amd/display/modules/vmid/vmid.c b/drivers/gpu/drm/amd/display/modules/vmid/vmid.c
index 9f408cb11ac9..179b505f7777 100644
--- a/drivers/gpu/drm/amd/display/modules/vmid/vmid.c
+++ b/drivers/gpu/drm/amd/display/modules/vmid/vmid.c
@@ -57,7 +57,10 @@ static void clear_entry_from_vmid_table(struct core_vmid *core_vmid, unsigned in
static void evict_vmids(struct core_vmid *core_vmid)
{
int i;
- uint16_t ord = dc_get_vmid_use_vector(core_vmid->dc);
+ int ord_int = dc_get_vmid_use_vector(core_vmid->dc);
+
+ ASSERT(ord_int >= 0 && ord_int <= 0xFFFF);
+ uint16_t ord = (uint16_t)ord_int;
// At this point any positions with value 0 are unused vmids, evict them
for (i = 1; i < core_vmid->num_vmid; i++) {
@@ -120,7 +123,8 @@ uint8_t mod_vmid_get_for_ptb(struct mod_vmid *mod_vmid, uint64_t ptb)
ASSERT(0);
}
- return vmid;
+ ASSERT(vmid >= 0 && vmid <= 0xFF);
+ return (uint8_t)vmid;
}
void mod_vmid_reset(struct mod_vmid *mod_vmid)
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index 62b0b1ef0d10..736304e73ca4 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -995,12 +995,15 @@ static ssize_t amdgpu_get_pp_dpm_clock(struct device *dev,
return ret;
ret = amdgpu_dpm_emit_clock_levels(adev, type, buf, &size);
- if (ret)
- return ret;
+ if (ret) {
+ size = ret;
+ goto out_pm_put;
+ }
if (size == 0)
size = sysfs_emit(buf, "\n");
+out_pm_put:
amdgpu_pm_put_access(adev);
return size;
@@ -3902,11 +3905,14 @@ static int amdgpu_retrieve_od_settings(struct amdgpu_device *adev,
return ret;
ret = amdgpu_dpm_emit_clock_levels(adev, od_type, buf, &size);
- if (ret)
- return ret;
+ if (ret) {
+ size = ret;
+ goto out_pm_put;
+ }
if (size == 0)
size = sysfs_emit(buf, "\n");
+out_pm_put:
amdgpu_pm_put_access(adev);
return size;
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
index 8c37aa452569..55e2375e1dad 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
@@ -3062,9 +3062,6 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
smu7_set_private_data_based_on_pptable_v0(hwmgr);
}
- if (result)
- goto fail;
-
data->is_tlu_enabled = false;
hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
index 126fc54cb511..d76e0b005308 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
@@ -584,6 +584,7 @@ struct cmn2asic_mapping {
/* Message flags for smu_msg_args */
#define SMU_MSG_FLAG_ASYNC BIT(0) /* Async send - skip post-poll */
#define SMU_MSG_FLAG_LOCK_HELD BIT(1) /* Caller holds ctl->lock */
+#define SMU_MSG_FLAG_FORCE_READ_ARG BIT(2) /* force read smu arg from pmfw */
/* smu_msg_ctl flags */
#define SMU_MSG_CTL_DEBUG_MAILBOX BIT(0) /* Debug mailbox supported */
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
index dc056f1e4b64..7f386ff0c872 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
@@ -1846,6 +1846,7 @@ static int aldebaran_mode2_reset(struct smu_context *smu)
amdgpu_device_load_pci_state(adev->pdev);
dev_dbg(adev->dev, "wait for reset ack\n");
+ ret = -ETIME;
while (ret == -ETIME && timeout) {
ret = smu_msg_wait_response(ctl, 0);
/* Wait a bit more time for getting ACK */
@@ -1855,7 +1856,7 @@ static int aldebaran_mode2_reset(struct smu_context *smu)
continue;
}
- if (ret != 1) {
+ if (ret != 0) {
dev_err(adev->dev, "failed to send mode2 message \tparam: 0x%08x response %#x\n",
SMU_RESET_MODE_2, ret);
goto out;
@@ -1865,10 +1866,9 @@ static int aldebaran_mode2_reset(struct smu_context *smu)
} else {
dev_err(adev->dev, "smu fw 0x%x does not support MSG_GfxDeviceDriverReset MSG\n",
smu->smc_fw_version);
+ ret = -EOPNOTSUPP;
}
- if (ret == 1)
- ret = 0;
out:
mutex_unlock(&ctl->lock);
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
index 62514e3ac600..5ce4e982ca33 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
@@ -2214,17 +2214,61 @@ static void smu_v14_0_2_dump_od_table(struct smu_context *smu,
od_table->OverDriveTable.UclkFmax);
}
+#define OD_ERROR_MSG_MAP(msg) \
+ [msg] = #msg
+
+static const char *od_error_message[] = {
+ OD_ERROR_MSG_MAP(OD_REQUEST_ADVANCED_NOT_SUPPORTED),
+ OD_ERROR_MSG_MAP(OD_UNSUPPORTED_FEATURE),
+ OD_ERROR_MSG_MAP(OD_INVALID_FEATURE_COMBO_ERROR),
+ OD_ERROR_MSG_MAP(OD_GFXCLK_VF_CURVE_OFFSET_ERROR),
+ OD_ERROR_MSG_MAP(OD_VDD_GFX_VMAX_ERROR),
+ OD_ERROR_MSG_MAP(OD_VDD_SOC_VMAX_ERROR),
+ OD_ERROR_MSG_MAP(OD_PPT_ERROR),
+ OD_ERROR_MSG_MAP(OD_FAN_MIN_PWM_ERROR),
+ OD_ERROR_MSG_MAP(OD_FAN_ACOUSTIC_TARGET_ERROR),
+ OD_ERROR_MSG_MAP(OD_FAN_ACOUSTIC_LIMIT_ERROR),
+ OD_ERROR_MSG_MAP(OD_FAN_TARGET_TEMP_ERROR),
+ OD_ERROR_MSG_MAP(OD_FAN_ZERO_RPM_STOP_TEMP_ERROR),
+ OD_ERROR_MSG_MAP(OD_FAN_CURVE_PWM_ERROR),
+ OD_ERROR_MSG_MAP(OD_FAN_CURVE_TEMP_ERROR),
+ OD_ERROR_MSG_MAP(OD_FULL_CTRL_GFXCLK_ERROR),
+ OD_ERROR_MSG_MAP(OD_FULL_CTRL_UCLK_ERROR),
+ OD_ERROR_MSG_MAP(OD_FULL_CTRL_FCLK_ERROR),
+ OD_ERROR_MSG_MAP(OD_FULL_CTRL_VDD_GFX_ERROR),
+ OD_ERROR_MSG_MAP(OD_FULL_CTRL_VDD_SOC_ERROR),
+ OD_ERROR_MSG_MAP(OD_TDC_ERROR),
+ OD_ERROR_MSG_MAP(OD_GFXCLK_ERROR),
+ OD_ERROR_MSG_MAP(OD_UCLK_ERROR),
+ OD_ERROR_MSG_MAP(OD_FCLK_ERROR),
+ OD_ERROR_MSG_MAP(OD_OP_TEMP_ERROR),
+ OD_ERROR_MSG_MAP(OD_OP_GFX_EDC_ERROR),
+ OD_ERROR_MSG_MAP(OD_OP_GFX_PCC_ERROR),
+ OD_ERROR_MSG_MAP(OD_POWER_FEATURE_CTRL_ERROR),
+};
+
static int smu_v14_0_2_upload_overdrive_table(struct smu_context *smu,
OverDriveTableExternal_t *od_table)
{
- int ret;
- ret = smu_cmn_update_table(smu,
- SMU_TABLE_OVERDRIVE,
- 0,
- (void *)od_table,
- true);
- if (ret)
- dev_err(smu->adev->dev, "Failed to upload overdrive table!\n");
+ uint32_t read_arg = 0;
+ int ret, od_error_type;
+
+ ret = smu_cmn_update_table_read_arg(smu,
+ SMU_TABLE_OVERDRIVE,
+ 0,
+ (void *)od_table,
+ &read_arg,
+ true);
+ if (ret) {
+ dev_err(smu->adev->dev, "Failed to upload overdrive table, ret:%d\n", ret);
+ if ((read_arg & 0xff) == TABLE_TRANSFER_FAILED) {
+ od_error_type = read_arg >> 16;
+ dev_err(smu->adev->dev, "Invalid overdrive table content: %s (%d)\n",
+ od_error_type < ARRAY_SIZE(od_error_message) ?
+ od_error_message[od_error_type] : "unknown",
+ od_error_type);
+ }
+ }
return ret;
}
@@ -2374,6 +2418,7 @@ static int smu_v14_0_2_od_restore_table_single(struct smu_context *smu, long inp
}
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask &= ~BIT(PP_OD_FEATURE_FAN_LEGACY_BIT);
break;
case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
od_table->OverDriveTable.FanZeroRpmEnable =
@@ -2402,7 +2447,8 @@ static int smu_v14_0_2_od_restore_table_single(struct smu_context *smu, long inp
od_table->OverDriveTable.FanMinimumPwm =
boot_overdrive_table->OverDriveTable.FanMinimumPwm;
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
- od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_LEGACY_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask &= ~BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
default:
dev_info(adev->dev, "Invalid table index: %ld\n", input);
@@ -2572,6 +2618,7 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
od_table->OverDriveTable.FanLinearPwmPoints[input[0]] = input[2];
od_table->OverDriveTable.FanMode = FAN_MODE_MANUAL_LINEAR;
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask &= ~BIT(PP_OD_FEATURE_FAN_LEGACY_BIT);
break;
case PP_OD_EDIT_ACOUSTIC_LIMIT:
@@ -2641,7 +2688,7 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
break;
case PP_OD_EDIT_FAN_MINIMUM_PWM:
- if (!smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) {
+ if (!smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_LEGACY_BIT)) {
dev_warn(adev->dev, "Fan curve setting not supported!\n");
return -ENOTSUPP;
}
@@ -2659,7 +2706,8 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
od_table->OverDriveTable.FanMinimumPwm = input[0];
od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
- od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_LEGACY_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask &= ~BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
break;
case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
index 006ef585a377..3d49e58794d2 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
@@ -496,7 +496,8 @@ static int smu_msg_v1_send_msg(struct smu_msg_ctl *ctl,
}
/* Read output args */
- if (ret == 0 && args->num_out_args > 0) {
+ if ((ret == 0 || (args->flags & SMU_MSG_FLAG_FORCE_READ_ARG)) &&
+ args->num_out_args > 0) {
__smu_msg_v1_read_out_args(ctl, args);
dev_dbg(adev->dev, "smu send message: %s(%d) resp : 0x%08x",
smu_get_message_name(smu, args->msg), index, reg);
@@ -1060,20 +1061,24 @@ int smu_cmn_check_fw_version(struct smu_context *smu)
return 0;
}
-int smu_cmn_update_table(struct smu_context *smu,
- enum smu_table_id table_index,
- int argument,
- void *table_data,
- bool drv2smu)
+int smu_cmn_update_table_read_arg(struct smu_context *smu,
+ enum smu_table_id table_index,
+ int argument,
+ void *table_data,
+ uint32_t *read_arg,
+ bool drv2smu)
{
- struct smu_table_context *smu_table = &smu->smu_table;
struct amdgpu_device *adev = smu->adev;
+ struct smu_table_context *smu_table = &smu->smu_table;
struct smu_table *table = &smu_table->driver_table;
+ struct smu_msg_ctl *ctl = &smu->msg_ctl;
+ struct smu_msg_args args;
int table_id = smu_cmn_to_asic_specific_index(smu,
CMN2ASIC_MAPPING_TABLE,
table_index);
uint32_t table_size;
int ret = 0;
+
if (!table_data || table_index >= SMU_TABLE_COUNT || table_id < 0)
return -EINVAL;
@@ -1088,11 +1093,19 @@ int smu_cmn_update_table(struct smu_context *smu,
amdgpu_hdp_flush(adev, NULL);
}
- ret = smu_cmn_send_smc_msg_with_param(smu, drv2smu ?
- SMU_MSG_TransferTableDram2Smu :
- SMU_MSG_TransferTableSmu2Dram,
- table_id | ((argument & 0xFFFF) << 16),
- NULL);
+ args.msg = drv2smu ? SMU_MSG_TransferTableDram2Smu : SMU_MSG_TransferTableSmu2Dram;
+ args.args[0] = ((argument & 0xFFFF) << 16) | (table_id & 0xffff);
+ args.num_args = 1;
+ args.out_args[0] = 0;
+ args.num_out_args = read_arg ? 1 : 0;
+ args.flags = read_arg ? SMU_MSG_FLAG_FORCE_READ_ARG : 0;
+ args.timeout = 0;
+
+ ret = ctl->ops->send_msg(ctl, &args);
+
+ if (read_arg)
+ *read_arg = args.out_args[0];
+
if (ret)
return ret;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
index d129907535bd..c6ac0e876aea 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
@@ -102,6 +102,9 @@ int smu_msg_send_async_locked(struct smu_msg_ctl *ctl,
#define SMU_DPM_PCIE_GEN_IDX(gen) smu_cmn_dpm_pcie_gen_idx((gen))
#define SMU_DPM_PCIE_WIDTH_IDX(width) smu_cmn_dpm_pcie_width_idx((width))
+#define smu_cmn_update_table(smu, table_index, argument, table_data, drv2smu) \
+ smu_cmn_update_table_read_arg((smu), (table_index), (argument), (table_data), NULL, (drv2smu))
+
extern const int link_speed[];
/* Helper to Convert from PCIE Gen 1/2/3/4/5/6 to 0.1 GT/s speed units */
@@ -168,11 +171,12 @@ int smu_cmn_get_smc_version(struct smu_context *smu,
uint32_t *if_version,
uint32_t *smu_version);
-int smu_cmn_update_table(struct smu_context *smu,
- enum smu_table_id table_index,
- int argument,
- void *table_data,
- bool drv2smu);
+int smu_cmn_update_table_read_arg(struct smu_context *smu,
+ enum smu_table_id table_index,
+ int argument,
+ void *table_data,
+ uint32_t *read_arg,
+ bool drv2smu);
int smu_cmn_vram_cpy(struct smu_context *smu, void *dst,
const void *src, size_t len);
diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c
index eb552d0cce4a..fb4d375e87b2 100644
--- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c
+++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c
@@ -517,14 +517,9 @@ int amdgpu_virt_ras_hw_fini(struct amdgpu_device *adev)
(struct amdgpu_virt_ras_cmd *)ras_mgr->virt_ras_cmd;
struct vram_blocks_ecc *blks_ecc = &virt_ras->blocks_ecc;
- if (blks_ecc->shared_mem.cpu_addr) {
- __set_cmd_auto_update(adev,
- RAS_CMD__GET_ALL_BLOCK_ECC_STATUS,
- blks_ecc->shared_mem.gpa,
- blks_ecc->shared_mem.size, false);
-
+ if (blks_ecc->shared_mem.cpu_addr)
memset(blks_ecc->shared_mem.cpu_addr, 0, blks_ecc->shared_mem.size);
- }
+
memset(blks_ecc, 0, sizeof(*blks_ecc));
return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 998c3faf5f2e..53c10ae76ab5 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2981,7 +2981,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
return ret;
do {
- bool cursor_in_su_area;
+ bool cursor_in_su_area = false;
/*
* Adjust su area to cover cursor fully as necessary
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c
index 7c36c30a75b6..1a246ebbfc61 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c
@@ -513,7 +513,7 @@ static void rcar_du_cmm_setup(struct drm_crtc *crtc)
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
struct rcar_cmm_config cmm_config = {};
- if (!rcrtc->cmm->dev)
+ if (!rcrtc->cmm)
return;
if (drm_lut)
@@ -667,7 +667,7 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
if (rcar_du_has(rcrtc->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
rcar_du_vsp_disable(rcrtc);
- if (rcrtc->cmm->dev)
+ if (rcrtc->cmm)
rcar_cmm_disable(rcrtc->cmm->dev);
/*
@@ -726,7 +726,7 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
struct rcar_du_crtc_state *rstate = to_rcar_crtc_state(crtc->state);
struct rcar_du_device *rcdu = rcrtc->dev;
- if (rcrtc->cmm->dev)
+ if (rcrtc->cmm)
rcar_cmm_enable(rcrtc->cmm->dev);
rcar_du_crtc_get(rcrtc);