[PATCH 23/23] drm/amd/display: 3.2.301

2024-09-11 Thread Alex Hung
From: Aric Cyr 

- Clear cached watermark after resume
- Update IPS default mode for DCN35/DCN351
- Use full update for swizzle mode change
- Skip to enable dsc if it has been off
- Fix underflow when setting underscan on DCN401
- Remove always-false branches
- Check null pointer before dereferencing se

Acked-by: Alex Hung 
Signed-off-by: Aric Cyr 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/dc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 78ebe636389e..3992ad73165b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -55,7 +55,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.300"
+#define DC_VER "3.2.301"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.34.1



[PATCH 22/23] drm/amd/display: Clear cached watermark after resume

2024-09-11 Thread Alex Hung
From: Charlene Liu 

[WHY]
Driver could skip program watermarks when resume from S0i3/S4.

[HOW]
Clear the cached one first to make sure new value gets applied.

Reviewed-by: Alvin Lee 
Reviewed-by: Roman Li 
Signed-off-by: Charlene Liu 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c 
b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c
index 6293173ba2b9..5eb3da8d5206 100644
--- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c
@@ -545,6 +545,7 @@ static void hubbub35_init(struct hubbub *hubbub)
DCHUBBUB_ARB_MAX_REQ_OUTSTAND, 256,
DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 256);
 
+   memset(&hubbub2->watermarks.a.cstate_pstate, 0, 
sizeof(hubbub2->watermarks.a.cstate_pstate));
 }
 
 /*static void hubbub35_set_request_limit(struct hubbub *hubbub,
-- 
2.34.1



[PATCH 21/23] drm/amd/display: Update IPS default mode for DCN35/DCN351

2024-09-11 Thread Alex Hung
From: Roman Li 

[WHY]
RCG state of IPX in idle is more stable for DCN351 and some variants of
DCN35 than IPS2.

[HOW]
Rework dm_get_default_ips_mode() to specify default per ASIC and update
DCN35/DCN351 defaults accordingly.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Sun peng Li 
Signed-off-by: Roman Li 
Signed-off-by: Alex Hung 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 50 ---
 1 file changed, 33 insertions(+), 17 deletions(-)

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 c77982245f60..c50880422502 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1771,25 +1771,41 @@ static struct dml2_soc_bb 
*dm_dmub_get_vbios_bounding_box(struct amdgpu_device *
 static enum dmub_ips_disable_type dm_get_default_ips_mode(
struct amdgpu_device *adev)
 {
-   /*
-* On DCN35 systems with Z8 enabled, it's possible for IPS2 + Z8 to
-* cause a hard hang. A fix exists for newer PMFW.
-*
-* As a workaround, for non-fixed PMFW, force IPS1+RCG as the deepest
-* IPS state in all cases, except for s0ix and all displays off (DPMS),
-* where IPS2 is allowed.
-*
-* When checking pmfw version, use the major and minor only.
-*/
-   if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(3, 5, 0) &&
-   (adev->pm.fw_version & 0x0000) < 0x005D6300)
-   return DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
+   enum dmub_ips_disable_type ret = DMUB_IPS_ENABLE;
 
-   if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 5, 0))
-   return DMUB_IPS_ENABLE;
+   switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
+   case IP_VERSION(3, 5, 0):
+   /*
+* On DCN35 systems with Z8 enabled, it's possible for IPS2 + 
Z8 to
+* cause a hard hang. A fix exists for newer PMFW.
+*
+* As a workaround, for non-fixed PMFW, force IPS1+RCG as the 
deepest
+* IPS state in all cases, except for s0ix and all displays off 
(DPMS),
+* where IPS2 is allowed.
+*
+* When checking pmfw version, use the major and minor only.
+*/
+   if ((adev->pm.fw_version & 0x0000) < 0x005D6300)
+   ret = DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
+   else if (amdgpu_ip_version(adev, GC_HWIP, 0) > IP_VERSION(11, 
5, 0))
+   /*
+* Other ASICs with DCN35 that have residency issues 
with
+* IPS2 in idle.
+* We want them to use IPS2 only in display off cases.
+*/
+   ret =  DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
+   break;
+   case IP_VERSION(3, 5, 1):
+   ret =  DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
+   break;
+   default:
+   /* ASICs older than DCN35 do not have IPSs */
+   if (amdgpu_ip_version(adev, DCE_HWIP, 0) < IP_VERSION(3, 5, 0))
+   ret = DMUB_IPS_DISABLE_ALL;
+   break;
+   }
 
-   /* ASICs older than DCN35 do not have IPSs */
-   return DMUB_IPS_DISABLE_ALL;
+   return ret;
 }
 
 static int amdgpu_dm_init(struct amdgpu_device *adev)
-- 
2.34.1



[PATCH 20/23] drm/amd/display: Use full update for swizzle mode change

2024-09-11 Thread Alex Hung
From: Charlene Liu 

[WHY & HOW]
1) We did linear/non linear transition properly long ago
2) We used that path to handle SystemDisplayEnable
3) We fixed a SystemDisplayEnable inability to fallback to passive by
   impacting the transition flow generically
4) AFMF later relied on the generic transition behavior

Separating the two flows to make (3) non-generic is the best immediate
coarse of action.

DC can discern SSAMPO3 very easily from SDE.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Chris Park 
Signed-off-by: Charlene Liu 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 6 +++---
 drivers/gpu/drm/amd/display/dc/dc.h  | 1 +
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 67812fbbb006..a1652130e4be 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2376,7 +2376,7 @@ static bool is_surface_in_context(
return false;
 }
 
-static enum surface_update_type get_plane_info_update_type(const struct 
dc_surface_update *u)
+static enum surface_update_type get_plane_info_update_type(const struct dc 
*dc, const struct dc_surface_update *u)
 {
union surface_update_flags *update_flags = &u->surface->update_flags;
enum surface_update_type update_type = UPDATE_TYPE_FAST;
@@ -2455,7 +2455,7 @@ static enum surface_update_type 
get_plane_info_update_type(const struct dc_surfa
/* todo: below are HW dependent, we should add a hook to
 * DCE/N resource and validated there.
 */
-   if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR) {
+   if (!dc->debug.skip_full_updated_if_possible) {
/* swizzled mode requires RQ to be setup properly,
 * thus need to run DML to calculate RQ settings
 */
@@ -2547,7 +2547,7 @@ static enum surface_update_type det_surface_update(const 
struct dc *dc,
 
update_flags->raw = 0; // Reset all flags
 
-   type = get_plane_info_update_type(u);
+   type = get_plane_info_update_type(dc, u);
elevate_update_type(&overall_type, type);
 
type = get_scaling_info_update_type(dc, u);
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index e659f4fed19f..78ebe636389e 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1060,6 +1060,7 @@ struct dc_debug_options {
bool enable_ips_visual_confirm;
unsigned int sharpen_policy;
unsigned int scale_to_sharpness_policy;
+   bool skip_full_updated_if_possible;
 };
 
 
-- 
2.34.1



[PATCH 19/23] drm/amd/display: Skip to enable dsc if it has been off

2024-09-11 Thread Alex Hung
From: Zhikai Zhai 

[WHY]
It makes DSC enable when we commit the stream which need
keep power off, and then it will skip to disable DSC if
pipe reset at this situation as power has been off. It may
cause the DSC unexpected enable on the pipe with the
next new stream which doesn't support DSC.

[HOW]
Check the DSC used on current pipe status when update stream.
Skip to enable if it has been off. The operation enable
DSC should happen when set power on.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Wenjing Liu 
Signed-off-by: Zhikai Zhai 
Signed-off-by: Alex Hung 
---
 .../drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c| 14 ++
 .../drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c| 13 +
 2 files changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
index a36e11606f90..2e8c9f738259 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
@@ -1032,6 +1032,20 @@ void dcn32_update_dsc_on_stream(struct pipe_ctx 
*pipe_ctx, bool enable)
struct dsc_config dsc_cfg;
struct dsc_optc_config dsc_optc_cfg = {0};
enum optc_dsc_mode optc_dsc_mode;
+   struct dcn_dsc_state dsc_state = {0};
+
+   if (!dsc) {
+   DC_LOG_DSC("DSC is NULL for tg instance %d:", 
pipe_ctx->stream_res.tg->inst);
+   return;
+   }
+
+   if (dsc->funcs->dsc_read_state) {
+   dsc->funcs->dsc_read_state(dsc, &dsc_state);
+   if (!dsc_state.dsc_fw_en) {
+   DC_LOG_DSC("DSC has been disabled for tg 
instance %d:", pipe_ctx->stream_res.tg->inst);
+   return;
+   }
+   }
 
/* Enable DSC hw block */
dsc_cfg.pic_width = (stream->timing.h_addressable + 
stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
index 479fd3e89e5a..bd309dbdf7b2 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
@@ -334,7 +334,20 @@ static void update_dsc_on_stream(struct pipe_ctx 
*pipe_ctx, bool enable)
struct dsc_config dsc_cfg;
struct dsc_optc_config dsc_optc_cfg = {0};
enum optc_dsc_mode optc_dsc_mode;
+   struct dcn_dsc_state dsc_state = {0};
 
+   if (!dsc) {
+   DC_LOG_DSC("DSC is NULL for tg instance %d:", 
pipe_ctx->stream_res.tg->inst);
+   return;
+   }
+
+   if (dsc->funcs->dsc_read_state) {
+   dsc->funcs->dsc_read_state(dsc, &dsc_state);
+   if (!dsc_state.dsc_fw_en) {
+   DC_LOG_DSC("DSC has been disabled for tg 
instance %d:", pipe_ctx->stream_res.tg->inst);
+   return;
+   }
+   }
/* Enable DSC hw block */
dsc_cfg.pic_width = (stream->timing.h_addressable + 
stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
dsc_cfg.pic_height = stream->timing.v_addressable + 
stream->timing.v_border_top + stream->timing.v_border_bottom;
-- 
2.34.1



[PATCH 18/23] drm/amd/display: Fix underflow when setting underscan on DCN401

2024-09-11 Thread Alex Hung
From: Aurabindo Pillai 

[WHY & HOW]
When underscan is set through xrandr, it causes the stream destination
rect to change in a way it becomes complicated to handle the calculations
for subvp. Since this is a corner case, disable subvp when underscan is
set.

Fix the existing check that is supposed to catch this corner case by
adding a check based on the parameters in the stream

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Dillon Varone 
Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Aurabindo Pillai 
Signed-off-by: Alex Hung 
---
 .../drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c  | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
index b0d9aed0f265..8697eac1e1f7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
@@ -858,7 +858,9 @@ static void 
populate_dml21_plane_config_from_plane_state(struct dml2_context *dm
 
plane->immediate_flip = plane_state->flip_immediate;
 
-   plane->composition.rect_out_height_spans_vactive = 
plane_state->dst_rect.height >= stream->timing.v_addressable;
+   plane->composition.rect_out_height_spans_vactive =
+   plane_state->dst_rect.height >= stream->timing.v_addressable &&
+   stream->dst.height >= stream->timing.v_addressable;
 }
 
 //TODO : Could be possibly moved to a common helper layer.
-- 
2.34.1



[PATCH 17/23] drm/amd/display: Remove always-false branches

2024-09-11 Thread Alex Hung
[WHAT & HOW]
req128_c is always set to false and its branch is never taken.
Similarly, MacroTileSizeBytes is set to either 256 or 65535 and it is
never 4096 and it's branch is not taken.

Therefore, their branches are removed.

This fixes 3 DEADCODE issues reported by Coverity.

Acked-by: Alex Hung 
Reviewed-by: Alvin Lee 
Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Alex Hung 
---
 .../amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c| 3 ---
 .../amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c  | 3 ---
 .../drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c   | 9 -
 3 files changed, 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
index e7019c95ba79..4fce64a030b6 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
@@ -313,9 +313,6 @@ static void handle_det_buf_split(struct display_mode_lib 
*mode_lib,
 
if (swath_height_c > 0)
log2_swath_height_c = dml_log2(swath_height_c);
-
-   if (req128_c && log2_swath_height_c > 0)
-   log2_swath_height_c -= 1;
}
 
rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
index ae5251041728..3fa9a5da02f6 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
@@ -313,9 +313,6 @@ static void handle_det_buf_split(struct display_mode_lib 
*mode_lib,
 
if (swath_height_c > 0)
log2_swath_height_c = dml_log2(swath_height_c);
-
-   if (req128_c && log2_swath_height_c > 0)
-   log2_swath_height_c -= 1;
}
 
rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
index 0b132ce1d2cd..2b275e680379 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
@@ -1924,15 +1924,6 @@ static unsigned int CalculateVMAndRowBytes(
*PixelPTEReqWidth = 32768.0 / BytePerPixel;
*PTERequestSize = 64;
FractionOfPTEReturnDrop = 0;
-   } else if (MacroTileSizeBytes == 4096) {
-   PixelPTEReqHeightPTEs = 1;
-   *PixelPTEReqHeight = MacroTileHeight;
-   *PixelPTEReqWidth = 8 * *MacroTileWidth;
-   *PTERequestSize = 64;
-   if (ScanDirection != dm_vert)
-   FractionOfPTEReturnDrop = 0;
-   else
-   FractionOfPTEReturnDrop = 7.0 / 8;
} else if (GPUVMMinPageSize == 4 && MacroTileSizeBytes > 4096) {
PixelPTEReqHeightPTEs = 16;
*PixelPTEReqHeight = 16 * BlockHeight256Bytes;
-- 
2.34.1



[PATCH 16/23] drm/amd/display: Check null pointer before dereferencing se

2024-09-11 Thread Alex Hung
[WHAT & HOW]
se is null checked previously in the same function, indicating
it might be null; therefore, it must be checked when used again.

This fixes 1 FORWARD_NULL issue reported by Coverity.

Acked-by: Alex Hung 
Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index eb7c7681bdd9..67812fbbb006 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1767,7 +1767,7 @@ bool dc_validate_boot_timing(const struct dc *dc,
if (crtc_timing->pix_clk_100hz != pix_clk_100hz)
return false;
 
-   if (!se->funcs->dp_get_pixel_format)
+   if (!se || !se->funcs->dp_get_pixel_format)
return false;
 
if (!se->funcs->dp_get_pixel_format(
-- 
2.34.1



[PATCH 15/23] drm/amd/display: 3.2.300

2024-09-11 Thread Alex Hung
From: Aric Cyr 

- Add HDMI DSC native YCbCr422 support
- Add fullscreen only sharpening policy
- Restructure dpia link training
- Disable SYMCLK32_LE root clock gating
- Clean up dsc blocks in accelerated mode
- Block dynamic IPS2 on DCN35 for incompatible FW versions
- Add debug options to change sharpen policies
- Block timing sync for different output formats in pmo
- Enable DML2 override_det_buffer_size_kbytes
- Add dmub hpd sense callback
- Emulate Display Hotplug Hang
- Implement new DPCD register handling
- Use SDR white level to calculate matrix coefficients
- Round calculated vtotal

Reviewed-by: Alex Hung 
Signed-off-by: Aric Cyr 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/dc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 133cac4d9fc4..e659f4fed19f 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -55,7 +55,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.299"
+#define DC_VER "3.2.300"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.34.1



[PATCH 14/23] drm/amd/display: Add HDMI DSC native YCbCr422 support

2024-09-11 Thread Alex Hung
From: Leo Ma 

[WHY && HOW]
For some HDMI OVT timing, YCbCr422 encoding fails at the DSC
bandwidth check. The root cause is our DSC policy for timing
doesn't account for HDMI YCbCr422 native support.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Chris Park 
Signed-off-by: Leo Ma 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 4 ++--
 drivers/gpu/drm/amd/display/dc/dc_dsc.h | 3 ++-
 drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c | 5 +++--
 3 files changed, 7 insertions(+), 5 deletions(-)

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 658584819d6e..358c4bff1c40 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
@@ -1146,7 +1146,7 @@ static int compute_mst_dsc_configs_for_link(struct 
drm_atomic_state *state,
params[count].num_slices_v = 
aconnector->dsc_settings.dsc_num_slices_v;
params[count].bpp_overwrite = 
aconnector->dsc_settings.dsc_bits_per_pixel;
params[count].compression_possible = 
stream->sink->dsc_caps.dsc_dec_caps.is_dsc_supported;
-   dc_dsc_get_policy_for_timing(params[count].timing, 0, 
&dsc_policy);
+   dc_dsc_get_policy_for_timing(params[count].timing, 0, 
&dsc_policy, dc_link_get_highest_encoding_format(stream->link));
if (!dc_dsc_compute_bandwidth_range(
stream->sink->ctx->dc->res_pool->dscs[0],

stream->sink->ctx->dc->debug.dsc_min_slice_height_override,
@@ -1680,7 +1680,7 @@ static bool is_dsc_common_config_possible(struct 
dc_stream_state *stream,
 {
struct dc_dsc_policy dsc_policy = {0};
 
-   dc_dsc_get_policy_for_timing(&stream->timing, 0, &dsc_policy);
+   dc_dsc_get_policy_for_timing(&stream->timing, 0, &dsc_policy, 
dc_link_get_highest_encoding_format(stream->link));
dc_dsc_compute_bandwidth_range(stream->sink->ctx->dc->res_pool->dscs[0],
   
stream->sink->ctx->dc->debug.dsc_min_slice_height_override,
   dsc_policy.min_target_bpp * 16,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dsc.h 
b/drivers/gpu/drm/amd/display/dc/dc_dsc.h
index 2a5120ecf48b..9014c2409817 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dsc.h
@@ -101,7 +101,8 @@ uint32_t dc_dsc_stream_bandwidth_overhead_in_kbps(
  */
 void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
uint32_t max_target_bpp_limit_override_x16,
-   struct dc_dsc_policy *policy);
+   struct dc_dsc_policy *policy,
+   const enum dc_link_encoding_format link_encoding);
 
 void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit);
 
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 79c426425911..ebd5df1a36e8 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
@@ -883,7 +883,7 @@ static bool setup_dsc_config(
 
memset(dsc_cfg, 0, sizeof(struct dc_dsc_config));
 
-   dc_dsc_get_policy_for_timing(timing, 
options->max_target_bpp_limit_override_x16, &policy);
+   dc_dsc_get_policy_for_timing(timing, 
options->max_target_bpp_limit_override_x16, &policy, link_encoding);
pic_width = timing->h_addressable + timing->h_border_left + 
timing->h_border_right;
pic_height = timing->v_addressable + timing->v_border_top + 
timing->v_border_bottom;
 
@@ -1173,7 +1173,8 @@ uint32_t dc_dsc_stream_bandwidth_overhead_in_kbps(
 
 void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
uint32_t max_target_bpp_limit_override_x16,
-   struct dc_dsc_policy *policy)
+   struct dc_dsc_policy *policy,
+   const enum dc_link_encoding_format link_encoding)
 {
uint32_t bpc = 0;
 
-- 
2.34.1



[PATCH 13/23] drm/amd/display: Add fullscreen only sharpening policy

2024-09-11 Thread Alex Hung
From: Relja Vojvodic 

[WHAT & HOW]
Disable sharpening if not in fullscreen if this policy is selected

Reviewed-by: Samson Tam 
Signed-off-by: Relja Vojvodic 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/spl/dc_spl.c   | 3 +++
 drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h | 3 ++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c 
b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
index f7a654b3a092..014e8a296f0c 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
@@ -853,6 +853,9 @@ static bool spl_get_isharp_en(struct spl_in *spl_in,
else if ((spl_is_yuv420(spl_in->basic_in.format) && !fullscreen) &&
(spl_in->debug.sharpen_policy == SHARPEN_RGB_FULLSCREEN_YUV))
return enable_isharp;
+   else if (!spl_in->is_fullscreen &&
+   spl_in->debug.sharpen_policy == SHARPEN_FULLSCREEN_ALL)
+   return enable_isharp;
 
/*
 * Apply sharpness if supports horizontal taps 4,6 AND
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h 
b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h
index 425d4a282c7a..2a74ff5fdfdb 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl_types.h
@@ -490,7 +490,8 @@ enum linear_light_scaling   {   // convert it in 
translation logic
 enum sharpen_policy {
SHARPEN_ALWAYS = 0,
SHARPEN_YUV = 1,
-   SHARPEN_RGB_FULLSCREEN_YUV = 2
+   SHARPEN_RGB_FULLSCREEN_YUV = 2,
+   SHARPEN_FULLSCREEN_ALL = 3
 };
 enum scale_to_sharpness_policy {
NO_SCALE_TO_SHARPNESS_ADJ = 0,
-- 
2.34.1



[PATCH 12/23] drm/amd/display: Restructure dpia link training

2024-09-11 Thread Alex Hung
From: Peichen Huang 

[WHY]
We intend to consolidate dp tunneling and conventional dp link training.

[HOW]
1. Use the same link training entry for both dp and dpia
2. Move SET_CONFIG of non-transparent mode to dmub side
3. Add set_tps_notification dmub_cmd to notify tps request for
   non-transparent dpia link training
4. Check dpcd request result and abort link training early if dpia
   aux tunneling fails
5. Add option to avoid affect old product
6. Separately handle wait_time_microsec for dpia

Reviewed-by: Cruise Hung 
Reviewed-by: George Shen 
Reviewed-by: Meenakshikumar Somasundaram 
Signed-off-by: Peichen Huang 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  | 21 +
 drivers/gpu/drm/amd/display/dc/dc.h   |  6 +-
 .../amd/display/dc/link/hwss/link_hwss_dpia.c | 31 ++-
 .../dc/link/protocols/link_dp_training.c  | 80 ---
 .../dc/link/protocols/link_dp_training.h  | 16 +++-
 .../link/protocols/link_dp_training_8b_10b.c  | 21 ++---
 .../dc/link/protocols/link_dp_training_dpia.c | 64 ---
 .../dc/link/protocols/link_dp_training_dpia.h | 19 +
 drivers/gpu/drm/amd/display/dmub/dmub_srv.h   |  1 +
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   | 25 +-
 .../gpu/drm/amd/display/dmub/src/dmub_dcn35.c |  1 +
 11 files changed, 233 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 243928b0a39f..eb7c7681bdd9 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -5755,6 +5755,27 @@ enum dc_status dc_process_dmub_set_mst_slots(const 
struct dc *dc,
return DC_OK;
 }
 
+/**
+ * dc_process_dmub_dpia_set_tps_notification - Submits tps notification
+ *
+ * @dc: [in] dc structure
+ * @link_index: [in] link index
+ * @ts: [in] request tps
+ *
+ * Submits set_tps_notification command to dmub via inbox message
+ */
+void dc_process_dmub_dpia_set_tps_notification(const struct dc *dc, uint32_t 
link_index, uint8_t tps)
+{
+   union dmub_rb_cmd cmd = {0};
+
+   cmd.set_tps_notification.header.type = DMUB_CMD__DPIA;
+   cmd.set_tps_notification.header.sub_type = 
DMUB_CMD__DPIA_SET_TPS_NOTIFICATION;
+   cmd.set_tps_notification.tps_notification.instance = 
dc->links[link_index]->ddc_hw_inst;
+   cmd.set_tps_notification.tps_notification.tps = tps;
+
+   dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+}
+
 /**
  * dc_process_dmub_dpia_hpd_int_enable - Submits DPIA DPD interruption
  *
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 7c4812dd1a71..133cac4d9fc4 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -462,6 +462,7 @@ struct dc_config {
bool support_edp0_on_dp1;
unsigned int enable_fpo_flicker_detection;
bool disable_hbr_audio_dp2;
+   bool consolidated_dpia_dp_lt;
 };
 
 enum visual_confirm {
@@ -762,7 +763,8 @@ union dpia_debug_options {
uint32_t disable_mst_dsc_work_around:1; /* bit 3 */
uint32_t enable_force_tbt3_work_around:1; /* bit 4 */
uint32_t disable_usb4_pm_support:1; /* bit 5 */
-   uint32_t reserved:26;
+   uint32_t enable_consolidated_dpia_dp_lt:1; /* bit 6 */
+   uint32_t reserved:25;
} bits;
uint32_t raw;
 };
@@ -2525,6 +2527,8 @@ enum dc_status dc_process_dmub_set_mst_slots(const struct 
dc *dc,
uint8_t mst_alloc_slots,
uint8_t *mst_slots_in_use);
 
+void dc_process_dmub_dpia_set_tps_notification(const struct dc *dc, uint32_t 
link_index, uint8_t tps);
+
 void dc_process_dmub_dpia_hpd_int_enable(const struct dc *dc,
uint32_t hpd_int_enable);
 
diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dpia.c 
b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dpia.c
index 46fb3649bc86..6499807af72a 100644
--- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dpia.c
@@ -50,8 +50,31 @@ static void update_dpia_stream_allocation_table(struct 
dc_link *link,
DC_LOG_MST("dpia : status[%d]: alloc_slots[%d]: used_slots[%d]\n",
status, mst_alloc_slots, prev_mst_slots_in_use);
 
-   ASSERT(link_enc);
-   link_enc->funcs->update_mst_stream_allocation_table(link_enc, table);
+   if (link_enc)
+   link_enc->funcs->update_mst_stream_allocation_table(link_enc, 
table);
+}
+
+static void set_dio_dpia_link_test_pattern(struct dc_link *link,
+   const struct link_resource *link_res,
+   struct encoder_set_dp_phy_pattern_param *tp_params)
+{
+   if (tp_params->dp_phy_pattern != DP_TEST_PATTERN_VIDEO_MODE)
+   return;
+

[PATCH 11/23] drm/amd/display: Disable SYMCLK32_LE root clock gating

2024-09-11 Thread Alex Hung
From: Sung Joon Kim 

[WHY & HOW]
On display on sequence, enabling SYMCLK32_LE root clock gating
causes issue in link training so disabling it is needed.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Nicholas Kazlauskas 
Signed-off-by: Sung Joon Kim 
Signed-off-by: Alex Hung 
---
 .../gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c| 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
index 514c6d56925d..da9101b83e8c 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
@@ -736,7 +736,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.hdmichar = true,
.dpstream = true,
.symclk32_se = true,
-   .symclk32_le = true,
+   .symclk32_le = false,
.symclk_fe = true,
.physymclk = false,
.dpiasymclk = true,
-- 
2.34.1



[PATCH 10/23] drm/amd/display: Clean up dsc blocks in accelerated mode

2024-09-11 Thread Alex Hung
From: Martin Tsai 

[WHY]
DSC on eDP could be enabled during VBIOS post. The enabled
DSC may not be disabled when enter to OS, once the system was
in second screen only mode before entering to S4. In this
case, OS will not send setTimings to reset eDP path again.

The enabled DSC HW will make a new stream without DSC cannot
output normally if it reused this pipe with enabled DSC.

[HOW]
In accelerated mode, to clean up DSC blocks if eDP is on link
but not active when we are not in fast boot and seamless boot.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Charlene Liu 
Signed-off-by: Martin Tsai 
Signed-off-by: Alex Hung 
---
 .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 50 +++
 1 file changed, 50 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index d52ce58c6a98..aa7479b31898 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -57,6 +57,7 @@
 #include "panel_cntl.h"
 #include "dc_state_priv.h"
 #include "dpcd_defs.h"
+#include "dsc.h"
 /* include DCE11 register header files */
 #include "dce/dce_11_0_d.h"
 #include "dce/dce_11_0_sh_mask.h"
@@ -1823,6 +1824,48 @@ static void get_edp_links_with_sink(
}
 }
 
+static void clean_up_dsc_blocks(struct dc *dc)
+{
+   struct display_stream_compressor *dsc = NULL;
+   struct timing_generator *tg = NULL;
+   struct stream_encoder *se = NULL;
+   struct dccg *dccg = dc->res_pool->dccg;
+   struct pg_cntl *pg_cntl = dc->res_pool->pg_cntl;
+   int i;
+
+   if (dc->ctx->dce_version != DCN_VERSION_3_5 &&
+   dc->ctx->dce_version != DCN_VERSION_3_51)
+   return;
+
+   for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) {
+   struct dcn_dsc_state s  = {0};
+
+   dsc = dc->res_pool->dscs[i];
+   dsc->funcs->dsc_read_state(dsc, &s);
+   if (s.dsc_fw_en) {
+   /* disable DSC in OPTC */
+   if (i < dc->res_pool->timing_generator_count) {
+   tg = dc->res_pool->timing_generators[i];
+   tg->funcs->set_dsc_config(tg, 
OPTC_DSC_DISABLED, 0, 0);
+   }
+   /* disable DSC in stream encoder */
+   if (i < dc->res_pool->stream_enc_count) {
+   se = dc->res_pool->stream_enc[i];
+   se->funcs->dp_set_dsc_config(se, 
OPTC_DSC_DISABLED, 0, 0);
+   se->funcs->dp_set_dsc_pps_info_packet(se, 
false, NULL, true);
+   }
+   /* disable DSC block */
+   if (dccg->funcs->set_ref_dscclk)
+   dccg->funcs->set_ref_dscclk(dccg, dsc->inst);
+   dsc->funcs->dsc_disable(dsc);
+
+   /* power down DSC */
+   if (pg_cntl != NULL)
+   pg_cntl->funcs->dsc_pg_control(pg_cntl, 
dsc->inst, false);
+   }
+   }
+}
+
 /*
  * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need:
  *  1. Power down all DC HW blocks
@@ -1927,6 +1970,13 @@ void dce110_enable_accelerated_mode(struct dc *dc, 
struct dc_state *context)
clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
 
power_down_all_hw_blocks(dc);
+
+   /* DSC could be enabled on eDP during VBIOS post.
+* To clean up dsc blocks if eDP is in link but not active.
+*/
+   if (edp_link_with_sink && (edp_stream_num == 0))
+   clean_up_dsc_blocks(dc);
+
disable_vga_and_power_gate_all_controllers(dc);
if (edp_link_with_sink && !keep_edp_vdd_on)
dc->hwss.edp_power_control(edp_link_with_sink, false);
-- 
2.34.1



[PATCH 09/23] drm/amd/display: Block dynamic IPS2 on DCN35 for incompatible FW versions

2024-09-11 Thread Alex Hung
From: Nicholas Kazlauskas 

[WHY]
Hangs with Z8 can occur if running an older unfixed PMFW version.

[HOW]
Fallback to RCG only for dynamic IPS2 states if it's not newer than
93.12. Limit to DCN35.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Charlene Liu 
Signed-off-by: Nicholas Kazlauskas 
Signed-off-by: Alex Hung 
---
 .../gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c| 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
index 97164b5585a8..b46a3afe48ca 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
@@ -1222,6 +1222,12 @@ void dcn35_clk_mgr_construct(
ctx->dc->debug.disable_dpp_power_gate = false;
ctx->dc->debug.disable_hubp_power_gate = false;
ctx->dc->debug.disable_dsc_power_gate = false;
+
+   /* Disable dynamic IPS2 in older PMFW (93.12) for Z8 
interop. */
+   if (ctx->dc->config.disable_ips == DMUB_IPS_ENABLE &&
+   ctx->dce_version == DCN_VERSION_3_5 &&
+   ((clk_mgr->base.smu_ver & 0x00FF) <= 
0x005d0c00))
+   ctx->dc->config.disable_ips = 
DMUB_IPS_RCG_IN_ACTIVE_IPS2_IN_OFF;
} else {
/*let's reset the config control flag*/
ctx->dc->config.disable_ips = DMUB_IPS_DISABLE_ALL; 
/*pmfw not support it, disable it all*/
-- 
2.34.1



[PATCH 08/23] drm/amd/display: Add debug options to change sharpen policies

2024-09-11 Thread Alex Hung
From: Samson Tam 

[WHY]
Add options to change sharpen policy based on surface format
and scaling ratios.

[HOW]
Add sharpen_policy to change policy based on surface format
and scale_to_sharpness_policy based on scaling ratios.

Reviewed-by: Jun Lei 
Signed-off-by: Samson Tam 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/dc.h   |  2 +
 .../gpu/drm/amd/display/dc/dc_spl_translate.c |  5 ++
 drivers/gpu/drm/amd/display/dc/spl/dc_spl.c   | 34 ++--
 .../display/dc/spl/dc_spl_isharp_filters.c| 85 +--
 .../display/dc/spl/dc_spl_isharp_filters.h|  9 +-
 .../gpu/drm/amd/display/dc/spl/dc_spl_types.h | 12 +++
 6 files changed, 128 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index dcf8a90e961d..7c4812dd1a71 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1056,6 +1056,8 @@ struct dc_debug_options {
unsigned int force_lls;
bool notify_dpia_hr_bw;
bool enable_ips_visual_confirm;
+   unsigned int sharpen_policy;
+   unsigned int scale_to_sharpness_policy;
 };
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c 
b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
index f711fc2e3e65..603552dbd771 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
@@ -186,6 +186,11 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx 
*pipe_ctx, struct spl
 
spl_in->h_active = pipe_ctx->plane_res.scl_data.h_active;
spl_in->v_active = pipe_ctx->plane_res.scl_data.v_active;
+
+   spl_in->debug.sharpen_policy = (enum 
sharpen_policy)pipe_ctx->stream->ctx->dc->debug.sharpen_policy;
+   spl_in->debug.scale_to_sharpness_policy =
+   (enum 
scale_to_sharpness_policy)pipe_ctx->stream->ctx->dc->debug.scale_to_sharpness_policy;
+
/* Check if it is stream is in fullscreen and if its HDR.
 * Use this to determine sharpness levels
 */
diff --git a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c 
b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
index a59aa6b59687..f7a654b3a092 100644
--- a/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
+++ b/drivers/gpu/drm/amd/display/dc/spl/dc_spl.c
@@ -813,6 +813,14 @@ static bool enable_easf(struct spl_in *spl_in, struct 
spl_scratch *spl_scratch)
return skip_easf;
 }
 
+/* Check if video is in fullscreen mode */
+static bool spl_is_video_fullscreen(struct spl_in *spl_in)
+{
+   if (spl_is_yuv420(spl_in->basic_in.format) && spl_in->is_fullscreen)
+   return true;
+   return false;
+}
+
 static bool spl_get_isharp_en(struct spl_in *spl_in,
struct spl_scratch *spl_scratch)
 {
@@ -820,6 +828,7 @@ static bool spl_get_isharp_en(struct spl_in *spl_in,
int vratio = 0;
int hratio = 0;
struct spl_taps taps = spl_scratch->scl_data.taps;
+   bool fullscreen = spl_is_video_fullscreen(spl_in);
 
/* Return if adaptive sharpness is disabled */
if (spl_in->adaptive_sharpness.enable == false)
@@ -835,9 +844,15 @@ static bool spl_get_isharp_en(struct spl_in *spl_in,
// Scaling is up to 1:1 (no scaling) or upscaling
 
/*
-* Apply sharpness to all RGB surfaces and to
-*  NV12/P010 surfaces
+* Apply sharpness to RGB and YUV (NV12/P010)
+*  surfaces based on policy setting
 */
+   if (!spl_is_yuv420(spl_in->basic_in.format) &&
+   (spl_in->debug.sharpen_policy == SHARPEN_YUV))
+   return enable_isharp;
+   else if ((spl_is_yuv420(spl_in->basic_in.format) && !fullscreen) &&
+   (spl_in->debug.sharpen_policy == SHARPEN_RGB_FULLSCREEN_YUV))
+   return enable_isharp;
 
/*
 * Apply sharpness if supports horizontal taps 4,6 AND
@@ -1562,7 +1577,7 @@ static void spl_set_isharp_data(struct dscl_prog_data 
*dscl_prog_data,
struct adaptive_sharpness adp_sharpness, bool enable_isharp,
enum linear_light_scaling lls_pref, enum spl_pixel_format 
format,
const struct spl_scaler_data *data, struct spl_fixed31_32 ratio,
-   enum system_setup setup)
+   enum system_setup setup, enum scale_to_sharpness_policy 
scale_to_sharpness_policy)
 {
/* Turn off sharpener if not required */
if (!enable_isharp) {
@@ -1570,6 +1585,11 @@ static void spl_set_isharp_data(struct dscl_prog_data 
*dscl_prog_data,
return;
}
 
+   spl_build_isharp_1dlut_from_reference_curve(ratio, setup, adp_sharpness,
+   scale_to_sharpness_policy);
+   dscl_prog_data->isharp_delta = 
spl_get_pregen_filter_isharp_1D_lut(setup);
+   dscl_prog_data->sharpness_level = adp_sharpness.sharpness_level;
+
 

[PATCH 07/23] drm/amd/display: Block timing sync for different output formats in pmo

2024-09-11 Thread Alex Hung
From: Dillon Varone 

[WHY & HOW]
If the output format is different for HDMI TMDS signals, they are not
synchronizable.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Alvin Lee 
Signed-off-by: Dillon Varone 
Signed-off-by: Alex Hung 
---
 .../dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c  | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
index d63558ee3135..1cf9015e854a 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c
@@ -940,9 +940,11 @@ static void build_synchronized_timing_groups(
/* find synchronizable timing groups */
for (j = i + 1; j < display_config->display_config.num_streams; 
j++) {
if (memcmp(master_timing,
-   
&display_config->display_config.stream_descriptors[j].timing,
-   sizeof(struct dml2_timing_cfg)) == 0 &&
-   
display_config->display_config.stream_descriptors[i].output.output_encoder == 
display_config->display_config.stream_descriptors[j].output.output_encoder) {
+   
&display_config->display_config.stream_descriptors[j].timing,
+   sizeof(struct dml2_timing_cfg)) == 0 &&
+   
display_config->display_config.stream_descriptors[i].output.output_encoder == 
display_config->display_config.stream_descriptors[j].output.output_encoder &&
+   
(display_config->display_config.stream_descriptors[i].output.output_encoder != 
dml2_hdmi || //hdmi requires formats match
+   
display_config->display_config.stream_descriptors[i].output.output_format == 
display_config->display_config.stream_descriptors[j].output.output_format)) {

set_bit_in_bitfield(&pmo->scratch.pmo_dcn4.synchronized_timing_group_masks[timing_group_idx],
 j);
set_bit_in_bitfield(&stream_mapped_mask, j);
}
-- 
2.34.1



[PATCH 06/23] drm/amd/display: Enable DML2 override_det_buffer_size_kbytes

2024-09-11 Thread Alex Hung
From: Yihan Zhu 

[WHY]
Corrupted screen will be observed when 4k144 DP/HDMI display and
4k144 eDP are connected, changing eDP refresh rate from 60Hz to 144Hz.

[HOW]
override_det_buffer_size_kbytes should be true for DCN35/DCN351.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Roman Li 
Reviewed-by: Nicholas Kazlauskas 
Signed-off-by: Yihan Zhu 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c   | 1 +
 drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
index 46ad684fe192..893a9d9ee870 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
@@ -2155,6 +2155,7 @@ static bool dcn35_resource_construct(
 
dc->dml2_options.max_segments_per_hubp = 24;
dc->dml2_options.det_segment_size = DCN3_2_DET_SEG_SIZE;/*todo*/
+   dc->dml2_options.override_det_buffer_size_kbytes = true;
 
if (dc->config.sdpif_request_limit_words_per_umc == 0)
dc->config.sdpif_request_limit_words_per_umc = 16;/*todo*/
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
index 4c5e722baa3a..514c6d56925d 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
@@ -2133,6 +2133,7 @@ static bool dcn351_resource_construct(
 
dc->dml2_options.max_segments_per_hubp = 24;
dc->dml2_options.det_segment_size = DCN3_2_DET_SEG_SIZE;/*todo*/
+   dc->dml2_options.override_det_buffer_size_kbytes = true;
 
if (dc->config.sdpif_request_limit_words_per_umc == 0)
dc->config.sdpif_request_limit_words_per_umc = 16;/*todo*/
-- 
2.34.1



[PATCH 05/23] drm/amd/display: Add dmub hpd sense callback

2024-09-11 Thread Alex Hung
From: Roman Li 

[WHY]
HPD sense notification has been implemented in DMUB, which
can occur during low power states and need to be
notified from firmware to driver.

[HOW]
Define callback and register new HPD sense notification.

Reviewed-by: Nicholas Kazlauskas 
Signed-off-by: Roman Li 
Signed-off-by: Alex Hung 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +-
 2 files changed, 21 insertions(+), 1 deletion(-)

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 a3edaf658ae0..c77982245f60 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -807,6 +807,20 @@ static void dmub_hpd_callback(struct amdgpu_device *adev,
}
 }
 
+/**
+ * dmub_hpd_sense_callback - DMUB HPD sense processing callback.
+ * @adev: amdgpu_device pointer
+ * @notify: dmub notification structure
+ *
+ * HPD sense changes can occur during low power states and need to be
+ * notified from firmware to driver.
+ */
+static void dmub_hpd_sense_callback(struct amdgpu_device *adev,
+ struct dmub_notification *notify)
+{
+   DRM_DEBUG_DRIVER("DMUB HPD SENSE callback.\n");
+}
+
 /**
  * register_dmub_notify_callback - Sets callback for DMUB notify
  * @adev: amdgpu_device pointer
@@ -3808,6 +3822,12 @@ static int register_hpd_handlers(struct amdgpu_device 
*adev)
DRM_ERROR("amdgpu: fail to register dmub hpd callback");
return -EINVAL;
}
+
+   if (!register_dmub_notify_callback(adev, 
DMUB_NOTIFICATION_HPD_SENSE_NOTIFY,
+   dmub_hpd_sense_callback, true)) {
+   DRM_ERROR("amdgpu: fail to register dmub hpd sense 
callback");
+   return -EINVAL;
+   }
}
 
list_for_each_entry(connector,
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 2d7755e2b6c3..15d4690c74d6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -50,7 +50,7 @@
 
 #define AMDGPU_DM_MAX_NUM_EDP 2
 
-#define AMDGPU_DMUB_NOTIFICATION_MAX 6
+#define AMDGPU_DMUB_NOTIFICATION_MAX 7
 
 #define HDMI_AMD_VENDOR_SPECIFIC_DATA_BLOCK_IEEE_REGISTRATION_ID 0x1A
 #define AMD_VSDB_VERSION_3_FEATURECAP_REPLAYMODE 0x40
-- 
2.34.1



[PATCH 04/23] drm/amd/display: Emulate Display Hotplug Hang

2024-09-11 Thread Alex Hung
From: Daniel Sa 

[WHY]
Driver reports 0 display when the virtual display is still present, and
causes P-state hang in FW.

[HOW]
When enumerating through streams, check for active planes and use that
to indicate number of displays.

Reviewed-by: Dillon Varone 
Signed-off-by: Daniel Sa 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
index f770828df149..0e243f4344d0 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
@@ -59,6 +59,7 @@ int clk_mgr_helper_get_active_display_cnt(
display_count = 0;
for (i = 0; i < context->stream_count; i++) {
const struct dc_stream_state *stream = context->streams[i];
+   const struct dc_stream_status *stream_status = 
&context->stream_status[i];
 
/* Don't count SubVP phantom pipes as part of active
 * display count
@@ -66,13 +67,7 @@ int clk_mgr_helper_get_active_display_cnt(
if (dc_state_get_stream_subvp_type(context, stream) == 
SUBVP_PHANTOM)
continue;
 
-   /*
-* Only notify active stream or virtual stream.
-* Need to notify virtual stream to work around
-* headless case. HPD does not fire when system is in
-* S0i2.
-*/
-   if (!stream->dpms_off || stream->signal == SIGNAL_TYPE_VIRTUAL)
+   if (!stream->dpms_off || (stream_status && 
stream_status->plane_count))
display_count++;
}
 
-- 
2.34.1



[PATCH 03/23] drm/amd/display: Implement new DPCD register handling

2024-09-11 Thread Alex Hung
From: Ryan Seto 

[WHY]
There are some monitor timings that seem to be supported without
DSC but actually require DSC to be displayed. A VESA SCR introduced
a new max uncompressed pixel rate cap register that we can use to
handle these edge cases.

[HOW]
SST: Read caps from link and invalidate timings that exceed the
max limit but do not support DSC. Then check for options override
when determining BPP.

MST: Read caps from virtual DPCD peer device or daisy chained SST
monitor and set validation set BPPs to max if pixel rate exceeds
uncompressed limit. Validation set optimization continues as normal.

Reviewed-by: Wenjing Liu 
Signed-off-by: Ryan Seto 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 12 
 drivers/gpu/drm/amd/display/dc/dc_dsc.h  |  1 +
 drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c  | 10 +-
 .../gpu/drm/amd/display/dc/link/link_validation.c|  7 +++
 .../display/dc/link/protocols/link_dp_capability.c   |  5 +
 5 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
index 519c3df78ee5..41bd95e9177a 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
@@ -969,6 +969,14 @@ union dp_sink_video_fallback_formats {
uint8_t raw;
 };
 
+union dpcd_max_uncompressed_pixel_rate_cap {
+   struct {
+   uint16_t max_uncompressed_pixel_rate_cap:15;
+   uint16_t valid  :1;
+   } bits;
+   uint8_t raw[2];
+};
+
 union dp_fec_capability1 {
struct {
uint8_t AGGREGATED_ERROR_COUNTERS_CAPABLE   :1;
@@ -1170,6 +1178,7 @@ struct dpcd_caps {
struct dc_lttpr_caps lttpr_caps;
struct adaptive_sync_caps adaptive_sync_caps;
struct dpcd_usb4_dp_tunneling_info usb4_dp_tun_info;
+   union dpcd_max_uncompressed_pixel_rate_cap 
max_uncompressed_pixel_rate_cap;
 
union dp_128b_132b_supported_link_rates 
dp_128b_132b_supported_link_rates;
union dp_main_line_channel_coding_cap channel_coding_cap;
@@ -1340,6 +1349,9 @@ struct dp_trace {
 #ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX
 #define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX0x110
 #endif
+#ifndef DPCD_MAX_UNCOMPRESSED_PIXEL_RATE_CAP
+#define DPCD_MAX_UNCOMPRESSED_PIXEL_RATE_CAP0x221c
+#endif
 #ifndef DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE
 #define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE  0x50
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dsc.h 
b/drivers/gpu/drm/amd/display/dc/dc_dsc.h
index fe3078b8789e..2a5120ecf48b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dsc.h
@@ -59,6 +59,7 @@ struct dc_dsc_config_options {
uint32_t max_target_bpp_limit_override_x16;
uint32_t slice_height_granularity;
uint32_t dsc_force_odm_hslice_override;
+   bool force_dsc_when_not_needed;
 };
 
 bool dc_dsc_parse_dsc_dpcd(const struct dc *dc,
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 a1727e5bf024..79c426425911 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
@@ -668,6 +668,7 @@ static bool decide_dsc_bandwidth_range(
  */
 static bool decide_dsc_target_bpp_x16(
const struct dc_dsc_policy *policy,
+   const struct dc_dsc_config_options *options,
const struct dsc_enc_caps *dsc_common_caps,
const int target_bandwidth_kbps,
const struct dc_crtc_timing *timing,
@@ -682,7 +683,7 @@ static bool decide_dsc_target_bpp_x16(
if (decide_dsc_bandwidth_range(policy->min_target_bpp * 16, 
policy->max_target_bpp * 16,
num_slices_h, dsc_common_caps, timing, link_encoding, 
&range)) {
if (target_bandwidth_kbps >= range.stream_kbps) {
-   if (policy->enable_dsc_when_not_needed)
+   if (policy->enable_dsc_when_not_needed || 
options->force_dsc_when_not_needed)
/* enable max bpp even dsc is not needed */
*target_bpp_x16 = range.max_target_bpp_x16;
} else if (target_bandwidth_kbps >= range.max_kbps) {
@@ -1080,6 +1081,7 @@ static bool setup_dsc_config(
if (target_bandwidth_kbps > 0) {
is_dsc_possible = decide_dsc_target_bpp_x16(
&policy,
+   options,
&dsc_common_caps,
target_bandwidth_kbps,
timing,
@@ -1235,10 +1237,7 @@ void dc_dsc_get_policy_for_timing(const struct 
dc_crtc_timing *timing,
policy->max_target_bpp = max_target_bpp_limit_ove

[PATCH 02/23] drm/amd/display: Use SDR white level to calculate matrix coefficients

2024-09-11 Thread Alex Hung
From: Samson Tam 

[WHY]
Certain profiles have higher HDR multiplier than SDR white level max
which is not currently supported.

[HOW]
Use SDR white level when calculating matrix coefficients for HDR RGB MPO
path instead of HDR multiplier.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Jun Lei 
Signed-off-by: Samson Tam 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c| 12 
 drivers/gpu/drm/amd/display/dc/dc.h |  3 +++
 .../gpu/drm/amd/display/dc/dc_spl_translate.c   |  9 +
 drivers/gpu/drm/amd/display/dc/spl/dc_spl.c | 17 +++--
 .../gpu/drm/amd/display/dc/spl/dc_spl_types.h   |  2 +-
 5 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index ae788154896c..243928b0a39f 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2596,6 +2596,12 @@ static enum surface_update_type det_surface_update(const 
struct dc *dc,
elevate_update_type(&overall_type, UPDATE_TYPE_MED);
}
 
+   if (u->sdr_white_level_nits)
+   if (u->sdr_white_level_nits != 
u->surface->sdr_white_level_nits) {
+   update_flags->bits.sdr_white_level_nits = 1;
+   elevate_update_type(&overall_type, UPDATE_TYPE_FULL);
+   }
+
if (u->cm2_params) {
if ((u->cm2_params->component_settings.shaper_3dlut_setting
!= u->surface->mcm_shaper_3dlut_setting)
@@ -2876,6 +2882,10 @@ static void copy_surface_update_to_plane(
surface->hdr_mult =
srf_update->hdr_mult;
 
+   if (srf_update->sdr_white_level_nits)
+   surface->sdr_white_level_nits =
+   srf_update->sdr_white_level_nits;
+
if (srf_update->blend_tf)
memcpy(&surface->blend_tf, srf_update->blend_tf,
sizeof(surface->blend_tf));
@@ -4679,6 +4689,8 @@ static bool full_update_required(struct dc *dc,
srf_updates[i].scaling_info ||
(srf_updates[i].hdr_mult.value &&
srf_updates[i].hdr_mult.value != 
srf_updates->surface->hdr_mult.value) ||
+   (srf_updates[i].sdr_white_level_nits &&
+   srf_updates[i].sdr_white_level_nits != 
srf_updates->surface->sdr_white_level_nits) ||
srf_updates[i].in_transfer_func ||
srf_updates[i].func_shaper ||
srf_updates[i].lut3d_func ||
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 4c94dd38be4b..dcf8a90e961d 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1269,6 +1269,7 @@ union surface_update_flags {
uint32_t tmz_changed:1;
uint32_t mcm_transfer_function_enable_change:1; /* disable or 
enable MCM transfer func */
uint32_t full_update:1;
+   uint32_t sdr_white_level_nits:1;
} bits;
 
uint32_t raw;
@@ -1351,6 +1352,7 @@ struct dc_plane_state {
bool adaptive_sharpness_en;
int sharpness_level;
enum linear_light_scaling linear_light_scaling;
+   unsigned int sdr_white_level_nits;
 };
 
 struct dc_plane_info {
@@ -1508,6 +1510,7 @@ struct dc_surface_update {
 */
struct dc_cm2_parameters *cm2_params;
const struct dc_csc_transform *cursor_csc_color_matrix;
+   unsigned int sdr_white_level_nits;
 };
 
 /*
diff --git a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c 
b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
index cd6de93eb91c..f711fc2e3e65 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c
@@ -191,14 +191,7 @@ void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx 
*pipe_ctx, struct spl
 */
spl_in->is_fullscreen = dm_helpers_is_fullscreen(pipe_ctx->stream->ctx, 
pipe_ctx->stream);
spl_in->is_hdr_on = dm_helpers_is_hdr_on(pipe_ctx->stream->ctx, 
pipe_ctx->stream);
-   spl_in->hdr_multx100 = 0;
-   if (spl_in->is_hdr_on) {
-   spl_in->hdr_multx100 = 
(uint32_t)dc_fixpt_floor(dc_fixpt_mul(plane_state->hdr_mult,
-   dc_fixpt_from_int(100)));
-   /* Disable sharpness for HDR Mult > 6.0 */
-   if (spl_in->hdr_multx100 > 600)
-   spl_in->adaptive_sharpness.enable = false;
-   }
+   spl_in->sdr_white_level_nits = plane_state->sdr_whi

[PATCH 01/23] drm/amd/display: Round calculated vtotal

2024-09-11 Thread Alex Hung
From: Robin Chen 

[WHY]
The calculated vtotal may has 1 line deviation. To get precisely
vtotal number, round the vtotal result.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Anthony Koo 
Signed-off-by: Robin Chen 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 
b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index a40e6590215a..bbd259cea4f4 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -134,7 +134,7 @@ unsigned int mod_freesync_calc_v_total_from_refresh(
 
v_total = div64_u64(div64_u64(((unsigned long long)(
frame_duration_in_ns) * (stream->timing.pix_clk_100hz / 
10)),
-   stream->timing.h_total), 100);
+   stream->timing.h_total) + 50, 100);
 
/* v_total cannot be less than nominal */
if (v_total < stream->timing.v_total) {
-- 
2.34.1



[PATCH 00/23] DC Patches Sept 11, 2024

2024-09-11 Thread Alex Hung
This DC patchset brings improvements in multiple areas. In summary, we 
highlight:

- Fixes on DCN35, DCN401 and IPS
- Enhancements in DMUB and DSC
- Misc fixes for Coverity errors

Cc: Daniel Wheeler 

Alex Hung (2):
  drm/amd/display: Check null pointer before dereferencing se
  drm/amd/display: Remove always-false branches

Aric Cyr (2):
  drm/amd/display: 3.2.300
  drm/amd/display: 3.2.301

Aurabindo Pillai (1):
  drm/amd/display: Fix underflow when setting underscan on DCN401

Charlene Liu (2):
  drm/amd/display: Use full update for swizzle mode change
  drm/amd/display: Clear cached watermark after resume

Daniel Sa (1):
  drm/amd/display: Emulate Display Hotplug Hang

Dillon Varone (1):
  drm/amd/display: Block timing sync for different output formats in pmo

Leo Ma (1):
  drm/amd/display: Add HDMI DSC native YCbCr422 support

Martin Tsai (1):
  drm/amd/display: Clean up dsc blocks in accelerated mode

Nicholas Kazlauskas (1):
  drm/amd/display: Block dynamic IPS2 on DCN35 for incompatible FW
versions

Peichen Huang (1):
  drm/amd/display: Restructure dpia link training

Relja Vojvodic (1):
  drm/amd/display: Add fullscreen only sharpening policy

Robin Chen (1):
  drm/amd/display: Round calculated vtotal

Roman Li (2):
  drm/amd/display: Add dmub hpd sense callback
  drm/amd/display: Update IPS default mode for DCN35/DCN351

Ryan Seto (1):
  drm/amd/display: Implement new DPCD register handling

Samson Tam (2):
  drm/amd/display: Use SDR white level to calculate matrix coefficients
  drm/amd/display: Add debug options to change sharpen policies

Sung Joon Kim (1):
  drm/amd/display: Disable SYMCLK32_LE root clock gating

Yihan Zhu (1):
  drm/amd/display: Enable DML2 override_det_buffer_size_kbytes

Zhikai Zhai (1):
  drm/amd/display: Skip to enable dsc if it has been off

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 70 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  4 +-
 .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c  |  9 +-
 .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c  |  6 ++
 drivers/gpu/drm/amd/display/dc/core/dc.c  | 41 -
 drivers/gpu/drm/amd/display/dc/dc.h   | 14 ++-
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h  | 12 +++
 drivers/gpu/drm/amd/display/dc/dc_dsc.h   |  4 +-
 .../gpu/drm/amd/display/dc/dc_spl_translate.c | 14 ++-
 .../dc/dml/dcn20/display_rq_dlg_calc_20.c |  3 -
 .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c   |  3 -
 .../dc/dml/dcn31/display_mode_vba_31.c|  9 --
 .../dc/dml2/dml21/dml21_translation_helper.c  |  4 +-
 .../dml21/src/dml2_pmo/dml2_pmo_dcn4_fams2.c  |  8 +-
 drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c   | 15 ++--
 .../display/dc/hubbub/dcn35/dcn35_hubbub.c|  1 +
 .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 50 +++
 .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c   | 14 +++
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c   | 13 +++
 .../amd/display/dc/link/hwss/link_hwss_dpia.c | 31 ++-
 .../drm/amd/display/dc/link/link_validation.c |  7 ++
 .../dc/link/protocols/link_dp_capability.c|  5 ++
 .../dc/link/protocols/link_dp_training.c  | 80 +++--
 .../dc/link/protocols/link_dp_training.h  | 16 +++-
 .../link/protocols/link_dp_training_8b_10b.c  | 21 +++--
 .../dc/link/protocols/link_dp_training_dpia.c | 64 --
 .../dc/link/protocols/link_dp_training_dpia.h | 19 +
 .../dc/resource/dcn35/dcn35_resource.c|  1 +
 .../dc/resource/dcn351/dcn351_resource.c  |  3 +-
 drivers/gpu/drm/amd/display/dc/spl/dc_spl.c   | 54 
 .../display/dc/spl/dc_spl_isharp_filters.c| 85 +--
 .../display/dc/spl/dc_spl_isharp_filters.h|  9 +-
 .../gpu/drm/amd/display/dc/spl/dc_spl_types.h | 15 +++-
 drivers/gpu/drm/amd/display/dmub/dmub_srv.h   |  1 +
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   | 25 +-
 .../gpu/drm/amd/display/dmub/src/dmub_dcn35.c |  1 +
 .../amd/display/modules/freesync/freesync.c   |  2 +-
 38 files changed, 588 insertions(+), 147 deletions(-)

-- 
2.34.1



Re: [PATCH v4 09/11] drm/amd/display: get SAD from drm_eld when parsing EDID caps

2024-07-29 Thread Alex Hung




On 2024-07-28 20:02, Melissa Wen wrote:

On 07/25, Alex Hung wrote:



On 2024-07-05 21:35, Melissa Wen wrote:

instead of parsing struct edid.


A more informative commit message will be helpful.


sure. I'll improve it in the next version.


A soft reminder - a few other patches need improved commit messages too.





Signed-off-by: Melissa Wen 
---
   .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c   | 17 +
   1 file changed, 9 insertions(+), 8 deletions(-)

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 7657b1051c54..45c04de08c65 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
@@ -97,7 +97,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
const struct drm_edid *drm_edid = aconnector->drm_edid;
struct drm_edid_product_id product_id;
struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL;
-   struct cea_sad *sads;
int sad_count, sadb_count;
int i = 0;
uint8_t *sadb = NULL;
@@ -127,18 +126,21 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
apply_edid_quirks(&product_id, edid_caps);
-   sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads);
+   sad_count = drm_eld_sad_count(connector->eld);
if (sad_count <= 0)
return result;
edid_caps->audio_mode_count = min(sad_count, DC_MAX_AUDIO_DESC_COUNT);
for (i = 0; i < edid_caps->audio_mode_count; ++i) {
-   struct cea_sad *sad = &sads[i];
+   struct cea_sad sad;
-   edid_caps->audio_modes[i].format_code = sad->format;
-   edid_caps->audio_modes[i].channel_count = sad->channels + 1;
-   edid_caps->audio_modes[i].sample_rate = sad->freq;
-   edid_caps->audio_modes[i].sample_size = sad->byte2;
+   if (drm_eld_sad_get(connector->eld, i, &sad) < 0)
+   continue;
+
+   edid_caps->audio_modes[i].format_code = sad.format;
+   edid_caps->audio_modes[i].channel_count = sad.channels + 1;
+   edid_caps->audio_modes[i].sample_rate = sad.freq;
+   edid_caps->audio_modes[i].sample_size = sad.byte2;
}
sadb_count = drm_edid_to_speaker_allocation((struct edid *) edid->raw_edid, 
&sadb);
@@ -153,7 +155,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
else
edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION;
-   kfree(sads);
kfree(sadb);
return result;


Re: [PATCH v4 01/11] drm/amd/display: clean unused variables for hdmi freesync parser

2024-07-29 Thread Alex Hung




On 2024-07-28 19:32, Melissa Wen wrote:

On 07/25, Alex Hung wrote:

Hi Melissa,

There are no commit messages in this patch.

Also, do you think this can be merged with Patch 5 "drm/amd/display: remove
redundant freesync parser for  DP"?


Hi Alex,

Thanks for your feedback.
I'll add a brief description in the next version.
Regarding merging it into patch 5, I'd prefer to keep it detached
because here we have a non-functional change. I can send it as a
separate, single patch from this series to reduce noise and make
validation faster. WDYT?


Make thanks. Thanks for clarification.



Melissa



On 2024-07-05 21:35, Melissa Wen wrote:

Signed-off-by: Melissa Wen 
---
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ---
   1 file changed, 3 deletions(-)

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 98cf523a629e..1dfa7ec9af35 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -12108,9 +12108,6 @@ void amdgpu_dm_update_freesync_caps(struct 
drm_connector *connector,
} else if (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) {
-   timing  = &edid->detailed_timings[i];
-   data= &timing->data.other_data;
-
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)


Re: [PATCH v4 10/11] drm/amd/display: get SADB from drm_eld when parsing EDID caps

2024-07-25 Thread Alex Hung




On 2024-07-05 21:35, Melissa Wen wrote:

instead of parsing struct edid.


A more informative commit message will be helpful.



Signed-off-by: Melissa Wen 
---
  .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 15 +++
  1 file changed, 3 insertions(+), 12 deletions(-)

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 45c04de08c65..3fb07f437793 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
@@ -97,9 +97,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
const struct drm_edid *drm_edid = aconnector->drm_edid;
struct drm_edid_product_id product_id;
struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL;
-   int sad_count, sadb_count;
+   int sad_count;
int i = 0;
-   uint8_t *sadb = NULL;
  
  	enum dc_edid_status result = EDID_OK;
  
@@ -143,20 +142,12 @@ enum dc_edid_status dm_helpers_parse_edid_caps(

edid_caps->audio_modes[i].sample_size = sad.byte2;
}
  
-	sadb_count = drm_edid_to_speaker_allocation((struct edid *) edid->raw_edid, &sadb);
  
-	if (sadb_count < 0) {

-   DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", 
sadb_count);
-   sadb_count = 0;
-   }
-
-   if (sadb_count)
-   edid_caps->speaker_flags = sadb[0];
+   if (connector->eld[DRM_ELD_SPEAKER])
+   edid_caps->speaker_flags = connector->eld[DRM_ELD_SPEAKER];
else
edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION;
  
-	kfree(sadb);

-
return result;
  }
  


Re: [PATCH v4 09/11] drm/amd/display: get SAD from drm_eld when parsing EDID caps

2024-07-25 Thread Alex Hung




On 2024-07-05 21:35, Melissa Wen wrote:

instead of parsing struct edid.


A more informative commit message will be helpful.



Signed-off-by: Melissa Wen 
---
  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c   | 17 +
  1 file changed, 9 insertions(+), 8 deletions(-)

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 7657b1051c54..45c04de08c65 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
@@ -97,7 +97,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
const struct drm_edid *drm_edid = aconnector->drm_edid;
struct drm_edid_product_id product_id;
struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL;
-   struct cea_sad *sads;
int sad_count, sadb_count;
int i = 0;
uint8_t *sadb = NULL;
@@ -127,18 +126,21 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
  
  	apply_edid_quirks(&product_id, edid_caps);
  
-	sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads);

+   sad_count = drm_eld_sad_count(connector->eld);
if (sad_count <= 0)
return result;
  
  	edid_caps->audio_mode_count = min(sad_count, DC_MAX_AUDIO_DESC_COUNT);

for (i = 0; i < edid_caps->audio_mode_count; ++i) {
-   struct cea_sad *sad = &sads[i];
+   struct cea_sad sad;
  
-		edid_caps->audio_modes[i].format_code = sad->format;

-   edid_caps->audio_modes[i].channel_count = sad->channels + 1;
-   edid_caps->audio_modes[i].sample_rate = sad->freq;
-   edid_caps->audio_modes[i].sample_size = sad->byte2;
+   if (drm_eld_sad_get(connector->eld, i, &sad) < 0)
+   continue;
+
+   edid_caps->audio_modes[i].format_code = sad.format;
+   edid_caps->audio_modes[i].channel_count = sad.channels + 1;
+   edid_caps->audio_modes[i].sample_rate = sad.freq;
+   edid_caps->audio_modes[i].sample_size = sad.byte2;
}
  
  	sadb_count = drm_edid_to_speaker_allocation((struct edid *) edid->raw_edid, &sadb);

@@ -153,7 +155,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
else
edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION;
  
-	kfree(sads);

kfree(sadb);
  
  	return result;


Re: [PATCH v4 07/11] drm/amd/display: don't give initial values for sad/b_count

2024-07-25 Thread Alex Hung
Can this be merged with [PATCH 10/11] drm/amd/display: get SADB from 
drm_eld when parsing EDID caps


On 2024-07-05 21:35, Melissa Wen wrote:

Signed-off-by: Melissa Wen 
---
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 3 +--
  1 file changed, 1 insertion(+), 2 deletions(-)

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 85704fd75ee4..6df55161d6df 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
@@ -97,8 +97,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
struct drm_edid_product_id product_id;
struct edid *edid_buf = edid ? (struct edid *) edid->raw_edid : NULL;
struct cea_sad *sads;
-   int sad_count = -1;
-   int sadb_count = -1;
+   int sad_count, sadb_count;
int i = 0;
uint8_t *sadb = NULL;
  


Re: [PATCH v4 03/11] drm/amd/display: switch to setting physical address directly

2024-07-25 Thread Alex Hung




On 2024-07-05 21:35, Melissa Wen wrote:

Connectors have source physical address available in display
info. Use drm_dp_cec_attach() to use it instead of parsing the EDID
again.

Signed-off-by: Melissa Wen 
---
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++---
  1 file changed, 2 insertions(+), 3 deletions(-)

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 49b8c5b00728..163850aeac4a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3477,10 +3477,9 @@ void amdgpu_dm_update_connector_after_detect(
aconnector->drm_edid = drm_edid_alloc(edid, 
sink->dc_edid.length);
drm_edid_connector_update(connector, 
aconnector->drm_edid);
  
-			/* FIXME: Get rid of drm_edid_raw() */

if (aconnector->dc_link->aux_mode)
-   drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux,
-   
drm_edid_raw(aconnector->drm_edid));
drm_dp_cec_set_edid is removed here. I guess it doesn't matter if edid 
or drm_edid_raw(aconnector->drm_edid) is past here.



+   drm_dp_cec_attach(&aconnector->dm_dp_aux.aux,
+ 
connector->display_info.source_physical_address);
}
  
  		if (!aconnector->timing_requested) {


Re: [PATCH v4 02/11] drm/amd/display: switch amdgpu_dm_connector to use struct drm_edid

2024-07-25 Thread Alex Hung

Please see inline comments.

On 2024-07-05 21:35, Melissa Wen wrote:

Replace raw edid handling (struct edid) with the opaque EDID type
(struct drm_edid) on amdgpu_dm_connector for consistency. It may also
prevent mismatch of approaches in different parts of the driver code.
Working in progress. It was only exercised with IGT tests.

v2: use const to fix warnings (Alex Hung)
v3: fix general protection fault on mst
v4: rename edid to drm_edid in amdgpu_connector (Jani)
 call drm_edid_connector_update to clear edid in case of NULL (Jani)
 keep setting NULL instead of free drm_edid (Jani)
 check drm_edid not NULL, instead of valid (Jani)

Signed-off-by: Melissa Wen 
---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 106 +-
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   4 +-
  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  13 ++-
  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  32 +++---
  4 files changed, 79 insertions(+), 76 deletions(-)

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 1dfa7ec9af35..49b8c5b00728 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3408,7 +3408,7 @@ void amdgpu_dm_update_connector_after_detect(
aconnector->dc_sink = sink;
dc_sink_retain(aconnector->dc_sink);
amdgpu_dm_update_freesync_caps(connector,
-   aconnector->edid);
+   aconnector->drm_edid);
} else {
amdgpu_dm_update_freesync_caps(connector, NULL);
if (!aconnector->dc_sink) {
@@ -3467,18 +3467,20 @@ void amdgpu_dm_update_connector_after_detect(
aconnector->dc_sink = sink;
dc_sink_retain(aconnector->dc_sink);
if (sink->dc_edid.length == 0) {
-   aconnector->edid = NULL;
+   aconnector->drm_edid = NULL;
if (aconnector->dc_link->aux_mode) {
drm_dp_cec_unset_edid(
&aconnector->dm_dp_aux.aux);
}
} else {
-   aconnector->edid =
-   (struct edid *)sink->dc_edid.raw_edid;
+   const struct edid *edid = (const struct edid 
*)sink->dc_edid.raw_edid;
+   aconnector->drm_edid = drm_edid_alloc(edid, 
sink->dc_edid.length);
+   drm_edid_connector_update(connector, 
aconnector->drm_edid);
  
+			/* FIXME: Get rid of drm_edid_raw() */

if (aconnector->dc_link->aux_mode)
drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux,
-   aconnector->edid);

Why not pass edid but drm_edid_raw(aconnector->drm_edid)?


+   
drm_edid_raw(aconnector->drm_edid));
}
  
  		if (!aconnector->timing_requested) {

@@ -3489,17 +3491,18 @@ void amdgpu_dm_update_connector_after_detect(
"failed to create 
aconnector->requested_timing\n");
}
  
-		drm_connector_update_edid_property(connector, aconnector->edid);

-   amdgpu_dm_update_freesync_caps(connector, aconnector->edid);
+   drm_edid_connector_update(connector, aconnector->drm_edid);
+   amdgpu_dm_update_freesync_caps(connector, aconnector->drm_edid);
update_connector_ext_caps(aconnector);
} else {
drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux);
amdgpu_dm_update_freesync_caps(connector, NULL);
-   drm_connector_update_edid_property(connector, NULL);
+   drm_edid_connector_update(connector, NULL);
aconnector->num_modes = 0;
dc_sink_release(aconnector->dc_sink);
aconnector->dc_sink = NULL;
-   aconnector->edid = NULL;
+   drm_edid_free(aconnector->drm_edid);
+   aconnector->drm_edid = NULL;
kfree(aconnector->timing_requested);
aconnector->timing_requested = NULL;
/* Set CP to DESIRED if it was ENABLED, so we can re-enable it 
again on hotplug */
@@ -7002,13 +7005,7 @@ static void amdgpu_dm_connector_funcs_force(struct 
drm_connector *connector)
struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
struct dc_link *dc_link = aconnector->dc_link;
struct dc_sink *dc_em_sink = aconnector->dc_em_sink;
-   struct edid *edid;
-   struct 

Re: [PATCH v4 01/11] drm/amd/display: clean unused variables for hdmi freesync parser

2024-07-25 Thread Alex Hung

Hi Melissa,

There are no commit messages in this patch.

Also, do you think this can be merged with Patch 5 "drm/amd/display: 
remove redundant freesync parser for  DP"?


On 2024-07-05 21:35, Melissa Wen wrote:

Signed-off-by: Melissa Wen 
---
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ---
  1 file changed, 3 deletions(-)

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 98cf523a629e..1dfa7ec9af35 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -12108,9 +12108,6 @@ void amdgpu_dm_update_freesync_caps(struct 
drm_connector *connector,
} else if (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) {
-   timing  = &edid->detailed_timings[i];
-   data= &timing->data.other_data;
-
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)


Re: [PATCH v2] drm/amd/display: Add NULL check for clk_mgr in dcn32_init_hw

2024-07-22 Thread Alex Hung

Reviewed-by: Alex Hung 

On 2024-07-22 05:14, Srinivasan Shanmugam wrote:

This commit addresses a potential null pointer dereference issue in the
`dcn32_init_hw` function. The issue could occur when `dc->clk_mgr` is
null.

The fix adds a check to ensure `dc->clk_mgr` is not null before
accessing its functions. This prevents a potential null pointer
dereference.

Reported by smatch:
drivers/gpu/drm/amd/amdgpu/../display/dc/hwss/dcn32/dcn32_hwseq.c:961 
dcn32_init_hw() error: we previously assumed 'dc->clk_mgr' could be null (see 
line 782)

Cc: Tom Chung 
Cc: Rodrigo Siqueira 
Cc: Roman Li 
Cc: Alex Hung 
Cc: Aurabindo Pillai 
Cc: Harry Wentland 
Cc: Hamza Mahfooz 
Signed-off-by: Srinivasan Shanmugam 
---
v2: Along with "dc->clk_mgr" add check for even dc->clk_mgr->funcs" (Tom)

  drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 7 ---
  1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
index a7cb003f1dfb..fcaabad204a2 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
@@ -779,7 +779,7 @@ void dcn32_init_hw(struct dc *dc)
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
uint32_t user_level = MAX_BACKLIGHT_LEVEL;
  
-	if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)

+   if (dc->clk_mgr && dc->clk_mgr->funcs && 
dc->clk_mgr->funcs->init_clocks)
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
  
  	// Initialize the dccg

@@ -958,10 +958,11 @@ void dcn32_init_hw(struct dc *dc)
if (!dcb->funcs->is_accelerated_mode(dcb) && 
dc->res_pool->hubbub->funcs->init_watermarks)

dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
  
-	if (dc->clk_mgr->funcs->notify_wm_ranges)

+   if (dc->clk_mgr && dc->clk_mgr->funcs && 
dc->clk_mgr->funcs->notify_wm_ranges)
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
  
-	if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)

+   if (dc->clk_mgr && dc->clk_mgr->funcs && 
dc->clk_mgr->funcs->set_hard_max_memclk &&
+   !dc->clk_mgr->dc_mode_softmax_enabled)
dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
  
  	if (dc->res_pool->hubbub->funcs->force_pstate_change_control)


Re: [PATCH v2] drm/amd/display: Add NULL check for clk_mgr and clk_mgr->funcs in dcn30_init_hw

2024-07-22 Thread Alex Hung

Reviewed-by: Alex Hung 

On 2024-07-22 04:51, Srinivasan Shanmugam wrote:

This commit addresses a potential null pointer dereference issue in the
`dcn30_init_hw` function. The issue could occur when `dc->clk_mgr` or
`dc->clk_mgr->funcs` is null.

The fix adds a check to ensure `dc->clk_mgr` and `dc->clk_mgr->funcs` is
not null before accessing its functions. This prevents a potential null
pointer dereference.

Reported by smatch:
drivers/gpu/drm/amd/amdgpu/../display/dc/hwss/dcn30/dcn30_hwseq.c:789 
dcn30_init_hw() error: we previously assumed 'dc->clk_mgr' could be null (see 
line 628)

Cc: Tom Chung 
Cc: Rodrigo Siqueira 
Cc: Roman Li 
Cc: Alex Hung 
Cc: Aurabindo Pillai 
Cc: Harry Wentland 
Cc: Hamza Mahfooz 
Signed-off-by: Srinivasan Shanmugam 
---
v2: Along with "dc->clk_mgr" add check for even dc->clk_mgr->funcs" (Tom)

  drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c | 7 ---
  1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
index fc5936460ac2..98a40d46aaae 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
@@ -625,7 +625,7 @@ void dcn30_init_hw(struct dc *dc)
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
uint32_t user_level = MAX_BACKLIGHT_LEVEL;
  
-	if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)

+   if (dc->clk_mgr && dc->clk_mgr->funcs && 
dc->clk_mgr->funcs->init_clocks)
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
  
  	// Initialize the dccg

@@ -786,11 +786,12 @@ void dcn30_init_hw(struct dc *dc)
if (!dcb->funcs->is_accelerated_mode(dcb) && 
dc->res_pool->hubbub->funcs->init_watermarks)

dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
  
-	if (dc->clk_mgr->funcs->notify_wm_ranges)

+   if (dc->clk_mgr && dc->clk_mgr->funcs && 
dc->clk_mgr->funcs->notify_wm_ranges)
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
  
  	//if softmax is enabled then hardmax will be set by a different call

-   if (dc->clk_mgr->funcs->set_hard_max_memclk && 
!dc->clk_mgr->dc_mode_softmax_enabled)
+   if (dc->clk_mgr && dc->clk_mgr->funcs && 
dc->clk_mgr->funcs->set_hard_max_memclk &&
+   !dc->clk_mgr->dc_mode_softmax_enabled)
dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
  
  	if (dc->res_pool->hubbub->funcs->force_pstate_change_control)


Re: [PATCH v2] drm/amd/display: Add NULL check for clk_mgr and clk_mgr->funcs in dcn401_init_hw

2024-07-22 Thread Alex Hung

Reviewed-by: Alex Hung 

On 2024-07-22 05:28, Srinivasan Shanmugam wrote:

This commit addresses a potential null pointer dereference issue in the
`dcn401_init_hw` function. The issue could occur when `dc->clk_mgr` or
`dc->clk_mgr->funcs` is null.

The fix adds a check to ensure `dc->clk_mgr` and `dc->clk_mgr->funcs` is
not null before accessing its functions. This prevents a potential null
pointer dereference.

Reported by smatch:
drivers/gpu/drm/amd/amdgpu/../display/dc/hwss/dcn401/dcn401_hwseq.c:416 
dcn401_init_hw() error: we previously assumed 'dc->clk_mgr' could be null (see 
line 225)

Cc: Tom Chung 
Cc: Rodrigo Siqueira 
Cc: Roman Li 
Cc: Alex Hung 
Cc: Aurabindo Pillai 
Cc: Harry Wentland 
Cc: Hamza Mahfooz 
Signed-off-by: Srinivasan Shanmugam 
---
v2: Along with "dc->clk_mgr" add check for even dc->clk_mgr->funcs" (Tom)

  drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 8 +---
  1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 87c5ef579ecb..0fa610590245 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -222,7 +222,7 @@ void dcn401_init_hw(struct dc *dc)
uint32_t backlight = MAX_BACKLIGHT_LEVEL;
uint32_t user_level = MAX_BACKLIGHT_LEVEL;
  
-	if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) {

+   if (dc->clk_mgr && dc->clk_mgr->funcs && 
dc->clk_mgr->funcs->init_clocks) {
dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
  
  		// mark dcmode limits present if any clock has distinct AC and DC values from SMU

@@ -413,7 +413,7 @@ void dcn401_init_hw(struct dc *dc)
if (!dcb->funcs->is_accelerated_mode(dcb) && 
dc->res_pool->hubbub->funcs->init_watermarks)

dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
  
-	if (dc->clk_mgr->funcs->notify_wm_ranges)

+   if (dc->clk_mgr && dc->clk_mgr->funcs && 
dc->clk_mgr->funcs->notify_wm_ranges)
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
  
  	if (dc->res_pool->hubbub->funcs->force_pstate_change_control)

@@ -435,7 +435,9 @@ void dcn401_init_hw(struct dc *dc)
dc->debug.fams2_config.bits.enable &= 
dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver == 2;
if (!dc->debug.fams2_config.bits.enable && 
dc->res_pool->funcs->update_bw_bounding_box) {
/* update bounding box if FAMS2 disabled */
-   dc->res_pool->funcs->update_bw_bounding_box(dc, 
dc->clk_mgr->bw_params);
+   if (dc->clk_mgr)
+   dc->res_pool->funcs->update_bw_bounding_box(dc,
+   
dc->clk_mgr->bw_params);
}
}
  }


[PATCH] drm/amd/display: Add doc entry for program_3dlut_size

2024-07-15 Thread Alex Hung
Fixes the warning:

Function parameter or struct member 'program_3dlut_size' not described in 
'mpc_funcs'

Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
index 40a9b3471208..3a89cc0cffc1 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
@@ -1039,6 +1039,20 @@ struct mpc_funcs {
*/
void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_ID id, 
const enum MCM_LUT_XABLE xable,
bool lut_bank_a, int mpcc_id);
+   /**
+   * @program_3dlut_size:
+   *
+   * Program 3D LUT size.
+   *
+   * Parameters:
+   * - [in/out] mpc - MPC context.
+   * - [in] is_17x17x17 - is 3dlut 17x17x17
+   * - [in] mpcc_id
+   *
+   * Return:
+   *
+   * void
+   */
void (*program_3dlut_size)(struct mpc *mpc, bool is_17x17x17, int 
mpcc_id);
 };
 
-- 
2.34.1



[PATCH 39/39] drm/amd/display: 3.2.290

2024-06-20 Thread Alex Hung
From: Aric Cyr 

This version brings along the following:

- Enable DCC on DCN401
- Add reg definitions for DCN401 DCC
- Remove duplicate null check
- Remove always true condition
- Validate function returns
- Ensure curve to hw translation succeed
- Use periodic detection for ipx/headless
- Fix 1DLUT setting for NL SDR blending
- Adjust reg field for DSC wait for disconnect
- Remove a redundant check in authenticated_dp
- Add HW cursor visual confirm
- Fix cursor issues with ODMs and magnification
- Wait for double buffer update on ODM changes
- Reset DSC memory status
- Program CURSOR_DST_X_OFFSET in viewport space
- Add null checks before accessing struct elements
- Fix reduced resolution and refresh rate
- Make DML2.1 P-State method force per stream
- Add workaround to restrict max frac urgent for DPM0
- Call dpmm when checking mode support
- resync OTG after DIO FIFO resync
- Always enable HPO for DCN4 dGPU
- Use sw cursor for DCN401 with rotation
- Add Replay general cmd
- Check HDCP returned status
- Check and log for function error codes
- Check and log for function error codes
- Remove useless function call
- Fix uninitialized variables in dcn401
- Fix cursor size issues
- Run DC_LOG_DC after checking link->link_enc
- Remove redundant checks for pipe_ctx->stream
- Send DP_TOTAL_LTTPR_CNT during detection if LTTPR is present
- Fix cursor issues with ODMs and HW rotations
- Remove unnecessary variable
- Remove redundant var from display_rq_dig_calc in dml
- Refactor dccg401_get_other_enable_symclk_fe

Acked-by: Alex Hung 
Signed-off-by: Aric Cyr 
---
 drivers/gpu/drm/amd/display/dc/dc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 40f183816e31..900892855436 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -55,7 +55,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.289"
+#define DC_VER "3.2.290"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.34.1



[PATCH 38/39] drm/amd/display: Enable DCC on DCN401

2024-06-20 Thread Alex Hung
From: Aurabindo Pillai 

[WHAT]
Add registers and entry points to enable DCC on DCN4x

Reviewed-by: Rodrigo Siqueira 
Acked-by: Alex Hung 
Signed-off-by: Aurabindo Pillai 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  12 +
 .../drm/amd/display/dc/core/dc_hw_sequencer.c |  11 +
 drivers/gpu/drm/amd/display/dc/dc.h   |   4 +
 .../drm/amd/display/dc/dml2/dml2_wrapper.c|   6 +
 .../drm/amd/display/dc/dml2/dml2_wrapper.h|   2 +-
 .../display/dc/hubbub/dcn30/dcn30_hubbub.c|   3 +
 .../display/dc/hubbub/dcn31/dcn31_hubbub.c|   3 +
 .../display/dc/hubbub/dcn401/dcn401_hubbub.c  | 280 ++
 .../display/dc/hubbub/dcn401/dcn401_hubbub.h  |   5 +
 .../amd/display/dc/hubp/dcn20/dcn20_hubp.h|  14 +
 .../amd/display/dc/hubp/dcn401/dcn401_hubp.c  |  21 ++
 .../amd/display/dc/hubp/dcn401/dcn401_hubp.h  |  14 +-
 .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c   |   4 +
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c |  25 ++
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.h |   2 +
 .../amd/display/dc/hwss/dcn401/dcn401_init.c  |   1 +
 .../drm/amd/display/dc/hwss/hw_sequencer.h|   9 +
 .../gpu/drm/amd/display/dc/inc/core_types.h   |   3 +
 .../gpu/drm/amd/display/dc/inc/hw/dchubbub.h  |   4 +
 drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h  |   1 +
 .../dc/resource/dcn401/dcn401_resource.c  |   9 +
 .../dc/resource/dcn401/dcn401_resource.h  |   2 +
 22 files changed, 433 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index a4ba6f99cd34..85a2ef82afa5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1264,6 +1264,9 @@ static void disable_dangling_plane(struct dc *dc, struct 
dc_state *context)
apply_ctx_interdependent_lock(dc, 
dc->current_state, old_stream, false);
dc->hwss.post_unlock_program_front_end(dc, 
dangling_context);
}
+
+   if (dc->res_pool->funcs->prepare_mcache_programming)
+   
dc->res_pool->funcs->prepare_mcache_programming(dc, dangling_context);
if (dc->hwss.program_front_end_for_ctx) {
dc->hwss.interdependent_update_lock(dc, 
dc->current_state, true);
dc->hwss.program_front_end_for_ctx(dc, 
dangling_context);
@@ -2037,6 +2040,8 @@ static enum dc_status dc_commit_state_no_check(struct dc 
*dc, struct dc_state *c
}
 
/* Program all planes within new context*/
+   if (dc->res_pool->funcs->prepare_mcache_programming)
+   dc->res_pool->funcs->prepare_mcache_programming(dc, context);
if (dc->hwss.program_front_end_for_ctx) {
dc->hwss.interdependent_update_lock(dc, context, true);
dc->hwss.program_front_end_for_ctx(dc, context);
@@ -3884,6 +3889,9 @@ static void commit_planes_for_stream(struct dc *dc,
odm_pipe->ttu_regs.min_ttu_vblank = MAX_TTU;
}
 
+   if (update_type != UPDATE_TYPE_FAST && 
dc->res_pool->funcs->prepare_mcache_programming)
+   dc->res_pool->funcs->prepare_mcache_programming(dc, context);
+
if ((update_type != UPDATE_TYPE_FAST) && 
stream->update_flags.bits.dsc_changed)
if (top_pipe_to_program &&

top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
@@ -3903,6 +3911,10 @@ static void commit_planes_for_stream(struct dc *dc,

top_pipe_to_program->stream_res.tg);
}
 
+   if (dc->hwss.wait_for_dcc_meta_propagation) {
+   dc->hwss.wait_for_dcc_meta_propagation(dc, top_pipe_to_program);
+   }
+
if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
if (dc->hwss.subvp_pipe_control_lock)
dc->hwss.subvp_pipe_control_lock(dc, context, true, 
should_lock_all_pipes, NULL, subvp_prev_use);
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 5037474bf95c..87e36d51c56d 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
@@ -595,6 +595,12 @@ void hwss_build_fast_sequence(struct dc *dc,
if (!plane || !stream)
return;
 
+   if (dc->hwss.wait_for_dcc_meta_propagation) {
+   
block_sequence[*num_steps].params.wait_for_dcc_meta_propagation_params.dc = dc;
+   
block_sequence[*num_steps].params.wait_for_dcc_meta_propagation_params.top_pipe_to_program
 = pipe_ctx;
+   block_sequence[*num_steps].func = HUBP_WAIT_FOR_DCC

[PATCH 37/39] drm/amd: Add reg definitions for DCN401 DCC

2024-06-20 Thread Alex Hung
From: Aurabindo Pillai 

[WHAT]
Add the necessary register definitions to enable DCC on DCN4x

Reviewed-by: Rodrigo Siqueira 
Acked-by: Alex Hung 
Signed-off-by: Aurabindo Pillai 
---
 .../include/asic_reg/dcn/dcn_4_1_0_sh_mask.h  | 110 ++
 1 file changed, 110 insertions(+)

diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_4_1_0_sh_mask.h 
b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_4_1_0_sh_mask.h
index 0c68f5d818bb..f42a276499cd 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_4_1_0_sh_mask.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_4_1_0_sh_mask.h
@@ -6430,6 +6430,28 @@
 //DCHUBBUB_SDPIF_MEM_PWR_STATUS
 #define DCHUBBUB_SDPIF_MEM_PWR_STATUS__DCHUBBUB_SDPIF_MEM_PWR_STATE__SHIFT 
   0x0
 #define DCHUBBUB_SDPIF_MEM_PWR_STATUS__DCHUBBUB_SDPIF_MEM_PWR_STATE_MASK   
   0x0003L
+//DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE0__SHIFT
 0x0
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE1__SHIFT
 0x1
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE2__SHIFT
 0x2
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE3__SHIFT
 0x3
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE0__SHIFT
0xc
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE1__SHIFT
0xd
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE2__SHIFT
0xe
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE3__SHIFT
0xf
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_ENABLE__SHIFT
 0x1c
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_VREADY_MODE__SHIFT
0x1f
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE0_MASK
   0x0001L
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE1_MASK
   0x0002L
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE2_MASK
   0x0004L
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_FLIP_AWAY_MISSING_PIPE3_MASK
   0x0008L
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE0_MASK
  0x1000L
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE1_MASK
  0x2000L
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE2_MASK
  0x4000L
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_CLEAR_PIPE3_MASK
  0x8000L
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_ERR_ENABLE_MASK
   0x1000L
+#define 
DCHUBBUB_SDPIF_MCACHE_INVALIDATION_CTL__DCHUBBUB_SDPIF_MCACHEID_INV_VREADY_MODE_MASK
  0x8000L
+
 
 
 // addressBlock: dcn_dcec_dchubbubl_hubbub_ret_path_dispdec
@@ -7084,6 +7106,11 @@
 #define HUBP0_DCSURF_PRI_VIEWPORT_START__PRI_VIEWPORT_Y_START__SHIFT   
   0x10
 #define HUBP0_DCSURF_PRI_VIEWPORT_START__PRI_VIEWPORT_X_START_MASK 
   0xL
 #define HUBP0_DCSURF_PRI_VIEWPORT_START__PRI_VIEWPORT_Y_START_MASK 
   0xL
+//HUBP0_DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE
+#define 
HUBP0_DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE__VIEWPORT_MCACHE_SPLIT_COORDINATE__SHIFT
0x0
+#define 
HUBP0_DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE__VIEWPORT_MCACHE_SPLIT_COORDINATE_C__SHIFT
  0x10
+#define 
HUBP0_DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE__VIEWPORT_MCACHE_SPLIT_COORDINATE_MASK
  0xL
+#define 
HUBP0_DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE__VIEWPORT_MCACHE_SPLIT_COORDINATE_C_MASK
0xL
 //HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION
 #define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_WIDTH__SHIFT 
   0x0
 #define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_HEIGHT__SHIFT
   0x10
@@ -7244,6 +7271,23 @@
 #define HUBP0_DCHUBP_MALL_SUB_VP2__SUB_VP_HEIGHT_NEXT_S1__SHIFT
   0xc
 #define HUBP0_DCHUBP_MALL_SUB_VP2__SUB_VP_HEIGHT_CURR_S1_MASK  
   0x0FFFL
 #define HUBP0_DCHUBP_MALL_SUB_VP2__SUB_VP_HEIGHT_NEXT_S1_MASK

[PATCH 36/39] drm/amd/display: Remove duplicate null check

2024-06-20 Thread Alex Hung
[WHAT & HOW]
The same display null check was a few lines above.

This fixes 1 DEADCODE issue reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Acked-by: Alex Hung 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c 
b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
index 7c9805705fd3..8c137d7c032e 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
@@ -513,9 +513,6 @@ enum mod_hdcp_status mod_hdcp_hdcp2_create_session(struct 
mod_hdcp *hdcp)
hdcp_cmd = (struct ta_hdcp_shared_memory 
*)psp->hdcp_context.context.mem_context.shared_buf;
memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
-   if (!display)
-   return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;
-
hdcp_cmd->in_msg.hdcp2_create_session_v2.display_handle = 
display->index;
 
if (hdcp->connection.link.adjust.hdcp2.force_type == 
MOD_HDCP_FORCE_TYPE_0)
-- 
2.34.1



[PATCH 35/39] drm/amd/display: Remove always true condition

2024-06-20 Thread Alex Hung
[WHAT & HOW]
advanced_pstate_switching was initialized to false and never assigned to
another value; as a result !advanced_pstate_switching is always true and
should be removed.

This fixes 2 DEADCODE issues reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Acked-by: Alex Hung 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
index 90bb6e718301..60e2bf4ae6de 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
@@ -442,7 +442,6 @@ static bool optimize_pstate_with_svp_and_drr(struct 
dml2_context *dml2, struct d
bool result = false;
int drr_display_index = 0, non_svp_streams = 0;
bool force_svp = dml2->config.svp_pstate.force_enable_subvp;
-   bool advanced_pstate_switching = false;
 
display_state->bw_ctx.bw.dcn.clk.fw_based_mclk_switching = false;
display_state->bw_ctx.bw.dcn.legacy_svp_drr_stream_index_valid = false;
@@ -451,8 +450,7 @@ static bool optimize_pstate_with_svp_and_drr(struct 
dml2_context *dml2, struct d
 
if (!result) {
pstate_optimization_done = true;
-   } else if (!advanced_pstate_switching ||
-   (s->mode_support_info.DRAMClockChangeSupport[0] != 
dml_dram_clock_change_unsupported && !force_svp)) {
+   } else if (s->mode_support_info.DRAMClockChangeSupport[0] != 
dml_dram_clock_change_unsupported && !force_svp) {
pstate_optimization_success = true;
pstate_optimization_done = true;
}
-- 
2.34.1



[PATCH 34/39] drm/amd/display: Validate function returns

2024-06-20 Thread Alex Hung
[WHAT & HOW]
Function return values must be checked before data can be used
in subsequent functions.

This fixes 4 CHECKED_RETURN issues reported by Coverity.

Reviewed-by: Harry Wentland 
Acked-by: Alex Hung 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c   | 7 +--
 drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.c | 3 ++-
 .../drm/amd/display/dc/link/protocols/link_dp_training.c   | 3 +--
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c 
b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index b2051c4dd7b6..ded13026c8ff 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -245,7 +245,9 @@ bool dc_dmub_srv_cmd_run_list(struct dc_dmub_srv 
*dc_dmub_srv, unsigned int coun
if (status == DMUB_STATUS_POWER_STATE_D3)
return false;
 
-   dmub_srv_wait_for_idle(dmub, 10);
+   status = dmub_srv_wait_for_idle(dmub, 10);
+   if (status != DMUB_STATUS_OK)
+   return false;
 
/* Requeue the command. */
status = dmub_srv_cmd_queue(dmub, &cmd_list[i]);
@@ -517,7 +519,8 @@ void dc_dmub_srv_get_visual_confirm_color_cmd(struct dc 
*dc, struct pipe_ctx *pi
union dmub_rb_cmd cmd = { 0 };
unsigned int panel_inst = 0;
 
-   dc_get_edp_link_panel_inst(dc, pipe_ctx->stream->link, &panel_inst);
+   if (!dc_get_edp_link_panel_inst(dc, pipe_ctx->stream->link, 
&panel_inst))
+   return;
 
memset(&cmd, 0, sizeof(cmd));
 
diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.c 
b/drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.c
index 8901bd80f7d1..5c6f7ddafd6b 100644
--- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn20/dcn20_hubbub.c
@@ -616,7 +616,8 @@ static bool hubbub2_program_watermarks(
hubbub1->base.ctx->dc->clk_mgr->clks.p_state_change_support == 
false)
safe_to_lower = true;
 
-   hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, 
safe_to_lower);
+   if (hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, 
safe_to_lower))
+   wm_pending = true;
 
REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0,
DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
index 5a0f574056d4..988999c44475 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
@@ -1663,8 +1663,7 @@ bool perform_link_training_with_retries(
if (status == LINK_TRAINING_ABORT) {
enum dc_connection_type type = dc_connection_none;
 
-   link_detect_connection_type(link, &type);
-   if (type == dc_connection_none) {
+   if (link_detect_connection_type(link, &type) && type == 
dc_connection_none) {
DC_LOG_HW_LINK_TRAINING("%s: Aborting training 
because sink unplugged\n", __func__);
break;
}
-- 
2.34.1



[PATCH 33/39] drm/amd/display: Ensure curve to hw translation succeed

2024-06-20 Thread Alex Hung
[WHAT & HOW]
Check cm3_helper_translate_curve_to_hw_format runs successfully so the
regamma_params is valid and can be used.

Also revmoed two result assignments.

This fixes 2 CHECKED_RETURN UNUSED_VALUE issues reported by Coverity.

Reviewed-by: Harry Wentland 
Acked-by: Alex Hung 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c | 5 -
 drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 9 ++---
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
index bcacfd893cf7..eaeeade31ed7 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
@@ -228,8 +228,11 @@ bool dcn30_set_blend_lut(
if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
blend_lut = &plane_state->blend_tf.pwl;
else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
-   cm3_helper_translate_curve_to_hw_format(
+   result = cm3_helper_translate_curve_to_hw_format(
&plane_state->blend_tf, 
&dpp_base->regamma_params, false);
+   if (!result)
+   return result;
+
blend_lut = &dpp_base->regamma_params;
}
result = dpp_base->funcs->dpp_program_blnd_lut(dpp_base, blend_lut);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
index fe62478fbcde..05d8f81daa06 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
@@ -483,11 +483,14 @@ bool dcn32_set_mcm_luts(
if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
lut_params = &plane_state->blend_tf.pwl;
else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
-   cm3_helper_translate_curve_to_hw_format(&plane_state->blend_tf,
+   result = 
cm3_helper_translate_curve_to_hw_format(&plane_state->blend_tf,
&dpp_base->regamma_params, false);
+   if (!result)
+   return result;
+
lut_params = &dpp_base->regamma_params;
}
-   result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
+   mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
lut_params = NULL;
 
// Shaper
@@ -501,7 +504,7 @@ bool dcn32_set_mcm_luts(
lut_params = &dpp_base->shaper_params;
}
 
-   result = mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
+   mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
 
// 3D
if (plane_state->lut3d_func.state.bits.initialized == 1)
-- 
2.34.1



[PATCH 32/39] drm/amd/display: Use periodic detection for ipx/headless

2024-06-20 Thread Alex Hung
From: Roman Li 

[WHY]
Hotplug is not detected in headless (no eDP) mode on dcn35x.
With no display dcn35x goes to IPS2 powersaving state where HPD interrupt
is not handled.

[HOW]
Use idle worker thread for periodic detection of HPD in headless mode.

Reviewed-by: Aurabindo Pillai 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Roman Li 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  3 ++
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 48 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  5 +-
 3 files changed, 46 insertions(+), 10 deletions(-)

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 dfcbc1970fe6..5fd1b6b44577 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -989,4 +989,7 @@ void *dm_allocate_gpu_mem(struct amdgpu_device *adev,
  enum dc_gpu_mem_alloc_type 
type,
  size_t size,
  long long *addr);
+
+bool amdgpu_dm_is_headless(struct amdgpu_device *adev);
+
 #endif /* __AMDGPU_DM_H__ */
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 e16eecb146fd..99014339aaa3 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
@@ -162,33 +162,63 @@ static void amdgpu_dm_crtc_set_panel_sr_feature(
}
 }
 
+bool amdgpu_dm_is_headless(struct amdgpu_device *adev)
+{
+   struct drm_connector *connector;
+   struct drm_connector_list_iter iter;
+   struct drm_device *dev;
+   bool is_headless = true;
+
+   if (adev == NULL)
+   return true;
+
+   dev = adev->dm.ddev;
+
+   drm_connector_list_iter_begin(dev, &iter);
+   drm_for_each_connector_iter(connector, &iter) {
+
+   if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+   continue;
+
+   if (connector->status == connector_status_connected) {
+   is_headless = false;
+   break;
+   }
+   }
+   drm_connector_list_iter_end(&iter);
+   return is_headless;
+}
+
 static void amdgpu_dm_idle_worker(struct work_struct *work)
 {
struct idle_workqueue *idle_work;
 
idle_work = container_of(work, struct idle_workqueue, work);
idle_work->dm->idle_workqueue->running = true;
-   fsleep(HPD_DETECTION_PERIOD_uS);
-   mutex_lock(&idle_work->dm->dc_lock);
+
while (idle_work->enable) {
-   if (!idle_work->dm->dc->idle_optimizations_allowed)
+   fsleep(HPD_DETECTION_PERIOD_uS);
+   mutex_lock(&idle_work->dm->dc_lock);
+   if (!idle_work->dm->dc->idle_optimizations_allowed) {
+   mutex_unlock(&idle_work->dm->dc_lock);
break;
-
+   }
dc_allow_idle_optimizations(idle_work->dm->dc, false);
 
mutex_unlock(&idle_work->dm->dc_lock);
fsleep(HPD_DETECTION_TIME_uS);
mutex_lock(&idle_work->dm->dc_lock);
 
-   if (!amdgpu_dm_psr_is_active_allowed(idle_work->dm))
+   if (!amdgpu_dm_is_headless(idle_work->dm->adev) &&
+   !amdgpu_dm_psr_is_active_allowed(idle_work->dm)) {
+   mutex_unlock(&idle_work->dm->dc_lock);
break;
+   }
 
-   dc_allow_idle_optimizations(idle_work->dm->dc, true);
+   if (idle_work->enable)
+   dc_allow_idle_optimizations(idle_work->dm->dc, true);
mutex_unlock(&idle_work->dm->dc_lock);
-   fsleep(HPD_DETECTION_PERIOD_uS);
-   mutex_lock(&idle_work->dm->dc_lock);
}
-   mutex_unlock(&idle_work->dm->dc_lock);
idle_work->dm->idle_workqueue->running = false;
 }
 
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 659dd67be1ba..f5e1f2d1c5f2 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
@@ -1239,8 +1239,11 @@ void dm_helpers_enable_periodic_detection(struct 
dc_context *ctx, bool enable)
 {
struct amdgpu_device *adev = ctx->driver_context;
 
-   if (adev->dm.idle_workqueue)
+   if (adev->dm.idle_workqueue) {
adev->dm.idle_workqueue->enable = enable;
+   if (enab

[PATCH 31/39] drm/amd/display: Fix 1DLUT setting for NL SDR blending

2024-06-20 Thread Alex Hung
From: Relja Vojvodic 

[WHY]
Enabling NL SDR blending caused the 1D LUTs to be set/populated in two
different functions. This caused flickering as the LUT was set differently
by the two functions, one of which should only have been modifying the 1D
LUT if 3D LUT was enabled.

[HOW]
Added check to only modify the 1D LUT in populate_mcm if 3D LUT was
enabled.

Added blend_tf function update for non-main planes if the 3D LUT path
was taken.

Reviewed-by: Ilya Bakoulin 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Relja Vojvodic 
---
 drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 5306c8c170c5..b5a02a8fc9d8 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -502,7 +502,7 @@ void dcn401_populate_mcm_luts(struct dc *dc,
dcn401_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, 
&lut3d_xable, &lut1d_xable);
 
/* 1D LUT */
-   if (mcm_luts.lut1d_func) {
+   if (mcm_luts.lut1d_func && lut3d_xable != MCM_LUT_DISABLE) {
memset(&m_lut_params, 0, sizeof(m_lut_params));
if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL)
m_lut_params.pwl = &mcm_luts.lut1d_func->pwl;
@@ -674,7 +674,7 @@ bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
mpc->funcs->set_movable_cm_location(mpc, 
MPCC_MOVABLE_CM_LOCATION_BEFORE, mpcc_id);
pipe_ctx->plane_state->mcm_location = MPCC_MOVABLE_CM_LOCATION_BEFORE;
// 1D LUT
-   if (!plane_state->mcm_lut1d_enable) {
+   if (plane_state->mcm_shaper_3dlut_setting == 
DC_CM2_SHAPER_3DLUT_SETTING_BYPASS_ALL) {
if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
lut_params = &plane_state->blend_tf.pwl;
else if (plane_state->blend_tf.type == 
TF_TYPE_DISTRIBUTED_POINTS) {
-- 
2.34.1



[PATCH 30/39] drm/amd/display: Adjust reg field for DSC wait for disconnect

2024-06-20 Thread Alex Hung
From: Ryan Seto 

[WHY]
DSC was waiting for the wrong field to disconnect cleanly.

[HOW]
Changed field the DSC disconnect was waiting on.

Reviewed-by: Wenjing Liu 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Ryan Seto 
---
 drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h   | 4 +++-
 drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.c | 2 +-
 drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h | 3 ++-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h 
b/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h
index a23308a785bc..1fb90b52b814 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h
@@ -454,7 +454,9 @@
type DSCCIF_UPDATE_TAKEN_ACK; \
type DSCRM_DSC_FORWARD_EN; \
type DSCRM_DSC_OPP_PIPE_SOURCE; \
-   type DSCRM_DSC_DOUBLE_BUFFER_REG_UPDATE_PENDING
+   type DSCRM_DSC_DOUBLE_BUFFER_REG_UPDATE_PENDING; \
+   type DSCRM_DSC_FORWARD_EN_STATUS
+
 
 struct dcn20_dsc_registers {
uint32_t DSC_TOP_CONTROL;
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 52f23bb554af..6acb6699f146 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
@@ -208,7 +208,7 @@ static void dsc401_wait_disconnect_pending_clear(struct 
display_stream_compresso
 {
struct dcn401_dsc *dsc401 = TO_DCN401_DSC(dsc);
 
-   REG_WAIT(DSCRM_DSC_FORWARD_CONFIG, 
DSCRM_DSC_DOUBLE_BUFFER_REG_UPDATE_PENDING, 0, 2, 5);
+   REG_WAIT(DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_FORWARD_EN_STATUS, 0, 2, 
5);
 }
 
 static void dsc401_disconnect(struct display_stream_compressor *dsc)
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h 
b/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h
index 2143e81ca22a..3c9fa8988974 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn401/dcn401_dsc.h
@@ -196,7 +196,8 @@
DSC2_SF(DSCCIF0, DSCCIF_CONFIG0__BITS_PER_COMPONENT, mask_sh), \
DSC_SF(DSCCIF0_DSCCIF_CONFIG0, DOUBLE_BUFFER_REG_UPDATE_PENDING, 
mask_sh), \
DSC_SF(DSCRM0_DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_FORWARD_EN, mask_sh), 
\
-   DSC_SF(DSCRM0_DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_OPP_PIPE_SOURCE, 
mask_sh)
+   DSC_SF(DSCRM0_DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_OPP_PIPE_SOURCE, 
mask_sh), \
+   DSC_SF(DSCRM0_DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_FORWARD_EN_STATUS, 
mask_sh)
 
 struct dcn401_dsc_registers {
uint32_t DSC_TOP_CONTROL;
-- 
2.34.1



[PATCH 29/39] drm/amd/display: Remove a redundant check in authenticated_dp

2024-06-20 Thread Alex Hung
From: Wenjing Liu 

[WHY]
mod_hdcp_execute_and_set returns (*status == MOD_HDCP_STATUS_SUCCESS).
When it return 0, it is guaranteed that status == MOD_HDCP_STATUS_SUCCESS
will be evaluated as false. Since now we are using goto out already, all 3
if (status == MOD_HDCP_STATUS_SUCCESS) clauses are guaranteed to enter.
Therefore we are removing the if statements due to redundancy.

Reviewed-by: Rodrigo Siqueira 
Acked-by: Alex Hung 
Signed-off-by: Wenjing Liu 
---
 .../display/modules/hdcp/hdcp1_execution.c| 27 +--
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c 
b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
index d77836cef563..1e495e884484 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
@@ -432,21 +432,18 @@ static enum mod_hdcp_status authenticated_dp(struct 
mod_hdcp *hdcp,
goto out;
}
 
-   if (status == MOD_HDCP_STATUS_SUCCESS)
-   if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
-   &input->bstatus_read, &status,
-   hdcp, "bstatus_read"))
-   goto out;
-   if (status == MOD_HDCP_STATUS_SUCCESS)
-   if (!mod_hdcp_execute_and_set(check_link_integrity_dp,
-   &input->link_integrity_check, &status,
-   hdcp, "link_integrity_check"))
-   goto out;
-   if (status == MOD_HDCP_STATUS_SUCCESS)
-   if 
(!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
-   &input->reauth_request_check, &status,
-   hdcp, "reauth_request_check"))
-   goto out;
+   if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
+   &input->bstatus_read, &status,
+   hdcp, "bstatus_read"))
+   goto out;
+   if (!mod_hdcp_execute_and_set(check_link_integrity_dp,
+   &input->link_integrity_check, &status,
+   hdcp, "link_integrity_check"))
+   goto out;
+   if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
+   &input->reauth_request_check, &status,
+   hdcp, "reauth_request_check"))
+   goto out;
 out:
return status;
 }
-- 
2.34.1



[PATCH 28/39] drm/amd/display: Add HW cursor visual confirm

2024-06-20 Thread Alex Hung
From: Ryan Seto 

[WHY]
Added HW cursor visual confirm

[HOW]
Added visual confirm logic when programming cursor positions.
HW is programmed on cursor updates since cursor can change without flips.

Reviewed-by: Alvin Lee 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Ryan Seto 
---
 .../gpu/drm/amd/display/dc/core/dc_stream.c   | 29 +++
 drivers/gpu/drm/amd/display/dc/dc.h   |  1 +
 2 files changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 9b24f448ce50..de0633f98158 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -416,6 +416,35 @@ bool dc_stream_program_cursor_position(
if (reset_idle_optimizations && 
!dc->debug.disable_dmub_reallow_idle)
dc_allow_idle_optimizations(dc, true);
 
+   /* apply/update visual confirm */
+   if (dc->debug.visual_confirm == VISUAL_CONFIRM_HW_CURSOR) {
+   /* update software state */
+   uint32_t color_value = MAX_TG_COLOR_VALUE;
+   int i;
+
+   for (i = 0; i < dc->res_pool->pipe_count; i++) {
+   struct pipe_ctx *pipe_ctx = 
&dc->current_state->res_ctx.pipe_ctx[i];
+
+   /* adjust visual confirm color for all pipes 
with current stream */
+   if (stream == pipe_ctx->stream) {
+   if (stream->cursor_position.enable) {
+   
pipe_ctx->visual_confirm_color.color_r_cr = color_value;
+   
pipe_ctx->visual_confirm_color.color_g_y = 0;
+   
pipe_ctx->visual_confirm_color.color_b_cb = 0;
+   } else {
+   
pipe_ctx->visual_confirm_color.color_r_cr = 0;
+   
pipe_ctx->visual_confirm_color.color_g_y = 0;
+   
pipe_ctx->visual_confirm_color.color_b_cb = color_value;
+   }
+
+   /* programming hardware */
+   if (pipe_ctx->plane_state)
+   
dc->hwss.update_visual_confirm_color(dc, pipe_ctx,
+   
pipe_ctx->plane_res.hubp->mpcc_id);
+   }
+   }
+   }
+
return true;
}
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index e0334b573f2d..64241de70f15 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -476,6 +476,7 @@ enum visual_confirm {
VISUAL_CONFIRM_SUBVP = 14,
VISUAL_CONFIRM_MCLK_SWITCH = 16,
VISUAL_CONFIRM_FAMS2 = 19,
+   VISUAL_CONFIRM_HW_CURSOR = 20,
 };
 
 enum dc_psr_power_opts {
-- 
2.34.1



[PATCH 27/39] drm/amd/display: Fix cursor issues with ODMs and magnification

2024-06-20 Thread Alex Hung
From: Nevenko Stupar 

[WHY & HOW]
Adjust hot spot positions between ODM slices when cursor
magnification is used.

Reviewed-by: Sridevi Arvindekar 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Nevenko Stupar 
---
 .../gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c| 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 79a911e1a09a..5306c8c170c5 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -1177,6 +1177,15 @@ void dcn401_set_cursor_position(struct pipe_ctx 
*pipe_ctx)
 
if (x_pos < 0) {
pos_cpy.x_hotspot -= x_pos;
+   if ((odm_combine_on) && 
(hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION)) {
+   if (hubp->curs_attr.width <= 128) {
+   pos_cpy.x_hotspot /= 2;
+   pos_cpy.x_hotspot += 1;
+   } else {
+   pos_cpy.x_hotspot /= 2;
+   pos_cpy.x_hotspot += 2;
+   }
+   }
x_pos = 0;
}
 
-- 
2.34.1



[PATCH 26/39] drm/amd/display: Wait for double buffer update on ODM changes

2024-06-20 Thread Alex Hung
From: Alvin Lee 

[WHAT & HOW]
We must wait for ODM double buffer updates to complete
before exiting the pipe update sequence or we may reduce
DISPCLK and hit some transient underflow (pixel rate is
reduced before the pipes have ODM enabled).

Reviewed-by: Samson Tam 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Alvin Lee 
---
 .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c   | 23 +++
 .../amd/display/dc/inc/hw/timing_generator.h  |  1 +
 .../amd/display/dc/optc/dcn10/dcn10_optc.h|  3 ++-
 .../amd/display/dc/optc/dcn32/dcn32_optc.c| 13 +++
 .../amd/display/dc/optc/dcn32/dcn32_optc.h|  2 ++
 .../amd/display/dc/optc/dcn401/dcn401_optc.c  |  1 +
 .../amd/display/dc/optc/dcn401/dcn401_optc.h  |  1 +
 7 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
index 4d359bb9b1ec..36797ed7ad8c 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
@@ -2227,6 +2227,29 @@ void dcn20_post_unlock_program_front_end(
}
}
 
+   for (i = 0; i < dc->res_pool->pipe_count; i++) {
+   struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+   struct pipe_ctx *old_pipe = 
&dc->current_state->res_ctx.pipe_ctx[i];
+
+   /* When going from a smaller ODM slice count to larger, we must 
ensure double
+* buffer update completes before we return to ensure we don't 
reduce DISPCLK
+* before we've transitioned to 2:1 or 4:1
+*/
+   if (resource_is_pipe_type(old_pipe, OTG_MASTER) && 
resource_is_pipe_type(pipe, OTG_MASTER) &&
+   resource_get_odm_slice_count(old_pipe) < 
resource_get_odm_slice_count(pipe) &&
+   dc_state_get_pipe_subvp_type(context, pipe) != 
SUBVP_PHANTOM) {
+   int j = 0;
+   struct timing_generator *tg = pipe->stream_res.tg;
+
+
+   if (tg->funcs->get_double_buffer_pending) {
+   for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_US / 
polling_interval_us
+   && tg->funcs->get_double_buffer_pending(tg); 
j++)
+   udelay(polling_interval_us);
+   }
+   }
+   }
+
if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
dc->res_pool->hubbub->funcs->force_pstate_change_control(
dc->res_pool->hubbub, false, false);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
index cd4826f329c1..0f453452234c 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
@@ -340,6 +340,7 @@ struct timing_generator_funcs {
void (*wait_drr_doublebuffer_pending_clear)(struct timing_generator 
*tg);
void (*set_long_vtotal)(struct timing_generator *optc, const struct 
long_vtotal_params *params);
void (*wait_odm_doublebuffer_pending_clear)(struct timing_generator 
*tg);
+   bool (*get_double_buffer_pending)(struct timing_generator *tg);
 };
 
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h 
b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
index e3e70c1db040..369a13244e5e 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
@@ -562,7 +562,8 @@ struct dcn_optc_registers {
type OTG_CRC_DATA_FORMAT;\
type OTG_V_TOTAL_LAST_USED_BY_DRR;\
type OTG_DRR_TIMING_DBUF_UPDATE_PENDING;\
-   type OTG_H_TIMING_DIV_MODE_DB_UPDATE_PENDING;
+   type OTG_H_TIMING_DIV_MODE_DB_UPDATE_PENDING;\
+   type OPTC_DOUBLE_BUFFER_PENDING;\
 
 #define TG_REG_FIELD_LIST_DCN3_2(type) \
type OTG_H_TIMING_DIV_MODE_MANUAL;
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c 
b/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c
index 6c837409df42..00094f0e8470 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c
@@ -297,6 +297,18 @@ static void optc32_set_drr(
optc32_setup_manual_trigger(optc);
 }
 
+bool optc32_get_double_buffer_pending(struct timing_generator *optc)
+{
+   struct optc *optc1 = DCN10TG_FROM_TG(optc);
+   uint32_t update_pending = 0;
+
+   REG_GET(OPTC_INPUT_GLOBAL_CONTROL,
+   OPTC_DOUBLE_BUFFER_PENDING,
+   &update_pending);
+
+   return (update_pendin

[PATCH 25/39] drm/amd/display: Reset DSC memory status

2024-06-20 Thread Alex Hung
From: Duncan Ma 

[WHY]
When system exits idle state followed by enabling the display,
DSC memory may still be forced in a deep sleep or shutdown state.

Intermittent DSC corruption is seen when display is visible.

[HOW]
When DSC is enabled, reset dsc memory to force and disable status.

Reviewed-by: Nicholas Kazlauskas 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Duncan Ma 
---
 .../drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c  | 24 +++-
 .../drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h  |  9 +++
 .../drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c  | 58 ++-
 3 files changed, 71 insertions(+), 20 deletions(-)

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 d6b2334d5364..75128fd34306 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
@@ -32,16 +32,6 @@
 
 static void dsc_write_to_registers(struct display_stream_compressor *dsc, 
const struct dsc_reg_values *reg_vals);
 
-/* Object I/F functions */
-static void dsc2_read_state(struct display_stream_compressor *dsc, struct 
dcn_dsc_state *s);
-static bool dsc2_validate_stream(struct display_stream_compressor *dsc, const 
struct dsc_config *dsc_cfg);
-static void dsc2_set_config(struct display_stream_compressor *dsc, const 
struct dsc_config *dsc_cfg,
-   struct dsc_optc_config *dsc_optc_cfg);
-static void dsc2_enable(struct display_stream_compressor *dsc, int opp_pipe);
-static void dsc2_disable(struct display_stream_compressor *dsc);
-static void dsc2_disconnect(struct display_stream_compressor *dsc);
-static void dsc2_wait_disconnect_pending_clear(struct 
display_stream_compressor *dsc);
-
 static const struct dsc_funcs dcn20_dsc_funcs = {
.dsc_get_enc_caps = dsc2_get_enc_caps,
.dsc_read_state = dsc2_read_state,
@@ -156,7 +146,7 @@ void dsc2_get_enc_caps(struct dsc_enc_caps *dsc_enc_caps, 
int pixel_clock_100Hz)
 /* this function read dsc related register fields to be logged later in 
dcn10_log_hw_state
  * into a dcn_dsc_state struct.
  */
-static void dsc2_read_state(struct display_stream_compressor *dsc, struct 
dcn_dsc_state *s)
+void dsc2_read_state(struct display_stream_compressor *dsc, struct 
dcn_dsc_state *s)
 {
struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc);
 
@@ -173,7 +163,7 @@ static void dsc2_read_state(struct 
display_stream_compressor *dsc, struct dcn_ds
 }
 
 
-static bool dsc2_validate_stream(struct display_stream_compressor *dsc, const 
struct dsc_config *dsc_cfg)
+bool dsc2_validate_stream(struct display_stream_compressor *dsc, const struct 
dsc_config *dsc_cfg)
 {
struct dsc_optc_config dsc_optc_cfg;
struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc);
@@ -196,7 +186,7 @@ void dsc_config_log(struct display_stream_compressor *dsc, 
const struct dsc_conf
DC_LOG_DSC("\tcolor_depth %d", config->color_depth);
 }
 
-static void dsc2_set_config(struct display_stream_compressor *dsc, const 
struct dsc_config *dsc_cfg,
+void dsc2_set_config(struct display_stream_compressor *dsc, const struct 
dsc_config *dsc_cfg,
struct dsc_optc_config *dsc_optc_cfg)
 {
bool is_config_ok;
@@ -233,7 +223,7 @@ bool dsc2_get_packed_pps(struct display_stream_compressor 
*dsc, const struct dsc
 }
 
 
-static void dsc2_enable(struct display_stream_compressor *dsc, int opp_pipe)
+void dsc2_enable(struct display_stream_compressor *dsc, int opp_pipe)
 {
struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc);
int dsc_clock_en;
@@ -258,7 +248,7 @@ static void dsc2_enable(struct display_stream_compressor 
*dsc, int opp_pipe)
 }
 
 
-static void dsc2_disable(struct display_stream_compressor *dsc)
+void dsc2_disable(struct display_stream_compressor *dsc)
 {
struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc);
int dsc_clock_en;
@@ -277,14 +267,14 @@ static void dsc2_disable(struct display_stream_compressor 
*dsc)
DSC_CLOCK_EN, 0);
 }
 
-static void dsc2_wait_disconnect_pending_clear(struct 
display_stream_compressor *dsc)
+void dsc2_wait_disconnect_pending_clear(struct display_stream_compressor *dsc)
 {
struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc);
 
REG_WAIT(DSCRM_DSC_FORWARD_CONFIG, 
DSCRM_DSC_DOUBLE_BUFFER_REG_UPDATE_PENDING, 0, 2, 5);
 }
 
-static void dsc2_disconnect(struct display_stream_compressor *dsc)
+void dsc2_disconnect(struct display_stream_compressor *dsc)
 {
struct dcn20_dsc *dsc20 = TO_DCN20_DSC(dsc);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h 
b/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h
index a136b26c914c..a23308a785bc 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h
@@ -597,5 +597,14 @@ bool dsc2_get_packed_pps(struct display_stream_compressor 
*dsc,
const struct dsc_co

[PATCH 24/39] drm/amd/display: Program CURSOR_DST_X_OFFSET in viewport space

2024-06-20 Thread Alex Hung
From: Alvin Lee 

[WHAT & HOW]
According to register specifications, the CURSOR_DST_X_OFFSET
is relative to the start of the data viewport, not RECOUT space.
In this case we must transform the cursor coordinates passed to
hubp401_cursor_set_position into viewport space to program this
register. This fixes an underflow issue that occurs in scaled
mode with low refresh rate.

Reviewed-by: Nevenko Stupar 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Alvin Lee 
---
 .../gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c 
b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
index a893160ae775..3f9ca9b40949 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
@@ -656,7 +656,9 @@ void hubp401_cursor_set_position(
int y_pos = pos->y - param->recout.y;
int rec_x_offset = x_pos - pos->x_hotspot;
int rec_y_offset = y_pos - pos->y_hotspot;
-   uint32_t dst_x_offset;
+   int dst_x_offset;
+   int x_pos_viewport = x_pos * param->viewport.width / 
param->recout.width;
+   int x_hot_viewport = pos->x_hotspot * param->viewport.width / 
param->recout.width;
uint32_t cur_en = pos->enable ? 1 : 0;
 
hubp->curs_pos = *pos;
@@ -668,7 +670,13 @@ void hubp401_cursor_set_position(
if (hubp->curs_attr.address.quad_part == 0)
return;
 
-   dst_x_offset = (rec_x_offset >= 0) ? rec_x_offset : 0;
+   /* Translate the x position of the cursor from rect
+* space into viewport space. CURSOR_DST_X_OFFSET
+* is the offset relative to viewport start position.
+*/
+   dst_x_offset = x_pos_viewport - x_hot_viewport *
+   (1 + 
hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION);
+   dst_x_offset = (dst_x_offset >= 0) ? dst_x_offset : 0;
dst_x_offset *= param->ref_clk_khz;
dst_x_offset /= param->pixel_clk_khz;
 
-- 
2.34.1



[PATCH 23/39] drm/amd/display: Add null checks before accessing struct elements

2024-06-20 Thread Alex Hung
[WHAT]
1. is_pwrseq0 needs to check link before accessing link->link_index.
2. context is checked before accessing its bw_ctx.dml2
3. clk_mgr_base->bw_params is checked before clk_table.num_entries_per_cl

This fixes 4 REVERSE_INULL issues reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Acked-by: Alex Hung 
Signed-off-by: Alex Hung 
---
 .../drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c   | 10 ++
 .../drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c | 10 ++
 drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c   |  2 +-
 drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c |  4 +++-
 4 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
index 06f0c41ad6f1..3b10b24f5e23 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
@@ -163,9 +163,14 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
 {
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
unsigned int num_levels;
-   struct clk_limit_num_entries *num_entries_per_clk = 
&clk_mgr_base->bw_params->clk_table.num_entries_per_clk;
+   struct clk_limit_num_entries *num_entries_per_clk;
unsigned int i;
 
+   if (!clk_mgr_base->bw_params)
+   return;
+
+   num_entries_per_clk = 
&clk_mgr_base->bw_params->clk_table.num_entries_per_clk;
+
memset(&(clk_mgr_base->clks), 0, sizeof(struct dc_clocks));
clk_mgr_base->clks.p_state_change_support = true;
clk_mgr_base->clks.prev_p_state_change_support = true;
@@ -173,9 +178,6 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
clk_mgr->smu_present = false;
clk_mgr->dpm_present = false;
 
-   if (!clk_mgr_base->bw_params)
-   return;
-
if (!clk_mgr_base->force_smu_not_present && 
dcn30_smu_get_smu_version(clk_mgr, &clk_mgr->smu_ver))
clk_mgr->smu_present = true;
 
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
index 70f06a7c882e..606b2411eee9 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
@@ -207,9 +207,14 @@ static void dcn401_build_wm_range_table(struct clk_mgr 
*clk_mgr)
 void dcn401_init_clocks(struct clk_mgr *clk_mgr_base)
 {
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
-   struct clk_limit_num_entries *num_entries_per_clk = 
&clk_mgr_base->bw_params->clk_table.num_entries_per_clk;
+   struct clk_limit_num_entries *num_entries_per_clk;
unsigned int i;
 
+   if (!clk_mgr_base->bw_params)
+   return;
+
+   num_entries_per_clk = 
&clk_mgr_base->bw_params->clk_table.num_entries_per_clk;
+
memset(&(clk_mgr_base->clks), 0, sizeof(struct dc_clocks));
clk_mgr_base->clks.p_state_change_support = true;
clk_mgr_base->clks.prev_p_state_change_support = true;
@@ -217,9 +222,6 @@ void dcn401_init_clocks(struct clk_mgr *clk_mgr_base)
clk_mgr->smu_present = false;
clk_mgr->dpm_present = false;
 
-   if (!clk_mgr_base->bw_params)
-   return;
-
if (!clk_mgr_base->force_smu_not_present && 
dcn30_smu_get_smu_version(clk_mgr, &clk_mgr->smu_ver))
clk_mgr->smu_present = true;
 
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 54dd7e164635..8a8efe408a9d 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
@@ -1084,7 +1084,7 @@ static enum dcn_zstate_support_state  
decide_zstate_support(struct dc *dc, struc
struct dc_stream_status *stream_status = 
&context->stream_status[0];
int minmum_z8_residency = dc->debug.minimum_z8_residency_time > 
0 ? dc->debug.minimum_z8_residency_time : 1000;
bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > 
(double)minmum_z8_residency;
-   bool is_pwrseq0 = link->link_index == 0;
+   bool is_pwrseq0 = (link && link->link_index == 0);
bool is_psr = (link && (link->psr_settings.psr_version == 
DC_PSR_VERSION_1 ||
link->psr_settings.psr_version 
== DC_PSR_VERSION_SU_1) && !link->panel_config.psr.disable_psr);
bool is_replay = link && 
link->replay_settings.replay_feature_enabled;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c 
b/drivers/gpu/d

[PATCH 22/39] drm/amd/display: Fix reduced resolution and refresh rate

2024-06-20 Thread Alex Hung
From: Daniel Sa 

[WHY]
Some monitors are forced to a lower resolution and refresh rate after
system restarts.

[HOW]
Some monitors may give invalid LTTPR information when queried such as
indicating they have one DP lane instead of 4. If given an invalid DPCD
version, skip over getting lttpr link rate and lane counts.

Reviewed-by: Wenjing Liu 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Daniel Sa 
---
 .../dc/link/protocols/link_dp_capability.c| 21 ++-
 1 file changed, 11 insertions(+), 10 deletions(-)

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 f1cac74dd7f7..46bb7a855bc2 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
@@ -409,9 +409,6 @@ static enum dc_link_rate get_lttpr_max_link_rate(struct 
dc_link *link)
case LINK_RATE_HIGH3:
lttpr_max_link_rate = link->dpcd_caps.lttpr_caps.max_link_rate;
break;
-   default:
-   // Assume all LTTPRs support up to HBR3 to improve misbehaving 
sink interop
-   lttpr_max_link_rate = LINK_RATE_HIGH3;
}
 
if (link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR20)
@@ -2137,15 +2134,19 @@ struct dc_link_settings dp_get_max_link_cap(struct 
dc_link *link)
 * notes: repeaters do not snoop in the DPRX Capabilities addresses 
(3.6.3).
 */
if (dp_is_lttpr_present(link)) {
-   if (link->dpcd_caps.lttpr_caps.max_lane_count < 
max_link_cap.lane_count)
-   max_link_cap.lane_count = 
link->dpcd_caps.lttpr_caps.max_lane_count;
-   lttpr_max_link_rate = get_lttpr_max_link_rate(link);
 
-   if (lttpr_max_link_rate < max_link_cap.link_rate)
-   max_link_cap.link_rate = lttpr_max_link_rate;
+   /* Some LTTPR devices do not report valid DPCD revisions, if 
so, do not take it's link cap into consideration. */
+   if (link->dpcd_caps.lttpr_caps.revision.raw >= DPCD_REV_14) {
+   if (link->dpcd_caps.lttpr_caps.max_lane_count < 
max_link_cap.lane_count)
+   max_link_cap.lane_count = 
link->dpcd_caps.lttpr_caps.max_lane_count;
+   lttpr_max_link_rate = get_lttpr_max_link_rate(link);
 
-   if 
(!link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR13_5)
-   is_uhbr13_5_supported = false;
+   if (lttpr_max_link_rate < max_link_cap.link_rate)
+   max_link_cap.link_rate = lttpr_max_link_rate;
+
+   if 
(!link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR13_5)
+   is_uhbr13_5_supported = false;
+   }
 
DC_LOG_HW_LINK_TRAINING("%s\n Training with LTTPR,  max_lane 
count %d max_link rate %d \n",
__func__,
-- 
2.34.1



[PATCH 21/39] drm/amd/display: Make DML2.1 P-State method force per stream

2024-06-20 Thread Alex Hung
From: Dillon Varone 

[WHY & HOW]
Currently the force only works for a single display, make it so it can
be forced per stream.

Reviewed-by: Alvin Lee 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Dillon Varone 
---
 drivers/gpu/drm/amd/display/dc/dc.h| 2 +-
 .../drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c   | 2 +-
 drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c  | 3 ++-
 drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h | 2 +-
 4 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index d0d1af451b64..e0334b573f2d 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1038,7 +1038,7 @@ struct dc_debug_options {
bool force_chroma_subsampling_1tap;
bool disable_422_left_edge_pixel;
bool dml21_force_pstate_method;
-   uint32_t dml21_force_pstate_method_value;
+   uint32_t dml21_force_pstate_method_values[MAX_PIPES];
uint32_t dml21_disable_pstate_method_mask;
union dmub_fams2_global_feature_config fams2_config;
bool enable_legacy_clock_update;
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
index d5ead0205053..06387b8b0aee 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
@@ -1000,7 +1000,7 @@ bool dml21_map_dc_state_into_dml_display_cfg(const struct 
dc *in_dc, struct dc_s
/* apply forced pstate policy */
if 
(dml_ctx->config.pmo.force_pstate_method_enable) {

dml_dispcfg->plane_descriptors[disp_cfg_plane_location].overrides.uclk_pstate_change_strategy
 =
-   
dml21_force_pstate_method_to_uclk_state_change_strategy(dml_ctx->config.pmo.force_pstate_method_value);
+   
dml21_force_pstate_method_to_uclk_state_change_strategy(dml_ctx->config.pmo.force_pstate_method_values[stream_index]);
}
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c
index 9c28304568d2..c310354cd5fc 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c
@@ -47,7 +47,8 @@ static void dml21_apply_debug_options(const struct dc *in_dc, 
struct dml2_contex
/* UCLK P-State options */
if (in_dc->debug.dml21_force_pstate_method) {
dml_ctx->config.pmo.force_pstate_method_enable = true;
-   dml_ctx->config.pmo.force_pstate_method_value = 
in_dc->debug.dml21_force_pstate_method_value;
+   for (int i = 0; i < MAX_PIPES; i++)
+   dml_ctx->config.pmo.force_pstate_method_values[i] = 
in_dc->debug.dml21_force_pstate_method_values[i];
} else {
dml_ctx->config.pmo.force_pstate_method_enable = false;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h 
b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
index 79bf2d757804..1e891a3297c2 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
@@ -230,7 +230,7 @@ struct dml2_configuration_options {
struct socbb_ip_params_external *external_socbb_ip_params;
struct {
bool force_pstate_method_enable;
-   enum dml2_force_pstate_methods force_pstate_method_value;
+   enum dml2_force_pstate_methods 
force_pstate_method_values[MAX_PIPES];
} pmo;
bool map_dc_pipes_with_callbacks;
 
-- 
2.34.1



[PATCH 20/39] drm/amd/display: Add workaround to restrict max frac urgent for DPM0

2024-06-20 Thread Alex Hung
From: Sung-huai Wang 

[WHY]
Underflow occurs on some platforms when urgent BW is close to
the maximum in DPM0.

[HOW]
It does not occur at DPM1, so as a workaround restrict the maximum
amount and increase the lowest state index for clock states until
we're out of DPM0.
Adds DML2 config options to specify this pe platform as required.

Reviewed-by: Nicholas Kazlauskas 
Acked-by: Alex Hung 
Signed-off-by: Sung-huai Wang 
---
 .../gpu/drm/amd/display/dc/dml2/dml2_wrapper.c| 15 +++
 .../gpu/drm/amd/display/dc/dml2/dml2_wrapper.h|  2 ++
 .../display/dc/resource/dcn35/dcn35_resource.c|  3 ++-
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
index f6310408dbba..f4038ac2e476 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
@@ -628,6 +628,21 @@ static bool dml2_validate_and_build_resource(const struct 
dc *in_dc, struct dc_s
 
if (result) {
unsigned int lowest_state_idx = 
s->mode_support_params.out_lowest_state_idx;
+   double min_fclk_mhz_for_urgent_workaround = 
(double)dml2->config.min_fclk_for_urgent_workaround_khz / 1000.0;
+   double max_frac_urgent = 
(double)dml2->config.max_frac_urgent_for_min_fclk_x1000 / 1000.0;
+
+   if (min_fclk_mhz_for_urgent_workaround > 0.0 && max_frac_urgent 
> 0.0 &&
+   (dml2->v20.dml_core_ctx.mp.FractionOfUrgentBandwidth > 
max_frac_urgent ||
+
dml2->v20.dml_core_ctx.mp.FractionOfUrgentBandwidthImmediateFlip > 
max_frac_urgent)) {
+   unsigned int forced_lowest_state_idx = lowest_state_idx;
+
+   while (forced_lowest_state_idx < 
dml2->v20.dml_core_ctx.states.num_states &&
+  
dml2->v20.dml_core_ctx.states.state_array[forced_lowest_state_idx].fabricclk_mhz
 <= min_fclk_mhz_for_urgent_workaround) {
+   forced_lowest_state_idx += 1;
+   }
+   lowest_state_idx = forced_lowest_state_idx;
+   }
+
out_clks.dispclk_khz = (unsigned 
int)dml2->v20.dml_core_ctx.mp.Dispclk_calculated * 1000;
out_clks.p_state_supported = 
s->mode_support_info.DRAMClockChangeSupport[0] != 
dml_dram_clock_change_unsupported;
if (in_dc->config.use_default_clock_table &&
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h 
b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
index 20b3970c0857..79bf2d757804 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
@@ -237,6 +237,8 @@ struct dml2_configuration_options {
bool use_clock_dc_limits;
bool gpuvm_enable;
struct dml2_soc_bb *bb_from_dmub;
+   int max_frac_urgent_for_min_fclk_x1000;
+   int min_fclk_for_urgent_workaround_khz;
 };
 
 /*
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
index 67ab8c1962ff..1ce0f9ecff9c 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
@@ -2152,8 +2152,9 @@ static bool dcn35_resource_construct(

dc->dml2_options.callbacks.can_support_mclk_switch_using_fw_based_vblank_stretch
 = &dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch;
 
dc->dml2_options.max_segments_per_hubp = 24;
-
dc->dml2_options.det_segment_size = DCN3_2_DET_SEG_SIZE;/*todo*/
+   dc->dml2_options.max_frac_urgent_for_min_fclk_x1000 = 900;
+   dc->dml2_options.min_fclk_for_urgent_workaround_khz = 400 * 1000;
 
if (dc->config.sdpif_request_limit_words_per_umc == 0)
dc->config.sdpif_request_limit_words_per_umc = 16;/*todo*/
-- 
2.34.1



[PATCH 19/39] drm/amd/display: Call dpmm when checking mode support

2024-06-20 Thread Alex Hung
From: George Shen 

[WHY]
In check_mode_supported, we should validate that the required clocks
can be successfully mapped to DPM levels.

This ensures we only apply dynamic ODM optimizations to modes that
are supported without dynamic ODM optimizations to begin with.

[HOW]
Call dpmm to check that the display config can successfully be
mapped to a DPM level.

Reviewed-by: Chaitanya Dhere 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: George Shen 
---
 .../amd/display/dc/dml2/dml21/dml21_wrapper.c   |  1 +
 .../dc/dml2/dml21/src/dml2_top/dml_top.c| 17 +
 .../dml21/src/inc/dml2_internal_shared_types.h  |  1 +
 3 files changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c
index b442e1f9f204..9c28304568d2 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_wrapper.c
@@ -257,6 +257,7 @@ static bool dml21_check_mode_support(const struct dc 
*in_dc, struct dc_state *co
 
mode_support->dml2_instance = dml_init->dml2_instance;
dml21_map_dc_state_into_dml_display_cfg(in_dc, context, dml_ctx);
+   
dml_ctx->v21.mode_programming.dml2_instance->scratch.build_mode_programming_locals.mode_programming_params.programming
 = dml_ctx->v21.mode_programming.programming;
is_supported = dml2_check_mode_supported(mode_support);
if (!is_supported)
return false;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c
index 6f334fdc6eb8..2fb3e2f45e07 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_top/dml_top.c
@@ -96,10 +96,15 @@ bool dml2_check_mode_supported(struct 
dml2_check_mode_supported_in_out *in_out)
 {
struct dml2_instance *dml = (struct dml2_instance 
*)in_out->dml2_instance;
struct dml2_check_mode_supported_locals *l = 
&dml->scratch.check_mode_supported_locals;
+   /* Borrow the build_mode_programming_locals programming struct for DPMM 
call. */
+   struct dml2_display_cfg_programming *dpmm_programming = 
dml->scratch.build_mode_programming_locals.mode_programming_params.programming;
 
bool result = false;
bool mcache_success = false;
 
+   if (dpmm_programming)
+   memset(dpmm_programming, 0, sizeof(struct 
dml2_display_cfg_programming));
+
setup_unoptimized_display_config_with_meta(dml, 
&l->base_display_config_with_meta, in_out->display_config);
 
l->mode_support_params.instance = &dml->core_instance;
@@ -122,6 +127,18 @@ bool dml2_check_mode_supported(struct 
dml2_check_mode_supported_in_out *in_out)
mcache_success = 
dml2_top_optimization_perform_optimization_phase(&l->optimization_phase_locals, 
&mcache_phase);
}
 
+   /*
+* Call DPMM to map all requirements to minimum clock state
+*/
+   if (result && dpmm_programming) {
+   l->dppm_map_mode_params.min_clk_table = &dml->min_clk_table;
+   l->dppm_map_mode_params.display_cfg = 
&l->base_display_config_with_meta;
+   l->dppm_map_mode_params.programming = dpmm_programming;
+   l->dppm_map_mode_params.soc_bb = &dml->soc_bbox;
+   l->dppm_map_mode_params.ip = 
&dml->core_instance.clean_me_up.mode_lib.ip;
+   result = 
dml->dpmm_instance.map_mode_to_soc_dpm(&l->dppm_map_mode_params);
+   }
+
in_out->is_supported = mcache_success;
result = result && in_out->is_supported;
 
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_internal_shared_types.h
 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_internal_shared_types.h
index dd90c5df5a5a..5632cdacb7f4 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_internal_shared_types.h
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/inc/dml2_internal_shared_types.h
@@ -870,6 +870,7 @@ struct dml2_check_mode_supported_locals {
struct dml2_optimization_phase_locals optimization_phase_locals;
struct display_configuation_with_meta base_display_config_with_meta;
struct display_configuation_with_meta 
optimized_display_config_with_meta;
+   struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out dppm_map_mode_params;
 };
 
 struct optimization_init_function_params {
-- 
2.34.1



[PATCH 18/39] drm/amd/display: resync OTG after DIO FIFO resync

2024-06-20 Thread Alex Hung
From: TungYu Lu 

[WHY]
Tiled displays showed not aligned on 8K60hz when system resumed
from S3/S4.

[HOW]
Do dc_trigger_sync to re-sync pipes to ensure OTG become synced.

Reviewed-by: Alvin Lee 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: TungYu Lu 
---
 drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
index bdbb4a71651f..fe62478fbcde 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
@@ -1254,6 +1254,8 @@ void dcn32_resync_fifo_dccg_dio(struct dce_hwseq *hws, 
struct dc *dc, struct dc_

pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
}
}
+
+   dc_trigger_sync(dc, dc->current_state);
 }
 
 void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx,
-- 
2.34.1



[PATCH 17/39] drm/amd/display: Always enable HPO for DCN4 dGPU

2024-06-20 Thread Alex Hung
From: "Leo (Hanghong) Ma" 

[WHY && HOW]
Some DP EDID CTS tests fail due to HPO disable, and we should keep it
enable on DCN4 dGPU.

Reviewed-by: Wenjing Liu 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Leo (Hanghong) Ma 
---
 drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 2 ++
 drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c  | 1 -
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 42753f56d31d..79a911e1a09a 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -408,6 +408,8 @@ void dcn401_init_hw(struct dc *dc)
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
}
 
+   dcn401_setup_hpo_hw_control(hws, true);
+
if (!dcb->funcs->is_accelerated_mode(dcb) && 
dc->res_pool->hubbub->funcs->init_watermarks)

dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
 
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
index 1cf0608e1980..8159fd838dc3 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c
@@ -137,7 +137,6 @@ static const struct hwseq_private_funcs 
dcn401_private_funcs = {
.program_mall_pipe_config = dcn32_program_mall_pipe_config,
.update_force_pstate = dcn32_update_force_pstate,
.update_mall_sel = dcn32_update_mall_sel,
-   .setup_hpo_hw_control = dcn401_setup_hpo_hw_control,
.calculate_dccg_k1_k2_values = NULL,
.apply_single_controller_ctx_to_hw = 
dce110_apply_single_controller_ctx_to_hw,
.reset_back_end_for_pipe = dcn20_reset_back_end_for_pipe,
-- 
2.34.1



[PATCH 16/39] drm/amd/display: Use sw cursor for DCN401 with rotation

2024-06-20 Thread Alex Hung
From: Aurabindo Pillai 

[WHAT & HOW]
On DCN401, the cursor composition to the plane happens after scaler.
So the cursor isn't stretched with the rest of the surface. Temporarily
disable hardware cursor in case when hardware rotation is enabled
such that userspace falls back to software cursor.

Reviewed-by: Sun peng Li 
Reviewed-by: Rodrigo Siqueira 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Aurabindo Pillai 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 34 ---
 1 file changed, 29 insertions(+), 5 deletions(-)

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 590e899ae3d0..89e371f870b8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -11093,8 +11093,12 @@ static int dm_crtc_get_cursor_mode(struct 
amdgpu_device *adev,
int cursor_scale_w, cursor_scale_h;
int i;
 
-   /* Overlay cursor not supported on HW before DCN */
-   if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0) {
+   /* Overlay cursor not supported on HW before DCN
+* DCN401 does not have the cursor-on-scaled-plane or 
cursor-on-yuv-plane restrictions
+* as previous DCN generations, so enable native mode on DCN401 in 
addition to DCE
+*/
+   if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0 ||
+   amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) {
*cursor_mode = DM_CURSOR_NATIVE_MODE;
return 0;
}
@@ -11237,7 +11241,7 @@ static int amdgpu_dm_atomic_check(struct drm_device 
*dev,
struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
struct drm_plane *plane;
-   struct drm_plane_state *old_plane_state, *new_plane_state;
+   struct drm_plane_state *old_plane_state, *new_plane_state, 
*new_cursor_state;
enum dc_status status;
int ret, i;
bool lock_and_validation_needed = false;
@@ -11465,19 +11469,39 @@ static int amdgpu_dm_atomic_check(struct drm_device 
*dev,
drm_dbg_atomic(dev, "MPO enablement requested on 
crtc:[%p]\n", crtc);
}
 
-   /* Check cursor planes restrictions */
+   /* Check cursor restrictions */
for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
enum amdgpu_dm_cursor_mode required_cursor_mode;
+   int is_rotated, is_scaled;
 
/* Overlay cusor not subject to native cursor restrictions */
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
if (dm_new_crtc_state->cursor_mode == DM_CURSOR_OVERLAY_MODE)
continue;
 
+   /* Check if rotation or scaling is enabled on DCN401 */
+   if ((drm_plane_mask(crtc->cursor) & new_crtc_state->plane_mask) 
&&
+   amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 
1)) {
+   new_cursor_state = 
drm_atomic_get_new_plane_state(state, crtc->cursor);
+
+   is_rotated = new_cursor_state &&
+   ((new_cursor_state->rotation & 
DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_0);
+   is_scaled = new_cursor_state && 
((new_cursor_state->src_w >> 16 != new_cursor_state->crtc_w) ||
+   (new_cursor_state->src_h >> 16 != 
new_cursor_state->crtc_h));
+
+   if (is_rotated || is_scaled) {
+   drm_dbg_driver(
+   crtc->dev,
+   "[CRTC:%d:%s] cannot enable hardware 
cursor due to rotation/scaling\n",
+   crtc->base.id, crtc->name);
+   ret = -EINVAL;
+   goto fail;
+   }
+   }
+
/* If HW can only do native cursor, check restrictions again */
ret = dm_crtc_get_cursor_mode(adev, state, dm_new_crtc_state,
  &required_cursor_mode);
-
if (ret) {
drm_dbg_driver(crtc->dev,
   "[CRTC:%d:%s] Checking cursor mode 
failed\n",
-- 
2.34.1



[PATCH 15/39] drm/amd/display: Add Replay general cmd

2024-06-20 Thread Alex Hung
From: Joan Lee 

[WHY & HOW]
Driver side adding replay general cmd interface.
Replay general command will config at most two uint_32 parameters,
with a replay general command subtype to set relative configurations.

Reviewed-by: Nicholas Kazlauskas 
Acked-by: Alex Hung 
Signed-off-by: Joan Lee 
---
 drivers/gpu/drm/amd/display/dc/dc_types.h  |  1 +
 .../gpu/drm/amd/display/dc/dce/dmub_replay.c   | 18 +-
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 21f4af9ab096..c550e8997033 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -1036,6 +1036,7 @@ enum replay_FW_Message_type {
Replay_Set_Residency_Frameupdate_Timer,
Replay_Set_Pseudo_VTotal,
Replay_Disabled_Adaptive_Sync_SDP,
+   Replay_Set_General_Cmd,
 };
 
 union replay_error_status {
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c 
b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
index 5437ebd8bc21..2a21bcf5224f 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
@@ -346,13 +346,29 @@ static void dmub_replay_send_cmd(struct dmub_replay *dmub,
cmd.replay_disabled_adaptive_sync_sdp.header.sub_type =
DMUB_CMD__REPLAY_DISABLED_ADAPTIVE_SYNC_SDP;
cmd.replay_disabled_adaptive_sync_sdp.header.payload_bytes =
-   sizeof(struct dmub_rb_cmd_replay_set_pseudo_vtotal);
+   sizeof(struct 
dmub_rb_cmd_replay_disabled_adaptive_sync_sdp);
//Cmd Body
cmd.replay_disabled_adaptive_sync_sdp.data.panel_inst =
cmd_element->disabled_adaptive_sync_sdp_data.panel_inst;
cmd.replay_disabled_adaptive_sync_sdp.data.force_disabled =

cmd_element->disabled_adaptive_sync_sdp_data.force_disabled;
break;
+   case Replay_Set_General_Cmd:
+   //Header
+   cmd.replay_set_general_cmd.header.sub_type =
+   DMUB_CMD__REPLAY_SET_GENERAL_CMD;
+   cmd.replay_set_general_cmd.header.payload_bytes =
+   sizeof(struct dmub_rb_cmd_replay_set_general_cmd);
+   //Cmd Body
+   cmd.replay_set_general_cmd.data.panel_inst =
+   cmd_element->set_general_cmd_data.panel_inst;
+   cmd.replay_set_general_cmd.data.subtype =
+   cmd_element->set_general_cmd_data.subtype;
+   cmd.replay_set_general_cmd.data.param1 =
+   cmd_element->set_general_cmd_data.param1;
+   cmd.replay_set_general_cmd.data.param2 =
+   cmd_element->set_general_cmd_data.param2;
+   break;
case Replay_Msg_Not_Support:
default:
return;
-- 
2.34.1



[PATCH 14/39] drm/amd/display: Check HDCP returned status

2024-06-20 Thread Alex Hung
[WHAT & HOW]
Check mod_hdcp_execute_and_set() return values in authenticated_dp.

This fixes 3 CHECKED_RETURN issues reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Acked-by: Alex Hung 
Signed-off-by: Alex Hung 
---
 .../amd/display/modules/hdcp/hdcp1_execution.c| 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c 
b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
index 182e7532dda8..d77836cef563 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
@@ -433,17 +433,20 @@ static enum mod_hdcp_status authenticated_dp(struct 
mod_hdcp *hdcp,
}
 
if (status == MOD_HDCP_STATUS_SUCCESS)
-   mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
+   if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
&input->bstatus_read, &status,
-   hdcp, "bstatus_read");
+   hdcp, "bstatus_read"))
+   goto out;
if (status == MOD_HDCP_STATUS_SUCCESS)
-   mod_hdcp_execute_and_set(check_link_integrity_dp,
+   if (!mod_hdcp_execute_and_set(check_link_integrity_dp,
&input->link_integrity_check, &status,
-   hdcp, "link_integrity_check");
+   hdcp, "link_integrity_check"))
+   goto out;
if (status == MOD_HDCP_STATUS_SUCCESS)
-   mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
+   if 
(!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
&input->reauth_request_check, &status,
-   hdcp, "reauth_request_check");
+   hdcp, "reauth_request_check"))
+   goto out;
 out:
return status;
 }
-- 
2.34.1



[PATCH 13/39] drm/amd/display: Check and log for function error codes

2024-06-20 Thread Alex Hung
[WHAT & HOW]
dm_dmub_hw_init and drm_dp_mst_topology_mgr_set_mst can return error
codes and errors should be reported.

This fixes 2 CHECKED_RETURN issues reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Acked-by: Alex Hung 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 -
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 5 -
 2 files changed, 8 insertions(+), 2 deletions(-)

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 60404385d4d0..590e899ae3d0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1302,6 +1302,7 @@ static void dm_dmub_hw_resume(struct amdgpu_device *adev)
struct dmub_srv *dmub_srv = adev->dm.dmub_srv;
enum dmub_status status;
bool init;
+   int r;
 
if (!dmub_srv) {
/* DMUB isn't supported on the ASIC. */
@@ -1319,7 +1320,9 @@ static void dm_dmub_hw_resume(struct amdgpu_device *adev)
DRM_WARN("Wait for DMUB auto-load failed: %d\n", 
status);
} else {
/* Perform the full hardware initialization. */
-   dm_dmub_hw_init(adev);
+   r = dm_dmub_hw_init(adev);
+   if (r)
+   DRM_ERROR("DMUB interface failed to initialize: 
status=%d\n", r);
}
 }
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 717d97191dda..62cb59f00929 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -3795,6 +3795,7 @@ static int trigger_hpd_mst_set(void *data, u64 val)
struct amdgpu_dm_connector *aconnector;
struct drm_connector *connector;
struct dc_link *link = NULL;
+   int ret;
 
if (val == 1) {
drm_connector_list_iter_begin(dev, &iter);
@@ -3806,7 +3807,9 @@ static int trigger_hpd_mst_set(void *data, u64 val)
dc_link_detect(aconnector->dc_link, 
DETECT_REASON_HPD);
mutex_unlock(&adev->dm.dc_lock);
 
-   
drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true);
+   ret = 
drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true);
+   if (ret < 0)
+   DRM_ERROR("DM_MST: Failed to set the 
device into MST mode!");
}
}
} else if (val == 0) {
-- 
2.34.1



[PATCH 12/39] drm/amd/display: Check and log for function error codes

2024-06-20 Thread Alex Hung
[WHAT & HOW]
BIOS_CMD_TABLE_REVISION and link_transmitter_control can return error
codes and errors should be reported.

This fixes 3 CHECKED_RETURN issues reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Acked-by: Alex Hung 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/bios/command_table2.c  | 3 ++-
 drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | 5 -
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c | 8 +++-
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c 
b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
index cc000833d300..4254bdfefe38 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
@@ -227,7 +227,8 @@ static void init_transmitter_control(struct bios_parser *bp)
uint8_t frev;
uint8_t crev = 0;
 
-   BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev);
+   if (!BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev))
+   BREAK_TO_DEBUGGER();
 
switch (crev) {
case 6:
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
index 136bd93c3b65..4a9d07c31bc5 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
@@ -1361,7 +1361,10 @@ void dce110_link_encoder_dp_set_lane_settings(
cntl.lane_settings = training_lane_set.raw;
 
/* call VBIOS table to set voltage swing and pre-emphasis */
-   link_transmitter_control(enc110, &cntl);
+   if (link_transmitter_control(enc110, &cntl) != BP_RESULT_OK) {
+   DC_LOG_ERROR("%s: Failed to execute VBIOS command 
table!\n", __func__);
+   BREAK_TO_DEBUGGER();
+   }
}
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
index 4d0eed7598b2..e0558a78b11c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
@@ -1104,6 +1104,7 @@ void dcn10_link_encoder_dp_set_lane_settings(
union dpcd_training_lane_set training_lane_set = { { 0 } };
int32_t lane = 0;
struct bp_transmitter_control cntl = { 0 };
+   enum bp_result result;
 
if (!link_settings) {
BREAK_TO_DEBUGGER();
@@ -1138,7 +1139,12 @@ void dcn10_link_encoder_dp_set_lane_settings(
cntl.lane_settings = training_lane_set.raw;
 
/* call VBIOS table to set voltage swing and pre-emphasis */
-   link_transmitter_control(enc10, &cntl);
+   result = link_transmitter_control(enc10, &cntl);
+
+   if (result != BP_RESULT_OK) {
+   DC_LOG_ERROR("%s: Failed to execute VBIOS command 
table!\n", __func__);
+   BREAK_TO_DEBUGGER();
+   }
}
 }
 
-- 
2.34.1



[PATCH 11/39] drm/amd/display: Remove useless function call

2024-06-20 Thread Alex Hung
[WHAT & HOW]
clk_mgr_helper_get_active_display_cnt returns display count and itself
alone has no use.

This fixes 1 CHECKED_RETURN issue reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Acked-by: Alex Hung 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c
index f77840dd051e..7920f6f1aa62 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn201/dcn201_clk_mgr.c
@@ -113,8 +113,6 @@ static void dcn201_update_clocks(struct clk_mgr 
*clk_mgr_base,
dcn2_read_clocks_from_hw_dentist(clk_mgr_base);
}
 
-   clk_mgr_helper_get_active_display_cnt(dc, context);
-
if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, 
clk_mgr_base->clks.phyclk_khz))
clk_mgr_base->clks.phyclk_khz = new_clocks->phyclk_khz;
 
-- 
2.34.1



[PATCH 10/39] drm/amd/display: Fix uninitialized variables in dcn401

2024-06-20 Thread Alex Hung
[WHAT & HOW]
surf_linear_128_l/c are used in CalculateBytePerPixelAndBlockSizes
before they are assigned, so initializing them before passing them into
the function.

This fixes 2 UNINIT issues reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Acked-by: Alex Hung 
Signed-off-by: Alex Hung 
---
 .../dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c| 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
index be73784e21eb..6f4026e396e0 100644
--- 
a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
+++ 
b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
@@ -11521,8 +11521,8 @@ void dml2_core_calcs_get_dpte_row_height(
unsigned int MacroTileWidthC;
unsigned int MacroTileHeightY;
unsigned int MacroTileHeightC;
-   bool surf_linear_128_l;
-   bool surf_linear_128_c;
+   bool surf_linear_128_l = false;
+   bool surf_linear_128_c = false;
 
CalculateBytePerPixelAndBlockSizes(
SourcePixelFormat,
-- 
2.34.1



[PATCH 09/39] drm/amd/display: Fix cursor size issues

2024-06-20 Thread Alex Hung
From: Nevenko Stupar 

[WHY & HOW]
Fix the cursor size between ODM slices.

Reviewed-by: Sridevi Arvindekar 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Nevenko Stupar 
---
 .../drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c  | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 0cf55f557c3c..42753f56d31d 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -1169,6 +1169,20 @@ void dcn401_set_cursor_position(struct pipe_ctx 
*pipe_ctx)
x_pos -= (prev_odm_width + prev_odm_offset);
}
 
+   /* If the position is negative then we need to add to the hotspot
+* to fix cursor size between ODM slices
+*/
+
+   if (x_pos < 0) {
+   pos_cpy.x_hotspot -= x_pos;
+   x_pos = 0;
+   }
+
+   if (y_pos < 0) {
+   pos_cpy.y_hotspot -= y_pos;
+   y_pos = 0;
+   }
+
pos_cpy.x = (uint32_t)x_pos;
pos_cpy.y = (uint32_t)y_pos;
 
-- 
2.34.1



[PATCH 08/39] drm/amd/display: Run DC_LOG_DC after checking link->link_enc

2024-06-20 Thread Alex Hung
[WHAT]
The DC_LOG_DC should be run after link->link_enc is checked, not before.

This fixes 1 REVERSE_INULL issue reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Acked-by: Alex Hung 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/link/link_factory.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c 
b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
index 8073fdae9cb1..8246006857b3 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
@@ -610,14 +610,14 @@ static bool construct_phy(struct dc_link *link,
link->link_enc =
link->dc->res_pool->funcs->link_enc_create(dc_ctx, 
&enc_init_data);
 
-   DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", 
link->link_enc->features.flags.bits.DP_IS_USB_C);
-   DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", 
link->link_enc->features.flags.bits.IS_DP2_CAPABLE);
-
if (!link->link_enc) {
DC_ERROR("Failed to create link encoder!\n");
goto link_enc_create_fail;
}
 
+   DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", 
link->link_enc->features.flags.bits.DP_IS_USB_C);
+   DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", 
link->link_enc->features.flags.bits.IS_DP2_CAPABLE);
+
/* Update link encoder tracking variables. These are used for the 
dynamic
 * assignment of link encoders to streams.
 */
-- 
2.34.1



[PATCH 07/39] drm/amd/display: Remove redundant checks for pipe_ctx->stream

2024-06-20 Thread Alex Hung
[WHAT & HOW]
The null checks for pipe_ctx->stream and pipe_ctx->stream_res.tg
are redundant as they were already dereferenced previously, as
reported by Coverity; therefore the null checks are removed.

This fixes 6 REVERSE_INULL issues reported by Coverity.

Reviewed-by: Rodrigo Siqueira 
Acked-by: Alex Hung 
Signed-off-by: Alex Hung 
---
 drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c| 7 +++
 drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c  | 4 ++--
 .../gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c  | 2 +-
 3 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
index 82d1ded09561..4d359bb9b1ec 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
@@ -974,8 +974,8 @@ enum dc_status dcn20_enable_stream_timing(
/* TODO enable stream if timing changed */
/* TODO unblank stream if DP */
 
-   if (pipe_ctx->stream && dc_state_get_pipe_subvp_type(context, pipe_ctx) 
== SUBVP_PHANTOM) {
-   if (pipe_ctx->stream_res.tg && 
pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable)
+   if (dc_state_get_pipe_subvp_type(context, pipe_ctx) == SUBVP_PHANTOM) {
+   if (pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable)

pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable(pipe_ctx->stream_res.tg);
}
 
@@ -1827,8 +1827,7 @@ static void dcn20_update_dchubp_dpp(
if (pipe_ctx->update_flags.bits.enable)
hubp->funcs->set_blank(hubp, false);
/* If the stream paired with this plane is phantom, the plane is also 
phantom */
-   if (pipe_ctx->stream && pipe_mall_type == SUBVP_PHANTOM
-   && hubp->funcs->phantom_hubp_post_enable)
+   if (pipe_mall_type == SUBVP_PHANTOM && 
hubp->funcs->phantom_hubp_post_enable)
hubp->funcs->phantom_hubp_post_enable(hubp);
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 8d0da56e4cc5..0cf55f557c3c 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -916,8 +916,8 @@ enum dc_status dcn401_enable_stream_timing(
/* TODO enable stream if timing changed */
/* TODO unblank stream if DP */
 
-   if (pipe_ctx->stream && dc_state_get_pipe_subvp_type(context, pipe_ctx) 
== SUBVP_PHANTOM) {
-   if (pipe_ctx->stream_res.tg && 
pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable)
+   if (dc_state_get_pipe_subvp_type(context, pipe_ctx) == SUBVP_PHANTOM) {
+   if (pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable)

pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable(pipe_ctx->stream_res.tg);
}
 
diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c 
b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
index 8d1a1cc94a8b..555c1c484cfd 100644
--- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
+++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
@@ -853,7 +853,7 @@ bool dp_set_test_pattern(
CRTC_STATE_VACTIVE);
 
if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable) {
-   if (pipe_ctx->stream && 
should_use_dmub_lock(pipe_ctx->stream->link)) {
+   if (should_use_dmub_lock(pipe_ctx->stream->link)) {
union dmub_hw_lock_flags hw_locks = { 0 };
struct dmub_hw_lock_inst_flags inst_flags = { 0 
};
 
-- 
2.34.1



[PATCH 06/39] drm/amd/display: Send DP_TOTAL_LTTPR_CNT during detection if LTTPR is present

2024-06-20 Thread Alex Hung
From: Michael Strauss 

[WHY]
New register field added in DP2.1 SCR, needed for auxless ALPM

[HOW]
Echo value read from 0xF0007 back to sink

Reviewed-by: Wenjing Liu 
Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Michael Strauss 
---
 .../amd/display/dc/link/protocols/link_dp_capability.c | 10 +-
 drivers/gpu/drm/amd/display/include/dpcd_defs.h|  5 +
 2 files changed, 14 insertions(+), 1 deletion(-)

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 00974c50e11f..f1cac74dd7f7 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
@@ -1605,9 +1605,17 @@ static bool retrieve_link_cap(struct dc_link *link)
return false;
}
 
-   if (dp_is_lttpr_present(link))
+   if (dp_is_lttpr_present(link)) {
configure_lttpr_mode_transparent(link);
 
+   // Echo TOTAL_LTTPR_CNT back downstream
+   core_link_write_dpcd(
+   link,
+   DP_TOTAL_LTTPR_CNT,
+   &link->dpcd_caps.lttpr_caps.phy_repeater_cnt,
+   
sizeof(link->dpcd_caps.lttpr_caps.phy_repeater_cnt));
+   }
+
/* Read DP tunneling information. */
status = dpcd_get_tunneling_device_data(link);
 
diff --git a/drivers/gpu/drm/amd/display/include/dpcd_defs.h 
b/drivers/gpu/drm/amd/display/include/dpcd_defs.h
index 914f28e9f224..aee5170f5fb2 100644
--- a/drivers/gpu/drm/amd/display/include/dpcd_defs.h
+++ b/drivers/gpu/drm/amd/display/include/dpcd_defs.h
@@ -177,4 +177,9 @@ enum dpcd_psr_sink_states {
 #define DP_SINK_PR_PIXEL_DEVIATION_PER_LINE 0x379
 #define DP_SINK_PR_MAX_NUMBER_OF_DEVIATION_LINE 0x37A
 
+/* Remove once drm_dp_helper.h is updated upstream */
+#ifndef DP_TOTAL_LTTPR_CNT
+#define DP_TOTAL_LTTPR_CNT  0xF000A /* 2.1 */
+#endif
+
 #endif /* __DAL_DPCD_DEFS_H__ */
-- 
2.34.1



[PATCH 05/39] drm/amd/display: Fix cursor issues with ODMs and HW rotations

2024-06-20 Thread Alex Hung
From: Nevenko Stupar 

[WHY & HOW]
Current code for cursor positions does not work properly
with different ODM options and HW rotations like ODM
2to1, 3to1 and 4to1, and has different issues depending on
angle of HW rotations.

[HOW]
Fixed these issues so to work properly when ODM is used with HW rotations.

Reviewed-by: Sridevi Arvindekar 
Acked-by: Alex Hung 
Signed-off-by: Nevenko Stupar 
---
 .../amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c |  50 ---
 .../amd/display/dc/hubp/dcn401/dcn401_hubp.c  |  38 -
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 135 +++---
 3 files changed, 19 insertions(+), 204 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c 
b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c
index aef73bd1221a..d0f8c9ff5232 100644
--- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c
+++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c
@@ -153,58 +153,8 @@ void dpp401_set_cursor_position(
uint32_t height)
 {
struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
-   int x_pos = pos->x - param->recout.x;
-   int y_pos = pos->y - param->recout.y;
-   int x_hotspot = pos->x_hotspot;
-   int y_hotspot = pos->y_hotspot;
-   int rec_x_offset = x_pos - pos->x_hotspot;
-   int rec_y_offset = y_pos - pos->y_hotspot;
-   int cursor_height = (int)height;
-   int cursor_width = (int)width;
uint32_t cur_en = pos->enable ? 1 : 0;
 
-   // Transform cursor width / height and hotspots for offset calculations
-   if (param->rotation == ROTATION_ANGLE_90 || param->rotation == 
ROTATION_ANGLE_270) {
-   swap(cursor_height, cursor_width);
-   swap(x_hotspot, y_hotspot);
-
-   if (param->rotation == ROTATION_ANGLE_90) {
-   // hotspot = (-y, x)
-   rec_x_offset = x_pos - (cursor_width - x_hotspot);
-   rec_y_offset = y_pos - y_hotspot;
-   } else if (param->rotation == ROTATION_ANGLE_270) {
-   // hotspot = (y, -x)
-   rec_x_offset = x_pos - x_hotspot;
-   rec_y_offset = y_pos - (cursor_height - y_hotspot);
-   }
-   } else if (param->rotation == ROTATION_ANGLE_180) {
-   // hotspot = (-x, -y)
-   if (!param->mirror)
-   rec_x_offset = x_pos - (cursor_width - x_hotspot);
-
-   rec_y_offset = y_pos - (cursor_height - y_hotspot);
-   }
-
-   if (param->rotation == ROTATION_ANGLE_0 && !param->mirror) {
-   if (rec_x_offset >= (int)param->recout.width)
-   cur_en = 0;  /* not visible beyond right edge*/
-
-   if (rec_y_offset >= (int)param->recout.height)
-   cur_en = 0;  /* not visible beyond bottom edge*/
-   } else {
-   if (rec_x_offset > (int)param->recout.width)
-   cur_en = 0;  /* not visible beyond right edge*/
-
-   if (rec_y_offset > (int)param->recout.height)
-   cur_en = 0;  /* not visible beyond bottom edge*/
-   }
-
-   if (rec_x_offset + cursor_width <= 0)
-   cur_en = 0;  /* not visible beyond left edge*/
-
-   if (rec_y_offset + cursor_height <= 0)
-   cur_en = 0;  /* not visible beyond top edge*/
-
REG_UPDATE(CURSOR0_CONTROL, CUR0_ENABLE, cur_en);
 
dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en;
diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c 
b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
index 6692d57d5cce..a893160ae775 100644
--- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c
@@ -654,12 +654,8 @@ void hubp401_cursor_set_position(
struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
int x_pos = pos->x - param->recout.x;
int y_pos = pos->y - param->recout.y;
-   int x_hotspot = pos->x_hotspot;
-   int y_hotspot = pos->y_hotspot;
int rec_x_offset = x_pos - pos->x_hotspot;
int rec_y_offset = y_pos - pos->y_hotspot;
-   int cursor_height = (int)hubp->curs_attr.height;
-   int cursor_width = (int)hubp->curs_attr.width;
uint32_t dst_x_offset;
uint32_t cur_en = pos->enable ? 1 : 0;
 
@@ -672,28 +668,6 @@ void hubp401_cursor_set_position(
if (hubp->curs_attr.address.quad_part == 0)
return;
 
-   // Transform cursor width / height and hotspots for offset calculations
-   if (param->rotation == ROTATION_ANGLE_90 || param->rotation == 
ROTATION_ANGLE_270) {
-   swap(cursor_height, cursor_width);
-   swap(x_hotspot, y_hotspot);
-
-   if (param->rotation 

[PATCH 04/39] drm/amd/display: Remove unnecessary variable

2024-06-20 Thread Alex Hung
From: Ivan Lipski 

[WHY]
Coverity analysis flagged this code as DEADCODE because
the condition '(!need_recovery)' is never true.

The variable 'need_recovery' is initialized as 'true',
is not assigned to 'false' anywhere before the
conditional statement.

Since the variable is only used for the conditional check,
but the check can never be true, the variable itself is
redundant.

[HOW]
Removed the variable 'need_recovery'.

Reviewed-by: Alex Hung 
Acked-by: Alex Hung 
Signed-off-by: Ivan Lipski 
---
 .../drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 17 -
 1 file changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
index 35151dd056cb..4ef329a4d764 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
@@ -1134,26 +1134,9 @@ static bool dcn10_hw_wa_force_recovery(struct dc *dc)
 {
struct hubp *hubp ;
unsigned int i;
-   bool need_recover = true;
 
if (!dc->debug.recovery_enabled)
return false;
-
-   for (i = 0; i < dc->res_pool->pipe_count; i++) {
-   struct pipe_ctx *pipe_ctx =
-   &dc->current_state->res_ctx.pipe_ctx[i];
-   if (pipe_ctx != NULL) {
-   hubp = pipe_ctx->plane_res.hubp;
-   if (hubp != NULL && 
hubp->funcs->hubp_get_underflow_status) {
-   if 
(hubp->funcs->hubp_get_underflow_status(hubp) != 0) {
-   /* one pipe underflow, we will reset 
all the pipes*/
-   need_recover = true;
-   }
-   }
-   }
-   }
-   if (!need_recover)
-   return false;
/*
DCHUBP_CNTL:HUBP_BLANK_EN=1
DCHUBBUB_SOFT_RESET:DCHUBBUB_GLOBAL_SOFT_RESET=1
-- 
2.34.1



[PATCH 03/39] drm/amd/display: Remove redundant var from display_rq_dig_calc in dml

2024-06-20 Thread Alex Hung
From: Ivan Lipski 

[WHY]
Coverity analysis flagged these files as containing DEADCODE, i. e.
redundant or unreachabale. In these files, variable 'mode_422' is
always the same file (0 or false), so any code logic with it is
redundant.

[HOW]
Removed 'mode_422' variable and all code with it from
'display_rq_dlg_calc_' functions in dml.

Reviewed-by: Alex Hung 
Acked-by: Alex Hung 
Signed-off-by: Ivan Lipski 
---
 .../display/dc/dml/dcn20/display_rq_dlg_calc_20.c  | 14 +++---
 .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c| 14 +++---
 .../display/dc/dml/dcn21/display_rq_dlg_calc_21.c  | 14 +++---
 .../display/dc/dml/dcn30/display_rq_dlg_calc_30.c  | 14 +++---
 .../display/dc/dml/dcn31/display_rq_dlg_calc_31.c  | 14 +++---
 .../dc/dml/dcn314/display_rq_dlg_calc_314.c| 14 +++---
 6 files changed, 18 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
index 07146569e335..7c56ad0f8812 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
@@ -688,12 +688,11 @@ static void get_surf_rq_param(struct display_mode_lib 
*mode_lib,
const display_pipe_source_params_st *pipe_src_param,
bool is_chroma)
 {
-   bool mode_422 = false;
unsigned int vp_width = 0;
unsigned int vp_height = 0;
unsigned int data_pitch = 0;
unsigned int meta_pitch = 0;
-   unsigned int ppe = mode_422 ? 2 : 1;
+   unsigned int ppe = 1;
 
// TODO check if ppe apply for both luma and chroma in 422 case
if (is_chroma) {
@@ -825,7 +824,6 @@ static void dml20_rq_dlg_get_dlg_params(struct 
display_mode_lib *mode_lib,
double min_dst_y_ttu_vblank;
unsigned int dlg_vblank_start;
bool dual_plane;
-   bool mode_422;
unsigned int access_dir;
unsigned int vp_height_l;
unsigned int vp_width_l;
@@ -971,7 +969,6 @@ static void dml20_rq_dlg_get_dlg_params(struct 
display_mode_lib *mode_lib,
// Source
 // dcc_en  = src.dcc;
dual_plane = is_dual_plane((enum 
source_format_class)(src->source_format));
-   mode_422 = false; // TODO
access_dir = (src->source_scan == dm_vert); // vp access direction: 
horizontal or vertical accessed
 //  bytes_per_element_l = 
get_bytes_per_element(source_format_class(src.source_format), 0);
 //  bytes_per_element_c = 
get_bytes_per_element(source_format_class(src.source_format), 1);
@@ -1148,13 +1145,8 @@ static void dml20_rq_dlg_get_dlg_params(struct 
display_mode_lib *mode_lib,
dpte_row_height_l = rq_dlg_param->rq_l.dpte_row_height;
dpte_row_height_c = rq_dlg_param->rq_c.dpte_row_height;
 
-   if (mode_422) {
-   swath_width_pixels_ub_l = swath_width_ub_l * 2;  // *2 for 2 
pixel per element
-   swath_width_pixels_ub_c = swath_width_ub_c * 2;
-   } else {
-   swath_width_pixels_ub_l = swath_width_ub_l * 1;
-   swath_width_pixels_ub_c = swath_width_ub_c * 1;
-   }
+   swath_width_pixels_ub_l = swath_width_ub_l;
+   swath_width_pixels_ub_c = swath_width_ub_c;
 
if (htaps_l <= 1)
min_hratio_fact_l = 2.0;
diff --git 
a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
index f4bba1f2aeb6..3d95bfa5aca2 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
@@ -688,12 +688,11 @@ static void get_surf_rq_param(struct display_mode_lib 
*mode_lib,
const display_pipe_source_params_st *pipe_src_param,
bool is_chroma)
 {
-   bool mode_422 = false;
unsigned int vp_width = 0;
unsigned int vp_height = 0;
unsigned int data_pitch = 0;
unsigned int meta_pitch = 0;
-   unsigned int ppe = mode_422 ? 2 : 1;
+   unsigned int ppe = 1;
 
// TODO check if ppe apply for both luma and chroma in 422 case
if (is_chroma) {
@@ -825,7 +824,6 @@ static void dml20v2_rq_dlg_get_dlg_params(struct 
display_mode_lib *mode_lib,
double min_dst_y_ttu_vblank;
unsigned int dlg_vblank_start;
bool dual_plane;
-   bool mode_422;
unsigned int access_dir;
unsigned int vp_height_l;
unsigned int vp_width_l;
@@ -972,7 +970,6 @@ static void dml20v2_rq_dlg_get_dlg_params(struct 
display_mode_lib *mode_lib,
// Source
 // dcc_en  = src.dcc;
dual_plane = is_dual_plane((enum 
source_format_class)(src->source_format));
-   mode_422 = false; // TODO
access_dir = (src->source_scan 

[PATCH 02/39] drm/amd/display: Refactor dccg401_get_other_enable_symclk_fe

2024-06-20 Thread Alex Hung
From: Relja Vojvodic 

[WHY]
Function was used to check the number of FEs connected to the current BE.
This was then used to determine if the symclk could be disabled, if all
FEs were disconnected. However, the function would skip over the primary
FE and return 0 when the primary FE was still connected. This caused black
screens on driver disable with an MST daisy chain hooked up.

[HOW]
Refactored the function to correctly return the number of FEs connected to
the input BE. Also renamed it for clarity.

Reviewed-by: Wenjing Liu 
Acked-by: Alex Hung 
Signed-off-by: Relja Vojvodic 
---
 .../amd/display/dc/dccg/dcn401/dcn401_dccg.c  | 57 +++
 1 file changed, 22 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c 
b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
index 6a467c49b4a4..07f1f396ba52 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
@@ -853,43 +853,30 @@ static void dccg401_enable_symclk_se(struct dccg *dccg, 
uint32_t stream_enc_inst
 }
 
 /*get other front end connected to this backend*/
-static uint8_t dccg401_get_other_enabled_symclk_fe(struct dccg *dccg, uint32_t 
stream_enc_inst, uint32_t link_enc_inst)
+static uint8_t dccg401_get_number_enabled_symclk_fe_connected_to_be(struct 
dccg *dccg, uint32_t link_enc_inst)
 {
uint8_t num_enabled_symclk_fe = 0;
-   uint32_t be_clk_en = 0, fe_clk_en[4] = {0}, be_clk_sel[4] = {0};
+   uint32_t fe_clk_en[4] = {0}, be_clk_sel[4] = {0};
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+   uint8_t i;
 
-   switch (link_enc_inst) {
-   case 0:
-   REG_GET_3(SYMCLKA_CLOCK_ENABLE, SYMCLKA_CLOCK_ENABLE, 
&be_clk_en,
-   SYMCLKA_FE_EN, &fe_clk_en[0],
-   SYMCLKA_FE_SRC_SEL, &be_clk_sel[0]);
-   break;
-   case 1:
-   REG_GET_3(SYMCLKB_CLOCK_ENABLE, SYMCLKB_CLOCK_ENABLE, 
&be_clk_en,
-   SYMCLKB_FE_EN, &fe_clk_en[1],
-   SYMCLKB_FE_SRC_SEL, &be_clk_sel[1]);
-   break;
-   case 2:
-   REG_GET_3(SYMCLKC_CLOCK_ENABLE, SYMCLKC_CLOCK_ENABLE, 
&be_clk_en,
-   SYMCLKC_FE_EN, &fe_clk_en[2],
-   SYMCLKC_FE_SRC_SEL, &be_clk_sel[2]);
-   break;
-   case 3:
-   REG_GET_3(SYMCLKD_CLOCK_ENABLE, SYMCLKD_CLOCK_ENABLE, 
&be_clk_en,
-   SYMCLKD_FE_EN, &fe_clk_en[3],
-   SYMCLKD_FE_SRC_SEL, &be_clk_sel[3]);
-   break;
-   }
-   if (be_clk_en) {
-   /* for DPMST, this backend could be used by multiple front end.
-   only disable the backend if this stream_enc_ins is the last active 
stream enc connected to this back_end*/
-   uint8_t i;
-   for (i = 0; i != link_enc_inst && i < ARRAY_SIZE(fe_clk_en); 
i++) {
-   if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst)
-   num_enabled_symclk_fe++;
-   }
+   REG_GET_2(SYMCLKA_CLOCK_ENABLE, SYMCLKA_FE_EN, &fe_clk_en[0],
+   SYMCLKA_FE_SRC_SEL, &be_clk_sel[0]);
+
+   REG_GET_2(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_EN, &fe_clk_en[1],
+   SYMCLKB_FE_SRC_SEL, &be_clk_sel[1]);
+
+   REG_GET_2(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_EN, &fe_clk_en[2],
+   SYMCLKC_FE_SRC_SEL, &be_clk_sel[2]);
+
+   REG_GET_2(SYMCLKD_CLOCK_ENABLE, SYMCLKD_FE_EN, &fe_clk_en[3],
+   SYMCLKD_FE_SRC_SEL, &be_clk_sel[3]);
+
+   for (i = 0; i < ARRAY_SIZE(fe_clk_en); i++) {
+   if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst)
+   num_enabled_symclk_fe++;
}
+
return num_enabled_symclk_fe;
 }
 
@@ -921,9 +908,9 @@ static void dccg401_disable_symclk_se(struct dccg *dccg, 
uint32_t stream_enc_ins
break;
}
 
-   /*check other enabled symclk fe */
-   num_enabled_symclk_fe = dccg401_get_other_enabled_symclk_fe(dccg, 
stream_enc_inst, link_enc_inst);
-   /*only turn off backend clk if other front end attachecd to this 
backend are all off,
+   /*check other enabled symclk fe connected to this be */
+   num_enabled_symclk_fe = 
dccg401_get_number_enabled_symclk_fe_connected_to_be(dccg, link_enc_inst);
+   /*only turn off backend clk if other front ends attached to this 
backend are all off,
 for mst, only turn off the backend if this is the last front end*/
if (num_enabled_symclk_fe == 0) {
switch (link_enc_inst) {
-- 
2.34.1



[PATCH 01/39] drm/amd/display: Temporarily disable HPO PG on DCN35

2024-06-20 Thread Alex Hung
From: Nicholas Susanto 

[WHY]
On hotpluggin a 4k144 HDMI FRL setup, display fails FRL link training
and falls back to TMDS which is caused by driver not ungating HPO before
doing FRL link training.

[HOW]
Enable debug flag to disable HPO power gate in DCN35

Reviewed-by: Nicholas Kazlauskas 
Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Nicholas Susanto 
---
 drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
index 0094ef223c5d..67ab8c1962ff 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
@@ -721,7 +721,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.disable_dpp_power_gate = true,
.disable_hubp_power_gate = true,
.disable_optc_power_gate = true, /*should the same as above two*/
-   .disable_hpo_power_gate = false, /*dmubfw force domain25 on*/
+   .disable_hpo_power_gate = true, /*dmubfw force domain25 on*/
.disable_clock_gate = false,
.disable_dsc_power_gate = true,
.vsr_support = true,
-- 
2.34.1



[PATCH 00/39] DC Patches June 20, 2024

2024-06-20 Thread Alex Hung
This DC patchset brings improvements in multiple areas. In summary, we 
highlight:

* Enable DCC on DCN401
* Fix cursor issues
* Misc Coverity fixes

Cc: Daniel Wheeler 

Alex Hung (12):
  drm/amd/display: Remove redundant checks for pipe_ctx->stream
  drm/amd/display: Run DC_LOG_DC after checking link->link_enc
  drm/amd/display: Fix uninitialized variables in dcn401
  drm/amd/display: Remove useless function call
  drm/amd/display: Check and log for function error codes
  drm/amd/display: Check and log for function error codes
  drm/amd/display: Check HDCP returned status
  drm/amd/display: Add null checks before accessing struct elements
  drm/amd/display: Ensure curve to hw translation succeed
  drm/amd/display: Validate function returns
  drm/amd/display: Remove always true condition
  drm/amd/display: Remove duplicate null check

Alvin Lee (2):
  drm/amd/display: Program CURSOR_DST_X_OFFSET in viewport space
  drm/amd/display: Wait for double buffer update on ODM changes

Aric Cyr (1):
  drm/amd/display: 3.2.290

Aurabindo Pillai (3):
  drm/amd/display: Use sw cursor for DCN401 with rotation
  drm/amd: Add reg definitions for DCN401 DCC
  drm/amd/display: Enable DCC on DCN401

Daniel Sa (1):
  drm/amd/display: Fix reduced resolution and refresh rate

Dillon Varone (1):
  drm/amd/display: Make DML2.1 P-State method force per stream

Duncan Ma (1):
  drm/amd/display: Reset DSC memory status

George Shen (1):
  drm/amd/display: Call dpmm when checking mode support

Ivan Lipski (2):
  drm/amd/display: Remove redundant var from display_rq_dig_calc in dml
  drm/amd/display: Remove unnecessary variable

Joan Lee (1):
  drm/amd/display: Add Replay general cmd

Leo (Hanghong) Ma (1):
  drm/amd/display: Always enable HPO for DCN4 dGPU

Michael Strauss (1):
  drm/amd/display: Send DP_TOTAL_LTTPR_CNT during detection if LTTPR is
present

Nevenko Stupar (3):
  drm/amd/display: Fix cursor issues with ODMs and HW rotations
  drm/amd/display: Fix cursor size issues
  drm/amd/display: Fix cursor issues with ODMs and magnification

Nicholas Susanto (1):
  drm/amd/display: Temporarily disable HPO PG on DCN35

Relja Vojvodic (2):
  drm/amd/display: Refactor dccg401_get_other_enable_symclk_fe
  drm/amd/display: Fix 1DLUT setting for NL SDR blending

Roman Li (1):
  drm/amd/display: Use periodic detection for ipx/headless

Ryan Seto (2):
  drm/amd/display: Add HW cursor visual confirm
  drm/amd/display: Adjust reg field for DSC wait for disconnect

Sung-huai Wang (1):
  drm/amd/display: Add workaround to restrict max frac urgent for DPM0

TungYu Lu (1):
  drm/amd/display: resync OTG after DIO FIFO resync

Wenjing Liu (1):
  drm/amd/display: Remove a redundant check in authenticated_dp

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  39 ++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c|  48 ++-
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |   5 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |   5 +-
 .../drm/amd/display/dc/bios/command_table2.c  |   3 +-
 .../dc/clk_mgr/dcn201/dcn201_clk_mgr.c|   2 -
 .../display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c  |  10 +-
 .../dc/clk_mgr/dcn401/dcn401_clk_mgr.c|  10 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  12 +
 .../drm/amd/display/dc/core/dc_hw_sequencer.c |  11 +
 .../gpu/drm/amd/display/dc/core/dc_stream.c   |  29 ++
 drivers/gpu/drm/amd/display/dc/dc.h   |   9 +-
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  |   7 +-
 drivers/gpu/drm/amd/display/dc/dc_types.h |   1 +
 .../amd/display/dc/dccg/dcn401/dcn401_dccg.c  |  57 ++--
 .../drm/amd/display/dc/dce/dce_link_encoder.c |   5 +-
 .../gpu/drm/amd/display/dc/dce/dmub_replay.c  |  18 +-
 .../amd/display/dc/dcn10/dcn10_link_encoder.c |   8 +-
 .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.c  |   2 +-
 .../dc/dml/dcn20/display_rq_dlg_calc_20.c |  14 +-
 .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c   |  14 +-
 .../dc/dml/dcn21/display_rq_dlg_calc_21.c |  14 +-
 .../dc/dml/dcn30/display_rq_dlg_calc_30.c |  14 +-
 .../dc/dml/dcn31/display_rq_dlg_calc_31.c |  14 +-
 .../dc/dml/dcn314/display_rq_dlg_calc_314.c   |  14 +-
 .../dc/dml2/dml21/dml21_translation_helper.c  |   2 +-
 .../amd/display/dc/dml2/dml21/dml21_wrapper.c |   4 +-
 .../src/dml2_core/dml2_core_dcn4_calcs.c  |   4 +-
 .../dc/dml2/dml21/src/dml2_top/dml_top.c  |  17 ++
 .../src/inc/dml2_internal_shared_types.h  |   1 +
 .../drm/amd/display/dc/dml2/dml2_wrapper.c|  29 +-
 .../drm/amd/display/dc/dml2/dml2_wrapper.h|   6 +-
 .../amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c |  50 
 .../drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c  |  24 +-
 .../drm/amd/display/dc/dsc/dcn20/dcn20_dsc.h  |  13 +-
 .../drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c  |  58 +++-
 .../amd/display/dc/dsc/dcn401/dcn401_dsc.c|   2 +-
 .../amd/display/dc/dsc/dcn401/dcn401_dsc.h|   3 +-
 .../display/dc/hubbub/dcn20/dcn20_hubbub.c|   3 +-
 .../display/dc/hubbub

[PATCH 20/20] drm/amd/display: 3.2.285

2024-05-08 Thread Alex Hung
From: Aric Cyr 

This version brings along following fixes:
- Read default boot options
- Find max flickerless instant vtotal delta
- Refactor dcn401_update_clocks
- Reduce I2C speed to 95kHz in DCN401
- Allow higher DSC slice support for small timings on dcn401
- Don't offload flip if not only address update
- Check UHBR13.5 cap when determining max link cap
- Enable SYMCLK gating in DCCG
- Expand to higher link rates
- Add left edge pixel for YCbCr422/420 + ODM pipe split
- Add resource interfaces for get ODM slice rect
- Add COEF filter types for DCN401
- Refactor DCN401 DCCG into component directory
- Fix 3dlut size for Fastloading on DCN401
- Fix write to non-existent reg on DCN401
- Remove USBC check for DCN32
- Remove unused code for some dc files
- Disable AC/DC codepath when unnecessary
- Create dcn401_clk_mgr struct

Acked-by: Alex Hung 
Signed-off-by: Aric Cyr 
---
 drivers/gpu/drm/amd/display/dc/dc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index d550b6f97039..a7ba80c84128 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -55,7 +55,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.284"
+#define DC_VER "3.2.285"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.34.1



[PATCH 19/20] drm/amd/display: Read default boot options

2024-05-08 Thread Alex Hung
From: Duncan Ma 

[WHY]
DPIA boot option is set by VBIOS. It gets
overwritten when driver loads DMU.

[HOW]
Read PreOS boot options and determine if
dpia is enabled.

Reviewed-by: Ovidiu Bunea 
Acked-by: Alex Hung 
Signed-off-by: Duncan Ma 
---
 drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c 
b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c
index 70e63aeb8f89..7f53074f4e48 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c
@@ -410,10 +410,13 @@ union dmub_fw_boot_options 
dmub_dcn35_get_fw_boot_option(struct dmub_srv *dmub)
 void dmub_dcn35_enable_dmub_boot_options(struct dmub_srv *dmub, const struct 
dmub_srv_hw_params *params)
 {
union dmub_fw_boot_options boot_options = {0};
+   union dmub_fw_boot_options cur_boot_options = {0};
+
+   cur_boot_options = dmub_dcn35_get_fw_boot_option(dmub);
 
boot_options.bits.z10_disable = params->disable_z10;
boot_options.bits.dpia_supported = params->dpia_supported;
-   boot_options.bits.enable_dpia = params->disable_dpia == true ? 0:1;
+   boot_options.bits.enable_dpia = cur_boot_options.bits.enable_dpia && 
!params->disable_dpia;
boot_options.bits.usb4_cm_version = params->usb4_cm_version;
boot_options.bits.dpia_hpd_int_enable_supported = 
params->dpia_hpd_int_enable_supported;
boot_options.bits.power_optimization = params->power_optimization;
-- 
2.34.1



[PATCH 18/20] drm/amd/display: Find max flickerless instant vtotal delta

2024-05-08 Thread Alex Hung
From: Ethan Bitnun 

[WHAT & HOW]
 - Populate dml 2 callback with get_max_flickerless_instant_vtotal_increase
 - Use long long when necessary to prevent overflow
 - Add asic specific default values, currently disabled by
   default for every asic
 - Use the pre-existing debug option to protect the call to
   get_max_flickerless_instant_vtotal_increase

Reviewed-by: Alvin Lee 
Acked-by: Alex Hung 
Signed-off-by: Ethan Bitnun 
---
 .../gpu/drm/amd/display/dc/core/dc_resource.c |  3 +
 .../gpu/drm/amd/display/dc/core/dc_stream.c   | 64 +--
 .../gpu/drm/amd/display/dc/dc_stream_priv.h   | 14 
 .../display/dc/dcn32/dcn32_resource_helpers.c |  2 +-
 .../drm/amd/display/dc/dml2/dml2_wrapper.h|  3 +
 5 files changed, 79 insertions(+), 7 deletions(-)

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 8a5cc8b80217..70c39eef99e5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -43,6 +43,8 @@
 #include "link.h"
 #include "clk_mgr.h"
 #include "dc_state_priv.h"
+#include "dc_stream_priv.h"
+
 #include "virtual/virtual_link_hwss.h"
 #include "link/hwss/link_hwss_dio.h"
 #include "link/hwss/link_hwss_dpia.h"
@@ -5195,6 +5197,7 @@ void resource_init_common_dml2_callbacks(struct dc *dc, 
struct dml2_configuratio
dml2_options->callbacks.get_dpp_pipes_for_plane = 
&resource_get_dpp_pipes_for_plane;
dml2_options->callbacks.get_stream_status = &dc_state_get_stream_status;
dml2_options->callbacks.get_stream_from_id = 
&dc_state_get_stream_from_id;
+   dml2_options->callbacks.get_max_flickerless_instant_vtotal_increase = 
&dc_stream_get_max_flickerless_instant_vtotal_increase;
 
dml2_options->svp_pstate.callbacks.dc = dc;
dml2_options->svp_pstate.callbacks.add_phantom_plane = 
&dc_state_add_phantom_plane;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index b5a89b587d86..de48084eac25 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -833,7 +833,7 @@ static int 
dc_stream_get_brightness_millinits_linear_interpolation (struct dc_st
 int index2,
 int 
refresh_hz)
 {
-   int slope = 0;
+   long long slope = 0;
if (stream->lumin_data.refresh_rate_hz[index2] != 
stream->lumin_data.refresh_rate_hz[index1]) {
slope = (stream->lumin_data.luminance_millinits[index2] - 
stream->lumin_data.luminance_millinits[index1]) /
(stream->lumin_data.refresh_rate_hz[index2] - 
stream->lumin_data.refresh_rate_hz[index1]);
@@ -852,7 +852,7 @@ static int dc_stream_get_refresh_hz_linear_interpolation 
(struct dc_stream_state
   int index2,
   int 
brightness_millinits)
 {
-   int slope = 1;
+   long long slope = 1;
if (stream->lumin_data.refresh_rate_hz[index2] != 
stream->lumin_data.refresh_rate_hz[index1]) {
slope = (stream->lumin_data.luminance_millinits[index2] - 
stream->lumin_data.luminance_millinits[index1]) /
(stream->lumin_data.refresh_rate_hz[index2] - 
stream->lumin_data.refresh_rate_hz[index1]);
@@ -860,7 +860,7 @@ static int dc_stream_get_refresh_hz_linear_interpolation 
(struct dc_stream_state
 
int y_intercept = stream->lumin_data.luminance_millinits[index2] - 
slope * stream->lumin_data.refresh_rate_hz[index2];
 
-   return ((brightness_millinits - y_intercept) / slope);
+   return ((int)div64_s64((brightness_millinits - y_intercept), slope));
 }
 
 /*
@@ -884,8 +884,9 @@ static int dc_stream_get_brightness_millinits_from_refresh 
(struct dc_stream_sta
 }
 
 /*
- * Finds the lowest refresh rate that can be achieved
- * from starting_refresh_hz while staying within flicker criteria
+ * Finds the lowest/highest refresh rate (depending on search_for_max_increase)
+ * that can be achieved from starting_refresh_hz while staying
+ * within flicker criteria
  */
 static int dc_stream_calculate_flickerless_refresh_rate(struct dc_stream_state 
*stream,
 int current_brightness,
@@ -942,7 +943,7 @@ static int 
dc_stream_calculate_flickerless_refresh_rate(struct dc_stream_state *
}
 
if (search_for_max_increase)
-   return 
stream->lumin_data.refresh_rate_hz[LUMINANCE_DATA_TABLE_SIZE - 1];
+   return (int)div64_s64((long 
long)stream->timing.pix_clk_100hz*100

[PATCH 17/20] drm/amd/display: Refactor dcn401_update_clocks

2024-05-08 Thread Alex Hung
From: Dillon Varone 

[WHY & HOW]
Refactor complex code into manageable functions. This also cleans up
some updating logics.

Reviewed-by: Alvin Lee 
Acked-by: Alex Hung 
Signed-off-by: Dillon Varone 
---
 .../amd/display/dc/clk_mgr/dcn401/dalsmc.h|   8 +-
 .../dc/clk_mgr/dcn401/dcn401_clk_mgr.c| 523 +-
 .../dc/clk_mgr/dcn401/dcn401_clk_mgr.h|  94 
 .../clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.c   |  80 ++-
 .../clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.h   |  10 +
 .../gpu/drm/amd/display/dc/core/dc_resource.c |   3 +-
 drivers/gpu/drm/amd/display/dc/dc.h   |   3 +
 .../gpu/drm/amd/display/include/dal_asic_id.h |   3 +
 8 files changed, 718 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dalsmc.h 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dalsmc.h
index 0d2584437934..5653c7991c62 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dalsmc.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dalsmc.h
@@ -36,7 +36,13 @@
 #define DALSMC_MSG_SetFclkSwitchAllow 0x11
 #define DALSMC_MSG_SetCabForUclkPstate0x12
 #define DALSMC_MSG_SetWorstCaseUclkLatency0x13
-#define DALSMC_Message_Count  0x14
+#define DALSMC_MSG_DcnExitReset   0x14
+#define DALSMC_MSG_ReturnHardMinStatus0x15
+#define DALSMC_MSG_SetAlwaysWaitDmcubResp 0x16
+#define DALSMC_MSG_IndicateDrrStatus  0x17  // PMFW 15811
+#define DALSMC_MSG_ActiveUclkFclk 0x18
+#define DALSMC_MSG_IdleUclkFclk   0x19
+#define DALSMC_Message_Count  0x1A
 
 typedef enum {
   FCLK_SWITCH_DISALLOW,
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
index bd74ff47fb37..d2abc00a60c5 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
@@ -67,6 +67,9 @@ static const struct clk_mgr_mask clk_mgr_mask_dcn401 = {
CLK_COMMON_MASK_SH_LIST_DCN401(_MASK)
 };
 
+#define TO_DCN401_CLK_MGR(clk_mgr)\
+   container_of(clk_mgr, struct dcn401_clk_mgr, base)
+
 static bool dcn401_is_ppclk_dpm_enabled(struct clk_mgr_internal *clk_mgr, 
PPCLK_e clk)
 {
bool ppclk_dpm_enabled = false;
@@ -112,6 +115,30 @@ static bool dcn401_is_ppclk_dpm_enabled(struct 
clk_mgr_internal *clk_mgr, PPCLK_
return ppclk_dpm_enabled;
 }
 
+static bool dcn401_is_ppclk_idle_dpm_enabled(struct clk_mgr_internal *clk_mgr, 
PPCLK_e clk)
+{
+   bool ppclk_idle_dpm_enabled = false;
+
+   switch (clk) {
+   case PPCLK_UCLK:
+   case PPCLK_FCLK:
+   if 
(ASICREV_IS_GC_12_0_0_A0(clk_mgr->base.ctx->asic_id.hw_internal_rev) &&
+   clk_mgr->smu_ver >= 0x681800) {
+   ppclk_idle_dpm_enabled = true;
+   } else if 
(ASICREV_IS_GC_12_0_1_A0(clk_mgr->base.ctx->asic_id.hw_internal_rev) &&
+   clk_mgr->smu_ver >= 0x661300) {
+   ppclk_idle_dpm_enabled = true;
+   }
+   break;
+   default:
+   ppclk_idle_dpm_enabled = false;
+   }
+
+   ppclk_idle_dpm_enabled &= clk_mgr->smu_present;
+
+   return ppclk_idle_dpm_enabled;
+}
+
 /* Query SMU for all clock states for a particular clock */
 static void dcn401_init_single_clock(struct clk_mgr_internal *clk_mgr, PPCLK_e 
clk, unsigned int *entry_0,
unsigned int *num_levels)
@@ -470,7 +497,7 @@ static void dcn401_update_clocks_update_dentist(
 
 }
 
-static void dcn401_update_clocks(struct clk_mgr *clk_mgr_base,
+static void dcn401_update_clocks_legacy(struct clk_mgr *clk_mgr_base,
struct dc_state *context,
bool safe_to_lower)
 {
@@ -512,7 +539,7 @@ static void dcn401_update_clocks(struct clk_mgr 
*clk_mgr_base,
 
if (clk_mgr->smu_present) {
if (enter_display_off == safe_to_lower)
-   dcn30_smu_set_num_of_displays(clk_mgr, display_count);
+   dcn401_smu_set_num_of_displays(clk_mgr, display_count);
 
clk_mgr_base->clks.fclk_prev_p_state_change_support = 
clk_mgr_base->clks.fclk_p_state_change_support;
 
@@ -542,7 +569,7 @@ static void dcn401_update_clocks(struct clk_mgr 
*clk_mgr_base,
if (should_set_clock(safe_to_lower, 
new_clocks->dcfclk_deep_sleep_khz, clk_mgr_base->clks.dcfclk_deep_sleep_khz)) {
clk_mgr_base->clks.dcfclk_deep_sleep_khz = 
new_clocks->dcfclk_deep_sleep_khz;
if (dcn401_is_ppclk_dpm_enabled(clk_mgr, PPCLK_DCFCLK))
-   dcn30_smu_set_min_deep_sleep_dcef_clk(clk_mgr, 
khz_to_mhz_ceil(clk_mgr_base->clks.dcfclk_deep_sleep_khz));
+  

[PATCH 16/20] drm/amd/display: Reduce I2C speed to 95kHz in DCN401

2024-05-08 Thread Alex Hung
From: Chris Park 

[WHY]
HW for DCN401 is presented with a small I2C speed fluctuation that
exceeds the hard cap limitation of 100kHz occasionally. This violates
compliance requirement and will result in failure in compliance.

[HOW]
After various measurements and traceback to previous generation HW, DCN IP,
SI and SW driver agrees that we can reduce I2C speed to 95kHz to address
the I2C spped fluctuation in DCN401.

Reviewed-by: Dillon Varone 
Acked-by: Alex Hung 
Signed-off-by: Chris Park 
---
 .../gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
index 75e2c62ae792..a55421363772 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
@@ -1772,8 +1772,8 @@ static bool dcn401_resource_construct(
pool->base.pipe_count = num_pipes;
pool->base.mpcc_count = num_pipes;
dc->caps.max_downscale_ratio = 600;
-   dc->caps.i2c_speed_in_khz = 100;
-   dc->caps.i2c_speed_in_khz_hdcp = 100; /*1.4 w/a applied by default*/
+   dc->caps.i2c_speed_in_khz = 95;
+   dc->caps.i2c_speed_in_khz_hdcp = 95; /*1.4 w/a applied by default*/
/* TODO: Bring max cursor size back to 256 after subvp cursor 
corruption is fixed*/
dc->caps.max_cursor_size = 64;
dc->caps.cursor_not_scaled = true;
-- 
2.34.1



[PATCH 15/20] drm/amd/display: Allow higher DSC slice support for small timings on dcn401

2024-05-08 Thread Alex Hung
From: Wenjing Liu 

[WHY]
DML2.1 has added the support to determine ODM combine based on DSC slice
count limitation. This support would allow us to support DSC slice higher
than 4 on small timings. The change will allow higher DSC slice support
independent from pixel clock in use.

[HOW]
Add a DCN401 get_enc_caps function to allow the support for DSC slice count
higher than 4.

Reviewed-by: Dillon Varone 
Acked-by: Alex Hung 
Signed-off-by: Wenjing Liu 
---
 .../amd/display/dc/dsc/dcn401/dcn401_dsc.c| 412 ++
 1 file changed, 39 insertions(+), 373 deletions(-)

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 845686d57919..52f23bb554af 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
@@ -9,6 +9,9 @@
 #include "dsc/dscc_types.h"
 #include "dsc/rc_calc.h"
 
+#define MAX_THROUGHPUT_PER_DSC_100HZ 2000
+#define MAX_DSC_UNIT_COMBINE 4
+
 static void dsc_write_to_registers(struct display_stream_compressor *dsc, 
const struct dsc_reg_values *reg_vals);
 
 /* Object I/F functions */
@@ -22,9 +25,10 @@ static void dsc401_enable(struct display_stream_compressor 
*dsc, int opp_pipe);
 static void dsc401_disable(struct display_stream_compressor *dsc);
 static void dsc401_disconnect(struct display_stream_compressor *dsc);
 static void dsc401_wait_disconnect_pending_clear(struct 
display_stream_compressor *dsc);
+static void dsc401_get_enc_caps(struct dsc_enc_caps *dsc_enc_caps, int 
pixel_clock_100Hz);
 
 const struct dsc_funcs dcn401_dsc_funcs = {
-   .dsc_get_enc_caps = dsc2_get_enc_caps,
+   .dsc_get_enc_caps = dsc401_get_enc_caps,
.dsc_read_state = dsc401_read_state,
.dsc_validate_stream = dsc401_validate_stream,
.dsc_set_config = dsc401_set_config,
@@ -48,9 +52,6 @@ const struct dsc_funcs dcn401_dsc_funcs = {
 #define DC_LOGGER \
dsc->ctx->logger
 
-#define DCN401_MAX_PIXEL_CLOCK_Mhz  1188
-#define DCN401_MAX_DISPLAY_CLOCK_Mhz1200
-
 enum dsc_bits_per_comp {
DSC_BPC_8 = 8,
DSC_BPC_10 = 10,
@@ -78,50 +79,40 @@ void dsc401_construct(struct dcn401_dsc *dsc,
dsc->max_image_width = 5184;
 }
 
-/* This returns the capabilities for a single DSC encoder engine. Number of 
slices and total throughput
- * can be doubled, tripled etc. by using additional DSC engines.
- */
-//static void dsc401_get_enc_caps(struct dsc_enc_caps *dsc_enc_caps, int 
pixel_clock_100Hz)
-//{
-// dsc_enc_caps->dsc_version = 0x21; /* v1.2 - DP spec defined it in 
reverse order and we kept it */
-//
-// /*dsc_enc_caps->slice_caps.bits.NUM_SLICES_1 = 1;
-// dsc_enc_caps->slice_caps.bits.NUM_SLICES_2 = 1;
-// dsc_enc_caps->slice_caps.bits.NUM_SLICES_3 = 1;
-// dsc_enc_caps->slice_caps.bits.NUM_SLICES_4 = 1;
-//
-// dsc_enc_caps->lb_bit_depth = 13;
-// dsc_enc_caps->is_block_pred_supported = true;
-//
-// 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_420 = 1;
-//
-// dsc_enc_caps->color_depth.bits.COLOR_DEPTH_8_BPC = 1;
-// dsc_enc_caps->color_depth.bits.COLOR_DEPTH_10_BPC = 1;
-// dsc_enc_caps->color_depth.bits.COLOR_DEPTH_12_BPC = 1;
-//
-// /* Maximum total throughput with all the slices combined. This is 
different from how DP spec specifies it.
-//  * Our decoder's total throughput in Pix/s is equal to DISPCLK. This is 
then shared between slices.
-//  * The value below is the absolute maximum value. The actual throughput 
may be lower, but it'll always
-//  * be sufficient to process the input pixel rate fed into a single DSC 
engine.
-//  */
-// /*dsc_enc_caps->max_total_throughput_mps = DCN401_MAX_DISPLAY_CLOCK_Mhz;
-//
-// /* For pixel clock bigger than a single-pipe limit we'll need two 
engines, which then doubles our
-//  * throughput and number of slices, but also introduces a lower limit 
of 2 slices
-//  */
-// /*if (pixel_clock_100Hz >= DCN401_MAX_PIXEL_CLOCK_Mhz*1) {
-// dsc_enc_caps->slice_caps.bits.NUM_SLICES_1 = 0;
-// dsc_enc_caps->slice_caps.bits.NUM_SLICES_8 = 1;
-// dsc_enc_caps->max_total_throughput_mps = 
DCN401_MAX_DISPLAY_CLOCK_Mhz * 2;
-// }
-//
-// dsc_enc_caps->max_slice_width = 5184; /* (including 64 overlap pixels 
for eDP MSO mode) */
-// /*dsc_enc_caps->bpp_increment_div = 16; /* 1/16th of a bit */
-//}
+static void dsc401_get_enc_caps(struct dsc_enc_caps *dsc_enc_caps, int 
pixel_clock_100Hz)
+{
+   int min_dsc_unit_required = (pixel_clock_100Hz + 
MAX_THROUGHPUT_PER_DSC_100HZ - 1) / MAX_

[PATCH 14/20] drm/amd/display: Don't offload flip if not only address update

2024-05-08 Thread Alex Hung
From: Alvin Lee 

[WHAT & HOW]
Fast updates can consist of some stream updates as well (i.e., out_csc).
In these cases we should not offload the flip to FW as we can only
offload address only updates to FW.

Reviewed-by: Chris Park 
Acked-by: Alex Hung 
Signed-off-by: Alvin Lee 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 0f20a3d96d93..0208b28517ac 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3664,6 +3664,10 @@ static void commit_planes_for_stream_fast(struct dc *dc,
break;
}
}
+   if (stream_update) {
+   /* more than address update, need to acquire FAMS2 lock 
*/
+   should_offload_fams2_flip = false;
+   }
}
 
dc_exit_ips_for_hw_access(dc);
-- 
2.34.1



[PATCH 13/20] drm/amd/display: Check UHBR13.5 cap when determining max link cap

2024-05-08 Thread Alex Hung
From: George Shen 

[WHY]
UHBR13.5 support is optional, even if UHBR20 is supported by the device.
If source supports max UHBR13.5 while sink, cable and LTTPR support
UHBR20 but not UHBR13.5, UHBR10 should be used as the max link cap.

Reviewed-by: Wenjing Liu 
Acked-by: Alex Hung 
Signed-off-by: George Shen 
---
 .../dc/link/protocols/link_dp_capability.c| 22 +++
 1 file changed, 18 insertions(+), 4 deletions(-)

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 8f57b344f09e..766116ec627d 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
@@ -2062,7 +2062,7 @@ struct dc_link_settings dp_get_max_link_cap(struct 
dc_link *link)
enum dc_link_rate lttpr_max_link_rate;
enum dc_link_rate cable_max_link_rate;
struct link_encoder *link_enc = NULL;
-
+   bool is_uhbr13_5_supported = true;
 
link_enc = link_enc_cfg_get_link_enc(link);
ASSERT(link_enc);
@@ -2083,6 +2083,9 @@ struct dc_link_settings dp_get_max_link_cap(struct 
dc_link *link)
max_link_cap.link_spread =
link->reported_link_cap.link_spread;
 
+   if (!link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR13_5)
+   is_uhbr13_5_supported = false;
+
/* Lower link settings based on cable attributes
 * Cable ID is a DP2 feature to identify max certified link rate that
 * a cable can carry. The cable identification method requires both
@@ -2101,9 +2104,13 @@ struct dc_link_settings dp_get_max_link_cap(struct 
dc_link *link)
cable_max_link_rate = get_cable_max_link_rate(link);
 
if (!link->dc->debug.ignore_cable_id &&
-   cable_max_link_rate != LINK_RATE_UNKNOWN &&
-   cable_max_link_rate < max_link_cap.link_rate)
-   max_link_cap.link_rate = cable_max_link_rate;
+   cable_max_link_rate != LINK_RATE_UNKNOWN) {
+   if (cable_max_link_rate < max_link_cap.link_rate)
+   max_link_cap.link_rate = cable_max_link_rate;
+
+   if (!link->dpcd_caps.cable_id.bits.UHBR13_5_CAPABILITY)
+   is_uhbr13_5_supported = false;
+   }
 
/* account for lttpr repeaters cap
 * notes: repeaters do not snoop in the DPRX Capabilities addresses 
(3.6.3).
@@ -2116,12 +2123,19 @@ struct dc_link_settings dp_get_max_link_cap(struct 
dc_link *link)
if (lttpr_max_link_rate < max_link_cap.link_rate)
max_link_cap.link_rate = lttpr_max_link_rate;
 
+   if 
(!link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR13_5)
+   is_uhbr13_5_supported = false;
+
DC_LOG_HW_LINK_TRAINING("%s\n Training with LTTPR,  max_lane 
count %d max_link rate %d \n",
__func__,
max_link_cap.lane_count,
max_link_cap.link_rate);
}
 
+   if (max_link_cap.link_rate == LINK_RATE_UHBR13_5 &&
+   !is_uhbr13_5_supported)
+   max_link_cap.link_rate = LINK_RATE_UHBR10;
+
if (link_dp_get_encoding_format(&max_link_cap) == DP_128b_132b_ENCODING 
&&
link->dc->debug.disable_uhbr)
max_link_cap.link_rate = LINK_RATE_HIGH3;
-- 
2.34.1



[PATCH 12/20] drm/amd/display: Enable SYMCLK gating in DCCG

2024-05-08 Thread Alex Hung
From: Daniel Miess 

[WHY & HOW]
Enable root clock optimization for SYMCLK and only
disable it when it's actively used.

Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Daniel Miess 
---
 drivers/gpu/drm/amd/display/dc/dc.h   |   1 +
 .../amd/display/dc/dccg/dcn35/dcn35_dccg.c| 102 ++
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c   |  45 +++-
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.h   |   2 +
 .../amd/display/dc/hwss/dcn35/dcn35_init.c|   1 +
 .../amd/display/dc/hwss/dcn351/dcn351_init.c  |   1 +
 .../display/dc/hwss/hw_sequencer_private.h|   4 +
 drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h  |   7 ++
 8 files changed, 115 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 2fce8c0303fa..eef2f357fe14 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -726,6 +726,7 @@ enum pg_hw_pipe_resources {
PG_DPSTREAM,
PG_HDMISTREAM,
PG_PHYSYMCLK,
+   PG_SYMCLK,
PG_HW_PIPE_RESOURCES_NUM_ELEMENT
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c 
b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c
index 1fc3aa2b507b..d3b27920e294 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c
@@ -655,9 +655,61 @@ static void dccg35_disable_symclk32_se(
}
 }
 
+static void dccg35_set_symclk_root_clock_gating(struct dccg *dccg, uint32_t 
stream_enc_inst,
+   uint32_t link_enc_inst, bool enable)
+{
+   struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+   switch (stream_enc_inst) {
+   case 0:
+   if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe)
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
SYMCLKA_FE_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   case 1:
+   if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe)
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
SYMCLKB_FE_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   case 2:
+   if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe)
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
SYMCLKC_FE_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   case 3:
+   if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe)
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
SYMCLKD_FE_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   case 4:
+   if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe)
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
SYMCLKE_FE_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   }
+
+   switch (link_enc_inst) {
+   case 0:
+   if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe)
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
SYMCLKA_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   case 1:
+   if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe)
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
SYMCLKB_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   case 2:
+   if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe)
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
SYMCLKC_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   case 3:
+   if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe)
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
SYMCLKD_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   case 4:
+   if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe)
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
SYMCLKE_ROOT_GATE_DISABLE, enable ? 1 : 0);
+   break;
+   }
+}
+
 void dccg35_init(struct dccg *dccg)
 {
-   int otg_inst;
+   int otg_inst, phy_inst;
/* Set HPO stream encoder to use refclk to avoid case where PHY is
 * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which
 * will cause DCN to hang.
@@ -671,10 +723,9 @@ void dccg35_init(struct dccg *dccg)
dccg31_set_symclk32_le_root_clock_gating(dccg, 
otg_inst, false);
}
 
-// if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
-// for (otg_inst = 0; otg_inst < 4; otg_inst++)
-// dccg35_disable_symclk_se(dccg, otg_inst, otg_inst);
-
+   if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe)
+   for (phy_inst = 0; phy_inst < 5; phy_inst++)

[PATCH 11/20] drm/amd/display: Expand to higher link rates

2024-05-08 Thread Alex Hung
From: Sung Joon Kim 

[WHY & HOW]
To support higher link rates that sink allows, we need to make
sure driver is ready and perform correct link-training sequence.

Reviewed-by: Wenjing Liu 
Acked-by: Alex Hung 
Signed-off-by: Sung Joon Kim 
---
 .../gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c | 3 +++
 1 file changed, 3 insertions(+)

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 107b2cec572d..8f57b344f09e 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
@@ -209,6 +209,9 @@ static enum dc_link_rate 
linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in
case 810:
link_rate = LINK_RATE_HIGH3;// Rate_9 (HBR3)- 8.10 Gbps/Lane
break;
+   case 1000:
+   link_rate = LINK_RATE_UHBR10;   // UHBR10 - 10.0 Gbps/Lane
+   break;
default:
link_rate = LINK_RATE_UNKNOWN;
break;
-- 
2.34.1



[PATCH 10/20] drm/amd/display: Add left edge pixel for YCbCr422/420 + ODM pipe split

2024-05-08 Thread Alex Hung
From: Wenjing Liu 

[WHY]
Currently 3-tap chroma subsampling is used for YCbCr422/420. When ODM
pipesplit is used, pixels on the left edge of ODM slices need one extra
pixel from the right edge of the previous slice to calculate the correct
chroma value.

Without this change, the chroma value is slightly different than
expected. This is usually imperceptible visually, but it impacts test
pattern CRCs for compliance test automation.

[HOW]
Update logic to use the register for adding extra left edge pixel for
YCbCr422/420 ODM cases.

Reviewed-by: George Shen 
Acked-by: Alex Hung 
Signed-off-by: Wenjing Liu 
---
 .../gpu/drm/amd/display/dc/core/dc_resource.c |  9 ++-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_opp.c  | 25 +--
 .../gpu/drm/amd/display/dc/dcn20/dcn20_opp.h  |  4 +-
 .../drm/amd/display/dc/dcn201/dcn201_opp.c|  1 +
 .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c   | 67 +--
 .../amd/display/dc/hwss/dcn314/dcn314_hwseq.c |  4 +-
 .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c   |  8 ++-
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c   |  4 +-
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 48 -
 drivers/gpu/drm/amd/display/dc/inc/hw/opp.h   |  7 +-
 .../amd/display/dc/inc/hw/timing_generator.h  |  2 +-
 .../amd/display/dc/optc/dcn20/dcn20_optc.c|  6 +-
 .../amd/display/dc/optc/dcn20/dcn20_optc.h|  2 +-
 .../amd/display/dc/optc/dcn30/dcn30_optc.c|  6 +-
 .../amd/display/dc/optc/dcn30/dcn30_optc.h|  2 +-
 .../amd/display/dc/optc/dcn31/dcn31_optc.c|  8 +--
 .../amd/display/dc/optc/dcn314/dcn314_optc.c  |  7 +-
 .../amd/display/dc/optc/dcn32/dcn32_optc.c|  7 +-
 .../amd/display/dc/optc/dcn35/dcn35_optc.c|  7 +-
 .../amd/display/dc/optc/dcn401/dcn401_optc.c  | 22 ++
 20 files changed, 140 insertions(+), 106 deletions(-)

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 fd03d7129ffa..fd624b1fee25 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -2110,12 +2110,19 @@ struct rect resource_get_odm_slice_src_rect(struct 
pipe_ctx *pipe_ctx)
struct rect odm_slice_dst;
struct rect odm_slice_src;
struct pipe_ctx *opp_head = resource_get_opp_head(pipe_ctx);
+   struct output_pixel_processor *opp = opp_head->stream_res.opp;
uint32_t left_edge_extra_pixel_count;
 
odm_slice_dst = resource_get_odm_slice_dst_rect(opp_head);
odm_slice_src = odm_slice_dst;
 
-   left_edge_extra_pixel_count = 0;
+   if (opp->funcs->opp_get_left_edge_extra_pixel_count)
+   left_edge_extra_pixel_count =
+   opp->funcs->opp_get_left_edge_extra_pixel_count(
+   opp, 
pipe_ctx->stream->timing.pixel_encoding,
+   resource_is_pipe_type(opp_head, 
OTG_MASTER));
+   else
+   left_edge_extra_pixel_count = 0;
 
odm_slice_src.x -= left_edge_extra_pixel_count;
odm_slice_src.width += left_edge_extra_pixel_count;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c
index fbf1b6370eb2..f5fe0cac7cb0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c
@@ -23,6 +23,7 @@
  *
  */
 
+#include "core_types.h"
 #include "dm_services.h"
 #include "dcn20_opp.h"
 #include "reg_helper.h"
@@ -350,19 +351,32 @@ bool opp2_dpg_is_pending(struct output_pixel_processor 
*opp)
return (dpg_en == 1 && double_buffer_pending == 1);
 }
 
-void opp2_program_left_edge_extra_pixel (
+void opp2_program_left_edge_extra_pixel(
struct output_pixel_processor *opp,
-   bool count)
+   enum dc_pixel_encoding pixel_encoding,
+   bool is_primary)
 {
struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
+   uint32_t count = opp2_get_left_edge_extra_pixel_count(opp, 
pixel_encoding, is_primary);
 
-   /* Specifies the number of extra left edge pixels that are supplied to
+   /*
+* Specifies the number of extra left edge pixels that are supplied to
 * the 422 horizontal chroma sub-sample filter.
-* Note that when left edge pixel is not "0", fmt pixel encoding can be 
in either 420 or 422 mode
-* */
+*/
REG_UPDATE(FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, count);
 }
 
+uint32_t opp2_get_left_edge_extra_pixel_count(struct output_pixel_processor 
*opp,
+   enum dc_pixel_encoding pixel_encoding, bool is_primary)
+{
+   if ((pixel_encoding == PIXEL_ENCODING_YCBCR422 || pixel_encoding == 
PIXEL_ENCODING_YCBCR420) &&
+   !opp->ctx->dc->debug.force_chroma_subsampling_1tap &&a

[PATCH 09/20] drm/amd/display: Add resource interfaces for get ODM slice rect

2024-05-08 Thread Alex Hung
From: Wenjing Liu 

[WHY]
We need an unified location to perform ODM slice rect calculation.

[HOW]
Add three interfaces for ODM slice rect/width calucaltion in resource.h

Reviewed-by: George Shen 
Acked-by: Alex Hung 
Signed-off-by: Wenjing Liu 
---
 .../gpu/drm/amd/display/dc/core/dc_resource.c | 137 ++
 drivers/gpu/drm/amd/display/dc/inc/resource.h |  10 ++
 2 files changed, 83 insertions(+), 64 deletions(-)

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 532882ee7b2b..fd03d7129ffa 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -816,37 +816,6 @@ static struct rect shift_rec(const struct rect *rec_in, 
int x, int y)
return rec_out;
 }
 
-static struct rect calculate_odm_slice_in_timing_active(struct pipe_ctx 
*pipe_ctx)
-{
-   const struct dc_stream_state *stream = pipe_ctx->stream;
-   int odm_slice_count = resource_get_odm_slice_count(pipe_ctx);
-   int odm_slice_idx = resource_get_odm_slice_index(pipe_ctx);
-   bool is_last_odm_slice = (odm_slice_idx + 1) == odm_slice_count;
-   int h_active = stream->timing.h_addressable +
-   stream->timing.h_border_left +
-   stream->timing.h_border_right;
-   int odm_slice_width = h_active / odm_slice_count;
-   struct rect odm_rec;
-   bool is_two_pixels_per_container =
-   
pipe_ctx->stream_res.tg->funcs->is_two_pixels_per_container(&stream->timing);
-
-   if ((odm_slice_width % 2) && is_two_pixels_per_container)
-   odm_slice_width++;
-
-   odm_rec.x = odm_slice_width * odm_slice_idx;
-   odm_rec.width = is_last_odm_slice ?
-   /* last slice width is the reminder of h_active */
-   h_active - odm_slice_width * (odm_slice_count - 1) :
-   /* odm slice width is the floor of h_active / count */
-   odm_slice_width;
-   odm_rec.y = 0;
-   odm_rec.height = stream->timing.v_addressable +
-   stream->timing.v_border_bottom +
-   stream->timing.v_border_top;
-
-   return odm_rec;
-}
-
 static struct rect calculate_plane_rec_in_timing_active(
struct pipe_ctx *pipe_ctx,
const struct rect *rec_in)
@@ -1134,7 +1103,7 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx)
 */
struct rect plane_clip;
struct rect mpc_slice_of_plane_clip;
-   struct rect odm_slice;
+   struct rect odm_slice_src;
struct rect overlapping_area;
 
plane_clip = calculate_plane_rec_in_timing_active(pipe_ctx,
@@ -1144,16 +1113,16 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx)
&pipe_ctx->stream->dst);
mpc_slice_of_plane_clip = calculate_mpc_slice_in_timing_active(
pipe_ctx, &plane_clip);
-   odm_slice = calculate_odm_slice_in_timing_active(pipe_ctx);
-   overlapping_area = intersect_rec(&mpc_slice_of_plane_clip, &odm_slice);
+   odm_slice_src = resource_get_odm_slice_src_rect(pipe_ctx);
+   overlapping_area = intersect_rec(&mpc_slice_of_plane_clip, 
&odm_slice_src);
if (overlapping_area.height > 0 &&
overlapping_area.width > 0) {
/* shift the overlapping area so it is with respect to current
-* ODM slice's position
+* ODM slice source's position
 */
pipe_ctx->plane_res.scl_data.recout = shift_rec(
&overlapping_area,
-   -odm_slice.x, -odm_slice.y);
+   -odm_slice_src.x, -odm_slice_src.y);
adjust_recout_for_visual_confirm(
&pipe_ctx->plane_res.scl_data.recout,
pipe_ctx);
@@ -1290,13 +1259,13 @@ static void calculate_inits_and_viewports(struct 
pipe_ctx *pipe_ctx)
struct rect recout_clip_in_active_timing;
struct rect recout_clip_in_recout_dst;
struct rect overlap_in_active_timing;
-   struct rect odm_slice = calculate_odm_slice_in_timing_active(pipe_ctx);
+   struct rect odm_slice_src = resource_get_odm_slice_src_rect(pipe_ctx);
int vpc_div = (data->format == PIXEL_FORMAT_420BPP8
|| data->format == PIXEL_FORMAT_420BPP10) ? 2 : 
1;
bool orthogonal_rotation, flip_vert_scan_dir, flip_horz_scan_dir;
 
recout_clip_in_active_timing = shift_rec(
-   &data->recout, odm_slice.x, odm_slice.y);
+   &data->recout, odm_slice_src.x, odm_slice_src.y);
recout_dst_in_active_timin

[PATCH 08/20] drm/amd/display: Add COEF filter types for DCN401

2024-05-08 Thread Alex Hung
From: Samson Tam 

Add VERTICAL_BLUR_SCALE & HORIZONTAL_BLUR_SCALE types.

Reviewed-by: Jun Lei 
Acked-by: Alex Hung 
Signed-off-by: Samson Tam 
---
 drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c 
b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c
index 696ccf96b847..d9a08cd160b3 100644
--- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c
+++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_dscl.c
@@ -56,7 +56,9 @@ enum dcn401_coef_filter_type_sel {
SCL_COEF_CHROMA_VERT_FILTER = 2,
SCL_COEF_CHROMA_HORZ_FILTER = 3,
SCL_COEF_ALPHA_VERT_FILTER = 4,
-   SCL_COEF_ALPHA_HORZ_FILTER = 5
+   SCL_COEF_ALPHA_HORZ_FILTER = 5,
+   SCL_COEF_VERTICAL_BLUR_SCALE = SCL_COEF_ALPHA_VERT_FILTER,
+   SCL_COEF_HORIZONTAL_BLUR_SCALE = SCL_COEF_ALPHA_HORZ_FILTER
 };
 
 enum dscl_autocal_mode {
-- 
2.34.1



[PATCH 07/20] drm/amd/display: Refactor DCN401 DCCG into component directory

2024-05-08 Thread Alex Hung
From: Revalla Hari Krishna 

[WHY]
Clean up the code that requires dccg to be in its own component.

[HOW]
Move all files under newly created dccg dir and fix the makefiles.

Acked-by: Alex Hung 
Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Revalla Hari Krishna 
---
 drivers/gpu/drm/amd/display/dc/dccg/Makefile   | 7 ++-
 .../gpu/drm/amd/display/dc/{ => dccg}/dcn401/dcn401_dccg.c | 0
 .../gpu/drm/amd/display/dc/{ => dccg}/dcn401/dcn401_dccg.h | 0
 drivers/gpu/drm/amd/display/dc/dcn401/Makefile | 1 -
 4 files changed, 6 insertions(+), 2 deletions(-)
 rename drivers/gpu/drm/amd/display/dc/{ => dccg}/dcn401/dcn401_dccg.c (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => dccg}/dcn401/dcn401_dccg.h (100%)

diff --git a/drivers/gpu/drm/amd/display/dc/dccg/Makefile 
b/drivers/gpu/drm/amd/display/dc/dccg/Makefile
index bfdce98768f1..1d5cf0f8e79d 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dccg/Makefile
@@ -95,4 +95,9 @@ AMD_DAL_DCCG_DCN35 = $(addprefix 
$(AMDDALPATH)/dc/dccg/dcn35/,$(DCCG_DCN35))
 AMD_DISPLAY_FILES += $(AMD_DAL_DCCG_DCN35)
 
 ###
-endif
\ No newline at end of file
+DCCG_DCN401 = dcn401_dccg.o
+
+AMD_DAL_DCCG_DCN401 = $(addprefix $(AMDDALPATH)/dc/dccg/dcn401/,$(DCCG_DCN401))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_DCCG_DCN401)
+endif
diff --git a/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_dccg.c 
b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn401/dcn401_dccg.c
rename to drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c
diff --git a/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_dccg.h 
b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.h
similarity index 100%
rename from drivers/gpu/drm/amd/display/dc/dcn401/dcn401_dccg.h
rename to drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.h
diff --git a/drivers/gpu/drm/amd/display/dc/dcn401/Makefile 
b/drivers/gpu/drm/amd/display/dc/dcn401/Makefile
index 2e15e639194d..73544559f41f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn401/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn401/Makefile
@@ -6,7 +6,6 @@ DCN401 += dcn401_dio_link_encoder.o
 DCN401 += dcn401_dio_stream_encoder.o
 DCN401 += dcn401_hubp.o
 DCN401 += dcn401_mpc.o
-DCN401 += dcn401_dccg.o
 DCN401 += dcn401_hubbub.o
 
 AMD_DAL_DCN401 = $(addprefix $(AMDDALPATH)/dc/dcn401/,$(DCN401))
-- 
2.34.1



[PATCH 06/20] drm/amd/display: Fix 3dlut size for Fastloading on DCN401

2024-05-08 Thread Alex Hung
From: Adam Nelson 

[WHY]
After a non-3dlut test the MPCC_MCM_3DLUT_MODE::MPCC_MCM_3DLUT_SIZE is
incorrect.

[HOW]
Add register write to make valid.

Acked-by: Alex Hung 
Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Adam Nelson 
---
 drivers/gpu/drm/amd/display/dc/dcn401/dcn401_mpc.c| 8 
 drivers/gpu/drm/amd/display/dc/dcn401/dcn401_mpc.h| 5 +
 drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 3 +++
 drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h   | 1 +
 4 files changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_mpc.c 
b/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_mpc.c
index d6c99c6c2b35..37ab5a4eefc7 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_mpc.c
@@ -297,6 +297,13 @@ void mpc401_program_lut_read_write_control(struct mpc 
*mpc, const enum MCM_LUT_I
}
 }
 
+void mpc401_program_3dlut_size(struct mpc *mpc, bool is_17x17x17, int mpcc_id)
+{
+   struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
+
+   REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, 
is_17x17x17 ? 0 : 1);
+}
+
 static void program_gamut_remap(
struct mpc *mpc,
unsigned int mpcc_id,
@@ -615,6 +622,7 @@ static const struct mpc_funcs dcn401_mpc_funcs = {
.populate_lut = mpc401_populate_lut,
.program_lut_read_write_control = mpc401_program_lut_read_write_control,
.program_lut_mode = mpc401_program_lut_mode,
+   .program_3dlut_size = mpc401_program_3dlut_size,
 };
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_mpc.h 
b/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_mpc.h
index a8ef67695757..af44054c2477 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_mpc.h
@@ -221,6 +221,11 @@ void mpc401_program_lut_read_write_control(
bool lut_bank_a,
int mpcc_id);
 
+void mpc401_program_3dlut_size(
+   struct mpc *mpc,
+   bool is_17x17x17,
+   int mpcc_id);
+
 void mpc401_set_gamut_remap(
struct mpc *mpc,
int mpcc_id,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
index 3b74c4a9c2a8..5b87186598e6 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
@@ -478,6 +478,7 @@ void dcn401_populate_mcm_luts(struct dc *dc,
enum MCM_LUT_XABLE shaper_xable = MCM_LUT_DISABLE;
enum MCM_LUT_XABLE lut3d_xable = MCM_LUT_DISABLE;
enum MCM_LUT_XABLE lut1d_xable = MCM_LUT_DISABLE;
+   bool is_17x17x17 = true;
 
dcn401_get_mcm_lut_xable_from_pipe_ctx(dc, pipe_ctx, &shaper_xable, 
&lut3d_xable, &lut1d_xable);
 
@@ -543,6 +544,8 @@ void dcn401_populate_mcm_luts(struct dc *dc,
mpc->funcs->program_lut_read_write_control(mpc, 
MCM_LUT_3DLUT, lut_bank_a, mpcc_id);
if (mpc->funcs->program_lut_mode)
mpc->funcs->program_lut_mode(mpc, MCM_LUT_3DLUT, 
lut3d_xable, lut_bank_a, mpcc_id);
+   if (mpc->funcs->program_3dlut_size)
+   mpc->funcs->program_3dlut_size(mpc, is_17x17x17, 
mpcc_id);
if (hubp->funcs->hubp_program_3dlut_fl_addr)
hubp->funcs->hubp_program_3dlut_fl_addr(hubp, 
mcm_luts.lut3d_data.gpu_mem_params.addr);
switch (mcm_luts.lut3d_data.gpu_mem_params.layout) {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
index dd786600668f..34cf8efc5cb9 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
@@ -576,6 +576,7 @@ struct mpc_funcs {
void (*program_lut_read_write_control)(struct mpc *mpc, const enum 
MCM_LUT_ID id, bool lut_bank_a, int mpcc_id);
void (*program_lut_mode)(struct mpc *mpc, const enum MCM_LUT_ID id, 
const enum MCM_LUT_XABLE xable,
bool lut_bank_a, int mpcc_id);
+   void (*program_3dlut_size)(struct mpc *mpc, bool is_17x17x17, int 
mpcc_id);
 };
 
 #endif
-- 
2.34.1



[PATCH 05/20] drm/amd/display: Fix write to non-existent reg on DCN401

2024-05-08 Thread Alex Hung
From: Ilya Bakoulin 

DP_DSC_CNTL no longer exists on DCN401.

Acked-by: Alex Hung 
Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Ilya Bakoulin 
---
 .../dc/dcn401/dcn401_dio_stream_encoder.c | 20 +++
 1 file changed, 3 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_dio_stream_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_dio_stream_encoder.c
index 1c55ccede09b..090288305609 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_dio_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn401/dcn401_dio_stream_encoder.c
@@ -372,21 +372,6 @@ static void enc401_stream_encoder_dp_unblank(
link->dc->link_srv->dp_trace_source_sequence(link, 
DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
 }
 
-/* Set DSC-related configuration.
- *   dsc_mode: 0 disables DSC, other values enable DSC in specified format
- *   sc_bytes_per_pixel: DP_DSC_BYTES_PER_PIXEL removed in DCN3x
- *   dsc_slice_width: DP_DSC_SLICE_WIDTH removed in DCN3x
- */
-static void enc401_dp_set_dsc_config(struct stream_encoder *enc,
-   enum optc_dsc_mode dsc_mode,
-   uint32_t dsc_bytes_per_pixel,
-   uint32_t dsc_slice_width)
-{
-   struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
-
-   REG_UPDATE(DP_DSC_CNTL, DP_DSC_MODE, dsc_mode == OPTC_DSC_DISABLED ? 0 
: 1);
-}
-
 /* this function read dsc related register fields to be logged later in 
dcn10_log_hw_state
  * into a dcn_dsc_state struct.
  */
@@ -395,7 +380,8 @@ static void enc401_read_state(struct stream_encoder *enc, 
struct enc_state *s)
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 
//if dsc is enabled, continue to read
-   REG_GET(DP_DSC_CNTL, DP_DSC_MODE, &s->dsc_mode);
+   REG_GET(DP_PIXEL_FORMAT, PIXEL_ENCODING_TYPE, &s->dsc_mode);
+
if (s->dsc_mode) {
REG_GET(DP_GSP11_CNTL, DP_SEC_GSP11_LINE_NUM, 
&s->sec_gsp_pps_line_num);
 
@@ -770,7 +756,7 @@ static const struct stream_encoder_funcs 
dcn401_str_enc_funcs = {
.dp_get_pixel_format  = enc1_stream_encoder_dp_get_pixel_format,
 
.enc_read_state = enc401_read_state,
-   .dp_set_dsc_config = enc401_dp_set_dsc_config,
+   .dp_set_dsc_config = NULL,
.dp_set_dsc_pps_info_packet = enc3_dp_set_dsc_pps_info_packet,
.set_dynamic_metadata = enc401_set_dynamic_metadata,
.hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute,
-- 
2.34.1



[PATCH 04/20] drm/amd/display: Remove USBC check for DCN32

2024-05-08 Thread Alex Hung
From: Rodrigo Siqueira 

The CONNECTOR_ID_USBC check was removed to fix a regression, but it was
re-introduced by accident. This commit drops the USBC that causes the
regressions.

Acked-by: Alex Hung 
Signed-off-by: Rodrigo Siqueira 
---
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
index d9ff95cd2dbd..06907e8a4eda 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
@@ -252,9 +252,6 @@ void dcn32_link_encoder_construct(
 
enc10->base.features = *enc_features;
 
-   if (enc10->base.connector.id == CONNECTOR_ID_USBC)
-   enc10->base.features.flags.bits.DP_IS_USB_C = 1;
-
enc10->base.transmitter = init_data->transmitter;
 
/* set the flag to indicate whether driver poll the I2C data pin
-- 
2.34.1



[PATCH 03/20] drm/amd/display: Remove unused code for some dc files

2024-05-08 Thread Alex Hung
From: Rodrigo Siqueira 

Cleanup unused code in DC.

Acked-by: Alex Hung 
Signed-off-by: Rodrigo Siqueira 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 9 -
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 3 ---
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h | 4 
 3 files changed, 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index d19c67205de6..0f20a3d96d93 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3614,9 +3614,6 @@ static void 
commit_plane_for_stream_offload_fams2_flip(struct dc *dc,
for (i = 0; i < surface_count; i++) {
struct dc_plane_state *plane_state = srf_updates[i].surface;
 
-   /* set offload flag so driver does not program address */
-   plane_state->address.offload_flip = true;
-
for (j = 0; j < dc->res_pool->pipe_count; j++) {
struct pipe_ctx *pipe_ctx = 
&context->res_ctx.pipe_ctx[j];
 
@@ -3638,12 +3635,6 @@ static void 
commit_plane_for_stream_offload_fams2_flip(struct dc *dc,
stream,
srf_updates,
surface_count);
-
-   /* reset offload flip flag */
-   for (i = 0; i < surface_count; i++) {
-   struct dc_plane_state *plane_state = srf_updates[i].surface;
-   plane_state->address.offload_flip = false;
-   }
 }
 
 static void commit_planes_for_stream_fast(struct dc *dc,
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index 226285037b2b..959ae0df1e56 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -125,9 +125,6 @@ struct dc_plane_address {
union large_integer page_table_base;
 
uint8_t vmid;
-   /* dc should use hw flip queue rather than directly programming the 
surface address.
-* Value is determined on each flip. */
-   bool offload_flip;
 };
 
 struct dc_size {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h
index 54f889cfd911..ce93003dae01 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h
@@ -1091,10 +1091,6 @@ void mpc3_power_on_ogam_lut(
 
 void mpc3_init_mpcc(struct mpcc *mpcc, int mpcc_inst);
 
-void mpc3_mpc_init_single_inst(
-   struct mpc *mpc,
-   unsigned int mpcc_id);
-
 enum dc_lut_mode mpc3_get_ogam_current(
struct mpc *mpc,
int mpcc_id);
-- 
2.34.1



[PATCH 02/20] drm/amd/display: Disable AC/DC codepath when unnecessary

2024-05-08 Thread Alex Hung
From: Joshua Aberback 

[WHY]
If there are no DC clock limits present, or if the DC limits are the same
as the AC limits, we can disable the AC/DC codepath as there won't be any
validation differences between the two modes.

[HOW]
When all DC power mode clock limits are the same as the max clock
values, there won't be any difference between AC mode and DC mode. Zero
out DC limits that equal max and provide a new cap to indicate the
presence of any non-zero DC mode limit. In summary:
 - zero out DC limits that are the same as max clock value
 - new dc cap to indicate the presence of DC mode limits
 - set limits present if any clock has distinct AC and DC values from SMU

Acked-by: Alex Hung 
Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Joshua Aberback 
---
 .../dc/clk_mgr/dcn401/dcn401_clk_mgr.c| 28 ++-
 drivers/gpu/drm/amd/display/dc/dc.h   |  1 +
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 12 +++-
 3 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
index 1cf750cfed66..bd74ff47fb37 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
@@ -180,7 +180,6 @@ static void dcn401_build_wm_range_table(struct clk_mgr 
*clk_mgr)
 void dcn401_init_clocks(struct clk_mgr *clk_mgr_base)
 {
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
-   unsigned int num_levels;
struct clk_limit_num_entries *num_entries_per_clk = 
&clk_mgr_base->bw_params->clk_table.num_entries_per_clk;
unsigned int i;
 
@@ -208,34 +207,43 @@ void dcn401_init_clocks(struct clk_mgr *clk_mgr_base)

&clk_mgr_base->bw_params->clk_table.entries[0].dcfclk_mhz,
&num_entries_per_clk->num_dcfclk_levels);
clk_mgr_base->bw_params->dc_mode_limit.dcfclk_mhz = 
dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_DCFCLK);
+   if (num_entries_per_clk->num_dcfclk_levels && 
clk_mgr_base->bw_params->dc_mode_limit.dcfclk_mhz ==
+   
clk_mgr_base->bw_params->clk_table.entries[num_entries_per_clk->num_dcfclk_levels
 - 1].dcfclk_mhz)
+   clk_mgr_base->bw_params->dc_mode_limit.dcfclk_mhz = 0;
 
/* SOCCLK */
dcn401_init_single_clock(clk_mgr, PPCLK_SOCCLK,

&clk_mgr_base->bw_params->clk_table.entries[0].socclk_mhz,

&num_entries_per_clk->num_socclk_levels);
clk_mgr_base->bw_params->dc_mode_limit.socclk_mhz = 
dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_SOCCLK);
+   if (num_entries_per_clk->num_socclk_levels && 
clk_mgr_base->bw_params->dc_mode_limit.socclk_mhz ==
+   
clk_mgr_base->bw_params->clk_table.entries[num_entries_per_clk->num_socclk_levels
 - 1].socclk_mhz)
+   clk_mgr_base->bw_params->dc_mode_limit.socclk_mhz = 0;
 
/* DTBCLK */
if (!clk_mgr->base.ctx->dc->debug.disable_dtb_ref_clk_switch) {
dcn401_init_single_clock(clk_mgr, PPCLK_DTBCLK,

&clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz,
&num_entries_per_clk->num_dtbclk_levels);
-   clk_mgr_base->bw_params->dc_mode_limit.dtbclk_mhz =
-   dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, 
PPCLK_DTBCLK);
+   clk_mgr_base->bw_params->dc_mode_limit.dtbclk_mhz = 
dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_DTBCLK);
+   if (num_entries_per_clk->num_dtbclk_levels && 
clk_mgr_base->bw_params->dc_mode_limit.dtbclk_mhz ==
+   
clk_mgr_base->bw_params->clk_table.entries[num_entries_per_clk->num_dtbclk_levels
 - 1].dtbclk_mhz)
+   clk_mgr_base->bw_params->dc_mode_limit.dtbclk_mhz = 0;
}
 
/* DISPCLK */
dcn401_init_single_clock(clk_mgr, PPCLK_DISPCLK,

&clk_mgr_base->bw_params->clk_table.entries[0].dispclk_mhz,
&num_entries_per_clk->num_dispclk_levels);
-   num_levels = num_entries_per_clk->num_dispclk_levels;
clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz = 
dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_DISPCLK);
+   if (num_entries_per_clk->num_dispclk_levels && 
clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz ==
+   
clk_mgr_base->bw_params->clk_table.entries[num_entries_per_clk->num_dispclk_levels
 - 1].dispclk_mhz)
+   clk_mgr_base->bw_params->dc_mode_limit.dispcl

[PATCH 01/20] drm/amd/display: Create dcn401_clk_mgr struct

2024-05-08 Thread Alex Hung
From: Dillon Varone 

Create dcn401 specific structure to encapsulate version specific
variables.

Acked-by: Alex Hung 
Reviewed-by: Rodrigo Siqueira 
Signed-off-by: Dillon Varone 
---
 .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c  |  3 +--
 .../dc/clk_mgr/dcn401/dcn401_clk_mgr.c| 23 ---
 .../dc/clk_mgr/dcn401/dcn401_clk_mgr.h| 10 
 3 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
index 5f67d159e1e2..f770828df149 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
@@ -367,14 +367,13 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, 
struct pp_smu_funcs *p
break;
 
case AMDGPU_FAMILY_GC_12_0_0: {
-   struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), 
GFP_KERNEL);
+   struct clk_mgr_internal *clk_mgr = 
dcn401_clk_mgr_construct(ctx, dccg);
 
if (clk_mgr == NULL) {
BREAK_TO_DEBUGGER();
return NULL;
}
 
-   dcn401_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
return &clk_mgr->base;
}
break;
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
index 7db7446ad91f..1cf750cfed66 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
@@ -935,14 +935,18 @@ static struct clk_mgr_funcs dcn401_funcs = {
.is_smu_present = dcn401_is_smu_present,
 };
 
-void dcn401_clk_mgr_construct(
+struct clk_mgr_internal *dcn401_clk_mgr_construct(
struct dc_context *ctx,
-   struct clk_mgr_internal *clk_mgr,
-   struct pp_smu_funcs *pp_smu,
struct dccg *dccg)
 {
struct clk_log_info log_info = {0};
+   struct dcn401_clk_mgr *clk_mgr401 = kzalloc(sizeof(struct 
dcn401_clk_mgr), GFP_KERNEL);
+   struct clk_mgr_internal *clk_mgr;
+
+   if (!clk_mgr401)
+   return NULL;
 
+   clk_mgr = &clk_mgr401->base;
clk_mgr->base.ctx = ctx;
clk_mgr->base.funcs = &dcn401_funcs;
clk_mgr->regs = &clk_mgr_regs_dcn401;
@@ -987,11 +991,24 @@ void dcn401_clk_mgr_construct(
clk_mgr->smu_present = false;
 
clk_mgr->base.bw_params = kzalloc(sizeof(*clk_mgr->base.bw_params), 
GFP_KERNEL);
+   if (!clk_mgr->base.bw_params) {
+   BREAK_TO_DEBUGGER();
+   kfree(clk_mgr);
+   return NULL;
+   }
 
/* need physical address of table to give to PMFW */
clk_mgr->wm_range_table = dm_helpers_allocate_gpu_mem(clk_mgr->base.ctx,
DC_MEM_ALLOC_TYPE_GART, sizeof(WatermarksExternal_t),
&clk_mgr->wm_range_table_addr);
+   if (!clk_mgr->wm_range_table) {
+   BREAK_TO_DEBUGGER();
+   kfree(clk_mgr->base.bw_params);
+   return NULL;
+   }
+
+   return &clk_mgr401->base;
+
 }
 
 void dcn401_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.h 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.h
index 496540ec1950..dad203de0dd4 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.h
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.h
@@ -5,11 +5,13 @@
 #ifndef __DCN401_CLK_MGR_H_
 #define __DCN401_CLK_MGR_H_
 
+struct dcn401_clk_mgr {
+   struct clk_mgr_internal base;
+};
+
 void dcn401_init_clocks(struct clk_mgr *clk_mgr_base);
 
-void dcn401_clk_mgr_construct(struct dc_context *ctx,
-   struct clk_mgr_internal *clk_mgr,
-   struct pp_smu_funcs *pp_smu,
+struct clk_mgr_internal *dcn401_clk_mgr_construct(struct dc_context *ctx,
struct dccg *dccg);
 
 void dcn401_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr,
@@ -17,6 +19,4 @@ void dcn401_update_clocks_update_dpp_dto(struct 
clk_mgr_internal *clk_mgr,
 
 void dcn401_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr);
 
-
-
 #endif /* __DCN401_CLK_MGR_H_ */
-- 
2.34.1



[PATCH 00/20] DC Patches May 08, 2024

2024-05-08 Thread Alex Hung
This DC patchset brings improvements in multiple areas. In summary, we have:

* Fixes on DCN401, 3dlut and I2C
* Improvements on AC/DC, link rates, DSC and ODM slice rect and pipe
* Refactoring on code styles and unused code

Cc: Daniel Wheeler 

Adam Nelson (1):
  drm/amd/display: Fix 3dlut size for Fastloading on DCN401

Alvin Lee (1):
  drm/amd/display: Don't offload flip if not only address update

Aric Cyr (1):
  drm/amd/display: 3.2.285

Chris Park (1):
  drm/amd/display: Reduce I2C speed to 95kHz in DCN401

Daniel Miess (1):
  drm/amd/display: Enable SYMCLK gating in DCCG

Dillon Varone (2):
  drm/amd/display: Create dcn401_clk_mgr struct
  drm/amd/display: Refactor dcn401_update_clocks

Duncan Ma (1):
  drm/amd/display: Read default boot options

Ethan Bitnun (1):
  drm/amd/display: Find max flickerless instant vtotal delta

George Shen (1):
  drm/amd/display: Check UHBR13.5 cap when determining max link cap

Ilya Bakoulin (1):
  drm/amd/display: Fix write to non-existent reg on DCN401

Joshua Aberback (1):
  drm/amd/display: Disable AC/DC codepath when unnecessary

Revalla Hari Krishna (1):
  drm/amd/display: Refactor DCN401 DCCG into component directory

Rodrigo Siqueira (2):
  drm/amd/display: Remove unused code for some dc files
  drm/amd/display: Remove USBC check for DCN32

Samson Tam (1):
  drm/amd/display: Add COEF filter types for DCN401

Sung Joon Kim (1):
  drm/amd/display: Expand to higher link rates

Wenjing Liu (3):
  drm/amd/display: Add resource interfaces for get ODM slice rect
  drm/amd/display: Add left edge pixel for YCbCr422/420 + ODM pipe split
  drm/amd/display: Allow higher DSC slice support for small timings on
dcn401

 .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c  |   3 +-
 .../amd/display/dc/clk_mgr/dcn401/dalsmc.h|   8 +-
 .../dc/clk_mgr/dcn401/dcn401_clk_mgr.c| 574 +-
 .../dc/clk_mgr/dcn401/dcn401_clk_mgr.h| 104 +++-
 .../clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.c   |  80 ++-
 .../clk_mgr/dcn401/dcn401_clk_mgr_smu_msg.h   |  10 +
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  13 +-
 .../gpu/drm/amd/display/dc/core/dc_resource.c | 150 +++--
 .../gpu/drm/amd/display/dc/core/dc_stream.c   |  64 +-
 drivers/gpu/drm/amd/display/dc/dc.h   |   7 +-
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h  |   3 -
 .../gpu/drm/amd/display/dc/dc_stream_priv.h   |  14 +
 drivers/gpu/drm/amd/display/dc/dccg/Makefile  |   7 +-
 .../amd/display/dc/dccg/dcn35/dcn35_dccg.c| 102 ++--
 .../dc/{ => dccg}/dcn401/dcn401_dccg.c|   0
 .../dc/{ => dccg}/dcn401/dcn401_dccg.h|   0
 .../gpu/drm/amd/display/dc/dcn20/dcn20_opp.c  |  25 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_opp.h  |   4 +-
 .../drm/amd/display/dc/dcn201/dcn201_opp.c|   1 +
 .../gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h  |   4 -
 .../display/dc/dcn32/dcn32_dio_link_encoder.c |   3 -
 .../display/dc/dcn32/dcn32_resource_helpers.c |   2 +-
 .../gpu/drm/amd/display/dc/dcn401/Makefile|   1 -
 .../dc/dcn401/dcn401_dio_stream_encoder.c |  20 +-
 .../drm/amd/display/dc/dcn401/dcn401_mpc.c|   8 +
 .../drm/amd/display/dc/dcn401/dcn401_mpc.h|   5 +
 .../drm/amd/display/dc/dml2/dml2_wrapper.h|   3 +
 .../display/dc/dpp/dcn401/dcn401_dpp_dscl.c   |   4 +-
 .../amd/display/dc/dsc/dcn401/dcn401_dsc.c| 412 ++---
 .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c   |  67 +-
 .../amd/display/dc/hwss/dcn314/dcn314_hwseq.c |   4 +-
 .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c   |   8 +-
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c   |  49 +-
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.h   |   2 +
 .../amd/display/dc/hwss/dcn35/dcn35_init.c|   1 +
 .../amd/display/dc/hwss/dcn351/dcn351_init.c  |   1 +
 .../amd/display/dc/hwss/dcn401/dcn401_hwseq.c |  63 +-
 .../display/dc/hwss/hw_sequencer_private.h|   4 +
 drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h  |   7 +
 drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h   |   1 +
 drivers/gpu/drm/amd/display/dc/inc/hw/opp.h   |   7 +-
 .../amd/display/dc/inc/hw/timing_generator.h  |   2 +-
 drivers/gpu/drm/amd/display/dc/inc/resource.h |  10 +
 .../dc/link/protocols/link_dp_capability.c|  25 +-
 .../amd/display/dc/optc/dcn20/dcn20_optc.c|   6 +-
 .../amd/display/dc/optc/dcn20/dcn20_optc.h|   2 +-
 .../amd/display/dc/optc/dcn30/dcn30_optc.c|   6 +-
 .../amd/display/dc/optc/dcn30/dcn30_optc.h|   2 +-
 .../amd/display/dc/optc/dcn31/dcn31_optc.c|   8 +-
 .../amd/display/dc/optc/dcn314/dcn314_optc.c  |   7 +-
 .../amd/display/dc/optc/dcn32/dcn32_optc.c|   7 +-
 .../amd/display/dc/optc/dcn35/dcn35_optc.c|   7 +-
 .../amd/display/dc/optc/dcn401/dcn401_optc.c  |  22 +-
 .../dc/resource/dcn401/dcn401_resource.c  |   4 +-
 .../gpu/drm/amd/display/dmub/src/dmub_dcn35.c |   5 +-
 .../gpu/drm/amd/display/include/dal_asic_id.h |   3 +
 56 files changed, 1293 insertions(+), 668 deletions(-)
 rename drivers/gpu/drm/amd/display/dc/{ => dccg}/dcn401/dcn401_dccg.c (100%)
 rename drivers/gpu/drm/amd/displa

[PATCH 30/34] drm/amd/display: Backup and restore only on full updates

2024-02-28 Thread Alex Hung
From: Alvin Lee 

[WHY & HOW]
Since the backup and restore for plane and stream states has
a significant amount of data to copy, we will change the backup
and restore sequence to only take place during full updates.

We will also move the scratch memory to struct dc instead of dc_state
to avoid needing to allocate large amounts of memory every time
we create a new DC state.

Reviewed-by: Wenjing Liu 
Acked-by: Alex Hung 
Signed-off-by: Alvin Lee 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  10 +-
 .../gpu/drm/amd/display/dc/core/dc_state.c|   1 -
 drivers/gpu/drm/amd/display/dc/dc.h   | 164 ++
 .../gpu/drm/amd/display/dc/inc/core_types.h   |  22 ---
 4 files changed, 100 insertions(+), 97 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index d8967087335e..2105e4ba3384 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3162,9 +3162,10 @@ static bool update_planes_and_stream_state(struct dc *dc,
}
 
context = dc->current_state;
-   backup_planes_and_stream_state(&dc->current_state->scratch, stream);
update_type = dc_check_update_surfaces_for_stream(
dc, srf_updates, surface_count, stream_update, 
stream_status);
+   if (update_type == UPDATE_TYPE_FULL)
+   backup_planes_and_stream_state(&dc->scratch.current_state, 
stream);
 
/* update current stream with the new updates */
copy_stream_update_to_stream(dc, context, stream, stream_update);
@@ -3267,7 +3268,8 @@ static bool update_planes_and_stream_state(struct dc *dc,
 
*new_context = context;
*new_update_type = update_type;
-   backup_planes_and_stream_state(&context->scratch, stream);
+   if (update_type == UPDATE_TYPE_FULL)
+   backup_planes_and_stream_state(&dc->scratch.new_state, stream);
 
return true;
 
@@ -4321,7 +4323,7 @@ static bool 
commit_minimal_transition_based_on_current_context(struct dc *dc,
 * This restores back the original stream and plane states associated
 * with the current state.
 */
-   restore_planes_and_stream_state(&dc->current_state->scratch, stream);
+   restore_planes_and_stream_state(&dc->scratch.current_state, stream);
intermediate_context = create_minimal_transition_state(dc,
dc->current_state, &policy);
if (intermediate_context) {
@@ -4348,7 +4350,7 @@ static bool 
commit_minimal_transition_based_on_current_context(struct dc *dc,
 * Restore stream and plane states back to the values associated with
 * new context.
 */
-   restore_planes_and_stream_state(&new_context->scratch, stream);
+   restore_planes_and_stream_state(&dc->scratch.new_state, stream);
return success;
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_state.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
index 5cc7f8da209c..cce4e1c465b6 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_state.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
@@ -310,7 +310,6 @@ void dc_state_destruct(struct dc_state *state)
memset(state->dc_dmub_cmd, 0, sizeof(state->dc_dmub_cmd));
state->dmub_cmd_count = 0;
memset(&state->perf_params, 0, sizeof(state->perf_params));
-   memset(&state->scratch, 0, sizeof(state->scratch));
 }
 
 void dc_state_retain(struct dc_state *state)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 09c6a393642a..9629bd9252b4 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1004,76 +1004,6 @@ struct dc_current_properties {
unsigned int cursor_size_limit;
 };
 
-struct dc {
-   struct dc_debug_options debug;
-   struct dc_versions versions;
-   struct dc_caps caps;
-   struct dc_cap_funcs cap_funcs;
-   struct dc_config config;
-   struct dc_bounding_box_overrides bb_overrides;
-   struct dc_bug_wa work_arounds;
-   struct dc_context *ctx;
-   struct dc_phy_addr_space_config vm_pa_config;
-
-   uint8_t link_count;
-   struct dc_link *links[MAX_PIPES * 2];
-   struct link_service *link_srv;
-
-   struct dc_state *current_state;
-   struct resource_pool *res_pool;
-
-   struct clk_mgr *clk_mgr;
-
-   /* Display Engine Clock levels */
-   struct dm_pp_clock_levels sclk_lvls;
-
-   /* Inputs into BW and WM calculations. */
-   struct bw_calcs_dceip *bw_dceip;
-   struct bw_calcs_vbios *bw_vbios;
-   struct dcn_soc_bounding_box *dcn_soc;
-   struct dcn_ip_params *dcn_ip;
-   struct display_mode_lib dml;
-
-   /* HW functions */
-   struct hw_sequencer_funcs hwss;
-   struct dce_hwseq *hwseq;
-
-   /* Require t

[PATCH 34/34] drm/amd/display: 3.2.275

2024-02-28 Thread Alex Hung
From: Aric Cyr 

- Support long vblank feature
- Add monitor patch for specific eDP
- Init DPPCLK from SMU on dcn32
- Update odm when ODM combine is changed on an otg master pipe with
  no plane
- Fix idle check for shared firmware state
- Add guards for idle on reg read/write
- Guard cursor idle reallow by DC debug option
- Add debug counters to IPS exit prints
- Add left edge pixel for YCbCr422/420 + ODM pipe split
- Amend coasting vtotal for replay low hz
- Refactor DPP into a component directory
- Set the power_down_on_boot function pointer to null
- Implement update_planes_and_stream_v3 sequence
- Lock all enabled otg pipes even with no planes
- Implement wait_for_odm_update_pending_complete
- Add a dc_state NULL check in dc_state_release
- Backup and restore only on full updates
- Update DMUB flags and definitions
- Return the correct HDCP error code
- Add comments to v_total calculation and drop legacy TODO

Acked-by: Alex Hung 
Signed-off-by: Aric Cyr 
---
 drivers/gpu/drm/amd/display/dc/dc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 9629bd9252b4..e17ddda8ec38 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -51,7 +51,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.274"
+#define DC_VER "3.2.275"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.34.1



[PATCH 33/34] drm/amd/display: Add comments to v_total calculation and drop legacy TODO

2024-02-28 Thread Alex Hung
From: Rodrigo Siqueira 

[WHY & HOW]
This commit just adds some simple comments to help understand the
calculation of V total duration for Freesync. Also, remove a legacy TODO
comment from link service type.

Acked-by: Alex Hung 
Signed-off-by: Rodrigo Siqueira 
---
 drivers/gpu/drm/amd/display/include/link_service_types.h | 1 -
 drivers/gpu/drm/amd/display/modules/freesync/freesync.c  | 4 ++--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/include/link_service_types.h 
b/drivers/gpu/drm/amd/display/include/link_service_types.h
index 92dbff22a7c6..1867aac57cf2 100644
--- a/drivers/gpu/drm/amd/display/include/link_service_types.h
+++ b/drivers/gpu/drm/amd/display/include/link_service_types.h
@@ -73,7 +73,6 @@ struct link_training_settings {
enum dc_pre_emphasis *pre_emphasis;
enum dc_post_cursor2 *post_cursor2;
bool should_set_fec_ready;
-   /* TODO - factor lane_settings out because it changes during LT */
union dc_dp_ffe_preset *ffe_preset;
 
uint16_t cr_pattern_time;
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 
b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index fbaa6effd0e3..b19ef58d1555 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -158,13 +158,13 @@ static unsigned int calc_v_total_from_duration(
if (duration_in_us > vrr->max_duration_in_us)
duration_in_us = vrr->max_duration_in_us;
 
-   if (dc_is_hdmi_signal(stream->signal)) {
+   if (dc_is_hdmi_signal(stream->signal)) { // change for HDMI to comply 
with spec
uint32_t h_total_up_scaled;
 
h_total_up_scaled = stream->timing.h_total * 1;
v_total = div_u64((unsigned long long)duration_in_us
* stream->timing.pix_clk_100hz + 
(h_total_up_scaled - 1),
-   h_total_up_scaled);
+   h_total_up_scaled); //ceiling for MMax 
and MMin for MVRR
} else {
v_total = div64_u64(div64_u64(((unsigned long long)(
duration_in_us) * 
(stream->timing.pix_clk_100hz / 10)),
-- 
2.34.1



  1   2   3   4   >