[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 = 
_get_dpp_pipes_for_plane;
dml2_options->callbacks.get_stream_status = _state_get_stream_status;
dml2_options->callbacks.get_stream_from_id = 
_state_get_stream_from_id;
+   dml2_options->callbacks.get_max_flickerless_instant_vtotal_increase = 
_stream_get_max_flickerless_instant_vtotal_increase;
 
dml2_options->svp_pstate.callbacks.dc = dc;
dml2_options->svp_pstate.callbacks.add_phantom_plane = 
_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, 
stream->timing.v_total*stream->timing.h_total);
   

[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_THROUGHPUT_PER_

[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(_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(>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)
_ctx->stream->dst);
mpc_slice_of_plane_clip = calculate_mpc_slice_in_timing_active(
pipe_ctx, _clip);
-   odm_slice = calculate_odm_slice_in_timing_active(pipe_ctx);
-   overlapping_area = intersect_rec(_slice_of_plane_clip, _slice);
+   odm_slice_src = resource_get_odm_slice_src_rect(pipe_ctx);
+   overlapping_area = intersect_rec(_slice_of_plane_clip, 
_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(
_area,
-   -odm_slice.x, -odm_slice.y);
+   -odm_slice_src.x, -odm_slice_src.y);
adjust_recout_for_visual_confirm(
_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(
-   >recout, odm_slice.x, odm_slice.y);
+   >recout, odm_slice_src.x, odm_slice_src.y);
recout_dst_in_active_timing = calculate_plane_rec_in_timing_active(
pipe_ctx, _state->dst_rect);
overlap_in_active_

[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, _xable, 
_xable, _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, >dsc_mode);
+   REG_GET(DP_PIXEL_FORMAT, PIXEL_ENCODING_TYPE, >dsc_mode);
+
if (s->dsc_mode) {
REG_GET(DP_GSP11_CNTL, DP_SEC_GSP11_LINE_NUM, 
>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 = 
>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 = 
_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)

_mgr_base->bw_params->clk_table.entries[0].dcfclk_mhz,
_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,

_mgr_base->bw_params->clk_table.entries[0].socclk_mhz,

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

_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz,
_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,

_mgr_base->bw_params->clk_table.entries[0].dispclk_mhz,
_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.dispclk_mhz = 0;
 
/* DPPCLK */
dcn401_init_single_clock(clk_mgr, PPC

[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 _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 = _mgr401->base;
clk_mgr->base.ctx = ctx;
clk_mgr->base.funcs = _funcs;
clk_mgr->regs = _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),
_mgr->wm_range_table_addr);
+   if (!clk_mgr->wm_range_table) {
+   BREAK_TO_DEBUGGER();
+   kfree(clk_mgr->base.bw_params);
+   return NULL;
+   }
+
+   return _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 

[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(>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(>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(>scratch, stream);
+   if (update_type == UPDATE_TYPE_FULL)
+   backup_planes_and_stream_state(>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(>current_state->scratch, stream);
+   restore_planes_and_stream_state(>scratch.current_state, stream);
intermediate_context = create_minimal_transition_state(dc,
dc->current_state, );
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(_context->scratch, stream);
+   restore_planes_and_stream_state(>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(>perf_params, 0, sizeof(state->perf_params));
-   memset(>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 to optimize clocks and bandwidth for added/removed planes */
-   bool optimized_required;
-   bool w

[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



[PATCH 32/34] drm/amd/display: Return the correct HDCP error code

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

[WHY & HOW]
If the display is null when creating an HDCP session, return a proper
error code.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Rodrigo Siqueira 
---
 drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c | 3 +++
 1 file changed, 3 insertions(+)

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 8c137d7c032e..7c9805705fd3 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
@@ -513,6 +513,9 @@ 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 31/34] drm/amd/display: Update DMUB flags and definitions

2024-02-28 Thread Alex Hung
From: Anthony Koo 

[WHAT]
- Update replay residency tracing design to support more types
  including tracking PHY and ALPM residency types
- Add commands for Replay frame update count profiling
- Enhance HWFQ with additional flags to allow for more
  optimized IPS low power state residencies
- Add new flag to indicate if a new frame update needed for
  ABM to ramp up into steady state

Acked-by: Alex Hung 
Signed-off-by: Anthony Koo 
---
 .../gpu/drm/amd/display/dc/dce/dmub_replay.c  |  2 +-
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   | 40 +--
 2 files changed, 38 insertions(+), 4 deletions(-)

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 b010814706fe..4f559a025cf0 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
@@ -244,7 +244,7 @@ static void dmub_replay_residency(struct dmub_replay *dmub, 
uint8_t panel_inst,
uint16_t param = (uint16_t)(panel_inst << 8);
 
if (is_alpm)
-   param |= REPLAY_RESIDENCY_MODE_ALPM;
+   param |= REPLAY_RESIDENCY_FIELD_MODE_ALPM;
 
if (is_start)
param |= REPLAY_RESIDENCY_ENABLE;
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h 
b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index 4a650ac571d7..b81cd2649db3 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -194,6 +194,11 @@ union abm_flags {
 * of user backlight level.
 */
unsigned int abm_gradual_bl_change : 1;
+
+   /**
+* @abm_new_frame: Indicates if a new frame update needed for 
ABM to ramp up into steady
+*/
+   unsigned int abm_new_frame : 1;
} bitfields;
 
unsigned int u32All;
@@ -2937,18 +2942,47 @@ struct dmub_rb_cmd_psr_set_power_opt {
struct dmub_cmd_psr_set_power_opt_data psr_set_power_opt_data;
 };
 
+/**
+ * Definition of Replay Residency GPINT command.
+ * Bit[0] - Residency mode for Revision 0
+ * Bit[1] - Enable/Disable state
+ * Bit[2-3] - Revision number
+ * Bit[4-7] - Residency mode for Revision 1
+ * Bit[8] - Panel instance
+ * Bit[9-15] - Reserved
+ */
+
+enum pr_residency_mode {
+   PR_RESIDENCY_MODE_PHY = 0x0,
+   PR_RESIDENCY_MODE_ALPM,
+   PR_RESIDENCY_MODE_IPS2,
+   PR_RESIDENCY_MODE_FRAME_CNT,
+};
+
 #define REPLAY_RESIDENCY_MODE_SHIFT(0)
 #define REPLAY_RESIDENCY_ENABLE_SHIFT  (1)
+#define REPLAY_RESIDENCY_REVISION_SHIFT(2)
+#define REPLAY_RESIDENCY_MODE2_SHIFT   (4)
 
 #define REPLAY_RESIDENCY_MODE_MASK (0x1 << 
REPLAY_RESIDENCY_MODE_SHIFT)
-# define REPLAY_RESIDENCY_MODE_PHY (0x0 << 
REPLAY_RESIDENCY_MODE_SHIFT)
-# define REPLAY_RESIDENCY_MODE_ALPM(0x1 << 
REPLAY_RESIDENCY_MODE_SHIFT)
-# define REPLAY_RESIDENCY_MODE_IPS 0x10
+# define REPLAY_RESIDENCY_FIELD_MODE_PHY   (0x0 << 
REPLAY_RESIDENCY_MODE_SHIFT)
+# define REPLAY_RESIDENCY_FIELD_MODE_ALPM  (0x1 << 
REPLAY_RESIDENCY_MODE_SHIFT)
+
+#define REPLAY_RESIDENCY_MODE2_MASK(0xF << 
REPLAY_RESIDENCY_MODE2_SHIFT)
+# define REPLAY_RESIDENCY_FIELD_MODE2_IPS  (0x1 << 
REPLAY_RESIDENCY_MODE2_SHIFT)
+# define REPLAY_RESIDENCY_FIELD_MODE2_FRAME_CNT(0x2 << 
REPLAY_RESIDENCY_MODE2_SHIFT)
 
 #define REPLAY_RESIDENCY_ENABLE_MASK   (0x1 << 
REPLAY_RESIDENCY_ENABLE_SHIFT)
 # define REPLAY_RESIDENCY_DISABLE  (0x0 << 
REPLAY_RESIDENCY_ENABLE_SHIFT)
 # define REPLAY_RESIDENCY_ENABLE   (0x1 << 
REPLAY_RESIDENCY_ENABLE_SHIFT)
 
+#define REPLAY_RESIDENCY_REVISION_MASK (0x3 << 
REPLAY_RESIDENCY_REVISION_SHIFT)
+# define REPLAY_RESIDENCY_REVISION_0   (0x0 << 
REPLAY_RESIDENCY_REVISION_SHIFT)
+# define REPLAY_RESIDENCY_REVISION_1   (0x1 << 
REPLAY_RESIDENCY_REVISION_SHIFT)
+
+/**
+ * Definition of a replay_state.
+ */
 enum replay_state {
REPLAY_STATE_0  = 0x0,
REPLAY_STATE_1  = 0x10,
-- 
2.34.1



[PATCH 29/34] drm/amd/display: Add a dc_state NULL check in dc_state_release

2024-02-28 Thread Alex Hung
From: Allen Pan 

[How]
Check wheather state is NULL before releasing it.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Allen Pan 
---
 drivers/gpu/drm/amd/display/dc/core/dc_state.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

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 180ac47868c2..5cc7f8da209c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_state.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
@@ -334,7 +334,8 @@ static void dc_state_free(struct kref *kref)
 
 void dc_state_release(struct dc_state *state)
 {
-   kref_put(>refcount, dc_state_free);
+   if (state != NULL)
+   kref_put(>refcount, dc_state_free);
 }
 /*
  * dc_state_add_stream() - Add a new dc_stream_state to a dc_state.
-- 
2.34.1



[PATCH 28/34] drm/amd/display: Implement wait_for_odm_update_pending_complete

2024-02-28 Thread Alex Hung
From: Wenjing Liu 

[WHY]
Odm update is doubled buffered. We need to wait for ODM update to be
completed before optimizing bandwidth or programming new udpates.

[HOW]
implement wait_for_odm_update_pending_complete function to wait for:
1. odm configuration update is no longer pending in timing generator.
2. no pending dpg pattern update for each active OPP.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Alvin Lee 
Acked-by: Alex Hung 
Signed-off-by: Wenjing Liu 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  | 56 ++-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_opp.c  |  1 +
 .../gpu/drm/amd/display/dc/dcn20/dcn20_opp.c  | 14 +
 .../gpu/drm/amd/display/dc/dcn20/dcn20_opp.h  |  2 +
 .../drm/amd/display/dc/dcn201/dcn201_opp.c|  1 +
 .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c   |  4 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/opp.h   |  3 +
 .../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|  8 +++
 .../amd/display/dc/optc/dcn32/dcn32_optc.h|  1 +
 11 files changed, 90 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index e87aad983b40..d8967087335e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1335,6 +1335,54 @@ static void disable_vbios_mode_if_required(
}
 }
 
+/**
+ * wait_for_blank_complete - wait for all active OPPs to finish pending blank
+ * pattern updates
+ *
+ * @dc: [in] dc reference
+ * @context: [in] hardware context in use
+ */
+static void wait_for_blank_complete(struct dc *dc,
+   struct dc_state *context)
+{
+   struct pipe_ctx *opp_head;
+   struct dce_hwseq *hws = dc->hwseq;
+   int i;
+
+   if (!hws->funcs.wait_for_blank_complete)
+   return;
+
+   for (i = 0; i < MAX_PIPES; i++) {
+   opp_head = >res_ctx.pipe_ctx[i];
+
+   if (!resource_is_pipe_type(opp_head, OPP_HEAD) ||
+   dc_state_get_pipe_subvp_type(context, opp_head) 
== SUBVP_PHANTOM)
+   continue;
+
+   hws->funcs.wait_for_blank_complete(opp_head->stream_res.opp);
+   }
+}
+
+static void wait_for_odm_update_pending_complete(struct dc *dc, struct 
dc_state *context)
+{
+   struct pipe_ctx *otg_master;
+   struct timing_generator *tg;
+   int i;
+
+   for (i = 0; i < MAX_PIPES; i++) {
+   otg_master = >res_ctx.pipe_ctx[i];
+   if (!resource_is_pipe_type(otg_master, OTG_MASTER) ||
+   dc_state_get_pipe_subvp_type(context, 
otg_master) == SUBVP_PHANTOM)
+   continue;
+   tg = otg_master->stream_res.tg;
+   if (tg->funcs->wait_odm_doublebuffer_pending_clear)
+   tg->funcs->wait_odm_doublebuffer_pending_clear(tg);
+   }
+
+   /* ODM update may require to reprogram blank pattern for each OPP */
+   wait_for_blank_complete(dc, context);
+}
+
 static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
 {
int i;
@@ -2026,6 +2074,11 @@ static enum dc_status dc_commit_state_no_check(struct dc 
*dc, struct dc_state *c
context->stream_count == 0) {
/* Must wait for no flips to be pending before doing optimize 
bw */
wait_for_no_pipes_pending(dc, context);
+   /*
+* optimized dispclk depends on ODM setup. Need to wait for ODM
+* update pending complete before optimizing bandwidth.
+*/
+   wait_for_odm_update_pending_complete(dc, context);
/* pplib is notified if disp_num changed */
dc->hwss.optimize_bandwidth(dc, context);
/* Need to do otg sync again as otg could be out of sync due to 
otg
@@ -3591,7 +3644,7 @@ static void commit_planes_for_stream_fast(struct dc *dc,
top_pipe_to_program->stream->update_flags.raw = 0;
 }
 
-static void wait_for_outstanding_hw_updates(struct dc *dc, const struct 
dc_state *dc_context)
+static void wait_for_outstanding_hw_updates(struct dc *dc, struct dc_state 
*dc_context)
 {
 /*
  * This function calls HWSS to wait for any potentially double buffered
@@ -3629,6 +3682,7 @@ static void wait_for_outstanding_hw_updates(struct dc 
*dc, const struct dc_state
}
}
}
+   wait_for_odm_update_pending_complete(dc, dc_context);
 }
 
 static void commit_planes_for_stream(struct dc *dc,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
index 48a40dcc7050..5838a11efd00 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/

[PATCH 27/34] drm/amd/display: Lock all enabled otg pipes even with no planes

2024-02-28 Thread Alex Hung
From: Wenjing Liu 

[WHY]
On DCN32 we support dynamic ODM even when OTG is blanked. When ODM
configuration is dynamically changed and the OTG is on blank pattern,
we will need to reprogram OPP's test pattern based on new ODM
configuration. Therefore we need to lock the OTG pipe to avoid temporary
corruption when we are reprogramming OPP blank patterns.

[HOW]
Add a new interdependent update lock implementation to lock all enabled
OTG pipes even when there is no plane on the OTG for DCN32.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Alvin Lee 
Acked-by: Alex Hung 
Signed-off-by: Wenjing Liu 
---
 .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c   | 23 +++
 .../amd/display/dc/hwss/dcn32/dcn32_hwseq.h   |  2 ++
 .../amd/display/dc/hwss/dcn32/dcn32_init.c|  2 +-
 3 files changed, 26 insertions(+), 1 deletion(-)

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 b890db0bfc46..c0b526cf1786 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
@@ -1785,3 +1785,26 @@ void dcn32_prepare_bandwidth(struct dc *dc,
context->bw_ctx.bw.dcn.clk.p_state_change_support = 
p_state_change_support;
}
 }
+
+void dcn32_interdependent_update_lock(struct dc *dc,
+   struct dc_state *context, bool lock)
+{
+   unsigned int i;
+   struct pipe_ctx *pipe;
+   struct timing_generator *tg;
+
+   for (i = 0; i < dc->res_pool->pipe_count; i++) {
+   pipe = >res_ctx.pipe_ctx[i];
+   tg = pipe->stream_res.tg;
+
+   if (!resource_is_pipe_type(pipe, OTG_MASTER) ||
+   !tg->funcs->is_tg_enabled(tg) ||
+   dc_state_get_pipe_subvp_type(context, pipe) == 
SUBVP_PHANTOM)
+   continue;
+
+   if (lock)
+   dc->hwss.pipe_control_lock(dc, pipe, true);
+   else
+   dc->hwss.pipe_control_lock(dc, pipe, false);
+   }
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h
index 069e20bc87c0..f55c11fc56ec 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h
@@ -129,4 +129,6 @@ bool dcn32_is_pipe_topology_transition_seamless(struct dc 
*dc,
 void dcn32_prepare_bandwidth(struct dc *dc,
struct dc_state *context);
 
+void dcn32_interdependent_update_lock(struct dc *dc,
+   struct dc_state *context, bool lock);
 #endif /* __DC_HWSS_DCN32_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c
index 2b073123d3ed..67d661dbd5b7 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c
@@ -58,7 +58,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = {
.disable_plane = dcn20_disable_plane,
.disable_pixel_data = dcn20_disable_pixel_data,
.pipe_control_lock = dcn20_pipe_control_lock,
-   .interdependent_update_lock = dcn10_lock_all_pipes,
+   .interdependent_update_lock = dcn32_interdependent_update_lock,
.cursor_lock = dcn10_cursor_lock,
.prepare_bandwidth = dcn32_prepare_bandwidth,
.optimize_bandwidth = dcn20_optimize_bandwidth,
-- 
2.34.1



[PATCH 26/34] drm/amd/display: Implement update_planes_and_stream_v3 sequence

2024-02-28 Thread Alex Hung
From: Wenjing Liu 

[WHY & HOW]
Update planes and stream version 3 separates FULL and FAST updates
to their own sequences. It aims to clean up frequent checks for
update type resulting unnecessary branching in logic flow. It also
adds a new commit minimal transition sequence, which detects the need
for minimal transition based on the actual comparison of current and
new states instead of "predicting" it based on per feature software
policy, i.e. could_mpcc_tree_change_for_active_pipes.

The new commit minimal transition sequence is made universal to any
power saving features that would use extra free pipes such as Dynamic
ODM/MPC Combine, MPO or SubVp. Therefore there is no longer a need to
specially handle compatibility problems with transitions among those
features as they are now transparent to the new sequence.

Reviewed-by: Wenjing Liu 
Acked-by: Alex Hung 
Signed-off-by: Wenjing Liu 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 700 +++
 1 file changed, 469 insertions(+), 231 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index ed6579633a58..e87aad983b40 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2065,7 +2065,7 @@ static enum dc_status dc_commit_state_no_check(struct dc 
*dc, struct dc_state *c
return result;
 }
 
-static bool commit_minimal_transition_state_legacy(struct dc *dc,
+static bool commit_minimal_transition_state(struct dc *dc,
struct dc_state *transition_base_context);
 
 /**
@@ -2131,7 +2131,7 @@ enum dc_status dc_commit_streams(struct dc *dc,
}
 
if (handle_exit_odm2to1)
-   res = commit_minimal_transition_state_legacy(dc, 
dc->current_state);
+   res = commit_minimal_transition_state(dc, dc->current_state);
 
context = dc_state_create_current_copy(dc);
if (!context)
@@ -3029,6 +3029,63 @@ static void restore_planes_and_stream_state(
*stream->out_transfer_func = scratch->out_transfer_func;
 }
 
+/**
+ * update_seamless_boot_flags() - Helper function for updating seamless boot 
flags
+ *
+ * @dc: Current DC state
+ * @context: New DC state to be programmed
+ * @surface_count: Number of surfaces that have an updated
+ * @stream: Corresponding stream to be updated in the current flip
+ *
+ * Updating seamless boot flags do not need to be part of the commit sequence. 
This
+ * helper function will update the seamless boot flags on each flip (if 
required)
+ * outside of the HW commit sequence (fast or slow).
+ *
+ * Return: void
+ */
+static void update_seamless_boot_flags(struct dc *dc,
+   struct dc_state *context,
+   int surface_count,
+   struct dc_stream_state *stream)
+{
+   if (get_seamless_boot_stream_count(context) > 0 && surface_count > 0) {
+   /* Optimize seamless boot flag keeps clocks and watermarks high 
until
+* first flip. After first flip, optimization is required to 
lower
+* bandwidth. Important to note that it is expected UEFI will
+* only light up a single display on POST, therefore we only 
expect
+* one stream with seamless boot flag set.
+*/
+   if (stream->apply_seamless_boot_optimization) {
+   stream->apply_seamless_boot_optimization = false;
+
+   if (get_seamless_boot_stream_count(context) == 0)
+   dc->optimized_required = true;
+   }
+   }
+}
+
+/**
+ * update_planes_and_stream_state() - The function takes planes and stream
+ * updates as inputs and determines the appropriate update type. If update type
+ * is FULL, the function allocates a new context, populates and validates it.
+ * Otherwise, it updates current dc context. The function will return both
+ * new_context and new_update_type back to the caller. The function also backs
+ * up both current and new contexts into corresponding dc state scratch memory.
+ * TODO: The function does too many things, and even conditionally allocates dc
+ * context memory implicitly. We should consider to break it down.
+ *
+ * @dc: Current DC state
+ * @srf_updates: an array of surface updates
+ * @surface_count: surface update count
+ * @stream: Corresponding stream to be updated
+ * @stream_update: stream update
+ * @new_update_type: [out] determined update type by the function
+ * @new_context: [out] new context allocated and validated if update type is
+ * FULL, reference to current context if update type is less than FULL.
+ *
+ * Return: true if a valid update is populated into new_context, false
+ * otherwise.
+ */
 static bool update_planes_and_stream_state(struct dc *dc,
struct dc_surface_update *srf_updates, int surface_count,
struct dc_stream

[PATCH 25/34] drm/amd/display: Set the power_down_on_boot function pointer to null

2024-02-28 Thread Alex Hung
From: Muhammad Ahmed 

[WHY]
Blackscreen hang @ PC EF25 when trying to wake up from S0i3. DCN
gets powered off due to dc_power_down_on_boot() being called after
timeout.

[HOW]
Setting the power_down_on_boot function pointer to null since we don't
expect the function to be called for APU.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Nicholas Kazlauskas 
Acked-by: Alex Hung 
Signed-off-by: Muhammad Ahmed 
---
 drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
index dce620d359a6..d4e0abbef28e 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
@@ -39,7 +39,7 @@
 static const struct hw_sequencer_funcs dcn35_funcs = {
.program_gamut_remap = dcn30_program_gamut_remap,
.init_hw = dcn35_init_hw,
-   .power_down_on_boot = dcn35_power_down_on_boot,
+   .power_down_on_boot = NULL,
.apply_ctx_to_hw = dce110_apply_ctx_to_hw,
.apply_ctx_for_surface = NULL,
.program_front_end_for_ctx = dcn20_program_front_end_for_ctx,
-- 
2.34.1



[PATCH 24/34] drm/amd/display: Refactor DPP into a component directory

2024-02-28 Thread Alex Hung
From: Revalla Hari Krishna 

[WHY & HOW]
Move all dpp files to a new dpp directory.

Reviewed-by: Martin Leung 
Acked-by: Alex Hung 
Signed-off-by: Revalla Hari Krishna 
---
 drivers/gpu/drm/amd/display/Makefile  |  1 +
 drivers/gpu/drm/amd/display/dc/Makefile   |  2 +-
 drivers/gpu/drm/amd/display/dc/dcn10/Makefile |  4 +-
 .../amd/display/dc/dcn10/dcn10_cm_common.c|  2 +-
 drivers/gpu/drm/amd/display/dc/dcn20/Makefile |  2 +-
 .../gpu/drm/amd/display/dc/dcn201/Makefile|  2 +-
 drivers/gpu/drm/amd/display/dc/dcn30/Makefile |  2 -
 .../amd/display/dc/dcn30/dcn30_cm_common.c|  2 +-
 drivers/gpu/drm/amd/display/dc/dcn32/Makefile |  2 +-
 drivers/gpu/drm/amd/display/dc/dcn35/Makefile |  2 +-
 drivers/gpu/drm/amd/display/dc/dpp/Makefile   | 77 +++
 .../amd/display/dc/dpp/dcn10/CMakeLists.txt   |  6 ++
 .../display/dc/{ => dpp}/dcn10/dcn10_dpp.c|  2 +-
 .../display/dc/{ => dpp}/dcn10/dcn10_dpp.h|  0
 .../display/dc/{ => dpp}/dcn10/dcn10_dpp_cm.c |  4 +-
 .../dc/{ => dpp}/dcn10/dcn10_dpp_dscl.c   |  2 +-
 .../amd/display/dc/dpp/dcn20/CMakeLists.txt   |  5 ++
 .../display/dc/{ => dpp}/dcn20/dcn20_dpp.c|  2 +-
 .../display/dc/{ => dpp}/dcn20/dcn20_dpp.h|  0
 .../display/dc/{ => dpp}/dcn20/dcn20_dpp_cm.c |  2 +-
 .../amd/display/dc/dpp/dcn201/CMakeLists.txt  |  4 +
 .../display/dc/{ => dpp}/dcn201/dcn201_dpp.c  |  2 +-
 .../display/dc/{ => dpp}/dcn201/dcn201_dpp.h  |  0
 .../amd/display/dc/dpp/dcn30/CMakeLists.txt   |  5 ++
 .../display/dc/{ => dpp}/dcn30/dcn30_dpp.c|  4 +-
 .../display/dc/{ => dpp}/dcn30/dcn30_dpp.h|  0
 .../display/dc/{ => dpp}/dcn30/dcn30_dpp_cm.c |  4 +-
 .../amd/display/dc/dpp/dcn32/CMakeLists.txt   |  4 +
 .../display/dc/{ => dpp}/dcn32/dcn32_dpp.c|  2 +-
 .../display/dc/{ => dpp}/dcn32/dcn32_dpp.h|  0
 .../amd/display/dc/dpp/dcn35/CMakeLists.txt   |  4 +
 .../display/dc/{ => dpp}/dcn35/dcn35_dpp.c|  2 +-
 .../display/dc/{ => dpp}/dcn35/dcn35_dpp.h|  0
 33 files changed, 128 insertions(+), 24 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dpp/Makefile
 create mode 100644 drivers/gpu/drm/amd/display/dc/dpp/dcn10/CMakeLists.txt
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn10/dcn10_dpp.c (99%)
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn10/dcn10_dpp.h (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn10/dcn10_dpp_cm.c (99%)
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn10/dcn10_dpp_dscl.c (99%)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dpp/dcn20/CMakeLists.txt
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn20/dcn20_dpp.c (99%)
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn20/dcn20_dpp.h (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn20/dcn20_dpp_cm.c (99%)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dpp/dcn201/CMakeLists.txt
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn201/dcn201_dpp.c (99%)
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn201/dcn201_dpp.h (100%)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dpp/dcn30/CMakeLists.txt
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn30/dcn30_dpp.c (99%)
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn30/dcn30_dpp.h (100%)
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn30/dcn30_dpp_cm.c (99%)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dpp/dcn32/CMakeLists.txt
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn32/dcn32_dpp.c (99%)
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn32/dcn32_dpp.h (100%)
 create mode 100644 drivers/gpu/drm/amd/display/dc/dpp/dcn35/CMakeLists.txt
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn35/dcn35_dpp.c (98%)
 rename drivers/gpu/drm/amd/display/dc/{ => dpp}/dcn35/dcn35_dpp.h (100%)

diff --git a/drivers/gpu/drm/amd/display/Makefile 
b/drivers/gpu/drm/amd/display/Makefile
index 92a5c5efcf92..9a5bcafbf730 100644
--- a/drivers/gpu/drm/amd/display/Makefile
+++ b/drivers/gpu/drm/amd/display/Makefile
@@ -33,6 +33,7 @@ subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/hwss
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/resource
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/dsc
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/optc
+subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/dpp
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/inc
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/freesync
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/color
diff --git a/drivers/gpu/drm/amd/display/dc/Makefile 
b/drivers/gpu/drm/amd/display/dc/Makefile
index 7991ae468f75..4e9fb1742877 100644
--- a/drivers/gpu/drm/amd/display/dc/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/Makefile
@@ -22,7 +22,7 @@
 #
 # Makefile for Display Core (dc) component.
 
-DC_LIBS = basics bios dml clk_mgr dce gpio hwss irq link virtual dsc resource 
optc
+DC_LIBS = basics bios dml clk_mgr dce gpio hwss irq link virtua

[PATCH 23/34] drm/amd/display: Amend coasting vtotal for replay low hz

2024-02-28 Thread Alex Hung
From: ChunTao Tso 

[WHY]
The original coasting vtotal is 2 bytes, and it need to
be amended to 4 bytes because low hz case.

[HOW]
Amend coasting vtotal from 2 bytes to 4 bytes.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Alvin Lee 
Acked-by: Alex Hung 
Signed-off-by: ChunTao Tso 
---
 drivers/gpu/drm/amd/display/dc/dc_types.h | 4 ++--
 drivers/gpu/drm/amd/display/dc/inc/link.h | 4 ++--
 .../display/dc/link/protocols/link_edp_panel_control.c| 4 ++--
 .../display/dc/link/protocols/link_edp_panel_control.h| 4 ++--
 drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h   | 8 
 drivers/gpu/drm/amd/display/modules/power/power_helpers.c | 2 +-
 drivers/gpu/drm/amd/display/modules/power/power_helpers.h | 2 +-
 7 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 9900dda2eef5..be2ac5c442a4 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -1085,9 +1085,9 @@ struct replay_settings {
/* SMU optimization is enabled */
bool replay_smu_opt_enable;
/* Current Coasting vtotal */
-   uint16_t coasting_vtotal;
+   uint32_t coasting_vtotal;
/* Coasting vtotal table */
-   uint16_t coasting_vtotal_table[PR_COASTING_TYPE_NUM];
+   uint32_t coasting_vtotal_table[PR_COASTING_TYPE_NUM];
/* Maximum link off frame count */
enum replay_link_off_frame_count_level link_off_frame_count_level;
/* Replay pseudo vtotal for abm + ips on full screen video which can 
improve ips residency */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link.h 
b/drivers/gpu/drm/amd/display/dc/inc/link.h
index 26fe81f213da..bf29fc58ea6a 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link.h
@@ -285,12 +285,12 @@ struct link_service {
enum replay_FW_Message_type msg,
union dmub_replay_cmd_set *cmd_data);
bool (*edp_set_coasting_vtotal)(
-   struct dc_link *link, uint16_t coasting_vtotal);
+   struct dc_link *link, uint32_t coasting_vtotal);
bool (*edp_replay_residency)(const struct dc_link *link,
unsigned int *residency, const bool is_start,
const bool is_alpm);
bool (*edp_set_replay_power_opt_and_coasting_vtotal)(struct dc_link 
*link,
-   const unsigned int *power_opts, uint16_t 
coasting_vtotal);
+   const unsigned int *power_opts, uint32_t 
coasting_vtotal);
 
bool (*edp_wait_for_t12)(struct dc_link *link);
bool (*edp_is_ilr_optimization_required)(struct dc_link *link,
diff --git 
a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
index acfbbc638cc6..3baa2bdd6dd6 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
@@ -1034,7 +1034,7 @@ bool edp_send_replay_cmd(struct dc_link *link,
return true;
 }
 
-bool edp_set_coasting_vtotal(struct dc_link *link, uint16_t coasting_vtotal)
+bool edp_set_coasting_vtotal(struct dc_link *link, uint32_t coasting_vtotal)
 {
struct dc *dc = link->ctx->dc;
struct dmub_replay *replay = dc->res_pool->replay;
@@ -1073,7 +1073,7 @@ bool edp_replay_residency(const struct dc_link *link,
 }
 
 bool edp_set_replay_power_opt_and_coasting_vtotal(struct dc_link *link,
-   const unsigned int *power_opts, uint16_t coasting_vtotal)
+   const unsigned int *power_opts, uint32_t coasting_vtotal)
 {
struct dc  *dc = link->ctx->dc;
struct dmub_replay *replay = dc->res_pool->replay;
diff --git 
a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h
index 34e521af7bb4..a158c6234d42 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h
@@ -59,12 +59,12 @@ bool edp_setup_replay(struct dc_link *link,
 bool edp_send_replay_cmd(struct dc_link *link,
enum replay_FW_Message_type msg,
union dmub_replay_cmd_set *cmd_data);
-bool edp_set_coasting_vtotal(struct dc_link *link, uint16_t coasting_vtotal);
+bool edp_set_coasting_vtotal(struct dc_link *link, uint32_t coasting_vtotal);
 bool edp_replay_residency(const struct dc_link *link,
unsigned int *residency, const bool is_start, const bool is_alpm);
 bool edp_get_replay_state(const struct dc_link *link, uint64_t *state);
 bool edp_set_replay_power_opt_and_coasting_vtotal(struct dc_link *link,
-   const 

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

2024-02-28 Thread Alex Hung
From: George Shen 

[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.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Alvin Lee 
Acked-by: Alex Hung 
Signed-off-by: George Shen 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  4 ++
 .../gpu/drm/amd/display/dc/core/dc_resource.c | 37 +++
 .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c   | 10 +
 .../gpu/drm/amd/display/dc/inc/core_types.h   |  2 +
 drivers/gpu/drm/amd/display/dc/inc/resource.h |  4 ++
 5 files changed, 57 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index acd8f1257ade..ed6579633a58 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3147,6 +3147,10 @@ static bool update_planes_and_stream_state(struct dc *dc,
 
if (otg_master && otg_master->stream->test_pattern.type 
!= DP_TEST_PATTERN_VIDEO_MODE)

resource_build_test_pattern_params(>res_ctx, otg_master);
+
+   if (otg_master && 
(otg_master->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422 ||
+   
otg_master->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420))
+   
resource_build_subsampling_params(>res_ctx, otg_master);
}
}
 
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 1b7765bc5e5e..96ea283bd169 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -822,6 +822,16 @@ static struct rect 
calculate_odm_slice_in_timing_active(struct pipe_ctx *pipe_ct
stream->timing.v_border_bottom +
stream->timing.v_border_top;
 
+   /* Recout for ODM slices after the first slice need one extra left edge 
pixel
+* for 3-tap chroma subsampling.
+*/
+   if (odm_slice_idx > 0 &&
+   (pipe_ctx->stream->timing.pixel_encoding == 
PIXEL_ENCODING_YCBCR422 ||
+   pipe_ctx->stream->timing.pixel_encoding == 
PIXEL_ENCODING_YCBCR420)) {
+   odm_rec.x -= 1;
+   odm_rec.width += 1;
+   }
+
return odm_rec;
 }
 
@@ -1438,6 +1448,7 @@ void resource_build_test_pattern_params(struct 
resource_context *res_ctx,
enum controller_dp_test_pattern controller_test_pattern;
enum controller_dp_color_space controller_color_space;
enum dc_color_depth color_depth = 
otg_master->stream->timing.display_color_depth;
+   enum dc_pixel_encoding pixel_encoding = 
otg_master->stream->timing.pixel_encoding;
int h_active = otg_master->stream->timing.h_addressable +
otg_master->stream->timing.h_border_left +
otg_master->stream->timing.h_border_right;
@@ -1469,10 +1480,36 @@ void resource_build_test_pattern_params(struct 
resource_context *res_ctx,
else
params->width = last_odm_slice_width;
 
+   /* Extra left edge pixel is required for 3-tap chroma 
subsampling. */
+   if (i != 0 && (pixel_encoding == PIXEL_ENCODING_YCBCR422 ||
+   pixel_encoding == PIXEL_ENCODING_YCBCR420)) {
+   params->offset -= 1;
+   params->width += 1;
+   }
+
offset += odm_slice_width;
}
 }
 
+void resource_build_subsampling_params(struct resource_context *res_ctx,
+   struct pipe_ctx *otg_master)
+{
+   struct pipe_ctx *opp_heads[MAX_PIPES];
+   int odm_cnt = 1;
+   int i;
+
+   odm_cnt = resource_get_opp_heads_for_otg_master(otg_master, res_ctx, 
opp_heads);
+
+   /* For ODM slices after the first slice, extra left edge pixel is 
required
+* for 3-tap chroma subsampling.
+*/
+   if (otg_master->stream->timing.pixel_encoding == 
PIXEL_ENCODING_YCBCR422 ||
+   otg_master->stream->timing.pixel_encoding == 
PIXEL_ENCODING_YCBCR420) {
+   for (i = 0; i < odm_cnt; i++)
+   opp_heads[i]->stream_res.left_edge_extra_pixel = (i == 
0) ? false : true;
+   }
+}
+
 bool resource_build_scaling_params(struct pipe_ctx *pipe_ct

[PATCH 21/34] drm/amd/display: Add debug counters to IPS exit prints

2024-02-28 Thread Alex Hung
From: Nicholas Kazlauskas 

[WHY]
To have a log of the entry/exit counters in case the system hangs to
measure stability.

[HOW]
Read them from firmware state and pass them to the prints.

Reviewed-by: Duncan Ma 
Acked-by: Alex Hung 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 18 +++---
 1 file changed, 15 insertions(+), 3 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 938e8cb2fec1..765a459d54eb 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -1279,6 +1279,7 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, 
bool allow_idle)
 static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
 {
struct dc_dmub_srv *dc_dmub_srv;
+   uint32_t rcg_exit_count, ips1_exit_count, ips2_exit_count;
 
if (dc->debug.dmcub_emulation)
return;
@@ -1295,15 +1296,22 @@ static void dc_dmub_srv_exit_low_power_state(const 
struct dc *dc)

_dmub_srv->dmub->shared_state[DMUB_SHARED_SHARE_FEATURE__IPS_DRIVER].data.ips_driver;
union dmub_shared_state_ips_driver_signals prev_driver_signals 
= ips_driver->signals;
 
+   rcg_exit_count = ips_fw->rcg_exit_count;
+   ips1_exit_count = ips_fw->ips1_exit_count;
+   ips2_exit_count = ips_fw->ips2_exit_count;
+
ips_driver->signals.all = 0;
 
DC_LOG_IPS(
-   "%s check (allow_ips1=%d allow_ips2=%d) (ips1_commit=%d 
ips2_commit=%d)",
+   "%s (allow ips1=%d ips2=%d) (commit ips1=%d ips2=%d) 
(count rcg=%d ips1=%d ips2=%d)",
__func__,
ips_driver->signals.bits.allow_ips1,
ips_driver->signals.bits.allow_ips2,
ips_fw->signals.bits.ips1_commit,
-   ips_fw->signals.bits.ips2_commit);
+   ips_fw->signals.bits.ips2_commit,
+   ips_fw->rcg_entry_count,
+   ips_fw->ips1_entry_count,
+   ips_fw->ips2_entry_count);
 
/* Note: register access has technically not resumed for DCN 
here, but we
 * need to be message PMFW through our standard register 
interface.
@@ -1387,7 +1395,11 @@ static void dc_dmub_srv_exit_low_power_state(const 
struct dc *dc)
if (!dc_dmub_srv_is_hw_pwr_up(dc->ctx->dmub_srv, true))
ASSERT(0);
 
-   DC_LOG_IPS("%s exited", __func__);
+   DC_LOG_IPS("%s exit (count rcg=%d ips1=%d ips2=%d)",
+   __func__,
+   rcg_exit_count,
+   ips1_exit_count,
+   ips2_exit_count);
 }
 
 void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum 
dc_acpi_cm_power_state powerState)
-- 
2.34.1



[PATCH 20/34] drm/amd/display: Guard cursor idle reallow by DC debug option

2024-02-28 Thread Alex Hung
From: Nicholas Kazlauskas 

[WHY]
To control whether idle optimizations reallowed after the first cursor
update.

[HOW]
Add checks to the conditions.

Reviewed-by: Duncan Ma 
Acked-by: Alex Hung 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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 51a970fcb5d0..212e057ed9b0 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -319,7 +319,7 @@ bool dc_stream_set_cursor_attributes(
program_cursor_attributes(dc, stream, attributes);
 
/* re-enable idle optimizations if necessary */
-   if (reset_idle_optimizations)
+   if (reset_idle_optimizations && !dc->debug.disable_dmub_reallow_idle)
dc_allow_idle_optimizations(dc, true);
 
return true;
@@ -394,7 +394,7 @@ bool dc_stream_set_cursor_position(
 
program_cursor_position(dc, stream, position);
/* re-enable idle optimizations if necessary */
-   if (reset_idle_optimizations)
+   if (reset_idle_optimizations && !dc->debug.disable_dmub_reallow_idle)
dc_allow_idle_optimizations(dc, true);
 
return true;
-- 
2.34.1



[PATCH 19/34] drm/amd/display: Add guards for idle on reg read/write

2024-02-28 Thread Alex Hung
From: Nicholas Kazlauskas 

[WHY]
If DCN is in idle then we should not be accessing DCN registers or
it can lead to hangs.

[HOW]
Log the error and return 0 or drop the write if it's in idle.

This is skipped in the exit sequence itself since the boolean flips
before it starts.

It also does not cover accesses from external clients outside of DM/DC
like firmware or the kernel mode driver.

Reviewed-by: Duncan Ma 
Acked-by: Alex Hung 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 9 +
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 1 +
 2 files changed, 10 insertions(+)

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 b168dfc79381..938e8cb2fec1 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -1270,6 +1270,10 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, 
bool allow_idle)
/* NOTE: This does not use the "wake" interface since this is part of 
the wake path. */
/* We also do not perform a wait since DMCUB could enter idle after the 
notification. */
dm_execute_dmub_cmd(dc->ctx, , allow_idle ? 
DM_DMUB_WAIT_TYPE_NO_WAIT : DM_DMUB_WAIT_TYPE_WAIT);
+
+   /* Register access should stop at this point. */
+   if (allow_idle)
+   dc_dmub_srv->needs_idle_wake = true;
 }
 
 static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
@@ -1301,6 +1305,11 @@ static void dc_dmub_srv_exit_low_power_state(const 
struct dc *dc)
ips_fw->signals.bits.ips1_commit,
ips_fw->signals.bits.ips2_commit);
 
+   /* Note: register access has technically not resumed for DCN 
here, but we
+* need to be message PMFW through our standard register 
interface.
+*/
+   dc_dmub_srv->needs_idle_wake = false;
+
if (prev_driver_signals.bits.allow_ips2) {
DC_LOG_IPS(
"wait IPS2 eval (ips1_commit=%d 
ips2_commit=%d)",
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h 
b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
index 952bfb368886..60c93e9e3533 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h
@@ -52,6 +52,7 @@ struct dc_dmub_srv {
void *dm;
 
bool idle_allowed;
+   bool needs_idle_wake;
 };
 
 void dc_dmub_srv_wait_idle(struct dc_dmub_srv *dc_dmub_srv);
-- 
2.34.1



[PATCH 18/34] drm/amd/display: Fix idle check for shared firmware state

2024-02-28 Thread Alex Hung
From: Nicholas Kazlauskas 

[WHY]
We still had an instance of get_idle_state checking the PMFW scratch
register instead of the actual idle allow signal.

[HOW]
Replace it with the SW state check for whether we had allowed idle
through notify_idle.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Duncan Ma 
Acked-by: Alex Hung 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index daf6c7fe0906..acd8f1257ade 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -4884,22 +4884,16 @@ void dc_exit_ips_for_hw_access_internal(struct dc *dc, 
const char *caller_name)
 
 bool dc_dmub_is_ips_idle_state(struct dc *dc)
 {
-   uint32_t idle_state = 0;
-
if (dc->debug.disable_idle_power_optimizations)
return false;
 
if (!dc->caps.ips_support || (dc->config.disable_ips == 
DMUB_IPS_DISABLE_ALL))
return false;
 
-   if (dc->hwss.get_idle_state)
-   idle_state = dc->hwss.get_idle_state(dc);
-
-   if (!(idle_state & DMUB_IPS1_ALLOW_MASK) ||
-   !(idle_state & DMUB_IPS2_ALLOW_MASK))
-   return true;
+   if (!dc->ctx->dmub_srv)
+   return false;
 
-   return false;
+   return dc->ctx->dmub_srv->idle_allowed;
 }
 
 /* set min and max memory clock to lowest and highest DPM level, respectively 
*/
-- 
2.34.1



[PATCH 17/34] drm/amd/display: Update odm when ODM combine is changed on an otg master pipe with no plane

2024-02-28 Thread Alex Hung
From: Wenjing Liu 

[WHY]
When committing an update with ODM combine change when the plane is
removing or already removed, we fail to detect odm change in pipe
update flags. This has caused mismatch between new dc state and the
actual hardware state, because we missed odm programming.

[HOW]
- Detect odm change even for otg master pipe without a plane.
- Update odm config before calling program pipes for pipe with planes.

The commit also updates blank pattern programming when odm is changed
without plane. This is because number of OPP is changed when ODM
combine is changed. Blank pattern is per OPP so we will need to
reprogram OPP based on the new pipe topology.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Dillon Varone 
Acked-by: Alex Hung 
Signed-off-by: Wenjing Liu 
---
 .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c   | 41 ++-
 .../amd/display/dc/hwss/dcn32/dcn32_hwseq.c   |  7 
 2 files changed, 28 insertions(+), 20 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 c55d5155ecb9..40098d9f70cb 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
@@ -1498,6 +1498,11 @@ static void dcn20_detect_pipe_changes(struct dc_state 
*old_state,
return;
}
 
+   if (resource_is_pipe_type(new_pipe, OTG_MASTER) &&
+   resource_is_odm_topology_changed(new_pipe, old_pipe))
+   /* Detect odm changes */
+   new_pipe->update_flags.bits.odm = 1;
+
/* Exit on unchanged, unused pipe */
if (!old_pipe->plane_state && !new_pipe->plane_state)
return;
@@ -1551,10 +1556,6 @@ static void dcn20_detect_pipe_changes(struct dc_state 
*old_state,
 
/* Detect top pipe only changes */
if (resource_is_pipe_type(new_pipe, OTG_MASTER)) {
-   /* Detect odm changes */
-   if (resource_is_odm_topology_changed(new_pipe, old_pipe))
-   new_pipe->update_flags.bits.odm = 1;
-
/* Detect global sync changes */
if (old_pipe->pipe_dlg_param.vready_offset != 
new_pipe->pipe_dlg_param.vready_offset
|| old_pipe->pipe_dlg_param.vstartup_start != 
new_pipe->pipe_dlg_param.vstartup_start
@@ -1999,19 +2000,20 @@ void dcn20_program_front_end_for_ctx(
DC_LOGGER_INIT(dc->ctx->logger);
unsigned int prev_hubp_count = 0;
unsigned int hubp_count = 0;
+   struct pipe_ctx *pipe;
 
if (resource_is_pipe_topology_changed(dc->current_state, context))
resource_log_pipe_topology_update(dc, context);
 
if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) {
for (i = 0; i < dc->res_pool->pipe_count; i++) {
-   struct pipe_ctx *pipe_ctx = 
>res_ctx.pipe_ctx[i];
+   pipe = >res_ctx.pipe_ctx[i];
 
-   if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && 
pipe_ctx->plane_state) {
-   
ASSERT(!pipe_ctx->plane_state->triplebuffer_flips);
+   if (!pipe->top_pipe && !pipe->prev_odm_pipe && 
pipe->plane_state) {
+   ASSERT(!pipe->plane_state->triplebuffer_flips);
/*turn off triple buffer for full update*/
dc->hwss.program_triplebuffer(
-   dc, pipe_ctx, 
pipe_ctx->plane_state->triplebuffer_flips);
+   dc, pipe, 
pipe->plane_state->triplebuffer_flips);
}
}
}
@@ -2085,12 +2087,22 @@ void dcn20_program_front_end_for_ctx(
DC_LOG_DC("Reset mpcc for pipe %d\n", 
dc->current_state->res_ctx.pipe_ctx[i].pipe_idx);
}
 
+   /* update ODM for blanked OTG master pipes */
+   for (i = 0; i < dc->res_pool->pipe_count; i++) {
+   pipe = >res_ctx.pipe_ctx[i];
+   if (resource_is_pipe_type(pipe, OTG_MASTER) &&
+   !resource_is_pipe_type(pipe, DPP_PIPE) &&
+   pipe->update_flags.bits.odm &&
+   hws->funcs.update_odm)
+   hws->funcs.update_odm(dc, context, pipe);
+   }
+
/*
 * Program all updated pipes, order matters for mpcc setup. Start with
 * top pipe and program all pipes that follow in order
 */
for (i = 0; i < dc->res_pool->pipe_count; i++) {
-   struct pipe_ctx *pipe = &g

[PATCH 16/34] drm/amd/display: Init DPPCLK from SMU on dcn32

2024-02-28 Thread Alex Hung
From: Dillon Varone 

[WHY & HOW]
DPPCLK ranges should be obtained from the SMU when available.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Chaitanya Dhere 
Acked-by: Alex Hung 
Signed-off-by: Dillon Varone 
---
 .../display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c  | 14 ++
 .../drm/amd/display/dc/dml2/dml2_wrapper.c| 28 +--
 .../drm/amd/display/dc/dml2/dml2_wrapper.h|  3 ++
 .../dc/resource/dcn32/dcn32_resource.c|  2 ++
 .../dc/resource/dcn321/dcn321_resource.c  |  2 ++
 5 files changed, 41 insertions(+), 8 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 668f05c8654e..bec252e1dd27 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
@@ -216,6 +216,16 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
if (clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz > 1950)
clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz = 1950;
 
+   /* DPPCLK */
+   dcn32_init_single_clock(clk_mgr, PPCLK_DPPCLK,
+   
_mgr_base->bw_params->clk_table.entries[0].dppclk_mhz,
+   _entries_per_clk->num_dppclk_levels);
+   num_levels = num_entries_per_clk->num_dppclk_levels;
+   clk_mgr_base->bw_params->dc_mode_limit.dppclk_mhz = 
dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_DPPCLK);
+   //HW recommends limit of 1950 MHz in display clock for all DCN3.2.x
+   if (clk_mgr_base->bw_params->dc_mode_limit.dppclk_mhz > 1950)
+   clk_mgr_base->bw_params->dc_mode_limit.dppclk_mhz = 1950;
+
if (num_entries_per_clk->num_dcfclk_levels &&
num_entries_per_clk->num_dtbclk_levels &&
num_entries_per_clk->num_dispclk_levels)
@@ -240,6 +250,10 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
= 
khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz);
}
 
+   for (i = 0; i < num_levels; i++)
+   if (clk_mgr_base->bw_params->clk_table.entries[i].dppclk_mhz > 
1950)
+   
clk_mgr_base->bw_params->clk_table.entries[i].dppclk_mhz = 1950;
+
/* Get UCLK, update bounding box */
clk_mgr_base->funcs->get_memclk_states_from_smu(clk_mgr_base);
 
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 2a58a7687bdb..72cca367062e 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
@@ -703,13 +703,8 @@ static inline struct dml2_context 
*dml2_allocate_memory(void)
return (struct dml2_context *) kzalloc(sizeof(struct dml2_context), 
GFP_KERNEL);
 }
 
-bool dml2_create(const struct dc *in_dc, const struct 
dml2_configuration_options *config, struct dml2_context **dml2)
+static void dml2_init(const struct dc *in_dc, const struct 
dml2_configuration_options *config, struct dml2_context **dml2)
 {
-   // Allocate Mode Lib Ctx
-   *dml2 = dml2_allocate_memory();
-
-   if (!(*dml2))
-   return false;
 
// Store config options
(*dml2)->config = *config;
@@ -737,9 +732,18 @@ bool dml2_create(const struct dc *in_dc, const struct 
dml2_configuration_options
initialize_dml2_soc_bbox(*dml2, in_dc, &(*dml2)->v20.dml_core_ctx.soc);
 
initialize_dml2_soc_states(*dml2, in_dc, 
&(*dml2)->v20.dml_core_ctx.soc, &(*dml2)->v20.dml_core_ctx.states);
+}
+
+bool dml2_create(const struct dc *in_dc, const struct 
dml2_configuration_options *config, struct dml2_context **dml2)
+{
+   // Allocate Mode Lib Ctx
+   *dml2 = dml2_allocate_memory();
+
+   if (!(*dml2))
+   return false;
+
+   dml2_init(in_dc, config, dml2);
 
-   /*Initialize DML20 instance which calls dml2_core_create, and 
core_dcn3_populate_informative*/
-   //dml2_initialize_instance(&(*dml_ctx)->v20.dml_init);
return true;
 }
 
@@ -779,3 +783,11 @@ bool dml2_create_copy(struct dml2_context **dst_dml2,
 
return true;
 }
+
+void dml2_reinit(const struct dc *in_dc,
+const struct dml2_configuration_options 
*config,
+struct dml2_context **dml2)
+{
+
+   dml2_init(in_dc, config, dml2);
+}
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 ee0eb184eb6d..cc662d682fd4 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
@@ -214,6 +214,9 @@ void dml2_copy(struct dml2_context *dst_dml2,
struct dm

[PATCH 15/34] drm/amd/display: Add monitor patch for specific eDP

2024-02-28 Thread Alex Hung
From: Ryan Lin 

[WHY]
Some eDP panels' ext caps don't write initial values. The value of
dpcd_addr (0x317) can be random and the backlight control interface
will be incorrect.

[HOW]
Add new panel patches to remove sink ext caps.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org # 6.5.x
Cc: Tsung-hua Lin 
Cc: Chris Chi 
Reviewed-by: Wayne Lin 
Acked-by: Alex Hung 
Signed-off-by: Ryan Lin 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 6 --
 1 file changed, 4 insertions(+), 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 85b7f58a7f35..c27063305a13 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
@@ -67,6 +67,8 @@ static void apply_edid_quirks(struct edid *edid, struct 
dc_edid_caps *edid_caps)
/* Workaround for some monitors that do not clear DPCD 0x317 if 
FreeSync is unsupported */
case drm_edid_encode_panel_id('A', 'U', 'O', 0xA7AB):
case drm_edid_encode_panel_id('A', 'U', 'O', 0xE69B):
+   case drm_edid_encode_panel_id('B', 'O', 'E', 0x092A):
+   case drm_edid_encode_panel_id('L', 'G', 'D', 0x06D1):
DRM_DEBUG_DRIVER("Clearing DPCD 0x317 on monitor with panel id 
%X\n", panel_id);
edid_caps->panel_patch.remove_sink_ext_caps = true;
break;
@@ -120,6 +122,8 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
 
edid_caps->edid_hdmi = connector->display_info.is_hdmi;
 
+   apply_edid_quirks(edid_buf, edid_caps);
+
sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, );
if (sad_count <= 0)
return result;
@@ -146,8 +150,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
else
edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION;
 
-   apply_edid_quirks(edid_buf, edid_caps);
-
kfree(sads);
kfree(sadb);
 
-- 
2.34.1



[PATCH 14/34] drm/amd/display: Support long vblank feature

2024-02-28 Thread Alex Hung
From: Robin Chen 

[WHY]
We want to support low hz case, but the original
vtotal/vtotal_min/vtotal_max can't support more
than 0x7FFF.

[HOW]
We use the 2 HW reg to contorl long vblank case.
1. OTG_V_COUNT_STOP_CONTROL -> vcount_stop
2. OTG_V_COUNT_STOP_CONTROL2 -> vcount_stop_timer

vcount_stop define from which line we stop using vcount
and start using vcount2.
vcount_stop_timer define how long we use vcount2.

Ex:
Vtotal = 7
OTG_V_COUNT_STOP_CONTROL = 4
OTG_V_COUNT_STOP_CONTROL2 = 5

time: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
vcount  : 0, 1, 2, 3, -  -  -  -  -  4,  5,  6
vcount2 : 0, 1, 2, 3, 4,

Reviewed-by: Jun Lei 
Acked-by: Alex Hung 
Signed-off-by: ChunTao Tso 
Signed-off-by: Robin Chen
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  33 
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h  |   1 +
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c   |  28 +++
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.h   |   3 +
 .../amd/display/dc/hwss/dcn35/dcn35_init.c|   3 +-
 .../drm/amd/display/dc/hwss/hw_sequencer.h|   1 +
 .../amd/display/dc/inc/hw/timing_generator.h  |   7 +
 .../amd/display/dc/optc/dcn10/dcn10_optc.h|   6 +-
 .../amd/display/dc/optc/dcn35/dcn35_optc.c| 165 +-
 .../amd/display/dc/optc/dcn35/dcn35_optc.h|   6 +-
 .../dc/resource/dcn35/dcn35_resource.h|   2 +
 .../amd/display/modules/freesync/freesync.c   |   2 +
 12 files changed, 253 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 501e0298623a..daf6c7fe0906 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -386,6 +386,30 @@ static void dc_perf_trace_destroy(struct dc_perf_trace 
**perf_trace)
*perf_trace = NULL;
 }
 
+static bool set_long_vtotal(struct dc *dc, struct dc_stream_state *stream, 
struct dc_crtc_timing_adjust *adjust)
+{
+   if (!dc || !stream || !adjust)
+   return false;
+
+   if (!dc->current_state)
+   return false;
+
+   int i;
+
+   for (i = 0; i < MAX_PIPES; i++) {
+   struct pipe_ctx *pipe = >current_state->res_ctx.pipe_ctx[i];
+
+   if (pipe->stream == stream && pipe->stream_res.tg) {
+   if (dc->hwss.set_long_vtotal)
+   dc->hwss.set_long_vtotal(, 1, 
adjust->v_total_min, adjust->v_total_max);
+
+   return true;
+   }
+   }
+
+   return false;
+}
+
 /**
  *  dc_stream_adjust_vmin_vmax - look up pipe context & update parts of DRR
  *  @dc: dc reference
@@ -420,6 +444,15 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
stream->adjust.v_total_mid = adjust->v_total_mid;
stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num;
stream->adjust.v_total_min = adjust->v_total_min;
+   stream->adjust.allow_otg_v_count_halt = adjust->allow_otg_v_count_halt;
+
+   if (dc->caps.max_v_total != 0 &&
+   (adjust->v_total_max > dc->caps.max_v_total || 
adjust->v_total_min > dc->caps.max_v_total)) {
+   if (adjust->allow_otg_v_count_halt)
+   return set_long_vtotal(dc, stream, adjust);
+   else
+   return false;
+   }
 
for (i = 0; i < MAX_PIPES; i++) {
struct pipe_ctx *pipe = >current_state->res_ctx.pipe_ctx[i];
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 aae2f3a2660d..465e15f57f93 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -974,6 +974,7 @@ struct dc_crtc_timing_adjust {
uint32_t v_total_max;
uint32_t v_total_mid;
uint32_t v_total_mid_frame_num;
+   uint32_t allow_otg_v_count_halt;
 };
 
 
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 4b92df23ff0d..2e8ec58a16eb 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
@@ -1394,3 +1394,31 @@ void dcn35_set_static_screen_control(struct pipe_ctx 
**pipe_ctx,
set_static_screen_control(pipe_ctx[i]->stream_res.tg,
triggers, params->num_frames);
 }
+
+void dcn35_set_long_vblank(struct pipe_ctx **pipe_ctx,
+   int num_pipes, uint32_t v_total_min, uint32_t v_total_max)
+{
+   int i = 0;
+   struct long_vtotal_params params = {0};
+
+   params.vertical_total_max = v_total_max;
+   params.vertical_total_min = v_total_min;
+
+   for (i = 0; i < num_pipes; i++) {
+   if (!pipe_ctx[i])
+   continue;
+
+

[PATCH 13/34] drm/amd/display: 3.2.274

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

- Change default size for dummy plane in DML2
- Enable DML2 debug flags
- Add some forward declarations
- Add DML2 folder to include path
- Set DCN351 BB and IP the same as DCN35
- Override min required DCFCLK in dml1_validate
- Fix function banner for amdgpu_dm_psr_disable_all()
- Allow dirty rects to be sent to dmub when abm is active
- Add debug key to allow disabling dtbclk
- Add debug prints for IPS testing
- Exit idle optimizations before HDCP execution
- Add entry and exit counters

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 c9485a7744d7..09c6a393642a 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.273"
+#define DC_VER "3.2.274"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.34.1



[PATCH 12/34] drm/amd/display: Add entry and exit counters

2024-02-28 Thread Alex Hung
From: Anthony Koo 

[WHY & HOW]
Add new counters in the shared IPS firmware state.

Acked-by: Alex Hung 
Signed-off-by: Anthony Koo 
---
 drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h 
b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index a529e369b2ac..02ad641bd8df 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -724,7 +724,13 @@ union dmub_shared_state_ips_driver_signals {
  */
 struct dmub_shared_state_ips_fw {
union dmub_shared_state_ips_fw_signals signals; /**< 4 bytes, IPS 
signal bits */
-   uint32_t reserved[61]; /**< Reversed, to be updated when adding new 
fields. */
+   uint32_t rcg_entry_count; /**< Entry counter for RCG */
+   uint32_t rcg_exit_count; /**< Exit counter for RCG */
+   uint32_t ips1_entry_count; /**< Entry counter for IPS1 */
+   uint32_t ips1_exit_count; /**< Exit counter for IPS1 */
+   uint32_t ips2_entry_count; /**< Entry counter for IPS2 */
+   uint32_t ips2_exit_count; /**< Exit counter for IPS2 */
+   uint32_t reserved[55]; /**< Reversed, to be updated when adding new 
fields. */
 }; /* 248-bytes, fixed */
 
 /**
-- 
2.34.1



[PATCH 11/34] drm/amd/display: Exit idle optimizations before HDCP execution

2024-02-28 Thread Alex Hung
From: Nicholas Kazlauskas 

[WHY]
PSP can access DCN registers during command submission and we need
to ensure that DCN is not in PG before doing so.

[HOW]
Add a callback to DM to lock and notify DC for idle optimization exit.
It can't be DC directly because of a potential race condition with the
link protection thread and the rest of DM operation.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c| 10 ++
 drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h |  8 
 2 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c 
b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
index 5e01c6e24cbc..9a5a1726acaf 100644
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
+++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c
@@ -88,6 +88,14 @@ static uint8_t is_cp_desired_hdcp2(struct mod_hdcp *hdcp)
!hdcp->connection.is_hdcp2_revoked;
 }
 
+static void exit_idle_optimizations(struct mod_hdcp *hdcp)
+{
+   struct mod_hdcp_dm *dm = >config.dm;
+
+   if (dm->funcs.exit_idle_optimizations)
+   dm->funcs.exit_idle_optimizations(dm->handle);
+}
+
 static enum mod_hdcp_status execution(struct mod_hdcp *hdcp,
struct mod_hdcp_event_context *event_ctx,
union mod_hdcp_transition_input *input)
@@ -543,6 +551,8 @@ enum mod_hdcp_status mod_hdcp_process_event(struct mod_hdcp 
*hdcp,
memset(_ctx, 0, sizeof(struct mod_hdcp_event_context));
event_ctx.event = event;
 
+   exit_idle_optimizations(hdcp);
+
/* execute and transition */
exec_status = execution(hdcp, _ctx, >auth.trans_input);
trans_status = transition(
diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h 
b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
index a4d344a4db9e..cdb17b093f2b 100644
--- a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
+++ b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h
@@ -156,6 +156,13 @@ struct mod_hdcp_ddc {
} funcs;
 };
 
+struct mod_hdcp_dm {
+   void *handle;
+   struct {
+   void (*exit_idle_optimizations)(void *handle);
+   } funcs;
+};
+
 struct mod_hdcp_psp {
void *handle;
void *funcs;
@@ -272,6 +279,7 @@ struct mod_hdcp_display_query {
 struct mod_hdcp_config {
struct mod_hdcp_psp psp;
struct mod_hdcp_ddc ddc;
+   struct mod_hdcp_dm dm;
uint8_t index;
 };
 
-- 
2.34.1



[PATCH 10/34] drm/amd/display: Add debug prints for IPS testing

2024-02-28 Thread Alex Hung
From: Nicholas Kazlauskas 

[WHY]
To log commit states and when we transition in/out of allow and idle
states and the caller.

[HOW]
Add a new logging helper and wrap idle optimization calls to receive
the caller.

Reviewed-by: Duncan Ma 
Acked-by: Alex Hung 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  | 10 ++-
 drivers/gpu/drm/amd/display/dc/dc.h   |  7 +-
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  | 73 +++
 .../drm/amd/display/include/logger_types.h|  1 +
 4 files changed, 86 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 613d09c42f3b..501e0298623a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -4820,11 +4820,15 @@ bool dc_set_replay_allow_active(struct dc *dc, bool 
active)
return true;
 }
 
-void dc_allow_idle_optimizations(struct dc *dc, bool allow)
+void dc_allow_idle_optimizations_internal(struct dc *dc, bool allow, char 
const *caller_name)
 {
if (dc->debug.disable_idle_power_optimizations)
return;
 
+   if (allow != dc->idle_optimizations_allowed)
+   DC_LOG_IPS("%s: allow_idle old=%d new=%d (caller=%s)\n", 
__func__,
+  dc->idle_optimizations_allowed, allow, caller_name);
+
if (dc->caps.ips_support && (dc->config.disable_ips == 
DMUB_IPS_DISABLE_ALL))
return;
 
@@ -4839,10 +4843,10 @@ void dc_allow_idle_optimizations(struct dc *dc, bool 
allow)
dc->idle_optimizations_allowed = allow;
 }
 
-void dc_exit_ips_for_hw_access(struct dc *dc)
+void dc_exit_ips_for_hw_access_internal(struct dc *dc, const char *caller_name)
 {
if (dc->caps.ips_support)
-   dc_allow_idle_optimizations(dc, false);
+   dc_allow_idle_optimizations_internal(dc, false, caller_name);
 }
 
 bool dc_dmub_is_ips_idle_state(struct dc *dc)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index c1d8288a08b3..c9485a7744d7 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -2339,8 +2339,11 @@ void dc_get_clock(struct dc *dc, enum dc_clock_type 
clock_type, struct dc_clock_
 bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, struct 
dc_plane_state *plane,
struct dc_cursor_attributes *cursor_attr);
 
-void dc_allow_idle_optimizations(struct dc *dc, bool allow);
-void dc_exit_ips_for_hw_access(struct dc *dc);
+#define dc_allow_idle_optimizations(dc, allow) 
dc_allow_idle_optimizations_internal(dc, allow, __func__)
+#define dc_exit_ips_for_hw_access(dc) dc_exit_ips_for_hw_access_internal(dc, 
__func__)
+
+void dc_allow_idle_optimizations_internal(struct dc *dc, bool allow, const 
char *caller_name);
+void dc_exit_ips_for_hw_access_internal(struct dc *dc, const char 
*caller_name);
 bool dc_dmub_is_ips_idle_state(struct dc *dc);
 
 /* set min and max memory clock to lowest and highest DPM level, respectively 
*/
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 6083b1dcf050..b168dfc79381 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -910,6 +910,8 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv 
*dc_dmub_srv)
return;
}
 
+   DC_LOG_ERROR("%s: DMCUB error - collecting diagnostic data\n", 
__func__);
+
if (!dc_dmub_srv_get_diagnostic_data(dc_dmub_srv, _data)) {
DC_LOG_ERROR("%s: dc_dmub_srv_get_diagnostic_data failed.", 
__func__);
return;
@@ -1201,6 +1203,7 @@ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv 
*dc_dmub_srv, bool wait)
 
 static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle)
 {
+   volatile const struct dmub_shared_state_ips_fw *ips_fw;
struct dc_dmub_srv *dc_dmub_srv;
union dmub_rb_cmd cmd = {0};
 
@@ -1211,6 +1214,7 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, 
bool allow_idle)
return;
 
dc_dmub_srv = dc->ctx->dmub_srv;
+   ips_fw = 
_dmub_srv->dmub->shared_state[DMUB_SHARED_SHARE_FEATURE__IPS_FW].data.ips_fw;
 
memset(, 0, sizeof(cmd));
cmd.idle_opt_notify_idle.header.type = DMUB_CMD__IDLE_OPT;
@@ -1226,6 +1230,12 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, 
bool allow_idle)

_dmub_srv->dmub->shared_state[DMUB_SHARED_SHARE_FEATURE__IPS_DRIVER].data.ips_driver;
union dmub_shared_state_ips_driver_signals new_signals;
 
+   DC_LOG_IPS(
+   "%s wait idle (ips1_commit=%d ips2_commit=%d)",
+   __func__,
+   ips

[PATCH 09/34] drm/amd/display: Add debug key to allow disabling dtbclk

2024-02-28 Thread Alex Hung
From: Muhammad Ahmed 

[HOW]
Add debug key to allow disabling dtbclk

Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Muhammad Ahmed 
---
 drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 3 ++-
 drivers/gpu/drm/amd/display/dc/dc.h  | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

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 c378b879c76d..c6030bed95a0 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
@@ -244,7 +244,8 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base,
}
 
if (clk_mgr_base->clks.dtbclk_en && !new_clocks->dtbclk_en) {
-   dcn35_smu_set_dtbclk(clk_mgr, false);
+   if (clk_mgr->base.ctx->dc->config.allow_0_dtb_clk)
+   dcn35_smu_set_dtbclk(clk_mgr, false);
clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en;
}
/* check that we're not already in lower */
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index ee8453bf958f..c1d8288a08b3 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -435,6 +435,7 @@ struct dc_config {
unsigned int disable_ips;
unsigned int disable_ips_in_vpb;
bool usb4_bw_alloc_support;
+   bool allow_0_dtb_clk;
 };
 
 enum visual_confirm {
-- 
2.34.1



[PATCH 08/34] drm/amd/display: Allow dirty rects to be sent to dmub when abm is active

2024-02-28 Thread Alex Hung
From: Josip Pavic 

[WHY]
It's beneficial for ABM to know when new frame data are available.

[HOW]
Add new condition to allow dirty rects to be sent to DMUB when ABM is
active. ABM will use this as a signal that a new frame has arrived.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Anthony Koo 
Acked-by: Alex Hung 
Signed-off-by: Josip Pavic 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 5211c1c0f3c0..613d09c42f3b 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3270,6 +3270,9 @@ static bool dc_dmub_should_send_dirty_rect_cmd(struct dc 
*dc, struct dc_stream_s
if (stream->link->replay_settings.config.replay_supported)
return true;
 
+   if (stream->ctx->dce_version >= DCN_VERSION_3_5 && stream->abm_level)
+   return true;
+
return false;
 }
 
-- 
2.34.1



[PATCH 07/34] drm/amd/display: Fix function banner for amdgpu_dm_psr_disable_all()

2024-02-28 Thread Alex Hung
From: Roman Li 

[WHY]
Incorrect function name in function banner.

[HOW]
Correct name and brief description.

Reviewed-by: Hersen Wu 
Reviewed-by: Aurabindo Pillai 
Acked-by: Alex Hung 
Signed-off-by: Roman Li 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
index 1f08c6564c3b..a48a79e84e82 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
@@ -210,7 +210,7 @@ bool amdgpu_dm_psr_disable(struct dc_stream_state *stream)
 }
 
 /*
- * amdgpu_dm_psr_disable() - disable psr f/w
+ * amdgpu_dm_psr_disable_all() - disable psr f/w for all streams
  * if psr is enabled on any stream
  *
  * Return: true if success
-- 
2.34.1



[PATCH 06/34] drm/amd/display: Override min required DCFCLK in dml1_validate

2024-02-28 Thread Alex Hung
From: Sohaib Nadeem 

[WHY]:
Increasing min DCFCLK addresses underflow issues that occur when phantom
pipe is turned on for some Sub-Viewport configs

[HOW]:
dcn32_override_min_req_dcfclk is added to override DCFCLK value in
dml1_validate when subviewport is being used.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Alvin Lee 
Acked-by: Alex Hung 
Signed-off-by: Sohaib Nadeem 
---
 .../gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c   | 6 ++
 .../gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c  | 1 +
 .../gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h  | 3 +++
 3 files changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c 
b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
index 87760600e154..f98def6c8c2d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
@@ -782,3 +782,9 @@ void 
dcn32_update_dml_pipes_odm_policy_based_on_context(struct dc *dc, struct dc
pipe_cnt++;
}
 }
+
+void dcn32_override_min_req_dcfclk(struct dc *dc, struct dc_state *context)
+{
+   if (dcn32_subvp_in_use(dc, context) && 
context->bw_ctx.bw.dcn.clk.dcfclk_khz <= MIN_SUBVP_DCFCLK_KHZ)
+   context->bw_ctx.bw.dcn.clk.dcfclk_khz = MIN_SUBVP_DCFCLK_KHZ;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
index 3f3951f3ba98..f844f57ecc49 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
@@ -1771,6 +1771,7 @@ static bool dml1_validate(struct dc *dc, struct dc_state 
*context, bool fast_val
dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, 
vlevel);
 
dcn32_override_min_req_memclk(dc, context);
+   dcn32_override_min_req_dcfclk(dc, context);
 
BW_VAL_TRACE_END_WATERMARKS();
 
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h 
b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
index 0c87b0fabba7..2258c5c7212d 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
@@ -42,6 +42,7 @@
 #define SUBVP_ACTIVE_MARGIN_LIST_LEN 2
 #define DCN3_2_MAX_SUBVP_PIXEL_RATE_MHZ 1800
 #define DCN3_2_VMIN_DISPCLK_HZ 71700
+#define MIN_SUBVP_DCFCLK_KHZ 40
 
 #define TO_DCN32_RES_POOL(pool)\
container_of(pool, struct dcn32_resource_pool, base)
@@ -181,6 +182,8 @@ bool dcn32_subvp_vblank_admissable(struct dc *dc, struct 
dc_state *context, int
 
 void dcn32_update_dml_pipes_odm_policy_based_on_context(struct dc *dc, struct 
dc_state *context, display_e2e_pipe_params_st *pipes);
 
+void dcn32_override_min_req_dcfclk(struct dc *dc, struct dc_state *context);
+
 /* definitions for run time init of reg offsets */
 
 /* CLK SRC */
-- 
2.34.1



[PATCH 05/34] drm/amd/display: Set DCN351 BB and IP the same as DCN35

2024-02-28 Thread Alex Hung
From: Xi Liu 

[WHY & HOW]
DCN351 and DCN35 should use the same bounding box and IP settings.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Jun Lei 
Acked-by: Alex Hung 
Signed-off-by: Xi Liu 
---
 .../gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c   | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
index 17a58f41fc6a..a20f28a5d2e7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
@@ -228,17 +228,13 @@ void dml2_init_socbb_params(struct dml2_context *dml2, 
const struct dc *in_dc, s
break;
 
case dml_project_dcn35:
+   case dml_project_dcn351:
out->num_chans = 4;
out->round_trip_ping_latency_dcfclk_cycles = 106;
out->smn_latency_us = 2;
out->dispclk_dppclk_vco_speed_mhz = 3600;
break;
 
-   case dml_project_dcn351:
-   out->num_chans = 16;
-   out->round_trip_ping_latency_dcfclk_cycles = 1100;
-   out->smn_latency_us = 2;
-   break;
}
/* ---Overrides if available--- */
if (dml2->config.bbox_overrides.dram_num_chan)
-- 
2.34.1



[PATCH 04/34] drm/amd/display: Add DML2 folder to include path

2024-02-28 Thread Alex Hung
From: Aurabindo Pillai 

Add DML2 compilation rule in the Makefile.

Reviewed-by: Chaitanya Dhere 
Acked-by: Alex Hung 
Signed-off-by: Aurabindo Pillai 
---
 drivers/gpu/drm/amd/display/dc/dml2/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dml2/Makefile 
b/drivers/gpu/drm/amd/display/dc/dml2/Makefile
index acff3449b8d7..1c9498a72520 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml2/Makefile
@@ -67,6 +67,7 @@ frame_warn_flag := -Wframe-larger-than=2048
 endif
 endif
 
+subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc/dml2
 CFLAGS_$(AMDDALPATH)/dc/dml2/display_mode_core.o := $(dml2_ccflags) 
$(frame_warn_flag)
 CFLAGS_$(AMDDALPATH)/dc/dml2/display_mode_util.o := $(dml2_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml2/dml2_wrapper.o := $(dml2_ccflags)
-- 
2.34.1



[PATCH 03/34] drm/amd/display: Add some forward declarations

2024-02-28 Thread Alex Hung
From: Aurabindo Pillai 

[WHAT]
Add DML2 pipe and config struct forward declaration as a
preparation for DML2.

Reviewed-by: Chaitanya Dhere 
Acked-by: Alex Hung 
Signed-off-by: Aurabindo Pillai 
---
 drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.h 
b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.h
index 2f91244a7b01..1538b708d8be 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.h
@@ -30,6 +30,8 @@
 #include "dml2_dc_types.h"
 
 struct dml2_context;
+struct dml2_dml_to_dc_pipe_mapping;
+struct dml_display_cfg_st;
 
 /*
  * dml2_map_dc_pipes - Creates a pipe linkage in dc_state based on current 
display config.
-- 
2.34.1



[PATCH 02/34] drm/amd/display: Enable DML2 debug flags

2024-02-28 Thread Alex Hung
From: Aurabindo Pillai 

[WHY & HOW]
Enable DML2 related debug config options in DM for testing purposes.

Reviewed-by: Chaitanya Dhere 
Acked-by: Alex Hung 
Signed-off-by: Aurabindo Pillai 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++
 1 file changed, 3 insertions(+)

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 32efce81a5a7..e12f56ca3b6a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1766,6 +1766,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
if (amdgpu_dc_debug_mask & DC_FORCE_SUBVP_MCLK_SWITCH)
adev->dm.dc->debug.force_subvp_mclk_switch = true;
 
+   if (amdgpu_dc_debug_mask & DC_ENABLE_DML2)
+   adev->dm.dc->debug.using_dml2 = true;
+
adev->dm.dc->debug.visual_confirm = amdgpu_dc_visual_confirm;
 
/* TODO: Remove after DP2 receiver gets proper support of Cable ID 
feature */
-- 
2.34.1



[PATCH 01/34] drm/amd/display: Change default size for dummy plane in DML2

2024-02-28 Thread Alex Hung
From: Swapnil Patel 

[WHY & HOW]
Currently, to map dc states into dml_display_cfg,
We create a dummy plane if the stream doesn't have any planes
attached to it. This dummy plane uses max addersable width height.
This results in certain mode validations failing when they shouldn't.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Chaitanya Dhere 
Acked-by: Alex Hung 
Signed-off-by: Swapnil Patel 
---
 .../display/dc/dml2/dml2_translation_helper.c  | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
index 1ba6933d2b36..17a58f41fc6a 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
@@ -824,13 +824,25 @@ static struct scaler_data get_scaler_data_for_plane(const 
struct dc_plane_state
 
 static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, 
unsigned int location, const struct dc_stream_state *in)
 {
+   dml_uint_t width, height;
+
+   if (in->timing.h_addressable > 3840)
+   width = 3840;
+   else
+   width = in->timing.h_addressable;   // 4K max
+
+   if (in->timing.v_addressable > 2160)
+   height = 2160;
+   else
+   height = in->timing.v_addressable;  // 4K max
+
out->CursorBPP[location] = dml_cur_32bit;
out->CursorWidth[location] = 256;
 
out->GPUVMMinPageSizeKBytes[location] = 256;
 
-   out->ViewportWidth[location] = in->timing.h_addressable;
-   out->ViewportHeight[location] = in->timing.v_addressable;
+   out->ViewportWidth[location] = width;
+   out->ViewportHeight[location] = height;
out->ViewportStationary[location] = false;
out->ViewportWidthChroma[location] = 0;
out->ViewportHeightChroma[location] = 0;
@@ -849,7 +861,7 @@ static void populate_dummy_dml_plane_cfg(struct 
dml_plane_cfg_st *out, unsigned
out->HTapsChroma[location] = 0;
out->VTapsChroma[location] = 0;
out->SourceScan[location] = dml_rotation_0;
-   out->ScalerRecoutWidth[location] = in->timing.h_addressable;
+   out->ScalerRecoutWidth[location] = width;
 
out->LBBitPerPixel[location] = 57;
 
-- 
2.34.1



[PATCH 00/34] DC Patches Feb 28, 2020

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

* Fixes on HDCP, eDP and FW idle check.
* Enhancement in debug messages
* Improvement on updates sequences
* DPP refactoring to a new directory
* Enhancements in DMUB

Cc: Daniel Wheeler 

Allen Pan (1):
  drm/amd/display: Add a dc_state NULL check in dc_state_release

Alvin Lee (1):
  drm/amd/display: Backup and restore only on full updates

Anthony Koo (2):
  drm/amd/display: Add entry and exit counters
  drm/amd/display: Update DMUB flags and definitions

Aric Cyr (2):
  drm/amd/display: 3.2.274
  drm/amd/display: 3.2.275

Aurabindo Pillai (3):
  drm/amd/display: Enable DML2 debug flags
  drm/amd/display: Add some forward declarations
  drm/amd/display: Add DML2 folder to include path

ChunTao Tso (1):
  drm/amd/display: Amend coasting vtotal for replay low hz

Dillon Varone (1):
  drm/amd/display: Init DPPCLK from SMU on dcn32

George Shen (1):
  drm/amd/display: Add left edge pixel for YCbCr422/420 + ODM pipe split

Josip Pavic (1):
  drm/amd/display: Allow dirty rects to be sent to dmub when abm is
active

Muhammad Ahmed (2):
  drm/amd/display: Add debug key to allow disabling dtbclk
  drm/amd/display: Set the power_down_on_boot function pointer to null

Nicholas Kazlauskas (6):
  drm/amd/display: Add debug prints for IPS testing
  drm/amd/display: Exit idle optimizations before HDCP execution
  drm/amd/display: Fix idle check for shared firmware state
  drm/amd/display: Add guards for idle on reg read/write
  drm/amd/display: Guard cursor idle reallow by DC debug option
  drm/amd/display: Add debug counters to IPS exit prints

Revalla Hari Krishna (1):
  drm/amd/display: Refactor DPP into a component directory

Robin Chen (1):
  drm/amd/display: Support long vblank feature

Rodrigo Siqueira (2):
  drm/amd/display: Return the correct HDCP error code
  drm/amd/display: Add comments to v_total calculation and drop legacy
TODO

Roman Li (1):
  drm/amd/display: Fix function banner for amdgpu_dm_psr_disable_all()

Ryan Lin (1):
  drm/amd/display: Add monitor patch for specific eDP

Sohaib Nadeem (1):
  drm/amd/display: Override min required DCFCLK in dml1_validate

Swapnil Patel (1):
  drm/amd/display: Change default size for dummy plane in DML2

Wenjing Liu (4):
  drm/amd/display: Update odm when ODM combine is changed on an otg
master pipe with no plane
  drm/amd/display: Implement update_planes_and_stream_v3 sequence
  drm/amd/display: Lock all enabled otg pipes even with no planes
  drm/amd/display: Implement wait_for_odm_update_pending_complete

Xi Liu (1):
  drm/amd/display: Set DCN351 BB and IP the same as DCN35

 drivers/gpu/drm/amd/display/Makefile  |   1 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   3 +
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |   6 +-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c |   2 +-
 drivers/gpu/drm/amd/display/dc/Makefile   |   2 +-
 .../display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c  |  14 +
 .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c  |   3 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c  | 824 --
 .../gpu/drm/amd/display/dc/core/dc_resource.c |  37 +
 .../gpu/drm/amd/display/dc/core/dc_state.c|   4 +-
 .../gpu/drm/amd/display/dc/core/dc_stream.c   |   4 +-
 drivers/gpu/drm/amd/display/dc/dc.h   | 174 ++--
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  |  94 ++
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h  |   1 +
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h  |   1 +
 drivers/gpu/drm/amd/display/dc/dc_types.h |   4 +-
 .../gpu/drm/amd/display/dc/dce/dmub_replay.c  |   2 +-
 drivers/gpu/drm/amd/display/dc/dcn10/Makefile |   4 +-
 .../amd/display/dc/dcn10/dcn10_cm_common.c|   2 +-
 .../gpu/drm/amd/display/dc/dcn10/dcn10_opp.c  |   1 +
 drivers/gpu/drm/amd/display/dc/dcn20/Makefile |   2 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_opp.c  |  14 +
 .../gpu/drm/amd/display/dc/dcn20/dcn20_opp.h  |   2 +
 .../gpu/drm/amd/display/dc/dcn201/Makefile|   2 +-
 .../drm/amd/display/dc/dcn201/dcn201_opp.c|   1 +
 drivers/gpu/drm/amd/display/dc/dcn30/Makefile |   2 -
 .../amd/display/dc/dcn30/dcn30_cm_common.c|   2 +-
 drivers/gpu/drm/amd/display/dc/dcn32/Makefile |   2 +-
 .../display/dc/dcn32/dcn32_resource_helpers.c |   6 +
 drivers/gpu/drm/amd/display/dc/dcn35/Makefile |   2 +-
 drivers/gpu/drm/amd/display/dc/dml2/Makefile  |   1 +
 .../display/dc/dml2/dml2_dc_resource_mgmt.h   |   2 +
 .../display/dc/dml2/dml2_translation_helper.c |  24 +-
 .../drm/amd/display/dc/dml2/dml2_wrapper.c|  28 +-
 .../drm/amd/display/dc/dml2/dml2_wrapper.h|   3 +
 drivers/gpu/drm/amd/display/dc/dpp/Makefile   |  77 ++
 .../amd/display/dc/dpp/dcn10/CMakeLists.txt   |   6 +
 .../display/dc/{ => dpp}/dcn10/dcn10_dpp.c|   2 +-
 .../display/dc/{ => dpp}/dcn10/dcn10_dpp.h|   0
 .../display/dc/{ => dpp}/dcn10/dcn10_dpp_cm.c |   4 +-
 .../dc/{ => dpp}/dcn10/dcn10_dpp_dscl.c   |   2 +-
 

Re: [RFC PATCH 2/2] drm/amd/display: switch amdgpu_dm_connector to use struct drm_edid

2024-01-26 Thread Alex Hung




On 2024-01-26 09:28, 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. There are a couple of cast warnings and it was only
tested with IGT.

Signed-off-by: Melissa Wen 
---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 63 ++-
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  4 +-
  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  9 +--
  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 23 +++
  4 files changed, 51 insertions(+), 48 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 68e71e2ea472..741081d73bb3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3277,12 +3277,12 @@ void amdgpu_dm_update_connector_after_detect(
>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->edid = drm_edid_alloc(edid, 
(edid->extensions + 1) * EDID_LENGTH);
  
  			if (aconnector->dc_link->aux_mode)

drm_dp_cec_set_edid(>dm_dp_aux.aux,
-   aconnector->edid);
+   
drm_edid_raw(aconnector->edid));
}
  
  		if (!aconnector->timing_requested) {

@@ -3293,13 +3293,13 @@ void amdgpu_dm_update_connector_after_detect(
"failed to create 
aconnector->requested_timing\n");
}
  
-		drm_connector_update_edid_property(connector, aconnector->edid);

+   drm_edid_connector_update(connector, aconnector->edid);
amdgpu_dm_update_freesync_caps(connector, aconnector->edid);
update_connector_ext_caps(aconnector);
} else {
drm_dp_cec_unset_edid(>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;
@@ -6564,7 +6564,6 @@ static void amdgpu_dm_connector_funcs_force(struct 
drm_connector *connector)
struct dc_link *dc_link = aconnector->dc_link;
struct dc_sink *dc_em_sink = aconnector->dc_em_sink;
const struct drm_edid *drm_edid;
-   const struct edid *edid;
  
  	/*

 * Note: drm_get_edid gets edid in the following order:
@@ -6578,11 +6577,12 @@ static void amdgpu_dm_connector_funcs_force(struct 
drm_connector *connector)
DRM_ERROR("No EDID found on connector: %s.\n", connector->name);
return;
}
-   edid = drm_edid_raw(drm_edid);
-   aconnector->edid = edid;
-
+   aconnector->edid = drm_edid;
+   drm_edid_connector_update(connector, drm_edid);
/* Update emulated (virtual) sink's EDID */
if (dc_em_sink && dc_link) {
+   const struct edid *edid = drm_edid_raw(drm_edid);
+
memset(_em_sink->edid_caps, 0, sizeof(struct dc_edid_caps));
memmove(dc_em_sink->dc_edid.raw_edid, (uint8_t *)edid, 
(edid->extensions + 1) * EDID_LENGTH);
dm_helpers_parse_edid_caps(
@@ -6633,13 +6633,13 @@ static void create_eml_sink(struct amdgpu_dm_connector 
*aconnector)
return;
}
  
-	edid = drm_edid_raw(drm_edid);

-
-   if (drm_detect_hdmi_monitor(edid))
+   if (connector->display_info.is_hdmi)
init_params.sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
  
-	aconnector->edid = edid;

+   aconnector->edid = drm_edid;
+   drm_edid_connector_update(connector, drm_edid);
  
+	edid = drm_edid_raw(drm_edid);

aconnector->dc_em_sink = dc_link_add_remote_sink(
aconnector->dc_link,
(uint8_t *)edid,
@@ -7322,16 +7322,16 @@ static void amdgpu_set_panel_orientation(struct 
drm_connector *connector)
  }
  
  static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector,

- struct edid *edid)
+ const struct drm_edid *drm_edid)
  {
struct amdgpu_dm_connector *amdgpu_dm_connector =
to_amdgpu_dm_connector(connector);
  
-	if (edid) {

+   if (drm_edid) {
/* empty probed_modes */
INIT_LIST_HEAD(>probed_modes);

Re: [PATCH] drm/amd/display: Drop 'acrtc' and add 'new_crtc_state' NULL check for writeback requests.

2024-01-15 Thread Alex Hung

Thanks for catching this.

Reviewed-by: Alex Hung 

On 2024-01-13 02:11, Srinivasan Shanmugam wrote:

Return value of 'to_amdgpu_crtc' which is container_of(...) can't be
null, so it's null check 'acrtc' is dropped.

Fixing the below:
drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:9302 
amdgpu_dm_atomic_commit_tail() error: we previously assumed 'acrtc' could be 
null (see line 9299)

Add 'new_crtc_state'NULL check for function
'drm_atomic_get_new_crtc_state' that retrieves the new state for a CRTC,
while enabling writeback requests.

Cc: sta...@vger.kernel.org
Cc: Alex Hung 
Cc: Aurabindo Pillai 
Cc: Rodrigo Siqueira 
Cc: Hamza Mahfooz 
Signed-off-by: Srinivasan Shanmugam 
---
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 +++---
  1 file changed, 3 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 95ff3800fc87..8eb381d5f6b8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9294,10 +9294,10 @@ static void amdgpu_dm_atomic_commit_tail(struct 
drm_atomic_state *state)
if (!new_con_state->writeback_job)
continue;
  
-		new_crtc_state = NULL;

+   new_crtc_state = drm_atomic_get_new_crtc_state(state, 
>base);
  
-		if (acrtc)

-   new_crtc_state = drm_atomic_get_new_crtc_state(state, 
>base);
+   if (!new_crtc_state)
+   continue;
  
  		if (acrtc->wb_enabled)

continue;


[PATCH 19/19] drm/amd/display: 3.2.267

2024-01-10 Thread Alex Hung
From: Martin Leung 

- Align the returned error code with legacy DP
- Allow Z8 for multiplane configurations on DCN35
- Set default Z8 minimum residency for DCN35
- Rework DC Z10 restore
- Enable Panel Replay for static screen use case
- Add DP audio BW validation
- Fix dml2 assigned pipe search
- Ensure populate uclk in bb construction
- Update P010 scaling cap
- Reenable windowed mpo odm support
- Fix DML2 watermark calculation
- Clear OPTC mem select on disable
- Floor to mhz when requesting dpp disp clock changes to SMU
- Port DENTIST hang and TDR fixes to OTG disable W/A
- Add logging resource checks
- Add Replay IPS register for DMUB command table
- Init link enc resources in dc_state only if res_pool presents
- Allow IPS2 during Replay

Acked-by: Alex Hung 
Signed-off-by: Martin Leung 
---
 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 c9317ea0258e..1d052742d4c7 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.266"
+#define DC_VER "3.2.267"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.34.1



[PATCH 18/19] drm/amd/display: Align the returned error code with legacy DP

2024-01-10 Thread Alex Hung
From: Wayne Lin 

[Why]
For usb4 connector, AUX transaction is handled by dmub utilizing a differnt
code path comparing to legacy DP connector. If the usb4 DP connector is
disconnected, AUX access will report EBUSY and cause igt@kms_dp_aux_dev
fail.

[How]
Align the error code with the one reported by legacy DP as EIO.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Acked-by: Alex Hung 
Signed-off-by: Wayne Lin 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 5 +
 1 file changed, 5 insertions(+)

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 d3966ce3dc91..e3915c4f8566 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
@@ -978,6 +978,11 @@ int dm_helper_dmub_aux_transfer_sync(
struct aux_payload *payload,
enum aux_return_code_type *operation_result)
 {
+   if (!link->hpd_status) {
+   *operation_result = AUX_RET_ERROR_HPD_DISCON;
+   return -1;
+   }
+
return amdgpu_dm_process_dmub_aux_transfer_sync(ctx, link->link_index, 
payload,
operation_result);
 }
-- 
2.34.1



[PATCH 17/19] drm/amd/display: Allow Z8 for multiplane configurations on DCN35

2024-01-10 Thread Alex Hung
From: Nicholas Kazlauskas 

[Why]
Power improvement over DCN314, but also addresses a functional issue
where plane_state remains uncleared on pipes that aren't actually
active.

[How]
Update the check to allow for zero streams to be treated as z8 allow.
Update the check to remove plane count on the active stream case.

Z8 will still be blocked based on stutter duration, which is likely to
be the case for most multi plane configurations.

Reviewed-by: Gabe Teeger 
Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
index 475c4ec43c01..a85693caebd5 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
@@ -583,9 +583,9 @@ void dcn35_decide_zstate_support(struct dc *dc, struct 
dc_state *context)
plane_count++;
}
 
-   if (plane_count == 0) {
+   if (context->stream_count == 0 || plane_count == 0) {
support = DCN_ZSTATE_SUPPORT_ALLOW;
-   } else if (plane_count == 1 && context->stream_count == 1 && 
context->streams[0]->signal == SIGNAL_TYPE_EDP) {
+   } else if (context->stream_count == 1 && context->streams[0]->signal == 
SIGNAL_TYPE_EDP) {
struct dc_link *link = context->streams[0]->sink->link;
bool is_pwrseq0 = link && link->link_index == 0;
bool is_psr1 = link && link->psr_settings.psr_version == 
DC_PSR_VERSION_1 && !link->panel_config.psr.disable_psr;
-- 
2.34.1



[PATCH 16/19] drm/amd/display: Set default Z8 minimum residency for DCN35

2024-01-10 Thread Alex Hung
From: Nicholas Kazlauskas 

[Why & How]
Match DCN314's policy.

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

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 7d8e957d6a19..5f7cf01abef9 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
@@ -764,6 +764,7 @@ static const struct dc_debug_options debug_defaults_drv = {
},
.seamless_boot_odm_combine = DML_FAIL_SOURCE_PIXEL_FORMAT,
.enable_z9_disable_interface = true, /* Allow support for the PMFW 
interface for disable Z9*/
+   .minimum_z8_residency_time = 2100,
.using_dml2 = true,
.support_eDP1_5 = true,
.enable_hpo_pg_support = false,
-- 
2.34.1



[PATCH 15/19] drm/amd/display: Rework DC Z10 restore

2024-01-10 Thread Alex Hung
From: Nicholas Kazlauskas 

[Why]
The call currently does two things:
1. Exits DMCUB from idle optimization if it was in
2. Checks DMCUB scratch register to determine if we need to call
   DMCUB to do deferred HW restore and then sends the command if it's
   ready for it.

By doing (1) we prevent driver idle from being renotified in the cases
where driver had previously allowed DC level idle optimizations via
dc_allow_idle_optimizations since it thinks:

allow == dc->idle_optimizations_allowed

...and that the operation is a no-op.

We want driver idle to be resent at the next opprotunity to do so
for video playback cases.

[How]
Migrate all usecases of dc_z10_restore to only perform (2).

Add extra calls to dc_allow_idle_optimizations to handle (1) and also
keep SW state matching with when we requested enter/exit of DMCUB
idle optimizations.

Ensure cursor idle optimizations false always get called when IPS
is supported.

Further rework/redesign is needed to decide whether we need a separate
level of DM allow vs DC allow and when to attempt re-entry.

Reviewed-by: Yihan Zhu 
Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  | 11 ++-
 drivers/gpu/drm/amd/display/dc/core/dc_stream.c   |  9 +
 .../gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c   |  2 --
 3 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index aa7c02ba948e..af83ec23f3a0 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1836,8 +1836,8 @@ static enum dc_status dc_commit_state_no_check(struct dc 
*dc, struct dc_state *c
struct dc_state *old_state;
bool subvp_prev_use = false;
 
-   dc_z10_restore(dc);
dc_allow_idle_optimizations(dc, false);
+   dc_z10_restore(dc);
 
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *old_pipe = 
>current_state->res_ctx.pipe_ctx[i];
@@ -3376,6 +3376,9 @@ static void commit_planes_for_stream_fast(struct dc *dc,
int i, j;
struct pipe_ctx *top_pipe_to_program = NULL;
struct dc_stream_status *stream_status = NULL;
+   if (dc->caps.ips_support)
+   dc_allow_idle_optimizations(dc, false);
+
dc_z10_restore(dc);
 
top_pipe_to_program = resource_get_otg_master_for_stream(
@@ -3503,6 +3506,9 @@ static void commit_planes_for_stream(struct dc *dc,
// dc->current_state anymore, so we have to cache it before we apply
// the new SubVP context
subvp_prev_use = false;
+   if (dc->caps.ips_support)
+   dc_allow_idle_optimizations(dc, false);
+
dc_z10_restore(dc);
if (update_type == UPDATE_TYPE_FULL)
wait_for_outstanding_hw_updates(dc, context);
@@ -4686,6 +4692,9 @@ void dc_set_power_state(
case DC_ACPI_CM_POWER_STATE_D0:
dc_state_construct(dc, dc->current_state);
 
+   if (dc->caps.ips_support)
+   dc_allow_idle_optimizations(dc, false);
+
dc_z10_restore(dc);
 
dc->hwss.init_hw(dc);
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 54670e0b1518..23f4f3c070cb 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -309,7 +309,6 @@ bool dc_stream_set_cursor_attributes(
 
stream->cursor_attributes = *attributes;
 
-   dc_z10_restore(dc);
/* disable idle optimizations while updating cursor */
if (dc->idle_optimizations_allowed) {
dc_allow_idle_optimizations(dc, false);
@@ -381,12 +380,14 @@ bool dc_stream_set_cursor_position(
}
 
dc = stream->ctx->dc;
-   dc_z10_restore(dc);
 
/* disable idle optimizations if enabling cursor */
-   if (dc->idle_optimizations_allowed && (!stream->cursor_position.enable 
|| dc->debug.exit_idle_opt_for_cursor_updates)
-   && position->enable) {
+   if (dc->idle_optimizations_allowed &&
+   (!stream->cursor_position.enable || 
dc->debug.exit_idle_opt_for_cursor_updates ||
+dc->caps.ips_support) &&
+   position->enable) {
dc_allow_idle_optimizations(dc, false);
+   dc_z10_restore(dc);
reset_idle_optimizations = true;
}
 
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 8b6c49622f3b..da4f98de9b82 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
@@ -708,8 +708

[PATCH 14/19] drm/amd/display: Enable Panel Replay for static screen use case

2024-01-10 Thread Alex Hung
From: Tom Chung 

[Why]
Enable the Panel Replay if eDP panel and ASIC support.
(prioritize Panel Replay over PSR)

[How]
- Setup the Panel Replay config during the device init
  (prioritize Panel Replay over PSR).
- Separate the Replay init function into two functions
  amdgpu_dm_link_setup_replay() and amdgpu_dm_set_replay_caps()
  to fix the issue in the earlier commit that cause PSR and Replay
  enabled at the same time.

Reviewed-by: Sun peng Li 
Acked-by: Alex Hung 
Signed-off-by: Tom Chung 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  42 ++-
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c|  59 +++--
 .../amd/display/amdgpu_dm/amdgpu_dm_replay.c  | 119 ++
 .../amd/display/amdgpu_dm/amdgpu_dm_replay.h  |   4 +-
 4 files changed, 156 insertions(+), 68 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 95ff3800fc87..f9e41006ac87 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -67,6 +67,7 @@
 #include "amdgpu_dm_debugfs.h"
 #endif
 #include "amdgpu_dm_psr.h"
+#include "amdgpu_dm_replay.h"
 
 #include "ivsrcid/ivsrcid_vislands30.h"
 
@@ -4393,6 +4394,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
enum dc_connection_type new_connection_type = dc_connection_none;
const struct dc_plane_cap *plane;
bool psr_feature_enabled = false;
+   bool replay_feature_enabled = false;
int max_overlay = dm->dc->caps.max_slave_planes;
 
dm->display_indexes_num = dm->dc->caps.max_streams;
@@ -4504,6 +4506,23 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
}
}
 
+   /* Determine whether to enable Replay support by default. */
+   if (!(amdgpu_dc_debug_mask & DC_DISABLE_REPLAY)) {
+   switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
+   case IP_VERSION(3, 1, 4):
+   case IP_VERSION(3, 1, 5):
+   case IP_VERSION(3, 1, 6):
+   case IP_VERSION(3, 2, 0):
+   case IP_VERSION(3, 2, 1):
+   case IP_VERSION(3, 5, 0):
+   replay_feature_enabled = true;
+   break;
+   default:
+   replay_feature_enabled = amdgpu_dc_feature_mask & 
DC_REPLAY_MASK;
+   break;
+   }
+   }
+
/* loops over all connectors on the board */
for (i = 0; i < link_cnt; i++) {
struct dc_link *link = NULL;
@@ -4572,6 +4591,11 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)

amdgpu_dm_update_connector_after_detect(aconnector);
setup_backlight_device(dm, aconnector);
 
+   /* Disable PSR if Replay can be enabled */
+   if (replay_feature_enabled)
+   if (amdgpu_dm_set_replay_caps(link, 
aconnector))
+   psr_feature_enabled = false;
+
if (psr_feature_enabled)
amdgpu_dm_set_psr_caps(link);
 
@@ -8521,10 +8545,17 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
dm_update_pflip_irq_state(drm_to_adev(dev),
  acrtc_attach);
 
-   if ((acrtc_state->update_type > UPDATE_TYPE_FAST) &&
-   
acrtc_state->stream->link->psr_settings.psr_version != 
DC_PSR_VERSION_UNSUPPORTED &&
-   
!acrtc_state->stream->link->psr_settings.psr_feature_enabled)
-   amdgpu_dm_link_setup_psr(acrtc_state->stream);
+   if (acrtc_state->update_type > UPDATE_TYPE_FAST) {
+   if 
(acrtc_state->stream->link->replay_settings.config.replay_supported &&
+   
!acrtc_state->stream->link->replay_settings.replay_feature_enabled) {
+   struct amdgpu_dm_connector *aconn =
+   (struct amdgpu_dm_connector 
*)acrtc_state->stream->dm_stream_context;
+   
amdgpu_dm_link_setup_replay(acrtc_state->stream->link, aconn);
+   } else if 
(acrtc_state->stream->link->psr_settings.psr_version != 
DC_PSR_VERSION_UNSUPPORTED &&
+   
!acrtc_state->stream->link->psr_settings.psr_feature_enabled) {
+   amdgpu_dm_link_setup_psr(acrtc_state->stream);
+   }
+   }
 
  

[PATCH 13/19] drm/amd/display: Add DP audio BW validation

2024-01-10 Thread Alex Hung
From: George Shen 

[Why]
Timings with small HBlank (such as CVT RBv2) can result in insufficient
HBlank bandwidth for audio SDP transmission when DSC is active. This
will cause some higher bandwidth audio modes to fail.

The combination of CVT RBv2 timings + DSC can commonly be encountered
in MST scenarios.

[How]
Add DP audio bandwidth validation for 8b/10b MST and 128b/132b SST/MST
cases and filter out modes that cannot be supported with the current
timing config.

Reviewed-by: Wenjing Liu 
Acked-by: Alex Hung 
Signed-off-by: George Shen 
---
 .../gpu/drm/amd/display/dc/dce/dce_audio.c| 288 +-
 .../gpu/drm/amd/display/dc/dce/dce_audio.h|   3 +-
 .../amd/display/dc/hwss/dce110/dce110_hwseq.c |  56 +++-
 drivers/gpu/drm/amd/display/dc/inc/hw/audio.h |   3 +-
 .../gpu/drm/amd/display/include/audio_types.h |  15 +
 5 files changed, 349 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c 
b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
index f0458b8f00af..07b507150c51 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
@@ -239,27 +239,289 @@ static void check_audio_bandwidth_hdmi(
}
}
 }
+static struct fixed31_32 get_link_symbol_clk_freq_mhz(enum dc_link_rate 
link_rate)
+{
+   switch (link_rate) {
+   case LINK_RATE_LOW:
+   return dc_fixpt_from_int(162); /* 162 MHz */
+   case LINK_RATE_HIGH:
+   return dc_fixpt_from_int(270); /* 270 MHz */
+   case LINK_RATE_HIGH2:
+   return dc_fixpt_from_int(540); /* 540 MHz */
+   case LINK_RATE_HIGH3:
+   return dc_fixpt_from_int(810); /* 810 MHz */
+   case LINK_RATE_UHBR10:
+   return dc_fixpt_from_fraction(3125, 10); /* 312.5 MHz */
+   case LINK_RATE_UHBR13_5:
+   return dc_fixpt_from_fraction(421875, 1000); /* 421.875 MHz */
+   case LINK_RATE_UHBR20:
+   return dc_fixpt_from_int(625); /* 625 MHz */
+   default:
+   /* Unexpected case, this requires debug if encountered. */
+   ASSERT(0);
+   return dc_fixpt_from_int(0);
+   }
+}
+
+struct dp_audio_layout_config {
+   uint8_t layouts_per_sample_denom;
+   uint8_t symbols_per_layout;
+   uint8_t max_layouts_per_audio_sdp;
+};
+
+static void get_audio_layout_config(
+   uint32_t channel_count,
+   enum dp_link_encoding encoding,
+   struct dp_audio_layout_config *output)
+{
+   /* Assuming L-PCM audio. Current implementation uses max 1 layout per 
SDP,
+* with each layout being the same size (8ch layout).
+*/
+   if (encoding == DP_8b_10b_ENCODING) {
+   if (channel_count == 2) {
+   output->layouts_per_sample_denom = 4;
+   output->symbols_per_layout = 40;
+   output->max_layouts_per_audio_sdp = 1;
+   } else if (channel_count == 8) {
+   output->layouts_per_sample_denom = 1;
+   output->symbols_per_layout = 40;
+   output->max_layouts_per_audio_sdp = 1;
+   }
+   } else if (encoding == DP_128b_132b_ENCODING) {
+   if (channel_count == 2) {
+   output->layouts_per_sample_denom = 4;
+   output->symbols_per_layout = 10;
+   output->max_layouts_per_audio_sdp = 1;
+   } else if (channel_count == 8) {
+   output->layouts_per_sample_denom = 1;
+   output->symbols_per_layout = 10;
+   output->max_layouts_per_audio_sdp = 1;
+   }
+   }
+}
 
-/*For DP SST, calculate if specified sample rates can fit into a given timing 
*/
-static void check_audio_bandwidth_dpsst(
+static uint32_t get_av_stream_map_lane_count(
+   enum dp_link_encoding encoding,
+   enum dc_lane_count lane_count,
+   bool is_mst)
+{
+   uint32_t av_stream_map_lane_count = 0;
+
+   if (encoding == DP_8b_10b_ENCODING) {
+   if (!is_mst)
+   av_stream_map_lane_count = lane_count;
+   else
+   av_stream_map_lane_count = 4;
+   } else if (encoding == DP_128b_132b_ENCODING) {
+   av_stream_map_lane_count = 4;
+   }
+
+   ASSERT(av_stream_map_lane_count != 0);
+
+   return av_stream_map_lane_count;
+}
+
+static uint32_t get_audio_sdp_overhead(
+   enum dp_link_encoding encoding,
+   enum dc_lane_count lane_count,
+   bool is_mst)
+{
+   uint32_t audio_sdp_overhead = 0;
+
+   if (encoding == DP_8b_10b_ENCODING) {
+   if (is_mst)
+   audio_sdp_overhead = 16; /* 4 * 2 + 8 */
+   else
+   audio_sdp_overhead = lane_count * 2 + 8;
+   } else i

[PATCH 12/19] drm/amd/display: Fix dml2 assigned pipe search

2024-01-10 Thread Alex Hung
From: Dmytro Laktyushkin 

[Why & How]
DML2 currently finds assigned pipes in array order rather than the
existing linked list order. This results in rearranging pipe order
on flip and more importantly otg inst and pipe idx mismatch.

This change preserves the order of existing pipes and guarantees
the head pipe will have matching otg inst and pipe idx.

Reviewed-by: Gabe Teeger 
Acked-by: Alex Hung 
Signed-off-by: Dmytro Laktyushkin 
---
 .../display/dc/dml2/dml2_dc_resource_mgmt.c   | 36 ++-
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c 
b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
index 0baf39d64a2d..a0ce681b26c6 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
@@ -141,14 +141,28 @@ static unsigned int find_pipes_assigned_to_plane(struct 
dml2_context *ctx,
 {
int i;
unsigned int num_found = 0;
-   unsigned int plane_id_assigned_to_pipe;
+   unsigned int plane_id_assigned_to_pipe = -1;
 
for (i = 0; i < ctx->config.dcn_pipe_count; i++) {
-   if (state->res_ctx.pipe_ctx[i].plane_state && get_plane_id(ctx, 
state, state->res_ctx.pipe_ctx[i].plane_state,
-   state->res_ctx.pipe_ctx[i].stream->stream_id,
-   
ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_index[state->res_ctx.pipe_ctx[i].pipe_idx],
 _id_assigned_to_pipe)) {
-   if (plane_id_assigned_to_pipe == plane_id)
-   pipes[num_found++] = i;
+   struct pipe_ctx *pipe = >res_ctx.pipe_ctx[i];
+
+   if (!pipe->stream)
+   continue;
+
+   get_plane_id(ctx, state, pipe->plane_state, 
pipe->stream->stream_id,
+   
ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_index[pipe->pipe_idx],
+   _id_assigned_to_pipe);
+   if (pipe->plane_state && plane_id_assigned_to_pipe == plane_id 
&& !pipe->top_pipe && !pipe->prev_odm_pipe) {
+   while (pipe) {
+   struct pipe_ctx *mpo_pipe = pipe;
+
+   while (mpo_pipe) {
+   pipes[num_found++] = mpo_pipe->pipe_idx;
+   mpo_pipe = mpo_pipe->bottom_pipe;
+   }
+   pipe = pipe->next_odm_pipe;
+   }
+   break;
}
}
 
@@ -566,8 +580,14 @@ static unsigned int find_pipes_assigned_to_stream(struct 
dml2_context *ctx, stru
unsigned int num_found = 0;
 
for (i = 0; i < ctx->config.dcn_pipe_count; i++) {
-   if (state->res_ctx.pipe_ctx[i].stream && 
state->res_ctx.pipe_ctx[i].stream->stream_id == stream_id) {
-   pipes[num_found++] = i;
+   struct pipe_ctx *pipe = >res_ctx.pipe_ctx[i];
+
+   if (pipe->stream && pipe->stream->stream_id == stream_id && 
!pipe->top_pipe && !pipe->prev_odm_pipe) {
+   while (pipe) {
+   pipes[num_found++] = pipe->pipe_idx;
+   pipe = pipe->next_odm_pipe;
+   }
+   break;
}
}
 
-- 
2.34.1



[PATCH 11/19] drm/amd/display: Ensure populate uclk in bb construction

2024-01-10 Thread Alex Hung
From: Alvin Lee 

[Description]
- For some SKUs, the optimal DCFCLK for each UCLK is less than the
  smallest DCFCLK STA target due to low memory bandwidth. There is
  an assumption that the DCFCLK STA targets will always be less
  than one of the optimal DCFCLK values, but this is not true for
  SKUs that have low memory bandwidth. In this case we need to
  populate the optimal UCLK for each DCFCLK STA targets as the max
  UCLK freq.
- Also fix a bug in DML where start_state is not assigned and used
  correctly.

Reviewed-by: Samson Tam 
Reviewed-by: Chaitanya Dhere 
Acked-by: Alex Hung 
Signed-off-by: Alvin Lee 
---
 .../display/dc/dml/dcn30/display_mode_vba_30.c   | 16 
 .../drm/amd/display/dc/dml/dcn303/dcn303_fpu.c   | 11 +++
 .../display/dc/resource/dcn30/dcn30_resource.c   | 11 +++
 3 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
index 63c48c29ba49..e7f4a2d491cc 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
@@ -4273,7 +4273,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct 
display_mode_lib *mode_l
 
//Calculate Swath, DET Configuration, DCFCLKDeepSleep
//
-   for (i = 0; i < mode_lib->soc.num_states; ++i) {
+   for (i = start_state; i < mode_lib->soc.num_states; ++i) {
for (j = 0; j <= 1; ++j) {
for (k = 0; k < v->NumberOfActivePlanes; ++k) {
v->RequiredDPPCLKThisState[k] = 
v->RequiredDPPCLK[i][j][k];
@@ -4576,7 +4576,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct 
display_mode_lib *mode_l
 
//Calculate Return BW
 
-   for (i = 0; i < mode_lib->soc.num_states; ++i) {
+   for (i = start_state; i < mode_lib->soc.num_states; ++i) {
for (j = 0; j <= 1; ++j) {
for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
if (v->BlendingAndTiming[k] == k) {
@@ -4635,7 +4635,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct 
display_mode_lib *mode_l

v->UrgentOutOfOrderReturnPerChannelVMDataOnly);
v->FinalDRAMClockChangeLatency = (v->DRAMClockChangeLatencyOverride > 0 
? v->DRAMClockChangeLatencyOverride : v->DRAMClockChangeLatency);
 
-   for (i = 0; i < mode_lib->soc.num_states; ++i) {
+   for (i = start_state; i < mode_lib->soc.num_states; ++i) {
for (j = 0; j <= 1; ++j) {
v->DCFCLKState[i][j] = v->DCFCLKPerState[i];
}
@@ -4646,7 +4646,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct 
display_mode_lib *mode_l
 
if (v->ClampMinDCFCLK) {
/* Clamp calculated values to actual minimum */
-   for (i = 0; i < mode_lib->soc.num_states; ++i) {
+   for (i = start_state; i < mode_lib->soc.num_states; 
++i) {
for (j = 0; j <= 1; ++j) {
if (v->DCFCLKState[i][j] < 
mode_lib->soc.min_dcfclk) {
v->DCFCLKState[i][j] = 
mode_lib->soc.min_dcfclk;
@@ -4656,7 +4656,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct 
display_mode_lib *mode_l
}
}
 
-   for (i = 0; i < mode_lib->soc.num_states; ++i) {
+   for (i = start_state; i < mode_lib->soc.num_states; ++i) {
for (j = 0; j <= 1; ++j) {
v->IdealSDPPortBandwidthPerState[i][j] = dml_min3(
v->ReturnBusWidth * 
v->DCFCLKState[i][j],
@@ -4674,7 +4674,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct 
display_mode_lib *mode_l
 
//Re-ordering Buffer Support Check
 
-   for (i = 0; i < mode_lib->soc.num_states; ++i) {
+   for (i = start_state; i < mode_lib->soc.num_states; ++i) {
for (j = 0; j <= 1; ++j) {
if ((v->ROBBufferSizeInKByte - 
v->PixelChunkSizeInKByte) * 1024 / v->ReturnBWPerState[i][j]
> (v->RoundTripPingLatencyCycles + 32) 
/ v->DCFCLKState[i][j] + ReorderingBytes / v->ReturnBWPerState[i][j]) {
@@ -4692,7 +4692,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct 
display_mode_lib *mode_l
MaxTotalVActiveRDBandwidth = MaxTotalVActiveRDBandwidth + 
v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k];
}
 
-   for (i = 0; i < mode_lib->soc.num_states; ++i) {
+   for (i = start_state; i < mode_

[PATCH 10/19] drm/amd/display: Update P010 scaling cap

2024-01-10 Thread Alex Hung
From: Charlene Liu 

[Why]
Keep the same as previous APU and also insert clock dump

Reviewed-by: Ovidiu Bunea 
Acked-by: Alex Hung 
Signed-off-by: Charlene Liu 
---
 .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c  | 25 +--
 .../dc/resource/dcn35/dcn35_resource.c|  2 +-
 2 files changed, 13 insertions(+), 14 deletions(-)

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 9c660d1facc7..0e5a3184f01c 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
@@ -384,19 +384,6 @@ static void dcn35_enable_pme_wa(struct clk_mgr 
*clk_mgr_base)
dcn35_smu_enable_pme_wa(clk_mgr);
 }
 
-void dcn35_init_clocks(struct clk_mgr *clk_mgr)
-{
-   uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz;
-
-   memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
-
-   // Assumption is that boot state always supports pstate
-   clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk;  // restore ref_dtbclk
-   clk_mgr->clks.p_state_change_support = true;
-   clk_mgr->clks.prev_p_state_change_support = true;
-   clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN;
-   clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN;
-}
 
 bool dcn35_are_clock_states_equal(struct dc_clocks *a,
struct dc_clocks *b)
@@ -421,7 +408,19 @@ static void dcn35_dump_clk_registers(struct 
clk_state_registers_and_bypass *regs
struct clk_mgr_dcn35 *clk_mgr)
 {
 }
+void dcn35_init_clocks(struct clk_mgr *clk_mgr)
+{
+   uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz;
 
+   memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
+
+   // Assumption is that boot state always supports pstate
+   clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk;  // restore ref_dtbclk
+   clk_mgr->clks.p_state_change_support = true;
+   clk_mgr->clks.prev_p_state_change_support = true;
+   clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN;
+   clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN;
+}
 static struct clk_bw_params dcn35_bw_params = {
.vram_type = Ddr4MemType,
.num_channels = 1,
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 761ec9891875..7d8e957d6a19 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
@@ -701,7 +701,7 @@ static const struct dc_plane_cap plane_cap = {
 
// 6:1 downscaling ratio: 1000/6 = 166.666
.max_downscale_factor = {
-   .argb = 167,
+   .argb = 250,
.nv12 = 167,
.fp16 = 167
},
-- 
2.34.1



[PATCH 09/19] drm/amd/display: Reenable windowed mpo odm support

2024-01-10 Thread Alex Hung
From: Wenjing Liu 

[Why]
The feature was disabled due to regression found during testing. Now
that all the pending issues are addressed, we are reenabling the power
saving feature again.

The feature optimizes dispclk level when user is using MPO capable
broswers or watching MPO capable videos in windowed mode. The feature
achieves power optimization by utilizing free pipes to process incoming
pixels in parallel. So it reduces max dispclk requirements for each
pipe.

Previously ODM power optimization will be disabled when MPO plane is
present due to technical challeges. This is mainly because ODM divides
pixel workload with respect to stream but MPO plane position and size
are arbitrary with respect to stream. The pixel processing workload of
an MPO plane is not guaranteed to be evenly distributed across DCN pipes.
For example if a plane is moved inside single ODM slice, all the
processing for the plane is distributed to the pipe in the current ODM
slice, while the other ODM slices don't need to process this plane. If
the plane is then moved to the middle crosing two ODM slices, each ODM
slice gets half of the workload. This is especially difficult when the
plane itself has a large source rect which can't be processed by single
DCN pipe. In this case we can't enable ODM power optimization when the
plane is only within one ODM slice.

[How]
To overcome the challeges, new pipe resource management is in place to
make sure a plane is validated with ODM power optimization support if
it can be validated regardless of its position and the same pipe
topology can be used regardless of the plane's position. When the plane
is moved outside current ODM slice, we will set recout to 0 so the pipe
can be idling without the need to update pipe topology. When the user
resizes a plane, it may result in downscaling ratio changes. When the
downscaling ratio is above single pipe's threshold, we will seamlessly
exit ODM power optimization and applies MPC combine to support the plane.
when downscaling ratio becomes smaller, we will seamlessly enter ODM
power optimization again. All these pipe transitions happen
automatically and quietly when the conditions are met without any visual
impacts to the user.

Reviewed-by: Martin Leung 
Acked-by: Alex Hung 
Signed-off-by: Wenjing Liu 
---
 drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c   | 1 +
 drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
index c4d71e7f18af..5c24a769ce60 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
@@ -2104,6 +2104,7 @@ static bool dcn32_resource_construct(
dc->config.use_pipe_ctx_sync_logic = true;
 
dc->config.dc_mode_clk_limit_support = true;
+   dc->config.enable_windowed_mpo_odm = true;
/* read VBIOS LTTPR caps */
{
if (ctx->dc_bios->funcs->get_lttpr_caps) {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c 
b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
index 74412e5f03fe..b356fed1726d 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
@@ -1760,6 +1760,7 @@ static bool dcn321_resource_construct(
dc->caps.color.mpc.ocsc = 1;
 
dc->config.dc_mode_clk_limit_support = true;
+   dc->config.enable_windowed_mpo_odm = true;
/* read VBIOS LTTPR caps */
{
if (ctx->dc_bios->funcs->get_lttpr_caps) {
-- 
2.34.1



[PATCH 08/19] drm/amd/display: Fix DML2 watermark calculation

2024-01-10 Thread Alex Hung
From: Ovidiu Bunea 

[Why]
core_mode_programming in DML2 should output watermark calculations
to locals, but it incorrectly uses mode_lib

[How]
update code to match HW DML2

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Ovidiu Bunea 
---
 .../drm/amd/display/dc/dml2/display_mode_core.c| 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c 
b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c
index a6b938a12de1..9be5ebf3a8c0 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c
@@ -9446,13 +9446,13 @@ void dml_core_mode_programming(struct 
display_mode_lib_st *mode_lib, const struc
CalculateWatermarks_params->CompressedBufferSizeInkByte = 
locals->CompressedBufferSizeInkByte;
 
// Output
-   CalculateWatermarks_params->Watermark = >dummy_watermark; // 
Watermarks *Watermark
-   CalculateWatermarks_params->DRAMClockChangeSupport = 
_lib->ms.support.DRAMClockChangeSupport[0];
-   
CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = 
>dummy_single_array[0][0]; // dml_float_t 
*MaxActiveDRAMClockChangeLatencySupported[]
-   CalculateWatermarks_params->SubViewportLinesNeededInMALL = 
_lib->ms.SubViewportLinesNeededInMALL[j]; // dml_uint_t 
SubViewportLinesNeededInMALL[]
-   CalculateWatermarks_params->FCLKChangeSupport = 
_lib->ms.support.FCLKChangeSupport[0];
-   CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported 
= >dummy_single[0]; // dml_float_t *MaxActiveFCLKChangeLatencySupported
-   CalculateWatermarks_params->USRRetrainingSupport = 
_lib->ms.support.USRRetrainingSupport[0];
+   CalculateWatermarks_params->Watermark = >Watermark; // 
Watermarks *Watermark
+   CalculateWatermarks_params->DRAMClockChangeSupport = 
>DRAMClockChangeSupport;
+   
CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = 
locals->MaxActiveDRAMClockChangeLatencySupported; // dml_float_t 
*MaxActiveDRAMClockChangeLatencySupported[]
+   CalculateWatermarks_params->SubViewportLinesNeededInMALL = 
locals->SubViewportLinesNeededInMALL; // dml_uint_t 
SubViewportLinesNeededInMALL[]
+   CalculateWatermarks_params->FCLKChangeSupport = 
>FCLKChangeSupport;
+   CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported 
= >MaxActiveFCLKChangeLatencySupported; // dml_float_t 
*MaxActiveFCLKChangeLatencySupported
+   CalculateWatermarks_params->USRRetrainingSupport = 
>USRRetrainingSupport;
 
CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
_lib->scratch,
-- 
2.34.1



[PATCH 07/19] drm/amd/display: Clear OPTC mem select on disable

2024-01-10 Thread Alex Hung
From: Ilya Bakoulin 

[Why]
Not clearing the memory select bits prior to OPTC disable can cause DSC
corruption issues when attempting to reuse a memory instance for another
OPTC that enables ODM.

[How]
Clear the memory select bits prior to disabling an OPTC.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Ilya Bakoulin 
---
 drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c | 3 +++
 drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c | 3 +++
 2 files changed, 6 insertions(+)

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 1788eb29474b..823493543325 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
@@ -173,6 +173,9 @@ static bool optc32_disable_crtc(struct timing_generator 
*optc)
OPTC_SEG3_SRC_SEL, 0xf,
OPTC_NUM_OF_INPUT_SEGMENT, 0);
 
+   REG_UPDATE(OPTC_MEMORY_CONFIG,
+   OPTC_MEM_SEL, 0);
+
/* disable otg request until end of the first line
 * in the vertical blank region
 */
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c 
b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c
index 3d6c1b2c2b4d..5b1547508850 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c
@@ -145,6 +145,9 @@ static bool optc35_disable_crtc(struct timing_generator 
*optc)
OPTC_SEG3_SRC_SEL, 0xf,
OPTC_NUM_OF_INPUT_SEGMENT, 0);
 
+   REG_UPDATE(OPTC_MEMORY_CONFIG,
+   OPTC_MEM_SEL, 0);
+
/* disable otg request until end of the first line
 * in the vertical blank region
 */
-- 
2.34.1



[PATCH 06/19] drm/amd/display: Floor to mhz when requesting dpp disp clock changes to SMU

2024-01-10 Thread Alex Hung
From: Wenjing Liu 

[Why]
SMU uses discrete dpp and disp clock levels. When we submit SMU request
for clock changes in Mhz we need to floor the requested value from Khz so
SMU will choose the next higher clock level in Khz to set. If we ceil to
Mhz, SMU will have to choose the next higher clock level after the ceil,
which could result in unnecessarily jumpping to the next level.

For example, we request 1911,111Khz which is exactly one of the SMU preset
level. If we pass 1912Mhz, SMU will choose 2150,000 khz. If we pass
1911Mhz, SMU will choose 1911,111kHz, which is the expected value.

Reviewed-by: Alvin Lee 
Acked-by: Alex Hung 
Signed-off-by: Wenjing Liu 
---
 .../display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c  | 40 +--
 .../amd/display/dc/inc/hw/clk_mgr_internal.h  |  5 +++
 2 files changed, 41 insertions(+), 4 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 aadd07bc68c5..8fa0aae941c3 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
@@ -387,7 +387,15 @@ static void dcn32_update_clocks_update_dentist(
uint32_t temp_dispclk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR 
* clk_mgr->base.dentist_vco_freq_khz) / temp_disp_divider;
 
if (clk_mgr->smu_present)
-   dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK, 
khz_to_mhz_ceil(temp_dispclk_khz));
+   /*
+* SMU uses discrete dispclk presets. We applied
+* the same formula to increase our dppclk_khz
+* to the next matching discrete value. By
+* contract, we should use the preset dispclk
+* floored in Mhz to describe the intended clock.
+*/
+   dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK,
+   khz_to_mhz_floor(temp_dispclk_khz));
 
if (dc->debug.override_dispclk_programming) {
REG_GET(DENTIST_DISPCLK_CNTL,
@@ -426,7 +434,15 @@ static void dcn32_update_clocks_update_dentist(
 
/* do requested DISPCLK updates*/
if (clk_mgr->smu_present)
-   dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK, 
khz_to_mhz_ceil(clk_mgr->base.clks.dispclk_khz));
+   /*
+* SMU uses discrete dispclk presets. We applied
+* the same formula to increase our dppclk_khz
+* to the next matching discrete value. By
+* contract, we should use the preset dispclk
+* floored in Mhz to describe the intended clock.
+*/
+   dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DISPCLK,
+   
khz_to_mhz_floor(clk_mgr->base.clks.dispclk_khz));
 
if (dc->debug.override_dispclk_programming) {
REG_GET(DENTIST_DISPCLK_CNTL,
@@ -734,7 +750,15 @@ static void dcn32_update_clocks(struct clk_mgr 
*clk_mgr_base,
clk_mgr_base->clks.dppclk_khz = new_clocks->dppclk_khz;
 
if (clk_mgr->smu_present && !dpp_clock_lowered)
-   dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DPPCLK, 
khz_to_mhz_ceil(clk_mgr_base->clks.dppclk_khz));
+   /*
+* SMU uses discrete dppclk presets. We applied
+* the same formula to increase our dppclk_khz
+* to the next matching discrete value. By
+* contract, we should use the preset dppclk
+* floored in Mhz to describe the intended clock.
+*/
+   dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DPPCLK,
+   
khz_to_mhz_floor(clk_mgr_base->clks.dppclk_khz));
 
update_dppclk = true;
}
@@ -765,7 +789,15 @@ static void dcn32_update_clocks(struct clk_mgr 
*clk_mgr_base,
dcn32_update_clocks_update_dpp_dto(clk_mgr, context, 
safe_to_lower);
dcn32_update_clocks_update_dentist(clk_mgr, context);
if (clk_mgr->smu_present)
-   dcn32_smu_set_hard_min_by_freq(clk_mgr, 
PPCLK_DPPCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dppclk_khz));
+   /*
+* SMU uses discrete dppclk presets. We applied
+* the same formula to increase our dppclk_khz
+* to the next matching discrete value. By
+* contract, we should use the preset dppclk
+  

[PATCH 05/19] drm/amd/display: Port DENTIST hang and TDR fixes to OTG disable W/A

2024-01-10 Thread Alex Hung
From: Nicholas Kazlauskas 

[Why]
We can experience DENTIST hangs during optimize_bandwidth or TDRs if
FIFO is toggled and hangs.

[How]
Port the DCN35 fixes to DCN314.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Nicholas Kazlauskas 
---
 .../dc/clk_mgr/dcn314/dcn314_clk_mgr.c| 21 ---
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
index 878c0e7b78ab..a84f1e376dee 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
@@ -145,30 +145,27 @@ static int dcn314_get_active_display_cnt_wa(
return display_count;
 }
 
-static void dcn314_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct 
dc_state *context, bool disable)
+static void dcn314_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct 
dc_state *context,
+ bool safe_to_lower, bool disable)
 {
struct dc *dc = clk_mgr_base->ctx->dc;
int i;
 
for (i = 0; i < dc->res_pool->pipe_count; ++i) {
-   struct pipe_ctx *pipe = >current_state->res_ctx.pipe_ctx[i];
+   struct pipe_ctx *pipe = safe_to_lower
+   ? >res_ctx.pipe_ctx[i]
+   : >current_state->res_ctx.pipe_ctx[i];
 
if (pipe->top_pipe || pipe->prev_odm_pipe)
continue;
if (pipe->stream && (pipe->stream->dpms_off || 
dc_is_virtual_signal(pipe->stream->signal))) {
-   struct stream_encoder *stream_enc = 
pipe->stream_res.stream_enc;
-
if (disable) {
-   if (stream_enc && 
stream_enc->funcs->disable_fifo)
-   
pipe->stream_res.stream_enc->funcs->disable_fifo(stream_enc);
+   if (pipe->stream_res.tg && 
pipe->stream_res.tg->funcs->immediate_disable_crtc)
+   
pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
 
-   
pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
reset_sync_context_for_pipe(dc, context, i);
} else {

pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
-
-   if (stream_enc && 
stream_enc->funcs->enable_fifo)
-   
pipe->stream_res.stream_enc->funcs->enable_fifo(stream_enc);
}
}
}
@@ -297,11 +294,11 @@ void dcn314_update_clocks(struct clk_mgr *clk_mgr_base,
}
 
if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, 
clk_mgr_base->clks.dispclk_khz)) {
-   dcn314_disable_otg_wa(clk_mgr_base, context, true);
+   dcn314_disable_otg_wa(clk_mgr_base, context, safe_to_lower, 
true);
 
clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
dcn314_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
-   dcn314_disable_otg_wa(clk_mgr_base, context, false);
+   dcn314_disable_otg_wa(clk_mgr_base, context, safe_to_lower, 
false);
 
update_dispclk = true;
}
-- 
2.34.1



[PATCH 04/19] drm/amd/display: Add logging resource checks

2024-01-10 Thread Alex Hung
From: Charlene Liu 

[Why]
When mapping resources, resources could be unavailable.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Sung joon Kim 
Acked-by: Alex Hung 
Signed-off-by: Charlene Liu 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  | 4 +++-
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 4 
 drivers/gpu/drm/amd/display/dc/core/dc_state.c| 5 +++--
 3 files changed, 10 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 69e726630241..aa7c02ba948e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3522,7 +3522,7 @@ static void commit_planes_for_stream(struct dc *dc,
top_pipe_to_program = resource_get_otg_master_for_stream(
>res_ctx,
stream);
-
+   ASSERT(top_pipe_to_program != NULL);
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *old_pipe = 
>current_state->res_ctx.pipe_ctx[i];
 
@@ -4345,6 +4345,8 @@ static bool 
should_commit_minimal_transition_for_windowed_mpo_odm(struct dc *dc,
 
cur_pipe = 
resource_get_otg_master_for_stream(>current_state->res_ctx, stream);
new_pipe = resource_get_otg_master_for_stream(>res_ctx, 
stream);
+   if (!cur_pipe || !new_pipe)
+   return false;
cur_is_odm_in_use = resource_get_odm_slice_count(cur_pipe) > 1;
new_is_odm_in_use = resource_get_odm_slice_count(new_pipe) > 1;
if (cur_is_odm_in_use == new_is_odm_in_use)
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 f2abc1096ffb..9fbdb09697fd 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -2194,6 +2194,10 @@ void resource_log_pipe_topology_update(struct dc *dc, 
struct dc_state *state)
for (stream_idx = 0; stream_idx < state->stream_count; stream_idx++) {
otg_master = resource_get_otg_master_for_stream(
>res_ctx, state->streams[stream_idx]);
+   if (!otg_master || otg_master->stream_res.tg == NULL) {
+   DC_LOG_DC("topology update: otg_master NULL stream_idx 
%d!\n", stream_idx);
+   return;
+   }
slice_count = resource_get_opp_heads_for_otg_master(otg_master,
>res_ctx, opp_heads);
for (slice_idx = 0; slice_idx < slice_count; slice_idx++) {
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 56feee0ff01b..88c6436b28b6 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_state.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
@@ -434,8 +434,9 @@ bool dc_state_add_plane(
 
otg_master_pipe = resource_get_otg_master_for_stream(
>res_ctx, stream);
-   added = resource_append_dpp_pipes_for_plane_composition(state,
-   dc->current_state, pool, otg_master_pipe, plane_state);
+   if (otg_master_pipe)
+   added = resource_append_dpp_pipes_for_plane_composition(state,
+   dc->current_state, pool, otg_master_pipe, 
plane_state);
 
if (added) {
stream_status->plane_states[stream_status->plane_count] =
-- 
2.34.1



[PATCH 03/19] drm/amd/display: Add Replay IPS register for DMUB command table

2024-01-10 Thread Alex Hung
From: Alvin Lee 

- Introduce a new Replay mode for DMUB version 0.0.199.0

Reviewed-by: Martin Leung 
Acked-by: Alex Hung 
Signed-off-by: Alvin Lee 
---
 drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h 
b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index c64b6c848ef7..bcd3c361cca5 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -2832,6 +2832,7 @@ struct dmub_rb_cmd_psr_set_power_opt {
 #define REPLAY_RESIDENCY_MODE_MASK (0x1 << 
REPLAY_RESIDENCY_MODE_SHIFT)
 # define REPLAY_RESIDENCY_MODE_PHY (0x0 << 
REPLAY_RESIDENCY_MODE_SHIFT)
 # define REPLAY_RESIDENCY_MODE_ALPM(0x1 << 
REPLAY_RESIDENCY_MODE_SHIFT)
+# define REPLAY_RESIDENCY_MODE_IPS 0x10
 
 #define REPLAY_RESIDENCY_ENABLE_MASK   (0x1 << 
REPLAY_RESIDENCY_ENABLE_SHIFT)
 # define REPLAY_RESIDENCY_DISABLE  (0x0 << 
REPLAY_RESIDENCY_ENABLE_SHIFT)
-- 
2.34.1



[PATCH 02/19] drm/amd/display: Init link enc resources in dc_state only if res_pool presents

2024-01-10 Thread Alex Hung
From: Dillon Varone 

[Why & How]
res_pool is not initialized in all situations such as virtual
environments, and therefore link encoder resources should not be
initialized if res_pool is NULL.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Martin Leung 
Acked-by: Alex Hung 
Signed-off-by: Dillon Varone 
---
 drivers/gpu/drm/amd/display/dc/core/dc_state.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

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 460a8010c79f..56feee0ff01b 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_state.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
@@ -267,7 +267,8 @@ void dc_state_construct(struct dc *dc, struct dc_state 
*state)
state->clk_mgr = dc->clk_mgr;
 
/* Initialise DIG link encoder resource tracking variables. */
-   link_enc_cfg_init(dc, state);
+   if (dc->res_pool)
+   link_enc_cfg_init(dc, state);
 }
 
 void dc_state_destruct(struct dc_state *state)
-- 
2.34.1



[PATCH 01/19] drm/amd/display: Allow IPS2 during Replay

2024-01-10 Thread Alex Hung
From: Nicholas Kazlauskas 

[Why & How]
Add regkey to block video playback in IPS2 by default

Allow idle optimizations in the same spot we allow Replay for
video playback usecases.

Avoid sending it when there's an external display connected by
modifying the allow idle checks to check for active non-eDP screens.

Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Nicholas Kazlauskas 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c   | 2 ++
 drivers/gpu/drm/amd/display/dc/dc.h | 1 +
 drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 9 -
 3 files changed, 11 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 111c6f51f0ae..95ff3800fc87 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1716,6 +1716,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
 
init_data.flags.disable_ips = DMUB_IPS_DISABLE_ALL;
 
+   init_data.flags.disable_ips_in_vpb = 1;
+
/* Enable DWB for tested platforms only */
if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 0, 0))
init_data.num_virtual_links = 1;
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 5d7aa882416b..c9317ea0258e 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -434,6 +434,7 @@ struct dc_config {
bool EnableMinDispClkODM;
bool enable_auto_dpm_test_logs;
unsigned int disable_ips;
+   unsigned int disable_ips_in_vpb;
 };
 
 enum visual_confirm {
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 9c806385ecbd..8b6c49622f3b 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
@@ -680,7 +680,7 @@ void dcn35_power_down_on_boot(struct dc *dc)
 bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable)
 {
struct dc_link *edp_links[MAX_NUM_EDP];
-   int edp_num;
+   int i, edp_num;
if (dc->debug.dmcub_emulation)
return true;
 
@@ -688,6 +688,13 @@ bool dcn35_apply_idle_power_optimizations(struct dc *dc, 
bool enable)
dc_get_edp_links(dc, edp_links, _num);
if (edp_num == 0 || edp_num > 1)
return false;
+
+   for (i = 0; i < dc->current_state->stream_count; ++i) {
+   struct dc_stream_state *stream = 
dc->current_state->streams[i];
+
+   if (!stream->dpms_off && 
!dc_is_embedded_signal(stream->signal))
+   return false;
+   }
}
 
// TODO: review other cases when idle optimization is allowed
-- 
2.34.1



[PATCH 00/19] DC Patches January 10, 2024

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

* Fixes on DCN35 and DML2.
* Enhancements in DMUB.
* Improvements on IPS, DP and MPO and others.

Cc: Daniel Wheeler 

Alvin Lee (2):
  drm/amd/display: Add Replay IPS register for DMUB command table
  drm/amd/display: Ensure populate uclk in bb construction

Charlene Liu (2):
  drm/amd/display: Add logging resource checks
  drm/amd/display: Update P010 scaling cap

Dillon Varone (1):
  drm/amd/display: Init link enc resources in dc_state only if res_pool
presents

Dmytro Laktyushkin (1):
  drm/amd/display: Fix dml2 assigned pipe search

George Shen (1):
  drm/amd/display: Add DP audio BW validation

Ilya Bakoulin (1):
  drm/amd/display: Clear OPTC mem select on disable

Martin Leung (1):
  drm/amd/display: 3.2.267

Nicholas Kazlauskas (5):
  drm/amd/display: Allow IPS2 during Replay
  drm/amd/display: Port DENTIST hang and TDR fixes to OTG disable W/A
  drm/amd/display: Rework DC Z10 restore
  drm/amd/display: Set default Z8 minimum residency for DCN35
  drm/amd/display: Allow Z8 for multiplane configurations on DCN35

Ovidiu Bunea (1):
  drm/amd/display: Fix DML2 watermark calculation

Tom Chung (1):
  drm/amd/display: Enable Panel Replay for static screen use case

Wayne Lin (1):
  drm/amd/display: Align the returned error code with legacy DP

Wenjing Liu (2):
  drm/amd/display: Floor to mhz when requesting dpp disp clock changes
to SMU
  drm/amd/display: Reenable windowed mpo odm support

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  44 ++-
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c|  59 +++-
 .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |   5 +
 .../amd/display/amdgpu_dm/amdgpu_dm_replay.c  | 119 +---
 .../amd/display/amdgpu_dm/amdgpu_dm_replay.h  |   4 +-
 .../dc/clk_mgr/dcn314/dcn314_clk_mgr.c|  21 +-
 .../display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c  |  40 ++-
 .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c  |  25 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  15 +-
 .../gpu/drm/amd/display/dc/core/dc_resource.c |   4 +
 .../gpu/drm/amd/display/dc/core/dc_state.c|   8 +-
 .../gpu/drm/amd/display/dc/core/dc_stream.c   |   9 +-
 drivers/gpu/drm/amd/display/dc/dc.h   |   3 +-
 .../gpu/drm/amd/display/dc/dce/dce_audio.c| 288 +-
 .../gpu/drm/amd/display/dc/dce/dce_audio.h|   3 +-
 .../dc/dml/dcn30/display_mode_vba_30.c|  16 +-
 .../amd/display/dc/dml/dcn303/dcn303_fpu.c|  11 +
 .../drm/amd/display/dc/dml/dcn35/dcn35_fpu.c  |   4 +-
 .../amd/display/dc/dml2/display_mode_core.c   |  14 +-
 .../display/dc/dml2/dml2_dc_resource_mgmt.c   |  36 ++-
 .../amd/display/dc/hwss/dce110/dce110_hwseq.c |  56 +++-
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c   |  11 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/audio.h |   3 +-
 .../amd/display/dc/inc/hw/clk_mgr_internal.h  |   5 +
 .../amd/display/dc/optc/dcn32/dcn32_optc.c|   3 +
 .../amd/display/dc/optc/dcn35/dcn35_optc.c|   3 +
 .../dc/resource/dcn30/dcn30_resource.c|  11 +
 .../dc/resource/dcn32/dcn32_resource.c|   1 +
 .../dc/resource/dcn321/dcn321_resource.c  |   1 +
 .../dc/resource/dcn35/dcn35_resource.c|   3 +-
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   |   1 +
 .../gpu/drm/amd/display/include/audio_types.h |  15 +
 32 files changed, 689 insertions(+), 152 deletions(-)

-- 
2.34.1



Re: [PATCH] drm/amd/display: Fix memory leak in dm_set_writeback()

2023-12-11 Thread Alex Hung

Thanks for catching this.

Reviewed-by: Alex Hung 

On 2023-12-08 02:58, Harshit Mogalapalli wrote:

'wb_info' needs to be freed on error paths or it would leak the memory.

Smatch pointed this out.

Fixes: c81e13b929df ("drm/amd/display: Hande writeback request from userspace")
Signed-off-by: Harshit Mogalapalli 
---
This is based on static analysis and only compile tested
---
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
  1 file changed, 2 insertions(+)

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 afdcc43ea06c..333995f70239 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8871,12 +8871,14 @@ static void dm_set_writeback(struct 
amdgpu_display_manager *dm,
acrtc = to_amdgpu_crtc(wb_conn->encoder.crtc);
if (!acrtc) {
DRM_ERROR("no amdgpu_crtc found\n");
+   kfree(wb_info);
return;
}
  
  	afb = to_amdgpu_framebuffer(new_con_state->writeback_job->fb);

if (!afb) {
DRM_ERROR("No amdgpu_framebuffer found\n");
+   kfree(wb_info);
return;
}
  


[PATCH 20/20] drm/amd/display: Promote DC to 3.2.260

2023-11-08 Thread Alex Hung
From: Aric Cyr 

- Add missing chips for HDCP
- Add new command to disable replay timing resync
- Fix encoder disable logic
- Enable DSC Flag in MST Mode Validation
- Change the DMCUB mailbox memory location from FB to inbox
- Add disable timeout option
- Negate IPS allow and commit bits
- Enable DCN clock gating for DCN35
- Prefer currently used OTG master when acquiring free pipe
- Try to acquire a free OTG master not used in cur ctx first
- Clear dpcd_sink_ext_caps if not set
- Enable fast plane updates on DCN3.2 and above
- Add null checks for 8K60 lightup
- Refactor resource into component directory
- Fix DSC not Enabled on Direct MST Sink
- Guard against invalid RPTR/WPTR being set
- Enable CM low mem power optimization
- Fix a debugfs null pointer error

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 18ab453bfdb1..e6f109bbf468 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -49,7 +49,7 @@ struct aux_payload;
 struct set_config_cmd_payload;
 struct dmub_notification;
 
-#define DC_VER "3.2.259"
+#define DC_VER "3.2.260"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
-- 
2.42.0



[PATCH 19/20] drm/amd/display: Add missing chips for HDCP

2023-11-08 Thread Alex Hung
From: Rodrigo Siqueira 

[WHAT]
Add missing HDCP ID in the message id enum.

Acked-by: Alex Hung 
Signed-off-by: Rodrigo Siqueira 
---
 drivers/gpu/drm/amd/display/include/hdcp_msg_types.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/include/hdcp_msg_types.h 
b/drivers/gpu/drm/amd/display/include/hdcp_msg_types.h
index 42229b4effdc..eced9ad91f1d 100644
--- a/drivers/gpu/drm/amd/display/include/hdcp_msg_types.h
+++ b/drivers/gpu/drm/amd/display/include/hdcp_msg_types.h
@@ -69,6 +69,11 @@ enum hdcp_message_id {
HDCP_MESSAGE_ID_READ_RXSTATUS,
HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE,
 
+   /* PS175 chip */
+
+   HDCP_MESSAGE_ID_WRITE_PS175_CMD,
+   HDCP_MESSAGE_ID_READ_PS175_RSP,
+
HDCP_MESSAGE_ID_MAX
 };
 
-- 
2.42.0



[PATCH 18/20] drm/amd/display: Add new command to disable replay timing resync

2023-11-08 Thread Alex Hung
From: Anthony Koo 

[WHY & HOW]
Add new command to disable replay timing resync

Acked-by: Alex Hung 
Signed-off-by: Anthony Koo 
---
 .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h   | 41 +++
 1 file changed, 41 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h 
b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
index ed4379c04715..97faa9cfb6f7 100644
--- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -2840,6 +2840,10 @@ enum dmub_cmd_replay_type {
 * Set power opt and coasting vtotal.
 */
DMUB_CMD__REPLAY_SET_POWER_OPT_AND_COASTING_VTOTAL  = 4,
+   /**
+* Set disabled iiming sync.
+*/
+   DMUB_CMD__REPLAY_SET_TIMING_SYNC_SUPPORTED  = 5,
 };
 
 /**
@@ -3002,6 +3006,27 @@ struct dmub_cmd_replay_set_power_opt_data {
uint32_t power_opt;
 };
 
+/**
+ * Data passed from driver to FW in a 
DMUB_CMD__REPLAY_SET_TIMING_SYNC_SUPPORTED command.
+ */
+struct dmub_cmd_replay_set_timing_sync_data {
+   /**
+* Panel Instance.
+* Panel isntance to identify which replay_state to use
+* Currently the support is only for 0 or 1
+*/
+   uint8_t panel_inst;
+
+   /**
+* Explicit padding to 4 byte boundary.
+*/
+   uint8_t pad[3];
+   /**
+* REPLAY set_timing_sync
+*/
+   bool timing_sync_supported;
+};
+
 /**
  * Definition of a DMUB_CMD__SET_REPLAY_POWER_OPT command.
  */
@@ -3068,6 +3093,20 @@ struct 
dmub_rb_cmd_replay_set_power_opt_and_coasting_vtotal {
struct dmub_cmd_replay_set_coasting_vtotal_data 
replay_set_coasting_vtotal_data;
 };
 
+/**
+ * Definition of a DMUB_CMD__REPLAY_SET_TIMING_SYNC_SUPPORTED command.
+ */
+struct dmub_rb_cmd_replay_set_timing_sync {
+   /**
+* Command header.
+*/
+   struct dmub_cmd_header header;
+   /**
+* Definition of DMUB_CMD__REPLAY_SET_TIMING_SYNC_SUPPORTED command.
+*/
+   struct dmub_cmd_replay_set_timing_sync_data replay_set_timing_sync_data;
+};
+
 /**
  * Set of HW components that can be locked.
  *
@@ -4201,6 +4240,8 @@ union dmub_rb_cmd {
 * Definition of a DMUB_CMD__REPLAY_SET_POWER_OPT_AND_COASTING_VTOTAL 
command.
 */
struct dmub_rb_cmd_replay_set_power_opt_and_coasting_vtotal 
replay_set_power_opt_and_coasting_vtotal;
+
+   struct dmub_rb_cmd_replay_set_timing_sync replay_set_timing_sync;
 };
 
 /**
-- 
2.42.0



[PATCH 17/20] drm/amd/display: Send PQ bit in AMD VSIF

2023-11-08 Thread Alex Hung
From: Krunoslav Kovac 

[WHY & HOW]
PB9 bit 5 was added to signal PQ EOTF in AMD vendor specific infoframe.
This change sets it when appropriate.

Reviewed-by: Aric Cyr 
Acked-by: Alex Hung 
Signed-off-by: Krunoslav Kovac 
---
 drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 
b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index ccecddafeb05..47296d155c3a 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -693,10 +693,12 @@ static void build_vrr_infopacket_fs2_data(enum 
color_transfer_func app_tf,
if (app_tf != TRANSFER_FUNC_UNKNOWN) {
infopacket->valid = true;
 
-   if (app_tf != TRANSFER_FUNC_PQ2084) {
+   if (app_tf == TRANSFER_FUNC_PQ2084)
+   infopacket->sb[9] |= 0x20; // PB9 = [Bit 5 = PQ EOTF 
Active]
+   else {
infopacket->sb[6] |= 0x08;  // PB6 = [Bit 3 = Native 
Color Active]
if (app_tf == TRANSFER_FUNC_GAMMA_22)
-   infopacket->sb[9] |= 0x04;  // PB6 = [Bit 2 = 
Gamma 2.2 EOTF Active]
+   infopacket->sb[9] |= 0x04;  // PB9 = [Bit 2 = 
Gamma 2.2 EOTF Active]
}
}
 }
-- 
2.42.0



[PATCH 16/20] drm/amd/display: Fix encoder disable logic

2023-11-08 Thread Alex Hung
From: Nicholas Susanto 

[WHY]
DENTIST hangs when OTG is off and encoder is on. We were not
disabling the encoder properly when switching from extended mode to
external monitor only.

[HOW]
Disable the encoder using an existing enable/disable fifo helper instead
of enc35_stream_encoder_enable.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Nicholas Kazlauskas 
Acked-by: Alex Hung 
Signed-off-by: Nicholas Susanto 
---
 .../amd/display/dc/dcn35/dcn35_dio_stream_encoder.c| 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_stream_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_stream_encoder.c
index 001f9eb66920..62a8f0b56006 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_stream_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_stream_encoder.c
@@ -261,12 +261,6 @@ static void enc35_stream_encoder_enable(
/* invalid mode ! */
ASSERT_CRITICAL(false);
}
-
-   REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 1);
-   REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 1);
-   } else {
-   REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 0);
-   REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 0);
}
 }
 
@@ -436,6 +430,8 @@ static void enc35_disable_fifo(struct stream_encoder *enc)
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 
REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 0);
+   REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 0);
+   REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 0);
 }
 
 static void enc35_enable_fifo(struct stream_encoder *enc)
@@ -443,6 +439,8 @@ static void enc35_enable_fifo(struct stream_encoder *enc)
struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
 
REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, 0x7);
+   REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 1);
+   REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 1);
 
enc35_reset_fifo(enc, true);
enc35_reset_fifo(enc, false);
-- 
2.42.0



[PATCH 15/20] drm/amd/display: Enable DSC Flag in MST Mode Validation

2023-11-08 Thread Alex Hung
From: Fangzhi Zuo 

[WHY & HOW]
When dsc is possible, MST mode validation includes:
1. if maximum dsc compression cannot fit into end to end bw, mode pruned
2. if native bw cannot fit into end to end bw, try to enabled dsc to see
   whether a feasible dsc config can be found
3. if native bw can fit into end to end bw, mode supported

Reviewed-by: Wayne Lin 
Acked-by: Alex Hung 
Signed-off-by: Fangzhi Zuo 
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 44 +++
 1 file changed, 26 insertions(+), 18 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 ec87e31c6fe8..8d7d4024f285 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
@@ -1602,9 +1602,8 @@ enum dc_status dm_dp_mst_is_port_support_mode(
struct dc_link_settings cur_link_settings;
unsigned int end_to_end_bw_in_kbps = 0;
unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0;
-   unsigned int max_compressed_bw_in_kbps = 0;
struct dc_dsc_bw_range bw_range = {0};
-   uint16_t full_pbn = aconnector->mst_output_port->full_pbn;
+   struct dc_dsc_config_options dsc_options = {0};
 
/*
 * Consider the case with the depth of the mst topology tree is equal 
or less than 2
@@ -1620,30 +1619,39 @@ enum dc_status dm_dp_mst_is_port_support_mode(
   (aconnector->mst_output_port->passthrough_aux ||
aconnector->dsc_aux == >mst_output_port->aux)) {
cur_link_settings = stream->link->verified_link_cap;
+   upper_link_bw_in_kbps = 
dc_link_bandwidth_kbps(aconnector->dc_link, _link_settings);
+   down_link_bw_in_kbps = 
kbps_from_pbn(aconnector->mst_output_port->full_pbn);
 
-   upper_link_bw_in_kbps = 
dc_link_bandwidth_kbps(aconnector->dc_link,
-  
_link_settings);
-   down_link_bw_in_kbps = kbps_from_pbn(full_pbn);
-
-   /* pick the bottleneck */
-   end_to_end_bw_in_kbps = min(upper_link_bw_in_kbps,
-   down_link_bw_in_kbps);
-
-   /*
-* use the maximum dsc compression bandwidth as the required
-* bandwidth for the mode
-*/
-   max_compressed_bw_in_kbps = bw_range.min_kbps;
+   /* pick the end to end bw bottleneck */
+   end_to_end_bw_in_kbps = min(upper_link_bw_in_kbps, 
down_link_bw_in_kbps);
 
-   if (end_to_end_bw_in_kbps < max_compressed_bw_in_kbps) {
-   DRM_DEBUG_DRIVER("Mode does not fit into DSC 
pass-through bandwidth validation\n");
+   if (end_to_end_bw_in_kbps < bw_range.min_kbps) {
+   DRM_DEBUG_DRIVER("maximum dsc compression cannot fit 
into end-to-end bandwidth\n");
return DC_FAIL_BANDWIDTH_VALIDATE;
}
+
+   if (end_to_end_bw_in_kbps < bw_range.stream_kbps) {
+   dc_dsc_get_default_config_option(stream->link->dc, 
_options);
+   dsc_options.max_target_bpp_limit_override_x16 = 
aconnector->base.display_info.max_dsc_bpp * 16;
+   if 
(dc_dsc_compute_config(stream->sink->ctx->dc->res_pool->dscs[0],
+   >sink->dsc_caps.dsc_dec_caps,
+   _options,
+   end_to_end_bw_in_kbps,
+   >timing,
+   
dc_link_get_highest_encoding_format(stream->link),
+   >timing.dsc_cfg)) {
+   stream->timing.flags.DSC = 1;
+   DRM_DEBUG_DRIVER("end-to-end bandwidth require 
dsc and dsc config found\n");
+   } else {
+   DRM_DEBUG_DRIVER("end-to-end bandwidth require 
dsc but dsc config not found\n");
+   return DC_FAIL_BANDWIDTH_VALIDATE;
+   }
+   }
} else {
/* check if mode could be supported within full_pbn */
bpp = 
convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3;
pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, 
bpp, false);
-   if (pbn > full_pbn)
+   if (pbn > aconnector->mst_output_port->full_pbn)
return DC_FAIL_BANDWIDTH_VALIDATE;
}
 
-- 
2.42.0



[PATCH 14/20] drm/amd/display: Change the DMCUB mailbox memory location from FB to inbox

2023-11-08 Thread Alex Hung
From: Lewis Huang 

[WHY]
Flush command sent to DMCUB spends more time for execution on
a dGPU than on an APU. This causes cursor lag when using high
refresh rate mouses.

[HOW]
1. Change the DMCUB mailbox memory location from FB to inbox.
2. Only change windows memory to inbox.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Nicholas Kazlauskas 
Acked-by: Alex Hung 
Signed-off-by: Lewis Huang 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 13 
 drivers/gpu/drm/amd/display/dmub/dmub_srv.h   | 22 -
 .../gpu/drm/amd/display/dmub/src/dmub_srv.c   | 32 ++-
 3 files changed, 45 insertions(+), 22 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 8ebdbfbbb691..6199440a9da8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2078,7 +2078,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
struct dmub_srv_create_params create_params;
struct dmub_srv_region_params region_params;
struct dmub_srv_region_info region_info;
-   struct dmub_srv_fb_params fb_params;
+   struct dmub_srv_memory_params memory_params;
struct dmub_srv_fb_info *fb_info;
struct dmub_srv *dmub_srv;
const struct dmcub_firmware_header_v1_0 *hdr;
@@ -2181,6 +2181,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
adev->dm.dmub_fw->data +
le32_to_cpu(hdr->header.ucode_array_offset_bytes) +
PSP_HEADER_BYTES;
+   region_params.is_mailbox_in_inbox = false;
 
status = dmub_srv_calc_region_info(dmub_srv, _params,
   _info);
@@ -2204,10 +2205,10 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
return r;
 
/* Rebase the regions on the framebuffer address. */
-   memset(_params, 0, sizeof(fb_params));
-   fb_params.cpu_addr = adev->dm.dmub_bo_cpu_addr;
-   fb_params.gpu_addr = adev->dm.dmub_bo_gpu_addr;
-   fb_params.region_info = _info;
+   memset(_params, 0, sizeof(memory_params));
+   memory_params.cpu_fb_addr = adev->dm.dmub_bo_cpu_addr;
+   memory_params.gpu_fb_addr = adev->dm.dmub_bo_gpu_addr;
+   memory_params.region_info = _info;
 
adev->dm.dmub_fb_info =
kzalloc(sizeof(*adev->dm.dmub_fb_info), GFP_KERNEL);
@@ -2219,7 +2220,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
return -ENOMEM;
}
 
-   status = dmub_srv_calc_fb_info(dmub_srv, _params, fb_info);
+   status = dmub_srv_calc_mem_info(dmub_srv, _params, fb_info);
if (status != DMUB_STATUS_OK) {
DRM_ERROR("Error calculating DMUB FB info: %d\n", status);
return -EINVAL;
diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h 
b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
index 9665ada0f894..df63aa8f01e9 100644
--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
@@ -195,6 +195,7 @@ struct dmub_srv_region_params {
uint32_t vbios_size;
const uint8_t *fw_inst_const;
const uint8_t *fw_bss_data;
+   bool is_mailbox_in_inbox;
 };
 
 /**
@@ -214,20 +215,25 @@ struct dmub_srv_region_params {
  */
 struct dmub_srv_region_info {
uint32_t fb_size;
+   uint32_t inbox_size;
uint8_t num_regions;
struct dmub_region regions[DMUB_WINDOW_TOTAL];
 };
 
 /**
- * struct dmub_srv_fb_params - parameters used for driver fb setup
+ * struct dmub_srv_memory_params - parameters used for driver fb setup
  * @region_info: region info calculated by dmub service
- * @cpu_addr: base cpu address for the framebuffer
- * @gpu_addr: base gpu virtual address for the framebuffer
+ * @cpu_fb_addr: base cpu address for the framebuffer
+ * @cpu_inbox_addr: base cpu address for the gart
+ * @gpu_fb_addr: base gpu virtual address for the framebuffer
+ * @gpu_inbox_addr: base gpu virtual address for the gart
  */
-struct dmub_srv_fb_params {
+struct dmub_srv_memory_params {
const struct dmub_srv_region_info *region_info;
-   void *cpu_addr;
-   uint64_t gpu_addr;
+   void *cpu_fb_addr;
+   void *cpu_inbox_addr;
+   uint64_t gpu_fb_addr;
+   uint64_t gpu_inbox_addr;
 };
 
 /**
@@ -563,8 +569,8 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
  *   DMUB_STATUS_OK - success
  *   DMUB_STATUS_INVALID - unspecified error
  */
-enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
-  const struct dmub_srv_fb_params *params,
+enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub,
+  const struct dmub_srv_memory_params 
*params,
   struct dmub_srv_fb_info *out);
 
 /**
diff --git a

[PATCH 13/20] drm/amd/display: Add disable timeout option

2023-11-08 Thread Alex Hung
From: Duncan Ma 

[WHY]
Driver continues running whenever there is
is timeout from smu or dmcub.

It is difficult to track failure state
when dcn, dc or dmcub changes on root failure.

[HOW]
Add disable_timeout option to halt driver
whenever there is a failure in response.

Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Duncan Ma 
---
 .../amd/display/dc/clk_mgr/dcn35/dcn35_smu.c  |  3 ++
 drivers/gpu/drm/amd/display/dc/dc.h   |  1 +
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  | 29 +++
 3 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c
index b6b8c3ca1572..af0a0f292595 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c
@@ -116,6 +116,9 @@ static uint32_t dcn35_smu_wait_for_response(struct 
clk_mgr_internal *clk_mgr, un
msleep(delay_us/1000);
else if (delay_us > 0)
udelay(delay_us);
+
+   if (clk_mgr->base.ctx->dc->debug.disable_timeout)
+   max_retries++;
} while (max_retries--);
 
return res_val;
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index c5e7da302acb..18ab453bfdb1 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -978,6 +978,7 @@ struct dc_debug_options {
bool psp_disabled_wa;
unsigned int ips2_eval_delay_us;
unsigned int ips2_entry_delay_us;
+   bool disable_timeout;
 };
 
 struct gpu_info_soc_bounding_box_v1_0;
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 0e07699c1e83..53400cc05b5b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -241,7 +241,12 @@ bool dc_dmub_srv_cmd_run_list(struct dc_dmub_srv 
*dc_dmub_srv, unsigned int coun
 
// Wait for DMUB to process command
if (wait_type != DM_DMUB_WAIT_TYPE_NO_WAIT) {
-   status = dmub_srv_wait_for_idle(dmub, 10);
+   if (dc_dmub_srv->ctx->dc->debug.disable_timeout) {
+   do {
+   status = dmub_srv_wait_for_idle(dmub, 10);
+   } while (status != DMUB_STATUS_OK);
+   } else
+   status = dmub_srv_wait_for_idle(dmub, 10);
 
if (status != DMUB_STATUS_OK) {
DC_LOG_DEBUG("No reply for DMUB command: status=%d\n", 
status);
@@ -1147,10 +1152,16 @@ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv 
*dc_dmub_srv, bool wait)
return true;
 
if (wait) {
-   status = dmub_srv_wait_for_hw_pwr_up(dc_dmub_srv->dmub, 50);
-   if (status != DMUB_STATUS_OK) {
-   DC_ERROR("Error querying DMUB hw power up status: 
error=%d\n", status);
-   return false;
+   if (dc_dmub_srv->ctx->dc->debug.disable_timeout) {
+   do {
+   status = 
dmub_srv_wait_for_hw_pwr_up(dc_dmub_srv->dmub, 50);
+   } while (status != DMUB_STATUS_OK);
+   } else {
+   status = dmub_srv_wait_for_hw_pwr_up(dc_dmub_srv->dmub, 
50);
+   if (status != DMUB_STATUS_OK) {
+   DC_ERROR("Error querying DMUB hw power up 
status: error=%d\n", status);
+   return false;
+   }
}
} else
return dmub_srv_is_hw_pwr_up(dc_dmub_srv->dmub);
@@ -1187,7 +1198,7 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
const uint32_t max_num_polls = 1;
uint32_t allow_state = 0;
uint32_t commit_state = 0;
-   uint32_t i;
+   int i;
 
if (dc->debug.dmcub_emulation)
return;
@@ -1220,6 +1231,9 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
break;
 
udelay(1);
+
+   if (dc->debug.disable_timeout)
+   i--;
}
ASSERT(i < max_num_polls);
 
@@ -1242,6 +1256,9 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
break;
 
udelay(1);
+
+   if (dc->debug.disable_timeout)
+   i--;
}
ASSERT(i < max_num_polls);
}
-- 
2.42.0



[PATCH 12/20] drm/amd/display: Negate IPS allow and commit bits

2023-11-08 Thread Alex Hung
From: Duncan Ma 

[WHY]
On s0i3, IPS mask isn't saved and restored.
It is reset to zero on exit.

If it is cleared unexpectedly, driver will
proceed operations while DCN is in IPS2 and
cause a hang.

[HOW]
Negate the bit logic. Default value of
zero indicates it is still in IPS2. Driver
must poll for the bit to assert.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Duncan Ma 
---
 .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c   | 18 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c   |  4 ++--
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c   | 10 +-
 3 files changed, 16 insertions(+), 16 deletions(-)

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 0fa4fcd00de2..507a7cf56711 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
@@ -820,22 +820,22 @@ static void dcn35_set_idle_state(struct clk_mgr 
*clk_mgr_base, bool allow_idle)
 
if (dc->config.disable_ips == DMUB_IPS_ENABLE ||
dc->config.disable_ips == DMUB_IPS_DISABLE_DYNAMIC) {
-   val |= DMUB_IPS1_ALLOW_MASK;
-   val |= DMUB_IPS2_ALLOW_MASK;
-   } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS1) {
val = val & ~DMUB_IPS1_ALLOW_MASK;
val = val & ~DMUB_IPS2_ALLOW_MASK;
-   } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2) {
-   val |= DMUB_IPS1_ALLOW_MASK;
-   val = val & ~DMUB_IPS2_ALLOW_MASK;
-   } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2_Z10) {
+   } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS1) {
val |= DMUB_IPS1_ALLOW_MASK;
val |= DMUB_IPS2_ALLOW_MASK;
+   } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2) {
+   val = val & ~DMUB_IPS1_ALLOW_MASK;
+   val |= DMUB_IPS2_ALLOW_MASK;
+   } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2_Z10) {
+   val = val & ~DMUB_IPS1_ALLOW_MASK;
+   val = val & ~DMUB_IPS2_ALLOW_MASK;
}
 
if (!allow_idle) {
-   val = val & ~DMUB_IPS1_ALLOW_MASK;
-   val = val & ~DMUB_IPS2_ALLOW_MASK;
+   val |= DMUB_IPS1_ALLOW_MASK;
+   val |= DMUB_IPS2_ALLOW_MASK;
}
 
dcn35_smu_write_ips_scratch(clk_mgr, val);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index d8f434738212..76b47f178127 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -4934,8 +4934,8 @@ bool dc_dmub_is_ips_idle_state(struct dc *dc)
if (dc->hwss.get_idle_state)
idle_state = dc->hwss.get_idle_state(dc);
 
-   if ((idle_state & DMUB_IPS1_ALLOW_MASK) ||
-   (idle_state & DMUB_IPS2_ALLOW_MASK))
+   if (!(idle_state & DMUB_IPS1_ALLOW_MASK) ||
+   !(idle_state & DMUB_IPS2_ALLOW_MASK))
return true;
 
return false;
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 e4c007203318..0e07699c1e83 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -1202,11 +1202,11 @@ void dc_dmub_srv_exit_low_power_state(const struct dc 
*dc)
allow_state = dc->hwss.get_idle_state(dc);
dc->hwss.set_idle_state(dc, false);
 
-   if (allow_state & DMUB_IPS2_ALLOW_MASK) {
+   if (!(allow_state & DMUB_IPS2_ALLOW_MASK)) {
// Wait for evaluation time
udelay(dc->debug.ips2_eval_delay_us);
commit_state = dc->hwss.get_idle_state(dc);
-   if (commit_state & DMUB_IPS2_COMMIT_MASK) {
+   if (!(commit_state & DMUB_IPS2_COMMIT_MASK)) {
// Tell PMFW to exit low power state

dc->clk_mgr->funcs->exit_low_power_state(dc->clk_mgr);
 
@@ -1216,7 +1216,7 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
 
for (i = 0; i < max_num_polls; ++i) {
commit_state = 
dc->hwss.get_idle_state(dc);
-   if (!(commit_state & 
DMUB_IPS2_COMMIT_MASK))
+   if (commit_state & 
DMUB_IPS2_COMMIT_MASK)
break;
 
udelay(1);
@@ -1235,10 +1235,10 @@ void dc_dmub_srv_exit_low_power_state(const struct dc 

[PATCH 10/20] drm/amd/display: Prefer currently used OTG master when acquiring free pipe

2023-11-08 Thread Alex Hung
From: Wenjing Liu 

[WHY & HOW]
When acquiring an OTG master pipe we should prefer currently enabled OTG
master pipes first. If there are no free pipes used as current OTG
master pipe then we will try to acquire a currently unused free pipe as
new OTG master instead of tearing down current secondary pipes from ODM
or MPC combine.

Reviewed-by: Alvin Lee 
Reviewed-by: Dillon Varone 
Acked-by: Alex Hung 
Signed-off-by: Wenjing Liu 
---
 .../gpu/drm/amd/display/dc/core/dc_resource.c | 37 ++-
 drivers/gpu/drm/amd/display/dc/inc/resource.h | 12 ++
 2 files changed, 48 insertions(+), 1 deletion(-)

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 49f8c90f0d2b..42a927710743 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1764,6 +1764,29 @@ int recource_find_free_pipe_not_used_in_cur_res_ctx(
return free_pipe_idx;
 }
 
+int recource_find_free_pipe_used_as_otg_master_in_cur_res_ctx(
+   const struct resource_context *cur_res_ctx,
+   struct resource_context *new_res_ctx,
+   const struct resource_pool *pool)
+{
+   int free_pipe_idx = FREE_PIPE_INDEX_NOT_FOUND;
+   const struct pipe_ctx *new_pipe, *cur_pipe;
+   int i;
+
+   for (i = 0; i < pool->pipe_count; i++) {
+   cur_pipe = _res_ctx->pipe_ctx[i];
+   new_pipe = _res_ctx->pipe_ctx[i];
+
+   if (resource_is_pipe_type(cur_pipe, OTG_MASTER) &&
+   resource_is_pipe_type(new_pipe, FREE_PIPE)) {
+   free_pipe_idx = i;
+   break;
+   }
+   }
+
+   return free_pipe_idx;
+}
+
 int resource_find_free_pipe_used_as_cur_sec_dpp_in_mpcc_combine(
const struct resource_context *cur_res_ctx,
struct resource_context *new_res_ctx,
@@ -3600,8 +3623,20 @@ static bool acquire_otg_master_pipe_for_stream(
int pipe_idx;
struct pipe_ctx *pipe_ctx = NULL;
 
-   pipe_idx = recource_find_free_pipe_not_used_in_cur_res_ctx(
+   /*
+* Upper level code is responsible to optimize unnecessary addition and
+* removal for unchanged streams. So unchanged stream will keep the same
+* OTG master instance allocated. When current stream is removed and a
+* new stream is added, we want to reuse the OTG instance made available
+* by the removed stream first. If not found, we try to avoid of using
+* any free pipes already used in current context as this could tear
+* down exiting ODM/MPC/MPO configuration unnecessarily.
+*/
+   pipe_idx = recource_find_free_pipe_used_as_otg_master_in_cur_res_ctx(
_ctx->res_ctx, _ctx->res_ctx, pool);
+   if (pipe_idx == FREE_PIPE_INDEX_NOT_FOUND)
+   pipe_idx = recource_find_free_pipe_not_used_in_cur_res_ctx(
+   _ctx->res_ctx, _ctx->res_ctx, pool);
if (pipe_idx == FREE_PIPE_INDEX_NOT_FOUND)
pipe_idx = resource_find_any_free_pipe(_ctx->res_ctx, pool);
if (pipe_idx != FREE_PIPE_INDEX_NOT_FOUND) {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h 
b/drivers/gpu/drm/amd/display/dc/inc/resource.h
index 06ca8bfb91e7..0458d2d749f4 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
@@ -500,6 +500,18 @@ int recource_find_free_pipe_not_used_in_cur_res_ctx(
struct resource_context *new_res_ctx,
const struct resource_pool *pool);
 
+/*
+ * Look for a free pipe in new resource context that is used in current 
resource
+ * context as an OTG master pipe.
+ *
+ * return - FREE_PIPE_INDEX_NOT_FOUND if free pipe is not found, otherwise
+ * pipe idx of the free pipe
+ */
+int recource_find_free_pipe_used_as_otg_master_in_cur_res_ctx(
+   const struct resource_context *cur_res_ctx,
+   struct resource_context *new_res_ctx,
+   const struct resource_pool *pool);
+
 /*
  * Look for a free pipe in new resource context that is used as a secondary DPP
  * pipe in any MPCC combine in current resource context.
-- 
2.42.0



[PATCH 11/20] drm/amd/display: Enable DCN clock gating for DCN35

2023-11-08 Thread Alex Hung
From: Daniel Miess 

[WHY & HOW]
Enable DCN clock gating for DCN35.
Disable DTBCLK gate before link training
and re-enable afterwards

Reviewed-by: Nicholas Kazlauskas 
Acked-by: Alex Hung 
Signed-off-by: Daniel Miess 
---
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h |  6 ++-
 .../gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c | 30 +
 .../gpu/drm/amd/display/dc/dcn35/dcn35_dccg.h |  7 +++-
 .../drm/amd/display/dc/dcn35/dcn35_pg_cntl.c  | 10 +
 .../drm/amd/display/dc/dcn35/dcn35_pg_cntl.h  |  1 -
 .../drm/amd/display/dc/hwss/dce/dce_hwseq.h   | 15 ++-
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c   | 42 +--
 .../gpu/drm/amd/display/dc/inc/hw/pg_cntl.h   |  2 -
 .../dc/resource/dcn35/dcn35_resource.c| 16 ++-
 .../dc/resource/dcn35/dcn35_resource.h|  1 +
 .../include/asic_reg/dcn/dcn_3_5_0_sh_mask.h  |  8 
 11 files changed, 108 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h
index ab6d09c6fe34..76da59d8caaf 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h
@@ -291,7 +291,11 @@
type SYMCLKB_FE_SRC_SEL;\
type SYMCLKC_FE_SRC_SEL;\
type SYMCLKD_FE_SRC_SEL;\
-   type SYMCLKE_FE_SRC_SEL;
+   type SYMCLKE_FE_SRC_SEL;\
+   type DTBCLK_P0_GATE_DISABLE;\
+   type DTBCLK_P1_GATE_DISABLE;\
+   type DTBCLK_P2_GATE_DISABLE;\
+   type DTBCLK_P3_GATE_DISABLE;\
 
 struct dccg_shift {
DCCG_REG_FIELD_LIST(uint8_t)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c 
b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c
index 479f3683c0b7..142efd390d86 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c
@@ -256,6 +256,21 @@ static void dccg35_set_dtbclk_dto(
if (params->ref_dtbclk_khz && req_dtbclk_khz) {
uint32_t modulo, phase;
 
+   switch (params->otg_inst) {
+   case 0:
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
DTBCLK_P0_GATE_DISABLE, 1);
+   break;
+   case 1:
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
DTBCLK_P1_GATE_DISABLE, 1);
+   break;
+   case 2:
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
DTBCLK_P2_GATE_DISABLE, 1);
+   break;
+   case 3:
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
DTBCLK_P3_GATE_DISABLE, 1);
+   break;
+   }
+
// phase / modulo = dtbclk / dtbclk ref
modulo = params->ref_dtbclk_khz * 1000;
phase = req_dtbclk_khz * 1000;
@@ -280,6 +295,21 @@ static void dccg35_set_dtbclk_dto(
REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
PIPE_DTO_SRC_SEL[params->otg_inst], 2);
} else {
+   switch (params->otg_inst) {
+   case 0:
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
DTBCLK_P0_GATE_DISABLE, 0);
+   break;
+   case 1:
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
DTBCLK_P1_GATE_DISABLE, 0);
+   break;
+   case 2:
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
DTBCLK_P2_GATE_DISABLE, 0);
+   break;
+   case 3:
+   REG_UPDATE(DCCG_GATE_DISABLE_CNTL5, 
DTBCLK_P3_GATE_DISABLE, 0);
+   break;
+   }
+
REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
DTBCLK_DTO_ENABLE[params->otg_inst], 0,
PIPE_DTO_SRC_SEL[params->otg_inst], 
params->is_hdmi ? 0 : 1);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.h 
b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.h
index 423feb4c2f3f..bde48bee0119 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.h
@@ -34,6 +34,7 @@
 #define DCCG_REG_LIST_DCN35() \
DCCG_REG_LIST_DCN314(),\
SR(DPPCLK_CTRL),\
+   SR(DCCG_GATE_DISABLE_CNTL5),\
SR(DCCG_GATE_DISABLE_CNTL6),\
SR(DCCG_GLOBAL_FGCG_REP_CNTL),\
SR(SYMCLKA_CLOCK_ENABLE),\
@@ -174,7 +175,11 @@
DCCG_SF(SYMCLKB_CLOCK_ENABLE, SYMCLKB_FE_SRC_SEL, mask_sh),\
DCCG_SF(SYMCLKC_CLOCK_ENABLE, SYMCLKC_FE_SRC_SEL, mask_sh),\
DCCG_SF(SYMCLKD_CLOCK_ENABLE, SYMCLKD_FE_SRC_SEL, mask_sh),\
-   DCCG_SF(SYMCLKE_CLOCK_ENABLE, SYMCLKE_FE_SRC_SEL, mask_sh)
+   DCCG_SF(SYMCLKE_CLOCK_ENABLE, SYMCLKE_FE_SRC_SEL, mask_sh),\
+   DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P0_GATE_DISABLE, mask_sh),\
+   DCCG_SF(DCCG_GATE_DISABLE_CNTL5, DTBCLK_P1_GATE_DISABLE, mask_sh)

[PATCH 09/20] drm/amd/display: Try to acquire a free OTG master not used in cur ctx first

2023-11-08 Thread Alex Hung
From: Wenjing Liu 

[WHY & HOW]
The current otg master pipe allocation logic is not optimized based
current resource context. We should try to acquire a free OTG master not
used in cur cts first to avoid unnecessary pipe switch from current
state.

Acked-by: Alex Hung 
Signed-off-by: Wenjing Liu 
---
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 8 ++--
 1 file changed, 6 insertions(+), 2 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 6159d819c5c5..49f8c90f0d2b 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -3586,6 +3586,7 @@ static void mark_seamless_boot_stream(
  *   ||___|___|_|
  */
 static bool acquire_otg_master_pipe_for_stream(
+   const struct dc_state *cur_ctx,
struct dc_state *new_ctx,
const struct resource_pool *pool,
struct dc_stream_state *stream)
@@ -3599,7 +3600,10 @@ static bool acquire_otg_master_pipe_for_stream(
int pipe_idx;
struct pipe_ctx *pipe_ctx = NULL;
 
-   pipe_idx = resource_find_any_free_pipe(_ctx->res_ctx, pool);
+   pipe_idx = recource_find_free_pipe_not_used_in_cur_res_ctx(
+   _ctx->res_ctx, _ctx->res_ctx, pool);
+   if (pipe_idx == FREE_PIPE_INDEX_NOT_FOUND)
+   pipe_idx = resource_find_any_free_pipe(_ctx->res_ctx, pool);
if (pipe_idx != FREE_PIPE_INDEX_NOT_FOUND) {
pipe_ctx = _ctx->res_ctx.pipe_ctx[pipe_idx];
memset(pipe_ctx, 0, sizeof(*pipe_ctx));
@@ -3659,7 +3663,7 @@ enum dc_status resource_map_pool_resources(
 
if (!acquired)
/* acquire new resources */
-   acquired = acquire_otg_master_pipe_for_stream(
+   acquired = acquire_otg_master_pipe_for_stream(dc->current_state,
context, pool, stream);
 
pipe_ctx = resource_get_otg_master_for_stream(>res_ctx, 
stream);
-- 
2.42.0



[PATCH 08/20] drm/amd/display: Clear dpcd_sink_ext_caps if not set

2023-11-08 Thread Alex Hung
From: Paul Hsieh 

[WHY]
Some eDP panels' ext caps don't set initial values
and the value of dpcd_addr (0x317) is random.
It means that sometimes the eDP can be OLED, miniLED and etc,
and cause incorrect backlight control interface.

[HOW]
Add remove_sink_ext_caps to remove sink ext caps (HDR, OLED and etc)

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Anthony Koo 
Acked-by: Alex Hung 
Signed-off-by: Paul Hsieh 
---
 drivers/gpu/drm/amd/display/dc/dc_types.h| 1 +
 drivers/gpu/drm/amd/display/dc/link/link_detection.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_types.h
index cea666ea66c6..fcb825e4f1bb 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -177,6 +177,7 @@ struct dc_panel_patch {
unsigned int disable_fams;
unsigned int skip_avmute;
unsigned int mst_start_top_delay;
+   unsigned int remove_sink_ext_caps;
 };
 
 struct dc_edid_caps {
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c 
b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
index d6f0f857c05a..f2fe523f914f 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -1088,6 +1088,9 @@ static bool detect_link_and_local_sink(struct dc_link 
*link,
if (sink->edid_caps.panel_patch.skip_scdc_overwrite)
link->ctx->dc->debug.hdmi20_disable = true;
 
+   if (sink->edid_caps.panel_patch.remove_sink_ext_caps)
+   link->dpcd_sink_ext_caps.raw = 0;
+
if (dc_is_hdmi_signal(link->connector_signal))
read_scdc_caps(link->ddc, link->local_sink);
 
-- 
2.42.0



[PATCH 07/20] drm/amd/display: Enable fast plane updates on DCN3.2 and above

2023-11-08 Thread Alex Hung
From: Tianci Yin 

[WHY]
When cursor moves across screen boarder, lag cursor observed,
since subvp settings need to sync up with vblank that causes
cursor updates being delayed.

[HOW]
Enable fast plane updates on DCN3.2 to fix it.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Aurabindo Pillai 
Acked-by: Alex Hung 
Signed-off-by: Tianci Yin 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 
 1 file changed, 4 insertions(+), 4 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 adbeb2c897b5..8ebdbfbbb691 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9585,14 +9585,14 @@ static bool should_reset_plane(struct drm_atomic_state 
*state,
struct drm_plane *other;
struct drm_plane_state *old_other_state, *new_other_state;
struct drm_crtc_state *new_crtc_state;
+   struct amdgpu_device *adev = drm_to_adev(plane->dev);
int i;
 
/*
-* TODO: Remove this hack once the checks below are sufficient
-* enough to determine when we need to reset all the planes on
-* the stream.
+* TODO: Remove this hack for all asics once it proves that the
+* fast updates works fine on DCN3.2+.
 */
-   if (state->allow_modeset)
+   if (adev->ip_versions[DCE_HWIP][0] < IP_VERSION(3, 2, 0) && 
state->allow_modeset)
return true;
 
/* Exit early if we know that we're adding or removing the plane. */
-- 
2.42.0



[PATCH 06/20] drm/amd/display: Add null checks for 8K60 lightup

2023-11-08 Thread Alex Hung
From: Muhammad Ahmed 

[WHY & HOW]
Add some null checks to fix an issue where 8k60
tiled display fails to light up.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Charlene Liu 
Acked-by: Alex Hung 
Signed-off-by: Muhammad Ahmed 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c  | 2 +-
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 3 +++
 2 files changed, 4 insertions(+), 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 7b9bf5cb4529..d8f434738212 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3178,7 +3178,7 @@ static bool update_planes_and_stream_state(struct dc *dc,
struct pipe_ctx *otg_master = 
resource_get_otg_master_for_stream(>res_ctx,
context->streams[i]);
 
-   if (otg_master->stream->test_pattern.type != 
DP_TEST_PATTERN_VIDEO_MODE)
+   if (otg_master && otg_master->stream->test_pattern.type 
!= DP_TEST_PATTERN_VIDEO_MODE)

resource_build_test_pattern_params(>res_ctx, otg_master);
}
}
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 06fc4c5a3b69..6159d819c5c5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -5190,6 +5190,9 @@ bool 
dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy(
sec_next = sec_pipe->next_odm_pipe;
sec_prev = sec_pipe->prev_odm_pipe;
 
+   if (pri_pipe == NULL)
+   return false;
+
*sec_pipe = *pri_pipe;
 
sec_pipe->top_pipe = sec_top;
-- 
2.42.0



[PATCH 05/20] drm/amd/display: Refactor resource into component directory

2023-11-08 Thread Alex Hung
From: Mounika Adhuri 

[WHY]
Move all resource files to unique folder resource.

[HOW]
Created resource folder in dc, moved the
dcnxx_resource.c and dcnxx_resource.h files into
corresponding new folders inside the resource and
made appropriate changes for compilation in Makefiles.

Reviewed-by: Martin Leung 
Acked-by: Alex Hung 
Signed-off-by: Mounika Adhuri 
---
 drivers/gpu/drm/amd/display/Makefile  |   1 +
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |   2 +-
 drivers/gpu/drm/amd/display/dc/Makefile   |   5 +-
 .../gpu/drm/amd/display/dc/core/dc_resource.c |   4 +-
 .../gpu/drm/amd/display/dc/dce100/Makefile|  46 
 .../gpu/drm/amd/display/dc/dce110/Makefile|   4 +-
 .../gpu/drm/amd/display/dc/dce112/Makefile|   3 +-
 .../gpu/drm/amd/display/dc/dce120/Makefile|   2 +-
 drivers/gpu/drm/amd/display/dc/dce80/Makefile |   3 +-
 drivers/gpu/drm/amd/display/dc/dcn10/Makefile |   2 +-
 drivers/gpu/drm/amd/display/dc/dcn20/Makefile |   2 +-
 .../gpu/drm/amd/display/dc/dcn201/Makefile|   2 +-
 drivers/gpu/drm/amd/display/dc/dcn21/Makefile |   2 +-
 drivers/gpu/drm/amd/display/dc/dcn30/Makefile |   1 -
 .../gpu/drm/amd/display/dc/dcn301/Makefile|   2 +-
 .../gpu/drm/amd/display/dc/dcn302/Makefile|   2 +-
 .../gpu/drm/amd/display/dc/dcn303/Makefile|   2 +-
 drivers/gpu/drm/amd/display/dc/dcn31/Makefile |   2 +-
 .../gpu/drm/amd/display/dc/dcn314/Makefile|   2 +-
 .../gpu/drm/amd/display/dc/dcn315/Makefile|  30 ---
 .../gpu/drm/amd/display/dc/dcn316/Makefile|  30 ---
 drivers/gpu/drm/amd/display/dc/dcn32/Makefile |   2 +-
 .../display/dc/dcn32/dcn32_resource_helpers.c |   2 +-
 .../gpu/drm/amd/display/dc/dcn321/Makefile|   2 +-
 drivers/gpu/drm/amd/display/dc/dcn35/Makefile |   2 +-
 .../drm/amd/display/dc/dml/calcs/dcn_calcs.c  |   2 +-
 .../gpu/drm/amd/display/dc/resource/Makefile  | 199 ++
 .../{ => resource}/dce100/dce100_resource.c   |   0
 .../{ => resource}/dce100/dce100_resource.h   |   0
 .../{ => resource}/dce110/dce110_resource.c   |   0
 .../{ => resource}/dce110/dce110_resource.h   |   0
 .../{ => resource}/dce112/dce112_resource.c   |   0
 .../{ => resource}/dce112/dce112_resource.h   |   0
 .../{ => resource}/dce120/dce120_resource.c   |   2 +-
 .../{ => resource}/dce120/dce120_resource.h   |   0
 .../display/dc/resource/dce80/CMakeLists.txt  |   4 +
 .../dc/{ => resource}/dce80/dce80_resource.c  |   0
 .../dc/{ => resource}/dce80/dce80_resource.h  |   0
 .../dc/{ => resource}/dcn10/dcn10_resource.c  |  25 ++-
 .../dc/{ => resource}/dcn10/dcn10_resource.h  |   0
 .../dc/{ => resource}/dcn20/dcn20_resource.c  |  24 +--
 .../dc/{ => resource}/dcn20/dcn20_resource.h  |   0
 .../{ => resource}/dcn201/dcn201_resource.c   |  14 +-
 .../{ => resource}/dcn201/dcn201_resource.h   |   0
 .../dc/{ => resource}/dcn21/dcn21_resource.c  |   6 +-
 .../dc/{ => resource}/dcn21/dcn21_resource.h  |   0
 .../dc/{ => resource}/dcn30/dcn30_resource.c  |   2 +-
 .../dc/{ => resource}/dcn30/dcn30_resource.h  |   0
 .../{ => resource}/dcn301/dcn301_resource.c   |   4 +-
 .../{ => resource}/dcn301/dcn301_resource.h   |   0
 .../{ => resource}/dcn302/dcn302_resource.c   |   4 +-
 .../{ => resource}/dcn302/dcn302_resource.h   |   0
 .../{ => resource}/dcn303/dcn303_resource.c   |   4 +-
 .../{ => resource}/dcn303/dcn303_resource.h   |   0
 .../dc/{ => resource}/dcn31/dcn31_resource.c  |   2 +-
 .../dc/{ => resource}/dcn31/dcn31_resource.h  |   0
 .../{ => resource}/dcn314/dcn314_resource.c   |   0
 .../{ => resource}/dcn314/dcn314_resource.h   |   0
 .../{ => resource}/dcn315/dcn315_resource.c   |   0
 .../{ => resource}/dcn315/dcn315_resource.h   |   0
 .../{ => resource}/dcn316/dcn316_resource.c   |   0
 .../{ => resource}/dcn316/dcn316_resource.h   |   0
 .../dc/{ => resource}/dcn32/dcn32_resource.c  |   4 +-
 .../dc/{ => resource}/dcn32/dcn32_resource.h  |   0
 .../{ => resource}/dcn321/dcn321_resource.c   |   2 +-
 .../{ => resource}/dcn321/dcn321_resource.h   |   0
 .../dc/{ => resource}/dcn35/dcn35_resource.c  |   2 +-
 .../dc/{ => resource}/dcn35/dcn35_resource.h  |   0
 68 files changed, 276 insertions(+), 181 deletions(-)
 delete mode 100644 drivers/gpu/drm/amd/display/dc/dce100/Makefile
 delete mode 100644 drivers/gpu/drm/amd/display/dc/dcn315/Makefile
 delete mode 100644 drivers/gpu/drm/amd/display/dc/dcn316/Makefile
 create mode 100644 drivers/gpu/drm/amd/display/dc/resource/Makefile
 rename drivers/gpu/drm/amd/display/dc/{ => resource}/dce100/dce100_resource.c 
(100%)
 rename drivers/gpu/drm/amd/display/dc/{ => resource}/dce100/dce100_resource.h 
(100%)
 rename drivers/gpu/drm/amd/display/dc/{ => resource}/dce110/dce110_resource.c 
(100%)
 rename drivers/gpu/drm/amd/display/dc/{ => resource}/dce110/dce110_resource.h 
(100%)
 rename drivers/gpu/drm/amd/display/dc/{ => resource}/dce112/dce112_resource.

[PATCH 04/20] drm/amd/display: Fix DSC not Enabled on Direct MST Sink

2023-11-08 Thread Alex Hung
From: Fangzhi Zuo 

[WHY & HOW]
For the scenario when a dsc capable MST sink device is directly
connected, it needs to use max dsc compression as the link bw constraint.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Roman Li 
Acked-by: Alex Hung 
Signed-off-by: Fangzhi Zuo 
---
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   | 29 +--
 1 file changed, 14 insertions(+), 15 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 d3b13d362eda..11da0eebee6c 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
@@ -1604,31 +1604,31 @@ enum dc_status dm_dp_mst_is_port_support_mode(
unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0;
unsigned int max_compressed_bw_in_kbps = 0;
struct dc_dsc_bw_range bw_range = {0};
-   struct drm_dp_mst_topology_mgr *mst_mgr;
+   uint16_t full_pbn = aconnector->mst_output_port->full_pbn;
 
/*
-* check if the mode could be supported if DSC pass-through is supported
-* AND check if there enough bandwidth available to support the mode
-* with DSC enabled.
+* Consider the case with the depth of the mst topology tree is equal 
or less than 2
+* A. When dsc bitstream can be transmitted along the entire path
+*1. dsc is possible between source and branch/leaf device (common 
dsc params is possible), AND
+*2. dsc passthrough supported at MST branch, or
+*3. dsc decoding supported at leaf MST device
+*Use maximum dsc compression as bw constraint
+* B. When dsc bitstream cannot be transmitted along the entire path
+*Use native bw as bw constraint
 */
if (is_dsc_common_config_possible(stream, _range) &&
-   aconnector->mst_output_port->passthrough_aux) {
-   mst_mgr = aconnector->mst_output_port->mgr;
-   mutex_lock(_mgr->lock);
-
+  (aconnector->mst_output_port->passthrough_aux ||
+   aconnector->dsc_aux == >mst_output_port->aux)) {
cur_link_settings = stream->link->verified_link_cap;
 
upper_link_bw_in_kbps = 
dc_link_bandwidth_kbps(aconnector->dc_link,
-  
_link_settings
-  );
-   down_link_bw_in_kbps = 
kbps_from_pbn(aconnector->mst_output_port->full_pbn);
+  
_link_settings);
+   down_link_bw_in_kbps = kbps_from_pbn(full_pbn);
 
/* pick the bottleneck */
end_to_end_bw_in_kbps = min(upper_link_bw_in_kbps,
down_link_bw_in_kbps);
 
-   mutex_unlock(_mgr->lock);
-
/*
 * use the maximum dsc compression bandwidth as the required
 * bandwidth for the mode
@@ -1643,8 +1643,7 @@ enum dc_status dm_dp_mst_is_port_support_mode(
/* check if mode could be supported within full_pbn */
bpp = 
convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3;
pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, 
bpp, false);
-
-   if (pbn > aconnector->mst_output_port->full_pbn)
+   if (pbn > full_pbn)
return DC_FAIL_BANDWIDTH_VALIDATE;
}
 
-- 
2.42.0



[PATCH 03/20] drm/amd/display: Guard against invalid RPTR/WPTR being set

2023-11-08 Thread Alex Hung
From: Nicholas Kazlauskas 

[WHY]
HW can return invalid values on register read, guard against these being
set and causing us to access memory out of range and page fault.

[HOW]
Guard at sync_inbox1 and guard at pushing commands.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Hansen Dsouza 
Acked-by: Alex Hung 
Signed-off-by: Nicholas Kazlauskas 
---
 .../gpu/drm/amd/display/dmub/src/dmub_srv.c| 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c 
b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
index e43e8d4bfe37..5d36f3e5dc2b 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
@@ -707,9 +707,16 @@ enum dmub_status dmub_srv_sync_inbox1(struct dmub_srv 
*dmub)
return DMUB_STATUS_INVALID;
 
if (dmub->hw_funcs.get_inbox1_rptr && dmub->hw_funcs.get_inbox1_wptr) {
-   dmub->inbox1_rb.rptr = dmub->hw_funcs.get_inbox1_rptr(dmub);
-   dmub->inbox1_rb.wrpt = dmub->hw_funcs.get_inbox1_wptr(dmub);
-   dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt;
+   uint32_t rptr = dmub->hw_funcs.get_inbox1_rptr(dmub);
+   uint32_t wptr = dmub->hw_funcs.get_inbox1_wptr(dmub);
+
+   if (rptr > dmub->inbox1_rb.capacity || wptr > 
dmub->inbox1_rb.capacity) {
+   return DMUB_STATUS_HW_FAILURE;
+   } else {
+   dmub->inbox1_rb.rptr = rptr;
+   dmub->inbox1_rb.wrpt = wptr;
+   dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt;
+   }
}
 
return DMUB_STATUS_OK;
@@ -743,6 +750,11 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub,
if (!dmub->hw_init)
return DMUB_STATUS_INVALID;
 
+   if (dmub->inbox1_rb.rptr > dmub->inbox1_rb.capacity ||
+   dmub->inbox1_rb.wrpt > dmub->inbox1_rb.capacity) {
+   return DMUB_STATUS_HW_FAILURE;
+   }
+
if (dmub_rb_push_front(>inbox1_rb, cmd))
return DMUB_STATUS_OK;
 
-- 
2.42.0



[PATCH 02/20] drm/amd/display: Enable CM low mem power optimization

2023-11-08 Thread Alex Hung
From: Yihan Zhu 

[WHY & HOW]
MPC MCM low mem power optimization still causes color distortion on
first SCE enablement, only forces light sleep for it.

DPP low memory power optimization still needs this bit to save power.

Reviewed-by: Nicholas Kazlauskas 
Acked-by: Alex Hung 
Signed-off-by: Yihan Zhu 
---
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c| 13 -
 .../gpu/drm/amd/display/dc/dcn35/dcn35_resource.c   |  2 +-
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c 
b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c
index 994b21ed272f..1a2adb354718 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c
@@ -71,21 +71,24 @@ void mpc32_power_on_blnd_lut(
 {
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 
+/*
if (mpc->ctx->dc->debug.enable_mem_low_power.bits.cm) {
if (power_on) {
REG_UPDATE(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 
MPCC_MCM_1DLUT_MEM_PWR_FORCE, 0);
REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 
MPCC_MCM_1DLUT_MEM_PWR_STATE, 0, 1, 5);
} else if (!mpc->ctx->dc->debug.disable_mem_low_power) {
-   ASSERT(false);
-   /* TODO: change to mpc
-*  dpp_base->ctx->dc->optimized_required = true;
-*  dpp_base->deferred_reg_writes.bits.disable_blnd_lut 
= true;
-*/
+   //TODO: change to mpc
+   dpp_base->ctx->dc->optimized_required = true;
+   dpp_base->deferred_reg_writes.bits.disable_blnd_lut = 
true;
}
} else {
REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0,
MPCC_MCM_1DLUT_MEM_PWR_FORCE, power_on == true 
? 0 : 1);
}
+*/
+
+   REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0,
+   MPCC_MCM_1DLUT_MEM_PWR_FORCE, power_on == true ? 0 : 1);
 }
 
 static enum dc_lut_mode mpc32_get_post1dlut_current(struct mpc *mpc, uint32_t 
mpcc_id)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
index c7e011d26d41..7a3faf2b1f06 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
@@ -724,7 +724,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.i2c = true,
.dmcu = false, // This is previously known to cause 
hang on S3 cycles if enabled
.dscl = true,
-   .cm = false,
+   .cm = true,
.mpc = true,
.optc = true,
.vpg = true,
-- 
2.42.0



[PATCH 01/20] drm/amd/display: Fix a debugfs null pointer error

2023-11-08 Thread Alex Hung
From: Aurabindo Pillai 

[WHY & HOW]
Check whether get_subvp_en() callback exists before calling it.

Cc: Mario Limonciello 
Cc: Alex Deucher 
Cc: sta...@vger.kernel.org
Reviewed-by: Alex Hung 
Acked-by: Alex Hung 
Signed-off-by: Aurabindo Pillai 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

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 13a177d34376..45c972f2630d 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
@@ -3647,12 +3647,16 @@ static int capabilities_show(struct seq_file *m, void 
*unused)
bool mall_supported = dc->caps.mall_size_total;
bool subvp_supported = dc->caps.subvp_fw_processing_delay_us;
unsigned int mall_in_use = false;
-   unsigned int subvp_in_use = dc->cap_funcs.get_subvp_en(dc, 
dc->current_state);
+   unsigned int subvp_in_use = false;
+
struct hubbub *hubbub = dc->res_pool->hubbub;
 
if (hubbub->funcs->get_mall_en)
hubbub->funcs->get_mall_en(hubbub, _in_use);
 
+   if (dc->cap_funcs.get_subvp_en)
+   subvp_in_use = dc->cap_funcs.get_subvp_en(dc, 
dc->current_state);
+
seq_printf(m, "mall supported: %s, enabled: %s\n",
   mall_supported ? "yes" : "no", mall_in_use ? "yes" : 
"no");
seq_printf(m, "sub-viewport supported: %s, enabled: %s\n",
-- 
2.42.0



[PATCH 00/20] DC Patches Nov 08, 2023

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

* Add missing chips for HDCP
* Add new command to disable replay timing resync
* Fix encoder disable logic
* Enable DSC Flag in MST Mode Validation
* Change the DMCUB mailbox memory location from FB to inbox
* Add disable timeout option
* Negate IPS allow and commit bits
* Enable DCN clock gating for DCN35
* Prefer currently used OTG master when acquiring free pipe
* Try to acquire a free OTG master not used in cur ctx first
* Clear dpcd_sink_ext_caps if not set
* Enable fast plane updates on DCN3.2 and above
* Add null checks for 8K60 lightup
* Refactor resource into component directory
* Fix DSC not Enabled on Direct MST Sink
* Guard against invalid RPTR/WPTR being set
* Enable CM low mem power optimization
* Fix a debugfs null pointer error

Cc: Daniel Wheeler 

Anthony Koo (1):
  drm/amd/display: Add new command to disable replay timing resync

Aric Cyr (1):
  drm/amd/display: Promote DC to 3.2.260

Aurabindo Pillai (1):
  drm/amd/display: Fix a debugfs null pointer error

Daniel Miess (1):
  drm/amd/display: Enable DCN clock gating for DCN35

Duncan Ma (2):
  drm/amd/display: Negate IPS allow and commit bits
  drm/amd/display: Add disable timeout option

Fangzhi Zuo (2):
  drm/amd/display: Fix DSC not Enabled on Direct MST Sink
  drm/amd/display: Enable DSC Flag in MST Mode Validation

Krunoslav Kovac (1):
  drm/amd/display: Send PQ bit in AMD VSIF

Lewis Huang (1):
  drm/amd/display: Change the DMCUB mailbox memory location from FB to
inbox

Mounika Adhuri (1):
  drm/amd/display: Refactor resource into component directory

Muhammad Ahmed (1):
  drm/amd/display: Add null checks for 8K60 lightup

Nicholas Kazlauskas (1):
  drm/amd/display: Guard against invalid RPTR/WPTR being set

Nicholas Susanto (1):
  drm/amd/display: Fix encoder disable logic

Paul Hsieh (1):
  drm/amd/display: Clear dpcd_sink_ext_caps if not set

Rodrigo Siqueira (1):
  drm/amd/display: Add missing chips for HDCP

Tianci Yin (1):
  drm/amd/display: Enable fast plane updates on DCN3.2 and above

Wenjing Liu (2):
  drm/amd/display: Try to acquire a free OTG master not used in cur ctx
first
  drm/amd/display: Prefer currently used OTG master when acquiring free
pipe

Yihan Zhu (1):
  drm/amd/display: Enable CM low mem power optimization

 drivers/gpu/drm/amd/display/Makefile  |   1 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  21 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |   6 +-
 .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  63 +++---
 drivers/gpu/drm/amd/display/dc/Makefile   |   5 +-
 .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c  |  18 +-
 .../amd/display/dc/clk_mgr/dcn35/dcn35_smu.c  |   3 +
 drivers/gpu/drm/amd/display/dc/core/dc.c  |   6 +-
 .../gpu/drm/amd/display/dc/core/dc_resource.c |  50 -
 drivers/gpu/drm/amd/display/dc/dc.h   |   3 +-
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  |  39 +++-
 drivers/gpu/drm/amd/display/dc/dc_types.h |   1 +
 .../gpu/drm/amd/display/dc/dce100/Makefile|  46 
 .../gpu/drm/amd/display/dc/dce110/Makefile|   4 +-
 .../gpu/drm/amd/display/dc/dce112/Makefile|   3 +-
 .../gpu/drm/amd/display/dc/dce120/Makefile|   2 +-
 drivers/gpu/drm/amd/display/dc/dce80/Makefile |   3 +-
 drivers/gpu/drm/amd/display/dc/dcn10/Makefile |   2 +-
 drivers/gpu/drm/amd/display/dc/dcn20/Makefile |   2 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h |   6 +-
 .../gpu/drm/amd/display/dc/dcn201/Makefile|   2 +-
 drivers/gpu/drm/amd/display/dc/dcn21/Makefile |   2 +-
 drivers/gpu/drm/amd/display/dc/dcn30/Makefile |   1 -
 .../gpu/drm/amd/display/dc/dcn301/Makefile|   2 +-
 .../gpu/drm/amd/display/dc/dcn302/Makefile|   2 +-
 .../gpu/drm/amd/display/dc/dcn303/Makefile|   2 +-
 drivers/gpu/drm/amd/display/dc/dcn31/Makefile |   2 +-
 .../gpu/drm/amd/display/dc/dcn314/Makefile|   2 +-
 .../gpu/drm/amd/display/dc/dcn315/Makefile|  30 ---
 .../gpu/drm/amd/display/dc/dcn316/Makefile|  30 ---
 drivers/gpu/drm/amd/display/dc/dcn32/Makefile |   2 +-
 .../gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c  |  13 +-
 .../display/dc/dcn32/dcn32_resource_helpers.c |   2 +-
 .../gpu/drm/amd/display/dc/dcn321/Makefile|   2 +-
 drivers/gpu/drm/amd/display/dc/dcn35/Makefile |   2 +-
 .../gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c |  30 +++
 .../gpu/drm/amd/display/dc/dcn35/dcn35_dccg.h |   7 +-
 .../dc/dcn35/dcn35_dio_stream_encoder.c   |  10 +-
 .../drm/amd/display/dc/dcn35/dcn35_pg_cntl.c  |  10 +-
 .../drm/amd/display/dc/dcn35/dcn35_pg_cntl.h  |   1 -
 .../drm/amd/display/dc/dml/calcs/dcn_calcs.c  |   2 +-
 .../drm/amd/display/dc/hwss/dce/dce_hwseq.h   |  15 +-
 .../amd/display/dc/hwss/dcn35/dcn35_hwseq.c   |  42 ++--
 .../gpu/drm/amd/display/dc/inc/hw/pg_cntl.h   |   2 -
 drivers/gpu/drm/amd/display/dc/inc/resource.h |  12 ++
 .../drm/amd/display/dc/link/link_detection.c  |   3 +
 .../gpu/drm/amd/display/dc/resource/Makefile  | 199 

  1   2   3   >